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