summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaolin Wang <baolin.wang@linaro.org>2017-12-25 01:37:10 -0500
committerMark Brown <broonie@kernel.org>2018-01-12 13:32:55 -0500
commit3bafc09e779710abaa7b836fe3bbeeeab7754c2b (patch)
tree1c78fbe67c3ca13bf771978047d3582079766415
parenta4887813c3a9481ab87c8a71ab1de50b975cc823 (diff)
mfd: syscon: Add hardware spinlock support
Some system control registers need hardware spinlock to synchronize between the multiple subsystems, so we should add hardware spinlock support for syscon. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.txt8
-rw-r--r--drivers/mfd/syscon.c19
2 files changed, 27 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
index 8b92d4576c42..25d9e9c2fd53 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.txt
+++ b/Documentation/devicetree/bindings/mfd/syscon.txt
@@ -16,9 +16,17 @@ Required properties:
16Optional property: 16Optional property:
17- reg-io-width: the size (in bytes) of the IO accesses that should be 17- reg-io-width: the size (in bytes) of the IO accesses that should be
18 performed on the device. 18 performed on the device.
19- hwlocks: reference to a phandle of a hardware spinlock provider node.
19 20
20Examples: 21Examples:
21gpr: iomuxc-gpr@20e0000 { 22gpr: iomuxc-gpr@20e0000 {
22 compatible = "fsl,imx6q-iomuxc-gpr", "syscon"; 23 compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
23 reg = <0x020e0000 0x38>; 24 reg = <0x020e0000 0x38>;
25 hwlocks = <&hwlock1 1>;
26};
27
28hwlock1: hwspinlock@40500000 {
29 ...
30 reg = <0x40500000 0x1000>;
31 #hwlock-cells = <1>;
24}; 32};
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index b93fe4c4957a..7eaa40bc703f 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/hwspinlock.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/list.h> 19#include <linux/list.h>
@@ -87,6 +88,24 @@ static struct syscon *of_syscon_register(struct device_node *np)
87 if (ret) 88 if (ret)
88 reg_io_width = 4; 89 reg_io_width = 4;
89 90
91 ret = of_hwspin_lock_get_id(np, 0);
92 if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
93 syscon_config.use_hwlock = true;
94 syscon_config.hwlock_id = ret;
95 syscon_config.hwlock_mode = HWLOCK_IRQSTATE;
96 } else if (ret < 0) {
97 switch (ret) {
98 case -ENOENT:
99 /* Ignore missing hwlock, it's optional. */
100 break;
101 default:
102 pr_err("Failed to retrieve valid hwlock: %d\n", ret);
103 /* fall-through */
104 case -EPROBE_DEFER:
105 goto err_regmap;
106 }
107 }
108
90 syscon_config.reg_stride = reg_io_width; 109 syscon_config.reg_stride = reg_io_width;
91 syscon_config.val_bits = reg_io_width * 8; 110 syscon_config.val_bits = reg_io_width * 8;
92 syscon_config.max_register = resource_size(&res) - reg_io_width; 111 syscon_config.max_register = resource_size(&res) - reg_io_width;