xref: /rk3399_rockchip-uboot/drivers/core/device.c (revision cc73d37b7f1edbbf03e2abcf5815bdd122e8baed)
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 int device_bind(struct udevice *parent, const struct driver *drv,
28 		const char *name, void *platdata, int of_offset,
29 		struct udevice **devp)
30 {
31 	struct udevice *dev;
32 	struct uclass *uc;
33 	int size, ret = 0;
34 
35 	*devp = NULL;
36 	if (!name)
37 		return -EINVAL;
38 
39 	ret = uclass_get(drv->id, &uc);
40 	if (ret)
41 		return ret;
42 
43 	dev = calloc(1, sizeof(struct udevice));
44 	if (!dev)
45 		return -ENOMEM;
46 
47 	INIT_LIST_HEAD(&dev->sibling_node);
48 	INIT_LIST_HEAD(&dev->child_head);
49 	INIT_LIST_HEAD(&dev->uclass_node);
50 	dev->platdata = platdata;
51 	dev->name = name;
52 	dev->of_offset = of_offset;
53 	dev->parent = parent;
54 	dev->driver = drv;
55 	dev->uclass = uc;
56 
57 	dev->seq = -1;
58 	dev->req_seq = -1;
59 #ifdef CONFIG_OF_CONTROL
60 	/*
61 	 * Some devices, such as a SPI bus, I2C bus and serial ports are
62 	 * numbered using aliases.
63 	 *
64 	 * This is just a 'requested' sequence, and will be
65 	 * resolved (and ->seq updated) when the device is probed.
66 	 */
67 	if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
68 		if (uc->uc_drv->name && of_offset != -1) {
69 			fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name,
70 					     of_offset, &dev->req_seq);
71 		}
72 	}
73 #endif
74 	if (!dev->platdata && drv->platdata_auto_alloc_size) {
75 		dev->flags |= DM_FLAG_ALLOC_PDATA;
76 		dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
77 		if (!dev->platdata) {
78 			ret = -ENOMEM;
79 			goto fail_alloc1;
80 		}
81 	}
82 
83 	size = uc->uc_drv->per_device_platdata_auto_alloc_size;
84 	if (size) {
85 		dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA;
86 		dev->uclass_platdata = calloc(1, size);
87 		if (!dev->uclass_platdata) {
88 			ret = -ENOMEM;
89 			goto fail_alloc2;
90 		}
91 	}
92 
93 	if (parent) {
94 		size = parent->driver->per_child_platdata_auto_alloc_size;
95 		if (!size) {
96 			size = parent->uclass->uc_drv->
97 					per_child_platdata_auto_alloc_size;
98 		}
99 		if (size) {
100 			dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA;
101 			dev->parent_platdata = calloc(1, size);
102 			if (!dev->parent_platdata) {
103 				ret = -ENOMEM;
104 				goto fail_alloc3;
105 			}
106 		}
107 	}
108 
109 	/* put dev into parent's successor list */
110 	if (parent)
111 		list_add_tail(&dev->sibling_node, &parent->child_head);
112 
113 	ret = uclass_bind_device(dev);
114 	if (ret)
115 		goto fail_uclass_bind;
116 
117 	/* if we fail to bind we remove device from successors and free it */
118 	if (drv->bind) {
119 		ret = drv->bind(dev);
120 		if (ret)
121 			goto fail_bind;
122 	}
123 	if (parent && parent->driver->child_post_bind) {
124 		ret = parent->driver->child_post_bind(dev);
125 		if (ret)
126 			goto fail_child_post_bind;
127 	}
128 
129 	if (parent)
130 		dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
131 	*devp = dev;
132 
133 	return 0;
134 
135 fail_child_post_bind:
136 	if (drv->unbind && drv->unbind(dev)) {
137 		dm_warn("unbind() method failed on dev '%s' on error path\n",
138 			dev->name);
139 	}
140 
141 fail_bind:
142 	if (uclass_unbind_device(dev)) {
143 		dm_warn("Failed to unbind dev '%s' on error path\n",
144 			dev->name);
145 	}
146 fail_uclass_bind:
147 	list_del(&dev->sibling_node);
148 	if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
149 		free(dev->parent_platdata);
150 		dev->parent_platdata = NULL;
151 	}
152 fail_alloc3:
153 	if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
154 		free(dev->uclass_platdata);
155 		dev->uclass_platdata = NULL;
156 	}
157 fail_alloc2:
158 	if (dev->flags & DM_FLAG_ALLOC_PDATA) {
159 		free(dev->platdata);
160 		dev->platdata = NULL;
161 	}
162 fail_alloc1:
163 	free(dev);
164 
165 	return ret;
166 }
167 
168 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
169 			const struct driver_info *info, struct udevice **devp)
170 {
171 	struct driver *drv;
172 
173 	drv = lists_driver_lookup_name(info->name);
174 	if (!drv)
175 		return -ENOENT;
176 	if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
177 		return -EPERM;
178 
179 	return device_bind(parent, drv, info->name, (void *)info->platdata,
180 			   -1, devp);
181 }
182 
183 static void *alloc_priv(int size, uint flags)
184 {
185 	void *priv;
186 
187 	if (flags & DM_FLAG_ALLOC_PRIV_DMA) {
188 		priv = memalign(ARCH_DMA_MINALIGN, size);
189 		if (priv)
190 			memset(priv, '\0', size);
191 	} else {
192 		priv = calloc(1, size);
193 	}
194 
195 	return priv;
196 }
197 
198 int device_probe_child(struct udevice *dev, void *parent_priv)
199 {
200 	const struct driver *drv;
201 	int size = 0;
202 	int ret;
203 	int seq;
204 
205 	if (!dev)
206 		return -EINVAL;
207 
208 	if (dev->flags & DM_FLAG_ACTIVATED)
209 		return 0;
210 
211 	drv = dev->driver;
212 	assert(drv);
213 
214 	/* Allocate private data if requested */
215 	if (drv->priv_auto_alloc_size) {
216 		dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
217 		if (!dev->priv) {
218 			ret = -ENOMEM;
219 			goto fail;
220 		}
221 	}
222 	/* Allocate private data if requested */
223 	size = dev->uclass->uc_drv->per_device_auto_alloc_size;
224 	if (size) {
225 		dev->uclass_priv = calloc(1, size);
226 		if (!dev->uclass_priv) {
227 			ret = -ENOMEM;
228 			goto fail;
229 		}
230 	}
231 
232 	/* Ensure all parents are probed */
233 	if (dev->parent) {
234 		size = dev->parent->driver->per_child_auto_alloc_size;
235 		if (!size) {
236 			size = dev->parent->uclass->uc_drv->
237 					per_child_auto_alloc_size;
238 		}
239 		if (size) {
240 			dev->parent_priv = alloc_priv(size, drv->flags);
241 			if (!dev->parent_priv) {
242 				ret = -ENOMEM;
243 				goto fail;
244 			}
245 			if (parent_priv)
246 				memcpy(dev->parent_priv, parent_priv, size);
247 		}
248 
249 		ret = device_probe(dev->parent);
250 		if (ret)
251 			goto fail;
252 	}
253 
254 	seq = uclass_resolve_seq(dev);
255 	if (seq < 0) {
256 		ret = seq;
257 		goto fail;
258 	}
259 	dev->seq = seq;
260 
261 	dev->flags |= DM_FLAG_ACTIVATED;
262 
263 	ret = uclass_pre_probe_device(dev);
264 	if (ret)
265 		goto fail;
266 
267 	if (dev->parent && dev->parent->driver->child_pre_probe) {
268 		ret = dev->parent->driver->child_pre_probe(dev);
269 		if (ret)
270 			goto fail;
271 	}
272 
273 	if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
274 		ret = drv->ofdata_to_platdata(dev);
275 		if (ret)
276 			goto fail;
277 	}
278 
279 	dev->flags |= DM_FLAG_ACTIVATED;
280 	if (drv->probe) {
281 		ret = drv->probe(dev);
282 		if (ret) {
283 			dev->flags &= ~DM_FLAG_ACTIVATED;
284 			goto fail;
285 		}
286 	}
287 
288 	ret = uclass_post_probe_device(dev);
289 	if (ret)
290 		goto fail_uclass;
291 
292 	return 0;
293 fail_uclass:
294 	if (device_remove(dev)) {
295 		dm_warn("%s: Device '%s' failed to remove on error path\n",
296 			__func__, dev->name);
297 	}
298 fail:
299 	dev->flags &= ~DM_FLAG_ACTIVATED;
300 
301 	dev->seq = -1;
302 	device_free(dev);
303 
304 	return ret;
305 }
306 
307 int device_probe(struct udevice *dev)
308 {
309 	return device_probe_child(dev, NULL);
310 }
311 
312 void *dev_get_platdata(struct udevice *dev)
313 {
314 	if (!dev) {
315 		dm_warn("%s: null device\n", __func__);
316 		return NULL;
317 	}
318 
319 	return dev->platdata;
320 }
321 
322 void *dev_get_parent_platdata(struct udevice *dev)
323 {
324 	if (!dev) {
325 		dm_warn("%s: null device", __func__);
326 		return NULL;
327 	}
328 
329 	return dev->parent_platdata;
330 }
331 
332 void *dev_get_uclass_platdata(struct udevice *dev)
333 {
334 	if (!dev) {
335 		dm_warn("%s: null device", __func__);
336 		return NULL;
337 	}
338 
339 	return dev->uclass_platdata;
340 }
341 
342 void *dev_get_priv(struct udevice *dev)
343 {
344 	if (!dev) {
345 		dm_warn("%s: null device\n", __func__);
346 		return NULL;
347 	}
348 
349 	return dev->priv;
350 }
351 
352 void *dev_get_uclass_priv(struct udevice *dev)
353 {
354 	if (!dev) {
355 		dm_warn("%s: null device\n", __func__);
356 		return NULL;
357 	}
358 
359 	return dev->uclass_priv;
360 }
361 
362 void *dev_get_parentdata(struct udevice *dev)
363 {
364 	if (!dev) {
365 		dm_warn("%s: null device\n", __func__);
366 		return NULL;
367 	}
368 
369 	return dev->parent_priv;
370 }
371 
372 static int device_get_device_tail(struct udevice *dev, int ret,
373 				  struct udevice **devp)
374 {
375 	if (ret)
376 		return ret;
377 
378 	ret = device_probe(dev);
379 	if (ret)
380 		return ret;
381 
382 	*devp = dev;
383 
384 	return 0;
385 }
386 
387 int device_get_child(struct udevice *parent, int index, struct udevice **devp)
388 {
389 	struct udevice *dev;
390 
391 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
392 		if (!index--)
393 			return device_get_device_tail(dev, 0, devp);
394 	}
395 
396 	return -ENODEV;
397 }
398 
399 int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
400 			     bool find_req_seq, struct udevice **devp)
401 {
402 	struct udevice *dev;
403 
404 	*devp = NULL;
405 	if (seq_or_req_seq == -1)
406 		return -ENODEV;
407 
408 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
409 		if ((find_req_seq ? dev->req_seq : dev->seq) ==
410 				seq_or_req_seq) {
411 			*devp = dev;
412 			return 0;
413 		}
414 	}
415 
416 	return -ENODEV;
417 }
418 
419 int device_get_child_by_seq(struct udevice *parent, int seq,
420 			    struct udevice **devp)
421 {
422 	struct udevice *dev;
423 	int ret;
424 
425 	*devp = NULL;
426 	ret = device_find_child_by_seq(parent, seq, false, &dev);
427 	if (ret == -ENODEV) {
428 		/*
429 		 * We didn't find it in probed devices. See if there is one
430 		 * that will request this seq if probed.
431 		 */
432 		ret = device_find_child_by_seq(parent, seq, true, &dev);
433 	}
434 	return device_get_device_tail(dev, ret, devp);
435 }
436 
437 int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
438 				   struct udevice **devp)
439 {
440 	struct udevice *dev;
441 
442 	*devp = NULL;
443 
444 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
445 		if (dev->of_offset == of_offset) {
446 			*devp = dev;
447 			return 0;
448 		}
449 	}
450 
451 	return -ENODEV;
452 }
453 
454 int device_get_child_by_of_offset(struct udevice *parent, int seq,
455 				  struct udevice **devp)
456 {
457 	struct udevice *dev;
458 	int ret;
459 
460 	*devp = NULL;
461 	ret = device_find_child_by_of_offset(parent, seq, &dev);
462 	return device_get_device_tail(dev, ret, devp);
463 }
464 
465 int device_find_first_child(struct udevice *parent, struct udevice **devp)
466 {
467 	if (list_empty(&parent->child_head)) {
468 		*devp = NULL;
469 	} else {
470 		*devp = list_first_entry(&parent->child_head, struct udevice,
471 					 sibling_node);
472 	}
473 
474 	return 0;
475 }
476 
477 int device_find_next_child(struct udevice **devp)
478 {
479 	struct udevice *dev = *devp;
480 	struct udevice *parent = dev->parent;
481 
482 	if (list_is_last(&dev->sibling_node, &parent->child_head)) {
483 		*devp = NULL;
484 	} else {
485 		*devp = list_entry(dev->sibling_node.next, struct udevice,
486 				   sibling_node);
487 	}
488 
489 	return 0;
490 }
491 
492 struct udevice *dev_get_parent(struct udevice *child)
493 {
494 	return child->parent;
495 }
496 
497 ulong dev_get_driver_data(struct udevice *dev)
498 {
499 	return dev->driver_data;
500 }
501 
502 const void *dev_get_driver_ops(struct udevice *dev)
503 {
504 	if (!dev || !dev->driver->ops)
505 		return NULL;
506 
507 	return dev->driver->ops;
508 }
509 
510 enum uclass_id device_get_uclass_id(struct udevice *dev)
511 {
512 	return dev->uclass->uc_drv->id;
513 }
514 
515 #ifdef CONFIG_OF_CONTROL
516 fdt_addr_t dev_get_addr(struct udevice *dev)
517 {
518 	return fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
519 }
520 #else
521 fdt_addr_t dev_get_addr(struct udevice *dev)
522 {
523 	return FDT_ADDR_T_NONE;
524 }
525 #endif
526 
527 bool device_has_children(struct udevice *dev)
528 {
529 	return !list_empty(&dev->child_head);
530 }
531 
532 bool device_has_active_children(struct udevice *dev)
533 {
534 	struct udevice *child;
535 
536 	for (device_find_first_child(dev, &child);
537 	     child;
538 	     device_find_next_child(&child)) {
539 		if (device_active(child))
540 			return true;
541 	}
542 
543 	return false;
544 }
545 
546 bool device_is_last_sibling(struct udevice *dev)
547 {
548 	struct udevice *parent = dev->parent;
549 
550 	if (!parent)
551 		return false;
552 	return list_is_last(&dev->sibling_node, &parent->child_head);
553 }
554