ARM: dts: npcm8xx: add npcm845 function node
[platform/kernel/u-boot.git] / drivers / reset / reset-uclass.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016, NVIDIA CORPORATION.
4  */
5
6 #define LOG_CATEGORY UCLASS_RESET
7
8 #include <common.h>
9 #include <dm.h>
10 #include <fdtdec.h>
11 #include <log.h>
12 #include <malloc.h>
13 #include <reset.h>
14 #include <reset-uclass.h>
15 #include <dm/devres.h>
16 #include <dm/lists.h>
17
18 static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
19 {
20         return (struct reset_ops *)dev->driver->ops;
21 }
22
23 static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
24                                   struct ofnode_phandle_args *args)
25 {
26         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
27
28         if (args->args_count != 1) {
29                 debug("Invalid args_count: %d\n", args->args_count);
30                 return -EINVAL;
31         }
32
33         reset_ctl->id = args->args[0];
34
35         return 0;
36 }
37
38 static int reset_get_by_index_tail(int ret, ofnode node,
39                                    struct ofnode_phandle_args *args,
40                                    const char *list_name, int index,
41                                    struct reset_ctl *reset_ctl)
42 {
43         struct udevice *dev_reset;
44         struct reset_ops *ops;
45
46         assert(reset_ctl);
47         reset_ctl->dev = NULL;
48         if (ret)
49                 return ret;
50
51         ret = uclass_get_device_by_ofnode(UCLASS_RESET, args->node,
52                                           &dev_reset);
53         if (ret) {
54                 debug("%s: uclass_get_device_by_ofnode() failed: %d\n",
55                       __func__, ret);
56                 debug("%s %d\n", ofnode_get_name(args->node), args->args[0]);
57                 return ret;
58         }
59         ops = reset_dev_ops(dev_reset);
60
61         reset_ctl->dev = dev_reset;
62         if (ops->of_xlate)
63                 ret = ops->of_xlate(reset_ctl, args);
64         else
65                 ret = reset_of_xlate_default(reset_ctl, args);
66         if (ret) {
67                 debug("of_xlate() failed: %d\n", ret);
68                 return ret;
69         }
70
71         ret = ops->request ? ops->request(reset_ctl) : 0;
72         if (ret) {
73                 debug("ops->request() failed: %d\n", ret);
74                 return ret;
75         }
76
77         return 0;
78 }
79
80 int reset_get_by_index(struct udevice *dev, int index,
81                        struct reset_ctl *reset_ctl)
82 {
83         struct ofnode_phandle_args args;
84         int ret;
85
86         ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
87                                          index, &args);
88
89         return reset_get_by_index_tail(ret, dev_ofnode(dev), &args, "resets",
90                                        index > 0, reset_ctl);
91 }
92
93 int reset_get_by_index_nodev(ofnode node, int index,
94                              struct reset_ctl *reset_ctl)
95 {
96         struct ofnode_phandle_args args;
97         int ret;
98
99         ret = ofnode_parse_phandle_with_args(node, "resets", "#reset-cells", 0,
100                                              index, &args);
101
102         return reset_get_by_index_tail(ret, node, &args, "resets",
103                                        index > 0, reset_ctl);
104 }
105
106 static int __reset_get_bulk(struct udevice *dev, ofnode node,
107                             struct reset_ctl_bulk *bulk)
108 {
109         int i, ret, err, count;
110
111         bulk->count = 0;
112
113         count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells",
114                                                0);
115         if (count < 1)
116                 return count;
117
118         bulk->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
119                                     GFP_KERNEL);
120         if (!bulk->resets)
121                 return -ENOMEM;
122
123         for (i = 0; i < count; i++) {
124                 ret = reset_get_by_index_nodev(node, i, &bulk->resets[i]);
125                 if (ret < 0)
126                         goto bulk_get_err;
127
128                 ++bulk->count;
129         }
130
131         return 0;
132
133 bulk_get_err:
134         err = reset_release_all(bulk->resets, bulk->count);
135         if (err)
136                 debug("%s: could release all resets for %p\n",
137                       __func__, dev);
138
139         return ret;
140 }
141
142 int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk)
143 {
144         return __reset_get_bulk(dev, dev_ofnode(dev), bulk);
145 }
146
147 int reset_get_by_name(struct udevice *dev, const char *name,
148                      struct reset_ctl *reset_ctl)
149 {
150         int index;
151
152         debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
153               reset_ctl);
154         reset_ctl->dev = NULL;
155
156         index = dev_read_stringlist_search(dev, "reset-names", name);
157         if (index < 0) {
158                 debug("fdt_stringlist_search() failed: %d\n", index);
159                 return index;
160         }
161
162         return reset_get_by_index(dev, index, reset_ctl);
163 }
164
165 int reset_request(struct reset_ctl *reset_ctl)
166 {
167         struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
168
169         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
170
171         return ops->request ? ops->request(reset_ctl) : 0;
172 }
173
174 int reset_free(struct reset_ctl *reset_ctl)
175 {
176         struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
177
178         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
179
180         return ops->rfree ? ops->rfree(reset_ctl) : 0;
181 }
182
183 int reset_assert(struct reset_ctl *reset_ctl)
184 {
185         struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
186
187         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
188
189         return ops->rst_assert ? ops->rst_assert(reset_ctl) : 0;
190 }
191
192 int reset_assert_bulk(struct reset_ctl_bulk *bulk)
193 {
194         int i, ret;
195
196         for (i = 0; i < bulk->count; i++) {
197                 ret = reset_assert(&bulk->resets[i]);
198                 if (ret < 0)
199                         return ret;
200         }
201
202         return 0;
203 }
204
205 int reset_deassert(struct reset_ctl *reset_ctl)
206 {
207         struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
208
209         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
210
211         return ops->rst_deassert ? ops->rst_deassert(reset_ctl) : 0;
212 }
213
214 int reset_deassert_bulk(struct reset_ctl_bulk *bulk)
215 {
216         int i, ret;
217
218         for (i = 0; i < bulk->count; i++) {
219                 ret = reset_deassert(&bulk->resets[i]);
220                 if (ret < 0)
221                         return ret;
222         }
223
224         return 0;
225 }
226
227 int reset_status(struct reset_ctl *reset_ctl)
228 {
229         struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
230
231         debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
232
233         return ops->rst_status ? ops->rst_status(reset_ctl) : 0;
234 }
235
236 int reset_release_all(struct reset_ctl *reset_ctl, int count)
237 {
238         int i, ret;
239
240         for (i = 0; i < count; i++) {
241                 debug("%s(reset_ctl[%d]=%p)\n", __func__, i, &reset_ctl[i]);
242
243                 /* check if reset has been previously requested */
244                 if (!reset_ctl[i].dev)
245                         continue;
246
247                 ret = reset_assert(&reset_ctl[i]);
248                 if (ret)
249                         return ret;
250
251                 ret = reset_free(&reset_ctl[i]);
252                 if (ret)
253                         return ret;
254         }
255
256         return 0;
257 }
258
259 static void devm_reset_release(struct udevice *dev, void *res)
260 {
261         reset_free(res);
262 }
263
264 struct reset_ctl *devm_reset_control_get_by_index(struct udevice *dev,
265                                                   int index)
266 {
267         int rc;
268         struct reset_ctl *reset_ctl;
269
270         reset_ctl = devres_alloc(devm_reset_release, sizeof(struct reset_ctl),
271                                  __GFP_ZERO);
272         if (unlikely(!reset_ctl))
273                 return ERR_PTR(-ENOMEM);
274
275         rc = reset_get_by_index(dev, index, reset_ctl);
276         if (rc)
277                 return ERR_PTR(rc);
278
279         devres_add(dev, reset_ctl);
280         return reset_ctl;
281 }
282
283 struct reset_ctl *devm_reset_control_get(struct udevice *dev, const char *id)
284 {
285         int rc;
286         struct reset_ctl *reset_ctl;
287
288         reset_ctl = devres_alloc(devm_reset_release, sizeof(struct reset_ctl),
289                                  __GFP_ZERO);
290         if (unlikely(!reset_ctl))
291                 return ERR_PTR(-ENOMEM);
292
293         rc = reset_get_by_name(dev, id, reset_ctl);
294         if (rc)
295                 return ERR_PTR(rc);
296
297         devres_add(dev, reset_ctl);
298         return reset_ctl;
299 }
300
301 struct reset_ctl *devm_reset_control_get_optional(struct udevice *dev,
302                                                   const char *id)
303 {
304         struct reset_ctl *r = devm_reset_control_get(dev, id);
305
306         if (IS_ERR(r))
307                 return NULL;
308
309         return r;
310 }
311
312 static void devm_reset_bulk_release(struct udevice *dev, void *res)
313 {
314         struct reset_ctl_bulk *bulk = res;
315
316         reset_release_all(bulk->resets, bulk->count);
317 }
318
319 struct reset_ctl_bulk *devm_reset_bulk_get_by_node(struct udevice *dev,
320                                                    ofnode node)
321 {
322         int rc;
323         struct reset_ctl_bulk *bulk;
324
325         bulk = devres_alloc(devm_reset_bulk_release,
326                             sizeof(struct reset_ctl_bulk),
327                             __GFP_ZERO);
328
329         /* this looks like a leak, but devres takes care of it */
330         if (unlikely(!bulk))
331                 return ERR_PTR(-ENOMEM);
332
333         rc = __reset_get_bulk(dev, node, bulk);
334         if (rc)
335                 return ERR_PTR(rc);
336
337         devres_add(dev, bulk);
338         return bulk;
339 }
340
341 struct reset_ctl_bulk *devm_reset_bulk_get_optional_by_node(struct udevice *dev,
342                                                             ofnode node)
343 {
344         struct reset_ctl_bulk *bulk;
345
346         bulk = devm_reset_bulk_get_by_node(dev, node);
347
348         if (IS_ERR(bulk))
349                 return NULL;
350
351         return bulk;
352 }
353
354 struct reset_ctl_bulk *devm_reset_bulk_get(struct udevice *dev)
355 {
356         return devm_reset_bulk_get_by_node(dev, dev_ofnode(dev));
357 }
358
359 struct reset_ctl_bulk *devm_reset_bulk_get_optional(struct udevice *dev)
360 {
361         return devm_reset_bulk_get_optional_by_node(dev, dev_ofnode(dev));
362 }
363
364 UCLASS_DRIVER(reset) = {
365         .id             = UCLASS_RESET,
366         .name           = "reset",
367 };