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