hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/nvmem/sc27xx-efuse.c
....@@ -4,12 +4,14 @@
44 #include <linux/hwspinlock.h>
55 #include <linux/module.h>
66 #include <linux/of.h>
7
+#include <linux/of_device.h>
78 #include <linux/platform_device.h>
89 #include <linux/regmap.h>
910 #include <linux/nvmem-provider.h>
1011
1112 /* PMIC global registers definition */
1213 #define SC27XX_MODULE_EN 0xc08
14
+#define SC2730_MODULE_EN 0x1808
1315 #define SC27XX_EFUSE_EN BIT(6)
1416
1517 /* Efuse controller registers definition */
....@@ -49,12 +51,29 @@
4951 #define SC27XX_EFUSE_POLL_TIMEOUT 3000000
5052 #define SC27XX_EFUSE_POLL_DELAY_US 10000
5153
54
+/*
55
+ * Since different PMICs of SC27xx series can have different
56
+ * address , we should save address in the device data structure.
57
+ */
58
+struct sc27xx_efuse_variant_data {
59
+ u32 module_en;
60
+};
61
+
5262 struct sc27xx_efuse {
5363 struct device *dev;
5464 struct regmap *regmap;
5565 struct hwspinlock *hwlock;
5666 struct mutex mutex;
5767 u32 base;
68
+ const struct sc27xx_efuse_variant_data *var_data;
69
+};
70
+
71
+static const struct sc27xx_efuse_variant_data sc2731_edata = {
72
+ .module_en = SC27XX_MODULE_EN,
73
+};
74
+
75
+static const struct sc27xx_efuse_variant_data sc2730_edata = {
76
+ .module_en = SC2730_MODULE_EN,
5877 };
5978
6079 /*
....@@ -106,10 +125,12 @@
106125 static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
107126 {
108127 struct sc27xx_efuse *efuse = context;
109
- u32 buf;
128
+ u32 buf, blk_index = offset / SC27XX_EFUSE_BLOCK_WIDTH;
129
+ u32 blk_offset = (offset % SC27XX_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE;
110130 int ret;
111131
112
- if (offset > SC27XX_EFUSE_BLOCK_MAX || bytes > SC27XX_EFUSE_BLOCK_WIDTH)
132
+ if (blk_index > SC27XX_EFUSE_BLOCK_MAX ||
133
+ bytes > SC27XX_EFUSE_BLOCK_WIDTH)
113134 return -EINVAL;
114135
115136 ret = sc27xx_efuse_lock(efuse);
....@@ -117,7 +138,7 @@
117138 return ret;
118139
119140 /* Enable the efuse controller. */
120
- ret = regmap_update_bits(efuse->regmap, SC27XX_MODULE_EN,
141
+ ret = regmap_update_bits(efuse->regmap, efuse->var_data->module_en,
121142 SC27XX_EFUSE_EN, SC27XX_EFUSE_EN);
122143 if (ret)
123144 goto unlock_efuse;
....@@ -133,7 +154,7 @@
133154 /* Set the block address to be read. */
134155 ret = regmap_write(efuse->regmap,
135156 efuse->base + SC27XX_EFUSE_BLOCK_INDEX,
136
- offset & SC27XX_EFUSE_BLOCK_MASK);
157
+ blk_index & SC27XX_EFUSE_BLOCK_MASK);
137158 if (ret)
138159 goto disable_efuse;
139160
....@@ -167,12 +188,14 @@
167188
168189 disable_efuse:
169190 /* Disable the efuse controller after reading. */
170
- regmap_update_bits(efuse->regmap, SC27XX_MODULE_EN, SC27XX_EFUSE_EN, 0);
191
+ regmap_update_bits(efuse->regmap, efuse->var_data->module_en, SC27XX_EFUSE_EN, 0);
171192 unlock_efuse:
172193 sc27xx_efuse_unlock(efuse);
173194
174
- if (!ret)
195
+ if (!ret) {
196
+ buf >>= blk_offset;
175197 memcpy(val, &buf, bytes);
198
+ }
176199
177200 return ret;
178201 }
....@@ -207,7 +230,7 @@
207230 return ret;
208231 }
209232
210
- efuse->hwlock = hwspin_lock_request_specific(ret);
233
+ efuse->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret);
211234 if (!efuse->hwlock) {
212235 dev_err(&pdev->dev, "failed to request hwspinlock\n");
213236 return -ENXIO;
....@@ -215,7 +238,7 @@
215238
216239 mutex_init(&efuse->mutex);
217240 efuse->dev = &pdev->dev;
218
- platform_set_drvdata(pdev, efuse);
241
+ efuse->var_data = of_device_get_match_data(&pdev->dev);
219242
220243 econfig.stride = 1;
221244 econfig.word_size = 1;
....@@ -228,29 +251,20 @@
228251 nvmem = devm_nvmem_register(&pdev->dev, &econfig);
229252 if (IS_ERR(nvmem)) {
230253 dev_err(&pdev->dev, "failed to register nvmem config\n");
231
- hwspin_lock_free(efuse->hwlock);
232254 return PTR_ERR(nvmem);
233255 }
234256
235257 return 0;
236258 }
237259
238
-static int sc27xx_efuse_remove(struct platform_device *pdev)
239
-{
240
- struct sc27xx_efuse *efuse = platform_get_drvdata(pdev);
241
-
242
- hwspin_lock_free(efuse->hwlock);
243
- return 0;
244
-}
245
-
246260 static const struct of_device_id sc27xx_efuse_of_match[] = {
247
- { .compatible = "sprd,sc2731-efuse" },
261
+ { .compatible = "sprd,sc2731-efuse", .data = &sc2731_edata},
262
+ { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
248263 { }
249264 };
250265
251266 static struct platform_driver sc27xx_efuse_driver = {
252267 .probe = sc27xx_efuse_probe,
253
- .remove = sc27xx_efuse_remove,
254268 .driver = {
255269 .name = "sc27xx-efuse",
256270 .of_match_table = sc27xx_efuse_of_match,