xref: /openbmc/u-boot/drivers/core/device.c (revision cf659819)
1 /*
2  * Device manager
3  *
4  * Copyright (c) 2013 Google, Inc
5  *
6  * (C) Copyright 2012
7  * Pavel Herrmann <morpheus.ibis@gmail.com>
8  *
9  * SPDX-License-Identifier:	GPL-2.0+
10  */
11 
12 #include <common.h>
13 #include <fdtdec.h>
14 #include <malloc.h>
15 #include <dm/device.h>
16 #include <dm/device-internal.h>
17 #include <dm/lists.h>
18 #include <dm/platdata.h>
19 #include <dm/uclass.h>
20 #include <dm/uclass-internal.h>
21 #include <dm/util.h>
22 #include <linux/err.h>
23 #include <linux/list.h>
24 
25 DECLARE_GLOBAL_DATA_PTR;
26 
27 /**
28  * device_chld_unbind() - Unbind all device's children from the device
29  *
30  * On error, the function continues to unbind all children, and reports the
31  * first error.
32  *
33  * @dev:	The device that is to be stripped of its children
34  * @return 0 on success, -ve on error
35  */
36 static int device_chld_unbind(struct udevice *dev)
37 {
38 	struct udevice *pos, *n;
39 	int ret, saved_ret = 0;
40 
41 	assert(dev);
42 
43 	list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
44 		ret = device_unbind(pos);
45 		if (ret && !saved_ret)
46 			saved_ret = ret;
47 	}
48 
49 	return saved_ret;
50 }
51 
52 /**
53  * device_chld_remove() - Stop all device's children
54  * @dev:	The device whose children are to be removed
55  * @return 0 on success, -ve on error
56  */
57 static int device_chld_remove(struct udevice *dev)
58 {
59 	struct udevice *pos, *n;
60 	int ret;
61 
62 	assert(dev);
63 
64 	list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
65 		ret = device_remove(pos);
66 		if (ret)
67 			return ret;
68 	}
69 
70 	return 0;
71 }
72 
73 int device_bind(struct udevice *parent, struct driver *drv, const char *name,
74 		void *platdata, int of_offset, struct udevice **devp)
75 {
76 	struct udevice *dev;
77 	struct uclass *uc;
78 	int ret = 0;
79 
80 	*devp = NULL;
81 	if (!name)
82 		return -EINVAL;
83 
84 	ret = uclass_get(drv->id, &uc);
85 	if (ret)
86 		return ret;
87 
88 	dev = calloc(1, sizeof(struct udevice));
89 	if (!dev)
90 		return -ENOMEM;
91 
92 	INIT_LIST_HEAD(&dev->sibling_node);
93 	INIT_LIST_HEAD(&dev->child_head);
94 	INIT_LIST_HEAD(&dev->uclass_node);
95 	dev->platdata = platdata;
96 	dev->name = name;
97 	dev->of_offset = of_offset;
98 	dev->parent = parent;
99 	dev->driver = drv;
100 	dev->uclass = uc;
101 
102 	/*
103 	 * For some devices, such as a SPI or I2C bus, the 'reg' property
104 	 * is a reasonable indicator of the sequence number. But if there is
105 	 * an alias, we use that in preference. In any case, this is just
106 	 * a 'requested' sequence, and will be resolved (and ->seq updated)
107 	 * when the device is probed.
108 	 */
109 	dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1);
110 	dev->seq = -1;
111 	if (uc->uc_drv->name && of_offset != -1) {
112 		fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset,
113 				     &dev->req_seq);
114 	}
115 
116 	if (!dev->platdata && drv->platdata_auto_alloc_size)
117 		dev->flags |= DM_FLAG_ALLOC_PDATA;
118 
119 	/* put dev into parent's successor list */
120 	if (parent)
121 		list_add_tail(&dev->sibling_node, &parent->child_head);
122 
123 	ret = uclass_bind_device(dev);
124 	if (ret)
125 		goto fail_bind;
126 
127 	/* if we fail to bind we remove device from successors and free it */
128 	if (drv->bind) {
129 		ret = drv->bind(dev);
130 		if (ret) {
131 			if (uclass_unbind_device(dev)) {
132 				dm_warn("Failed to unbind dev '%s' on error path\n",
133 					dev->name);
134 			}
135 			goto fail_bind;
136 		}
137 	}
138 	if (parent)
139 		dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
140 	*devp = dev;
141 
142 	return 0;
143 
144 fail_bind:
145 	list_del(&dev->sibling_node);
146 	free(dev);
147 	return ret;
148 }
149 
150 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
151 			const struct driver_info *info, struct udevice **devp)
152 {
153 	struct driver *drv;
154 
155 	drv = lists_driver_lookup_name(info->name);
156 	if (!drv)
157 		return -ENOENT;
158 	if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
159 		return -EPERM;
160 
161 	return device_bind(parent, drv, info->name, (void *)info->platdata,
162 			   -1, devp);
163 }
164 
165 int device_unbind(struct udevice *dev)
166 {
167 	struct driver *drv;
168 	int ret;
169 
170 	if (!dev)
171 		return -EINVAL;
172 
173 	if (dev->flags & DM_FLAG_ACTIVATED)
174 		return -EINVAL;
175 
176 	drv = dev->driver;
177 	assert(drv);
178 
179 	if (drv->unbind) {
180 		ret = drv->unbind(dev);
181 		if (ret)
182 			return ret;
183 	}
184 
185 	ret = device_chld_unbind(dev);
186 	if (ret)
187 		return ret;
188 
189 	ret = uclass_unbind_device(dev);
190 	if (ret)
191 		return ret;
192 
193 	if (dev->parent)
194 		list_del(&dev->sibling_node);
195 	free(dev);
196 
197 	return 0;
198 }
199 
200 /**
201  * device_free() - Free memory buffers allocated by a device
202  * @dev:	Device that is to be started
203  */
204 static void device_free(struct udevice *dev)
205 {
206 	int size;
207 
208 	if (dev->driver->priv_auto_alloc_size) {
209 		free(dev->priv);
210 		dev->priv = NULL;
211 	}
212 	if (dev->flags & DM_FLAG_ALLOC_PDATA) {
213 		free(dev->platdata);
214 		dev->platdata = NULL;
215 	}
216 	size = dev->uclass->uc_drv->per_device_auto_alloc_size;
217 	if (size) {
218 		free(dev->uclass_priv);
219 		dev->uclass_priv = NULL;
220 	}
221 	if (dev->parent) {
222 		size = dev->parent->driver->per_child_auto_alloc_size;
223 		if (size) {
224 			free(dev->parent_priv);
225 			dev->parent_priv = NULL;
226 		}
227 	}
228 }
229 
230 int device_probe(struct udevice *dev)
231 {
232 	struct driver *drv;
233 	int size = 0;
234 	int ret;
235 	int seq;
236 
237 	if (!dev)
238 		return -EINVAL;
239 
240 	if (dev->flags & DM_FLAG_ACTIVATED)
241 		return 0;
242 
243 	drv = dev->driver;
244 	assert(drv);
245 
246 	/* Allocate private data and platdata if requested */
247 	if (drv->priv_auto_alloc_size) {
248 		dev->priv = calloc(1, drv->priv_auto_alloc_size);
249 		if (!dev->priv) {
250 			ret = -ENOMEM;
251 			goto fail;
252 		}
253 	}
254 	/* Allocate private data if requested */
255 	if (dev->flags & DM_FLAG_ALLOC_PDATA) {
256 		dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
257 		if (!dev->platdata) {
258 			ret = -ENOMEM;
259 			goto fail;
260 		}
261 	}
262 	size = dev->uclass->uc_drv->per_device_auto_alloc_size;
263 	if (size) {
264 		dev->uclass_priv = calloc(1, size);
265 		if (!dev->uclass_priv) {
266 			ret = -ENOMEM;
267 			goto fail;
268 		}
269 	}
270 
271 	/* Ensure all parents are probed */
272 	if (dev->parent) {
273 		size = dev->parent->driver->per_child_auto_alloc_size;
274 		if (size) {
275 			dev->parent_priv = calloc(1, size);
276 			if (!dev->parent_priv) {
277 				ret = -ENOMEM;
278 				goto fail;
279 			}
280 		}
281 
282 		ret = device_probe(dev->parent);
283 		if (ret)
284 			goto fail;
285 	}
286 
287 	seq = uclass_resolve_seq(dev);
288 	if (seq < 0) {
289 		ret = seq;
290 		goto fail;
291 	}
292 	dev->seq = seq;
293 
294 	if (dev->parent && dev->parent->driver->child_pre_probe) {
295 		ret = dev->parent->driver->child_pre_probe(dev);
296 		if (ret)
297 			goto fail;
298 	}
299 
300 	if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
301 		ret = drv->ofdata_to_platdata(dev);
302 		if (ret)
303 			goto fail;
304 	}
305 
306 	if (drv->probe) {
307 		ret = drv->probe(dev);
308 		if (ret)
309 			goto fail;
310 	}
311 
312 	dev->flags |= DM_FLAG_ACTIVATED;
313 
314 	ret = uclass_post_probe_device(dev);
315 	if (ret) {
316 		dev->flags &= ~DM_FLAG_ACTIVATED;
317 		goto fail_uclass;
318 	}
319 
320 	return 0;
321 fail_uclass:
322 	if (device_remove(dev)) {
323 		dm_warn("%s: Device '%s' failed to remove on error path\n",
324 			__func__, dev->name);
325 	}
326 fail:
327 	dev->seq = -1;
328 	device_free(dev);
329 
330 	return ret;
331 }
332 
333 int device_remove(struct udevice *dev)
334 {
335 	struct driver *drv;
336 	int ret;
337 
338 	if (!dev)
339 		return -EINVAL;
340 
341 	if (!(dev->flags & DM_FLAG_ACTIVATED))
342 		return 0;
343 
344 	drv = dev->driver;
345 	assert(drv);
346 
347 	ret = uclass_pre_remove_device(dev);
348 	if (ret)
349 		return ret;
350 
351 	ret = device_chld_remove(dev);
352 	if (ret)
353 		goto err;
354 
355 	if (drv->remove) {
356 		ret = drv->remove(dev);
357 		if (ret)
358 			goto err_remove;
359 	}
360 
361 	if (dev->parent && dev->parent->driver->child_post_remove) {
362 		ret = dev->parent->driver->child_post_remove(dev);
363 		if (ret) {
364 			dm_warn("%s: Device '%s' failed child_post_remove()",
365 				__func__, dev->name);
366 		}
367 	}
368 
369 	device_free(dev);
370 
371 	dev->seq = -1;
372 	dev->flags &= ~DM_FLAG_ACTIVATED;
373 
374 	return ret;
375 
376 err_remove:
377 	/* We can't put the children back */
378 	dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
379 		__func__, dev->name);
380 err:
381 	ret = uclass_post_probe_device(dev);
382 	if (ret) {
383 		dm_warn("%s: Device '%s' failed to post_probe on error path\n",
384 			__func__, dev->name);
385 	}
386 
387 	return ret;
388 }
389 
390 void *dev_get_platdata(struct udevice *dev)
391 {
392 	if (!dev) {
393 		dm_warn("%s: null device", __func__);
394 		return NULL;
395 	}
396 
397 	return dev->platdata;
398 }
399 
400 void *dev_get_priv(struct udevice *dev)
401 {
402 	if (!dev) {
403 		dm_warn("%s: null device", __func__);
404 		return NULL;
405 	}
406 
407 	return dev->priv;
408 }
409 
410 void *dev_get_parentdata(struct udevice *dev)
411 {
412 	if (!dev) {
413 		dm_warn("%s: null device", __func__);
414 		return NULL;
415 	}
416 
417 	return dev->parent_priv;
418 }
419 
420 static int device_get_device_tail(struct udevice *dev, int ret,
421 				  struct udevice **devp)
422 {
423 	if (ret)
424 		return ret;
425 
426 	ret = device_probe(dev);
427 	if (ret)
428 		return ret;
429 
430 	*devp = dev;
431 
432 	return 0;
433 }
434 
435 int device_get_child(struct udevice *parent, int index, struct udevice **devp)
436 {
437 	struct udevice *dev;
438 
439 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
440 		if (!index--)
441 			return device_get_device_tail(dev, 0, devp);
442 	}
443 
444 	return -ENODEV;
445 }
446 
447 int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
448 			     bool find_req_seq, struct udevice **devp)
449 {
450 	struct udevice *dev;
451 
452 	*devp = NULL;
453 	if (seq_or_req_seq == -1)
454 		return -ENODEV;
455 
456 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
457 		if ((find_req_seq ? dev->req_seq : dev->seq) ==
458 				seq_or_req_seq) {
459 			*devp = dev;
460 			return 0;
461 		}
462 	}
463 
464 	return -ENODEV;
465 }
466 
467 int device_get_child_by_seq(struct udevice *parent, int seq,
468 			    struct udevice **devp)
469 {
470 	struct udevice *dev;
471 	int ret;
472 
473 	*devp = NULL;
474 	ret = device_find_child_by_seq(parent, seq, false, &dev);
475 	if (ret == -ENODEV) {
476 		/*
477 		 * We didn't find it in probed devices. See if there is one
478 		 * that will request this seq if probed.
479 		 */
480 		ret = device_find_child_by_seq(parent, seq, true, &dev);
481 	}
482 	return device_get_device_tail(dev, ret, devp);
483 }
484 
485 int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
486 				   struct udevice **devp)
487 {
488 	struct udevice *dev;
489 
490 	*devp = NULL;
491 
492 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
493 		if (dev->of_offset == of_offset) {
494 			*devp = dev;
495 			return 0;
496 		}
497 	}
498 
499 	return -ENODEV;
500 }
501 
502 int device_get_child_by_of_offset(struct udevice *parent, int seq,
503 				  struct udevice **devp)
504 {
505 	struct udevice *dev;
506 	int ret;
507 
508 	*devp = NULL;
509 	ret = device_find_child_by_of_offset(parent, seq, &dev);
510 	return device_get_device_tail(dev, ret, devp);
511 }
512