.. | .. |
---|
8 | 8 | * Copyright (c) 2006 Novell, Inc. |
---|
9 | 9 | */ |
---|
10 | 10 | |
---|
| 11 | +#include <linux/acpi.h> |
---|
11 | 12 | #include <linux/cpufreq.h> |
---|
12 | 13 | #include <linux/device.h> |
---|
13 | 14 | #include <linux/err.h> |
---|
.. | .. |
---|
25 | 26 | #include <linux/pm_runtime.h> |
---|
26 | 27 | #include <linux/netdevice.h> |
---|
27 | 28 | #include <linux/sched/signal.h> |
---|
| 29 | +#include <linux/sched/mm.h> |
---|
28 | 30 | #include <linux/sysfs.h> |
---|
29 | 31 | |
---|
30 | 32 | #include "base.h" |
---|
.. | .. |
---|
44 | 46 | #endif |
---|
45 | 47 | |
---|
46 | 48 | /* Device links support. */ |
---|
47 | | -static LIST_HEAD(wait_for_suppliers); |
---|
48 | | -static DEFINE_MUTEX(wfs_lock); |
---|
49 | 49 | static LIST_HEAD(deferred_sync); |
---|
50 | 50 | static unsigned int defer_sync_state_count = 1; |
---|
51 | | -static unsigned int defer_fw_devlink_count; |
---|
52 | | -static LIST_HEAD(deferred_fw_devlink); |
---|
53 | | -static DEFINE_MUTEX(defer_fw_devlink_lock); |
---|
| 51 | +static DEFINE_MUTEX(fwnode_link_lock); |
---|
| 52 | +static bool fw_devlink_is_permissive(void); |
---|
| 53 | + |
---|
| 54 | +/** |
---|
| 55 | + * fwnode_link_add - Create a link between two fwnode_handles. |
---|
| 56 | + * @con: Consumer end of the link. |
---|
| 57 | + * @sup: Supplier end of the link. |
---|
| 58 | + * |
---|
| 59 | + * Create a fwnode link between fwnode handles @con and @sup. The fwnode link |
---|
| 60 | + * represents the detail that the firmware lists @sup fwnode as supplying a |
---|
| 61 | + * resource to @con. |
---|
| 62 | + * |
---|
| 63 | + * The driver core will use the fwnode link to create a device link between the |
---|
| 64 | + * two device objects corresponding to @con and @sup when they are created. The |
---|
| 65 | + * driver core will automatically delete the fwnode link between @con and @sup |
---|
| 66 | + * after doing that. |
---|
| 67 | + * |
---|
| 68 | + * Attempts to create duplicate links between the same pair of fwnode handles |
---|
| 69 | + * are ignored and there is no reference counting. |
---|
| 70 | + */ |
---|
| 71 | +int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) |
---|
| 72 | +{ |
---|
| 73 | + struct fwnode_link *link; |
---|
| 74 | + int ret = 0; |
---|
| 75 | + |
---|
| 76 | + mutex_lock(&fwnode_link_lock); |
---|
| 77 | + |
---|
| 78 | + list_for_each_entry(link, &sup->consumers, s_hook) |
---|
| 79 | + if (link->consumer == con) |
---|
| 80 | + goto out; |
---|
| 81 | + |
---|
| 82 | + link = kzalloc(sizeof(*link), GFP_KERNEL); |
---|
| 83 | + if (!link) { |
---|
| 84 | + ret = -ENOMEM; |
---|
| 85 | + goto out; |
---|
| 86 | + } |
---|
| 87 | + |
---|
| 88 | + link->supplier = sup; |
---|
| 89 | + INIT_LIST_HEAD(&link->s_hook); |
---|
| 90 | + link->consumer = con; |
---|
| 91 | + INIT_LIST_HEAD(&link->c_hook); |
---|
| 92 | + |
---|
| 93 | + list_add(&link->s_hook, &sup->consumers); |
---|
| 94 | + list_add(&link->c_hook, &con->suppliers); |
---|
| 95 | +out: |
---|
| 96 | + mutex_unlock(&fwnode_link_lock); |
---|
| 97 | + |
---|
| 98 | + return ret; |
---|
| 99 | +} |
---|
| 100 | + |
---|
| 101 | +/** |
---|
| 102 | + * fwnode_links_purge_suppliers - Delete all supplier links of fwnode_handle. |
---|
| 103 | + * @fwnode: fwnode whose supplier links need to be deleted |
---|
| 104 | + * |
---|
| 105 | + * Deletes all supplier links connecting directly to @fwnode. |
---|
| 106 | + */ |
---|
| 107 | +static void fwnode_links_purge_suppliers(struct fwnode_handle *fwnode) |
---|
| 108 | +{ |
---|
| 109 | + struct fwnode_link *link, *tmp; |
---|
| 110 | + |
---|
| 111 | + mutex_lock(&fwnode_link_lock); |
---|
| 112 | + list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) { |
---|
| 113 | + list_del(&link->s_hook); |
---|
| 114 | + list_del(&link->c_hook); |
---|
| 115 | + kfree(link); |
---|
| 116 | + } |
---|
| 117 | + mutex_unlock(&fwnode_link_lock); |
---|
| 118 | +} |
---|
| 119 | + |
---|
| 120 | +/** |
---|
| 121 | + * fwnode_links_purge_consumers - Delete all consumer links of fwnode_handle. |
---|
| 122 | + * @fwnode: fwnode whose consumer links need to be deleted |
---|
| 123 | + * |
---|
| 124 | + * Deletes all consumer links connecting directly to @fwnode. |
---|
| 125 | + */ |
---|
| 126 | +static void fwnode_links_purge_consumers(struct fwnode_handle *fwnode) |
---|
| 127 | +{ |
---|
| 128 | + struct fwnode_link *link, *tmp; |
---|
| 129 | + |
---|
| 130 | + mutex_lock(&fwnode_link_lock); |
---|
| 131 | + list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook) { |
---|
| 132 | + list_del(&link->s_hook); |
---|
| 133 | + list_del(&link->c_hook); |
---|
| 134 | + kfree(link); |
---|
| 135 | + } |
---|
| 136 | + mutex_unlock(&fwnode_link_lock); |
---|
| 137 | +} |
---|
| 138 | + |
---|
| 139 | +/** |
---|
| 140 | + * fwnode_links_purge - Delete all links connected to a fwnode_handle. |
---|
| 141 | + * @fwnode: fwnode whose links needs to be deleted |
---|
| 142 | + * |
---|
| 143 | + * Deletes all links connecting directly to a fwnode. |
---|
| 144 | + */ |
---|
| 145 | +void fwnode_links_purge(struct fwnode_handle *fwnode) |
---|
| 146 | +{ |
---|
| 147 | + fwnode_links_purge_suppliers(fwnode); |
---|
| 148 | + fwnode_links_purge_consumers(fwnode); |
---|
| 149 | +} |
---|
| 150 | + |
---|
| 151 | +static void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode) |
---|
| 152 | +{ |
---|
| 153 | + struct fwnode_handle *child; |
---|
| 154 | + |
---|
| 155 | + /* Don't purge consumer links of an added child */ |
---|
| 156 | + if (fwnode->dev) |
---|
| 157 | + return; |
---|
| 158 | + |
---|
| 159 | + fwnode->flags |= FWNODE_FLAG_NOT_DEVICE; |
---|
| 160 | + fwnode_links_purge_consumers(fwnode); |
---|
| 161 | + |
---|
| 162 | + fwnode_for_each_available_child_node(fwnode, child) |
---|
| 163 | + fw_devlink_purge_absent_suppliers(child); |
---|
| 164 | +} |
---|
54 | 165 | |
---|
55 | 166 | #ifdef CONFIG_SRCU |
---|
56 | 167 | static DEFINE_MUTEX(device_links_lock); |
---|
.. | .. |
---|
66 | 177 | mutex_unlock(&device_links_lock); |
---|
67 | 178 | } |
---|
68 | 179 | |
---|
69 | | -int device_links_read_lock(void) |
---|
| 180 | +int device_links_read_lock(void) __acquires(&device_links_srcu) |
---|
70 | 181 | { |
---|
71 | 182 | return srcu_read_lock(&device_links_srcu); |
---|
72 | 183 | } |
---|
73 | 184 | |
---|
74 | | -void device_links_read_unlock(int idx) |
---|
| 185 | +void device_links_read_unlock(int idx) __releases(&device_links_srcu) |
---|
75 | 186 | { |
---|
76 | 187 | srcu_read_unlock(&device_links_srcu, idx); |
---|
| 188 | +} |
---|
| 189 | + |
---|
| 190 | +int device_links_read_lock_held(void) |
---|
| 191 | +{ |
---|
| 192 | + return srcu_read_lock_held(&device_links_srcu); |
---|
| 193 | +} |
---|
| 194 | + |
---|
| 195 | +static void device_link_synchronize_removal(void) |
---|
| 196 | +{ |
---|
| 197 | + synchronize_srcu(&device_links_srcu); |
---|
| 198 | +} |
---|
| 199 | + |
---|
| 200 | +static void device_link_remove_from_lists(struct device_link *link) |
---|
| 201 | +{ |
---|
| 202 | + list_del_rcu(&link->s_node); |
---|
| 203 | + list_del_rcu(&link->c_node); |
---|
77 | 204 | } |
---|
78 | 205 | #else /* !CONFIG_SRCU */ |
---|
79 | 206 | static DECLARE_RWSEM(device_links_lock); |
---|
.. | .. |
---|
98 | 225 | { |
---|
99 | 226 | up_read(&device_links_lock); |
---|
100 | 227 | } |
---|
101 | | -#endif /* !CONFIG_SRCU */ |
---|
102 | 228 | |
---|
103 | | -EXPORT_SYMBOL(device_links_read_lock); |
---|
104 | | -EXPORT_SYMBOL(device_links_read_unlock); |
---|
| 229 | +#ifdef CONFIG_DEBUG_LOCK_ALLOC |
---|
| 230 | +int device_links_read_lock_held(void) |
---|
| 231 | +{ |
---|
| 232 | + return lockdep_is_held(&device_links_lock); |
---|
| 233 | +} |
---|
| 234 | +#endif |
---|
| 235 | + |
---|
| 236 | +static inline void device_link_synchronize_removal(void) |
---|
| 237 | +{ |
---|
| 238 | +} |
---|
| 239 | + |
---|
| 240 | +static void device_link_remove_from_lists(struct device_link *link) |
---|
| 241 | +{ |
---|
| 242 | + list_del(&link->s_node); |
---|
| 243 | + list_del(&link->c_node); |
---|
| 244 | +} |
---|
| 245 | +#endif /* !CONFIG_SRCU */ |
---|
105 | 246 | |
---|
106 | 247 | static bool device_is_ancestor(struct device *dev, struct device *target) |
---|
107 | 248 | { |
---|
.. | .. |
---|
121 | 262 | * Check if @target depends on @dev or any device dependent on it (its child or |
---|
122 | 263 | * its consumer etc). Return 1 if that is the case or 0 otherwise. |
---|
123 | 264 | */ |
---|
124 | | -static int device_is_dependent(struct device *dev, void *target) |
---|
| 265 | +int device_is_dependent(struct device *dev, void *target) |
---|
125 | 266 | { |
---|
126 | 267 | struct device_link *link; |
---|
127 | 268 | int ret; |
---|
.. | .. |
---|
139 | 280 | return ret; |
---|
140 | 281 | |
---|
141 | 282 | list_for_each_entry(link, &dev->links.consumers, s_node) { |
---|
142 | | - if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) |
---|
| 283 | + if ((link->flags & ~DL_FLAG_INFERRED) == |
---|
| 284 | + (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) |
---|
143 | 285 | continue; |
---|
144 | 286 | |
---|
145 | 287 | if (link->consumer == target) |
---|
.. | .. |
---|
212 | 354 | |
---|
213 | 355 | device_for_each_child(dev, NULL, device_reorder_to_tail); |
---|
214 | 356 | list_for_each_entry(link, &dev->links.consumers, s_node) { |
---|
215 | | - if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) |
---|
| 357 | + if ((link->flags & ~DL_FLAG_INFERRED) == |
---|
| 358 | + (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) |
---|
216 | 359 | continue; |
---|
217 | 360 | device_reorder_to_tail(link->consumer, NULL); |
---|
218 | 361 | } |
---|
.. | .. |
---|
240 | 383 | device_links_read_unlock(idx); |
---|
241 | 384 | } |
---|
242 | 385 | |
---|
| 386 | +#define to_devlink(dev) container_of((dev), struct device_link, link_dev) |
---|
| 387 | + |
---|
| 388 | +static ssize_t status_show(struct device *dev, |
---|
| 389 | + struct device_attribute *attr, char *buf) |
---|
| 390 | +{ |
---|
| 391 | + const char *output; |
---|
| 392 | + |
---|
| 393 | + switch (to_devlink(dev)->status) { |
---|
| 394 | + case DL_STATE_NONE: |
---|
| 395 | + output = "not tracked"; |
---|
| 396 | + break; |
---|
| 397 | + case DL_STATE_DORMANT: |
---|
| 398 | + output = "dormant"; |
---|
| 399 | + break; |
---|
| 400 | + case DL_STATE_AVAILABLE: |
---|
| 401 | + output = "available"; |
---|
| 402 | + break; |
---|
| 403 | + case DL_STATE_CONSUMER_PROBE: |
---|
| 404 | + output = "consumer probing"; |
---|
| 405 | + break; |
---|
| 406 | + case DL_STATE_ACTIVE: |
---|
| 407 | + output = "active"; |
---|
| 408 | + break; |
---|
| 409 | + case DL_STATE_SUPPLIER_UNBIND: |
---|
| 410 | + output = "supplier unbinding"; |
---|
| 411 | + break; |
---|
| 412 | + default: |
---|
| 413 | + output = "unknown"; |
---|
| 414 | + break; |
---|
| 415 | + } |
---|
| 416 | + |
---|
| 417 | + return sysfs_emit(buf, "%s\n", output); |
---|
| 418 | +} |
---|
| 419 | +static DEVICE_ATTR_RO(status); |
---|
| 420 | + |
---|
| 421 | +static ssize_t auto_remove_on_show(struct device *dev, |
---|
| 422 | + struct device_attribute *attr, char *buf) |
---|
| 423 | +{ |
---|
| 424 | + struct device_link *link = to_devlink(dev); |
---|
| 425 | + const char *output; |
---|
| 426 | + |
---|
| 427 | + if (link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER) |
---|
| 428 | + output = "supplier unbind"; |
---|
| 429 | + else if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER) |
---|
| 430 | + output = "consumer unbind"; |
---|
| 431 | + else |
---|
| 432 | + output = "never"; |
---|
| 433 | + |
---|
| 434 | + return sysfs_emit(buf, "%s\n", output); |
---|
| 435 | +} |
---|
| 436 | +static DEVICE_ATTR_RO(auto_remove_on); |
---|
| 437 | + |
---|
| 438 | +static ssize_t runtime_pm_show(struct device *dev, |
---|
| 439 | + struct device_attribute *attr, char *buf) |
---|
| 440 | +{ |
---|
| 441 | + struct device_link *link = to_devlink(dev); |
---|
| 442 | + |
---|
| 443 | + return sysfs_emit(buf, "%d\n", !!(link->flags & DL_FLAG_PM_RUNTIME)); |
---|
| 444 | +} |
---|
| 445 | +static DEVICE_ATTR_RO(runtime_pm); |
---|
| 446 | + |
---|
| 447 | +static ssize_t sync_state_only_show(struct device *dev, |
---|
| 448 | + struct device_attribute *attr, char *buf) |
---|
| 449 | +{ |
---|
| 450 | + struct device_link *link = to_devlink(dev); |
---|
| 451 | + |
---|
| 452 | + return sysfs_emit(buf, "%d\n", |
---|
| 453 | + !!(link->flags & DL_FLAG_SYNC_STATE_ONLY)); |
---|
| 454 | +} |
---|
| 455 | +static DEVICE_ATTR_RO(sync_state_only); |
---|
| 456 | + |
---|
| 457 | +static struct attribute *devlink_attrs[] = { |
---|
| 458 | + &dev_attr_status.attr, |
---|
| 459 | + &dev_attr_auto_remove_on.attr, |
---|
| 460 | + &dev_attr_runtime_pm.attr, |
---|
| 461 | + &dev_attr_sync_state_only.attr, |
---|
| 462 | + NULL, |
---|
| 463 | +}; |
---|
| 464 | +ATTRIBUTE_GROUPS(devlink); |
---|
| 465 | + |
---|
| 466 | +static void device_link_release_fn(struct work_struct *work) |
---|
| 467 | +{ |
---|
| 468 | + struct device_link *link = container_of(work, struct device_link, rm_work); |
---|
| 469 | + |
---|
| 470 | + /* Ensure that all references to the link object have been dropped. */ |
---|
| 471 | + device_link_synchronize_removal(); |
---|
| 472 | + |
---|
| 473 | + pm_runtime_release_supplier(link); |
---|
| 474 | + pm_request_idle(link->supplier); |
---|
| 475 | + |
---|
| 476 | + put_device(link->consumer); |
---|
| 477 | + put_device(link->supplier); |
---|
| 478 | + kfree(link); |
---|
| 479 | +} |
---|
| 480 | + |
---|
| 481 | +static void devlink_dev_release(struct device *dev) |
---|
| 482 | +{ |
---|
| 483 | + struct device_link *link = to_devlink(dev); |
---|
| 484 | + |
---|
| 485 | + INIT_WORK(&link->rm_work, device_link_release_fn); |
---|
| 486 | + /* |
---|
| 487 | + * It may take a while to complete this work because of the SRCU |
---|
| 488 | + * synchronization in device_link_release_fn() and if the consumer or |
---|
| 489 | + * supplier devices get deleted when it runs, so put it into the "long" |
---|
| 490 | + * workqueue. |
---|
| 491 | + */ |
---|
| 492 | + queue_work(system_long_wq, &link->rm_work); |
---|
| 493 | +} |
---|
| 494 | + |
---|
| 495 | +static struct class devlink_class = { |
---|
| 496 | + .name = "devlink", |
---|
| 497 | + .owner = THIS_MODULE, |
---|
| 498 | + .dev_groups = devlink_groups, |
---|
| 499 | + .dev_release = devlink_dev_release, |
---|
| 500 | +}; |
---|
| 501 | + |
---|
| 502 | +static int devlink_add_symlinks(struct device *dev, |
---|
| 503 | + struct class_interface *class_intf) |
---|
| 504 | +{ |
---|
| 505 | + int ret; |
---|
| 506 | + size_t len; |
---|
| 507 | + struct device_link *link = to_devlink(dev); |
---|
| 508 | + struct device *sup = link->supplier; |
---|
| 509 | + struct device *con = link->consumer; |
---|
| 510 | + char *buf; |
---|
| 511 | + |
---|
| 512 | + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), |
---|
| 513 | + strlen(dev_bus_name(con)) + strlen(dev_name(con))); |
---|
| 514 | + len += strlen(":"); |
---|
| 515 | + len += strlen("supplier:") + 1; |
---|
| 516 | + buf = kzalloc(len, GFP_KERNEL); |
---|
| 517 | + if (!buf) |
---|
| 518 | + return -ENOMEM; |
---|
| 519 | + |
---|
| 520 | + ret = sysfs_create_link(&link->link_dev.kobj, &sup->kobj, "supplier"); |
---|
| 521 | + if (ret) |
---|
| 522 | + goto out; |
---|
| 523 | + |
---|
| 524 | + ret = sysfs_create_link(&link->link_dev.kobj, &con->kobj, "consumer"); |
---|
| 525 | + if (ret) |
---|
| 526 | + goto err_con; |
---|
| 527 | + |
---|
| 528 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); |
---|
| 529 | + ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf); |
---|
| 530 | + if (ret) |
---|
| 531 | + goto err_con_dev; |
---|
| 532 | + |
---|
| 533 | + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); |
---|
| 534 | + ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf); |
---|
| 535 | + if (ret) |
---|
| 536 | + goto err_sup_dev; |
---|
| 537 | + |
---|
| 538 | + goto out; |
---|
| 539 | + |
---|
| 540 | +err_sup_dev: |
---|
| 541 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); |
---|
| 542 | + sysfs_remove_link(&sup->kobj, buf); |
---|
| 543 | +err_con_dev: |
---|
| 544 | + sysfs_remove_link(&link->link_dev.kobj, "consumer"); |
---|
| 545 | +err_con: |
---|
| 546 | + sysfs_remove_link(&link->link_dev.kobj, "supplier"); |
---|
| 547 | +out: |
---|
| 548 | + kfree(buf); |
---|
| 549 | + return ret; |
---|
| 550 | +} |
---|
| 551 | + |
---|
| 552 | +static void devlink_remove_symlinks(struct device *dev, |
---|
| 553 | + struct class_interface *class_intf) |
---|
| 554 | +{ |
---|
| 555 | + struct device_link *link = to_devlink(dev); |
---|
| 556 | + size_t len; |
---|
| 557 | + struct device *sup = link->supplier; |
---|
| 558 | + struct device *con = link->consumer; |
---|
| 559 | + char *buf; |
---|
| 560 | + |
---|
| 561 | + sysfs_remove_link(&link->link_dev.kobj, "consumer"); |
---|
| 562 | + sysfs_remove_link(&link->link_dev.kobj, "supplier"); |
---|
| 563 | + |
---|
| 564 | + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)), |
---|
| 565 | + strlen(dev_bus_name(con)) + strlen(dev_name(con))); |
---|
| 566 | + len += strlen(":"); |
---|
| 567 | + len += strlen("supplier:") + 1; |
---|
| 568 | + buf = kzalloc(len, GFP_KERNEL); |
---|
| 569 | + if (!buf) { |
---|
| 570 | + WARN(1, "Unable to properly free device link symlinks!\n"); |
---|
| 571 | + return; |
---|
| 572 | + } |
---|
| 573 | + |
---|
| 574 | + if (device_is_registered(con)) { |
---|
| 575 | + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); |
---|
| 576 | + sysfs_remove_link(&con->kobj, buf); |
---|
| 577 | + } |
---|
| 578 | + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); |
---|
| 579 | + sysfs_remove_link(&sup->kobj, buf); |
---|
| 580 | + kfree(buf); |
---|
| 581 | +} |
---|
| 582 | + |
---|
| 583 | +static struct class_interface devlink_class_intf = { |
---|
| 584 | + .class = &devlink_class, |
---|
| 585 | + .add_dev = devlink_add_symlinks, |
---|
| 586 | + .remove_dev = devlink_remove_symlinks, |
---|
| 587 | +}; |
---|
| 588 | + |
---|
| 589 | +static int __init devlink_class_init(void) |
---|
| 590 | +{ |
---|
| 591 | + int ret; |
---|
| 592 | + |
---|
| 593 | + ret = class_register(&devlink_class); |
---|
| 594 | + if (ret) |
---|
| 595 | + return ret; |
---|
| 596 | + |
---|
| 597 | + ret = class_interface_register(&devlink_class_intf); |
---|
| 598 | + if (ret) |
---|
| 599 | + class_unregister(&devlink_class); |
---|
| 600 | + |
---|
| 601 | + return ret; |
---|
| 602 | +} |
---|
| 603 | +postcore_initcall(devlink_class_init); |
---|
| 604 | + |
---|
243 | 605 | #define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \ |
---|
244 | 606 | DL_FLAG_AUTOREMOVE_SUPPLIER | \ |
---|
245 | 607 | DL_FLAG_AUTOPROBE_CONSUMER | \ |
---|
246 | | - DL_FLAG_SYNC_STATE_ONLY) |
---|
| 608 | + DL_FLAG_SYNC_STATE_ONLY | \ |
---|
| 609 | + DL_FLAG_INFERRED) |
---|
247 | 610 | |
---|
248 | 611 | #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \ |
---|
249 | 612 | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE) |
---|
.. | .. |
---|
309 | 672 | { |
---|
310 | 673 | struct device_link *link; |
---|
311 | 674 | |
---|
312 | | - if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS || |
---|
| 675 | + if (!consumer || !supplier || consumer == supplier || |
---|
| 676 | + flags & ~DL_ADD_VALID_FLAGS || |
---|
313 | 677 | (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) || |
---|
314 | 678 | (flags & DL_FLAG_SYNC_STATE_ONLY && |
---|
315 | | - flags != DL_FLAG_SYNC_STATE_ONLY) || |
---|
| 679 | + (flags & ~DL_FLAG_INFERRED) != DL_FLAG_SYNC_STATE_ONLY) || |
---|
316 | 680 | (flags & DL_FLAG_AUTOPROBE_CONSUMER && |
---|
317 | 681 | flags & (DL_FLAG_AUTOREMOVE_CONSUMER | |
---|
318 | 682 | DL_FLAG_AUTOREMOVE_SUPPLIER))) |
---|
.. | .. |
---|
346 | 710 | } |
---|
347 | 711 | |
---|
348 | 712 | /* |
---|
| 713 | + * SYNC_STATE_ONLY links are useless once a consumer device has probed. |
---|
| 714 | + * So, only create it if the consumer hasn't probed yet. |
---|
| 715 | + */ |
---|
| 716 | + if (flags & DL_FLAG_SYNC_STATE_ONLY && |
---|
| 717 | + consumer->links.status != DL_DEV_NO_DRIVER && |
---|
| 718 | + consumer->links.status != DL_DEV_PROBING) { |
---|
| 719 | + link = NULL; |
---|
| 720 | + goto out; |
---|
| 721 | + } |
---|
| 722 | + |
---|
| 723 | + /* |
---|
349 | 724 | * DL_FLAG_AUTOREMOVE_SUPPLIER indicates that the link will be needed |
---|
350 | 725 | * longer than for DL_FLAG_AUTOREMOVE_CONSUMER and setting them both |
---|
351 | 726 | * together doesn't make sense, so prefer DL_FLAG_AUTOREMOVE_SUPPLIER. |
---|
.. | .. |
---|
356 | 731 | list_for_each_entry(link, &supplier->links.consumers, s_node) { |
---|
357 | 732 | if (link->consumer != consumer) |
---|
358 | 733 | continue; |
---|
| 734 | + |
---|
| 735 | + if (link->flags & DL_FLAG_INFERRED && |
---|
| 736 | + !(flags & DL_FLAG_INFERRED)) |
---|
| 737 | + link->flags &= ~DL_FLAG_INFERRED; |
---|
359 | 738 | |
---|
360 | 739 | if (flags & DL_FLAG_PM_RUNTIME) { |
---|
361 | 740 | if (!(link->flags & DL_FLAG_PM_RUNTIME)) { |
---|
.. | .. |
---|
412 | 791 | |
---|
413 | 792 | refcount_set(&link->rpm_active, 1); |
---|
414 | 793 | |
---|
415 | | - if (flags & DL_FLAG_PM_RUNTIME) { |
---|
416 | | - if (flags & DL_FLAG_RPM_ACTIVE) |
---|
417 | | - refcount_inc(&link->rpm_active); |
---|
418 | | - |
---|
419 | | - pm_runtime_new_link(consumer); |
---|
420 | | - } |
---|
421 | | - |
---|
422 | 794 | get_device(supplier); |
---|
423 | 795 | link->supplier = supplier; |
---|
424 | 796 | INIT_LIST_HEAD(&link->s_node); |
---|
.. | .. |
---|
427 | 799 | INIT_LIST_HEAD(&link->c_node); |
---|
428 | 800 | link->flags = flags; |
---|
429 | 801 | kref_init(&link->kref); |
---|
| 802 | + |
---|
| 803 | + link->link_dev.class = &devlink_class; |
---|
| 804 | + device_set_pm_not_required(&link->link_dev); |
---|
| 805 | + dev_set_name(&link->link_dev, "%s:%s--%s:%s", |
---|
| 806 | + dev_bus_name(supplier), dev_name(supplier), |
---|
| 807 | + dev_bus_name(consumer), dev_name(consumer)); |
---|
| 808 | + if (device_register(&link->link_dev)) { |
---|
| 809 | + put_device(&link->link_dev); |
---|
| 810 | + link = NULL; |
---|
| 811 | + goto out; |
---|
| 812 | + } |
---|
| 813 | + |
---|
| 814 | + if (flags & DL_FLAG_PM_RUNTIME) { |
---|
| 815 | + if (flags & DL_FLAG_RPM_ACTIVE) |
---|
| 816 | + refcount_inc(&link->rpm_active); |
---|
| 817 | + |
---|
| 818 | + pm_runtime_new_link(consumer); |
---|
| 819 | + } |
---|
430 | 820 | |
---|
431 | 821 | /* Determine the initial link state. */ |
---|
432 | 822 | if (flags & DL_FLAG_STATELESS) |
---|
.. | .. |
---|
462 | 852 | */ |
---|
463 | 853 | device_reorder_to_tail(consumer, NULL); |
---|
464 | 854 | |
---|
465 | | - dev_info(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); |
---|
| 855 | + dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); |
---|
466 | 856 | |
---|
467 | 857 | out: |
---|
468 | 858 | device_pm_unlock(); |
---|
.. | .. |
---|
475 | 865 | } |
---|
476 | 866 | EXPORT_SYMBOL_GPL(device_link_add); |
---|
477 | 867 | |
---|
478 | | -/** |
---|
479 | | - * device_link_wait_for_supplier - Add device to wait_for_suppliers list |
---|
480 | | - * @consumer: Consumer device |
---|
481 | | - * |
---|
482 | | - * Marks the @consumer device as waiting for suppliers to become available by |
---|
483 | | - * adding it to the wait_for_suppliers list. The consumer device will never be |
---|
484 | | - * probed until it's removed from the wait_for_suppliers list. |
---|
485 | | - * |
---|
486 | | - * The caller is responsible for adding the links to the supplier devices once |
---|
487 | | - * they are available and removing the @consumer device from the |
---|
488 | | - * wait_for_suppliers list once links to all the suppliers have been created. |
---|
489 | | - * |
---|
490 | | - * This function is NOT meant to be called from the probe function of the |
---|
491 | | - * consumer but rather from code that creates/adds the consumer device. |
---|
492 | | - */ |
---|
493 | | -static void device_link_wait_for_supplier(struct device *consumer, |
---|
494 | | - bool need_for_probe) |
---|
495 | | -{ |
---|
496 | | - mutex_lock(&wfs_lock); |
---|
497 | | - list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); |
---|
498 | | - consumer->links.need_for_probe = need_for_probe; |
---|
499 | | - mutex_unlock(&wfs_lock); |
---|
500 | | -} |
---|
501 | | - |
---|
502 | | -static void device_link_wait_for_mandatory_supplier(struct device *consumer) |
---|
503 | | -{ |
---|
504 | | - device_link_wait_for_supplier(consumer, true); |
---|
505 | | -} |
---|
506 | | - |
---|
507 | | -static void device_link_wait_for_optional_supplier(struct device *consumer) |
---|
508 | | -{ |
---|
509 | | - device_link_wait_for_supplier(consumer, false); |
---|
510 | | -} |
---|
511 | | - |
---|
512 | | -/** |
---|
513 | | - * device_link_add_missing_supplier_links - Add links from consumer devices to |
---|
514 | | - * supplier devices, leaving any |
---|
515 | | - * consumer with inactive suppliers on |
---|
516 | | - * the wait_for_suppliers list |
---|
517 | | - * |
---|
518 | | - * Loops through all consumers waiting on suppliers and tries to add all their |
---|
519 | | - * supplier links. If that succeeds, the consumer device is removed from |
---|
520 | | - * wait_for_suppliers list. Otherwise, they are left in the wait_for_suppliers |
---|
521 | | - * list. Devices left on the wait_for_suppliers list will not be probed. |
---|
522 | | - * |
---|
523 | | - * The fwnode add_links callback is expected to return 0 if it has found and |
---|
524 | | - * added all the supplier links for the consumer device. It should return an |
---|
525 | | - * error if it isn't able to do so. |
---|
526 | | - * |
---|
527 | | - * The caller of device_link_wait_for_supplier() is expected to call this once |
---|
528 | | - * it's aware of potential suppliers becoming available. |
---|
529 | | - */ |
---|
530 | | -static void device_link_add_missing_supplier_links(void) |
---|
531 | | -{ |
---|
532 | | - struct device *dev, *tmp; |
---|
533 | | - |
---|
534 | | - mutex_lock(&wfs_lock); |
---|
535 | | - list_for_each_entry_safe(dev, tmp, &wait_for_suppliers, |
---|
536 | | - links.needs_suppliers) { |
---|
537 | | - int ret = fwnode_call_int_op(dev->fwnode, add_links, dev); |
---|
538 | | - if (!ret) |
---|
539 | | - list_del_init(&dev->links.needs_suppliers); |
---|
540 | | - else if (ret != -ENODEV) |
---|
541 | | - dev->links.need_for_probe = false; |
---|
542 | | - } |
---|
543 | | - mutex_unlock(&wfs_lock); |
---|
544 | | -} |
---|
545 | | - |
---|
546 | | -static void device_link_free(struct device_link *link) |
---|
547 | | -{ |
---|
548 | | - while (refcount_dec_not_one(&link->rpm_active)) |
---|
549 | | - pm_runtime_put(link->supplier); |
---|
550 | | - |
---|
551 | | - put_device(link->consumer); |
---|
552 | | - put_device(link->supplier); |
---|
553 | | - kfree(link); |
---|
554 | | -} |
---|
555 | | - |
---|
556 | | -#ifdef CONFIG_SRCU |
---|
557 | | -static void __device_link_free_srcu(struct rcu_head *rhead) |
---|
558 | | -{ |
---|
559 | | - device_link_free(container_of(rhead, struct device_link, rcu_head)); |
---|
560 | | -} |
---|
561 | | - |
---|
562 | 868 | static void __device_link_del(struct kref *kref) |
---|
563 | 869 | { |
---|
564 | 870 | struct device_link *link = container_of(kref, struct device_link, kref); |
---|
565 | 871 | |
---|
566 | | - dev_info(link->consumer, "Dropping the link to %s\n", |
---|
567 | | - dev_name(link->supplier)); |
---|
| 872 | + dev_dbg(link->consumer, "Dropping the link to %s\n", |
---|
| 873 | + dev_name(link->supplier)); |
---|
568 | 874 | |
---|
569 | | - if (link->flags & DL_FLAG_PM_RUNTIME) |
---|
570 | | - pm_runtime_drop_link(link->consumer); |
---|
| 875 | + pm_runtime_drop_link(link); |
---|
571 | 876 | |
---|
572 | | - list_del_rcu(&link->s_node); |
---|
573 | | - list_del_rcu(&link->c_node); |
---|
574 | | - call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); |
---|
| 877 | + device_link_remove_from_lists(link); |
---|
| 878 | + device_unregister(&link->link_dev); |
---|
575 | 879 | } |
---|
576 | | -#else /* !CONFIG_SRCU */ |
---|
577 | | -static void __device_link_del(struct kref *kref) |
---|
578 | | -{ |
---|
579 | | - struct device_link *link = container_of(kref, struct device_link, kref); |
---|
580 | | - |
---|
581 | | - dev_info(link->consumer, "Dropping the link to %s\n", |
---|
582 | | - dev_name(link->supplier)); |
---|
583 | | - |
---|
584 | | - if (link->flags & DL_FLAG_PM_RUNTIME) |
---|
585 | | - pm_runtime_drop_link(link->consumer); |
---|
586 | | - |
---|
587 | | - list_del(&link->s_node); |
---|
588 | | - list_del(&link->c_node); |
---|
589 | | - device_link_free(link); |
---|
590 | | -} |
---|
591 | | -#endif /* !CONFIG_SRCU */ |
---|
592 | 880 | |
---|
593 | 881 | static void device_link_put_kref(struct device_link *link) |
---|
594 | 882 | { |
---|
.. | .. |
---|
610 | 898 | void device_link_del(struct device_link *link) |
---|
611 | 899 | { |
---|
612 | 900 | device_links_write_lock(); |
---|
613 | | - device_pm_lock(); |
---|
614 | 901 | device_link_put_kref(link); |
---|
615 | | - device_pm_unlock(); |
---|
616 | 902 | device_links_write_unlock(); |
---|
617 | 903 | } |
---|
618 | 904 | EXPORT_SYMBOL_GPL(device_link_del); |
---|
.. | .. |
---|
633 | 919 | return; |
---|
634 | 920 | |
---|
635 | 921 | device_links_write_lock(); |
---|
636 | | - device_pm_lock(); |
---|
637 | 922 | |
---|
638 | 923 | list_for_each_entry(link, &supplier->links.consumers, s_node) { |
---|
639 | 924 | if (link->consumer == consumer) { |
---|
.. | .. |
---|
642 | 927 | } |
---|
643 | 928 | } |
---|
644 | 929 | |
---|
645 | | - device_pm_unlock(); |
---|
646 | 930 | device_links_write_unlock(); |
---|
647 | 931 | } |
---|
648 | 932 | EXPORT_SYMBOL_GPL(device_link_remove); |
---|
.. | .. |
---|
689 | 973 | * Device waiting for supplier to become available is not allowed to |
---|
690 | 974 | * probe. |
---|
691 | 975 | */ |
---|
692 | | - mutex_lock(&wfs_lock); |
---|
693 | | - if (!list_empty(&dev->links.needs_suppliers) && |
---|
694 | | - dev->links.need_for_probe) { |
---|
695 | | - mutex_unlock(&wfs_lock); |
---|
| 976 | + mutex_lock(&fwnode_link_lock); |
---|
| 977 | + if (dev->fwnode && !list_empty(&dev->fwnode->suppliers) && |
---|
| 978 | + !fw_devlink_is_permissive()) { |
---|
| 979 | + dev_dbg(dev, "probe deferral - wait for supplier %pfwP\n", |
---|
| 980 | + list_first_entry(&dev->fwnode->suppliers, |
---|
| 981 | + struct fwnode_link, |
---|
| 982 | + c_hook)->supplier); |
---|
| 983 | + mutex_unlock(&fwnode_link_lock); |
---|
696 | 984 | return -EPROBE_DEFER; |
---|
697 | 985 | } |
---|
698 | | - mutex_unlock(&wfs_lock); |
---|
| 986 | + mutex_unlock(&fwnode_link_lock); |
---|
699 | 987 | |
---|
700 | 988 | device_links_write_lock(); |
---|
701 | 989 | |
---|
.. | .. |
---|
706 | 994 | if (link->status != DL_STATE_AVAILABLE && |
---|
707 | 995 | !(link->flags & DL_FLAG_SYNC_STATE_ONLY)) { |
---|
708 | 996 | device_links_missing_supplier(dev); |
---|
| 997 | + dev_dbg(dev, "probe deferral - supplier %s not ready\n", |
---|
| 998 | + dev_name(link->supplier)); |
---|
709 | 999 | ret = -EPROBE_DEFER; |
---|
710 | 1000 | break; |
---|
711 | 1001 | } |
---|
.. | .. |
---|
740 | 1030 | { |
---|
741 | 1031 | struct device_link *link; |
---|
742 | 1032 | |
---|
| 1033 | + if (!dev_has_sync_state(dev)) |
---|
| 1034 | + return; |
---|
743 | 1035 | if (dev->state_synced) |
---|
744 | 1036 | return; |
---|
745 | 1037 | |
---|
.. | .. |
---|
757 | 1049 | */ |
---|
758 | 1050 | dev->state_synced = true; |
---|
759 | 1051 | |
---|
760 | | - if (WARN_ON(!list_empty(&dev->links.defer_hook))) |
---|
| 1052 | + if (WARN_ON(!list_empty(&dev->links.defer_sync))) |
---|
761 | 1053 | return; |
---|
762 | 1054 | |
---|
763 | 1055 | get_device(dev); |
---|
764 | | - list_add_tail(&dev->links.defer_hook, list); |
---|
| 1056 | + list_add_tail(&dev->links.defer_sync, list); |
---|
765 | 1057 | } |
---|
766 | 1058 | |
---|
767 | 1059 | /** |
---|
.. | .. |
---|
779 | 1071 | { |
---|
780 | 1072 | struct device *dev, *tmp; |
---|
781 | 1073 | |
---|
782 | | - list_for_each_entry_safe(dev, tmp, list, links.defer_hook) { |
---|
783 | | - list_del_init(&dev->links.defer_hook); |
---|
| 1074 | + list_for_each_entry_safe(dev, tmp, list, links.defer_sync) { |
---|
| 1075 | + list_del_init(&dev->links.defer_sync); |
---|
784 | 1076 | |
---|
785 | 1077 | if (dev != dont_lock_dev) |
---|
786 | 1078 | device_lock(dev); |
---|
.. | .. |
---|
818 | 1110 | if (defer_sync_state_count) |
---|
819 | 1111 | goto out; |
---|
820 | 1112 | |
---|
821 | | - list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_hook) { |
---|
| 1113 | + list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_sync) { |
---|
822 | 1114 | /* |
---|
823 | 1115 | * Delete from deferred_sync list before queuing it to |
---|
824 | | - * sync_list because defer_hook is used for both lists. |
---|
| 1116 | + * sync_list because defer_sync is used for both lists. |
---|
825 | 1117 | */ |
---|
826 | | - list_del_init(&dev->links.defer_hook); |
---|
| 1118 | + list_del_init(&dev->links.defer_sync); |
---|
827 | 1119 | __device_links_queue_sync_state(dev, &sync_list); |
---|
828 | 1120 | } |
---|
829 | 1121 | out: |
---|
.. | .. |
---|
841 | 1133 | |
---|
842 | 1134 | static void __device_links_supplier_defer_sync(struct device *sup) |
---|
843 | 1135 | { |
---|
844 | | - if (list_empty(&sup->links.defer_hook)) |
---|
845 | | - list_add_tail(&sup->links.defer_hook, &deferred_sync); |
---|
| 1136 | + if (list_empty(&sup->links.defer_sync) && dev_has_sync_state(sup)) |
---|
| 1137 | + list_add_tail(&sup->links.defer_sync, &deferred_sync); |
---|
846 | 1138 | } |
---|
847 | 1139 | |
---|
848 | 1140 | static void device_link_drop_managed(struct device_link *link) |
---|
.. | .. |
---|
851 | 1143 | WRITE_ONCE(link->status, DL_STATE_NONE); |
---|
852 | 1144 | kref_put(&link->kref, __device_link_del); |
---|
853 | 1145 | } |
---|
| 1146 | + |
---|
| 1147 | +static ssize_t waiting_for_supplier_show(struct device *dev, |
---|
| 1148 | + struct device_attribute *attr, |
---|
| 1149 | + char *buf) |
---|
| 1150 | +{ |
---|
| 1151 | + bool val; |
---|
| 1152 | + |
---|
| 1153 | + device_lock(dev); |
---|
| 1154 | + val = !list_empty(&dev->fwnode->suppliers); |
---|
| 1155 | + device_unlock(dev); |
---|
| 1156 | + return sysfs_emit(buf, "%u\n", val); |
---|
| 1157 | +} |
---|
| 1158 | +static DEVICE_ATTR_RO(waiting_for_supplier); |
---|
854 | 1159 | |
---|
855 | 1160 | /** |
---|
856 | 1161 | * device_links_driver_bound - Update device links after probing its driver. |
---|
.. | .. |
---|
869 | 1174 | LIST_HEAD(sync_list); |
---|
870 | 1175 | |
---|
871 | 1176 | /* |
---|
872 | | - * If a device probes successfully, it's expected to have created all |
---|
| 1177 | + * If a device binds successfully, it's expected to have created all |
---|
873 | 1178 | * the device links it needs to or make new device links as it needs |
---|
874 | | - * them. So, it no longer needs to wait on any suppliers. |
---|
| 1179 | + * them. So, fw_devlink no longer needs to create device links to any |
---|
| 1180 | + * of the device's suppliers. |
---|
| 1181 | + * |
---|
| 1182 | + * Also, if a child firmware node of this bound device is not added as |
---|
| 1183 | + * a device by now, assume it is never going to be added and make sure |
---|
| 1184 | + * other devices don't defer probe indefinitely by waiting for such a |
---|
| 1185 | + * child device. |
---|
875 | 1186 | */ |
---|
876 | | - mutex_lock(&wfs_lock); |
---|
877 | | - list_del_init(&dev->links.needs_suppliers); |
---|
878 | | - mutex_unlock(&wfs_lock); |
---|
| 1187 | + if (dev->fwnode && dev->fwnode->dev == dev) { |
---|
| 1188 | + struct fwnode_handle *child; |
---|
| 1189 | + fwnode_links_purge_suppliers(dev->fwnode); |
---|
| 1190 | + fwnode_for_each_available_child_node(dev->fwnode, child) |
---|
| 1191 | + fw_devlink_purge_absent_suppliers(child); |
---|
| 1192 | + } |
---|
| 1193 | + device_remove_file(dev, &dev_attr_waiting_for_supplier); |
---|
879 | 1194 | |
---|
880 | 1195 | device_links_write_lock(); |
---|
881 | 1196 | |
---|
.. | .. |
---|
1055 | 1370 | WRITE_ONCE(link->status, DL_STATE_DORMANT); |
---|
1056 | 1371 | } |
---|
1057 | 1372 | |
---|
1058 | | - list_del_init(&dev->links.defer_hook); |
---|
| 1373 | + list_del_init(&dev->links.defer_sync); |
---|
1059 | 1374 | __device_links_no_driver(dev); |
---|
1060 | 1375 | |
---|
1061 | 1376 | device_links_write_unlock(); |
---|
.. | .. |
---|
1162 | 1477 | { |
---|
1163 | 1478 | struct device_link *link, *ln; |
---|
1164 | 1479 | |
---|
1165 | | - mutex_lock(&wfs_lock); |
---|
1166 | | - list_del(&dev->links.needs_suppliers); |
---|
1167 | | - mutex_unlock(&wfs_lock); |
---|
| 1480 | + if (dev->class == &devlink_class) |
---|
| 1481 | + return; |
---|
1168 | 1482 | |
---|
1169 | 1483 | /* |
---|
1170 | 1484 | * Delete all of the remaining links from this device to any other |
---|
.. | .. |
---|
1186 | 1500 | device_links_write_unlock(); |
---|
1187 | 1501 | } |
---|
1188 | 1502 | |
---|
1189 | | -static void fw_devlink_link_device(struct device *dev) |
---|
| 1503 | +#define FW_DEVLINK_FLAGS_PERMISSIVE (DL_FLAG_INFERRED | \ |
---|
| 1504 | + DL_FLAG_SYNC_STATE_ONLY) |
---|
| 1505 | +#define FW_DEVLINK_FLAGS_ON (DL_FLAG_INFERRED | \ |
---|
| 1506 | + DL_FLAG_AUTOPROBE_CONSUMER) |
---|
| 1507 | +#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \ |
---|
| 1508 | + DL_FLAG_PM_RUNTIME) |
---|
| 1509 | + |
---|
| 1510 | +static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON; |
---|
| 1511 | +static int __init fw_devlink_setup(char *arg) |
---|
1190 | 1512 | { |
---|
1191 | | - int fw_ret; |
---|
| 1513 | + if (!arg) |
---|
| 1514 | + return -EINVAL; |
---|
1192 | 1515 | |
---|
1193 | | - mutex_lock(&defer_fw_devlink_lock); |
---|
1194 | | - if (!defer_fw_devlink_count) |
---|
1195 | | - device_link_add_missing_supplier_links(); |
---|
1196 | | - |
---|
1197 | | - /* |
---|
1198 | | - * The device's fwnode not having add_links() doesn't affect if other |
---|
1199 | | - * consumers can find this device as a supplier. So, this check is |
---|
1200 | | - * intentionally placed after device_link_add_missing_supplier_links(). |
---|
1201 | | - */ |
---|
1202 | | - if (!fwnode_has_op(dev->fwnode, add_links)) |
---|
1203 | | - goto out; |
---|
1204 | | - |
---|
1205 | | - /* |
---|
1206 | | - * If fw_devlink is being deferred, assume all devices have mandatory |
---|
1207 | | - * suppliers they need to link to later. Then, when the fw_devlink is |
---|
1208 | | - * resumed, all these devices will get a chance to try and link to any |
---|
1209 | | - * suppliers they have. |
---|
1210 | | - */ |
---|
1211 | | - if (!defer_fw_devlink_count) { |
---|
1212 | | - fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); |
---|
1213 | | - } else { |
---|
1214 | | - fw_ret = -ENODEV; |
---|
1215 | | - /* |
---|
1216 | | - * defer_hook is not used to add device to deferred_sync list |
---|
1217 | | - * until device is bound. Since deferred fw devlink also blocks |
---|
1218 | | - * probing, same list hook can be used for deferred_fw_devlink. |
---|
1219 | | - */ |
---|
1220 | | - list_add_tail(&dev->links.defer_hook, &deferred_fw_devlink); |
---|
| 1516 | + if (strcmp(arg, "off") == 0) { |
---|
| 1517 | + fw_devlink_flags = 0; |
---|
| 1518 | + } else if (strcmp(arg, "permissive") == 0) { |
---|
| 1519 | + fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE; |
---|
| 1520 | + } else if (strcmp(arg, "on") == 0) { |
---|
| 1521 | + fw_devlink_flags = FW_DEVLINK_FLAGS_ON; |
---|
| 1522 | + } else if (strcmp(arg, "rpm") == 0) { |
---|
| 1523 | + fw_devlink_flags = FW_DEVLINK_FLAGS_RPM; |
---|
1221 | 1524 | } |
---|
| 1525 | + return 0; |
---|
| 1526 | +} |
---|
| 1527 | +early_param("fw_devlink", fw_devlink_setup); |
---|
1222 | 1528 | |
---|
1223 | | - if (fw_ret == -ENODEV) |
---|
1224 | | - device_link_wait_for_mandatory_supplier(dev); |
---|
1225 | | - else if (fw_ret) |
---|
1226 | | - device_link_wait_for_optional_supplier(dev); |
---|
| 1529 | +static bool fw_devlink_strict = true; |
---|
| 1530 | +static int __init fw_devlink_strict_setup(char *arg) |
---|
| 1531 | +{ |
---|
| 1532 | + return strtobool(arg, &fw_devlink_strict); |
---|
| 1533 | +} |
---|
| 1534 | +early_param("fw_devlink.strict", fw_devlink_strict_setup); |
---|
1227 | 1535 | |
---|
1228 | | -out: |
---|
1229 | | - mutex_unlock(&defer_fw_devlink_lock); |
---|
| 1536 | +u32 fw_devlink_get_flags(void) |
---|
| 1537 | +{ |
---|
| 1538 | + return fw_devlink_flags; |
---|
| 1539 | +} |
---|
| 1540 | + |
---|
| 1541 | +static bool fw_devlink_is_permissive(void) |
---|
| 1542 | +{ |
---|
| 1543 | + return fw_devlink_flags == FW_DEVLINK_FLAGS_PERMISSIVE; |
---|
| 1544 | +} |
---|
| 1545 | + |
---|
| 1546 | +bool fw_devlink_is_strict(void) |
---|
| 1547 | +{ |
---|
| 1548 | + return fw_devlink_strict && !fw_devlink_is_permissive(); |
---|
| 1549 | +} |
---|
| 1550 | + |
---|
| 1551 | +static void fw_devlink_parse_fwnode(struct fwnode_handle *fwnode) |
---|
| 1552 | +{ |
---|
| 1553 | + if (fwnode->flags & FWNODE_FLAG_LINKS_ADDED) |
---|
| 1554 | + return; |
---|
| 1555 | + |
---|
| 1556 | + fwnode_call_int_op(fwnode, add_links); |
---|
| 1557 | + fwnode->flags |= FWNODE_FLAG_LINKS_ADDED; |
---|
| 1558 | +} |
---|
| 1559 | + |
---|
| 1560 | +static void fw_devlink_parse_fwtree(struct fwnode_handle *fwnode) |
---|
| 1561 | +{ |
---|
| 1562 | + struct fwnode_handle *child = NULL; |
---|
| 1563 | + |
---|
| 1564 | + fw_devlink_parse_fwnode(fwnode); |
---|
| 1565 | + |
---|
| 1566 | + while ((child = fwnode_get_next_available_child_node(fwnode, child))) |
---|
| 1567 | + fw_devlink_parse_fwtree(child); |
---|
1230 | 1568 | } |
---|
1231 | 1569 | |
---|
1232 | 1570 | /** |
---|
1233 | | - * fw_devlink_pause - Pause parsing of fwnode to create device links |
---|
| 1571 | + * fw_devlink_relax_cycle - Convert cyclic links to SYNC_STATE_ONLY links |
---|
| 1572 | + * @con: Device to check dependencies for. |
---|
| 1573 | + * @sup: Device to check against. |
---|
1234 | 1574 | * |
---|
1235 | | - * Calling this function defers any fwnode parsing to create device links until |
---|
1236 | | - * fw_devlink_resume() is called. Both these functions are ref counted and the |
---|
1237 | | - * caller needs to match the calls. |
---|
| 1575 | + * Check if @sup depends on @con or any device dependent on it (its child or |
---|
| 1576 | + * its consumer etc). When such a cyclic dependency is found, convert all |
---|
| 1577 | + * device links created solely by fw_devlink into SYNC_STATE_ONLY device links. |
---|
| 1578 | + * This is the equivalent of doing fw_devlink=permissive just between the |
---|
| 1579 | + * devices in the cycle. We need to do this because, at this point, fw_devlink |
---|
| 1580 | + * can't tell which of these dependencies is not a real dependency. |
---|
1238 | 1581 | * |
---|
1239 | | - * While fw_devlink is paused: |
---|
1240 | | - * - Any device that is added won't have its fwnode parsed to create device |
---|
1241 | | - * links. |
---|
1242 | | - * - The probe of the device will also be deferred during this period. |
---|
1243 | | - * - Any devices that were already added, but waiting for suppliers won't be |
---|
1244 | | - * able to link to newly added devices. |
---|
1245 | | - * |
---|
1246 | | - * Once fw_devlink_resume(): |
---|
1247 | | - * - All the fwnodes that was not parsed will be parsed. |
---|
1248 | | - * - All the devices that were deferred probing will be reattempted if they |
---|
1249 | | - * aren't waiting for any more suppliers. |
---|
1250 | | - * |
---|
1251 | | - * This pair of functions, is mainly meant to optimize the parsing of fwnodes |
---|
1252 | | - * when a lot of devices that need to link to each other are added in a short |
---|
1253 | | - * interval of time. For example, adding all the top level devices in a system. |
---|
1254 | | - * |
---|
1255 | | - * For example, if N devices are added and: |
---|
1256 | | - * - All the consumers are added before their suppliers |
---|
1257 | | - * - All the suppliers of the N devices are part of the N devices |
---|
1258 | | - * |
---|
1259 | | - * Then: |
---|
1260 | | - * |
---|
1261 | | - * - With the use of fw_devlink_pause() and fw_devlink_resume(), each device |
---|
1262 | | - * will only need one parsing of its fwnode because it is guaranteed to find |
---|
1263 | | - * all the supplier devices already registered and ready to link to. It won't |
---|
1264 | | - * have to do another pass later to find one or more suppliers it couldn't |
---|
1265 | | - * find in the first parse of the fwnode. So, we'll only need O(N) fwnode |
---|
1266 | | - * parses. |
---|
1267 | | - * |
---|
1268 | | - * - Without the use of fw_devlink_pause() and fw_devlink_resume(), we would |
---|
1269 | | - * end up doing O(N^2) parses of fwnodes because every device that's added is |
---|
1270 | | - * guaranteed to trigger a parse of the fwnode of every device added before |
---|
1271 | | - * it. This O(N^2) parse is made worse by the fact that when a fwnode of a |
---|
1272 | | - * device is parsed, all it descendant devices might need to have their |
---|
1273 | | - * fwnodes parsed too (even if the devices themselves aren't added). |
---|
| 1582 | + * Return 1 if a cycle is found. Otherwise, return 0. |
---|
1274 | 1583 | */ |
---|
1275 | | -void fw_devlink_pause(void) |
---|
| 1584 | +int fw_devlink_relax_cycle(struct device *con, void *sup) |
---|
1276 | 1585 | { |
---|
1277 | | - mutex_lock(&defer_fw_devlink_lock); |
---|
1278 | | - defer_fw_devlink_count++; |
---|
1279 | | - mutex_unlock(&defer_fw_devlink_lock); |
---|
| 1586 | + struct device_link *link; |
---|
| 1587 | + int ret; |
---|
| 1588 | + |
---|
| 1589 | + if (con == sup) |
---|
| 1590 | + return 1; |
---|
| 1591 | + |
---|
| 1592 | + ret = device_for_each_child(con, sup, fw_devlink_relax_cycle); |
---|
| 1593 | + if (ret) |
---|
| 1594 | + return ret; |
---|
| 1595 | + |
---|
| 1596 | + list_for_each_entry(link, &con->links.consumers, s_node) { |
---|
| 1597 | + if ((link->flags & ~DL_FLAG_INFERRED) == |
---|
| 1598 | + (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) |
---|
| 1599 | + continue; |
---|
| 1600 | + |
---|
| 1601 | + if (!fw_devlink_relax_cycle(link->consumer, sup)) |
---|
| 1602 | + continue; |
---|
| 1603 | + |
---|
| 1604 | + ret = 1; |
---|
| 1605 | + |
---|
| 1606 | + if (!(link->flags & DL_FLAG_INFERRED)) |
---|
| 1607 | + continue; |
---|
| 1608 | + |
---|
| 1609 | + pm_runtime_drop_link(link); |
---|
| 1610 | + link->flags = DL_FLAG_MANAGED | FW_DEVLINK_FLAGS_PERMISSIVE; |
---|
| 1611 | + dev_dbg(link->consumer, "Relaxing link with %s\n", |
---|
| 1612 | + dev_name(link->supplier)); |
---|
| 1613 | + } |
---|
| 1614 | + return ret; |
---|
1280 | 1615 | } |
---|
1281 | 1616 | |
---|
1282 | | -/** fw_devlink_resume - Resume parsing of fwnode to create device links |
---|
| 1617 | +/** |
---|
| 1618 | + * fw_devlink_create_devlink - Create a device link from a consumer to fwnode |
---|
| 1619 | + * @con - Consumer device for the device link |
---|
| 1620 | + * @sup_handle - fwnode handle of supplier |
---|
1283 | 1621 | * |
---|
1284 | | - * This function is used in conjunction with fw_devlink_pause() and is ref |
---|
1285 | | - * counted. See documentation for fw_devlink_pause() for more details. |
---|
| 1622 | + * This function will try to create a device link between the consumer device |
---|
| 1623 | + * @con and the supplier device represented by @sup_handle. |
---|
| 1624 | + * |
---|
| 1625 | + * The supplier has to be provided as a fwnode because incorrect cycles in |
---|
| 1626 | + * fwnode links can sometimes cause the supplier device to never be created. |
---|
| 1627 | + * This function detects such cases and returns an error if it cannot create a |
---|
| 1628 | + * device link from the consumer to a missing supplier. |
---|
| 1629 | + * |
---|
| 1630 | + * Returns, |
---|
| 1631 | + * 0 on successfully creating a device link |
---|
| 1632 | + * -EINVAL if the device link cannot be created as expected |
---|
| 1633 | + * -EAGAIN if the device link cannot be created right now, but it may be |
---|
| 1634 | + * possible to do that in the future |
---|
1286 | 1635 | */ |
---|
1287 | | -void fw_devlink_resume(void) |
---|
| 1636 | +static int fw_devlink_create_devlink(struct device *con, |
---|
| 1637 | + struct fwnode_handle *sup_handle, u32 flags) |
---|
1288 | 1638 | { |
---|
1289 | | - struct device *dev, *tmp; |
---|
1290 | | - LIST_HEAD(probe_list); |
---|
| 1639 | + struct device *sup_dev; |
---|
| 1640 | + int ret = 0; |
---|
1291 | 1641 | |
---|
1292 | | - mutex_lock(&defer_fw_devlink_lock); |
---|
1293 | | - if (!defer_fw_devlink_count) { |
---|
1294 | | - WARN(true, "Unmatched fw_devlink pause/resume!"); |
---|
| 1642 | + sup_dev = get_dev_from_fwnode(sup_handle); |
---|
| 1643 | + if (sup_dev) { |
---|
| 1644 | + /* |
---|
| 1645 | + * If it's one of those drivers that don't actually bind to |
---|
| 1646 | + * their device using driver core, then don't wait on this |
---|
| 1647 | + * supplier device indefinitely. |
---|
| 1648 | + */ |
---|
| 1649 | + if (sup_dev->links.status == DL_DEV_NO_DRIVER && |
---|
| 1650 | + sup_handle->flags & FWNODE_FLAG_INITIALIZED) { |
---|
| 1651 | + ret = -EINVAL; |
---|
| 1652 | + goto out; |
---|
| 1653 | + } |
---|
| 1654 | + |
---|
| 1655 | + /* |
---|
| 1656 | + * If this fails, it is due to cycles in device links. Just |
---|
| 1657 | + * give up on this link and treat it as invalid. |
---|
| 1658 | + */ |
---|
| 1659 | + if (!device_link_add(con, sup_dev, flags) && |
---|
| 1660 | + !(flags & DL_FLAG_SYNC_STATE_ONLY)) { |
---|
| 1661 | + dev_info(con, "Fixing up cyclic dependency with %s\n", |
---|
| 1662 | + dev_name(sup_dev)); |
---|
| 1663 | + device_links_write_lock(); |
---|
| 1664 | + fw_devlink_relax_cycle(con, sup_dev); |
---|
| 1665 | + device_links_write_unlock(); |
---|
| 1666 | + device_link_add(con, sup_dev, |
---|
| 1667 | + FW_DEVLINK_FLAGS_PERMISSIVE); |
---|
| 1668 | + ret = -EINVAL; |
---|
| 1669 | + } |
---|
| 1670 | + |
---|
1295 | 1671 | goto out; |
---|
1296 | 1672 | } |
---|
1297 | 1673 | |
---|
1298 | | - defer_fw_devlink_count--; |
---|
1299 | | - if (defer_fw_devlink_count) |
---|
1300 | | - goto out; |
---|
1301 | | - |
---|
1302 | | - device_link_add_missing_supplier_links(); |
---|
1303 | | - list_splice_tail_init(&deferred_fw_devlink, &probe_list); |
---|
1304 | | -out: |
---|
1305 | | - mutex_unlock(&defer_fw_devlink_lock); |
---|
| 1674 | + /* Supplier that's already initialized without a struct device. */ |
---|
| 1675 | + if (sup_handle->flags & FWNODE_FLAG_INITIALIZED) |
---|
| 1676 | + return -EINVAL; |
---|
1306 | 1677 | |
---|
1307 | 1678 | /* |
---|
1308 | | - * bus_probe_device() can cause new devices to get added and they'll |
---|
1309 | | - * try to grab defer_fw_devlink_lock. So, this needs to be done outside |
---|
1310 | | - * the defer_fw_devlink_lock. |
---|
| 1679 | + * DL_FLAG_SYNC_STATE_ONLY doesn't block probing and supports |
---|
| 1680 | + * cycles. So cycle detection isn't necessary and shouldn't be |
---|
| 1681 | + * done. |
---|
1311 | 1682 | */ |
---|
1312 | | - list_for_each_entry_safe(dev, tmp, &probe_list, links.defer_hook) { |
---|
1313 | | - list_del_init(&dev->links.defer_hook); |
---|
1314 | | - bus_probe_device(dev); |
---|
| 1683 | + if (flags & DL_FLAG_SYNC_STATE_ONLY) |
---|
| 1684 | + return -EAGAIN; |
---|
| 1685 | + |
---|
| 1686 | + /* |
---|
| 1687 | + * If we can't find the supplier device from its fwnode, it might be |
---|
| 1688 | + * due to a cyclic dependency between fwnodes. Some of these cycles can |
---|
| 1689 | + * be broken by applying logic. Check for these types of cycles and |
---|
| 1690 | + * break them so that devices in the cycle probe properly. |
---|
| 1691 | + * |
---|
| 1692 | + * If the supplier's parent is dependent on the consumer, then the |
---|
| 1693 | + * consumer and supplier have a cyclic dependency. Since fw_devlink |
---|
| 1694 | + * can't tell which of the inferred dependencies are incorrect, don't |
---|
| 1695 | + * enforce probe ordering between any of the devices in this cyclic |
---|
| 1696 | + * dependency. Do this by relaxing all the fw_devlink device links in |
---|
| 1697 | + * this cycle and by treating the fwnode link between the consumer and |
---|
| 1698 | + * the supplier as an invalid dependency. |
---|
| 1699 | + */ |
---|
| 1700 | + sup_dev = fwnode_get_next_parent_dev(sup_handle); |
---|
| 1701 | + if (sup_dev && device_is_dependent(con, sup_dev)) { |
---|
| 1702 | + dev_info(con, "Fixing up cyclic dependency with %pfwP (%s)\n", |
---|
| 1703 | + sup_handle, dev_name(sup_dev)); |
---|
| 1704 | + device_links_write_lock(); |
---|
| 1705 | + fw_devlink_relax_cycle(con, sup_dev); |
---|
| 1706 | + device_links_write_unlock(); |
---|
| 1707 | + ret = -EINVAL; |
---|
| 1708 | + } else { |
---|
| 1709 | + /* |
---|
| 1710 | + * Can't check for cycles or no cycles. So let's try |
---|
| 1711 | + * again later. |
---|
| 1712 | + */ |
---|
| 1713 | + ret = -EAGAIN; |
---|
| 1714 | + } |
---|
| 1715 | + |
---|
| 1716 | +out: |
---|
| 1717 | + put_device(sup_dev); |
---|
| 1718 | + return ret; |
---|
| 1719 | +} |
---|
| 1720 | + |
---|
| 1721 | +/** |
---|
| 1722 | + * __fw_devlink_link_to_consumers - Create device links to consumers of a device |
---|
| 1723 | + * @dev - Device that needs to be linked to its consumers |
---|
| 1724 | + * |
---|
| 1725 | + * This function looks at all the consumer fwnodes of @dev and creates device |
---|
| 1726 | + * links between the consumer device and @dev (supplier). |
---|
| 1727 | + * |
---|
| 1728 | + * If the consumer device has not been added yet, then this function creates a |
---|
| 1729 | + * SYNC_STATE_ONLY link between @dev (supplier) and the closest ancestor device |
---|
| 1730 | + * of the consumer fwnode. This is necessary to make sure @dev doesn't get a |
---|
| 1731 | + * sync_state() callback before the real consumer device gets to be added and |
---|
| 1732 | + * then probed. |
---|
| 1733 | + * |
---|
| 1734 | + * Once device links are created from the real consumer to @dev (supplier), the |
---|
| 1735 | + * fwnode links are deleted. |
---|
| 1736 | + */ |
---|
| 1737 | +static void __fw_devlink_link_to_consumers(struct device *dev) |
---|
| 1738 | +{ |
---|
| 1739 | + struct fwnode_handle *fwnode = dev->fwnode; |
---|
| 1740 | + struct fwnode_link *link, *tmp; |
---|
| 1741 | + |
---|
| 1742 | + list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook) { |
---|
| 1743 | + u32 dl_flags = fw_devlink_get_flags(); |
---|
| 1744 | + struct device *con_dev; |
---|
| 1745 | + bool own_link = true; |
---|
| 1746 | + int ret; |
---|
| 1747 | + |
---|
| 1748 | + con_dev = get_dev_from_fwnode(link->consumer); |
---|
| 1749 | + /* |
---|
| 1750 | + * If consumer device is not available yet, make a "proxy" |
---|
| 1751 | + * SYNC_STATE_ONLY link from the consumer's parent device to |
---|
| 1752 | + * the supplier device. This is necessary to make sure the |
---|
| 1753 | + * supplier doesn't get a sync_state() callback before the real |
---|
| 1754 | + * consumer can create a device link to the supplier. |
---|
| 1755 | + * |
---|
| 1756 | + * This proxy link step is needed to handle the case where the |
---|
| 1757 | + * consumer's parent device is added before the supplier. |
---|
| 1758 | + */ |
---|
| 1759 | + if (!con_dev) { |
---|
| 1760 | + con_dev = fwnode_get_next_parent_dev(link->consumer); |
---|
| 1761 | + /* |
---|
| 1762 | + * However, if the consumer's parent device is also the |
---|
| 1763 | + * parent of the supplier, don't create a |
---|
| 1764 | + * consumer-supplier link from the parent to its child |
---|
| 1765 | + * device. Such a dependency is impossible. |
---|
| 1766 | + */ |
---|
| 1767 | + if (con_dev && |
---|
| 1768 | + fwnode_is_ancestor_of(con_dev->fwnode, fwnode)) { |
---|
| 1769 | + put_device(con_dev); |
---|
| 1770 | + con_dev = NULL; |
---|
| 1771 | + } else { |
---|
| 1772 | + own_link = false; |
---|
| 1773 | + dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE; |
---|
| 1774 | + } |
---|
| 1775 | + } |
---|
| 1776 | + |
---|
| 1777 | + if (!con_dev) |
---|
| 1778 | + continue; |
---|
| 1779 | + |
---|
| 1780 | + ret = fw_devlink_create_devlink(con_dev, fwnode, dl_flags); |
---|
| 1781 | + put_device(con_dev); |
---|
| 1782 | + if (!own_link || ret == -EAGAIN) |
---|
| 1783 | + continue; |
---|
| 1784 | + |
---|
| 1785 | + list_del(&link->s_hook); |
---|
| 1786 | + list_del(&link->c_hook); |
---|
| 1787 | + kfree(link); |
---|
1315 | 1788 | } |
---|
1316 | 1789 | } |
---|
| 1790 | + |
---|
| 1791 | +/** |
---|
| 1792 | + * __fw_devlink_link_to_suppliers - Create device links to suppliers of a device |
---|
| 1793 | + * @dev - The consumer device that needs to be linked to its suppliers |
---|
| 1794 | + * @fwnode - Root of the fwnode tree that is used to create device links |
---|
| 1795 | + * |
---|
| 1796 | + * This function looks at all the supplier fwnodes of fwnode tree rooted at |
---|
| 1797 | + * @fwnode and creates device links between @dev (consumer) and all the |
---|
| 1798 | + * supplier devices of the entire fwnode tree at @fwnode. |
---|
| 1799 | + * |
---|
| 1800 | + * The function creates normal (non-SYNC_STATE_ONLY) device links between @dev |
---|
| 1801 | + * and the real suppliers of @dev. Once these device links are created, the |
---|
| 1802 | + * fwnode links are deleted. When such device links are successfully created, |
---|
| 1803 | + * this function is called recursively on those supplier devices. This is |
---|
| 1804 | + * needed to detect and break some invalid cycles in fwnode links. See |
---|
| 1805 | + * fw_devlink_create_devlink() for more details. |
---|
| 1806 | + * |
---|
| 1807 | + * In addition, it also looks at all the suppliers of the entire fwnode tree |
---|
| 1808 | + * because some of the child devices of @dev that have not been added yet |
---|
| 1809 | + * (because @dev hasn't probed) might already have their suppliers added to |
---|
| 1810 | + * driver core. So, this function creates SYNC_STATE_ONLY device links between |
---|
| 1811 | + * @dev (consumer) and these suppliers to make sure they don't execute their |
---|
| 1812 | + * sync_state() callbacks before these child devices have a chance to create |
---|
| 1813 | + * their device links. The fwnode links that correspond to the child devices |
---|
| 1814 | + * aren't delete because they are needed later to create the device links |
---|
| 1815 | + * between the real consumer and supplier devices. |
---|
| 1816 | + */ |
---|
| 1817 | +static void __fw_devlink_link_to_suppliers(struct device *dev, |
---|
| 1818 | + struct fwnode_handle *fwnode) |
---|
| 1819 | +{ |
---|
| 1820 | + bool own_link = (dev->fwnode == fwnode); |
---|
| 1821 | + struct fwnode_link *link, *tmp; |
---|
| 1822 | + struct fwnode_handle *child = NULL; |
---|
| 1823 | + u32 dl_flags; |
---|
| 1824 | + |
---|
| 1825 | + if (own_link) |
---|
| 1826 | + dl_flags = fw_devlink_get_flags(); |
---|
| 1827 | + else |
---|
| 1828 | + dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE; |
---|
| 1829 | + |
---|
| 1830 | + list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) { |
---|
| 1831 | + int ret; |
---|
| 1832 | + struct device *sup_dev; |
---|
| 1833 | + struct fwnode_handle *sup = link->supplier; |
---|
| 1834 | + |
---|
| 1835 | + ret = fw_devlink_create_devlink(dev, sup, dl_flags); |
---|
| 1836 | + if (!own_link || ret == -EAGAIN) |
---|
| 1837 | + continue; |
---|
| 1838 | + |
---|
| 1839 | + list_del(&link->s_hook); |
---|
| 1840 | + list_del(&link->c_hook); |
---|
| 1841 | + kfree(link); |
---|
| 1842 | + |
---|
| 1843 | + /* If no device link was created, nothing more to do. */ |
---|
| 1844 | + if (ret) |
---|
| 1845 | + continue; |
---|
| 1846 | + |
---|
| 1847 | + /* |
---|
| 1848 | + * If a device link was successfully created to a supplier, we |
---|
| 1849 | + * now need to try and link the supplier to all its suppliers. |
---|
| 1850 | + * |
---|
| 1851 | + * This is needed to detect and delete false dependencies in |
---|
| 1852 | + * fwnode links that haven't been converted to a device link |
---|
| 1853 | + * yet. See comments in fw_devlink_create_devlink() for more |
---|
| 1854 | + * details on the false dependency. |
---|
| 1855 | + * |
---|
| 1856 | + * Without deleting these false dependencies, some devices will |
---|
| 1857 | + * never probe because they'll keep waiting for their false |
---|
| 1858 | + * dependency fwnode links to be converted to device links. |
---|
| 1859 | + */ |
---|
| 1860 | + sup_dev = get_dev_from_fwnode(sup); |
---|
| 1861 | + __fw_devlink_link_to_suppliers(sup_dev, sup_dev->fwnode); |
---|
| 1862 | + put_device(sup_dev); |
---|
| 1863 | + } |
---|
| 1864 | + |
---|
| 1865 | + /* |
---|
| 1866 | + * Make "proxy" SYNC_STATE_ONLY device links to represent the needs of |
---|
| 1867 | + * all the descendants. This proxy link step is needed to handle the |
---|
| 1868 | + * case where the supplier is added before the consumer's parent device |
---|
| 1869 | + * (@dev). |
---|
| 1870 | + */ |
---|
| 1871 | + while ((child = fwnode_get_next_available_child_node(fwnode, child))) |
---|
| 1872 | + __fw_devlink_link_to_suppliers(dev, child); |
---|
| 1873 | +} |
---|
| 1874 | + |
---|
| 1875 | +static void fw_devlink_link_device(struct device *dev) |
---|
| 1876 | +{ |
---|
| 1877 | + struct fwnode_handle *fwnode = dev->fwnode; |
---|
| 1878 | + |
---|
| 1879 | + if (!fw_devlink_flags) |
---|
| 1880 | + return; |
---|
| 1881 | + |
---|
| 1882 | + fw_devlink_parse_fwtree(fwnode); |
---|
| 1883 | + |
---|
| 1884 | + mutex_lock(&fwnode_link_lock); |
---|
| 1885 | + __fw_devlink_link_to_consumers(dev); |
---|
| 1886 | + __fw_devlink_link_to_suppliers(dev, fwnode); |
---|
| 1887 | + mutex_unlock(&fwnode_link_lock); |
---|
| 1888 | +} |
---|
| 1889 | + |
---|
1317 | 1890 | /* Device links support end. */ |
---|
1318 | 1891 | |
---|
1319 | 1892 | int (*platform_notify)(struct device *dev) = NULL; |
---|
.. | .. |
---|
1356 | 1929 | } |
---|
1357 | 1930 | #endif |
---|
1358 | 1931 | |
---|
| 1932 | +static int |
---|
| 1933 | +device_platform_notify(struct device *dev, enum kobject_action action) |
---|
| 1934 | +{ |
---|
| 1935 | + int ret; |
---|
| 1936 | + |
---|
| 1937 | + ret = acpi_platform_notify(dev, action); |
---|
| 1938 | + if (ret) |
---|
| 1939 | + return ret; |
---|
| 1940 | + |
---|
| 1941 | + ret = software_node_notify(dev, action); |
---|
| 1942 | + if (ret) |
---|
| 1943 | + return ret; |
---|
| 1944 | + |
---|
| 1945 | + if (platform_notify && action == KOBJ_ADD) |
---|
| 1946 | + platform_notify(dev); |
---|
| 1947 | + else if (platform_notify_remove && action == KOBJ_REMOVE) |
---|
| 1948 | + platform_notify_remove(dev); |
---|
| 1949 | + return 0; |
---|
| 1950 | +} |
---|
| 1951 | + |
---|
1359 | 1952 | /** |
---|
1360 | 1953 | * dev_driver_string - Return a device's driver name, if at all possible |
---|
1361 | 1954 | * @dev: struct device to get the name of |
---|
.. | .. |
---|
1374 | 1967 | * never change once they are set, so they don't need special care. |
---|
1375 | 1968 | */ |
---|
1376 | 1969 | drv = READ_ONCE(dev->driver); |
---|
1377 | | - return drv ? drv->name : |
---|
1378 | | - (dev->bus ? dev->bus->name : |
---|
1379 | | - (dev->class ? dev->class->name : "")); |
---|
| 1970 | + return drv ? drv->name : dev_bus_name(dev); |
---|
1380 | 1971 | } |
---|
1381 | 1972 | EXPORT_SYMBOL(dev_driver_string); |
---|
1382 | 1973 | |
---|
.. | .. |
---|
1422 | 2013 | const char *buf, size_t size) |
---|
1423 | 2014 | { |
---|
1424 | 2015 | struct dev_ext_attribute *ea = to_ext_attr(attr); |
---|
1425 | | - char *end; |
---|
1426 | | - unsigned long new = simple_strtoul(buf, &end, 0); |
---|
1427 | | - if (end == buf) |
---|
1428 | | - return -EINVAL; |
---|
| 2016 | + int ret; |
---|
| 2017 | + unsigned long new; |
---|
| 2018 | + |
---|
| 2019 | + ret = kstrtoul(buf, 0, &new); |
---|
| 2020 | + if (ret) |
---|
| 2021 | + return ret; |
---|
1429 | 2022 | *(unsigned long *)(ea->var) = new; |
---|
1430 | 2023 | /* Always return full write size even if we didn't consume all */ |
---|
1431 | 2024 | return size; |
---|
.. | .. |
---|
1437 | 2030 | char *buf) |
---|
1438 | 2031 | { |
---|
1439 | 2032 | struct dev_ext_attribute *ea = to_ext_attr(attr); |
---|
1440 | | - return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); |
---|
| 2033 | + return sysfs_emit(buf, "%lx\n", *(unsigned long *)(ea->var)); |
---|
1441 | 2034 | } |
---|
1442 | 2035 | EXPORT_SYMBOL_GPL(device_show_ulong); |
---|
1443 | 2036 | |
---|
.. | .. |
---|
1446 | 2039 | const char *buf, size_t size) |
---|
1447 | 2040 | { |
---|
1448 | 2041 | struct dev_ext_attribute *ea = to_ext_attr(attr); |
---|
1449 | | - char *end; |
---|
1450 | | - long new = simple_strtol(buf, &end, 0); |
---|
1451 | | - if (end == buf || new > INT_MAX || new < INT_MIN) |
---|
| 2042 | + int ret; |
---|
| 2043 | + long new; |
---|
| 2044 | + |
---|
| 2045 | + ret = kstrtol(buf, 0, &new); |
---|
| 2046 | + if (ret) |
---|
| 2047 | + return ret; |
---|
| 2048 | + |
---|
| 2049 | + if (new > INT_MAX || new < INT_MIN) |
---|
1452 | 2050 | return -EINVAL; |
---|
1453 | 2051 | *(int *)(ea->var) = new; |
---|
1454 | 2052 | /* Always return full write size even if we didn't consume all */ |
---|
.. | .. |
---|
1462 | 2060 | { |
---|
1463 | 2061 | struct dev_ext_attribute *ea = to_ext_attr(attr); |
---|
1464 | 2062 | |
---|
1465 | | - return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); |
---|
| 2063 | + return sysfs_emit(buf, "%d\n", *(int *)(ea->var)); |
---|
1466 | 2064 | } |
---|
1467 | 2065 | EXPORT_SYMBOL_GPL(device_show_int); |
---|
1468 | 2066 | |
---|
.. | .. |
---|
1483 | 2081 | { |
---|
1484 | 2082 | struct dev_ext_attribute *ea = to_ext_attr(attr); |
---|
1485 | 2083 | |
---|
1486 | | - return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); |
---|
| 2084 | + return sysfs_emit(buf, "%d\n", *(bool *)(ea->var)); |
---|
1487 | 2085 | } |
---|
1488 | 2086 | EXPORT_SYMBOL_GPL(device_show_bool); |
---|
1489 | 2087 | |
---|
.. | .. |
---|
1511 | 2109 | */ |
---|
1512 | 2110 | devres_release_all(dev); |
---|
1513 | 2111 | |
---|
| 2112 | + kfree(dev->dma_range_map); |
---|
| 2113 | + |
---|
1514 | 2114 | if (dev->release) |
---|
1515 | 2115 | dev->release(dev); |
---|
1516 | 2116 | else if (dev->type && dev->type->release) |
---|
.. | .. |
---|
1518 | 2118 | else if (dev->class && dev->class->dev_release) |
---|
1519 | 2119 | dev->class->dev_release(dev); |
---|
1520 | 2120 | else |
---|
1521 | | - WARN(1, KERN_ERR "Device '%s' does not have a release() " |
---|
1522 | | - "function, it is broken and must be fixed.\n", |
---|
| 2121 | + WARN(1, KERN_ERR "Device '%s' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.\n", |
---|
1523 | 2122 | dev_name(dev)); |
---|
1524 | 2123 | kfree(p); |
---|
1525 | 2124 | } |
---|
.. | .. |
---|
1656 | 2255 | struct kset *kset; |
---|
1657 | 2256 | struct kobj_uevent_env *env = NULL; |
---|
1658 | 2257 | int i; |
---|
1659 | | - size_t count = 0; |
---|
| 2258 | + int len = 0; |
---|
1660 | 2259 | int retval; |
---|
1661 | 2260 | |
---|
1662 | 2261 | /* search the kset, the device belongs to */ |
---|
.. | .. |
---|
1686 | 2285 | |
---|
1687 | 2286 | /* copy keys to file */ |
---|
1688 | 2287 | for (i = 0; i < env->envp_idx; i++) |
---|
1689 | | - count += sprintf(&buf[count], "%s\n", env->envp[i]); |
---|
| 2288 | + len += sysfs_emit_at(buf, len, "%s\n", env->envp[i]); |
---|
1690 | 2289 | out: |
---|
1691 | 2290 | kfree(env); |
---|
1692 | | - return count; |
---|
| 2291 | + return len; |
---|
1693 | 2292 | } |
---|
1694 | 2293 | |
---|
1695 | 2294 | static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, |
---|
.. | .. |
---|
1716 | 2315 | device_lock(dev); |
---|
1717 | 2316 | val = !dev->offline; |
---|
1718 | 2317 | device_unlock(dev); |
---|
1719 | | - return sprintf(buf, "%u\n", val); |
---|
| 2318 | + return sysfs_emit(buf, "%u\n", val); |
---|
1720 | 2319 | } |
---|
1721 | 2320 | |
---|
1722 | 2321 | static ssize_t online_store(struct device *dev, struct device_attribute *attr, |
---|
.. | .. |
---|
1910 | 2509 | goto err_remove_dev_groups; |
---|
1911 | 2510 | } |
---|
1912 | 2511 | |
---|
| 2512 | + if (fw_devlink_flags && !fw_devlink_is_permissive() && dev->fwnode) { |
---|
| 2513 | + error = device_create_file(dev, &dev_attr_waiting_for_supplier); |
---|
| 2514 | + if (error) |
---|
| 2515 | + goto err_remove_dev_online; |
---|
| 2516 | + } |
---|
| 2517 | + |
---|
1913 | 2518 | return 0; |
---|
1914 | 2519 | |
---|
| 2520 | + err_remove_dev_online: |
---|
| 2521 | + device_remove_file(dev, &dev_attr_online); |
---|
1915 | 2522 | err_remove_dev_groups: |
---|
1916 | 2523 | device_remove_groups(dev, dev->groups); |
---|
1917 | 2524 | err_remove_type_groups: |
---|
.. | .. |
---|
1929 | 2536 | struct class *class = dev->class; |
---|
1930 | 2537 | const struct device_type *type = dev->type; |
---|
1931 | 2538 | |
---|
| 2539 | + device_remove_file(dev, &dev_attr_waiting_for_supplier); |
---|
1932 | 2540 | device_remove_file(dev, &dev_attr_online); |
---|
1933 | 2541 | device_remove_groups(dev, dev->groups); |
---|
1934 | 2542 | |
---|
.. | .. |
---|
2119 | 2727 | kobject_init(&dev->kobj, &device_ktype); |
---|
2120 | 2728 | INIT_LIST_HEAD(&dev->dma_pools); |
---|
2121 | 2729 | mutex_init(&dev->mutex); |
---|
| 2730 | +#ifdef CONFIG_PROVE_LOCKING |
---|
| 2731 | + mutex_init(&dev->lockdep_mutex); |
---|
| 2732 | +#endif |
---|
2122 | 2733 | lockdep_set_novalidate_class(&dev->mutex); |
---|
2123 | 2734 | spin_lock_init(&dev->devres_lock); |
---|
2124 | 2735 | INIT_LIST_HEAD(&dev->devres_head); |
---|
.. | .. |
---|
2129 | 2740 | #endif |
---|
2130 | 2741 | INIT_LIST_HEAD(&dev->links.consumers); |
---|
2131 | 2742 | INIT_LIST_HEAD(&dev->links.suppliers); |
---|
2132 | | - INIT_LIST_HEAD(&dev->links.needs_suppliers); |
---|
2133 | | - INIT_LIST_HEAD(&dev->links.defer_hook); |
---|
| 2743 | + INIT_LIST_HEAD(&dev->links.defer_sync); |
---|
2134 | 2744 | dev->links.status = DL_DEV_NO_DRIVER; |
---|
2135 | 2745 | } |
---|
2136 | 2746 | EXPORT_SYMBOL_GPL(device_initialize); |
---|
.. | .. |
---|
2508 | 3118 | * NOTE: _Never_ directly free @dev after calling this function, even |
---|
2509 | 3119 | * if it returned an error! Always use put_device() to give up your |
---|
2510 | 3120 | * reference instead. |
---|
| 3121 | + * |
---|
| 3122 | + * Rule of thumb is: if device_add() succeeds, you should call |
---|
| 3123 | + * device_del() when you want to get rid of it. If device_add() has |
---|
| 3124 | + * *not* succeeded, use *only* put_device() to drop the reference |
---|
| 3125 | + * count. |
---|
2511 | 3126 | */ |
---|
2512 | 3127 | int device_add(struct device *dev) |
---|
2513 | 3128 | { |
---|
.. | .. |
---|
2570 | 3185 | } |
---|
2571 | 3186 | |
---|
2572 | 3187 | /* notify platform of device entry */ |
---|
2573 | | - if (platform_notify) |
---|
2574 | | - platform_notify(dev); |
---|
| 3188 | + error = device_platform_notify(dev, KOBJ_ADD); |
---|
| 3189 | + if (error) |
---|
| 3190 | + goto platform_error; |
---|
2575 | 3191 | |
---|
2576 | 3192 | error = device_create_file(dev, &dev_attr_uevent); |
---|
2577 | 3193 | if (error) |
---|
.. | .. |
---|
2637 | 3253 | if (dev->class) { |
---|
2638 | 3254 | mutex_lock(&dev->class->p->mutex); |
---|
2639 | 3255 | /* tie the class to the device */ |
---|
2640 | | - klist_add_tail(&dev->knode_class, |
---|
| 3256 | + klist_add_tail(&dev->p->knode_class, |
---|
2641 | 3257 | &dev->class->p->klist_devices); |
---|
2642 | 3258 | |
---|
2643 | 3259 | /* notify any interfaces that the device is here */ |
---|
.. | .. |
---|
2665 | 3281 | SymlinkError: |
---|
2666 | 3282 | device_remove_file(dev, &dev_attr_uevent); |
---|
2667 | 3283 | attrError: |
---|
| 3284 | + device_platform_notify(dev, KOBJ_REMOVE); |
---|
| 3285 | +platform_error: |
---|
2668 | 3286 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
---|
2669 | 3287 | glue_dir = get_glue_dir(dev); |
---|
2670 | 3288 | kobject_del(&dev->kobj); |
---|
.. | .. |
---|
2766 | 3384 | struct device *parent = dev->parent; |
---|
2767 | 3385 | struct kobject *glue_dir = NULL; |
---|
2768 | 3386 | struct class_interface *class_intf; |
---|
| 3387 | + unsigned int noio_flag; |
---|
2769 | 3388 | |
---|
2770 | 3389 | device_lock(dev); |
---|
2771 | 3390 | kill_device(dev); |
---|
.. | .. |
---|
2777 | 3396 | /* Notify clients of device removal. This call must come |
---|
2778 | 3397 | * before dpm_sysfs_remove(). |
---|
2779 | 3398 | */ |
---|
| 3399 | + noio_flag = memalloc_noio_save(); |
---|
2780 | 3400 | if (dev->bus) |
---|
2781 | 3401 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
---|
2782 | 3402 | BUS_NOTIFY_DEL_DEVICE, dev); |
---|
.. | .. |
---|
2799 | 3419 | if (class_intf->remove_dev) |
---|
2800 | 3420 | class_intf->remove_dev(dev, class_intf); |
---|
2801 | 3421 | /* remove the device from the class list */ |
---|
2802 | | - klist_del(&dev->knode_class); |
---|
| 3422 | + klist_del(&dev->p->knode_class); |
---|
2803 | 3423 | mutex_unlock(&dev->class->p->mutex); |
---|
2804 | 3424 | } |
---|
2805 | 3425 | device_remove_file(dev, &dev_attr_uevent); |
---|
.. | .. |
---|
2807 | 3427 | bus_remove_device(dev); |
---|
2808 | 3428 | device_pm_remove(dev); |
---|
2809 | 3429 | driver_deferred_probe_del(dev); |
---|
| 3430 | + device_platform_notify(dev, KOBJ_REMOVE); |
---|
2810 | 3431 | device_remove_properties(dev); |
---|
2811 | 3432 | device_links_purge(dev); |
---|
2812 | 3433 | |
---|
2813 | | - /* Notify the platform of the removal, in case they |
---|
2814 | | - * need to do anything... |
---|
2815 | | - */ |
---|
2816 | | - if (platform_notify_remove) |
---|
2817 | | - platform_notify_remove(dev); |
---|
2818 | 3434 | if (dev->bus) |
---|
2819 | 3435 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
---|
2820 | 3436 | BUS_NOTIFY_REMOVED_DEVICE, dev); |
---|
.. | .. |
---|
2822 | 3438 | glue_dir = get_glue_dir(dev); |
---|
2823 | 3439 | kobject_del(&dev->kobj); |
---|
2824 | 3440 | cleanup_glue_dir(dev, glue_dir); |
---|
| 3441 | + memalloc_noio_restore(noio_flag); |
---|
2825 | 3442 | put_device(parent); |
---|
2826 | 3443 | } |
---|
2827 | 3444 | EXPORT_SYMBOL_GPL(device_del); |
---|
.. | .. |
---|
3011 | 3628 | } |
---|
3012 | 3629 | EXPORT_SYMBOL_GPL(device_find_child); |
---|
3013 | 3630 | |
---|
| 3631 | +/** |
---|
| 3632 | + * device_find_child_by_name - device iterator for locating a child device. |
---|
| 3633 | + * @parent: parent struct device |
---|
| 3634 | + * @name: name of the child device |
---|
| 3635 | + * |
---|
| 3636 | + * This is similar to the device_find_child() function above, but it |
---|
| 3637 | + * returns a reference to a device that has the name @name. |
---|
| 3638 | + * |
---|
| 3639 | + * NOTE: you will need to drop the reference with put_device() after use. |
---|
| 3640 | + */ |
---|
| 3641 | +struct device *device_find_child_by_name(struct device *parent, |
---|
| 3642 | + const char *name) |
---|
| 3643 | +{ |
---|
| 3644 | + struct klist_iter i; |
---|
| 3645 | + struct device *child; |
---|
| 3646 | + |
---|
| 3647 | + if (!parent) |
---|
| 3648 | + return NULL; |
---|
| 3649 | + |
---|
| 3650 | + klist_iter_init(&parent->p->klist_children, &i); |
---|
| 3651 | + while ((child = next_device(&i))) |
---|
| 3652 | + if (sysfs_streq(dev_name(child), name) && get_device(child)) |
---|
| 3653 | + break; |
---|
| 3654 | + klist_iter_exit(&i); |
---|
| 3655 | + return child; |
---|
| 3656 | +} |
---|
| 3657 | +EXPORT_SYMBOL_GPL(device_find_child_by_name); |
---|
| 3658 | + |
---|
3014 | 3659 | int __init devices_init(void) |
---|
3015 | 3660 | { |
---|
3016 | 3661 | devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); |
---|
.. | .. |
---|
3117 | 3762 | |
---|
3118 | 3763 | return ret; |
---|
3119 | 3764 | } |
---|
3120 | | -EXPORT_SYMBOL_GPL(device_online); |
---|
3121 | 3765 | |
---|
3122 | 3766 | struct root_device { |
---|
3123 | 3767 | struct device dev; |
---|
.. | .. |
---|
3263 | 3907 | } |
---|
3264 | 3908 | |
---|
3265 | 3909 | /** |
---|
3266 | | - * device_create_vargs - creates a device and registers it with sysfs |
---|
3267 | | - * @class: pointer to the struct class that this device should be registered to |
---|
3268 | | - * @parent: pointer to the parent struct device of this new device, if any |
---|
3269 | | - * @devt: the dev_t for the char device to be added |
---|
3270 | | - * @drvdata: the data to be added to the device for callbacks |
---|
3271 | | - * @fmt: string for the device's name |
---|
3272 | | - * @args: va_list for the device's name |
---|
3273 | | - * |
---|
3274 | | - * This function can be used by char device classes. A struct device |
---|
3275 | | - * will be created in sysfs, registered to the specified class. |
---|
3276 | | - * |
---|
3277 | | - * A "dev" file will be created, showing the dev_t for the device, if |
---|
3278 | | - * the dev_t is not 0,0. |
---|
3279 | | - * If a pointer to a parent struct device is passed in, the newly created |
---|
3280 | | - * struct device will be a child of that device in sysfs. |
---|
3281 | | - * The pointer to the struct device will be returned from the call. |
---|
3282 | | - * Any further sysfs files that might be required can be created using this |
---|
3283 | | - * pointer. |
---|
3284 | | - * |
---|
3285 | | - * Returns &struct device pointer on success, or ERR_PTR() on error. |
---|
3286 | | - * |
---|
3287 | | - * Note: the struct class passed to this function must have previously |
---|
3288 | | - * been created with a call to class_create(). |
---|
3289 | | - */ |
---|
3290 | | -struct device *device_create_vargs(struct class *class, struct device *parent, |
---|
3291 | | - dev_t devt, void *drvdata, const char *fmt, |
---|
3292 | | - va_list args) |
---|
3293 | | -{ |
---|
3294 | | - return device_create_groups_vargs(class, parent, devt, drvdata, NULL, |
---|
3295 | | - fmt, args); |
---|
3296 | | -} |
---|
3297 | | -EXPORT_SYMBOL_GPL(device_create_vargs); |
---|
3298 | | - |
---|
3299 | | -/** |
---|
3300 | 3910 | * device_create - creates a device and registers it with sysfs |
---|
3301 | 3911 | * @class: pointer to the struct class that this device should be registered to |
---|
3302 | 3912 | * @parent: pointer to the parent struct device of this new device, if any |
---|
.. | .. |
---|
3327 | 3937 | struct device *dev; |
---|
3328 | 3938 | |
---|
3329 | 3939 | va_start(vargs, fmt); |
---|
3330 | | - dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); |
---|
| 3940 | + dev = device_create_groups_vargs(class, parent, devt, drvdata, NULL, |
---|
| 3941 | + fmt, vargs); |
---|
3331 | 3942 | va_end(vargs); |
---|
3332 | 3943 | return dev; |
---|
3333 | 3944 | } |
---|
.. | .. |
---|
3377 | 3988 | } |
---|
3378 | 3989 | EXPORT_SYMBOL_GPL(device_create_with_groups); |
---|
3379 | 3990 | |
---|
3380 | | -static int __match_devt(struct device *dev, const void *data) |
---|
3381 | | -{ |
---|
3382 | | - const dev_t *devt = data; |
---|
3383 | | - |
---|
3384 | | - return dev->devt == *devt; |
---|
3385 | | -} |
---|
3386 | | - |
---|
3387 | 3991 | /** |
---|
3388 | 3992 | * device_destroy - removes a device that was created with device_create() |
---|
3389 | 3993 | * @class: pointer to the struct class that this device was registered with |
---|
.. | .. |
---|
3396 | 4000 | { |
---|
3397 | 4001 | struct device *dev; |
---|
3398 | 4002 | |
---|
3399 | | - dev = class_find_device(class, NULL, &devt, __match_devt); |
---|
| 4003 | + dev = class_find_device_by_devt(class, devt); |
---|
3400 | 4004 | if (dev) { |
---|
3401 | 4005 | put_device(dev); |
---|
3402 | 4006 | device_unregister(dev); |
---|
.. | .. |
---|
3585 | 4189 | } |
---|
3586 | 4190 | EXPORT_SYMBOL_GPL(device_move); |
---|
3587 | 4191 | |
---|
| 4192 | +static int device_attrs_change_owner(struct device *dev, kuid_t kuid, |
---|
| 4193 | + kgid_t kgid) |
---|
| 4194 | +{ |
---|
| 4195 | + struct kobject *kobj = &dev->kobj; |
---|
| 4196 | + struct class *class = dev->class; |
---|
| 4197 | + const struct device_type *type = dev->type; |
---|
| 4198 | + int error; |
---|
| 4199 | + |
---|
| 4200 | + if (class) { |
---|
| 4201 | + /* |
---|
| 4202 | + * Change the device groups of the device class for @dev to |
---|
| 4203 | + * @kuid/@kgid. |
---|
| 4204 | + */ |
---|
| 4205 | + error = sysfs_groups_change_owner(kobj, class->dev_groups, kuid, |
---|
| 4206 | + kgid); |
---|
| 4207 | + if (error) |
---|
| 4208 | + return error; |
---|
| 4209 | + } |
---|
| 4210 | + |
---|
| 4211 | + if (type) { |
---|
| 4212 | + /* |
---|
| 4213 | + * Change the device groups of the device type for @dev to |
---|
| 4214 | + * @kuid/@kgid. |
---|
| 4215 | + */ |
---|
| 4216 | + error = sysfs_groups_change_owner(kobj, type->groups, kuid, |
---|
| 4217 | + kgid); |
---|
| 4218 | + if (error) |
---|
| 4219 | + return error; |
---|
| 4220 | + } |
---|
| 4221 | + |
---|
| 4222 | + /* Change the device groups of @dev to @kuid/@kgid. */ |
---|
| 4223 | + error = sysfs_groups_change_owner(kobj, dev->groups, kuid, kgid); |
---|
| 4224 | + if (error) |
---|
| 4225 | + return error; |
---|
| 4226 | + |
---|
| 4227 | + if (device_supports_offline(dev) && !dev->offline_disabled) { |
---|
| 4228 | + /* Change online device attributes of @dev to @kuid/@kgid. */ |
---|
| 4229 | + error = sysfs_file_change_owner(kobj, dev_attr_online.attr.name, |
---|
| 4230 | + kuid, kgid); |
---|
| 4231 | + if (error) |
---|
| 4232 | + return error; |
---|
| 4233 | + } |
---|
| 4234 | + |
---|
| 4235 | + return 0; |
---|
| 4236 | +} |
---|
| 4237 | + |
---|
| 4238 | +/** |
---|
| 4239 | + * device_change_owner - change the owner of an existing device. |
---|
| 4240 | + * @dev: device. |
---|
| 4241 | + * @kuid: new owner's kuid |
---|
| 4242 | + * @kgid: new owner's kgid |
---|
| 4243 | + * |
---|
| 4244 | + * This changes the owner of @dev and its corresponding sysfs entries to |
---|
| 4245 | + * @kuid/@kgid. This function closely mirrors how @dev was added via driver |
---|
| 4246 | + * core. |
---|
| 4247 | + * |
---|
| 4248 | + * Returns 0 on success or error code on failure. |
---|
| 4249 | + */ |
---|
| 4250 | +int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) |
---|
| 4251 | +{ |
---|
| 4252 | + int error; |
---|
| 4253 | + struct kobject *kobj = &dev->kobj; |
---|
| 4254 | + |
---|
| 4255 | + dev = get_device(dev); |
---|
| 4256 | + if (!dev) |
---|
| 4257 | + return -EINVAL; |
---|
| 4258 | + |
---|
| 4259 | + /* |
---|
| 4260 | + * Change the kobject and the default attributes and groups of the |
---|
| 4261 | + * ktype associated with it to @kuid/@kgid. |
---|
| 4262 | + */ |
---|
| 4263 | + error = sysfs_change_owner(kobj, kuid, kgid); |
---|
| 4264 | + if (error) |
---|
| 4265 | + goto out; |
---|
| 4266 | + |
---|
| 4267 | + /* |
---|
| 4268 | + * Change the uevent file for @dev to the new owner. The uevent file |
---|
| 4269 | + * was created in a separate step when @dev got added and we mirror |
---|
| 4270 | + * that step here. |
---|
| 4271 | + */ |
---|
| 4272 | + error = sysfs_file_change_owner(kobj, dev_attr_uevent.attr.name, kuid, |
---|
| 4273 | + kgid); |
---|
| 4274 | + if (error) |
---|
| 4275 | + goto out; |
---|
| 4276 | + |
---|
| 4277 | + /* |
---|
| 4278 | + * Change the device groups, the device groups associated with the |
---|
| 4279 | + * device class, and the groups associated with the device type of @dev |
---|
| 4280 | + * to @kuid/@kgid. |
---|
| 4281 | + */ |
---|
| 4282 | + error = device_attrs_change_owner(dev, kuid, kgid); |
---|
| 4283 | + if (error) |
---|
| 4284 | + goto out; |
---|
| 4285 | + |
---|
| 4286 | + error = dpm_sysfs_change_owner(dev, kuid, kgid); |
---|
| 4287 | + if (error) |
---|
| 4288 | + goto out; |
---|
| 4289 | + |
---|
| 4290 | +#ifdef CONFIG_BLOCK |
---|
| 4291 | + if (sysfs_deprecated && dev->class == &block_class) |
---|
| 4292 | + goto out; |
---|
| 4293 | +#endif |
---|
| 4294 | + |
---|
| 4295 | + /* |
---|
| 4296 | + * Change the owner of the symlink located in the class directory of |
---|
| 4297 | + * the device class associated with @dev which points to the actual |
---|
| 4298 | + * directory entry for @dev to @kuid/@kgid. This ensures that the |
---|
| 4299 | + * symlink shows the same permissions as its target. |
---|
| 4300 | + */ |
---|
| 4301 | + error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj, |
---|
| 4302 | + dev_name(dev), kuid, kgid); |
---|
| 4303 | + if (error) |
---|
| 4304 | + goto out; |
---|
| 4305 | + |
---|
| 4306 | +out: |
---|
| 4307 | + put_device(dev); |
---|
| 4308 | + return error; |
---|
| 4309 | +} |
---|
| 4310 | +EXPORT_SYMBOL_GPL(device_change_owner); |
---|
| 4311 | + |
---|
3588 | 4312 | /** |
---|
3589 | 4313 | * device_shutdown - call ->shutdown() on each device to shutdown. |
---|
3590 | 4314 | */ |
---|
.. | .. |
---|
3662 | 4386 | */ |
---|
3663 | 4387 | |
---|
3664 | 4388 | #ifdef CONFIG_PRINTK |
---|
3665 | | -static int |
---|
3666 | | -create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) |
---|
| 4389 | +static void |
---|
| 4390 | +set_dev_info(const struct device *dev, struct dev_printk_info *dev_info) |
---|
3667 | 4391 | { |
---|
3668 | 4392 | const char *subsys; |
---|
3669 | | - size_t pos = 0; |
---|
| 4393 | + |
---|
| 4394 | + memset(dev_info, 0, sizeof(*dev_info)); |
---|
3670 | 4395 | |
---|
3671 | 4396 | if (dev->class) |
---|
3672 | 4397 | subsys = dev->class->name; |
---|
3673 | 4398 | else if (dev->bus) |
---|
3674 | 4399 | subsys = dev->bus->name; |
---|
3675 | 4400 | else |
---|
3676 | | - return 0; |
---|
| 4401 | + return; |
---|
3677 | 4402 | |
---|
3678 | | - pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); |
---|
3679 | | - if (pos >= hdrlen) |
---|
3680 | | - goto overflow; |
---|
| 4403 | + strscpy(dev_info->subsystem, subsys, sizeof(dev_info->subsystem)); |
---|
3681 | 4404 | |
---|
3682 | 4405 | /* |
---|
3683 | 4406 | * Add device identifier DEVICE=: |
---|
.. | .. |
---|
3693 | 4416 | c = 'b'; |
---|
3694 | 4417 | else |
---|
3695 | 4418 | c = 'c'; |
---|
3696 | | - pos++; |
---|
3697 | | - pos += snprintf(hdr + pos, hdrlen - pos, |
---|
3698 | | - "DEVICE=%c%u:%u", |
---|
3699 | | - c, MAJOR(dev->devt), MINOR(dev->devt)); |
---|
| 4419 | + |
---|
| 4420 | + snprintf(dev_info->device, sizeof(dev_info->device), |
---|
| 4421 | + "%c%u:%u", c, MAJOR(dev->devt), MINOR(dev->devt)); |
---|
3700 | 4422 | } else if (strcmp(subsys, "net") == 0) { |
---|
3701 | 4423 | struct net_device *net = to_net_dev(dev); |
---|
3702 | 4424 | |
---|
3703 | | - pos++; |
---|
3704 | | - pos += snprintf(hdr + pos, hdrlen - pos, |
---|
3705 | | - "DEVICE=n%u", net->ifindex); |
---|
| 4425 | + snprintf(dev_info->device, sizeof(dev_info->device), |
---|
| 4426 | + "n%u", net->ifindex); |
---|
3706 | 4427 | } else { |
---|
3707 | | - pos++; |
---|
3708 | | - pos += snprintf(hdr + pos, hdrlen - pos, |
---|
3709 | | - "DEVICE=+%s:%s", subsys, dev_name(dev)); |
---|
| 4428 | + snprintf(dev_info->device, sizeof(dev_info->device), |
---|
| 4429 | + "+%s:%s", subsys, dev_name(dev)); |
---|
3710 | 4430 | } |
---|
3711 | | - |
---|
3712 | | - if (pos >= hdrlen) |
---|
3713 | | - goto overflow; |
---|
3714 | | - |
---|
3715 | | - return pos; |
---|
3716 | | - |
---|
3717 | | -overflow: |
---|
3718 | | - dev_WARN(dev, "device/subsystem name too long"); |
---|
3719 | | - return 0; |
---|
3720 | 4431 | } |
---|
3721 | 4432 | |
---|
3722 | 4433 | int dev_vprintk_emit(int level, const struct device *dev, |
---|
3723 | 4434 | const char *fmt, va_list args) |
---|
3724 | 4435 | { |
---|
3725 | | - char hdr[128]; |
---|
3726 | | - size_t hdrlen; |
---|
| 4436 | + struct dev_printk_info dev_info; |
---|
3727 | 4437 | |
---|
3728 | | - hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); |
---|
| 4438 | + set_dev_info(dev, &dev_info); |
---|
3729 | 4439 | |
---|
3730 | | - return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); |
---|
| 4440 | + return vprintk_emit(0, level, &dev_info, fmt, args); |
---|
3731 | 4441 | } |
---|
3732 | 4442 | EXPORT_SYMBOL(dev_vprintk_emit); |
---|
3733 | 4443 | |
---|
.. | .. |
---|
3800 | 4510 | |
---|
3801 | 4511 | #endif |
---|
3802 | 4512 | |
---|
| 4513 | +/** |
---|
| 4514 | + * dev_err_probe - probe error check and log helper |
---|
| 4515 | + * @dev: the pointer to the struct device |
---|
| 4516 | + * @err: error value to test |
---|
| 4517 | + * @fmt: printf-style format string |
---|
| 4518 | + * @...: arguments as specified in the format string |
---|
| 4519 | + * |
---|
| 4520 | + * This helper implements common pattern present in probe functions for error |
---|
| 4521 | + * checking: print debug or error message depending if the error value is |
---|
| 4522 | + * -EPROBE_DEFER and propagate error upwards. |
---|
| 4523 | + * In case of -EPROBE_DEFER it sets also defer probe reason, which can be |
---|
| 4524 | + * checked later by reading devices_deferred debugfs attribute. |
---|
| 4525 | + * It replaces code sequence:: |
---|
| 4526 | + * |
---|
| 4527 | + * if (err != -EPROBE_DEFER) |
---|
| 4528 | + * dev_err(dev, ...); |
---|
| 4529 | + * else |
---|
| 4530 | + * dev_dbg(dev, ...); |
---|
| 4531 | + * return err; |
---|
| 4532 | + * |
---|
| 4533 | + * with:: |
---|
| 4534 | + * |
---|
| 4535 | + * return dev_err_probe(dev, err, ...); |
---|
| 4536 | + * |
---|
| 4537 | + * Returns @err. |
---|
| 4538 | + * |
---|
| 4539 | + */ |
---|
| 4540 | +int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) |
---|
| 4541 | +{ |
---|
| 4542 | + struct va_format vaf; |
---|
| 4543 | + va_list args; |
---|
| 4544 | + |
---|
| 4545 | + va_start(args, fmt); |
---|
| 4546 | + vaf.fmt = fmt; |
---|
| 4547 | + vaf.va = &args; |
---|
| 4548 | + |
---|
| 4549 | + if (err != -EPROBE_DEFER) { |
---|
| 4550 | + dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); |
---|
| 4551 | + } else { |
---|
| 4552 | + device_set_deferred_probe_reason(dev, &vaf); |
---|
| 4553 | + dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); |
---|
| 4554 | + } |
---|
| 4555 | + |
---|
| 4556 | + va_end(args); |
---|
| 4557 | + |
---|
| 4558 | + return err; |
---|
| 4559 | +} |
---|
| 4560 | +EXPORT_SYMBOL_GPL(dev_err_probe); |
---|
| 4561 | + |
---|
3803 | 4562 | static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) |
---|
3804 | 4563 | { |
---|
3805 | 4564 | return fwnode && !IS_ERR(fwnode->secondary); |
---|
.. | .. |
---|
3858 | 4617 | else |
---|
3859 | 4618 | dev->fwnode = fwnode; |
---|
3860 | 4619 | } |
---|
| 4620 | +EXPORT_SYMBOL_GPL(set_secondary_fwnode); |
---|
3861 | 4621 | |
---|
3862 | 4622 | /** |
---|
3863 | 4623 | * device_set_of_node_from_dev - reuse device-tree node of another device |
---|
.. | .. |
---|
3874 | 4634 | dev->of_node_reused = true; |
---|
3875 | 4635 | } |
---|
3876 | 4636 | EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); |
---|
| 4637 | + |
---|
| 4638 | +void device_set_node(struct device *dev, struct fwnode_handle *fwnode) |
---|
| 4639 | +{ |
---|
| 4640 | + dev->fwnode = fwnode; |
---|
| 4641 | + dev->of_node = to_of_node(fwnode); |
---|
| 4642 | +} |
---|
| 4643 | +EXPORT_SYMBOL_GPL(device_set_node); |
---|
| 4644 | + |
---|
| 4645 | +int device_match_name(struct device *dev, const void *name) |
---|
| 4646 | +{ |
---|
| 4647 | + return sysfs_streq(dev_name(dev), name); |
---|
| 4648 | +} |
---|
| 4649 | +EXPORT_SYMBOL_GPL(device_match_name); |
---|
| 4650 | + |
---|
| 4651 | +int device_match_of_node(struct device *dev, const void *np) |
---|
| 4652 | +{ |
---|
| 4653 | + return dev->of_node == np; |
---|
| 4654 | +} |
---|
| 4655 | +EXPORT_SYMBOL_GPL(device_match_of_node); |
---|
| 4656 | + |
---|
| 4657 | +int device_match_fwnode(struct device *dev, const void *fwnode) |
---|
| 4658 | +{ |
---|
| 4659 | + return dev_fwnode(dev) == fwnode; |
---|
| 4660 | +} |
---|
| 4661 | +EXPORT_SYMBOL_GPL(device_match_fwnode); |
---|
| 4662 | + |
---|
| 4663 | +int device_match_devt(struct device *dev, const void *pdevt) |
---|
| 4664 | +{ |
---|
| 4665 | + return dev->devt == *(dev_t *)pdevt; |
---|
| 4666 | +} |
---|
| 4667 | +EXPORT_SYMBOL_GPL(device_match_devt); |
---|
| 4668 | + |
---|
| 4669 | +int device_match_acpi_dev(struct device *dev, const void *adev) |
---|
| 4670 | +{ |
---|
| 4671 | + return ACPI_COMPANION(dev) == adev; |
---|
| 4672 | +} |
---|
| 4673 | +EXPORT_SYMBOL(device_match_acpi_dev); |
---|
| 4674 | + |
---|
| 4675 | +int device_match_any(struct device *dev, const void *unused) |
---|
| 4676 | +{ |
---|
| 4677 | + return 1; |
---|
| 4678 | +} |
---|
| 4679 | +EXPORT_SYMBOL_GPL(device_match_any); |
---|