3b6e6e57f52b44f30f5e0513d082765128a92e87
[openwrt/staging/stintel.git] /
1 From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001
2 From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
3 Date: Sun, 11 Jun 2023 15:03:13 +0100
4 Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data
5
6 In preparation to support new Rockchip OTP memory devices with different
7 clock configurations and register layout, extend rockchip_data struct
8 with the related members: clks, num_clks, reg_read.
9
10 Additionally, to avoid managing redundant driver data, drop num_clks
11 member from rockchip_otp struct and update all references to point to
12 the equivalent member in rockchip_data.
13
14 Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
15 Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
16 Reviewed-by: Heiko Stuebner <heiko@sntech.de>
17 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
18 Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20 ---
21 drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++--------------
22 1 file changed, 49 insertions(+), 30 deletions(-)
23
24 --- a/drivers/nvmem/rockchip-otp.c
25 +++ b/drivers/nvmem/rockchip-otp.c
26 @@ -54,21 +54,19 @@
27
28 #define OTPC_TIMEOUT 10000
29
30 +struct rockchip_data {
31 + int size;
32 + const char * const *clks;
33 + int num_clks;
34 + nvmem_reg_read_t reg_read;
35 +};
36 +
37 struct rockchip_otp {
38 struct device *dev;
39 void __iomem *base;
40 - struct clk_bulk_data *clks;
41 - int num_clks;
42 + struct clk_bulk_data *clks;
43 struct reset_control *rst;
44 -};
45 -
46 -/* list of required clocks */
47 -static const char * const rockchip_otp_clocks[] = {
48 - "otp", "apb_pclk", "phy",
49 -};
50 -
51 -struct rockchip_data {
52 - int size;
53 + const struct rockchip_data *data;
54 };
55
56 static int rockchip_otp_reset(struct rockchip_otp *otp)
57 @@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc
58 return ret;
59 }
60
61 -static int rockchip_otp_read(void *context, unsigned int offset,
62 - void *val, size_t bytes)
63 +static int px30_otp_read(void *context, unsigned int offset,
64 + void *val, size_t bytes)
65 {
66 struct rockchip_otp *otp = context;
67 u8 *buf = val;
68 - int ret = 0;
69 -
70 - ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
71 - if (ret < 0) {
72 - dev_err(otp->dev, "failed to prepare/enable clks\n");
73 - return ret;
74 - }
75 + int ret;
76
77 ret = rockchip_otp_reset(otp);
78 if (ret) {
79 dev_err(otp->dev, "failed to reset otp phy\n");
80 - goto disable_clks;
81 + return ret;
82 }
83
84 ret = rockchip_otp_ecc_enable(otp, false);
85 if (ret < 0) {
86 dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
87 - goto disable_clks;
88 + return ret;
89 }
90
91 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
92 @@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte
93
94 read_end:
95 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
96 -disable_clks:
97 - clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
98 +
99 + return ret;
100 +}
101 +
102 +static int rockchip_otp_read(void *context, unsigned int offset,
103 + void *val, size_t bytes)
104 +{
105 + struct rockchip_otp *otp = context;
106 + int ret;
107 +
108 + if (!otp->data || !otp->data->reg_read)
109 + return -EINVAL;
110 +
111 + ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
112 + if (ret < 0) {
113 + dev_err(otp->dev, "failed to prepare/enable clks\n");
114 + return ret;
115 + }
116 +
117 + ret = otp->data->reg_read(context, offset, val, bytes);
118 +
119 + clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
120
121 return ret;
122 }
123 @@ -189,8 +201,15 @@ static struct nvmem_config otp_config =
124 .reg_read = rockchip_otp_read,
125 };
126
127 +static const char * const px30_otp_clocks[] = {
128 + "otp", "apb_pclk", "phy",
129 +};
130 +
131 static const struct rockchip_data px30_data = {
132 .size = 0x40,
133 + .clks = px30_otp_clocks,
134 + .num_clks = ARRAY_SIZE(px30_otp_clocks),
135 + .reg_read = px30_otp_read,
136 };
137
138 static const struct of_device_id rockchip_otp_match[] = {
139 @@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla
140 if (!otp)
141 return -ENOMEM;
142
143 + otp->data = data;
144 otp->dev = dev;
145 otp->base = devm_platform_ioremap_resource(pdev, 0);
146 if (IS_ERR(otp->base))
147 return PTR_ERR(otp->base);
148
149 - otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks);
150 - otp->clks = devm_kcalloc(dev, otp->num_clks,
151 - sizeof(*otp->clks), GFP_KERNEL);
152 + otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
153 + GFP_KERNEL);
154 if (!otp->clks)
155 return -ENOMEM;
156
157 - for (i = 0; i < otp->num_clks; ++i)
158 - otp->clks[i].id = rockchip_otp_clocks[i];
159 + for (i = 0; i < data->num_clks; ++i)
160 + otp->clks[i].id = data->clks[i];
161
162 - ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks);
163 + ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
164 if (ret)
165 return ret;
166