hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/hwspinlock/qcom_hwspinlock.c
....@@ -12,7 +12,6 @@
1212 #include <linux/of.h>
1313 #include <linux/of_device.h>
1414 #include <linux/platform_device.h>
15
-#include <linux/pm_runtime.h>
1615 #include <linux/regmap.h>
1716
1817 #include "hwspinlock_internal.h"
....@@ -71,40 +70,78 @@
7170 };
7271 MODULE_DEVICE_TABLE(of, qcom_hwspinlock_of_match);
7372
73
+static struct regmap *qcom_hwspinlock_probe_syscon(struct platform_device *pdev,
74
+ u32 *base, u32 *stride)
75
+{
76
+ struct device_node *syscon;
77
+ struct regmap *regmap;
78
+ int ret;
79
+
80
+ syscon = of_parse_phandle(pdev->dev.of_node, "syscon", 0);
81
+ if (!syscon)
82
+ return ERR_PTR(-ENODEV);
83
+
84
+ regmap = syscon_node_to_regmap(syscon);
85
+ of_node_put(syscon);
86
+ if (IS_ERR(regmap))
87
+ return regmap;
88
+
89
+ ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, base);
90
+ if (ret < 0) {
91
+ dev_err(&pdev->dev, "no offset in syscon\n");
92
+ return ERR_PTR(-EINVAL);
93
+ }
94
+
95
+ ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 2, stride);
96
+ if (ret < 0) {
97
+ dev_err(&pdev->dev, "no stride syscon\n");
98
+ return ERR_PTR(-EINVAL);
99
+ }
100
+
101
+ return regmap;
102
+}
103
+
104
+static const struct regmap_config tcsr_mutex_config = {
105
+ .reg_bits = 32,
106
+ .reg_stride = 4,
107
+ .val_bits = 32,
108
+ .max_register = 0x20000,
109
+ .fast_io = true,
110
+};
111
+
112
+static struct regmap *qcom_hwspinlock_probe_mmio(struct platform_device *pdev,
113
+ u32 *offset, u32 *stride)
114
+{
115
+ struct device *dev = &pdev->dev;
116
+ void __iomem *base;
117
+
118
+ /* All modern platform has offset 0 and stride of 4k */
119
+ *offset = 0;
120
+ *stride = 0x1000;
121
+
122
+ base = devm_platform_ioremap_resource(pdev, 0);
123
+ if (IS_ERR(base))
124
+ return ERR_CAST(base);
125
+
126
+ return devm_regmap_init_mmio(dev, base, &tcsr_mutex_config);
127
+}
128
+
74129 static int qcom_hwspinlock_probe(struct platform_device *pdev)
75130 {
76131 struct hwspinlock_device *bank;
77
- struct device_node *syscon;
78132 struct reg_field field;
79133 struct regmap *regmap;
80134 size_t array_size;
81135 u32 stride;
82136 u32 base;
83
- int ret;
84137 int i;
85138
86
- syscon = of_parse_phandle(pdev->dev.of_node, "syscon", 0);
87
- if (!syscon) {
88
- dev_err(&pdev->dev, "no syscon property\n");
89
- return -ENODEV;
90
- }
139
+ regmap = qcom_hwspinlock_probe_syscon(pdev, &base, &stride);
140
+ if (IS_ERR(regmap) && PTR_ERR(regmap) == -ENODEV)
141
+ regmap = qcom_hwspinlock_probe_mmio(pdev, &base, &stride);
91142
92
- regmap = syscon_node_to_regmap(syscon);
93
- of_node_put(syscon);
94143 if (IS_ERR(regmap))
95144 return PTR_ERR(regmap);
96
-
97
- ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, &base);
98
- if (ret < 0) {
99
- dev_err(&pdev->dev, "no offset in syscon\n");
100
- return -EINVAL;
101
- }
102
-
103
- ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 2, &stride);
104
- if (ret < 0) {
105
- dev_err(&pdev->dev, "no stride syscon\n");
106
- return -EINVAL;
107
- }
108145
109146 array_size = QCOM_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
110147 bank = devm_kzalloc(&pdev->dev, sizeof(*bank) + array_size, GFP_KERNEL);
....@@ -122,35 +159,12 @@
122159 regmap, field);
123160 }
124161
125
- pm_runtime_enable(&pdev->dev);
126
-
127
- ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
128
- 0, QCOM_MUTEX_NUM_LOCKS);
129
- if (ret)
130
- pm_runtime_disable(&pdev->dev);
131
-
132
- return ret;
133
-}
134
-
135
-static int qcom_hwspinlock_remove(struct platform_device *pdev)
136
-{
137
- struct hwspinlock_device *bank = platform_get_drvdata(pdev);
138
- int ret;
139
-
140
- ret = hwspin_lock_unregister(bank);
141
- if (ret) {
142
- dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
143
- return ret;
144
- }
145
-
146
- pm_runtime_disable(&pdev->dev);
147
-
148
- return 0;
162
+ return devm_hwspin_lock_register(&pdev->dev, bank, &qcom_hwspinlock_ops,
163
+ 0, QCOM_MUTEX_NUM_LOCKS);
149164 }
150165
151166 static struct platform_driver qcom_hwspinlock_driver = {
152167 .probe = qcom_hwspinlock_probe,
153
- .remove = qcom_hwspinlock_remove,
154168 .driver = {
155169 .name = "qcom_hwspinlock",
156170 .of_match_table = qcom_hwspinlock_of_match,