Home | History | Annotate | Download | only in core
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (c) 2013 Google, Inc
      4  *
      5  * (C) Copyright 2012
      6  * Pavel Herrmann <morpheus.ibis (at) gmail.com>
      7  */
      8 
      9 #include <common.h>
     10 #include <dm.h>
     11 #include <errno.h>
     12 #include <malloc.h>
     13 #include <dm/device.h>
     14 #include <dm/device-internal.h>
     15 #include <dm/lists.h>
     16 #include <dm/uclass.h>
     17 #include <dm/uclass-internal.h>
     18 #include <dm/util.h>
     19 
     20 DECLARE_GLOBAL_DATA_PTR;
     21 
     22 struct uclass *uclass_find(enum uclass_id key)
     23 {
     24 	struct uclass *uc;
     25 
     26 	if (!gd->dm_root)
     27 		return NULL;
     28 	/*
     29 	 * TODO(sjg (at) chromium.org): Optimise this, perhaps moving the found
     30 	 * node to the start of the list, or creating a linear array mapping
     31 	 * id to node.
     32 	 */
     33 	list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
     34 		if (uc->uc_drv->id == key)
     35 			return uc;
     36 	}
     37 
     38 	return NULL;
     39 }
     40 
     41 /**
     42  * uclass_add() - Create new uclass in list
     43  * @id: Id number to create
     44  * @ucp: Returns pointer to uclass, or NULL on error
     45  * @return 0 on success, -ve on error
     46  *
     47  * The new uclass is added to the list. There must be only one uclass for
     48  * each id.
     49  */
     50 static int uclass_add(enum uclass_id id, struct uclass **ucp)
     51 {
     52 	struct uclass_driver *uc_drv;
     53 	struct uclass *uc;
     54 	int ret;
     55 
     56 	*ucp = NULL;
     57 	uc_drv = lists_uclass_lookup(id);
     58 	if (!uc_drv) {
     59 		debug("Cannot find uclass for id %d: please add the UCLASS_DRIVER() declaration for this UCLASS_... id\n",
     60 		      id);
     61 		/*
     62 		 * Use a strange error to make this case easier to find. When
     63 		 * a uclass is not available it can prevent driver model from
     64 		 * starting up and this failure is otherwise hard to debug.
     65 		 */
     66 		return -EPFNOSUPPORT;
     67 	}
     68 	uc = calloc(1, sizeof(*uc));
     69 	if (!uc)
     70 		return -ENOMEM;
     71 	if (uc_drv->priv_auto_alloc_size) {
     72 		uc->priv = calloc(1, uc_drv->priv_auto_alloc_size);
     73 		if (!uc->priv) {
     74 			ret = -ENOMEM;
     75 			goto fail_mem;
     76 		}
     77 	}
     78 	uc->uc_drv = uc_drv;
     79 	INIT_LIST_HEAD(&uc->sibling_node);
     80 	INIT_LIST_HEAD(&uc->dev_head);
     81 	list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);
     82 
     83 	if (uc_drv->init) {
     84 		ret = uc_drv->init(uc);
     85 		if (ret)
     86 			goto fail;
     87 	}
     88 
     89 	*ucp = uc;
     90 
     91 	return 0;
     92 fail:
     93 	if (uc_drv->priv_auto_alloc_size) {
     94 		free(uc->priv);
     95 		uc->priv = NULL;
     96 	}
     97 	list_del(&uc->sibling_node);
     98 fail_mem:
     99 	free(uc);
    100 
    101 	return ret;
    102 }
    103 
    104 int uclass_destroy(struct uclass *uc)
    105 {
    106 	struct uclass_driver *uc_drv;
    107 	struct udevice *dev;
    108 	int ret;
    109 
    110 	/*
    111 	 * We cannot use list_for_each_entry_safe() here. If a device in this
    112 	 * uclass has a child device also in this uclass, it will be also be
    113 	 * unbound (by the recursion in the call to device_unbind() below).
    114 	 * We can loop until the list is empty.
    115 	 */
    116 	while (!list_empty(&uc->dev_head)) {
    117 		dev = list_first_entry(&uc->dev_head, struct udevice,
    118 				       uclass_node);
    119 		ret = device_remove(dev, DM_REMOVE_NORMAL);
    120 		if (ret)
    121 			return ret;
    122 		ret = device_unbind(dev);
    123 		if (ret)
    124 			return ret;
    125 	}
    126 
    127 	uc_drv = uc->uc_drv;
    128 	if (uc_drv->destroy)
    129 		uc_drv->destroy(uc);
    130 	list_del(&uc->sibling_node);
    131 	if (uc_drv->priv_auto_alloc_size)
    132 		free(uc->priv);
    133 	free(uc);
    134 
    135 	return 0;
    136 }
    137 
    138 int uclass_get(enum uclass_id id, struct uclass **ucp)
    139 {
    140 	struct uclass *uc;
    141 
    142 	*ucp = NULL;
    143 	uc = uclass_find(id);
    144 	if (!uc)
    145 		return uclass_add(id, ucp);
    146 	*ucp = uc;
    147 
    148 	return 0;
    149 }
    150 
    151 const char *uclass_get_name(enum uclass_id id)
    152 {
    153 	struct uclass *uc;
    154 
    155 	if (uclass_get(id, &uc))
    156 		return NULL;
    157 	return uc->uc_drv->name;
    158 }
    159 
    160 enum uclass_id uclass_get_by_name(const char *name)
    161 {
    162 	int i;
    163 
    164 	for (i = 0; i < UCLASS_COUNT; i++) {
    165 		struct uclass_driver *uc_drv = lists_uclass_lookup(i);
    166 
    167 		if (uc_drv && !strcmp(uc_drv->name, name))
    168 			return i;
    169 	}
    170 
    171 	return UCLASS_INVALID;
    172 }
    173 
    174 int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
    175 {
    176 	struct uclass *uc;
    177 	struct udevice *dev;
    178 	int ret;
    179 
    180 	*devp = NULL;
    181 	ret = uclass_get(id, &uc);
    182 	if (ret)
    183 		return ret;
    184 	if (list_empty(&uc->dev_head))
    185 		return -ENODEV;
    186 
    187 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    188 		if (!index--) {
    189 			*devp = dev;
    190 			return 0;
    191 		}
    192 	}
    193 
    194 	return -ENODEV;
    195 }
    196 
    197 int uclass_find_first_device(enum uclass_id id, struct udevice **devp)
    198 {
    199 	struct uclass *uc;
    200 	int ret;
    201 
    202 	*devp = NULL;
    203 	ret = uclass_get(id, &uc);
    204 	if (ret)
    205 		return ret;
    206 	if (list_empty(&uc->dev_head))
    207 		return 0;
    208 
    209 	*devp = list_first_entry(&uc->dev_head, struct udevice, uclass_node);
    210 
    211 	return 0;
    212 }
    213 
    214 int uclass_find_next_device(struct udevice **devp)
    215 {
    216 	struct udevice *dev = *devp;
    217 
    218 	*devp = NULL;
    219 	if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head))
    220 		return 0;
    221 
    222 	*devp = list_entry(dev->uclass_node.next, struct udevice, uclass_node);
    223 
    224 	return 0;
    225 }
    226 
    227 int uclass_find_device_by_name(enum uclass_id id, const char *name,
    228 			       struct udevice **devp)
    229 {
    230 	struct uclass *uc;
    231 	struct udevice *dev;
    232 	int ret;
    233 
    234 	*devp = NULL;
    235 	if (!name)
    236 		return -EINVAL;
    237 	ret = uclass_get(id, &uc);
    238 	if (ret)
    239 		return ret;
    240 
    241 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    242 		if (!strncmp(dev->name, name, strlen(name))) {
    243 			*devp = dev;
    244 			return 0;
    245 		}
    246 	}
    247 
    248 	return -ENODEV;
    249 }
    250 
    251 int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
    252 			      bool find_req_seq, struct udevice **devp)
    253 {
    254 	struct uclass *uc;
    255 	struct udevice *dev;
    256 	int ret;
    257 
    258 	*devp = NULL;
    259 	debug("%s: %d %d\n", __func__, find_req_seq, seq_or_req_seq);
    260 	if (seq_or_req_seq == -1)
    261 		return -ENODEV;
    262 	ret = uclass_get(id, &uc);
    263 	if (ret)
    264 		return ret;
    265 
    266 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    267 		debug("   - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name);
    268 		if ((find_req_seq ? dev->req_seq : dev->seq) ==
    269 				seq_or_req_seq) {
    270 			*devp = dev;
    271 			debug("   - found\n");
    272 			return 0;
    273 		}
    274 	}
    275 	debug("   - not found\n");
    276 
    277 	return -ENODEV;
    278 }
    279 
    280 int uclass_find_device_by_of_offset(enum uclass_id id, int node,
    281 				    struct udevice **devp)
    282 {
    283 	struct uclass *uc;
    284 	struct udevice *dev;
    285 	int ret;
    286 
    287 	*devp = NULL;
    288 	if (node < 0)
    289 		return -ENODEV;
    290 	ret = uclass_get(id, &uc);
    291 	if (ret)
    292 		return ret;
    293 
    294 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    295 		if (dev_of_offset(dev) == node) {
    296 			*devp = dev;
    297 			return 0;
    298 		}
    299 	}
    300 
    301 	return -ENODEV;
    302 }
    303 
    304 int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
    305 				 struct udevice **devp)
    306 {
    307 	struct uclass *uc;
    308 	struct udevice *dev;
    309 	int ret;
    310 
    311 	*devp = NULL;
    312 	if (!ofnode_valid(node))
    313 		return -ENODEV;
    314 	ret = uclass_get(id, &uc);
    315 	if (ret)
    316 		return ret;
    317 
    318 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    319 		if (ofnode_equal(dev_ofnode(dev), node)) {
    320 			*devp = dev;
    321 			return 0;
    322 		}
    323 	}
    324 
    325 	return -ENODEV;
    326 }
    327 
    328 #if CONFIG_IS_ENABLED(OF_CONTROL)
    329 static int uclass_find_device_by_phandle(enum uclass_id id,
    330 					 struct udevice *parent,
    331 					 const char *name,
    332 					 struct udevice **devp)
    333 {
    334 	struct udevice *dev;
    335 	struct uclass *uc;
    336 	int find_phandle;
    337 	int ret;
    338 
    339 	*devp = NULL;
    340 	find_phandle = dev_read_u32_default(parent, name, -1);
    341 	if (find_phandle <= 0)
    342 		return -ENOENT;
    343 	ret = uclass_get(id, &uc);
    344 	if (ret)
    345 		return ret;
    346 
    347 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    348 		uint phandle;
    349 
    350 		phandle = dev_read_phandle(dev);
    351 
    352 		if (phandle == find_phandle) {
    353 			*devp = dev;
    354 			return 0;
    355 		}
    356 	}
    357 
    358 	return -ENODEV;
    359 }
    360 #endif
    361 
    362 int uclass_get_device_by_driver(enum uclass_id id,
    363 				const struct driver *find_drv,
    364 				struct udevice **devp)
    365 {
    366 	struct udevice *dev;
    367 	struct uclass *uc;
    368 	int ret;
    369 
    370 	ret = uclass_get(id, &uc);
    371 	if (ret)
    372 		return ret;
    373 
    374 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    375 		if (dev->driver == find_drv)
    376 			return uclass_get_device_tail(dev, 0, devp);
    377 	}
    378 
    379 	return -ENODEV;
    380 }
    381 
    382 int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp)
    383 {
    384 	if (ret)
    385 		return ret;
    386 
    387 	assert(dev);
    388 	ret = device_probe(dev);
    389 	if (ret)
    390 		return ret;
    391 
    392 	*devp = dev;
    393 
    394 	return 0;
    395 }
    396 
    397 int uclass_get_device(enum uclass_id id, int index, struct udevice **devp)
    398 {
    399 	struct udevice *dev;
    400 	int ret;
    401 
    402 	*devp = NULL;
    403 	ret = uclass_find_device(id, index, &dev);
    404 	return uclass_get_device_tail(dev, ret, devp);
    405 }
    406 
    407 int uclass_get_device_by_name(enum uclass_id id, const char *name,
    408 			      struct udevice **devp)
    409 {
    410 	struct udevice *dev;
    411 	int ret;
    412 
    413 	*devp = NULL;
    414 	ret = uclass_find_device_by_name(id, name, &dev);
    415 	return uclass_get_device_tail(dev, ret, devp);
    416 }
    417 
    418 int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
    419 {
    420 	struct udevice *dev;
    421 	int ret;
    422 
    423 	*devp = NULL;
    424 	ret = uclass_find_device_by_seq(id, seq, false, &dev);
    425 	if (ret == -ENODEV) {
    426 		/*
    427 		 * We didn't find it in probed devices. See if there is one
    428 		 * that will request this seq if probed.
    429 		 */
    430 		ret = uclass_find_device_by_seq(id, seq, true, &dev);
    431 	}
    432 	return uclass_get_device_tail(dev, ret, devp);
    433 }
    434 
    435 int uclass_get_device_by_of_offset(enum uclass_id id, int node,
    436 				   struct udevice **devp)
    437 {
    438 	struct udevice *dev;
    439 	int ret;
    440 
    441 	*devp = NULL;
    442 	ret = uclass_find_device_by_of_offset(id, node, &dev);
    443 	return uclass_get_device_tail(dev, ret, devp);
    444 }
    445 
    446 int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
    447 				struct udevice **devp)
    448 {
    449 	struct udevice *dev;
    450 	int ret;
    451 
    452 	*devp = NULL;
    453 	ret = uclass_find_device_by_ofnode(id, node, &dev);
    454 
    455 	return uclass_get_device_tail(dev, ret, devp);
    456 }
    457 
    458 #if CONFIG_IS_ENABLED(OF_CONTROL)
    459 int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,
    460 				    struct udevice **devp)
    461 {
    462 	struct udevice *dev;
    463 	struct uclass *uc;
    464 	int ret;
    465 
    466 	*devp = NULL;
    467 	ret = uclass_get(id, &uc);
    468 	if (ret)
    469 		return ret;
    470 
    471 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
    472 		uint phandle;
    473 
    474 		phandle = dev_read_phandle(dev);
    475 
    476 		if (phandle == phandle_id) {
    477 			*devp = dev;
    478 			return uclass_get_device_tail(dev, ret, devp);
    479 		}
    480 	}
    481 
    482 	return -ENODEV;
    483 }
    484 
    485 int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
    486 				 const char *name, struct udevice **devp)
    487 {
    488 	struct udevice *dev;
    489 	int ret;
    490 
    491 	*devp = NULL;
    492 	ret = uclass_find_device_by_phandle(id, parent, name, &dev);
    493 	return uclass_get_device_tail(dev, ret, devp);
    494 }
    495 #endif
    496 
    497 int uclass_first_device(enum uclass_id id, struct udevice **devp)
    498 {
    499 	struct udevice *dev;
    500 	int ret;
    501 
    502 	*devp = NULL;
    503 	ret = uclass_find_first_device(id, &dev);
    504 	if (!dev)
    505 		return 0;
    506 	return uclass_get_device_tail(dev, ret, devp);
    507 }
    508 
    509 int uclass_first_device_err(enum uclass_id id, struct udevice **devp)
    510 {
    511 	int ret;
    512 
    513 	ret = uclass_first_device(id, devp);
    514 	if (ret)
    515 		return ret;
    516 	else if (!*devp)
    517 		return -ENODEV;
    518 
    519 	return 0;
    520 }
    521 
    522 int uclass_next_device(struct udevice **devp)
    523 {
    524 	struct udevice *dev = *devp;
    525 	int ret;
    526 
    527 	*devp = NULL;
    528 	ret = uclass_find_next_device(&dev);
    529 	if (!dev)
    530 		return 0;
    531 	return uclass_get_device_tail(dev, ret, devp);
    532 }
    533 
    534 int uclass_first_device_check(enum uclass_id id, struct udevice **devp)
    535 {
    536 	int ret;
    537 
    538 	*devp = NULL;
    539 	ret = uclass_find_first_device(id, devp);
    540 	if (ret)
    541 		return ret;
    542 	if (!*devp)
    543 		return 0;
    544 
    545 	return device_probe(*devp);
    546 }
    547 
    548 int uclass_next_device_check(struct udevice **devp)
    549 {
    550 	int ret;
    551 
    552 	ret = uclass_find_next_device(devp);
    553 	if (ret)
    554 		return ret;
    555 	if (!*devp)
    556 		return 0;
    557 
    558 	return device_probe(*devp);
    559 }
    560 
    561 int uclass_bind_device(struct udevice *dev)
    562 {
    563 	struct uclass *uc;
    564 	int ret;
    565 
    566 	uc = dev->uclass;
    567 	list_add_tail(&dev->uclass_node, &uc->dev_head);
    568 
    569 	if (dev->parent) {
    570 		struct uclass_driver *uc_drv = dev->parent->uclass->uc_drv;
    571 
    572 		if (uc_drv->child_post_bind) {
    573 			ret = uc_drv->child_post_bind(dev);
    574 			if (ret)
    575 				goto err;
    576 		}
    577 	}
    578 
    579 	return 0;
    580 err:
    581 	/* There is no need to undo the parent's post_bind call */
    582 	list_del(&dev->uclass_node);
    583 
    584 	return ret;
    585 }
    586 
    587 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
    588 int uclass_unbind_device(struct udevice *dev)
    589 {
    590 	struct uclass *uc;
    591 	int ret;
    592 
    593 	uc = dev->uclass;
    594 	if (uc->uc_drv->pre_unbind) {
    595 		ret = uc->uc_drv->pre_unbind(dev);
    596 		if (ret)
    597 			return ret;
    598 	}
    599 
    600 	list_del(&dev->uclass_node);
    601 	return 0;
    602 }
    603 #endif
    604 
    605 int uclass_resolve_seq(struct udevice *dev)
    606 {
    607 	struct udevice *dup;
    608 	int seq;
    609 	int ret;
    610 
    611 	assert(dev->seq == -1);
    612 	ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq,
    613 					false, &dup);
    614 	if (!ret) {
    615 		dm_warn("Device '%s': seq %d is in use by '%s'\n",
    616 			dev->name, dev->req_seq, dup->name);
    617 	} else if (ret == -ENODEV) {
    618 		/* Our requested sequence number is available */
    619 		if (dev->req_seq != -1)
    620 			return dev->req_seq;
    621 	} else {
    622 		return ret;
    623 	}
    624 
    625 	for (seq = 0; seq < DM_MAX_SEQ; seq++) {
    626 		ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq,
    627 						false, &dup);
    628 		if (ret == -ENODEV)
    629 			break;
    630 		if (ret)
    631 			return ret;
    632 	}
    633 	return seq;
    634 }
    635 
    636 int uclass_pre_probe_device(struct udevice *dev)
    637 {
    638 	struct uclass_driver *uc_drv;
    639 	int ret;
    640 
    641 	uc_drv = dev->uclass->uc_drv;
    642 	if (uc_drv->pre_probe) {
    643 		ret = uc_drv->pre_probe(dev);
    644 		if (ret)
    645 			return ret;
    646 	}
    647 
    648 	if (!dev->parent)
    649 		return 0;
    650 	uc_drv = dev->parent->uclass->uc_drv;
    651 	if (uc_drv->child_pre_probe)
    652 		return uc_drv->child_pre_probe(dev);
    653 
    654 	return 0;
    655 }
    656 
    657 int uclass_post_probe_device(struct udevice *dev)
    658 {
    659 	struct uclass_driver *uc_drv = dev->uclass->uc_drv;
    660 
    661 	if (uc_drv->post_probe)
    662 		return uc_drv->post_probe(dev);
    663 
    664 	return 0;
    665 }
    666 
    667 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
    668 int uclass_pre_remove_device(struct udevice *dev)
    669 {
    670 	struct uclass *uc;
    671 	int ret;
    672 
    673 	uc = dev->uclass;
    674 	if (uc->uc_drv->pre_remove) {
    675 		ret = uc->uc_drv->pre_remove(dev);
    676 		if (ret)
    677 			return ret;
    678 	}
    679 
    680 	return 0;
    681 }
    682 #endif
    683