All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
To: Ohad Ben-Cohen <ohad@wizery.com>
Cc: linux-arm-msm@vger.kernel.org,
	Jeffrey Hugo <jhugo@codeaurora.org>, Suman Anna <s-anna@ti.com>,
	Andy Gross <agross@codeaurora.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH v8 2/2] hwspinlock: qcom: Add support for Qualcomm HW Mutex block
Date: Tue, 24 Mar 2015 10:11:05 -0700	[thread overview]
Message-ID: <1427217065-17186-2-git-send-email-bjorn.andersson@sonymobile.com> (raw)
In-Reply-To: <1427217065-17186-1-git-send-email-bjorn.andersson@sonymobile.com>

Add driver for Qualcomm Hardware Mutex block found in many Qualcomm
SoCs.

Based on initial effort by Kumar Gala <galak@codeaurora.org>

Reviewed-by: Andy Gross <agross@codeaurora.org>
Reviewed-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
---

Changes since v7:
- None (DT binding only)

Changes since v6:
- Added missing select of MFD_SYSCON

Changes since v5:
- Dropped all but hwspinlock specific dt bindings
- Hardcoded the number of locks (there is 32)
- Rework to sit ontop of syscon

Changes since v4:
- Aligned with devicetree support in hwlock framework and hence depends on [1]

Changes since v3:
- Reverted back to getting stride from of_match, per Kumars request

Changes since v2:
- MODULE_DEVICE_TABLE
- Changed prefix to qcom
- Cleaned up includes
- Rely on reg and num-locks to figure out stride, instead of of_match data

Changes since v1:
- Added the pm_runtime calls needed to be able to boot a kernel with
  pm_runtime and this driver, patch from Courtney.
- Added sfpb-mutex compatible, for re-use of the driver in family A platforms.
- Updated formatting of DT binding documentation, while adding the extra
  compatible.
- Dropped Stephen Boyds Reviewed-by due to these changes.

 drivers/hwspinlock/Kconfig           |  12 +++
 drivers/hwspinlock/Makefile          |   1 +
 drivers/hwspinlock/qcom_hwspinlock.c | 181 +++++++++++++++++++++++++++++++++++
 3 files changed, 194 insertions(+)
 create mode 100644 drivers/hwspinlock/qcom_hwspinlock.c

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index 3612cb5..b5b4f52 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -18,6 +18,18 @@ config HWSPINLOCK_OMAP
 
 	  If unsure, say N.
 
+config HWSPINLOCK_QCOM
+	tristate "Qualcomm Hardware Spinlock device"
+	depends on ARCH_QCOM
+	select HWSPINLOCK
+	select MFD_SYSCON
+	help
+	  Say y here to support the Qualcomm Hardware Mutex functionality, which
+	  provides a synchronisation mechanism for the various processors on
+	  the SoC.
+
+	  If unsure, say N.
+
 config HSEM_U8500
 	tristate "STE Hardware Semaphore functionality"
 	depends on ARCH_U8500
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 93eb64b..68f95d9 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,4 +4,5 @@
 
 obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
 obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
+obj-$(CONFIG_HWSPINLOCK_QCOM)		+= qcom_hwspinlock.o
 obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
new file mode 100644
index 0000000..93b62e0
--- /dev/null
+++ b/drivers/hwspinlock/qcom_hwspinlock.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, Sony Mobile Communications AB
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/hwspinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "hwspinlock_internal.h"
+
+#define QCOM_MUTEX_APPS_PROC_ID	1
+#define QCOM_MUTEX_NUM_LOCKS	32
+
+static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
+{
+	struct regmap_field *field = lock->priv;
+	u32 lock_owner;
+	int ret;
+
+	ret = regmap_field_write(field, QCOM_MUTEX_APPS_PROC_ID);
+	if (ret)
+		return ret;
+
+	ret = regmap_field_read(field, &lock_owner);
+	if (ret)
+		return ret;
+
+	return lock_owner == QCOM_MUTEX_APPS_PROC_ID;
+}
+
+static void qcom_hwspinlock_unlock(struct hwspinlock *lock)
+{
+	struct regmap_field *field = lock->priv;
+	u32 lock_owner;
+	int ret;
+
+	ret = regmap_field_read(field, &lock_owner);
+	if (ret) {
+		pr_err("%s: unable to query spinlock owner\n", __func__);
+		return;
+	}
+
+	if (lock_owner != QCOM_MUTEX_APPS_PROC_ID) {
+		pr_err("%s: spinlock not owned by us (actual owner is %d)\n",
+				__func__, lock_owner);
+	}
+
+	ret = regmap_field_write(field, 0);
+	if (ret)
+		pr_err("%s: failed to unlock spinlock\n", __func__);
+}
+
+static const struct hwspinlock_ops qcom_hwspinlock_ops = {
+	.trylock	= qcom_hwspinlock_trylock,
+	.unlock		= qcom_hwspinlock_unlock,
+};
+
+static const struct of_device_id qcom_hwspinlock_of_match[] = {
+	{ .compatible = "qcom,sfpb-mutex" },
+	{ .compatible = "qcom,tcsr-mutex" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_hwspinlock_of_match);
+
+static int qcom_hwspinlock_probe(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank;
+	struct device_node *syscon;
+	struct reg_field field;
+	struct regmap *regmap;
+	size_t array_size;
+	u32 stride;
+	u32 base;
+	int ret;
+	int i;
+
+	syscon = of_parse_phandle(pdev->dev.of_node, "syscon", 0);
+	if (!syscon) {
+		dev_err(&pdev->dev, "no syscon property\n");
+		return -ENODEV;
+	}
+
+	regmap = syscon_node_to_regmap(syscon);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, &base);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no offset in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 2, &stride);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no stride syscon\n");
+		return -EINVAL;
+	}
+
+	array_size = QCOM_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
+	bank = devm_kzalloc(&pdev->dev, sizeof(*bank) + array_size, GFP_KERNEL);
+	if (!bank)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, bank);
+
+	for (i = 0; i < QCOM_MUTEX_NUM_LOCKS; i++) {
+		field.reg = base + i * stride;
+		field.lsb = 0;
+		field.msb = 32;
+
+		bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev,
+							     regmap, field);
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
+				   0, QCOM_MUTEX_NUM_LOCKS);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int qcom_hwspinlock_remove(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static struct platform_driver qcom_hwspinlock_driver = {
+	.probe		= qcom_hwspinlock_probe,
+	.remove		= qcom_hwspinlock_remove,
+	.driver		= {
+		.name	= "qcom_hwspinlock",
+		.of_match_table = qcom_hwspinlock_of_match,
+	},
+};
+
+static int __init qcom_hwspinlock_init(void)
+{
+	return platform_driver_register(&qcom_hwspinlock_driver);
+}
+/* board init code might need to reserve hwspinlocks for predefined purposes */
+postcore_initcall(qcom_hwspinlock_init);
+
+static void __exit qcom_hwspinlock_exit(void)
+{
+	platform_driver_unregister(&qcom_hwspinlock_driver);
+}
+module_exit(qcom_hwspinlock_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware spinlock driver for Qualcomm SoCs");
-- 
1.8.2.2

WARNING: multiple messages have this Message-ID (diff)
From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
To: Ohad Ben-Cohen <ohad@wizery.com>
Cc: <linux-arm-msm@vger.kernel.org>,
	Jeffrey Hugo <jhugo@codeaurora.org>, Suman Anna <s-anna@ti.com>,
	Andy Gross <agross@codeaurora.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH v8 2/2] hwspinlock: qcom: Add support for Qualcomm HW Mutex block
Date: Tue, 24 Mar 2015 10:11:05 -0700	[thread overview]
Message-ID: <1427217065-17186-2-git-send-email-bjorn.andersson@sonymobile.com> (raw)
In-Reply-To: <1427217065-17186-1-git-send-email-bjorn.andersson@sonymobile.com>

Add driver for Qualcomm Hardware Mutex block found in many Qualcomm
SoCs.

Based on initial effort by Kumar Gala <galak@codeaurora.org>

Reviewed-by: Andy Gross <agross@codeaurora.org>
Reviewed-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
---

Changes since v7:
- None (DT binding only)

Changes since v6:
- Added missing select of MFD_SYSCON

Changes since v5:
- Dropped all but hwspinlock specific dt bindings
- Hardcoded the number of locks (there is 32)
- Rework to sit ontop of syscon

Changes since v4:
- Aligned with devicetree support in hwlock framework and hence depends on [1]

Changes since v3:
- Reverted back to getting stride from of_match, per Kumars request

Changes since v2:
- MODULE_DEVICE_TABLE
- Changed prefix to qcom
- Cleaned up includes
- Rely on reg and num-locks to figure out stride, instead of of_match data

Changes since v1:
- Added the pm_runtime calls needed to be able to boot a kernel with
  pm_runtime and this driver, patch from Courtney.
- Added sfpb-mutex compatible, for re-use of the driver in family A platforms.
- Updated formatting of DT binding documentation, while adding the extra
  compatible.
- Dropped Stephen Boyds Reviewed-by due to these changes.

 drivers/hwspinlock/Kconfig           |  12 +++
 drivers/hwspinlock/Makefile          |   1 +
 drivers/hwspinlock/qcom_hwspinlock.c | 181 +++++++++++++++++++++++++++++++++++
 3 files changed, 194 insertions(+)
 create mode 100644 drivers/hwspinlock/qcom_hwspinlock.c

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index 3612cb5..b5b4f52 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -18,6 +18,18 @@ config HWSPINLOCK_OMAP
 
 	  If unsure, say N.
 
+config HWSPINLOCK_QCOM
+	tristate "Qualcomm Hardware Spinlock device"
+	depends on ARCH_QCOM
+	select HWSPINLOCK
+	select MFD_SYSCON
+	help
+	  Say y here to support the Qualcomm Hardware Mutex functionality, which
+	  provides a synchronisation mechanism for the various processors on
+	  the SoC.
+
+	  If unsure, say N.
+
 config HSEM_U8500
 	tristate "STE Hardware Semaphore functionality"
 	depends on ARCH_U8500
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 93eb64b..68f95d9 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,4 +4,5 @@
 
 obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
 obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
+obj-$(CONFIG_HWSPINLOCK_QCOM)		+= qcom_hwspinlock.o
 obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
new file mode 100644
index 0000000..93b62e0
--- /dev/null
+++ b/drivers/hwspinlock/qcom_hwspinlock.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, Sony Mobile Communications AB
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/hwspinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "hwspinlock_internal.h"
+
+#define QCOM_MUTEX_APPS_PROC_ID	1
+#define QCOM_MUTEX_NUM_LOCKS	32
+
+static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
+{
+	struct regmap_field *field = lock->priv;
+	u32 lock_owner;
+	int ret;
+
+	ret = regmap_field_write(field, QCOM_MUTEX_APPS_PROC_ID);
+	if (ret)
+		return ret;
+
+	ret = regmap_field_read(field, &lock_owner);
+	if (ret)
+		return ret;
+
+	return lock_owner == QCOM_MUTEX_APPS_PROC_ID;
+}
+
+static void qcom_hwspinlock_unlock(struct hwspinlock *lock)
+{
+	struct regmap_field *field = lock->priv;
+	u32 lock_owner;
+	int ret;
+
+	ret = regmap_field_read(field, &lock_owner);
+	if (ret) {
+		pr_err("%s: unable to query spinlock owner\n", __func__);
+		return;
+	}
+
+	if (lock_owner != QCOM_MUTEX_APPS_PROC_ID) {
+		pr_err("%s: spinlock not owned by us (actual owner is %d)\n",
+				__func__, lock_owner);
+	}
+
+	ret = regmap_field_write(field, 0);
+	if (ret)
+		pr_err("%s: failed to unlock spinlock\n", __func__);
+}
+
+static const struct hwspinlock_ops qcom_hwspinlock_ops = {
+	.trylock	= qcom_hwspinlock_trylock,
+	.unlock		= qcom_hwspinlock_unlock,
+};
+
+static const struct of_device_id qcom_hwspinlock_of_match[] = {
+	{ .compatible = "qcom,sfpb-mutex" },
+	{ .compatible = "qcom,tcsr-mutex" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_hwspinlock_of_match);
+
+static int qcom_hwspinlock_probe(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank;
+	struct device_node *syscon;
+	struct reg_field field;
+	struct regmap *regmap;
+	size_t array_size;
+	u32 stride;
+	u32 base;
+	int ret;
+	int i;
+
+	syscon = of_parse_phandle(pdev->dev.of_node, "syscon", 0);
+	if (!syscon) {
+		dev_err(&pdev->dev, "no syscon property\n");
+		return -ENODEV;
+	}
+
+	regmap = syscon_node_to_regmap(syscon);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, &base);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no offset in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 2, &stride);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no stride syscon\n");
+		return -EINVAL;
+	}
+
+	array_size = QCOM_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
+	bank = devm_kzalloc(&pdev->dev, sizeof(*bank) + array_size, GFP_KERNEL);
+	if (!bank)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, bank);
+
+	for (i = 0; i < QCOM_MUTEX_NUM_LOCKS; i++) {
+		field.reg = base + i * stride;
+		field.lsb = 0;
+		field.msb = 32;
+
+		bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev,
+							     regmap, field);
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
+				   0, QCOM_MUTEX_NUM_LOCKS);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int qcom_hwspinlock_remove(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static struct platform_driver qcom_hwspinlock_driver = {
+	.probe		= qcom_hwspinlock_probe,
+	.remove		= qcom_hwspinlock_remove,
+	.driver		= {
+		.name	= "qcom_hwspinlock",
+		.of_match_table = qcom_hwspinlock_of_match,
+	},
+};
+
+static int __init qcom_hwspinlock_init(void)
+{
+	return platform_driver_register(&qcom_hwspinlock_driver);
+}
+/* board init code might need to reserve hwspinlocks for predefined purposes */
+postcore_initcall(qcom_hwspinlock_init);
+
+static void __exit qcom_hwspinlock_exit(void)
+{
+	platform_driver_unregister(&qcom_hwspinlock_driver);
+}
+module_exit(qcom_hwspinlock_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware spinlock driver for Qualcomm SoCs");
-- 
1.8.2.2


  reply	other threads:[~2015-03-24 17:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-24 17:11 [PATCH v8 1/2] DT: hwspinlock: Add binding documentation for Qualcomm hwmutex Bjorn Andersson
2015-03-24 17:11 ` Bjorn Andersson
2015-03-24 17:11 ` Bjorn Andersson [this message]
2015-03-24 17:11   ` [PATCH v8 2/2] hwspinlock: qcom: Add support for Qualcomm HW Mutex block Bjorn Andersson
2015-05-02  7:57 ` [PATCH v8 1/2] DT: hwspinlock: Add binding documentation for Qualcomm hwmutex Ohad Ben-Cohen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1427217065-17186-2-git-send-email-bjorn.andersson@sonymobile.com \
    --to=bjorn.andersson@sonymobile.com \
    --cc=agross@codeaurora.org \
    --cc=jhugo@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ohad@wizery.com \
    --cc=s-anna@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.