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