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 
reset_dev_ops(struct udevice * dev)18 static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
19 {
20 	return (struct reset_ops *)dev->driver->ops;
21 }
22 
reset_of_xlate_default(struct reset_ctl * reset_ctl,struct ofnode_phandle_args * args)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("Invaild 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 
reset_get_by_index_tail(int ret,ofnode node,struct ofnode_phandle_args * args,const char * list_name,int index,struct reset_ctl * reset_ctl)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(reset_ctl);
72 	if (ret) {
73 		debug("ops->request() failed: %d\n", ret);
74 		return ret;
75 	}
76 
77 	return 0;
78 }
79 
reset_get_by_index(struct udevice * dev,int index,struct reset_ctl * reset_ctl)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 
reset_get_by_index_nodev(ofnode node,int index,struct reset_ctl * reset_ctl)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 
__reset_get_bulk(struct udevice * dev,ofnode node,struct reset_ctl_bulk * bulk)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 
reset_get_bulk(struct udevice * dev,struct reset_ctl_bulk * bulk)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 
reset_get_by_name(struct udevice * dev,const char * name,struct reset_ctl * reset_ctl)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 
reset_request(struct reset_ctl * reset_ctl)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(reset_ctl);
172 }
173 
reset_free(struct reset_ctl * reset_ctl)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(reset_ctl);
181 }
182 
reset_assert(struct reset_ctl * reset_ctl)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(reset_ctl);
190 }
191 
reset_assert_bulk(struct reset_ctl_bulk * bulk)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 
reset_deassert(struct reset_ctl * reset_ctl)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(reset_ctl);
212 }
213 
reset_deassert_bulk(struct reset_ctl_bulk * bulk)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 
reset_status(struct reset_ctl * reset_ctl)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(reset_ctl);
234 }
235 
reset_release_all(struct reset_ctl * reset_ctl,int count)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 
devm_reset_release(struct udevice * dev,void * res)259 static void devm_reset_release(struct udevice *dev, void *res)
260 {
261 	reset_free(res);
262 }
263 
devm_reset_control_get_by_index(struct udevice * dev,int index)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 
devm_reset_control_get(struct udevice * dev,const char * id)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 
devm_reset_control_get_optional(struct udevice * dev,const char * id)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 
devm_reset_bulk_release(struct udevice * dev,void * res)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 
devm_reset_bulk_get_by_node(struct udevice * dev,ofnode node)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 
devm_reset_bulk_get_optional_by_node(struct udevice * dev,ofnode node)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 
devm_reset_bulk_get(struct udevice * dev)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 
devm_reset_bulk_get_optional(struct udevice * dev)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 };
368