1989d42e8SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc) 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 61da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 764bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de> 864bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc. 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 117847a145SHeikki Krogerus #include <linux/acpi.h> 1265650b35SRafael J. Wysocki #include <linux/cpufreq.h> 131da177e4SLinus Torvalds #include <linux/device.h> 141da177e4SLinus Torvalds #include <linux/err.h> 1597badf87SRafael J. Wysocki #include <linux/fwnode.h> 161da177e4SLinus Torvalds #include <linux/init.h> 171da177e4SLinus Torvalds #include <linux/module.h> 181da177e4SLinus Torvalds #include <linux/slab.h> 191da177e4SLinus Torvalds #include <linux/string.h> 2023681e47SGreg Kroah-Hartman #include <linux/kdev_t.h> 21116af378SBenjamin Herrenschmidt #include <linux/notifier.h> 2207d57a32SGrant Likely #include <linux/of.h> 2307d57a32SGrant Likely #include <linux/of_device.h> 24da231fd5SKay Sievers #include <linux/genhd.h> 25f75b1c60SDave Young #include <linux/mutex.h> 26af8db150SPeter Chen #include <linux/pm_runtime.h> 27c4e00daaSKay Sievers #include <linux/netdevice.h> 28174cd4b1SIngo Molnar #include <linux/sched/signal.h> 29b8530017SOliver Neukum #include <linux/sched/mm.h> 3063967685SGreg Kroah-Hartman #include <linux/sysfs.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #include "base.h" 331da177e4SLinus Torvalds #include "power/power.h" 341da177e4SLinus Torvalds 35e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED 36e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2 37e52eec13SAndi Kleen long sysfs_deprecated = 1; 38e52eec13SAndi Kleen #else 39e52eec13SAndi Kleen long sysfs_deprecated = 0; 40e52eec13SAndi Kleen #endif 413454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg) 42e52eec13SAndi Kleen { 4334da5e67SJingoo Han return kstrtol(arg, 10, &sysfs_deprecated); 44e52eec13SAndi Kleen } 45e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup); 46e52eec13SAndi Kleen #endif 47e52eec13SAndi Kleen 489ed98953SRafael J. Wysocki /* Device links support. */ 49e2ae9bccSSaravana Kannan static LIST_HEAD(wait_for_suppliers); 50e2ae9bccSSaravana Kannan static DEFINE_MUTEX(wfs_lock); 51fc5a251dSSaravana Kannan static LIST_HEAD(deferred_sync); 52fc5a251dSSaravana Kannan static unsigned int defer_sync_state_count = 1; 53716a7a25SSaravana Kannan static unsigned int defer_fw_devlink_count; 542451e746SSaravana Kannan static LIST_HEAD(deferred_fw_devlink); 55716a7a25SSaravana Kannan static DEFINE_MUTEX(defer_fw_devlink_lock); 56716a7a25SSaravana Kannan static bool fw_devlink_is_permissive(void); 579ed98953SRafael J. Wysocki 589ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 599ed98953SRafael J. Wysocki static DEFINE_MUTEX(device_links_lock); 609ed98953SRafael J. Wysocki DEFINE_STATIC_SRCU(device_links_srcu); 619ed98953SRafael J. Wysocki 629ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 639ed98953SRafael J. Wysocki { 649ed98953SRafael J. Wysocki mutex_lock(&device_links_lock); 659ed98953SRafael J. Wysocki } 669ed98953SRafael J. Wysocki 679ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 689ed98953SRafael J. Wysocki { 699ed98953SRafael J. Wysocki mutex_unlock(&device_links_lock); 709ed98953SRafael J. Wysocki } 719ed98953SRafael J. Wysocki 7268464d79SJules Irenge int device_links_read_lock(void) __acquires(&device_links_srcu) 739ed98953SRafael J. Wysocki { 749ed98953SRafael J. Wysocki return srcu_read_lock(&device_links_srcu); 759ed98953SRafael J. Wysocki } 769ed98953SRafael J. Wysocki 77ab7789c5SJules Irenge void device_links_read_unlock(int idx) __releases(&device_links_srcu) 789ed98953SRafael J. Wysocki { 799ed98953SRafael J. Wysocki srcu_read_unlock(&device_links_srcu, idx); 809ed98953SRafael J. Wysocki } 81c2fa1e1bSJoel Fernandes (Google) 82c2fa1e1bSJoel Fernandes (Google) int device_links_read_lock_held(void) 83c2fa1e1bSJoel Fernandes (Google) { 84c2fa1e1bSJoel Fernandes (Google) return srcu_read_lock_held(&device_links_srcu); 85c2fa1e1bSJoel Fernandes (Google) } 869ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 879ed98953SRafael J. Wysocki static DECLARE_RWSEM(device_links_lock); 889ed98953SRafael J. Wysocki 899ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 909ed98953SRafael J. Wysocki { 919ed98953SRafael J. Wysocki down_write(&device_links_lock); 929ed98953SRafael J. Wysocki } 939ed98953SRafael J. Wysocki 949ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 959ed98953SRafael J. Wysocki { 969ed98953SRafael J. Wysocki up_write(&device_links_lock); 979ed98953SRafael J. Wysocki } 989ed98953SRafael J. Wysocki 999ed98953SRafael J. Wysocki int device_links_read_lock(void) 1009ed98953SRafael J. Wysocki { 1019ed98953SRafael J. Wysocki down_read(&device_links_lock); 1029ed98953SRafael J. Wysocki return 0; 1039ed98953SRafael J. Wysocki } 1049ed98953SRafael J. Wysocki 1059ed98953SRafael J. Wysocki void device_links_read_unlock(int not_used) 1069ed98953SRafael J. Wysocki { 1079ed98953SRafael J. Wysocki up_read(&device_links_lock); 1089ed98953SRafael J. Wysocki } 109c2fa1e1bSJoel Fernandes (Google) 110c2fa1e1bSJoel Fernandes (Google) #ifdef CONFIG_DEBUG_LOCK_ALLOC 111c2fa1e1bSJoel Fernandes (Google) int device_links_read_lock_held(void) 112c2fa1e1bSJoel Fernandes (Google) { 113c2fa1e1bSJoel Fernandes (Google) return lockdep_is_held(&device_links_lock); 114c2fa1e1bSJoel Fernandes (Google) } 115c2fa1e1bSJoel Fernandes (Google) #endif 1169ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 1179ed98953SRafael J. Wysocki 1189ed98953SRafael J. Wysocki /** 1199ed98953SRafael J. Wysocki * device_is_dependent - Check if one device depends on another one 1209ed98953SRafael J. Wysocki * @dev: Device to check dependencies for. 1219ed98953SRafael J. Wysocki * @target: Device to check against. 1229ed98953SRafael J. Wysocki * 1239ed98953SRafael J. Wysocki * Check if @target depends on @dev or any device dependent on it (its child or 1249ed98953SRafael J. Wysocki * its consumer etc). Return 1 if that is the case or 0 otherwise. 1259ed98953SRafael J. Wysocki */ 1267d34ca38SSaravana Kannan int device_is_dependent(struct device *dev, void *target) 1279ed98953SRafael J. Wysocki { 1289ed98953SRafael J. Wysocki struct device_link *link; 1299ed98953SRafael J. Wysocki int ret; 1309ed98953SRafael J. Wysocki 131e16f4f3eSBenjamin Gaignard if (dev == target) 1329ed98953SRafael J. Wysocki return 1; 1339ed98953SRafael J. Wysocki 1349ed98953SRafael J. Wysocki ret = device_for_each_child(dev, target, device_is_dependent); 1359ed98953SRafael J. Wysocki if (ret) 1369ed98953SRafael J. Wysocki return ret; 1379ed98953SRafael J. Wysocki 1389ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 13905ef983eSSaravana Kannan if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) 14005ef983eSSaravana Kannan continue; 14105ef983eSSaravana Kannan 142e16f4f3eSBenjamin Gaignard if (link->consumer == target) 1439ed98953SRafael J. Wysocki return 1; 1449ed98953SRafael J. Wysocki 1459ed98953SRafael J. Wysocki ret = device_is_dependent(link->consumer, target); 1469ed98953SRafael J. Wysocki if (ret) 1479ed98953SRafael J. Wysocki break; 1489ed98953SRafael J. Wysocki } 1499ed98953SRafael J. Wysocki return ret; 1509ed98953SRafael J. Wysocki } 1519ed98953SRafael J. Wysocki 152515db266SRafael J. Wysocki static void device_link_init_status(struct device_link *link, 153515db266SRafael J. Wysocki struct device *consumer, 154515db266SRafael J. Wysocki struct device *supplier) 155515db266SRafael J. Wysocki { 156515db266SRafael J. Wysocki switch (supplier->links.status) { 157515db266SRafael J. Wysocki case DL_DEV_PROBING: 158515db266SRafael J. Wysocki switch (consumer->links.status) { 159515db266SRafael J. Wysocki case DL_DEV_PROBING: 160515db266SRafael J. Wysocki /* 161515db266SRafael J. Wysocki * A consumer driver can create a link to a supplier 162515db266SRafael J. Wysocki * that has not completed its probing yet as long as it 163515db266SRafael J. Wysocki * knows that the supplier is already functional (for 164515db266SRafael J. Wysocki * example, it has just acquired some resources from the 165515db266SRafael J. Wysocki * supplier). 166515db266SRafael J. Wysocki */ 167515db266SRafael J. Wysocki link->status = DL_STATE_CONSUMER_PROBE; 168515db266SRafael J. Wysocki break; 169515db266SRafael J. Wysocki default: 170515db266SRafael J. Wysocki link->status = DL_STATE_DORMANT; 171515db266SRafael J. Wysocki break; 172515db266SRafael J. Wysocki } 173515db266SRafael J. Wysocki break; 174515db266SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 175515db266SRafael J. Wysocki switch (consumer->links.status) { 176515db266SRafael J. Wysocki case DL_DEV_PROBING: 177515db266SRafael J. Wysocki link->status = DL_STATE_CONSUMER_PROBE; 178515db266SRafael J. Wysocki break; 179515db266SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 180515db266SRafael J. Wysocki link->status = DL_STATE_ACTIVE; 181515db266SRafael J. Wysocki break; 182515db266SRafael J. Wysocki default: 183515db266SRafael J. Wysocki link->status = DL_STATE_AVAILABLE; 184515db266SRafael J. Wysocki break; 185515db266SRafael J. Wysocki } 186515db266SRafael J. Wysocki break; 187515db266SRafael J. Wysocki case DL_DEV_UNBINDING: 188515db266SRafael J. Wysocki link->status = DL_STATE_SUPPLIER_UNBIND; 189515db266SRafael J. Wysocki break; 190515db266SRafael J. Wysocki default: 191515db266SRafael J. Wysocki link->status = DL_STATE_DORMANT; 192515db266SRafael J. Wysocki break; 193515db266SRafael J. Wysocki } 194515db266SRafael J. Wysocki } 195515db266SRafael J. Wysocki 1969ed98953SRafael J. Wysocki static int device_reorder_to_tail(struct device *dev, void *not_used) 1979ed98953SRafael J. Wysocki { 1989ed98953SRafael J. Wysocki struct device_link *link; 1999ed98953SRafael J. Wysocki 2009ed98953SRafael J. Wysocki /* 2019ed98953SRafael J. Wysocki * Devices that have not been registered yet will be put to the ends 2029ed98953SRafael J. Wysocki * of the lists during the registration, so skip them here. 2039ed98953SRafael J. Wysocki */ 2049ed98953SRafael J. Wysocki if (device_is_registered(dev)) 2059ed98953SRafael J. Wysocki devices_kset_move_last(dev); 2069ed98953SRafael J. Wysocki 2079ed98953SRafael J. Wysocki if (device_pm_initialized(dev)) 2089ed98953SRafael J. Wysocki device_pm_move_last(dev); 2099ed98953SRafael J. Wysocki 2109ed98953SRafael J. Wysocki device_for_each_child(dev, NULL, device_reorder_to_tail); 21105ef983eSSaravana Kannan list_for_each_entry(link, &dev->links.consumers, s_node) { 21205ef983eSSaravana Kannan if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) 21305ef983eSSaravana Kannan continue; 2149ed98953SRafael J. Wysocki device_reorder_to_tail(link->consumer, NULL); 21505ef983eSSaravana Kannan } 2169ed98953SRafael J. Wysocki 2179ed98953SRafael J. Wysocki return 0; 2189ed98953SRafael J. Wysocki } 2199ed98953SRafael J. Wysocki 2209ed98953SRafael J. Wysocki /** 221494fd7b7SFeng Kan * device_pm_move_to_tail - Move set of devices to the end of device lists 222494fd7b7SFeng Kan * @dev: Device to move 223494fd7b7SFeng Kan * 224494fd7b7SFeng Kan * This is a device_reorder_to_tail() wrapper taking the requisite locks. 225494fd7b7SFeng Kan * 226494fd7b7SFeng Kan * It moves the @dev along with all of its children and all of its consumers 227494fd7b7SFeng Kan * to the ends of the device_kset and dpm_list, recursively. 228494fd7b7SFeng Kan */ 229494fd7b7SFeng Kan void device_pm_move_to_tail(struct device *dev) 230494fd7b7SFeng Kan { 231494fd7b7SFeng Kan int idx; 232494fd7b7SFeng Kan 233494fd7b7SFeng Kan idx = device_links_read_lock(); 234494fd7b7SFeng Kan device_pm_lock(); 235494fd7b7SFeng Kan device_reorder_to_tail(dev, NULL); 236494fd7b7SFeng Kan device_pm_unlock(); 237494fd7b7SFeng Kan device_links_read_unlock(idx); 238494fd7b7SFeng Kan } 239494fd7b7SFeng Kan 240287905e6SSaravana Kannan #define to_devlink(dev) container_of((dev), struct device_link, link_dev) 241287905e6SSaravana Kannan 242287905e6SSaravana Kannan static ssize_t status_show(struct device *dev, 243287905e6SSaravana Kannan struct device_attribute *attr, char *buf) 244287905e6SSaravana Kannan { 245287905e6SSaravana Kannan char *status; 246287905e6SSaravana Kannan 247287905e6SSaravana Kannan switch (to_devlink(dev)->status) { 248287905e6SSaravana Kannan case DL_STATE_NONE: 249287905e6SSaravana Kannan status = "not tracked"; break; 250287905e6SSaravana Kannan case DL_STATE_DORMANT: 251287905e6SSaravana Kannan status = "dormant"; break; 252287905e6SSaravana Kannan case DL_STATE_AVAILABLE: 253287905e6SSaravana Kannan status = "available"; break; 254287905e6SSaravana Kannan case DL_STATE_CONSUMER_PROBE: 255287905e6SSaravana Kannan status = "consumer probing"; break; 256287905e6SSaravana Kannan case DL_STATE_ACTIVE: 257287905e6SSaravana Kannan status = "active"; break; 258287905e6SSaravana Kannan case DL_STATE_SUPPLIER_UNBIND: 259287905e6SSaravana Kannan status = "supplier unbinding"; break; 260287905e6SSaravana Kannan default: 261287905e6SSaravana Kannan status = "unknown"; break; 262287905e6SSaravana Kannan } 263aa838896SJoe Perches return sysfs_emit(buf, "%s\n", status); 264287905e6SSaravana Kannan } 265287905e6SSaravana Kannan static DEVICE_ATTR_RO(status); 266287905e6SSaravana Kannan 267287905e6SSaravana Kannan static ssize_t auto_remove_on_show(struct device *dev, 268287905e6SSaravana Kannan struct device_attribute *attr, char *buf) 269287905e6SSaravana Kannan { 270287905e6SSaravana Kannan struct device_link *link = to_devlink(dev); 271287905e6SSaravana Kannan char *str; 272287905e6SSaravana Kannan 273287905e6SSaravana Kannan if (link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER) 274287905e6SSaravana Kannan str = "supplier unbind"; 275287905e6SSaravana Kannan else if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER) 276287905e6SSaravana Kannan str = "consumer unbind"; 277287905e6SSaravana Kannan else 278287905e6SSaravana Kannan str = "never"; 279287905e6SSaravana Kannan 280aa838896SJoe Perches return sysfs_emit(buf, "%s\n", str); 281287905e6SSaravana Kannan } 282287905e6SSaravana Kannan static DEVICE_ATTR_RO(auto_remove_on); 283287905e6SSaravana Kannan 284287905e6SSaravana Kannan static ssize_t runtime_pm_show(struct device *dev, 285287905e6SSaravana Kannan struct device_attribute *attr, char *buf) 286287905e6SSaravana Kannan { 287287905e6SSaravana Kannan struct device_link *link = to_devlink(dev); 288287905e6SSaravana Kannan 289aa838896SJoe Perches return sysfs_emit(buf, "%d\n", !!(link->flags & DL_FLAG_PM_RUNTIME)); 290287905e6SSaravana Kannan } 291287905e6SSaravana Kannan static DEVICE_ATTR_RO(runtime_pm); 292287905e6SSaravana Kannan 293287905e6SSaravana Kannan static ssize_t sync_state_only_show(struct device *dev, 294287905e6SSaravana Kannan struct device_attribute *attr, char *buf) 295287905e6SSaravana Kannan { 296287905e6SSaravana Kannan struct device_link *link = to_devlink(dev); 297287905e6SSaravana Kannan 298aa838896SJoe Perches return sysfs_emit(buf, "%d\n", 299aa838896SJoe Perches !!(link->flags & DL_FLAG_SYNC_STATE_ONLY)); 300287905e6SSaravana Kannan } 301287905e6SSaravana Kannan static DEVICE_ATTR_RO(sync_state_only); 302287905e6SSaravana Kannan 303287905e6SSaravana Kannan static struct attribute *devlink_attrs[] = { 304287905e6SSaravana Kannan &dev_attr_status.attr, 305287905e6SSaravana Kannan &dev_attr_auto_remove_on.attr, 306287905e6SSaravana Kannan &dev_attr_runtime_pm.attr, 307287905e6SSaravana Kannan &dev_attr_sync_state_only.attr, 308287905e6SSaravana Kannan NULL, 309287905e6SSaravana Kannan }; 310287905e6SSaravana Kannan ATTRIBUTE_GROUPS(devlink); 311287905e6SSaravana Kannan 312843e600bSSaravana Kannan static void device_link_free(struct device_link *link) 313843e600bSSaravana Kannan { 314843e600bSSaravana Kannan while (refcount_dec_not_one(&link->rpm_active)) 315843e600bSSaravana Kannan pm_runtime_put(link->supplier); 316843e600bSSaravana Kannan 317843e600bSSaravana Kannan put_device(link->consumer); 318843e600bSSaravana Kannan put_device(link->supplier); 319843e600bSSaravana Kannan kfree(link); 320843e600bSSaravana Kannan } 321843e600bSSaravana Kannan 322843e600bSSaravana Kannan #ifdef CONFIG_SRCU 323843e600bSSaravana Kannan static void __device_link_free_srcu(struct rcu_head *rhead) 324843e600bSSaravana Kannan { 325843e600bSSaravana Kannan device_link_free(container_of(rhead, struct device_link, rcu_head)); 326843e600bSSaravana Kannan } 327843e600bSSaravana Kannan 328287905e6SSaravana Kannan static void devlink_dev_release(struct device *dev) 329287905e6SSaravana Kannan { 330843e600bSSaravana Kannan struct device_link *link = to_devlink(dev); 331843e600bSSaravana Kannan 332843e600bSSaravana Kannan call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); 333287905e6SSaravana Kannan } 334843e600bSSaravana Kannan #else 335843e600bSSaravana Kannan static void devlink_dev_release(struct device *dev) 336843e600bSSaravana Kannan { 337843e600bSSaravana Kannan device_link_free(to_devlink(dev)); 338843e600bSSaravana Kannan } 339843e600bSSaravana Kannan #endif 340287905e6SSaravana Kannan 341287905e6SSaravana Kannan static struct class devlink_class = { 342287905e6SSaravana Kannan .name = "devlink", 343287905e6SSaravana Kannan .owner = THIS_MODULE, 344287905e6SSaravana Kannan .dev_groups = devlink_groups, 345287905e6SSaravana Kannan .dev_release = devlink_dev_release, 346287905e6SSaravana Kannan }; 347287905e6SSaravana Kannan 348287905e6SSaravana Kannan static int devlink_add_symlinks(struct device *dev, 349287905e6SSaravana Kannan struct class_interface *class_intf) 350287905e6SSaravana Kannan { 351287905e6SSaravana Kannan int ret; 352287905e6SSaravana Kannan size_t len; 353287905e6SSaravana Kannan struct device_link *link = to_devlink(dev); 354287905e6SSaravana Kannan struct device *sup = link->supplier; 355287905e6SSaravana Kannan struct device *con = link->consumer; 356287905e6SSaravana Kannan char *buf; 357287905e6SSaravana Kannan 358287905e6SSaravana Kannan len = max(strlen(dev_name(sup)), strlen(dev_name(con))); 359287905e6SSaravana Kannan len += strlen("supplier:") + 1; 360287905e6SSaravana Kannan buf = kzalloc(len, GFP_KERNEL); 361287905e6SSaravana Kannan if (!buf) 362287905e6SSaravana Kannan return -ENOMEM; 363287905e6SSaravana Kannan 364287905e6SSaravana Kannan ret = sysfs_create_link(&link->link_dev.kobj, &sup->kobj, "supplier"); 365287905e6SSaravana Kannan if (ret) 366287905e6SSaravana Kannan goto out; 367287905e6SSaravana Kannan 368287905e6SSaravana Kannan ret = sysfs_create_link(&link->link_dev.kobj, &con->kobj, "consumer"); 369287905e6SSaravana Kannan if (ret) 370287905e6SSaravana Kannan goto err_con; 371287905e6SSaravana Kannan 372287905e6SSaravana Kannan snprintf(buf, len, "consumer:%s", dev_name(con)); 373287905e6SSaravana Kannan ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf); 374287905e6SSaravana Kannan if (ret) 375287905e6SSaravana Kannan goto err_con_dev; 376287905e6SSaravana Kannan 377287905e6SSaravana Kannan snprintf(buf, len, "supplier:%s", dev_name(sup)); 378287905e6SSaravana Kannan ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf); 379287905e6SSaravana Kannan if (ret) 380287905e6SSaravana Kannan goto err_sup_dev; 381287905e6SSaravana Kannan 382287905e6SSaravana Kannan goto out; 383287905e6SSaravana Kannan 384287905e6SSaravana Kannan err_sup_dev: 385287905e6SSaravana Kannan snprintf(buf, len, "consumer:%s", dev_name(con)); 386287905e6SSaravana Kannan sysfs_remove_link(&sup->kobj, buf); 387287905e6SSaravana Kannan err_con_dev: 388287905e6SSaravana Kannan sysfs_remove_link(&link->link_dev.kobj, "consumer"); 389287905e6SSaravana Kannan err_con: 390287905e6SSaravana Kannan sysfs_remove_link(&link->link_dev.kobj, "supplier"); 391287905e6SSaravana Kannan out: 392287905e6SSaravana Kannan kfree(buf); 393287905e6SSaravana Kannan return ret; 394287905e6SSaravana Kannan } 395287905e6SSaravana Kannan 396287905e6SSaravana Kannan static void devlink_remove_symlinks(struct device *dev, 397287905e6SSaravana Kannan struct class_interface *class_intf) 398287905e6SSaravana Kannan { 399287905e6SSaravana Kannan struct device_link *link = to_devlink(dev); 400287905e6SSaravana Kannan size_t len; 401287905e6SSaravana Kannan struct device *sup = link->supplier; 402287905e6SSaravana Kannan struct device *con = link->consumer; 403287905e6SSaravana Kannan char *buf; 404287905e6SSaravana Kannan 405287905e6SSaravana Kannan sysfs_remove_link(&link->link_dev.kobj, "consumer"); 406287905e6SSaravana Kannan sysfs_remove_link(&link->link_dev.kobj, "supplier"); 407287905e6SSaravana Kannan 408287905e6SSaravana Kannan len = max(strlen(dev_name(sup)), strlen(dev_name(con))); 409287905e6SSaravana Kannan len += strlen("supplier:") + 1; 410287905e6SSaravana Kannan buf = kzalloc(len, GFP_KERNEL); 411287905e6SSaravana Kannan if (!buf) { 412287905e6SSaravana Kannan WARN(1, "Unable to properly free device link symlinks!\n"); 413287905e6SSaravana Kannan return; 414287905e6SSaravana Kannan } 415287905e6SSaravana Kannan 416287905e6SSaravana Kannan snprintf(buf, len, "supplier:%s", dev_name(sup)); 417287905e6SSaravana Kannan sysfs_remove_link(&con->kobj, buf); 418287905e6SSaravana Kannan snprintf(buf, len, "consumer:%s", dev_name(con)); 419287905e6SSaravana Kannan sysfs_remove_link(&sup->kobj, buf); 420287905e6SSaravana Kannan kfree(buf); 421287905e6SSaravana Kannan } 422287905e6SSaravana Kannan 423287905e6SSaravana Kannan static struct class_interface devlink_class_intf = { 424287905e6SSaravana Kannan .class = &devlink_class, 425287905e6SSaravana Kannan .add_dev = devlink_add_symlinks, 426287905e6SSaravana Kannan .remove_dev = devlink_remove_symlinks, 427287905e6SSaravana Kannan }; 428287905e6SSaravana Kannan 429287905e6SSaravana Kannan static int __init devlink_class_init(void) 430287905e6SSaravana Kannan { 431287905e6SSaravana Kannan int ret; 432287905e6SSaravana Kannan 433287905e6SSaravana Kannan ret = class_register(&devlink_class); 434287905e6SSaravana Kannan if (ret) 435287905e6SSaravana Kannan return ret; 436287905e6SSaravana Kannan 437287905e6SSaravana Kannan ret = class_interface_register(&devlink_class_intf); 438287905e6SSaravana Kannan if (ret) 439287905e6SSaravana Kannan class_unregister(&devlink_class); 440287905e6SSaravana Kannan 441287905e6SSaravana Kannan return ret; 442287905e6SSaravana Kannan } 443287905e6SSaravana Kannan postcore_initcall(devlink_class_init); 444287905e6SSaravana Kannan 445515db266SRafael J. Wysocki #define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \ 446515db266SRafael J. Wysocki DL_FLAG_AUTOREMOVE_SUPPLIER | \ 44705ef983eSSaravana Kannan DL_FLAG_AUTOPROBE_CONSUMER | \ 44805ef983eSSaravana Kannan DL_FLAG_SYNC_STATE_ONLY) 449515db266SRafael J. Wysocki 450fb583c8eSRafael J. Wysocki #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \ 451fb583c8eSRafael J. Wysocki DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE) 452fb583c8eSRafael J. Wysocki 453494fd7b7SFeng Kan /** 4549ed98953SRafael J. Wysocki * device_link_add - Create a link between two devices. 4559ed98953SRafael J. Wysocki * @consumer: Consumer end of the link. 4569ed98953SRafael J. Wysocki * @supplier: Supplier end of the link. 4579ed98953SRafael J. Wysocki * @flags: Link flags. 4589ed98953SRafael J. Wysocki * 45921d5c57bSRafael J. Wysocki * The caller is responsible for the proper synchronization of the link creation 46021d5c57bSRafael J. Wysocki * with runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause the 46121d5c57bSRafael J. Wysocki * runtime PM framework to take the link into account. Second, if the 46221d5c57bSRafael J. Wysocki * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will 46321d5c57bSRafael J. Wysocki * be forced into the active metastate and reference-counted upon the creation 46421d5c57bSRafael J. Wysocki * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be 46521d5c57bSRafael J. Wysocki * ignored. 46621d5c57bSRafael J. Wysocki * 467515db266SRafael J. Wysocki * If DL_FLAG_STATELESS is set in @flags, the caller of this function is 468515db266SRafael J. Wysocki * expected to release the link returned by it directly with the help of either 469515db266SRafael J. Wysocki * device_link_del() or device_link_remove(). 47072175d4eSRafael J. Wysocki * 47172175d4eSRafael J. Wysocki * If that flag is not set, however, the caller of this function is handing the 47272175d4eSRafael J. Wysocki * management of the link over to the driver core entirely and its return value 47372175d4eSRafael J. Wysocki * can only be used to check whether or not the link is present. In that case, 47472175d4eSRafael J. Wysocki * the DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_AUTOREMOVE_SUPPLIER device link 47572175d4eSRafael J. Wysocki * flags can be used to indicate to the driver core when the link can be safely 47672175d4eSRafael J. Wysocki * deleted. Namely, setting one of them in @flags indicates to the driver core 47772175d4eSRafael J. Wysocki * that the link is not going to be used (by the given caller of this function) 47872175d4eSRafael J. Wysocki * after unbinding the consumer or supplier driver, respectively, from its 47972175d4eSRafael J. Wysocki * device, so the link can be deleted at that point. If none of them is set, 48072175d4eSRafael J. Wysocki * the link will be maintained until one of the devices pointed to by it (either 48172175d4eSRafael J. Wysocki * the consumer or the supplier) is unregistered. 482c8d50986SRafael J. Wysocki * 483e7dd4010SRafael J. Wysocki * Also, if DL_FLAG_STATELESS, DL_FLAG_AUTOREMOVE_CONSUMER and 484e7dd4010SRafael J. Wysocki * DL_FLAG_AUTOREMOVE_SUPPLIER are not set in @flags (that is, a persistent 485e7dd4010SRafael J. Wysocki * managed device link is being added), the DL_FLAG_AUTOPROBE_CONSUMER flag can 486e7dd4010SRafael J. Wysocki * be used to request the driver core to automaticall probe for a consmer 487e7dd4010SRafael J. Wysocki * driver after successfully binding a driver to the supplier device. 488e7dd4010SRafael J. Wysocki * 489515db266SRafael J. Wysocki * The combination of DL_FLAG_STATELESS and one of DL_FLAG_AUTOREMOVE_CONSUMER, 490515db266SRafael J. Wysocki * DL_FLAG_AUTOREMOVE_SUPPLIER, or DL_FLAG_AUTOPROBE_CONSUMER set in @flags at 491515db266SRafael J. Wysocki * the same time is invalid and will cause NULL to be returned upfront. 492515db266SRafael J. Wysocki * However, if a device link between the given @consumer and @supplier pair 493515db266SRafael J. Wysocki * exists already when this function is called for them, the existing link will 494515db266SRafael J. Wysocki * be returned regardless of its current type and status (the link's flags may 495515db266SRafael J. Wysocki * be modified then). The caller of this function is then expected to treat 496515db266SRafael J. Wysocki * the link as though it has just been created, so (in particular) if 497515db266SRafael J. Wysocki * DL_FLAG_STATELESS was passed in @flags, the link needs to be released 498515db266SRafael J. Wysocki * explicitly when not needed any more (as stated above). 4999ed98953SRafael J. Wysocki * 5009ed98953SRafael J. Wysocki * A side effect of the link creation is re-ordering of dpm_list and the 5019ed98953SRafael J. Wysocki * devices_kset list by moving the consumer device and all devices depending 5029ed98953SRafael J. Wysocki * on it to the ends of these lists (that does not happen to devices that have 5039ed98953SRafael J. Wysocki * not been registered when this function is called). 5049ed98953SRafael J. Wysocki * 5059ed98953SRafael J. Wysocki * The supplier device is required to be registered when this function is called 5069ed98953SRafael J. Wysocki * and NULL will be returned if that is not the case. The consumer device need 50764df1148SLukas Wunner * not be registered, however. 5089ed98953SRafael J. Wysocki */ 5099ed98953SRafael J. Wysocki struct device_link *device_link_add(struct device *consumer, 5109ed98953SRafael J. Wysocki struct device *supplier, u32 flags) 5119ed98953SRafael J. Wysocki { 5129ed98953SRafael J. Wysocki struct device_link *link; 5139ed98953SRafael J. Wysocki 514fb583c8eSRafael J. Wysocki if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS || 515515db266SRafael J. Wysocki (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) || 51605ef983eSSaravana Kannan (flags & DL_FLAG_SYNC_STATE_ONLY && 51705ef983eSSaravana Kannan flags != DL_FLAG_SYNC_STATE_ONLY) || 518e7dd4010SRafael J. Wysocki (flags & DL_FLAG_AUTOPROBE_CONSUMER && 519e7dd4010SRafael J. Wysocki flags & (DL_FLAG_AUTOREMOVE_CONSUMER | 520e7dd4010SRafael J. Wysocki DL_FLAG_AUTOREMOVE_SUPPLIER))) 5219ed98953SRafael J. Wysocki return NULL; 5229ed98953SRafael J. Wysocki 5235db25c9eSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) { 5245db25c9eSRafael J. Wysocki if (pm_runtime_get_sync(supplier) < 0) { 5255db25c9eSRafael J. Wysocki pm_runtime_put_noidle(supplier); 5265db25c9eSRafael J. Wysocki return NULL; 5275db25c9eSRafael J. Wysocki } 5285db25c9eSRafael J. Wysocki } 5295db25c9eSRafael J. Wysocki 530515db266SRafael J. Wysocki if (!(flags & DL_FLAG_STATELESS)) 531515db266SRafael J. Wysocki flags |= DL_FLAG_MANAGED; 532515db266SRafael J. Wysocki 5339ed98953SRafael J. Wysocki device_links_write_lock(); 5349ed98953SRafael J. Wysocki device_pm_lock(); 5359ed98953SRafael J. Wysocki 5369ed98953SRafael J. Wysocki /* 5379ed98953SRafael J. Wysocki * If the supplier has not been fully registered yet or there is a 53805ef983eSSaravana Kannan * reverse (non-SYNC_STATE_ONLY) dependency between the consumer and 53905ef983eSSaravana Kannan * the supplier already in the graph, return NULL. If the link is a 54005ef983eSSaravana Kannan * SYNC_STATE_ONLY link, we don't check for reverse dependencies 54105ef983eSSaravana Kannan * because it only affects sync_state() callbacks. 5429ed98953SRafael J. Wysocki */ 5439ed98953SRafael J. Wysocki if (!device_pm_initialized(supplier) 54405ef983eSSaravana Kannan || (!(flags & DL_FLAG_SYNC_STATE_ONLY) && 54505ef983eSSaravana Kannan device_is_dependent(consumer, supplier))) { 5469ed98953SRafael J. Wysocki link = NULL; 5479ed98953SRafael J. Wysocki goto out; 5489ed98953SRafael J. Wysocki } 5499ed98953SRafael J. Wysocki 55072175d4eSRafael J. Wysocki /* 55172175d4eSRafael J. Wysocki * DL_FLAG_AUTOREMOVE_SUPPLIER indicates that the link will be needed 55272175d4eSRafael J. Wysocki * longer than for DL_FLAG_AUTOREMOVE_CONSUMER and setting them both 55372175d4eSRafael J. Wysocki * together doesn't make sense, so prefer DL_FLAG_AUTOREMOVE_SUPPLIER. 55472175d4eSRafael J. Wysocki */ 55572175d4eSRafael J. Wysocki if (flags & DL_FLAG_AUTOREMOVE_SUPPLIER) 55672175d4eSRafael J. Wysocki flags &= ~DL_FLAG_AUTOREMOVE_CONSUMER; 55772175d4eSRafael J. Wysocki 558f265df55SRafael J. Wysocki list_for_each_entry(link, &supplier->links.consumers, s_node) { 559f265df55SRafael J. Wysocki if (link->consumer != consumer) 560f265df55SRafael J. Wysocki continue; 561f265df55SRafael J. Wysocki 562e2f3cd83SRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) { 563e2f3cd83SRafael J. Wysocki if (!(link->flags & DL_FLAG_PM_RUNTIME)) { 5644c06c4e6SRafael J. Wysocki pm_runtime_new_link(consumer); 565e2f3cd83SRafael J. Wysocki link->flags |= DL_FLAG_PM_RUNTIME; 566e2f3cd83SRafael J. Wysocki } 567e2f3cd83SRafael J. Wysocki if (flags & DL_FLAG_RPM_ACTIVE) 56836003d4cSRafael J. Wysocki refcount_inc(&link->rpm_active); 569e2f3cd83SRafael J. Wysocki } 570e2f3cd83SRafael J. Wysocki 57172175d4eSRafael J. Wysocki if (flags & DL_FLAG_STATELESS) { 572ead18c23SLukas Wunner kref_get(&link->kref); 57321c27f06SSaravana Kannan if (link->flags & DL_FLAG_SYNC_STATE_ONLY && 57444e96049SSaravana Kannan !(link->flags & DL_FLAG_STATELESS)) { 57544e96049SSaravana Kannan link->flags |= DL_FLAG_STATELESS; 57605ef983eSSaravana Kannan goto reorder; 57744e96049SSaravana Kannan } else { 57844e96049SSaravana Kannan link->flags |= DL_FLAG_STATELESS; 5799ed98953SRafael J. Wysocki goto out; 580ead18c23SLukas Wunner } 58144e96049SSaravana Kannan } 5829ed98953SRafael J. Wysocki 58372175d4eSRafael J. Wysocki /* 58472175d4eSRafael J. Wysocki * If the life time of the link following from the new flags is 58572175d4eSRafael J. Wysocki * longer than indicated by the flags of the existing link, 58672175d4eSRafael J. Wysocki * update the existing link to stay around longer. 58772175d4eSRafael J. Wysocki */ 58872175d4eSRafael J. Wysocki if (flags & DL_FLAG_AUTOREMOVE_SUPPLIER) { 58972175d4eSRafael J. Wysocki if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER) { 59072175d4eSRafael J. Wysocki link->flags &= ~DL_FLAG_AUTOREMOVE_CONSUMER; 59172175d4eSRafael J. Wysocki link->flags |= DL_FLAG_AUTOREMOVE_SUPPLIER; 59272175d4eSRafael J. Wysocki } 59372175d4eSRafael J. Wysocki } else if (!(flags & DL_FLAG_AUTOREMOVE_CONSUMER)) { 59472175d4eSRafael J. Wysocki link->flags &= ~(DL_FLAG_AUTOREMOVE_CONSUMER | 59572175d4eSRafael J. Wysocki DL_FLAG_AUTOREMOVE_SUPPLIER); 59672175d4eSRafael J. Wysocki } 597515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) { 598515db266SRafael J. Wysocki kref_get(&link->kref); 599515db266SRafael J. Wysocki link->flags |= DL_FLAG_MANAGED; 600515db266SRafael J. Wysocki device_link_init_status(link, consumer, supplier); 601515db266SRafael J. Wysocki } 60205ef983eSSaravana Kannan if (link->flags & DL_FLAG_SYNC_STATE_ONLY && 60305ef983eSSaravana Kannan !(flags & DL_FLAG_SYNC_STATE_ONLY)) { 60405ef983eSSaravana Kannan link->flags &= ~DL_FLAG_SYNC_STATE_ONLY; 60505ef983eSSaravana Kannan goto reorder; 60605ef983eSSaravana Kannan } 60705ef983eSSaravana Kannan 60872175d4eSRafael J. Wysocki goto out; 60972175d4eSRafael J. Wysocki } 61072175d4eSRafael J. Wysocki 61121d5c57bSRafael J. Wysocki link = kzalloc(sizeof(*link), GFP_KERNEL); 6129ed98953SRafael J. Wysocki if (!link) 6139ed98953SRafael J. Wysocki goto out; 6149ed98953SRafael J. Wysocki 615e2f3cd83SRafael J. Wysocki refcount_set(&link->rpm_active, 1); 616e2f3cd83SRafael J. Wysocki 6179ed98953SRafael J. Wysocki get_device(supplier); 6189ed98953SRafael J. Wysocki link->supplier = supplier; 6199ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->s_node); 6209ed98953SRafael J. Wysocki get_device(consumer); 6219ed98953SRafael J. Wysocki link->consumer = consumer; 6229ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->c_node); 6239ed98953SRafael J. Wysocki link->flags = flags; 624ead18c23SLukas Wunner kref_init(&link->kref); 6259ed98953SRafael J. Wysocki 626287905e6SSaravana Kannan link->link_dev.class = &devlink_class; 627287905e6SSaravana Kannan device_set_pm_not_required(&link->link_dev); 62890b109d5SSaravana Kannan dev_set_name(&link->link_dev, "%s--%s", 629287905e6SSaravana Kannan dev_name(supplier), dev_name(consumer)); 630287905e6SSaravana Kannan if (device_register(&link->link_dev)) { 631287905e6SSaravana Kannan put_device(consumer); 632287905e6SSaravana Kannan put_device(supplier); 633287905e6SSaravana Kannan kfree(link); 634287905e6SSaravana Kannan link = NULL; 635287905e6SSaravana Kannan goto out; 636287905e6SSaravana Kannan } 637287905e6SSaravana Kannan 638287905e6SSaravana Kannan if (flags & DL_FLAG_PM_RUNTIME) { 639287905e6SSaravana Kannan if (flags & DL_FLAG_RPM_ACTIVE) 640287905e6SSaravana Kannan refcount_inc(&link->rpm_active); 641287905e6SSaravana Kannan 642287905e6SSaravana Kannan pm_runtime_new_link(consumer); 643287905e6SSaravana Kannan } 644287905e6SSaravana Kannan 64564df1148SLukas Wunner /* Determine the initial link state. */ 646515db266SRafael J. Wysocki if (flags & DL_FLAG_STATELESS) 6479ed98953SRafael J. Wysocki link->status = DL_STATE_NONE; 648515db266SRafael J. Wysocki else 649515db266SRafael J. Wysocki device_link_init_status(link, consumer, supplier); 6509ed98953SRafael J. Wysocki 6519ed98953SRafael J. Wysocki /* 65215cfb094SRafael J. Wysocki * Some callers expect the link creation during consumer driver probe to 65315cfb094SRafael J. Wysocki * resume the supplier even without DL_FLAG_RPM_ACTIVE. 65415cfb094SRafael J. Wysocki */ 65515cfb094SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE && 65615cfb094SRafael J. Wysocki flags & DL_FLAG_PM_RUNTIME) 65715cfb094SRafael J. Wysocki pm_runtime_resume(supplier); 65815cfb094SRafael J. Wysocki 65921c27f06SSaravana Kannan list_add_tail_rcu(&link->s_node, &supplier->links.consumers); 66021c27f06SSaravana Kannan list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); 66121c27f06SSaravana Kannan 66205ef983eSSaravana Kannan if (flags & DL_FLAG_SYNC_STATE_ONLY) { 66305ef983eSSaravana Kannan dev_dbg(consumer, 66405ef983eSSaravana Kannan "Linked as a sync state only consumer to %s\n", 66505ef983eSSaravana Kannan dev_name(supplier)); 66605ef983eSSaravana Kannan goto out; 66705ef983eSSaravana Kannan } 66821c27f06SSaravana Kannan 66905ef983eSSaravana Kannan reorder: 67015cfb094SRafael J. Wysocki /* 6719ed98953SRafael J. Wysocki * Move the consumer and all of the devices depending on it to the end 6729ed98953SRafael J. Wysocki * of dpm_list and the devices_kset list. 6739ed98953SRafael J. Wysocki * 6749ed98953SRafael J. Wysocki * It is necessary to hold dpm_list locked throughout all that or else 6759ed98953SRafael J. Wysocki * we may end up suspending with a wrong ordering of it. 6769ed98953SRafael J. Wysocki */ 6779ed98953SRafael J. Wysocki device_reorder_to_tail(consumer, NULL); 6789ed98953SRafael J. Wysocki 6798a4b3269SJerome Brunet dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); 6809ed98953SRafael J. Wysocki 6819ed98953SRafael J. Wysocki out: 6829ed98953SRafael J. Wysocki device_pm_unlock(); 6839ed98953SRafael J. Wysocki device_links_write_unlock(); 6845db25c9eSRafael J. Wysocki 685e2f3cd83SRafael J. Wysocki if ((flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) && !link) 6865db25c9eSRafael J. Wysocki pm_runtime_put(supplier); 6875db25c9eSRafael J. Wysocki 6889ed98953SRafael J. Wysocki return link; 6899ed98953SRafael J. Wysocki } 6909ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_add); 6919ed98953SRafael J. Wysocki 692e2ae9bccSSaravana Kannan /** 693e2ae9bccSSaravana Kannan * device_link_wait_for_supplier - Add device to wait_for_suppliers list 694e2ae9bccSSaravana Kannan * @consumer: Consumer device 695e2ae9bccSSaravana Kannan * 696e2ae9bccSSaravana Kannan * Marks the @consumer device as waiting for suppliers to become available by 697e2ae9bccSSaravana Kannan * adding it to the wait_for_suppliers list. The consumer device will never be 698e2ae9bccSSaravana Kannan * probed until it's removed from the wait_for_suppliers list. 699e2ae9bccSSaravana Kannan * 700e2ae9bccSSaravana Kannan * The caller is responsible for adding the links to the supplier devices once 701e2ae9bccSSaravana Kannan * they are available and removing the @consumer device from the 702e2ae9bccSSaravana Kannan * wait_for_suppliers list once links to all the suppliers have been created. 703e2ae9bccSSaravana Kannan * 704e2ae9bccSSaravana Kannan * This function is NOT meant to be called from the probe function of the 705e2ae9bccSSaravana Kannan * consumer but rather from code that creates/adds the consumer device. 706e2ae9bccSSaravana Kannan */ 707bcbbcfd5SSaravana Kannan static void device_link_wait_for_supplier(struct device *consumer, 708bcbbcfd5SSaravana Kannan bool need_for_probe) 709e2ae9bccSSaravana Kannan { 710e2ae9bccSSaravana Kannan mutex_lock(&wfs_lock); 711e2ae9bccSSaravana Kannan list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); 712bcbbcfd5SSaravana Kannan consumer->links.need_for_probe = need_for_probe; 713e2ae9bccSSaravana Kannan mutex_unlock(&wfs_lock); 714e2ae9bccSSaravana Kannan } 715e2ae9bccSSaravana Kannan 716bcbbcfd5SSaravana Kannan static void device_link_wait_for_mandatory_supplier(struct device *consumer) 717bcbbcfd5SSaravana Kannan { 718bcbbcfd5SSaravana Kannan device_link_wait_for_supplier(consumer, true); 719bcbbcfd5SSaravana Kannan } 720bcbbcfd5SSaravana Kannan 721bcbbcfd5SSaravana Kannan static void device_link_wait_for_optional_supplier(struct device *consumer) 722bcbbcfd5SSaravana Kannan { 723bcbbcfd5SSaravana Kannan device_link_wait_for_supplier(consumer, false); 724bcbbcfd5SSaravana Kannan } 725bcbbcfd5SSaravana Kannan 726e2ae9bccSSaravana Kannan /** 727e2ae9bccSSaravana Kannan * device_link_add_missing_supplier_links - Add links from consumer devices to 728e2ae9bccSSaravana Kannan * supplier devices, leaving any 729e2ae9bccSSaravana Kannan * consumer with inactive suppliers on 730e2ae9bccSSaravana Kannan * the wait_for_suppliers list 731e2ae9bccSSaravana Kannan * 732e2ae9bccSSaravana Kannan * Loops through all consumers waiting on suppliers and tries to add all their 733e2ae9bccSSaravana Kannan * supplier links. If that succeeds, the consumer device is removed from 734e2ae9bccSSaravana Kannan * wait_for_suppliers list. Otherwise, they are left in the wait_for_suppliers 735e2ae9bccSSaravana Kannan * list. Devices left on the wait_for_suppliers list will not be probed. 736e2ae9bccSSaravana Kannan * 737e2ae9bccSSaravana Kannan * The fwnode add_links callback is expected to return 0 if it has found and 738e2ae9bccSSaravana Kannan * added all the supplier links for the consumer device. It should return an 739e2ae9bccSSaravana Kannan * error if it isn't able to do so. 740e2ae9bccSSaravana Kannan * 741e2ae9bccSSaravana Kannan * The caller of device_link_wait_for_supplier() is expected to call this once 742e2ae9bccSSaravana Kannan * it's aware of potential suppliers becoming available. 743e2ae9bccSSaravana Kannan */ 744e2ae9bccSSaravana Kannan static void device_link_add_missing_supplier_links(void) 745e2ae9bccSSaravana Kannan { 746e2ae9bccSSaravana Kannan struct device *dev, *tmp; 747e2ae9bccSSaravana Kannan 748e2ae9bccSSaravana Kannan mutex_lock(&wfs_lock); 749e2ae9bccSSaravana Kannan list_for_each_entry_safe(dev, tmp, &wait_for_suppliers, 7501745d299SSaravana Kannan links.needs_suppliers) { 7511745d299SSaravana Kannan int ret = fwnode_call_int_op(dev->fwnode, add_links, dev); 7521745d299SSaravana Kannan if (!ret) 753e2ae9bccSSaravana Kannan list_del_init(&dev->links.needs_suppliers); 754716a7a25SSaravana Kannan else if (ret != -ENODEV || fw_devlink_is_permissive()) 7551745d299SSaravana Kannan dev->links.need_for_probe = false; 7561745d299SSaravana Kannan } 757e2ae9bccSSaravana Kannan mutex_unlock(&wfs_lock); 758e2ae9bccSSaravana Kannan } 759e2ae9bccSSaravana Kannan 7609ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 761ead18c23SLukas Wunner static void __device_link_del(struct kref *kref) 7629ed98953SRafael J. Wysocki { 763ead18c23SLukas Wunner struct device_link *link = container_of(kref, struct device_link, kref); 764ead18c23SLukas Wunner 7658a4b3269SJerome Brunet dev_dbg(link->consumer, "Dropping the link to %s\n", 7669ed98953SRafael J. Wysocki dev_name(link->supplier)); 7679ed98953SRafael J. Wysocki 768baa8809fSRafael J. Wysocki if (link->flags & DL_FLAG_PM_RUNTIME) 769baa8809fSRafael J. Wysocki pm_runtime_drop_link(link->consumer); 770baa8809fSRafael J. Wysocki 7719ed98953SRafael J. Wysocki list_del_rcu(&link->s_node); 7729ed98953SRafael J. Wysocki list_del_rcu(&link->c_node); 773843e600bSSaravana Kannan device_unregister(&link->link_dev); 7749ed98953SRafael J. Wysocki } 7759ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 776ead18c23SLukas Wunner static void __device_link_del(struct kref *kref) 7779ed98953SRafael J. Wysocki { 778ead18c23SLukas Wunner struct device_link *link = container_of(kref, struct device_link, kref); 779ead18c23SLukas Wunner 7809ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 7819ed98953SRafael J. Wysocki dev_name(link->supplier)); 7829ed98953SRafael J. Wysocki 783433986c2SLukas Wunner if (link->flags & DL_FLAG_PM_RUNTIME) 784433986c2SLukas Wunner pm_runtime_drop_link(link->consumer); 785433986c2SLukas Wunner 7869ed98953SRafael J. Wysocki list_del(&link->s_node); 7879ed98953SRafael J. Wysocki list_del(&link->c_node); 788843e600bSSaravana Kannan device_unregister(&link->link_dev); 7899ed98953SRafael J. Wysocki } 7909ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 7919ed98953SRafael J. Wysocki 79272175d4eSRafael J. Wysocki static void device_link_put_kref(struct device_link *link) 79372175d4eSRafael J. Wysocki { 79472175d4eSRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 79572175d4eSRafael J. Wysocki kref_put(&link->kref, __device_link_del); 79672175d4eSRafael J. Wysocki else 79772175d4eSRafael J. Wysocki WARN(1, "Unable to drop a managed device link reference\n"); 79872175d4eSRafael J. Wysocki } 79972175d4eSRafael J. Wysocki 8009ed98953SRafael J. Wysocki /** 80172175d4eSRafael J. Wysocki * device_link_del - Delete a stateless link between two devices. 8029ed98953SRafael J. Wysocki * @link: Device link to delete. 8039ed98953SRafael J. Wysocki * 8049ed98953SRafael J. Wysocki * The caller must ensure proper synchronization of this function with runtime 805ead18c23SLukas Wunner * PM. If the link was added multiple times, it needs to be deleted as often. 806ead18c23SLukas Wunner * Care is required for hotplugged devices: Their links are purged on removal 807ead18c23SLukas Wunner * and calling device_link_del() is then no longer allowed. 8089ed98953SRafael J. Wysocki */ 8099ed98953SRafael J. Wysocki void device_link_del(struct device_link *link) 8109ed98953SRafael J. Wysocki { 8119ed98953SRafael J. Wysocki device_links_write_lock(); 81272175d4eSRafael J. Wysocki device_link_put_kref(link); 8139ed98953SRafael J. Wysocki device_links_write_unlock(); 8149ed98953SRafael J. Wysocki } 8159ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_del); 8169ed98953SRafael J. Wysocki 817d8842211Spascal paillet /** 81872175d4eSRafael J. Wysocki * device_link_remove - Delete a stateless link between two devices. 819d8842211Spascal paillet * @consumer: Consumer end of the link. 820d8842211Spascal paillet * @supplier: Supplier end of the link. 821d8842211Spascal paillet * 822d8842211Spascal paillet * The caller must ensure proper synchronization of this function with runtime 823d8842211Spascal paillet * PM. 824d8842211Spascal paillet */ 825d8842211Spascal paillet void device_link_remove(void *consumer, struct device *supplier) 826d8842211Spascal paillet { 827d8842211Spascal paillet struct device_link *link; 828d8842211Spascal paillet 829d8842211Spascal paillet if (WARN_ON(consumer == supplier)) 830d8842211Spascal paillet return; 831d8842211Spascal paillet 832d8842211Spascal paillet device_links_write_lock(); 833d8842211Spascal paillet 834d8842211Spascal paillet list_for_each_entry(link, &supplier->links.consumers, s_node) { 835d8842211Spascal paillet if (link->consumer == consumer) { 83672175d4eSRafael J. Wysocki device_link_put_kref(link); 837d8842211Spascal paillet break; 838d8842211Spascal paillet } 839d8842211Spascal paillet } 840d8842211Spascal paillet 841d8842211Spascal paillet device_links_write_unlock(); 842d8842211Spascal paillet } 843d8842211Spascal paillet EXPORT_SYMBOL_GPL(device_link_remove); 844d8842211Spascal paillet 8459ed98953SRafael J. Wysocki static void device_links_missing_supplier(struct device *dev) 8469ed98953SRafael J. Wysocki { 8479ed98953SRafael J. Wysocki struct device_link *link; 8489ed98953SRafael J. Wysocki 8498c3e315dSSaravana Kannan list_for_each_entry(link, &dev->links.suppliers, c_node) { 8508c3e315dSSaravana Kannan if (link->status != DL_STATE_CONSUMER_PROBE) 8518c3e315dSSaravana Kannan continue; 8528c3e315dSSaravana Kannan 8538c3e315dSSaravana Kannan if (link->supplier->links.status == DL_DEV_DRIVER_BOUND) { 8549ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 8558c3e315dSSaravana Kannan } else { 8568c3e315dSSaravana Kannan WARN_ON(!(link->flags & DL_FLAG_SYNC_STATE_ONLY)); 8578c3e315dSSaravana Kannan WRITE_ONCE(link->status, DL_STATE_DORMANT); 8588c3e315dSSaravana Kannan } 8598c3e315dSSaravana Kannan } 8609ed98953SRafael J. Wysocki } 8619ed98953SRafael J. Wysocki 8629ed98953SRafael J. Wysocki /** 8639ed98953SRafael J. Wysocki * device_links_check_suppliers - Check presence of supplier drivers. 8649ed98953SRafael J. Wysocki * @dev: Consumer device. 8659ed98953SRafael J. Wysocki * 8669ed98953SRafael J. Wysocki * Check links from this device to any suppliers. Walk the list of the device's 8679ed98953SRafael J. Wysocki * links to suppliers and see if all of them are available. If not, simply 8689ed98953SRafael J. Wysocki * return -EPROBE_DEFER. 8699ed98953SRafael J. Wysocki * 8709ed98953SRafael J. Wysocki * We need to guarantee that the supplier will not go away after the check has 8719ed98953SRafael J. Wysocki * been positive here. It only can go away in __device_release_driver() and 8729ed98953SRafael J. Wysocki * that function checks the device's links to consumers. This means we need to 8739ed98953SRafael J. Wysocki * mark the link as "consumer probe in progress" to make the supplier removal 8749ed98953SRafael J. Wysocki * wait for us to complete (or bad things may happen). 8759ed98953SRafael J. Wysocki * 876515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 8779ed98953SRafael J. Wysocki */ 8789ed98953SRafael J. Wysocki int device_links_check_suppliers(struct device *dev) 8799ed98953SRafael J. Wysocki { 8809ed98953SRafael J. Wysocki struct device_link *link; 8819ed98953SRafael J. Wysocki int ret = 0; 8829ed98953SRafael J. Wysocki 883e2ae9bccSSaravana Kannan /* 884e2ae9bccSSaravana Kannan * Device waiting for supplier to become available is not allowed to 885e2ae9bccSSaravana Kannan * probe. 886e2ae9bccSSaravana Kannan */ 887e2ae9bccSSaravana Kannan mutex_lock(&wfs_lock); 888bcbbcfd5SSaravana Kannan if (!list_empty(&dev->links.needs_suppliers) && 889bcbbcfd5SSaravana Kannan dev->links.need_for_probe) { 890e2ae9bccSSaravana Kannan mutex_unlock(&wfs_lock); 891e2ae9bccSSaravana Kannan return -EPROBE_DEFER; 892e2ae9bccSSaravana Kannan } 893e2ae9bccSSaravana Kannan mutex_unlock(&wfs_lock); 894e2ae9bccSSaravana Kannan 8959ed98953SRafael J. Wysocki device_links_write_lock(); 8969ed98953SRafael J. Wysocki 8979ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 8988c3e315dSSaravana Kannan if (!(link->flags & DL_FLAG_MANAGED)) 8999ed98953SRafael J. Wysocki continue; 9009ed98953SRafael J. Wysocki 9018c3e315dSSaravana Kannan if (link->status != DL_STATE_AVAILABLE && 9028c3e315dSSaravana Kannan !(link->flags & DL_FLAG_SYNC_STATE_ONLY)) { 9039ed98953SRafael J. Wysocki device_links_missing_supplier(dev); 9049ed98953SRafael J. Wysocki ret = -EPROBE_DEFER; 9059ed98953SRafael J. Wysocki break; 9069ed98953SRafael J. Wysocki } 9079ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_CONSUMER_PROBE); 9089ed98953SRafael J. Wysocki } 9099ed98953SRafael J. Wysocki dev->links.status = DL_DEV_PROBING; 9109ed98953SRafael J. Wysocki 9119ed98953SRafael J. Wysocki device_links_write_unlock(); 9129ed98953SRafael J. Wysocki return ret; 9139ed98953SRafael J. Wysocki } 9149ed98953SRafael J. Wysocki 91526e77708SSaravana Kannan /** 91626e77708SSaravana Kannan * __device_links_queue_sync_state - Queue a device for sync_state() callback 91726e77708SSaravana Kannan * @dev: Device to call sync_state() on 91826e77708SSaravana Kannan * @list: List head to queue the @dev on 91926e77708SSaravana Kannan * 92026e77708SSaravana Kannan * Queues a device for a sync_state() callback when the device links write lock 92126e77708SSaravana Kannan * isn't held. This allows the sync_state() execution flow to use device links 92226e77708SSaravana Kannan * APIs. The caller must ensure this function is called with 92326e77708SSaravana Kannan * device_links_write_lock() held. 92426e77708SSaravana Kannan * 92526e77708SSaravana Kannan * This function does a get_device() to make sure the device is not freed while 92626e77708SSaravana Kannan * on this list. 92726e77708SSaravana Kannan * 92826e77708SSaravana Kannan * So the caller must also ensure that device_links_flush_sync_list() is called 92926e77708SSaravana Kannan * as soon as the caller releases device_links_write_lock(). This is necessary 93026e77708SSaravana Kannan * to make sure the sync_state() is called in a timely fashion and the 93126e77708SSaravana Kannan * put_device() is called on this device. 93226e77708SSaravana Kannan */ 93326e77708SSaravana Kannan static void __device_links_queue_sync_state(struct device *dev, 93426e77708SSaravana Kannan struct list_head *list) 935fc5a251dSSaravana Kannan { 936fc5a251dSSaravana Kannan struct device_link *link; 937fc5a251dSSaravana Kannan 93877036165SSaravana Kannan if (!dev_has_sync_state(dev)) 93977036165SSaravana Kannan return; 940fc5a251dSSaravana Kannan if (dev->state_synced) 941fc5a251dSSaravana Kannan return; 942fc5a251dSSaravana Kannan 943fc5a251dSSaravana Kannan list_for_each_entry(link, &dev->links.consumers, s_node) { 944fc5a251dSSaravana Kannan if (!(link->flags & DL_FLAG_MANAGED)) 945fc5a251dSSaravana Kannan continue; 946fc5a251dSSaravana Kannan if (link->status != DL_STATE_ACTIVE) 947fc5a251dSSaravana Kannan return; 948fc5a251dSSaravana Kannan } 949fc5a251dSSaravana Kannan 95026e77708SSaravana Kannan /* 95126e77708SSaravana Kannan * Set the flag here to avoid adding the same device to a list more 95226e77708SSaravana Kannan * than once. This can happen if new consumers get added to the device 95326e77708SSaravana Kannan * and probed before the list is flushed. 95426e77708SSaravana Kannan */ 95526e77708SSaravana Kannan dev->state_synced = true; 95626e77708SSaravana Kannan 957ec7bd784SSaravana Kannan if (WARN_ON(!list_empty(&dev->links.defer_hook))) 95826e77708SSaravana Kannan return; 95926e77708SSaravana Kannan 96026e77708SSaravana Kannan get_device(dev); 961ec7bd784SSaravana Kannan list_add_tail(&dev->links.defer_hook, list); 96226e77708SSaravana Kannan } 96326e77708SSaravana Kannan 96426e77708SSaravana Kannan /** 96526e77708SSaravana Kannan * device_links_flush_sync_list - Call sync_state() on a list of devices 96626e77708SSaravana Kannan * @list: List of devices to call sync_state() on 96721eb93f4SSaravana Kannan * @dont_lock_dev: Device for which lock is already held by the caller 96826e77708SSaravana Kannan * 96926e77708SSaravana Kannan * Calls sync_state() on all the devices that have been queued for it. This 97021eb93f4SSaravana Kannan * function is used in conjunction with __device_links_queue_sync_state(). The 97121eb93f4SSaravana Kannan * @dont_lock_dev parameter is useful when this function is called from a 97221eb93f4SSaravana Kannan * context where a device lock is already held. 97326e77708SSaravana Kannan */ 97421eb93f4SSaravana Kannan static void device_links_flush_sync_list(struct list_head *list, 97521eb93f4SSaravana Kannan struct device *dont_lock_dev) 97626e77708SSaravana Kannan { 97726e77708SSaravana Kannan struct device *dev, *tmp; 97826e77708SSaravana Kannan 979ec7bd784SSaravana Kannan list_for_each_entry_safe(dev, tmp, list, links.defer_hook) { 980ec7bd784SSaravana Kannan list_del_init(&dev->links.defer_hook); 98126e77708SSaravana Kannan 98221eb93f4SSaravana Kannan if (dev != dont_lock_dev) 98326e77708SSaravana Kannan device_lock(dev); 98426e77708SSaravana Kannan 985fc5a251dSSaravana Kannan if (dev->bus->sync_state) 986fc5a251dSSaravana Kannan dev->bus->sync_state(dev); 987fc5a251dSSaravana Kannan else if (dev->driver && dev->driver->sync_state) 988fc5a251dSSaravana Kannan dev->driver->sync_state(dev); 989fc5a251dSSaravana Kannan 99021eb93f4SSaravana Kannan if (dev != dont_lock_dev) 99126e77708SSaravana Kannan device_unlock(dev); 99226e77708SSaravana Kannan 99326e77708SSaravana Kannan put_device(dev); 99426e77708SSaravana Kannan } 995fc5a251dSSaravana Kannan } 996fc5a251dSSaravana Kannan 997fc5a251dSSaravana Kannan void device_links_supplier_sync_state_pause(void) 998fc5a251dSSaravana Kannan { 999fc5a251dSSaravana Kannan device_links_write_lock(); 1000fc5a251dSSaravana Kannan defer_sync_state_count++; 1001fc5a251dSSaravana Kannan device_links_write_unlock(); 1002fc5a251dSSaravana Kannan } 1003fc5a251dSSaravana Kannan 1004fc5a251dSSaravana Kannan void device_links_supplier_sync_state_resume(void) 1005fc5a251dSSaravana Kannan { 1006fc5a251dSSaravana Kannan struct device *dev, *tmp; 100726e77708SSaravana Kannan LIST_HEAD(sync_list); 1008fc5a251dSSaravana Kannan 1009fc5a251dSSaravana Kannan device_links_write_lock(); 1010fc5a251dSSaravana Kannan if (!defer_sync_state_count) { 1011fc5a251dSSaravana Kannan WARN(true, "Unmatched sync_state pause/resume!"); 1012fc5a251dSSaravana Kannan goto out; 1013fc5a251dSSaravana Kannan } 1014fc5a251dSSaravana Kannan defer_sync_state_count--; 1015fc5a251dSSaravana Kannan if (defer_sync_state_count) 1016fc5a251dSSaravana Kannan goto out; 1017fc5a251dSSaravana Kannan 1018ec7bd784SSaravana Kannan list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_hook) { 101926e77708SSaravana Kannan /* 102026e77708SSaravana Kannan * Delete from deferred_sync list before queuing it to 1021ec7bd784SSaravana Kannan * sync_list because defer_hook is used for both lists. 102226e77708SSaravana Kannan */ 1023ec7bd784SSaravana Kannan list_del_init(&dev->links.defer_hook); 102426e77708SSaravana Kannan __device_links_queue_sync_state(dev, &sync_list); 1025fc5a251dSSaravana Kannan } 1026fc5a251dSSaravana Kannan out: 1027fc5a251dSSaravana Kannan device_links_write_unlock(); 102826e77708SSaravana Kannan 102921eb93f4SSaravana Kannan device_links_flush_sync_list(&sync_list, NULL); 1030fc5a251dSSaravana Kannan } 1031fc5a251dSSaravana Kannan 1032fc5a251dSSaravana Kannan static int sync_state_resume_initcall(void) 1033fc5a251dSSaravana Kannan { 1034fc5a251dSSaravana Kannan device_links_supplier_sync_state_resume(); 1035fc5a251dSSaravana Kannan return 0; 1036fc5a251dSSaravana Kannan } 1037fc5a251dSSaravana Kannan late_initcall(sync_state_resume_initcall); 1038fc5a251dSSaravana Kannan 1039fc5a251dSSaravana Kannan static void __device_links_supplier_defer_sync(struct device *sup) 1040fc5a251dSSaravana Kannan { 1041ec7bd784SSaravana Kannan if (list_empty(&sup->links.defer_hook) && dev_has_sync_state(sup)) 1042ec7bd784SSaravana Kannan list_add_tail(&sup->links.defer_hook, &deferred_sync); 1043fc5a251dSSaravana Kannan } 1044fc5a251dSSaravana Kannan 104521c27f06SSaravana Kannan static void device_link_drop_managed(struct device_link *link) 104621c27f06SSaravana Kannan { 104721c27f06SSaravana Kannan link->flags &= ~DL_FLAG_MANAGED; 104821c27f06SSaravana Kannan WRITE_ONCE(link->status, DL_STATE_NONE); 104921c27f06SSaravana Kannan kref_put(&link->kref, __device_link_del); 105021c27f06SSaravana Kannan } 105121c27f06SSaravana Kannan 1052da6d6475SSaravana Kannan static ssize_t waiting_for_supplier_show(struct device *dev, 1053da6d6475SSaravana Kannan struct device_attribute *attr, 1054da6d6475SSaravana Kannan char *buf) 1055da6d6475SSaravana Kannan { 1056da6d6475SSaravana Kannan bool val; 1057da6d6475SSaravana Kannan 1058da6d6475SSaravana Kannan device_lock(dev); 1059da6d6475SSaravana Kannan mutex_lock(&wfs_lock); 1060da6d6475SSaravana Kannan val = !list_empty(&dev->links.needs_suppliers) 1061da6d6475SSaravana Kannan && dev->links.need_for_probe; 1062da6d6475SSaravana Kannan mutex_unlock(&wfs_lock); 1063da6d6475SSaravana Kannan device_unlock(dev); 1064aa838896SJoe Perches return sysfs_emit(buf, "%u\n", val); 1065da6d6475SSaravana Kannan } 1066da6d6475SSaravana Kannan static DEVICE_ATTR_RO(waiting_for_supplier); 1067da6d6475SSaravana Kannan 10689ed98953SRafael J. Wysocki /** 10699ed98953SRafael J. Wysocki * device_links_driver_bound - Update device links after probing its driver. 10709ed98953SRafael J. Wysocki * @dev: Device to update the links for. 10719ed98953SRafael J. Wysocki * 10729ed98953SRafael J. Wysocki * The probe has been successful, so update links from this device to any 10739ed98953SRafael J. Wysocki * consumers by changing their status to "available". 10749ed98953SRafael J. Wysocki * 10759ed98953SRafael J. Wysocki * Also change the status of @dev's links to suppliers to "active". 10769ed98953SRafael J. Wysocki * 1077515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 10789ed98953SRafael J. Wysocki */ 10799ed98953SRafael J. Wysocki void device_links_driver_bound(struct device *dev) 10809ed98953SRafael J. Wysocki { 108121c27f06SSaravana Kannan struct device_link *link, *ln; 108226e77708SSaravana Kannan LIST_HEAD(sync_list); 10839ed98953SRafael J. Wysocki 1084bcbbcfd5SSaravana Kannan /* 1085bcbbcfd5SSaravana Kannan * If a device probes successfully, it's expected to have created all 1086bcbbcfd5SSaravana Kannan * the device links it needs to or make new device links as it needs 1087bcbbcfd5SSaravana Kannan * them. So, it no longer needs to wait on any suppliers. 1088bcbbcfd5SSaravana Kannan */ 1089bcbbcfd5SSaravana Kannan mutex_lock(&wfs_lock); 1090bcbbcfd5SSaravana Kannan list_del_init(&dev->links.needs_suppliers); 1091bcbbcfd5SSaravana Kannan mutex_unlock(&wfs_lock); 1092da6d6475SSaravana Kannan device_remove_file(dev, &dev_attr_waiting_for_supplier); 1093bcbbcfd5SSaravana Kannan 10949ed98953SRafael J. Wysocki device_links_write_lock(); 10959ed98953SRafael J. Wysocki 10969ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1097515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 10989ed98953SRafael J. Wysocki continue; 10999ed98953SRafael J. Wysocki 110015cfb094SRafael J. Wysocki /* 110115cfb094SRafael J. Wysocki * Links created during consumer probe may be in the "consumer 110215cfb094SRafael J. Wysocki * probe" state to start with if the supplier is still probing 110315cfb094SRafael J. Wysocki * when they are created and they may become "active" if the 110415cfb094SRafael J. Wysocki * consumer probe returns first. Skip them here. 110515cfb094SRafael J. Wysocki */ 110615cfb094SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE || 110715cfb094SRafael J. Wysocki link->status == DL_STATE_ACTIVE) 110815cfb094SRafael J. Wysocki continue; 110915cfb094SRafael J. Wysocki 11109ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT); 11119ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 1112e7dd4010SRafael J. Wysocki 1113e7dd4010SRafael J. Wysocki if (link->flags & DL_FLAG_AUTOPROBE_CONSUMER) 1114e7dd4010SRafael J. Wysocki driver_deferred_probe_add(link->consumer); 11159ed98953SRafael J. Wysocki } 11169ed98953SRafael J. Wysocki 111721eb93f4SSaravana Kannan if (defer_sync_state_count) 111821eb93f4SSaravana Kannan __device_links_supplier_defer_sync(dev); 111921eb93f4SSaravana Kannan else 112021eb93f4SSaravana Kannan __device_links_queue_sync_state(dev, &sync_list); 112121eb93f4SSaravana Kannan 112221c27f06SSaravana Kannan list_for_each_entry_safe(link, ln, &dev->links.suppliers, c_node) { 112321c27f06SSaravana Kannan struct device *supplier; 112421c27f06SSaravana Kannan 1125515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 11269ed98953SRafael J. Wysocki continue; 11279ed98953SRafael J. Wysocki 112821c27f06SSaravana Kannan supplier = link->supplier; 112921c27f06SSaravana Kannan if (link->flags & DL_FLAG_SYNC_STATE_ONLY) { 113021c27f06SSaravana Kannan /* 113121c27f06SSaravana Kannan * When DL_FLAG_SYNC_STATE_ONLY is set, it means no 113221c27f06SSaravana Kannan * other DL_MANAGED_LINK_FLAGS have been set. So, it's 113321c27f06SSaravana Kannan * save to drop the managed link completely. 113421c27f06SSaravana Kannan */ 113521c27f06SSaravana Kannan device_link_drop_managed(link); 113621c27f06SSaravana Kannan } else { 11379ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); 11389ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_ACTIVE); 113921c27f06SSaravana Kannan } 1140fc5a251dSSaravana Kannan 114121c27f06SSaravana Kannan /* 114221c27f06SSaravana Kannan * This needs to be done even for the deleted 114321c27f06SSaravana Kannan * DL_FLAG_SYNC_STATE_ONLY device link in case it was the last 114421c27f06SSaravana Kannan * device link that was preventing the supplier from getting a 114521c27f06SSaravana Kannan * sync_state() call. 114621c27f06SSaravana Kannan */ 1147fc5a251dSSaravana Kannan if (defer_sync_state_count) 114821c27f06SSaravana Kannan __device_links_supplier_defer_sync(supplier); 1149fc5a251dSSaravana Kannan else 115021c27f06SSaravana Kannan __device_links_queue_sync_state(supplier, &sync_list); 11519ed98953SRafael J. Wysocki } 11529ed98953SRafael J. Wysocki 11539ed98953SRafael J. Wysocki dev->links.status = DL_DEV_DRIVER_BOUND; 11549ed98953SRafael J. Wysocki 11559ed98953SRafael J. Wysocki device_links_write_unlock(); 115626e77708SSaravana Kannan 115721eb93f4SSaravana Kannan device_links_flush_sync_list(&sync_list, dev); 11589ed98953SRafael J. Wysocki } 11599ed98953SRafael J. Wysocki 11609ed98953SRafael J. Wysocki /** 11619ed98953SRafael J. Wysocki * __device_links_no_driver - Update links of a device without a driver. 11629ed98953SRafael J. Wysocki * @dev: Device without a drvier. 11639ed98953SRafael J. Wysocki * 11649ed98953SRafael J. Wysocki * Delete all non-persistent links from this device to any suppliers. 11659ed98953SRafael J. Wysocki * 11669ed98953SRafael J. Wysocki * Persistent links stay around, but their status is changed to "available", 11679ed98953SRafael J. Wysocki * unless they already are in the "supplier unbind in progress" state in which 11689ed98953SRafael J. Wysocki * case they need not be updated. 11699ed98953SRafael J. Wysocki * 1170515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 11719ed98953SRafael J. Wysocki */ 11729ed98953SRafael J. Wysocki static void __device_links_no_driver(struct device *dev) 11739ed98953SRafael J. Wysocki { 11749ed98953SRafael J. Wysocki struct device_link *link, *ln; 11759ed98953SRafael J. Wysocki 11769ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 1177515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 11789ed98953SRafael J. Wysocki continue; 11799ed98953SRafael J. Wysocki 11808c3e315dSSaravana Kannan if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER) { 1181515db266SRafael J. Wysocki device_link_drop_managed(link); 11828c3e315dSSaravana Kannan continue; 11838c3e315dSSaravana Kannan } 11848c3e315dSSaravana Kannan 11858c3e315dSSaravana Kannan if (link->status != DL_STATE_CONSUMER_PROBE && 11868c3e315dSSaravana Kannan link->status != DL_STATE_ACTIVE) 11878c3e315dSSaravana Kannan continue; 11888c3e315dSSaravana Kannan 11898c3e315dSSaravana Kannan if (link->supplier->links.status == DL_DEV_DRIVER_BOUND) { 11909ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 11918c3e315dSSaravana Kannan } else { 11928c3e315dSSaravana Kannan WARN_ON(!(link->flags & DL_FLAG_SYNC_STATE_ONLY)); 11938c3e315dSSaravana Kannan WRITE_ONCE(link->status, DL_STATE_DORMANT); 11948c3e315dSSaravana Kannan } 11959ed98953SRafael J. Wysocki } 11969ed98953SRafael J. Wysocki 11979ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 11989ed98953SRafael J. Wysocki } 11999ed98953SRafael J. Wysocki 120015cfb094SRafael J. Wysocki /** 120115cfb094SRafael J. Wysocki * device_links_no_driver - Update links after failing driver probe. 120215cfb094SRafael J. Wysocki * @dev: Device whose driver has just failed to probe. 120315cfb094SRafael J. Wysocki * 120415cfb094SRafael J. Wysocki * Clean up leftover links to consumers for @dev and invoke 120515cfb094SRafael J. Wysocki * %__device_links_no_driver() to update links to suppliers for it as 120615cfb094SRafael J. Wysocki * appropriate. 120715cfb094SRafael J. Wysocki * 1208515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 120915cfb094SRafael J. Wysocki */ 12109ed98953SRafael J. Wysocki void device_links_no_driver(struct device *dev) 12119ed98953SRafael J. Wysocki { 121215cfb094SRafael J. Wysocki struct device_link *link; 121315cfb094SRafael J. Wysocki 12149ed98953SRafael J. Wysocki device_links_write_lock(); 121515cfb094SRafael J. Wysocki 121615cfb094SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1217515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 121815cfb094SRafael J. Wysocki continue; 121915cfb094SRafael J. Wysocki 122015cfb094SRafael J. Wysocki /* 122115cfb094SRafael J. Wysocki * The probe has failed, so if the status of the link is 122215cfb094SRafael J. Wysocki * "consumer probe" or "active", it must have been added by 122315cfb094SRafael J. Wysocki * a probing consumer while this device was still probing. 122415cfb094SRafael J. Wysocki * Change its state to "dormant", as it represents a valid 122515cfb094SRafael J. Wysocki * relationship, but it is not functionally meaningful. 122615cfb094SRafael J. Wysocki */ 122715cfb094SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE || 122815cfb094SRafael J. Wysocki link->status == DL_STATE_ACTIVE) 122915cfb094SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_DORMANT); 123015cfb094SRafael J. Wysocki } 123115cfb094SRafael J. Wysocki 12329ed98953SRafael J. Wysocki __device_links_no_driver(dev); 123315cfb094SRafael J. Wysocki 12349ed98953SRafael J. Wysocki device_links_write_unlock(); 12359ed98953SRafael J. Wysocki } 12369ed98953SRafael J. Wysocki 12379ed98953SRafael J. Wysocki /** 12389ed98953SRafael J. Wysocki * device_links_driver_cleanup - Update links after driver removal. 12399ed98953SRafael J. Wysocki * @dev: Device whose driver has just gone away. 12409ed98953SRafael J. Wysocki * 12419ed98953SRafael J. Wysocki * Update links to consumers for @dev by changing their status to "dormant" and 12429ed98953SRafael J. Wysocki * invoke %__device_links_no_driver() to update links to suppliers for it as 12439ed98953SRafael J. Wysocki * appropriate. 12449ed98953SRafael J. Wysocki * 1245515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 12469ed98953SRafael J. Wysocki */ 12479ed98953SRafael J. Wysocki void device_links_driver_cleanup(struct device *dev) 12489ed98953SRafael J. Wysocki { 1249c8d50986SRafael J. Wysocki struct device_link *link, *ln; 12509ed98953SRafael J. Wysocki 12519ed98953SRafael J. Wysocki device_links_write_lock(); 12529ed98953SRafael J. Wysocki 1253c8d50986SRafael J. Wysocki list_for_each_entry_safe(link, ln, &dev->links.consumers, s_node) { 1254515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 12559ed98953SRafael J. Wysocki continue; 12569ed98953SRafael J. Wysocki 1257e88728f4SVivek Gautam WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER); 12589ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND); 12591689cac5SVivek Gautam 12601689cac5SVivek Gautam /* 12611689cac5SVivek Gautam * autoremove the links between this @dev and its consumer 12621689cac5SVivek Gautam * devices that are not active, i.e. where the link state 12631689cac5SVivek Gautam * has moved to DL_STATE_SUPPLIER_UNBIND. 12641689cac5SVivek Gautam */ 12651689cac5SVivek Gautam if (link->status == DL_STATE_SUPPLIER_UNBIND && 12661689cac5SVivek Gautam link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER) 1267515db266SRafael J. Wysocki device_link_drop_managed(link); 12681689cac5SVivek Gautam 12699ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_DORMANT); 12709ed98953SRafael J. Wysocki } 12719ed98953SRafael J. Wysocki 1272ec7bd784SSaravana Kannan list_del_init(&dev->links.defer_hook); 12739ed98953SRafael J. Wysocki __device_links_no_driver(dev); 12749ed98953SRafael J. Wysocki 12759ed98953SRafael J. Wysocki device_links_write_unlock(); 12769ed98953SRafael J. Wysocki } 12779ed98953SRafael J. Wysocki 12789ed98953SRafael J. Wysocki /** 12799ed98953SRafael J. Wysocki * device_links_busy - Check if there are any busy links to consumers. 12809ed98953SRafael J. Wysocki * @dev: Device to check. 12819ed98953SRafael J. Wysocki * 12829ed98953SRafael J. Wysocki * Check each consumer of the device and return 'true' if its link's status 12839ed98953SRafael J. Wysocki * is one of "consumer probe" or "active" (meaning that the given consumer is 12849ed98953SRafael J. Wysocki * probing right now or its driver is present). Otherwise, change the link 12859ed98953SRafael J. Wysocki * state to "supplier unbind" to prevent the consumer from being probed 12869ed98953SRafael J. Wysocki * successfully going forward. 12879ed98953SRafael J. Wysocki * 12889ed98953SRafael J. Wysocki * Return 'false' if there are no probing or active consumers. 12899ed98953SRafael J. Wysocki * 1290515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 12919ed98953SRafael J. Wysocki */ 12929ed98953SRafael J. Wysocki bool device_links_busy(struct device *dev) 12939ed98953SRafael J. Wysocki { 12949ed98953SRafael J. Wysocki struct device_link *link; 12959ed98953SRafael J. Wysocki bool ret = false; 12969ed98953SRafael J. Wysocki 12979ed98953SRafael J. Wysocki device_links_write_lock(); 12989ed98953SRafael J. Wysocki 12999ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1300515db266SRafael J. Wysocki if (!(link->flags & DL_FLAG_MANAGED)) 13019ed98953SRafael J. Wysocki continue; 13029ed98953SRafael J. Wysocki 13039ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE 13049ed98953SRafael J. Wysocki || link->status == DL_STATE_ACTIVE) { 13059ed98953SRafael J. Wysocki ret = true; 13069ed98953SRafael J. Wysocki break; 13079ed98953SRafael J. Wysocki } 13089ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 13099ed98953SRafael J. Wysocki } 13109ed98953SRafael J. Wysocki 13119ed98953SRafael J. Wysocki dev->links.status = DL_DEV_UNBINDING; 13129ed98953SRafael J. Wysocki 13139ed98953SRafael J. Wysocki device_links_write_unlock(); 13149ed98953SRafael J. Wysocki return ret; 13159ed98953SRafael J. Wysocki } 13169ed98953SRafael J. Wysocki 13179ed98953SRafael J. Wysocki /** 13189ed98953SRafael J. Wysocki * device_links_unbind_consumers - Force unbind consumers of the given device. 13199ed98953SRafael J. Wysocki * @dev: Device to unbind the consumers of. 13209ed98953SRafael J. Wysocki * 13219ed98953SRafael J. Wysocki * Walk the list of links to consumers for @dev and if any of them is in the 13229ed98953SRafael J. Wysocki * "consumer probe" state, wait for all device probes in progress to complete 13239ed98953SRafael J. Wysocki * and start over. 13249ed98953SRafael J. Wysocki * 13259ed98953SRafael J. Wysocki * If that's not the case, change the status of the link to "supplier unbind" 13269ed98953SRafael J. Wysocki * and check if the link was in the "active" state. If so, force the consumer 13279ed98953SRafael J. Wysocki * driver to unbind and start over (the consumer will not re-probe as we have 13289ed98953SRafael J. Wysocki * changed the state of the link already). 13299ed98953SRafael J. Wysocki * 1330515db266SRafael J. Wysocki * Links without the DL_FLAG_MANAGED flag set are ignored. 13319ed98953SRafael J. Wysocki */ 13329ed98953SRafael J. Wysocki void device_links_unbind_consumers(struct device *dev) 13339ed98953SRafael J. Wysocki { 13349ed98953SRafael J. Wysocki struct device_link *link; 13359ed98953SRafael J. Wysocki 13369ed98953SRafael J. Wysocki start: 13379ed98953SRafael J. Wysocki device_links_write_lock(); 13389ed98953SRafael J. Wysocki 13399ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 13409ed98953SRafael J. Wysocki enum device_link_state status; 13419ed98953SRafael J. Wysocki 134205ef983eSSaravana Kannan if (!(link->flags & DL_FLAG_MANAGED) || 134305ef983eSSaravana Kannan link->flags & DL_FLAG_SYNC_STATE_ONLY) 13449ed98953SRafael J. Wysocki continue; 13459ed98953SRafael J. Wysocki 13469ed98953SRafael J. Wysocki status = link->status; 13479ed98953SRafael J. Wysocki if (status == DL_STATE_CONSUMER_PROBE) { 13489ed98953SRafael J. Wysocki device_links_write_unlock(); 13499ed98953SRafael J. Wysocki 13509ed98953SRafael J. Wysocki wait_for_device_probe(); 13519ed98953SRafael J. Wysocki goto start; 13529ed98953SRafael J. Wysocki } 13539ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 13549ed98953SRafael J. Wysocki if (status == DL_STATE_ACTIVE) { 13559ed98953SRafael J. Wysocki struct device *consumer = link->consumer; 13569ed98953SRafael J. Wysocki 13579ed98953SRafael J. Wysocki get_device(consumer); 13589ed98953SRafael J. Wysocki 13599ed98953SRafael J. Wysocki device_links_write_unlock(); 13609ed98953SRafael J. Wysocki 13619ed98953SRafael J. Wysocki device_release_driver_internal(consumer, NULL, 13629ed98953SRafael J. Wysocki consumer->parent); 13639ed98953SRafael J. Wysocki put_device(consumer); 13649ed98953SRafael J. Wysocki goto start; 13659ed98953SRafael J. Wysocki } 13669ed98953SRafael J. Wysocki } 13679ed98953SRafael J. Wysocki 13689ed98953SRafael J. Wysocki device_links_write_unlock(); 13699ed98953SRafael J. Wysocki } 13709ed98953SRafael J. Wysocki 13719ed98953SRafael J. Wysocki /** 13729ed98953SRafael J. Wysocki * device_links_purge - Delete existing links to other devices. 13739ed98953SRafael J. Wysocki * @dev: Target device. 13749ed98953SRafael J. Wysocki */ 13759ed98953SRafael J. Wysocki static void device_links_purge(struct device *dev) 13769ed98953SRafael J. Wysocki { 13779ed98953SRafael J. Wysocki struct device_link *link, *ln; 13789ed98953SRafael J. Wysocki 1379287905e6SSaravana Kannan if (dev->class == &devlink_class) 1380287905e6SSaravana Kannan return; 1381287905e6SSaravana Kannan 1382e2ae9bccSSaravana Kannan mutex_lock(&wfs_lock); 1383e2ae9bccSSaravana Kannan list_del(&dev->links.needs_suppliers); 1384e2ae9bccSSaravana Kannan mutex_unlock(&wfs_lock); 1385e2ae9bccSSaravana Kannan 13869ed98953SRafael J. Wysocki /* 13879ed98953SRafael J. Wysocki * Delete all of the remaining links from this device to any other 13889ed98953SRafael J. Wysocki * devices (either consumers or suppliers). 13899ed98953SRafael J. Wysocki */ 13909ed98953SRafael J. Wysocki device_links_write_lock(); 13919ed98953SRafael J. Wysocki 13929ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 13939ed98953SRafael J. Wysocki WARN_ON(link->status == DL_STATE_ACTIVE); 1394ead18c23SLukas Wunner __device_link_del(&link->kref); 13959ed98953SRafael J. Wysocki } 13969ed98953SRafael J. Wysocki 13979ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) { 13989ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT && 13999ed98953SRafael J. Wysocki link->status != DL_STATE_NONE); 1400ead18c23SLukas Wunner __device_link_del(&link->kref); 14019ed98953SRafael J. Wysocki } 14029ed98953SRafael J. Wysocki 14039ed98953SRafael J. Wysocki device_links_write_unlock(); 14049ed98953SRafael J. Wysocki } 14059ed98953SRafael J. Wysocki 140642926ac3SSaravana Kannan static u32 fw_devlink_flags = DL_FLAG_SYNC_STATE_ONLY; 140742926ac3SSaravana Kannan static int __init fw_devlink_setup(char *arg) 140842926ac3SSaravana Kannan { 140942926ac3SSaravana Kannan if (!arg) 141042926ac3SSaravana Kannan return -EINVAL; 141142926ac3SSaravana Kannan 141242926ac3SSaravana Kannan if (strcmp(arg, "off") == 0) { 141342926ac3SSaravana Kannan fw_devlink_flags = 0; 141442926ac3SSaravana Kannan } else if (strcmp(arg, "permissive") == 0) { 141542926ac3SSaravana Kannan fw_devlink_flags = DL_FLAG_SYNC_STATE_ONLY; 141642926ac3SSaravana Kannan } else if (strcmp(arg, "on") == 0) { 141742926ac3SSaravana Kannan fw_devlink_flags = DL_FLAG_AUTOPROBE_CONSUMER; 141842926ac3SSaravana Kannan } else if (strcmp(arg, "rpm") == 0) { 141942926ac3SSaravana Kannan fw_devlink_flags = DL_FLAG_AUTOPROBE_CONSUMER | 142042926ac3SSaravana Kannan DL_FLAG_PM_RUNTIME; 142142926ac3SSaravana Kannan } 142242926ac3SSaravana Kannan return 0; 142342926ac3SSaravana Kannan } 142442926ac3SSaravana Kannan early_param("fw_devlink", fw_devlink_setup); 142542926ac3SSaravana Kannan 142642926ac3SSaravana Kannan u32 fw_devlink_get_flags(void) 142742926ac3SSaravana Kannan { 142842926ac3SSaravana Kannan return fw_devlink_flags; 142942926ac3SSaravana Kannan } 143042926ac3SSaravana Kannan 143142926ac3SSaravana Kannan static bool fw_devlink_is_permissive(void) 143242926ac3SSaravana Kannan { 143342926ac3SSaravana Kannan return fw_devlink_flags == DL_FLAG_SYNC_STATE_ONLY; 143442926ac3SSaravana Kannan } 143542926ac3SSaravana Kannan 14365f5377eaSSaravana Kannan static void fw_devlink_link_device(struct device *dev) 14375f5377eaSSaravana Kannan { 14385f5377eaSSaravana Kannan int fw_ret; 14395f5377eaSSaravana Kannan 1440716a7a25SSaravana Kannan if (!fw_devlink_flags) 1441716a7a25SSaravana Kannan return; 1442716a7a25SSaravana Kannan 1443716a7a25SSaravana Kannan mutex_lock(&defer_fw_devlink_lock); 1444716a7a25SSaravana Kannan if (!defer_fw_devlink_count) 14455f5377eaSSaravana Kannan device_link_add_missing_supplier_links(); 14465f5377eaSSaravana Kannan 1447716a7a25SSaravana Kannan /* 1448716a7a25SSaravana Kannan * The device's fwnode not having add_links() doesn't affect if other 1449716a7a25SSaravana Kannan * consumers can find this device as a supplier. So, this check is 1450716a7a25SSaravana Kannan * intentionally placed after device_link_add_missing_supplier_links(). 1451716a7a25SSaravana Kannan */ 1452716a7a25SSaravana Kannan if (!fwnode_has_op(dev->fwnode, add_links)) 1453716a7a25SSaravana Kannan goto out; 1454716a7a25SSaravana Kannan 1455716a7a25SSaravana Kannan /* 1456716a7a25SSaravana Kannan * If fw_devlink is being deferred, assume all devices have mandatory 1457716a7a25SSaravana Kannan * suppliers they need to link to later. Then, when the fw_devlink is 1458716a7a25SSaravana Kannan * resumed, all these devices will get a chance to try and link to any 1459716a7a25SSaravana Kannan * suppliers they have. 1460716a7a25SSaravana Kannan */ 1461716a7a25SSaravana Kannan if (!defer_fw_devlink_count) { 14625f5377eaSSaravana Kannan fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); 1463716a7a25SSaravana Kannan if (fw_ret == -ENODEV && fw_devlink_is_permissive()) 1464716a7a25SSaravana Kannan fw_ret = -EAGAIN; 1465716a7a25SSaravana Kannan } else { 1466716a7a25SSaravana Kannan fw_ret = -ENODEV; 14672451e746SSaravana Kannan /* 14682451e746SSaravana Kannan * defer_hook is not used to add device to deferred_sync list 14692451e746SSaravana Kannan * until device is bound. Since deferred fw devlink also blocks 14702451e746SSaravana Kannan * probing, same list hook can be used for deferred_fw_devlink. 14712451e746SSaravana Kannan */ 14722451e746SSaravana Kannan list_add_tail(&dev->links.defer_hook, &deferred_fw_devlink); 1473716a7a25SSaravana Kannan } 1474716a7a25SSaravana Kannan 1475716a7a25SSaravana Kannan if (fw_ret == -ENODEV) 14765f5377eaSSaravana Kannan device_link_wait_for_mandatory_supplier(dev); 14775f5377eaSSaravana Kannan else if (fw_ret) 14785f5377eaSSaravana Kannan device_link_wait_for_optional_supplier(dev); 1479716a7a25SSaravana Kannan 1480716a7a25SSaravana Kannan out: 1481716a7a25SSaravana Kannan mutex_unlock(&defer_fw_devlink_lock); 14825f5377eaSSaravana Kannan } 14835f5377eaSSaravana Kannan 1484716a7a25SSaravana Kannan /** 1485716a7a25SSaravana Kannan * fw_devlink_pause - Pause parsing of fwnode to create device links 1486716a7a25SSaravana Kannan * 1487716a7a25SSaravana Kannan * Calling this function defers any fwnode parsing to create device links until 1488716a7a25SSaravana Kannan * fw_devlink_resume() is called. Both these functions are ref counted and the 1489716a7a25SSaravana Kannan * caller needs to match the calls. 1490716a7a25SSaravana Kannan * 1491716a7a25SSaravana Kannan * While fw_devlink is paused: 1492716a7a25SSaravana Kannan * - Any device that is added won't have its fwnode parsed to create device 1493716a7a25SSaravana Kannan * links. 1494716a7a25SSaravana Kannan * - The probe of the device will also be deferred during this period. 1495716a7a25SSaravana Kannan * - Any devices that were already added, but waiting for suppliers won't be 1496716a7a25SSaravana Kannan * able to link to newly added devices. 1497716a7a25SSaravana Kannan * 1498716a7a25SSaravana Kannan * Once fw_devlink_resume(): 1499716a7a25SSaravana Kannan * - All the fwnodes that was not parsed will be parsed. 1500716a7a25SSaravana Kannan * - All the devices that were deferred probing will be reattempted if they 1501716a7a25SSaravana Kannan * aren't waiting for any more suppliers. 1502716a7a25SSaravana Kannan * 1503716a7a25SSaravana Kannan * This pair of functions, is mainly meant to optimize the parsing of fwnodes 1504716a7a25SSaravana Kannan * when a lot of devices that need to link to each other are added in a short 1505716a7a25SSaravana Kannan * interval of time. For example, adding all the top level devices in a system. 1506716a7a25SSaravana Kannan * 1507716a7a25SSaravana Kannan * For example, if N devices are added and: 1508716a7a25SSaravana Kannan * - All the consumers are added before their suppliers 1509716a7a25SSaravana Kannan * - All the suppliers of the N devices are part of the N devices 1510716a7a25SSaravana Kannan * 1511716a7a25SSaravana Kannan * Then: 1512716a7a25SSaravana Kannan * 1513716a7a25SSaravana Kannan * - With the use of fw_devlink_pause() and fw_devlink_resume(), each device 1514716a7a25SSaravana Kannan * will only need one parsing of its fwnode because it is guaranteed to find 1515716a7a25SSaravana Kannan * all the supplier devices already registered and ready to link to. It won't 1516716a7a25SSaravana Kannan * have to do another pass later to find one or more suppliers it couldn't 1517716a7a25SSaravana Kannan * find in the first parse of the fwnode. So, we'll only need O(N) fwnode 1518716a7a25SSaravana Kannan * parses. 1519716a7a25SSaravana Kannan * 1520716a7a25SSaravana Kannan * - Without the use of fw_devlink_pause() and fw_devlink_resume(), we would 1521716a7a25SSaravana Kannan * end up doing O(N^2) parses of fwnodes because every device that's added is 1522716a7a25SSaravana Kannan * guaranteed to trigger a parse of the fwnode of every device added before 1523716a7a25SSaravana Kannan * it. This O(N^2) parse is made worse by the fact that when a fwnode of a 1524716a7a25SSaravana Kannan * device is parsed, all it descendant devices might need to have their 1525716a7a25SSaravana Kannan * fwnodes parsed too (even if the devices themselves aren't added). 1526716a7a25SSaravana Kannan */ 1527716a7a25SSaravana Kannan void fw_devlink_pause(void) 1528716a7a25SSaravana Kannan { 1529716a7a25SSaravana Kannan mutex_lock(&defer_fw_devlink_lock); 1530716a7a25SSaravana Kannan defer_fw_devlink_count++; 1531716a7a25SSaravana Kannan mutex_unlock(&defer_fw_devlink_lock); 1532716a7a25SSaravana Kannan } 1533716a7a25SSaravana Kannan 1534716a7a25SSaravana Kannan /** fw_devlink_resume - Resume parsing of fwnode to create device links 1535716a7a25SSaravana Kannan * 1536716a7a25SSaravana Kannan * This function is used in conjunction with fw_devlink_pause() and is ref 1537716a7a25SSaravana Kannan * counted. See documentation for fw_devlink_pause() for more details. 1538716a7a25SSaravana Kannan */ 1539716a7a25SSaravana Kannan void fw_devlink_resume(void) 1540716a7a25SSaravana Kannan { 15412451e746SSaravana Kannan struct device *dev, *tmp; 15422451e746SSaravana Kannan LIST_HEAD(probe_list); 15432451e746SSaravana Kannan 1544716a7a25SSaravana Kannan mutex_lock(&defer_fw_devlink_lock); 1545716a7a25SSaravana Kannan if (!defer_fw_devlink_count) { 1546716a7a25SSaravana Kannan WARN(true, "Unmatched fw_devlink pause/resume!"); 1547716a7a25SSaravana Kannan goto out; 1548716a7a25SSaravana Kannan } 1549716a7a25SSaravana Kannan 1550716a7a25SSaravana Kannan defer_fw_devlink_count--; 1551716a7a25SSaravana Kannan if (defer_fw_devlink_count) 1552716a7a25SSaravana Kannan goto out; 1553716a7a25SSaravana Kannan 1554716a7a25SSaravana Kannan device_link_add_missing_supplier_links(); 15552451e746SSaravana Kannan list_splice_tail_init(&deferred_fw_devlink, &probe_list); 1556716a7a25SSaravana Kannan out: 1557716a7a25SSaravana Kannan mutex_unlock(&defer_fw_devlink_lock); 15582451e746SSaravana Kannan 15592451e746SSaravana Kannan /* 15602451e746SSaravana Kannan * bus_probe_device() can cause new devices to get added and they'll 15612451e746SSaravana Kannan * try to grab defer_fw_devlink_lock. So, this needs to be done outside 15622451e746SSaravana Kannan * the defer_fw_devlink_lock. 15632451e746SSaravana Kannan */ 15642451e746SSaravana Kannan list_for_each_entry_safe(dev, tmp, &probe_list, links.defer_hook) { 15652451e746SSaravana Kannan list_del_init(&dev->links.defer_hook); 15662451e746SSaravana Kannan bus_probe_device(dev); 15672451e746SSaravana Kannan } 1568716a7a25SSaravana Kannan } 15699ed98953SRafael J. Wysocki /* Device links support end. */ 15709ed98953SRafael J. Wysocki 15711da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 15721da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 1573e105b8bfSDan Williams static struct kobject *dev_kobj; 1574e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 1575e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 15761da177e4SLinus Torvalds 15775e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 15785e33bc41SRafael J. Wysocki 15795e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 15805e33bc41SRafael J. Wysocki { 15815e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 15825e33bc41SRafael J. Wysocki } 15835e33bc41SRafael J. Wysocki 15845e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 15855e33bc41SRafael J. Wysocki { 15865e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 15875e33bc41SRafael J. Wysocki } 15885e33bc41SRafael J. Wysocki 15895e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 15905e33bc41SRafael J. Wysocki { 15915e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 15925e33bc41SRafael J. Wysocki return 0; 15935e33bc41SRafael J. Wysocki 15945e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 15955e33bc41SRafael J. Wysocki msleep(5); 15965e33bc41SRafael J. Wysocki return restart_syscall(); 15975e33bc41SRafael J. Wysocki } 15985e33bc41SRafael J. Wysocki 15994e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 16004e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 16014e886c29SGreg Kroah-Hartman { 16024e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 16034e886c29SGreg Kroah-Hartman } 16044e886c29SGreg Kroah-Hartman #else 16054e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 16064e886c29SGreg Kroah-Hartman { 16074e886c29SGreg Kroah-Hartman return 1; 16084e886c29SGreg Kroah-Hartman } 16094e886c29SGreg Kroah-Hartman #endif 16101da177e4SLinus Torvalds 161107de0e86SHeikki Krogerus static int 161207de0e86SHeikki Krogerus device_platform_notify(struct device *dev, enum kobject_action action) 161307de0e86SHeikki Krogerus { 16147847a145SHeikki Krogerus int ret; 16157847a145SHeikki Krogerus 16167847a145SHeikki Krogerus ret = acpi_platform_notify(dev, action); 16177847a145SHeikki Krogerus if (ret) 16187847a145SHeikki Krogerus return ret; 16197847a145SHeikki Krogerus 162059abd836SHeikki Krogerus ret = software_node_notify(dev, action); 162159abd836SHeikki Krogerus if (ret) 162259abd836SHeikki Krogerus return ret; 162359abd836SHeikki Krogerus 162407de0e86SHeikki Krogerus if (platform_notify && action == KOBJ_ADD) 162507de0e86SHeikki Krogerus platform_notify(dev); 162607de0e86SHeikki Krogerus else if (platform_notify_remove && action == KOBJ_REMOVE) 162707de0e86SHeikki Krogerus platform_notify_remove(dev); 162807de0e86SHeikki Krogerus return 0; 162907de0e86SHeikki Krogerus } 163007de0e86SHeikki Krogerus 16313e95637aSAlan Stern /** 16323e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 16333e95637aSAlan Stern * @dev: struct device to get the name of 16343e95637aSAlan Stern * 16353e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 16369169c012Syan * the device is not bound to a driver, it will return the name of the bus 16373e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 16383e95637aSAlan Stern * string will be returned. 16393e95637aSAlan Stern */ 1640bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 16413e95637aSAlan Stern { 16423589972eSAlan Stern struct device_driver *drv; 16433589972eSAlan Stern 16443589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 16453589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 16463589972eSAlan Stern * never change once they are set, so they don't need special care. 16473589972eSAlan Stern */ 16486aa7de05SMark Rutland drv = READ_ONCE(dev->driver); 16493589972eSAlan Stern return drv ? drv->name : 1650a456b702SJean Delvare (dev->bus ? dev->bus->name : 1651a456b702SJean Delvare (dev->class ? dev->class->name : "")); 16523e95637aSAlan Stern } 1653310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 16543e95637aSAlan Stern 16551da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 16561da177e4SLinus Torvalds 16574a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 16584a3ad20cSGreg Kroah-Hartman char *buf) 16591da177e4SLinus Torvalds { 16601da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 1661b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 16624a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 16631da177e4SLinus Torvalds 16641da177e4SLinus Torvalds if (dev_attr->show) 166554b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 1666815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 1667a52668c6SSergey Senozhatsky printk("dev_attr_show: %pS returned bad count\n", 1668a52668c6SSergey Senozhatsky dev_attr->show); 1669815d2d50SAndrew Morton } 16701da177e4SLinus Torvalds return ret; 16711da177e4SLinus Torvalds } 16721da177e4SLinus Torvalds 16734a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 16741da177e4SLinus Torvalds const char *buf, size_t count) 16751da177e4SLinus Torvalds { 16761da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 1677b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 16784a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 16791da177e4SLinus Torvalds 16801da177e4SLinus Torvalds if (dev_attr->store) 168154b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 16821da177e4SLinus Torvalds return ret; 16831da177e4SLinus Torvalds } 16841da177e4SLinus Torvalds 168552cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 16861da177e4SLinus Torvalds .show = dev_attr_show, 16871da177e4SLinus Torvalds .store = dev_attr_store, 16881da177e4SLinus Torvalds }; 16891da177e4SLinus Torvalds 1690ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 1691ca22e56dSKay Sievers 1692ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 1693ca22e56dSKay Sievers struct device_attribute *attr, 1694ca22e56dSKay Sievers const char *buf, size_t size) 1695ca22e56dSKay Sievers { 1696ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 1697f88184bfSKaitao cheng int ret; 1698f88184bfSKaitao cheng unsigned long new; 1699f88184bfSKaitao cheng 1700f88184bfSKaitao cheng ret = kstrtoul(buf, 0, &new); 1701f88184bfSKaitao cheng if (ret) 1702f88184bfSKaitao cheng return ret; 1703ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 1704ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 1705ca22e56dSKay Sievers return size; 1706ca22e56dSKay Sievers } 1707ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 1708ca22e56dSKay Sievers 1709ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 1710ca22e56dSKay Sievers struct device_attribute *attr, 1711ca22e56dSKay Sievers char *buf) 1712ca22e56dSKay Sievers { 1713ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 1714aa838896SJoe Perches return sysfs_emit(buf, "%lx\n", *(unsigned long *)(ea->var)); 1715ca22e56dSKay Sievers } 1716ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 1717ca22e56dSKay Sievers 1718ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 1719ca22e56dSKay Sievers struct device_attribute *attr, 1720ca22e56dSKay Sievers const char *buf, size_t size) 1721ca22e56dSKay Sievers { 1722ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 1723f88184bfSKaitao cheng int ret; 1724f88184bfSKaitao cheng long new; 1725f88184bfSKaitao cheng 1726f88184bfSKaitao cheng ret = kstrtol(buf, 0, &new); 1727f88184bfSKaitao cheng if (ret) 1728f88184bfSKaitao cheng return ret; 1729f88184bfSKaitao cheng 1730f88184bfSKaitao cheng if (new > INT_MAX || new < INT_MIN) 1731ca22e56dSKay Sievers return -EINVAL; 1732ca22e56dSKay Sievers *(int *)(ea->var) = new; 1733ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 1734ca22e56dSKay Sievers return size; 1735ca22e56dSKay Sievers } 1736ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 1737ca22e56dSKay Sievers 1738ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 1739ca22e56dSKay Sievers struct device_attribute *attr, 1740ca22e56dSKay Sievers char *buf) 1741ca22e56dSKay Sievers { 1742ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 1743ca22e56dSKay Sievers 1744aa838896SJoe Perches return sysfs_emit(buf, "%d\n", *(int *)(ea->var)); 1745ca22e56dSKay Sievers } 1746ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 17471da177e4SLinus Torvalds 174891872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 174991872392SBorislav Petkov const char *buf, size_t size) 175091872392SBorislav Petkov { 175191872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 175291872392SBorislav Petkov 175391872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 175491872392SBorislav Petkov return -EINVAL; 175591872392SBorislav Petkov 175691872392SBorislav Petkov return size; 175791872392SBorislav Petkov } 175891872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 175991872392SBorislav Petkov 176091872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 176191872392SBorislav Petkov char *buf) 176291872392SBorislav Petkov { 176391872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 176491872392SBorislav Petkov 1765aa838896SJoe Perches return sysfs_emit(buf, "%d\n", *(bool *)(ea->var)); 176691872392SBorislav Petkov } 176791872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 176891872392SBorislav Petkov 17691da177e4SLinus Torvalds /** 17701da177e4SLinus Torvalds * device_release - free device structure. 17711da177e4SLinus Torvalds * @kobj: device's kobject. 17721da177e4SLinus Torvalds * 17731da177e4SLinus Torvalds * This is called once the reference count for the object 17741da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 17751da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 17761da177e4SLinus Torvalds */ 17771da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 17781da177e4SLinus Torvalds { 1779b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1780fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 17811da177e4SLinus Torvalds 1782a525a3ddSMing Lei /* 1783a525a3ddSMing Lei * Some platform devices are driven without driver attached 1784a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 1785a525a3ddSMing Lei * all resources are released. 1786a525a3ddSMing Lei * 1787a525a3ddSMing Lei * Drivers still can add resources into device after device 1788a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 1789a525a3ddSMing Lei * possible memory leak. 1790a525a3ddSMing Lei */ 1791a525a3ddSMing Lei devres_release_all(dev); 1792a525a3ddSMing Lei 17931da177e4SLinus Torvalds if (dev->release) 17941da177e4SLinus Torvalds dev->release(dev); 1795f9f852dfSKay Sievers else if (dev->type && dev->type->release) 1796f9f852dfSKay Sievers dev->type->release(dev); 17972620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 17982620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 1799f810a5cfSArjan van de Ven else 18000c1bc6b8SMauro Carvalho Chehab 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", 18011e0b2cf9SKay Sievers dev_name(dev)); 1802fb069a5dSGreg Kroah-Hartman kfree(p); 18031da177e4SLinus Torvalds } 18041da177e4SLinus Torvalds 1805bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 1806bc451f20SEric W. Biederman { 1807b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1808bc451f20SEric W. Biederman const void *ns = NULL; 1809bc451f20SEric W. Biederman 1810bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 1811bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 1812bc451f20SEric W. Biederman 1813bc451f20SEric W. Biederman return ns; 1814bc451f20SEric W. Biederman } 1815bc451f20SEric W. Biederman 18169944e894SDmitry Torokhov static void device_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) 18179944e894SDmitry Torokhov { 18189944e894SDmitry Torokhov struct device *dev = kobj_to_dev(kobj); 18199944e894SDmitry Torokhov 18209944e894SDmitry Torokhov if (dev->class && dev->class->get_ownership) 18219944e894SDmitry Torokhov dev->class->get_ownership(dev, uid, gid); 18229944e894SDmitry Torokhov } 18239944e894SDmitry Torokhov 18248f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 18251da177e4SLinus Torvalds .release = device_release, 18261da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 1827bc451f20SEric W. Biederman .namespace = device_namespace, 18289944e894SDmitry Torokhov .get_ownership = device_get_ownership, 18291da177e4SLinus Torvalds }; 18301da177e4SLinus Torvalds 18311da177e4SLinus Torvalds 1832312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 18331da177e4SLinus Torvalds { 18341da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 18351da177e4SLinus Torvalds 18368f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 1837b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 18381da177e4SLinus Torvalds if (dev->bus) 18391da177e4SLinus Torvalds return 1; 184023681e47SGreg Kroah-Hartman if (dev->class) 184123681e47SGreg Kroah-Hartman return 1; 18421da177e4SLinus Torvalds } 18431da177e4SLinus Torvalds return 0; 18441da177e4SLinus Torvalds } 18451da177e4SLinus Torvalds 1846312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 18471da177e4SLinus Torvalds { 1848b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 18491da177e4SLinus Torvalds 185023681e47SGreg Kroah-Hartman if (dev->bus) 18511da177e4SLinus Torvalds return dev->bus->name; 185223681e47SGreg Kroah-Hartman if (dev->class) 185323681e47SGreg Kroah-Hartman return dev->class->name; 185423681e47SGreg Kroah-Hartman return NULL; 18551da177e4SLinus Torvalds } 18561da177e4SLinus Torvalds 18577eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 18587eff2e7aSKay Sievers struct kobj_uevent_env *env) 18591da177e4SLinus Torvalds { 1860b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 18611da177e4SLinus Torvalds int retval = 0; 18621da177e4SLinus Torvalds 18636fcf53acSKay Sievers /* add device node properties if present */ 186423681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 18656fcf53acSKay Sievers const char *tmp; 18666fcf53acSKay Sievers const char *name; 18672c9ede55SAl Viro umode_t mode = 0; 18684e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 18694e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 18706fcf53acSKay Sievers 18717eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 18727eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 18733c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 18746fcf53acSKay Sievers if (name) { 18756fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 1876e454cea2SKay Sievers if (mode) 1877e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 18784e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 18794e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 18804e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 18814e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 18823c2670e6SKay Sievers kfree(tmp); 18836fcf53acSKay Sievers } 188423681e47SGreg Kroah-Hartman } 188523681e47SGreg Kroah-Hartman 1886414264f9SKay Sievers if (dev->type && dev->type->name) 18877eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 1888414264f9SKay Sievers 1889239378f1SKay Sievers if (dev->driver) 18907eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 1891239378f1SKay Sievers 189207d57a32SGrant Likely /* Add common DT information about the device */ 189307d57a32SGrant Likely of_device_uevent(dev, env); 189407d57a32SGrant Likely 18951da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 18967eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 18977eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 1898f9f852dfSKay Sievers if (retval) 18997dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 19001e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 19011da177e4SLinus Torvalds } 19021da177e4SLinus Torvalds 19032620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 19047eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 19057eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 1906f9f852dfSKay Sievers if (retval) 19077dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 19081e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 19092b3a302aSHarvey Harrison __func__, retval); 19102620efefSGreg Kroah-Hartman } 1911f9f852dfSKay Sievers 1912eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 19137eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 19147eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 1915f9f852dfSKay Sievers if (retval) 19167dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 19171e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 19182b3a302aSHarvey Harrison __func__, retval); 19192620efefSGreg Kroah-Hartman } 19202620efefSGreg Kroah-Hartman 19211da177e4SLinus Torvalds return retval; 19221da177e4SLinus Torvalds } 19231da177e4SLinus Torvalds 19249cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 1925312c004dSKay Sievers .filter = dev_uevent_filter, 1926312c004dSKay Sievers .name = dev_uevent_name, 1927312c004dSKay Sievers .uevent = dev_uevent, 19281da177e4SLinus Torvalds }; 19291da177e4SLinus Torvalds 1930c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 193116574dccSKay Sievers char *buf) 193216574dccSKay Sievers { 193316574dccSKay Sievers struct kobject *top_kobj; 193416574dccSKay Sievers struct kset *kset; 19357eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 193616574dccSKay Sievers int i; 193716574dccSKay Sievers size_t count = 0; 193816574dccSKay Sievers int retval; 193916574dccSKay Sievers 194016574dccSKay Sievers /* search the kset, the device belongs to */ 194116574dccSKay Sievers top_kobj = &dev->kobj; 19425c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 194316574dccSKay Sievers top_kobj = top_kobj->parent; 194416574dccSKay Sievers if (!top_kobj->kset) 194516574dccSKay Sievers goto out; 19465c5daf65SKay Sievers 194716574dccSKay Sievers kset = top_kobj->kset; 194816574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 194916574dccSKay Sievers goto out; 195016574dccSKay Sievers 195116574dccSKay Sievers /* respect filter */ 195216574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 195316574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 195416574dccSKay Sievers goto out; 195516574dccSKay Sievers 19567eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 19577eff2e7aSKay Sievers if (!env) 1958c7308c81SGreg Kroah-Hartman return -ENOMEM; 1959c7308c81SGreg Kroah-Hartman 196016574dccSKay Sievers /* let the kset specific function add its keys */ 19617eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 196216574dccSKay Sievers if (retval) 196316574dccSKay Sievers goto out; 196416574dccSKay Sievers 196516574dccSKay Sievers /* copy keys to file */ 19667eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 19677eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 196816574dccSKay Sievers out: 19697eff2e7aSKay Sievers kfree(env); 197016574dccSKay Sievers return count; 197116574dccSKay Sievers } 197216574dccSKay Sievers 1973c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 1974a7fd6706SKay Sievers const char *buf, size_t count) 1975a7fd6706SKay Sievers { 1976df44b479SPeter Rajnoha int rc; 1977df44b479SPeter Rajnoha 1978df44b479SPeter Rajnoha rc = kobject_synth_uevent(&dev->kobj, buf, count); 1979df44b479SPeter Rajnoha 1980df44b479SPeter Rajnoha if (rc) { 1981f36776faSPeter Rajnoha dev_err(dev, "uevent: failed to send synthetic uevent\n"); 1982df44b479SPeter Rajnoha return rc; 1983df44b479SPeter Rajnoha } 198460a96a59SKay Sievers 1985a7fd6706SKay Sievers return count; 1986a7fd6706SKay Sievers } 1987c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 1988a7fd6706SKay Sievers 1989c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 19904f3549d7SRafael J. Wysocki char *buf) 19914f3549d7SRafael J. Wysocki { 19924f3549d7SRafael J. Wysocki bool val; 19934f3549d7SRafael J. Wysocki 19945e33bc41SRafael J. Wysocki device_lock(dev); 19954f3549d7SRafael J. Wysocki val = !dev->offline; 19965e33bc41SRafael J. Wysocki device_unlock(dev); 1997aa838896SJoe Perches return sysfs_emit(buf, "%u\n", val); 19984f3549d7SRafael J. Wysocki } 19994f3549d7SRafael J. Wysocki 2000c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 20014f3549d7SRafael J. Wysocki const char *buf, size_t count) 20024f3549d7SRafael J. Wysocki { 20034f3549d7SRafael J. Wysocki bool val; 20044f3549d7SRafael J. Wysocki int ret; 20054f3549d7SRafael J. Wysocki 20064f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 20074f3549d7SRafael J. Wysocki if (ret < 0) 20084f3549d7SRafael J. Wysocki return ret; 20094f3549d7SRafael J. Wysocki 20105e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 20115e33bc41SRafael J. Wysocki if (ret) 20125e33bc41SRafael J. Wysocki return ret; 20135e33bc41SRafael J. Wysocki 20144f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 20154f3549d7SRafael J. Wysocki unlock_device_hotplug(); 20164f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 20174f3549d7SRafael J. Wysocki } 2018c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 20194f3549d7SRafael J. Wysocki 2020fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 2021621a1672SDmitry Torokhov { 20223e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 2023621a1672SDmitry Torokhov } 2024a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_add_groups); 2025621a1672SDmitry Torokhov 2026fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 2027a4dbd674SDavid Brownell const struct attribute_group **groups) 2028621a1672SDmitry Torokhov { 20293e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 2030621a1672SDmitry Torokhov } 2031a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_remove_groups); 2032de0ff00dSGreg Kroah-Hartman 203357b8ff07SDmitry Torokhov union device_attr_group_devres { 203457b8ff07SDmitry Torokhov const struct attribute_group *group; 203557b8ff07SDmitry Torokhov const struct attribute_group **groups; 203657b8ff07SDmitry Torokhov }; 203757b8ff07SDmitry Torokhov 203857b8ff07SDmitry Torokhov static int devm_attr_group_match(struct device *dev, void *res, void *data) 203957b8ff07SDmitry Torokhov { 204057b8ff07SDmitry Torokhov return ((union device_attr_group_devres *)res)->group == data; 204157b8ff07SDmitry Torokhov } 204257b8ff07SDmitry Torokhov 204357b8ff07SDmitry Torokhov static void devm_attr_group_remove(struct device *dev, void *res) 204457b8ff07SDmitry Torokhov { 204557b8ff07SDmitry Torokhov union device_attr_group_devres *devres = res; 204657b8ff07SDmitry Torokhov const struct attribute_group *group = devres->group; 204757b8ff07SDmitry Torokhov 204857b8ff07SDmitry Torokhov dev_dbg(dev, "%s: removing group %p\n", __func__, group); 204957b8ff07SDmitry Torokhov sysfs_remove_group(&dev->kobj, group); 205057b8ff07SDmitry Torokhov } 205157b8ff07SDmitry Torokhov 205257b8ff07SDmitry Torokhov static void devm_attr_groups_remove(struct device *dev, void *res) 205357b8ff07SDmitry Torokhov { 205457b8ff07SDmitry Torokhov union device_attr_group_devres *devres = res; 205557b8ff07SDmitry Torokhov const struct attribute_group **groups = devres->groups; 205657b8ff07SDmitry Torokhov 205757b8ff07SDmitry Torokhov dev_dbg(dev, "%s: removing groups %p\n", __func__, groups); 205857b8ff07SDmitry Torokhov sysfs_remove_groups(&dev->kobj, groups); 205957b8ff07SDmitry Torokhov } 206057b8ff07SDmitry Torokhov 206157b8ff07SDmitry Torokhov /** 206257b8ff07SDmitry Torokhov * devm_device_add_group - given a device, create a managed attribute group 206357b8ff07SDmitry Torokhov * @dev: The device to create the group for 206457b8ff07SDmitry Torokhov * @grp: The attribute group to create 206557b8ff07SDmitry Torokhov * 206657b8ff07SDmitry Torokhov * This function creates a group for the first time. It will explicitly 206757b8ff07SDmitry Torokhov * warn and error if any of the attribute files being created already exist. 206857b8ff07SDmitry Torokhov * 206957b8ff07SDmitry Torokhov * Returns 0 on success or error code on failure. 207057b8ff07SDmitry Torokhov */ 207157b8ff07SDmitry Torokhov int devm_device_add_group(struct device *dev, const struct attribute_group *grp) 207257b8ff07SDmitry Torokhov { 207357b8ff07SDmitry Torokhov union device_attr_group_devres *devres; 207457b8ff07SDmitry Torokhov int error; 207557b8ff07SDmitry Torokhov 207657b8ff07SDmitry Torokhov devres = devres_alloc(devm_attr_group_remove, 207757b8ff07SDmitry Torokhov sizeof(*devres), GFP_KERNEL); 207857b8ff07SDmitry Torokhov if (!devres) 207957b8ff07SDmitry Torokhov return -ENOMEM; 208057b8ff07SDmitry Torokhov 208157b8ff07SDmitry Torokhov error = sysfs_create_group(&dev->kobj, grp); 208257b8ff07SDmitry Torokhov if (error) { 208357b8ff07SDmitry Torokhov devres_free(devres); 208457b8ff07SDmitry Torokhov return error; 208557b8ff07SDmitry Torokhov } 208657b8ff07SDmitry Torokhov 208757b8ff07SDmitry Torokhov devres->group = grp; 208857b8ff07SDmitry Torokhov devres_add(dev, devres); 208957b8ff07SDmitry Torokhov return 0; 209057b8ff07SDmitry Torokhov } 209157b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_group); 209257b8ff07SDmitry Torokhov 209357b8ff07SDmitry Torokhov /** 209457b8ff07SDmitry Torokhov * devm_device_remove_group: remove a managed group from a device 209557b8ff07SDmitry Torokhov * @dev: device to remove the group from 209657b8ff07SDmitry Torokhov * @grp: group to remove 209757b8ff07SDmitry Torokhov * 209857b8ff07SDmitry Torokhov * This function removes a group of attributes from a device. The attributes 209957b8ff07SDmitry Torokhov * previously have to have been created for this group, otherwise it will fail. 210057b8ff07SDmitry Torokhov */ 210157b8ff07SDmitry Torokhov void devm_device_remove_group(struct device *dev, 210257b8ff07SDmitry Torokhov const struct attribute_group *grp) 210357b8ff07SDmitry Torokhov { 210457b8ff07SDmitry Torokhov WARN_ON(devres_release(dev, devm_attr_group_remove, 210557b8ff07SDmitry Torokhov devm_attr_group_match, 210657b8ff07SDmitry Torokhov /* cast away const */ (void *)grp)); 210757b8ff07SDmitry Torokhov } 210857b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_group); 210957b8ff07SDmitry Torokhov 211057b8ff07SDmitry Torokhov /** 211157b8ff07SDmitry Torokhov * devm_device_add_groups - create a bunch of managed attribute groups 211257b8ff07SDmitry Torokhov * @dev: The device to create the group for 211357b8ff07SDmitry Torokhov * @groups: The attribute groups to create, NULL terminated 211457b8ff07SDmitry Torokhov * 211557b8ff07SDmitry Torokhov * This function creates a bunch of managed attribute groups. If an error 211657b8ff07SDmitry Torokhov * occurs when creating a group, all previously created groups will be 211757b8ff07SDmitry Torokhov * removed, unwinding everything back to the original state when this 211857b8ff07SDmitry Torokhov * function was called. It will explicitly warn and error if any of the 211957b8ff07SDmitry Torokhov * attribute files being created already exist. 212057b8ff07SDmitry Torokhov * 212157b8ff07SDmitry Torokhov * Returns 0 on success or error code from sysfs_create_group on failure. 212257b8ff07SDmitry Torokhov */ 212357b8ff07SDmitry Torokhov int devm_device_add_groups(struct device *dev, 212457b8ff07SDmitry Torokhov const struct attribute_group **groups) 212557b8ff07SDmitry Torokhov { 212657b8ff07SDmitry Torokhov union device_attr_group_devres *devres; 212757b8ff07SDmitry Torokhov int error; 212857b8ff07SDmitry Torokhov 212957b8ff07SDmitry Torokhov devres = devres_alloc(devm_attr_groups_remove, 213057b8ff07SDmitry Torokhov sizeof(*devres), GFP_KERNEL); 213157b8ff07SDmitry Torokhov if (!devres) 213257b8ff07SDmitry Torokhov return -ENOMEM; 213357b8ff07SDmitry Torokhov 213457b8ff07SDmitry Torokhov error = sysfs_create_groups(&dev->kobj, groups); 213557b8ff07SDmitry Torokhov if (error) { 213657b8ff07SDmitry Torokhov devres_free(devres); 213757b8ff07SDmitry Torokhov return error; 213857b8ff07SDmitry Torokhov } 213957b8ff07SDmitry Torokhov 214057b8ff07SDmitry Torokhov devres->groups = groups; 214157b8ff07SDmitry Torokhov devres_add(dev, devres); 214257b8ff07SDmitry Torokhov return 0; 214357b8ff07SDmitry Torokhov } 214457b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_groups); 214557b8ff07SDmitry Torokhov 214657b8ff07SDmitry Torokhov /** 214757b8ff07SDmitry Torokhov * devm_device_remove_groups - remove a list of managed groups 214857b8ff07SDmitry Torokhov * 214957b8ff07SDmitry Torokhov * @dev: The device for the groups to be removed from 215057b8ff07SDmitry Torokhov * @groups: NULL terminated list of groups to be removed 215157b8ff07SDmitry Torokhov * 215257b8ff07SDmitry Torokhov * If groups is not NULL, remove the specified groups from the device. 215357b8ff07SDmitry Torokhov */ 215457b8ff07SDmitry Torokhov void devm_device_remove_groups(struct device *dev, 215557b8ff07SDmitry Torokhov const struct attribute_group **groups) 215657b8ff07SDmitry Torokhov { 215757b8ff07SDmitry Torokhov WARN_ON(devres_release(dev, devm_attr_groups_remove, 215857b8ff07SDmitry Torokhov devm_attr_group_match, 215957b8ff07SDmitry Torokhov /* cast away const */ (void *)groups)); 216057b8ff07SDmitry Torokhov } 216157b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_groups); 21621da177e4SLinus Torvalds 21632620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 21642620efefSGreg Kroah-Hartman { 21652620efefSGreg Kroah-Hartman struct class *class = dev->class; 2166aed65af1SStephen Hemminger const struct device_type *type = dev->type; 2167621a1672SDmitry Torokhov int error; 21682620efefSGreg Kroah-Hartman 2169621a1672SDmitry Torokhov if (class) { 2170d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 21712620efefSGreg Kroah-Hartman if (error) 2172621a1672SDmitry Torokhov return error; 2173f9f852dfSKay Sievers } 2174f9f852dfSKay Sievers 2175621a1672SDmitry Torokhov if (type) { 2176621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 2177f9f852dfSKay Sievers if (error) 2178a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 2179f9f852dfSKay Sievers } 2180621a1672SDmitry Torokhov 2181621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 2182f9f852dfSKay Sievers if (error) 2183621a1672SDmitry Torokhov goto err_remove_type_groups; 2184621a1672SDmitry Torokhov 21854f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 2186c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 21874f3549d7SRafael J. Wysocki if (error) 2188ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 21894f3549d7SRafael J. Wysocki } 21904f3549d7SRafael J. Wysocki 2191da6d6475SSaravana Kannan if (fw_devlink_flags && !fw_devlink_is_permissive()) { 2192da6d6475SSaravana Kannan error = device_create_file(dev, &dev_attr_waiting_for_supplier); 2193da6d6475SSaravana Kannan if (error) 2194da6d6475SSaravana Kannan goto err_remove_dev_online; 2195da6d6475SSaravana Kannan } 2196da6d6475SSaravana Kannan 2197621a1672SDmitry Torokhov return 0; 2198621a1672SDmitry Torokhov 2199da6d6475SSaravana Kannan err_remove_dev_online: 2200da6d6475SSaravana Kannan device_remove_file(dev, &dev_attr_online); 2201ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 2202ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 2203621a1672SDmitry Torokhov err_remove_type_groups: 2204621a1672SDmitry Torokhov if (type) 2205621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 2206d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 2207d05a6f96SGreg Kroah-Hartman if (class) 2208d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 2209f9f852dfSKay Sievers 22102620efefSGreg Kroah-Hartman return error; 22112620efefSGreg Kroah-Hartman } 22122620efefSGreg Kroah-Hartman 22132620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 22142620efefSGreg Kroah-Hartman { 22152620efefSGreg Kroah-Hartman struct class *class = dev->class; 2216aed65af1SStephen Hemminger const struct device_type *type = dev->type; 22172620efefSGreg Kroah-Hartman 2218da6d6475SSaravana Kannan device_remove_file(dev, &dev_attr_waiting_for_supplier); 2219c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 2220621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 2221f9f852dfSKay Sievers 2222621a1672SDmitry Torokhov if (type) 2223621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 2224621a1672SDmitry Torokhov 2225a6b01dedSGreg Kroah-Hartman if (class) 2226d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 2227c97415a7SStefan Achatz } 22282620efefSGreg Kroah-Hartman 2229c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 223023681e47SGreg Kroah-Hartman char *buf) 223123681e47SGreg Kroah-Hartman { 223223681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 223323681e47SGreg Kroah-Hartman } 2234c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 2235ad6a1e1cSTejun Heo 2236ca22e56dSKay Sievers /* /sys/devices/ */ 2237881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 22381da177e4SLinus Torvalds 22391da177e4SLinus Torvalds /** 224052cdbdd4SGrygorii Strashko * devices_kset_move_before - Move device in the devices_kset's list. 224152cdbdd4SGrygorii Strashko * @deva: Device to move. 224252cdbdd4SGrygorii Strashko * @devb: Device @deva should come before. 224352cdbdd4SGrygorii Strashko */ 224452cdbdd4SGrygorii Strashko static void devices_kset_move_before(struct device *deva, struct device *devb) 224552cdbdd4SGrygorii Strashko { 224652cdbdd4SGrygorii Strashko if (!devices_kset) 224752cdbdd4SGrygorii Strashko return; 224852cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s before %s\n", 224952cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 225052cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 225152cdbdd4SGrygorii Strashko list_move_tail(&deva->kobj.entry, &devb->kobj.entry); 225252cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 225352cdbdd4SGrygorii Strashko } 225452cdbdd4SGrygorii Strashko 225552cdbdd4SGrygorii Strashko /** 225652cdbdd4SGrygorii Strashko * devices_kset_move_after - Move device in the devices_kset's list. 225752cdbdd4SGrygorii Strashko * @deva: Device to move 225852cdbdd4SGrygorii Strashko * @devb: Device @deva should come after. 225952cdbdd4SGrygorii Strashko */ 226052cdbdd4SGrygorii Strashko static void devices_kset_move_after(struct device *deva, struct device *devb) 226152cdbdd4SGrygorii Strashko { 226252cdbdd4SGrygorii Strashko if (!devices_kset) 226352cdbdd4SGrygorii Strashko return; 226452cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s after %s\n", 226552cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 226652cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 226752cdbdd4SGrygorii Strashko list_move(&deva->kobj.entry, &devb->kobj.entry); 226852cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 226952cdbdd4SGrygorii Strashko } 227052cdbdd4SGrygorii Strashko 227152cdbdd4SGrygorii Strashko /** 227252cdbdd4SGrygorii Strashko * devices_kset_move_last - move the device to the end of devices_kset's list. 227352cdbdd4SGrygorii Strashko * @dev: device to move 227452cdbdd4SGrygorii Strashko */ 227552cdbdd4SGrygorii Strashko void devices_kset_move_last(struct device *dev) 227652cdbdd4SGrygorii Strashko { 227752cdbdd4SGrygorii Strashko if (!devices_kset) 227852cdbdd4SGrygorii Strashko return; 227952cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); 228052cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 228152cdbdd4SGrygorii Strashko list_move_tail(&dev->kobj.entry, &devices_kset->list); 228252cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 228352cdbdd4SGrygorii Strashko } 228452cdbdd4SGrygorii Strashko 228552cdbdd4SGrygorii Strashko /** 22861da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 22871da177e4SLinus Torvalds * @dev: device. 22881da177e4SLinus Torvalds * @attr: device attribute descriptor. 22891da177e4SLinus Torvalds */ 229026579ab7SPhil Carmody int device_create_file(struct device *dev, 229126579ab7SPhil Carmody const struct device_attribute *attr) 22921da177e4SLinus Torvalds { 22931da177e4SLinus Torvalds int error = 0; 22948f46baaaSFelipe Balbi 22958f46baaaSFelipe Balbi if (dev) { 22968f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 229797521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 229897521978Sdyoung@redhat.com attr->attr.name); 22998f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 230097521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 230197521978Sdyoung@redhat.com attr->attr.name); 23021da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 23038f46baaaSFelipe Balbi } 23048f46baaaSFelipe Balbi 23051da177e4SLinus Torvalds return error; 23061da177e4SLinus Torvalds } 230786df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 23081da177e4SLinus Torvalds 23091da177e4SLinus Torvalds /** 23101da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 23111da177e4SLinus Torvalds * @dev: device. 23121da177e4SLinus Torvalds * @attr: device attribute descriptor. 23131da177e4SLinus Torvalds */ 231426579ab7SPhil Carmody void device_remove_file(struct device *dev, 231526579ab7SPhil Carmody const struct device_attribute *attr) 23161da177e4SLinus Torvalds { 23170c98b19fSCornelia Huck if (dev) 23181da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 23191da177e4SLinus Torvalds } 232086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 23211da177e4SLinus Torvalds 23222589f188SGreg Kroah-Hartman /** 23236b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 23246b0afc2aSTejun Heo * @dev: device. 23256b0afc2aSTejun Heo * @attr: device attribute descriptor. 23266b0afc2aSTejun Heo * 23276b0afc2aSTejun Heo * See kernfs_remove_self() for details. 23286b0afc2aSTejun Heo */ 23296b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 23306b0afc2aSTejun Heo const struct device_attribute *attr) 23316b0afc2aSTejun Heo { 23326b0afc2aSTejun Heo if (dev) 23336b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 23346b0afc2aSTejun Heo else 23356b0afc2aSTejun Heo return false; 23366b0afc2aSTejun Heo } 23376b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 23386b0afc2aSTejun Heo 23396b0afc2aSTejun Heo /** 23402589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 23412589f188SGreg Kroah-Hartman * @dev: device. 23422589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 23432589f188SGreg Kroah-Hartman */ 234466ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 234566ecb92bSPhil Carmody const struct bin_attribute *attr) 23462589f188SGreg Kroah-Hartman { 23472589f188SGreg Kroah-Hartman int error = -EINVAL; 23482589f188SGreg Kroah-Hartman if (dev) 23492589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 23502589f188SGreg Kroah-Hartman return error; 23512589f188SGreg Kroah-Hartman } 23522589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 23532589f188SGreg Kroah-Hartman 23542589f188SGreg Kroah-Hartman /** 23552589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 23562589f188SGreg Kroah-Hartman * @dev: device. 23572589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 23582589f188SGreg Kroah-Hartman */ 235966ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 236066ecb92bSPhil Carmody const struct bin_attribute *attr) 23612589f188SGreg Kroah-Hartman { 23622589f188SGreg Kroah-Hartman if (dev) 23632589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 23642589f188SGreg Kroah-Hartman } 23652589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 23662589f188SGreg Kroah-Hartman 236734bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 236834bb61f9SJames Bottomley { 2369f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 2370f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 237134bb61f9SJames Bottomley 237234bb61f9SJames Bottomley get_device(dev); 237334bb61f9SJames Bottomley } 237434bb61f9SJames Bottomley 237534bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 237634bb61f9SJames Bottomley { 2377f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 2378f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 237934bb61f9SJames Bottomley 238034bb61f9SJames Bottomley put_device(dev); 238134bb61f9SJames Bottomley } 238234bb61f9SJames Bottomley 23831da177e4SLinus Torvalds /** 23841da177e4SLinus Torvalds * device_initialize - init device structure. 23851da177e4SLinus Torvalds * @dev: device. 23861da177e4SLinus Torvalds * 23875739411aSCornelia Huck * This prepares the device for use by other layers by initializing 23885739411aSCornelia Huck * its fields. 23891da177e4SLinus Torvalds * It is the first half of device_register(), if called by 23905739411aSCornelia Huck * that function, though it can also be called separately, so one 23915739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 23925739411aSCornelia Huck * may be used for reference counting of @dev after calling this 23935739411aSCornelia Huck * function. 23945739411aSCornelia Huck * 2395b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 2396b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 2397b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 2398b10d5efdSAlan Stern * @dev. 2399b10d5efdSAlan Stern * 24005739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 24015739411aSCornelia Huck * @dev directly once you have called this function. 24021da177e4SLinus Torvalds */ 24031da177e4SLinus Torvalds void device_initialize(struct device *dev) 24041da177e4SLinus Torvalds { 2405881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 2406f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 24071da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 24083142788bSThomas Gleixner mutex_init(&dev->mutex); 240987a30e1fSDan Williams #ifdef CONFIG_PROVE_LOCKING 241087a30e1fSDan Williams mutex_init(&dev->lockdep_mutex); 241187a30e1fSDan Williams #endif 24121704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 24139ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 24149ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 24153b98aeafSAlan Stern device_pm_init(dev); 241687348136SChristoph Hellwig set_dev_node(dev, -1); 24174a7cc831SJiang Liu #ifdef CONFIG_GENERIC_MSI_IRQ 24184a7cc831SJiang Liu INIT_LIST_HEAD(&dev->msi_list); 24194a7cc831SJiang Liu #endif 24209ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.consumers); 24219ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.suppliers); 2422e2ae9bccSSaravana Kannan INIT_LIST_HEAD(&dev->links.needs_suppliers); 2423ec7bd784SSaravana Kannan INIT_LIST_HEAD(&dev->links.defer_hook); 24249ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 24251da177e4SLinus Torvalds } 242686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 24271da177e4SLinus Torvalds 2428d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 2429f0ee61a6SGreg Kroah-Hartman { 2430f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 2431f0ee61a6SGreg Kroah-Hartman 2432f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 24334ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 2434881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 2435f0ee61a6SGreg Kroah-Hartman 243686406245SKay Sievers return virtual_dir; 2437f0ee61a6SGreg Kroah-Hartman } 2438f0ee61a6SGreg Kroah-Hartman 2439bc451f20SEric W. Biederman struct class_dir { 2440bc451f20SEric W. Biederman struct kobject kobj; 2441bc451f20SEric W. Biederman struct class *class; 2442bc451f20SEric W. Biederman }; 2443bc451f20SEric W. Biederman 2444bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 2445bc451f20SEric W. Biederman 2446bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 2447bc451f20SEric W. Biederman { 2448bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 2449bc451f20SEric W. Biederman kfree(dir); 2450bc451f20SEric W. Biederman } 2451bc451f20SEric W. Biederman 2452bc451f20SEric W. Biederman static const 2453bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 2454bc451f20SEric W. Biederman { 2455bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 2456bc451f20SEric W. Biederman return dir->class->ns_type; 2457bc451f20SEric W. Biederman } 2458bc451f20SEric W. Biederman 2459bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 2460bc451f20SEric W. Biederman .release = class_dir_release, 2461bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 2462bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 2463bc451f20SEric W. Biederman }; 2464bc451f20SEric W. Biederman 2465bc451f20SEric W. Biederman static struct kobject * 2466bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 2467bc451f20SEric W. Biederman { 2468bc451f20SEric W. Biederman struct class_dir *dir; 2469bc451f20SEric W. Biederman int retval; 2470bc451f20SEric W. Biederman 2471bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 2472bc451f20SEric W. Biederman if (!dir) 247384d0c27dSTetsuo Handa return ERR_PTR(-ENOMEM); 2474bc451f20SEric W. Biederman 2475bc451f20SEric W. Biederman dir->class = class; 2476bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 2477bc451f20SEric W. Biederman 24786b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 2479bc451f20SEric W. Biederman 2480bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 2481bc451f20SEric W. Biederman if (retval < 0) { 2482bc451f20SEric W. Biederman kobject_put(&dir->kobj); 248384d0c27dSTetsuo Handa return ERR_PTR(retval); 2484bc451f20SEric W. Biederman } 2485bc451f20SEric W. Biederman return &dir->kobj; 2486bc451f20SEric W. Biederman } 2487bc451f20SEric W. Biederman 2488e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex); 2489bc451f20SEric W. Biederman 2490c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 2491c744aeaeSCornelia Huck struct device *parent) 249240fa5422SGreg Kroah-Hartman { 249386406245SKay Sievers if (dev->class) { 249486406245SKay Sievers struct kobject *kobj = NULL; 249586406245SKay Sievers struct kobject *parent_kobj; 249686406245SKay Sievers struct kobject *k; 249786406245SKay Sievers 2498ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 249939aba963SKay Sievers /* block disks show up in /sys/block */ 2500e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 250139aba963SKay Sievers if (parent && parent->class == &block_class) 250239aba963SKay Sievers return &parent->kobj; 25036b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 250439aba963SKay Sievers } 2505ead454feSRandy Dunlap #endif 2506e52eec13SAndi Kleen 250786406245SKay Sievers /* 250886406245SKay Sievers * If we have no parent, we live in "virtual". 25090f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 25100f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 251186406245SKay Sievers */ 251286406245SKay Sievers if (parent == NULL) 251386406245SKay Sievers parent_kobj = virtual_device_parent(dev); 251424b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 251586406245SKay Sievers return &parent->kobj; 251686406245SKay Sievers else 251786406245SKay Sievers parent_kobj = &parent->kobj; 251886406245SKay Sievers 251977d3d7c1STejun Heo mutex_lock(&gdp_mutex); 252077d3d7c1STejun Heo 252186406245SKay Sievers /* find our class-directory at the parent and reference it */ 25226b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 25236b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 252486406245SKay Sievers if (k->parent == parent_kobj) { 252586406245SKay Sievers kobj = kobject_get(k); 252686406245SKay Sievers break; 252786406245SKay Sievers } 25286b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 252977d3d7c1STejun Heo if (kobj) { 253077d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 253186406245SKay Sievers return kobj; 253277d3d7c1STejun Heo } 253386406245SKay Sievers 253486406245SKay Sievers /* or create a new class-directory at the parent device */ 2535bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 25360f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 253777d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 253843968d2fSGreg Kroah-Hartman return k; 253986406245SKay Sievers } 254086406245SKay Sievers 2541ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 2542ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 2543ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 2544ca22e56dSKay Sievers 254586406245SKay Sievers if (parent) 2546c744aeaeSCornelia Huck return &parent->kobj; 2547c744aeaeSCornelia Huck return NULL; 2548c744aeaeSCornelia Huck } 2549da231fd5SKay Sievers 2550cebf8fd1SMing Lei static inline bool live_in_glue_dir(struct kobject *kobj, 2551cebf8fd1SMing Lei struct device *dev) 2552cebf8fd1SMing Lei { 2553cebf8fd1SMing Lei if (!kobj || !dev->class || 2554cebf8fd1SMing Lei kobj->kset != &dev->class->p->glue_dirs) 2555cebf8fd1SMing Lei return false; 2556cebf8fd1SMing Lei return true; 2557cebf8fd1SMing Lei } 2558cebf8fd1SMing Lei 2559cebf8fd1SMing Lei static inline struct kobject *get_glue_dir(struct device *dev) 2560cebf8fd1SMing Lei { 2561cebf8fd1SMing Lei return dev->kobj.parent; 2562cebf8fd1SMing Lei } 2563cebf8fd1SMing Lei 2564cebf8fd1SMing Lei /* 2565cebf8fd1SMing Lei * make sure cleaning up dir as the last step, we need to make 2566cebf8fd1SMing Lei * sure .release handler of kobject is run with holding the 2567cebf8fd1SMing Lei * global lock 2568cebf8fd1SMing Lei */ 256963b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 2570da231fd5SKay Sievers { 2571ac43432cSMuchun Song unsigned int ref; 2572ac43432cSMuchun Song 25730f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 2574cebf8fd1SMing Lei if (!live_in_glue_dir(glue_dir, dev)) 2575da231fd5SKay Sievers return; 2576da231fd5SKay Sievers 2577e4a60d13SYijing Wang mutex_lock(&gdp_mutex); 2578ac43432cSMuchun Song /** 2579ac43432cSMuchun Song * There is a race condition between removing glue directory 2580ac43432cSMuchun Song * and adding a new device under the glue directory. 2581ac43432cSMuchun Song * 2582ac43432cSMuchun Song * CPU1: CPU2: 2583ac43432cSMuchun Song * 2584ac43432cSMuchun Song * device_add() 2585ac43432cSMuchun Song * get_device_parent() 2586ac43432cSMuchun Song * class_dir_create_and_add() 2587ac43432cSMuchun Song * kobject_add_internal() 2588ac43432cSMuchun Song * create_dir() // create glue_dir 2589ac43432cSMuchun Song * 2590ac43432cSMuchun Song * device_add() 2591ac43432cSMuchun Song * get_device_parent() 2592ac43432cSMuchun Song * kobject_get() // get glue_dir 2593ac43432cSMuchun Song * 2594ac43432cSMuchun Song * device_del() 2595ac43432cSMuchun Song * cleanup_glue_dir() 2596ac43432cSMuchun Song * kobject_del(glue_dir) 2597ac43432cSMuchun Song * 2598ac43432cSMuchun Song * kobject_add() 2599ac43432cSMuchun Song * kobject_add_internal() 2600ac43432cSMuchun Song * create_dir() // in glue_dir 2601ac43432cSMuchun Song * sysfs_create_dir_ns() 2602ac43432cSMuchun Song * kernfs_create_dir_ns(sd) 2603ac43432cSMuchun Song * 2604ac43432cSMuchun Song * sysfs_remove_dir() // glue_dir->sd=NULL 2605ac43432cSMuchun Song * sysfs_put() // free glue_dir->sd 2606ac43432cSMuchun Song * 2607ac43432cSMuchun Song * // sd is freed 2608ac43432cSMuchun Song * kernfs_new_node(sd) 2609ac43432cSMuchun Song * kernfs_get(glue_dir) 2610ac43432cSMuchun Song * kernfs_add_one() 2611ac43432cSMuchun Song * kernfs_put() 2612ac43432cSMuchun Song * 2613ac43432cSMuchun Song * Before CPU1 remove last child device under glue dir, if CPU2 add 2614ac43432cSMuchun Song * a new device under glue dir, the glue_dir kobject reference count 2615ac43432cSMuchun Song * will be increase to 2 in kobject_get(k). And CPU2 has been called 2616ac43432cSMuchun Song * kernfs_create_dir_ns(). Meanwhile, CPU1 call sysfs_remove_dir() 2617ac43432cSMuchun Song * and sysfs_put(). This result in glue_dir->sd is freed. 2618ac43432cSMuchun Song * 2619ac43432cSMuchun Song * Then the CPU2 will see a stale "empty" but still potentially used 2620ac43432cSMuchun Song * glue dir around in kernfs_new_node(). 2621ac43432cSMuchun Song * 2622ac43432cSMuchun Song * In order to avoid this happening, we also should make sure that 2623ac43432cSMuchun Song * kernfs_node for glue_dir is released in CPU1 only when refcount 2624ac43432cSMuchun Song * for glue_dir kobj is 1. 2625ac43432cSMuchun Song */ 2626ac43432cSMuchun Song ref = kref_read(&glue_dir->kref); 2627ac43432cSMuchun Song if (!kobject_has_children(glue_dir) && !--ref) 2628726e4109SBenjamin Herrenschmidt kobject_del(glue_dir); 26290f4dafc0SKay Sievers kobject_put(glue_dir); 2630e4a60d13SYijing Wang mutex_unlock(&gdp_mutex); 2631da231fd5SKay Sievers } 263263b6971aSCornelia Huck 26332ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 26342ee97cafSCornelia Huck { 26355590f319SBenjamin Herrenschmidt struct device_node *of_node = dev_of_node(dev); 26362ee97cafSCornelia Huck int error; 26372ee97cafSCornelia Huck 26385590f319SBenjamin Herrenschmidt if (of_node) { 26390c3c234bSRob Herring error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node"); 26405590f319SBenjamin Herrenschmidt if (error) 26415590f319SBenjamin Herrenschmidt dev_warn(dev, "Error %d creating of_node link\n",error); 26425590f319SBenjamin Herrenschmidt /* An error here doesn't warrant bringing down the device */ 26435590f319SBenjamin Herrenschmidt } 26445590f319SBenjamin Herrenschmidt 26452ee97cafSCornelia Huck if (!dev->class) 26462ee97cafSCornelia Huck return 0; 2647da231fd5SKay Sievers 26481fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 26496b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 26502ee97cafSCornelia Huck "subsystem"); 26512ee97cafSCornelia Huck if (error) 26525590f319SBenjamin Herrenschmidt goto out_devnode; 2653da231fd5SKay Sievers 26544e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 26554f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 26564f01a757SDmitry Torokhov "device"); 26574f01a757SDmitry Torokhov if (error) 265839aba963SKay Sievers goto out_subsys; 26592ee97cafSCornelia Huck } 266039aba963SKay Sievers 2661ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 266239aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 2663e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 266439aba963SKay Sievers return 0; 2665ead454feSRandy Dunlap #endif 266639aba963SKay Sievers 266739aba963SKay Sievers /* link in the class directory pointing to the device */ 26686b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 266939aba963SKay Sievers &dev->kobj, dev_name(dev)); 267039aba963SKay Sievers if (error) 267139aba963SKay Sievers goto out_device; 267239aba963SKay Sievers 26732ee97cafSCornelia Huck return 0; 26742ee97cafSCornelia Huck 267539aba963SKay Sievers out_device: 267639aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 2677da231fd5SKay Sievers 26782ee97cafSCornelia Huck out_subsys: 26792ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 26805590f319SBenjamin Herrenschmidt out_devnode: 26815590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 26822ee97cafSCornelia Huck return error; 26832ee97cafSCornelia Huck } 26842ee97cafSCornelia Huck 26852ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 26862ee97cafSCornelia Huck { 26875590f319SBenjamin Herrenschmidt if (dev_of_node(dev)) 26885590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 26895590f319SBenjamin Herrenschmidt 26902ee97cafSCornelia Huck if (!dev->class) 26912ee97cafSCornelia Huck return; 2692da231fd5SKay Sievers 26934e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 2694da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 26952ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 2696ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 2697e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 269839aba963SKay Sievers return; 2699ead454feSRandy Dunlap #endif 27006b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 27012ee97cafSCornelia Huck } 27022ee97cafSCornelia Huck 27031da177e4SLinus Torvalds /** 2704413c239fSStephen Rothwell * dev_set_name - set a device name 2705413c239fSStephen Rothwell * @dev: device 270646232366SRandy Dunlap * @fmt: format string for the device's name 2707413c239fSStephen Rothwell */ 2708413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 2709413c239fSStephen Rothwell { 2710413c239fSStephen Rothwell va_list vargs; 27111fa5ae85SKay Sievers int err; 2712413c239fSStephen Rothwell 2713413c239fSStephen Rothwell va_start(vargs, fmt); 27141fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 2715413c239fSStephen Rothwell va_end(vargs); 27161fa5ae85SKay Sievers return err; 2717413c239fSStephen Rothwell } 2718413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 2719413c239fSStephen Rothwell 2720413c239fSStephen Rothwell /** 2721e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 2722e105b8bfSDan Williams * @dev: device 2723e105b8bfSDan Williams * 2724e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 2725e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 2726e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 2727e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 27280d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 27290d4e293cSPeter Korsgaard * the link. 2730e105b8bfSDan Williams */ 2731e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 2732e105b8bfSDan Williams { 2733e105b8bfSDan Williams struct kobject *kobj; 2734e105b8bfSDan Williams 2735e105b8bfSDan Williams if (dev->class) 2736e105b8bfSDan Williams kobj = dev->class->dev_kobj; 2737e105b8bfSDan Williams else 2738e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 2739e105b8bfSDan Williams 2740e105b8bfSDan Williams return kobj; 2741e105b8bfSDan Williams } 2742e105b8bfSDan Williams 2743e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 2744e105b8bfSDan Williams { 2745e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 2746e105b8bfSDan Williams int error = 0; 2747e105b8bfSDan Williams char devt_str[15]; 2748e105b8bfSDan Williams 2749e105b8bfSDan Williams if (kobj) { 2750e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 2751e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 2752e105b8bfSDan Williams } 2753e105b8bfSDan Williams 2754e105b8bfSDan Williams return error; 2755e105b8bfSDan Williams } 2756e105b8bfSDan Williams 2757e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 2758e105b8bfSDan Williams { 2759e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 2760e105b8bfSDan Williams char devt_str[15]; 2761e105b8bfSDan Williams 2762e105b8bfSDan Williams if (kobj) { 2763e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 2764e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 2765e105b8bfSDan Williams } 2766e105b8bfSDan Williams } 2767e105b8bfSDan Williams 276846d3a037SShaokun Zhang static int device_private_init(struct device *dev) 2769b4028437SGreg Kroah-Hartman { 2770b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 2771b4028437SGreg Kroah-Hartman if (!dev->p) 2772b4028437SGreg Kroah-Hartman return -ENOMEM; 2773b4028437SGreg Kroah-Hartman dev->p->device = dev; 2774b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 2775b4028437SGreg Kroah-Hartman klist_children_put); 2776ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 2777b4028437SGreg Kroah-Hartman return 0; 2778b4028437SGreg Kroah-Hartman } 2779b4028437SGreg Kroah-Hartman 2780e105b8bfSDan Williams /** 27811da177e4SLinus Torvalds * device_add - add device to device hierarchy. 27821da177e4SLinus Torvalds * @dev: device. 27831da177e4SLinus Torvalds * 27841da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 27851da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 27861da177e4SLinus Torvalds * 27875739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 27881da177e4SLinus Torvalds * to the global and sibling lists for the device, then 27891da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 27905739411aSCornelia Huck * 2791b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 2792b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 2793b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 2794b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 2795b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 2796b10d5efdSAlan Stern * and register a fresh new struct device instead. 2797b10d5efdSAlan Stern * 27985739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 27995739411aSCornelia Huck * if it returned an error! Always use put_device() to give up your 28005739411aSCornelia Huck * reference instead. 2801affada72SBorislav Petkov * 2802affada72SBorislav Petkov * Rule of thumb is: if device_add() succeeds, you should call 2803affada72SBorislav Petkov * device_del() when you want to get rid of it. If device_add() has 2804affada72SBorislav Petkov * *not* succeeded, use *only* put_device() to drop the reference 2805affada72SBorislav Petkov * count. 28061da177e4SLinus Torvalds */ 28071da177e4SLinus Torvalds int device_add(struct device *dev) 28081da177e4SLinus Torvalds { 280935dbf4efSViresh Kumar struct device *parent; 2810ca22e56dSKay Sievers struct kobject *kobj; 2811c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 28125f5377eaSSaravana Kannan int error = -EINVAL; 2813cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 2814775b64d2SRafael J. Wysocki 28151da177e4SLinus Torvalds dev = get_device(dev); 2816c906a48aSGreg Kroah-Hartman if (!dev) 2817c906a48aSGreg Kroah-Hartman goto done; 2818c906a48aSGreg Kroah-Hartman 2819fb069a5dSGreg Kroah-Hartman if (!dev->p) { 2820b4028437SGreg Kroah-Hartman error = device_private_init(dev); 2821b4028437SGreg Kroah-Hartman if (error) 2822fb069a5dSGreg Kroah-Hartman goto done; 2823fb069a5dSGreg Kroah-Hartman } 2824fb069a5dSGreg Kroah-Hartman 28251fa5ae85SKay Sievers /* 28261fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 28271fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 28281fa5ae85SKay Sievers * the name, and force the use of dev_name() 28291fa5ae85SKay Sievers */ 28301fa5ae85SKay Sievers if (dev->init_name) { 2831acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 28321fa5ae85SKay Sievers dev->init_name = NULL; 28331fa5ae85SKay Sievers } 2834c906a48aSGreg Kroah-Hartman 2835ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 2836ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 2837ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 2838ca22e56dSKay Sievers 2839e6309e75SThomas Gleixner if (!dev_name(dev)) { 2840e6309e75SThomas Gleixner error = -EINVAL; 28415c8563d7SKay Sievers goto name_error; 2842e6309e75SThomas Gleixner } 28431da177e4SLinus Torvalds 28441e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 2845c205ef48SGreg Kroah-Hartman 28461da177e4SLinus Torvalds parent = get_device(dev->parent); 2847ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 284884d0c27dSTetsuo Handa if (IS_ERR(kobj)) { 284984d0c27dSTetsuo Handa error = PTR_ERR(kobj); 285084d0c27dSTetsuo Handa goto parent_error; 285184d0c27dSTetsuo Handa } 2852ca22e56dSKay Sievers if (kobj) 2853ca22e56dSKay Sievers dev->kobj.parent = kobj; 28541da177e4SLinus Torvalds 28550d358f22SYinghai Lu /* use parent numa_node */ 285656f2de81SZhen Lei if (parent && (dev_to_node(dev) == NUMA_NO_NODE)) 28570d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 28580d358f22SYinghai Lu 28591da177e4SLinus Torvalds /* first, register with generic layer. */ 28608a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 28618a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 2862cebf8fd1SMing Lei if (error) { 2863cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 28641da177e4SLinus Torvalds goto Error; 2865cebf8fd1SMing Lei } 2866a7fd6706SKay Sievers 286737022644SBrian Walsh /* notify platform of device entry */ 286807de0e86SHeikki Krogerus error = device_platform_notify(dev, KOBJ_ADD); 286907de0e86SHeikki Krogerus if (error) 287007de0e86SHeikki Krogerus goto platform_error; 287137022644SBrian Walsh 2872c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 2873a306eea4SCornelia Huck if (error) 2874a306eea4SCornelia Huck goto attrError; 2875a7fd6706SKay Sievers 28762ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 28772ee97cafSCornelia Huck if (error) 28782ee97cafSCornelia Huck goto SymlinkError; 2879dc0afa83SCornelia Huck error = device_add_attrs(dev); 2880dc0afa83SCornelia Huck if (error) 28812620efefSGreg Kroah-Hartman goto AttrsError; 2882dc0afa83SCornelia Huck error = bus_add_device(dev); 2883dc0afa83SCornelia Huck if (error) 28841da177e4SLinus Torvalds goto BusError; 28853b98aeafSAlan Stern error = dpm_sysfs_add(dev); 288657eee3d2SRafael J. Wysocki if (error) 28873b98aeafSAlan Stern goto DPMError; 28883b98aeafSAlan Stern device_pm_add(dev); 2889ec0676eeSAlan Stern 28900cd75047SSergey Klyaus if (MAJOR(dev->devt)) { 28910cd75047SSergey Klyaus error = device_create_file(dev, &dev_attr_dev); 28920cd75047SSergey Klyaus if (error) 28930cd75047SSergey Klyaus goto DevAttrError; 28940cd75047SSergey Klyaus 28950cd75047SSergey Klyaus error = device_create_sys_dev_entry(dev); 28960cd75047SSergey Klyaus if (error) 28970cd75047SSergey Klyaus goto SysEntryError; 28980cd75047SSergey Klyaus 28990cd75047SSergey Klyaus devtmpfs_create_node(dev); 29000cd75047SSergey Klyaus } 29010cd75047SSergey Klyaus 2902ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 2903268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 2904ec0676eeSAlan Stern */ 2905ec0676eeSAlan Stern if (dev->bus) 2906ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 2907ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 2908ec0676eeSAlan Stern 290953877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 2910372a67c0SSaravana Kannan 2911e2ae9bccSSaravana Kannan /* 2912e2ae9bccSSaravana Kannan * Check if any of the other devices (consumers) have been waiting for 2913e2ae9bccSSaravana Kannan * this device (supplier) to be added so that they can create a device 2914e2ae9bccSSaravana Kannan * link to it. 2915e2ae9bccSSaravana Kannan * 2916e2ae9bccSSaravana Kannan * This needs to happen after device_pm_add() because device_link_add() 2917e2ae9bccSSaravana Kannan * requires the supplier be registered before it's called. 2918e2ae9bccSSaravana Kannan * 29192cd38fd1SSaravana Kannan * But this also needs to happen before bus_probe_device() to make sure 2920e2ae9bccSSaravana Kannan * waiting consumers can link to it before the driver is bound to the 2921e2ae9bccSSaravana Kannan * device and the driver sync_state callback is called for this device. 2922e2ae9bccSSaravana Kannan */ 29232cd38fd1SSaravana Kannan if (dev->fwnode && !dev->fwnode->dev) { 29242cd38fd1SSaravana Kannan dev->fwnode->dev = dev; 29255f5377eaSSaravana Kannan fw_devlink_link_device(dev); 292603324507SSaravana Kannan } 2927e2ae9bccSSaravana Kannan 29282023c610SAlan Stern bus_probe_device(dev); 29291da177e4SLinus Torvalds if (parent) 2930f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2931f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 29321da177e4SLinus Torvalds 29335d9fd169SGreg Kroah-Hartman if (dev->class) { 2934ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 2935c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 2936570d0200SWei Yang klist_add_tail(&dev->p->knode_class, 29376b6e39a6SKay Sievers &dev->class->p->klist_devices); 2938c47ed219SGreg Kroah-Hartman 2939c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 2940184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 2941ca22e56dSKay Sievers &dev->class->p->interfaces, node) 2942c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 2943c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 2944ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 29455d9fd169SGreg Kroah-Hartman } 2946c906a48aSGreg Kroah-Hartman done: 29471da177e4SLinus Torvalds put_device(dev); 29481da177e4SLinus Torvalds return error; 29490cd75047SSergey Klyaus SysEntryError: 29500cd75047SSergey Klyaus if (MAJOR(dev->devt)) 29510cd75047SSergey Klyaus device_remove_file(dev, &dev_attr_dev); 29520cd75047SSergey Klyaus DevAttrError: 29530cd75047SSergey Klyaus device_pm_remove(dev); 29540cd75047SSergey Klyaus dpm_sysfs_remove(dev); 29553b98aeafSAlan Stern DPMError: 295657eee3d2SRafael J. Wysocki bus_remove_device(dev); 295757eee3d2SRafael J. Wysocki BusError: 29582620efefSGreg Kroah-Hartman device_remove_attrs(dev); 29592620efefSGreg Kroah-Hartman AttrsError: 29602ee97cafSCornelia Huck device_remove_class_symlinks(dev); 29612ee97cafSCornelia Huck SymlinkError: 2962c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 296323681e47SGreg Kroah-Hartman attrError: 296407de0e86SHeikki Krogerus device_platform_notify(dev, KOBJ_REMOVE); 296507de0e86SHeikki Krogerus platform_error: 2966312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 2967cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 29681da177e4SLinus Torvalds kobject_del(&dev->kobj); 29691da177e4SLinus Torvalds Error: 2970cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 297184d0c27dSTetsuo Handa parent_error: 29721da177e4SLinus Torvalds put_device(parent); 29735c8563d7SKay Sievers name_error: 29745c8563d7SKay Sievers kfree(dev->p); 29755c8563d7SKay Sievers dev->p = NULL; 2976c906a48aSGreg Kroah-Hartman goto done; 29771da177e4SLinus Torvalds } 297886df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 29791da177e4SLinus Torvalds 29801da177e4SLinus Torvalds /** 29811da177e4SLinus Torvalds * device_register - register a device with the system. 29821da177e4SLinus Torvalds * @dev: pointer to the device structure 29831da177e4SLinus Torvalds * 29841da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 29851da177e4SLinus Torvalds * and add it to the system. The two steps can be called 29861da177e4SLinus Torvalds * separately, but this is the easiest and most common. 29871da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 29881da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 29891da177e4SLinus Torvalds * before it is added to the hierarchy. 29905739411aSCornelia Huck * 2991b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 2992b10d5efdSAlan Stern * and device_add(). 2993b10d5efdSAlan Stern * 29945739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 29955739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 29965739411aSCornelia Huck * reference initialized in this function instead. 29971da177e4SLinus Torvalds */ 29981da177e4SLinus Torvalds int device_register(struct device *dev) 29991da177e4SLinus Torvalds { 30001da177e4SLinus Torvalds device_initialize(dev); 30011da177e4SLinus Torvalds return device_add(dev); 30021da177e4SLinus Torvalds } 300386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 30041da177e4SLinus Torvalds 30051da177e4SLinus Torvalds /** 30061da177e4SLinus Torvalds * get_device - increment reference count for device. 30071da177e4SLinus Torvalds * @dev: device. 30081da177e4SLinus Torvalds * 30091da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 30101da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 30111da177e4SLinus Torvalds * pointer passed in. 30121da177e4SLinus Torvalds */ 30131da177e4SLinus Torvalds struct device *get_device(struct device *dev) 30141da177e4SLinus Torvalds { 3015b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 30161da177e4SLinus Torvalds } 301786df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 30181da177e4SLinus Torvalds 30191da177e4SLinus Torvalds /** 30201da177e4SLinus Torvalds * put_device - decrement reference count. 30211da177e4SLinus Torvalds * @dev: device in question. 30221da177e4SLinus Torvalds */ 30231da177e4SLinus Torvalds void put_device(struct device *dev) 30241da177e4SLinus Torvalds { 3025edfaa7c3SKay Sievers /* might_sleep(); */ 30261da177e4SLinus Torvalds if (dev) 30271da177e4SLinus Torvalds kobject_put(&dev->kobj); 30281da177e4SLinus Torvalds } 302986df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 30301da177e4SLinus Torvalds 303100289cd8SDan Williams bool kill_device(struct device *dev) 303200289cd8SDan Williams { 303300289cd8SDan Williams /* 303400289cd8SDan Williams * Require the device lock and set the "dead" flag to guarantee that 303500289cd8SDan Williams * the update behavior is consistent with the other bitfields near 303600289cd8SDan Williams * it and that we cannot have an asynchronous probe routine trying 303700289cd8SDan Williams * to run while we are tearing out the bus/class/sysfs from 303800289cd8SDan Williams * underneath the device. 303900289cd8SDan Williams */ 304000289cd8SDan Williams lockdep_assert_held(&dev->mutex); 304100289cd8SDan Williams 304200289cd8SDan Williams if (dev->p->dead) 304300289cd8SDan Williams return false; 304400289cd8SDan Williams dev->p->dead = true; 304500289cd8SDan Williams return true; 304600289cd8SDan Williams } 304700289cd8SDan Williams EXPORT_SYMBOL_GPL(kill_device); 304800289cd8SDan Williams 30491da177e4SLinus Torvalds /** 30501da177e4SLinus Torvalds * device_del - delete device from system. 30511da177e4SLinus Torvalds * @dev: device. 30521da177e4SLinus Torvalds * 30531da177e4SLinus Torvalds * This is the first part of the device unregistration 30541da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 30551da177e4SLinus Torvalds * from here, has it removed from the other driver model 30561da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 30571da177e4SLinus Torvalds * from the kobject hierarchy. 30581da177e4SLinus Torvalds * 30591da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 30601da177e4SLinus Torvalds * also called manually. 30611da177e4SLinus Torvalds */ 30621da177e4SLinus Torvalds void device_del(struct device *dev) 30631da177e4SLinus Torvalds { 30641da177e4SLinus Torvalds struct device *parent = dev->parent; 3065cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 3066c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 3067b8530017SOliver Neukum unsigned int noio_flag; 30681da177e4SLinus Torvalds 30693451a495SAlexander Duyck device_lock(dev); 307000289cd8SDan Williams kill_device(dev); 30713451a495SAlexander Duyck device_unlock(dev); 30723451a495SAlexander Duyck 3073372a67c0SSaravana Kannan if (dev->fwnode && dev->fwnode->dev == dev) 3074372a67c0SSaravana Kannan dev->fwnode->dev = NULL; 3075372a67c0SSaravana Kannan 3076ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 3077ec0676eeSAlan Stern * before dpm_sysfs_remove(). 3078ec0676eeSAlan Stern */ 3079b8530017SOliver Neukum noio_flag = memalloc_noio_save(); 3080ec0676eeSAlan Stern if (dev->bus) 3081ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 3082ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 30839ed98953SRafael J. Wysocki 30843b98aeafSAlan Stern dpm_sysfs_remove(dev); 30851da177e4SLinus Torvalds if (parent) 3086f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 3087e105b8bfSDan Williams if (MAJOR(dev->devt)) { 30882b2af54aSKay Sievers devtmpfs_delete_node(dev); 3089e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 3090c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 3091e105b8bfSDan Williams } 3092b9d9c82bSKay Sievers if (dev->class) { 3093da231fd5SKay Sievers device_remove_class_symlinks(dev); 309499ef3ef8SKay Sievers 3095ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 3096c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 3097184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 3098ca22e56dSKay Sievers &dev->class->p->interfaces, node) 3099c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 3100c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 3101c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 3102570d0200SWei Yang klist_del(&dev->p->knode_class); 3103ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 3104b9d9c82bSKay Sievers } 3105c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 31062620efefSGreg Kroah-Hartman device_remove_attrs(dev); 310728953533SBenjamin Herrenschmidt bus_remove_device(dev); 31084b6d1f12SLongX Zhang device_pm_remove(dev); 3109d1c3414cSGrant Likely driver_deferred_probe_del(dev); 311007de0e86SHeikki Krogerus device_platform_notify(dev, KOBJ_REMOVE); 3111478573c9SLukas Wunner device_remove_properties(dev); 31122ec16150SJeffy Chen device_links_purge(dev); 31131da177e4SLinus Torvalds 3114599bad38SJoerg Roedel if (dev->bus) 3115599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 3116599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 3117312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 3118cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 31191da177e4SLinus Torvalds kobject_del(&dev->kobj); 3120cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 3121b8530017SOliver Neukum memalloc_noio_restore(noio_flag); 31221da177e4SLinus Torvalds put_device(parent); 31231da177e4SLinus Torvalds } 312486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 31251da177e4SLinus Torvalds 31261da177e4SLinus Torvalds /** 31271da177e4SLinus Torvalds * device_unregister - unregister device from system. 31281da177e4SLinus Torvalds * @dev: device going away. 31291da177e4SLinus Torvalds * 31301da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 31311da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 31321da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 31331da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 31341da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 31351da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 31361da177e4SLinus Torvalds */ 31371da177e4SLinus Torvalds void device_unregister(struct device *dev) 31381da177e4SLinus Torvalds { 31391e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 31401da177e4SLinus Torvalds device_del(dev); 31411da177e4SLinus Torvalds put_device(dev); 31421da177e4SLinus Torvalds } 314386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 31441da177e4SLinus Torvalds 31453d060aebSAndy Shevchenko static struct device *prev_device(struct klist_iter *i) 31463d060aebSAndy Shevchenko { 31473d060aebSAndy Shevchenko struct klist_node *n = klist_prev(i); 31483d060aebSAndy Shevchenko struct device *dev = NULL; 31493d060aebSAndy Shevchenko struct device_private *p; 31503d060aebSAndy Shevchenko 31513d060aebSAndy Shevchenko if (n) { 31523d060aebSAndy Shevchenko p = to_device_private_parent(n); 31533d060aebSAndy Shevchenko dev = p->device; 31543d060aebSAndy Shevchenko } 31553d060aebSAndy Shevchenko return dev; 31563d060aebSAndy Shevchenko } 31573d060aebSAndy Shevchenko 315836239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 315936239577Smochel@digitalimplant.org { 316036239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 3161f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 3162f791b8c8SGreg Kroah-Hartman struct device_private *p; 3163f791b8c8SGreg Kroah-Hartman 3164f791b8c8SGreg Kroah-Hartman if (n) { 3165f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 3166f791b8c8SGreg Kroah-Hartman dev = p->device; 3167f791b8c8SGreg Kroah-Hartman } 3168f791b8c8SGreg Kroah-Hartman return dev; 316936239577Smochel@digitalimplant.org } 317036239577Smochel@digitalimplant.org 31711da177e4SLinus Torvalds /** 3172e454cea2SKay Sievers * device_get_devnode - path of device node file 31736fcf53acSKay Sievers * @dev: device 3174e454cea2SKay Sievers * @mode: returned file access mode 31753c2670e6SKay Sievers * @uid: returned file owner 31763c2670e6SKay Sievers * @gid: returned file group 31776fcf53acSKay Sievers * @tmp: possibly allocated string 31786fcf53acSKay Sievers * 31796fcf53acSKay Sievers * Return the relative path of a possible device node. 31806fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 31816fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 31826fcf53acSKay Sievers * freed by the caller. 31836fcf53acSKay Sievers */ 3184e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 31854e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 31863c2670e6SKay Sievers const char **tmp) 31876fcf53acSKay Sievers { 31886fcf53acSKay Sievers char *s; 31896fcf53acSKay Sievers 31906fcf53acSKay Sievers *tmp = NULL; 31916fcf53acSKay Sievers 31926fcf53acSKay Sievers /* the device type may provide a specific name */ 3193e454cea2SKay Sievers if (dev->type && dev->type->devnode) 31943c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 31956fcf53acSKay Sievers if (*tmp) 31966fcf53acSKay Sievers return *tmp; 31976fcf53acSKay Sievers 31986fcf53acSKay Sievers /* the class may provide a specific name */ 3199e454cea2SKay Sievers if (dev->class && dev->class->devnode) 3200e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 32016fcf53acSKay Sievers if (*tmp) 32026fcf53acSKay Sievers return *tmp; 32036fcf53acSKay Sievers 32046fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 32056fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 32066fcf53acSKay Sievers return dev_name(dev); 32076fcf53acSKay Sievers 32086fcf53acSKay Sievers /* replace '!' in the name with '/' */ 3209a29fd614SRasmus Villemoes s = kstrdup(dev_name(dev), GFP_KERNEL); 3210a29fd614SRasmus Villemoes if (!s) 32116fcf53acSKay Sievers return NULL; 3212a29fd614SRasmus Villemoes strreplace(s, '!', '/'); 3213a29fd614SRasmus Villemoes return *tmp = s; 32146fcf53acSKay Sievers } 32156fcf53acSKay Sievers 32166fcf53acSKay Sievers /** 32171da177e4SLinus Torvalds * device_for_each_child - device child iterator. 3218c41455fbSRandy Dunlap * @parent: parent struct device. 32191da177e4SLinus Torvalds * @fn: function to be called for each device. 3220f8878dcbSRobert P. J. Day * @data: data for the callback. 32211da177e4SLinus Torvalds * 3222c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 32231da177e4SLinus Torvalds * passing it @data. 32241da177e4SLinus Torvalds * 32251da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 32261da177e4SLinus Torvalds * other than 0, we break out and return that value. 32271da177e4SLinus Torvalds */ 322836239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 32294a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 32301da177e4SLinus Torvalds { 323136239577Smochel@digitalimplant.org struct klist_iter i; 32321da177e4SLinus Torvalds struct device *child; 32331da177e4SLinus Torvalds int error = 0; 32341da177e4SLinus Torvalds 3235014c90dbSGreg Kroah-Hartman if (!parent->p) 3236014c90dbSGreg Kroah-Hartman return 0; 3237014c90dbSGreg Kroah-Hartman 3238f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 323993ead7c9SGimcuan Hui while (!error && (child = next_device(&i))) 324036239577Smochel@digitalimplant.org error = fn(child, data); 324136239577Smochel@digitalimplant.org klist_iter_exit(&i); 32421da177e4SLinus Torvalds return error; 32431da177e4SLinus Torvalds } 324486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 32451da177e4SLinus Torvalds 32465ab69981SCornelia Huck /** 32473d060aebSAndy Shevchenko * device_for_each_child_reverse - device child iterator in reversed order. 32483d060aebSAndy Shevchenko * @parent: parent struct device. 32493d060aebSAndy Shevchenko * @fn: function to be called for each device. 32503d060aebSAndy Shevchenko * @data: data for the callback. 32513d060aebSAndy Shevchenko * 32523d060aebSAndy Shevchenko * Iterate over @parent's child devices, and call @fn for each, 32533d060aebSAndy Shevchenko * passing it @data. 32543d060aebSAndy Shevchenko * 32553d060aebSAndy Shevchenko * We check the return of @fn each time. If it returns anything 32563d060aebSAndy Shevchenko * other than 0, we break out and return that value. 32573d060aebSAndy Shevchenko */ 32583d060aebSAndy Shevchenko int device_for_each_child_reverse(struct device *parent, void *data, 32593d060aebSAndy Shevchenko int (*fn)(struct device *dev, void *data)) 32603d060aebSAndy Shevchenko { 32613d060aebSAndy Shevchenko struct klist_iter i; 32623d060aebSAndy Shevchenko struct device *child; 32633d060aebSAndy Shevchenko int error = 0; 32643d060aebSAndy Shevchenko 32653d060aebSAndy Shevchenko if (!parent->p) 32663d060aebSAndy Shevchenko return 0; 32673d060aebSAndy Shevchenko 32683d060aebSAndy Shevchenko klist_iter_init(&parent->p->klist_children, &i); 32693d060aebSAndy Shevchenko while ((child = prev_device(&i)) && !error) 32703d060aebSAndy Shevchenko error = fn(child, data); 32713d060aebSAndy Shevchenko klist_iter_exit(&i); 32723d060aebSAndy Shevchenko return error; 32733d060aebSAndy Shevchenko } 32743d060aebSAndy Shevchenko EXPORT_SYMBOL_GPL(device_for_each_child_reverse); 32753d060aebSAndy Shevchenko 32763d060aebSAndy Shevchenko /** 32775ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 32785ab69981SCornelia Huck * @parent: parent struct device 32795ab69981SCornelia Huck * @match: Callback function to check device 3280f8878dcbSRobert P. J. Day * @data: Data to pass to match function 32815ab69981SCornelia Huck * 32825ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 32835ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 32845ab69981SCornelia Huck * determined by the @match callback. 32855ab69981SCornelia Huck * 32865ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 32875ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 32885ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 32895ab69981SCornelia Huck * and not iterate over any more devices. 3290a4e2400aSFederico Vaga * 3291a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 32925ab69981SCornelia Huck */ 32935ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 32944a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 32955ab69981SCornelia Huck { 32965ab69981SCornelia Huck struct klist_iter i; 32975ab69981SCornelia Huck struct device *child; 32985ab69981SCornelia Huck 32995ab69981SCornelia Huck if (!parent) 33005ab69981SCornelia Huck return NULL; 33015ab69981SCornelia Huck 3302f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 33035ab69981SCornelia Huck while ((child = next_device(&i))) 33045ab69981SCornelia Huck if (match(child, data) && get_device(child)) 33055ab69981SCornelia Huck break; 33065ab69981SCornelia Huck klist_iter_exit(&i); 33075ab69981SCornelia Huck return child; 33085ab69981SCornelia Huck } 330986df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 33105ab69981SCornelia Huck 3311dad9bb01SHeikki Krogerus /** 3312dad9bb01SHeikki Krogerus * device_find_child_by_name - device iterator for locating a child device. 3313dad9bb01SHeikki Krogerus * @parent: parent struct device 3314dad9bb01SHeikki Krogerus * @name: name of the child device 3315dad9bb01SHeikki Krogerus * 3316dad9bb01SHeikki Krogerus * This is similar to the device_find_child() function above, but it 3317dad9bb01SHeikki Krogerus * returns a reference to a device that has the name @name. 3318dad9bb01SHeikki Krogerus * 3319dad9bb01SHeikki Krogerus * NOTE: you will need to drop the reference with put_device() after use. 3320dad9bb01SHeikki Krogerus */ 3321dad9bb01SHeikki Krogerus struct device *device_find_child_by_name(struct device *parent, 3322dad9bb01SHeikki Krogerus const char *name) 3323dad9bb01SHeikki Krogerus { 3324dad9bb01SHeikki Krogerus struct klist_iter i; 3325dad9bb01SHeikki Krogerus struct device *child; 3326dad9bb01SHeikki Krogerus 3327dad9bb01SHeikki Krogerus if (!parent) 3328dad9bb01SHeikki Krogerus return NULL; 3329dad9bb01SHeikki Krogerus 3330dad9bb01SHeikki Krogerus klist_iter_init(&parent->p->klist_children, &i); 3331dad9bb01SHeikki Krogerus while ((child = next_device(&i))) 3332dad9bb01SHeikki Krogerus if (!strcmp(dev_name(child), name) && get_device(child)) 3333dad9bb01SHeikki Krogerus break; 3334dad9bb01SHeikki Krogerus klist_iter_exit(&i); 3335dad9bb01SHeikki Krogerus return child; 3336dad9bb01SHeikki Krogerus } 3337dad9bb01SHeikki Krogerus EXPORT_SYMBOL_GPL(device_find_child_by_name); 3338dad9bb01SHeikki Krogerus 33391da177e4SLinus Torvalds int __init devices_init(void) 33401da177e4SLinus Torvalds { 3341881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 3342881c6cfdSGreg Kroah-Hartman if (!devices_kset) 3343881c6cfdSGreg Kroah-Hartman return -ENOMEM; 3344e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 3345e105b8bfSDan Williams if (!dev_kobj) 3346e105b8bfSDan Williams goto dev_kobj_err; 3347e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 3348e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 3349e105b8bfSDan Williams goto block_kobj_err; 3350e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 3351e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 3352e105b8bfSDan Williams goto char_kobj_err; 3353e105b8bfSDan Williams 3354881c6cfdSGreg Kroah-Hartman return 0; 3355e105b8bfSDan Williams 3356e105b8bfSDan Williams char_kobj_err: 3357e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 3358e105b8bfSDan Williams block_kobj_err: 3359e105b8bfSDan Williams kobject_put(dev_kobj); 3360e105b8bfSDan Williams dev_kobj_err: 3361e105b8bfSDan Williams kset_unregister(devices_kset); 3362e105b8bfSDan Williams return -ENOMEM; 33631da177e4SLinus Torvalds } 33641da177e4SLinus Torvalds 33654f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 33664f3549d7SRafael J. Wysocki { 33674f3549d7SRafael J. Wysocki int ret; 33684f3549d7SRafael J. Wysocki 33694f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 33704f3549d7SRafael J. Wysocki if (ret) 33714f3549d7SRafael J. Wysocki return ret; 33724f3549d7SRafael J. Wysocki 33734f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 33744f3549d7SRafael J. Wysocki } 33754f3549d7SRafael J. Wysocki 33764f3549d7SRafael J. Wysocki /** 33774f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 33784f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 33794f3549d7SRafael J. Wysocki * 33804f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 33814f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 33824f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 33834f3549d7SRafael J. Wysocki * is executed. 33844f3549d7SRafael J. Wysocki * 33854f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 33864f3549d7SRafael J. Wysocki */ 33874f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 33884f3549d7SRafael J. Wysocki { 33894f3549d7SRafael J. Wysocki int ret; 33904f3549d7SRafael J. Wysocki 33914f3549d7SRafael J. Wysocki if (dev->offline_disabled) 33924f3549d7SRafael J. Wysocki return -EPERM; 33934f3549d7SRafael J. Wysocki 33944f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 33954f3549d7SRafael J. Wysocki if (ret) 33964f3549d7SRafael J. Wysocki return ret; 33974f3549d7SRafael J. Wysocki 33984f3549d7SRafael J. Wysocki device_lock(dev); 33994f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 34004f3549d7SRafael J. Wysocki if (dev->offline) { 34014f3549d7SRafael J. Wysocki ret = 1; 34024f3549d7SRafael J. Wysocki } else { 34034f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 34044f3549d7SRafael J. Wysocki if (!ret) { 34054f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 34064f3549d7SRafael J. Wysocki dev->offline = true; 34074f3549d7SRafael J. Wysocki } 34084f3549d7SRafael J. Wysocki } 34094f3549d7SRafael J. Wysocki } 34104f3549d7SRafael J. Wysocki device_unlock(dev); 34114f3549d7SRafael J. Wysocki 34124f3549d7SRafael J. Wysocki return ret; 34134f3549d7SRafael J. Wysocki } 34144f3549d7SRafael J. Wysocki 34154f3549d7SRafael J. Wysocki /** 34164f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 34174f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 34184f3549d7SRafael J. Wysocki * 34194f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 34204f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 34214f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 34224f3549d7SRafael J. Wysocki * 34234f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 34244f3549d7SRafael J. Wysocki */ 34254f3549d7SRafael J. Wysocki int device_online(struct device *dev) 34264f3549d7SRafael J. Wysocki { 34274f3549d7SRafael J. Wysocki int ret = 0; 34284f3549d7SRafael J. Wysocki 34294f3549d7SRafael J. Wysocki device_lock(dev); 34304f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 34314f3549d7SRafael J. Wysocki if (dev->offline) { 34324f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 34334f3549d7SRafael J. Wysocki if (!ret) { 34344f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 34354f3549d7SRafael J. Wysocki dev->offline = false; 34364f3549d7SRafael J. Wysocki } 34374f3549d7SRafael J. Wysocki } else { 34384f3549d7SRafael J. Wysocki ret = 1; 34394f3549d7SRafael J. Wysocki } 34404f3549d7SRafael J. Wysocki } 34414f3549d7SRafael J. Wysocki device_unlock(dev); 34424f3549d7SRafael J. Wysocki 34434f3549d7SRafael J. Wysocki return ret; 34444f3549d7SRafael J. Wysocki } 34454f3549d7SRafael J. Wysocki 34467f100d15SKarthigan Srinivasan struct root_device { 34470aa0dc41SMark McLoughlin struct device dev; 34480aa0dc41SMark McLoughlin struct module *owner; 34490aa0dc41SMark McLoughlin }; 34500aa0dc41SMark McLoughlin 345193058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 3452481e2079SFerenc Wagner { 3453481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 3454481e2079SFerenc Wagner } 34550aa0dc41SMark McLoughlin 34560aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 34570aa0dc41SMark McLoughlin { 34580aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 34590aa0dc41SMark McLoughlin } 34600aa0dc41SMark McLoughlin 34610aa0dc41SMark McLoughlin /** 34620aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 34630aa0dc41SMark McLoughlin * @name: root device name 34640aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 34650aa0dc41SMark McLoughlin * 34660aa0dc41SMark McLoughlin * This function allocates a root device and registers it 34670aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 34680aa0dc41SMark McLoughlin * device, use root_device_unregister(). 34690aa0dc41SMark McLoughlin * 34700aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 34710aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 34720aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 34730aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 34740aa0dc41SMark McLoughlin * 34750aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 34760aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 34770aa0dc41SMark McLoughlin * in sysfs. 34780aa0dc41SMark McLoughlin * 3479f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 3480f0eae0edSJani Nikula * 34810aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 34820aa0dc41SMark McLoughlin */ 34830aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 34840aa0dc41SMark McLoughlin { 34850aa0dc41SMark McLoughlin struct root_device *root; 34860aa0dc41SMark McLoughlin int err = -ENOMEM; 34870aa0dc41SMark McLoughlin 34880aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 34890aa0dc41SMark McLoughlin if (!root) 34900aa0dc41SMark McLoughlin return ERR_PTR(err); 34910aa0dc41SMark McLoughlin 3492acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 34930aa0dc41SMark McLoughlin if (err) { 34940aa0dc41SMark McLoughlin kfree(root); 34950aa0dc41SMark McLoughlin return ERR_PTR(err); 34960aa0dc41SMark McLoughlin } 34970aa0dc41SMark McLoughlin 34980aa0dc41SMark McLoughlin root->dev.release = root_device_release; 34990aa0dc41SMark McLoughlin 35000aa0dc41SMark McLoughlin err = device_register(&root->dev); 35010aa0dc41SMark McLoughlin if (err) { 35020aa0dc41SMark McLoughlin put_device(&root->dev); 35030aa0dc41SMark McLoughlin return ERR_PTR(err); 35040aa0dc41SMark McLoughlin } 35050aa0dc41SMark McLoughlin 35061d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 35070aa0dc41SMark McLoughlin if (owner) { 35080aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 35090aa0dc41SMark McLoughlin 35100aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 35110aa0dc41SMark McLoughlin if (err) { 35120aa0dc41SMark McLoughlin device_unregister(&root->dev); 35130aa0dc41SMark McLoughlin return ERR_PTR(err); 35140aa0dc41SMark McLoughlin } 35150aa0dc41SMark McLoughlin root->owner = owner; 35160aa0dc41SMark McLoughlin } 35170aa0dc41SMark McLoughlin #endif 35180aa0dc41SMark McLoughlin 35190aa0dc41SMark McLoughlin return &root->dev; 35200aa0dc41SMark McLoughlin } 35210aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 35220aa0dc41SMark McLoughlin 35230aa0dc41SMark McLoughlin /** 35240aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 35257cbcf225SRandy Dunlap * @dev: device going away 35260aa0dc41SMark McLoughlin * 35270aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 35280aa0dc41SMark McLoughlin * root_device_register(). 35290aa0dc41SMark McLoughlin */ 35300aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 35310aa0dc41SMark McLoughlin { 35320aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 35330aa0dc41SMark McLoughlin 35340aa0dc41SMark McLoughlin if (root->owner) 35350aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 35360aa0dc41SMark McLoughlin 35370aa0dc41SMark McLoughlin device_unregister(dev); 35380aa0dc41SMark McLoughlin } 35390aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 35400aa0dc41SMark McLoughlin 354123681e47SGreg Kroah-Hartman 354223681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 354323681e47SGreg Kroah-Hartman { 35441e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 354523681e47SGreg Kroah-Hartman kfree(dev); 354623681e47SGreg Kroah-Hartman } 354723681e47SGreg Kroah-Hartman 35486a8b55d7SMathieu Malaterre static __printf(6, 0) struct device * 354939ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 355039ef3112SGuenter Roeck dev_t devt, void *drvdata, 355139ef3112SGuenter Roeck const struct attribute_group **groups, 355239ef3112SGuenter Roeck const char *fmt, va_list args) 355339ef3112SGuenter Roeck { 355439ef3112SGuenter Roeck struct device *dev = NULL; 355539ef3112SGuenter Roeck int retval = -ENODEV; 355639ef3112SGuenter Roeck 355739ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 355839ef3112SGuenter Roeck goto error; 355939ef3112SGuenter Roeck 356039ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 356139ef3112SGuenter Roeck if (!dev) { 356239ef3112SGuenter Roeck retval = -ENOMEM; 356339ef3112SGuenter Roeck goto error; 356439ef3112SGuenter Roeck } 356539ef3112SGuenter Roeck 3566bbc780f8SDavid Herrmann device_initialize(dev); 356739ef3112SGuenter Roeck dev->devt = devt; 356839ef3112SGuenter Roeck dev->class = class; 356939ef3112SGuenter Roeck dev->parent = parent; 357039ef3112SGuenter Roeck dev->groups = groups; 357139ef3112SGuenter Roeck dev->release = device_create_release; 357239ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 357339ef3112SGuenter Roeck 357439ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 357539ef3112SGuenter Roeck if (retval) 357639ef3112SGuenter Roeck goto error; 357739ef3112SGuenter Roeck 3578bbc780f8SDavid Herrmann retval = device_add(dev); 357939ef3112SGuenter Roeck if (retval) 358039ef3112SGuenter Roeck goto error; 358139ef3112SGuenter Roeck 358239ef3112SGuenter Roeck return dev; 358339ef3112SGuenter Roeck 358439ef3112SGuenter Roeck error: 358539ef3112SGuenter Roeck put_device(dev); 358639ef3112SGuenter Roeck return ERR_PTR(retval); 358739ef3112SGuenter Roeck } 358839ef3112SGuenter Roeck 358923681e47SGreg Kroah-Hartman /** 35904e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 35918882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 35928882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 35938882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 35948882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 35958882b394SGreg Kroah-Hartman * @fmt: string for the device's name 35968882b394SGreg Kroah-Hartman * 35978882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 35988882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 35998882b394SGreg Kroah-Hartman * 36008882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 36018882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 36028882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 36038882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 36048882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 36058882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 36068882b394SGreg Kroah-Hartman * pointer. 36078882b394SGreg Kroah-Hartman * 3608f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 3609f0eae0edSJani Nikula * 36108882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 36118882b394SGreg Kroah-Hartman * been created with a call to class_create(). 36128882b394SGreg Kroah-Hartman */ 36134e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 36144e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 36158882b394SGreg Kroah-Hartman { 36168882b394SGreg Kroah-Hartman va_list vargs; 36178882b394SGreg Kroah-Hartman struct device *dev; 36188882b394SGreg Kroah-Hartman 36198882b394SGreg Kroah-Hartman va_start(vargs, fmt); 36204c747466SChristoph Hellwig dev = device_create_groups_vargs(class, parent, devt, drvdata, NULL, 36214c747466SChristoph Hellwig fmt, vargs); 36228882b394SGreg Kroah-Hartman va_end(vargs); 36238882b394SGreg Kroah-Hartman return dev; 36248882b394SGreg Kroah-Hartman } 36254e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 36268882b394SGreg Kroah-Hartman 362739ef3112SGuenter Roeck /** 362839ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 362939ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 363039ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 363139ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 363239ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 363339ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 363439ef3112SGuenter Roeck * @fmt: string for the device's name 363539ef3112SGuenter Roeck * 363639ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 363739ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 363839ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 363939ef3112SGuenter Roeck * be created automatically. 364039ef3112SGuenter Roeck * 364139ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 364239ef3112SGuenter Roeck * the dev_t is not 0,0. 364339ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 364439ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 364539ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 364639ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 364739ef3112SGuenter Roeck * pointer. 364839ef3112SGuenter Roeck * 364939ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 365039ef3112SGuenter Roeck * 365139ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 365239ef3112SGuenter Roeck * been created with a call to class_create(). 365339ef3112SGuenter Roeck */ 365439ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 365539ef3112SGuenter Roeck struct device *parent, dev_t devt, 365639ef3112SGuenter Roeck void *drvdata, 365739ef3112SGuenter Roeck const struct attribute_group **groups, 365839ef3112SGuenter Roeck const char *fmt, ...) 365939ef3112SGuenter Roeck { 366039ef3112SGuenter Roeck va_list vargs; 366139ef3112SGuenter Roeck struct device *dev; 366239ef3112SGuenter Roeck 366339ef3112SGuenter Roeck va_start(vargs, fmt); 366439ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 366539ef3112SGuenter Roeck fmt, vargs); 366639ef3112SGuenter Roeck va_end(vargs); 366739ef3112SGuenter Roeck return dev; 366839ef3112SGuenter Roeck } 366939ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 367039ef3112SGuenter Roeck 3671775b64d2SRafael J. Wysocki /** 3672775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 3673775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 3674775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 3675775b64d2SRafael J. Wysocki * 3676775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 3677775b64d2SRafael J. Wysocki * call to device_create(). 3678775b64d2SRafael J. Wysocki */ 3679775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 3680775b64d2SRafael J. Wysocki { 3681775b64d2SRafael J. Wysocki struct device *dev; 3682775b64d2SRafael J. Wysocki 36834495dfddSSuzuki K Poulose dev = class_find_device_by_devt(class, devt); 3684cd35449bSDave Young if (dev) { 3685cd35449bSDave Young put_device(dev); 368623681e47SGreg Kroah-Hartman device_unregister(dev); 368723681e47SGreg Kroah-Hartman } 3688cd35449bSDave Young } 368923681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 3690a2de48caSGreg Kroah-Hartman 3691a2de48caSGreg Kroah-Hartman /** 3692a2de48caSGreg Kroah-Hartman * device_rename - renames a device 3693a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 3694a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 3695030c1d2bSEric W. Biederman * 3696030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 3697030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 3698030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 3699030c1d2bSEric W. Biederman * won't conflict with other devices. 3700c6c0ac66SMichael Ellerman * 3701a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 3702a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 3703a5462516STimur Tabi * some insight: 3704a5462516STimur Tabi * 3705a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 3706a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 3707a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 3708a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 3709a5462516STimur Tabi * 3710a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 3711a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 3712a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 3713a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 3714a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 3715a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 3716a5462516STimur Tabi * 3717a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 3718a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 3719a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 3720a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 3721a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 3722a5462516STimur Tabi * reasons. 3723a5462516STimur Tabi * 3724a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 3725a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 3726a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 3727a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 3728a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 3729a2de48caSGreg Kroah-Hartman */ 37306937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 3731a2de48caSGreg Kroah-Hartman { 37324b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 37332ee97cafSCornelia Huck char *old_device_name = NULL; 3734a2de48caSGreg Kroah-Hartman int error; 3735a2de48caSGreg Kroah-Hartman 3736a2de48caSGreg Kroah-Hartman dev = get_device(dev); 3737a2de48caSGreg Kroah-Hartman if (!dev) 3738a2de48caSGreg Kroah-Hartman return -EINVAL; 3739a2de48caSGreg Kroah-Hartman 374069df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 3741a2de48caSGreg Kroah-Hartman 37421fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 37432ee97cafSCornelia Huck if (!old_device_name) { 3744952ab431SJesper Juhl error = -ENOMEM; 37452ee97cafSCornelia Huck goto out; 3746952ab431SJesper Juhl } 3747a2de48caSGreg Kroah-Hartman 3748f349cf34SEric W. Biederman if (dev->class) { 37494b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 37504b30ee58STejun Heo kobj, old_device_name, 37514b30ee58STejun Heo new_name, kobject_namespace(kobj)); 3752f349cf34SEric W. Biederman if (error) 3753f349cf34SEric W. Biederman goto out; 3754f349cf34SEric W. Biederman } 375539aba963SKay Sievers 37564b30ee58STejun Heo error = kobject_rename(kobj, new_name); 37571fa5ae85SKay Sievers if (error) 37582ee97cafSCornelia Huck goto out; 3759a2de48caSGreg Kroah-Hartman 37602ee97cafSCornelia Huck out: 3761a2de48caSGreg Kroah-Hartman put_device(dev); 3762a2de48caSGreg Kroah-Hartman 37632ee97cafSCornelia Huck kfree(old_device_name); 3764a2de48caSGreg Kroah-Hartman 3765a2de48caSGreg Kroah-Hartman return error; 3766a2de48caSGreg Kroah-Hartman } 3767a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 37688a82472fSCornelia Huck 37698a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 37708a82472fSCornelia Huck struct device *old_parent, 37718a82472fSCornelia Huck struct device *new_parent) 37728a82472fSCornelia Huck { 3773f7f3461dSGreg Kroah-Hartman int error = 0; 37748a82472fSCornelia Huck 3775f7f3461dSGreg Kroah-Hartman if (old_parent) 3776f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 3777f7f3461dSGreg Kroah-Hartman if (new_parent) 3778f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 3779f7f3461dSGreg Kroah-Hartman "device"); 3780f7f3461dSGreg Kroah-Hartman return error; 37818a82472fSCornelia Huck } 37828a82472fSCornelia Huck 37838a82472fSCornelia Huck /** 37848a82472fSCornelia Huck * device_move - moves a device to a new parent 37858a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 378613509860SWolfram Sang * @new_parent: the new parent of the device (can be NULL) 3787ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 37888a82472fSCornelia Huck */ 3789ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 3790ffa6a705SCornelia Huck enum dpm_order dpm_order) 37918a82472fSCornelia Huck { 37928a82472fSCornelia Huck int error; 37938a82472fSCornelia Huck struct device *old_parent; 3794c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 37958a82472fSCornelia Huck 37968a82472fSCornelia Huck dev = get_device(dev); 37978a82472fSCornelia Huck if (!dev) 37988a82472fSCornelia Huck return -EINVAL; 37998a82472fSCornelia Huck 3800ffa6a705SCornelia Huck device_pm_lock(); 38018a82472fSCornelia Huck new_parent = get_device(new_parent); 3802c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 380384d0c27dSTetsuo Handa if (IS_ERR(new_parent_kobj)) { 380484d0c27dSTetsuo Handa error = PTR_ERR(new_parent_kobj); 380584d0c27dSTetsuo Handa put_device(new_parent); 380684d0c27dSTetsuo Handa goto out; 380784d0c27dSTetsuo Handa } 380863b6971aSCornelia Huck 38091e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 38101e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 3811c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 38128a82472fSCornelia Huck if (error) { 381363b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 38148a82472fSCornelia Huck put_device(new_parent); 38158a82472fSCornelia Huck goto out; 38168a82472fSCornelia Huck } 38178a82472fSCornelia Huck old_parent = dev->parent; 38188a82472fSCornelia Huck dev->parent = new_parent; 38198a82472fSCornelia Huck if (old_parent) 3820f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 38210d358f22SYinghai Lu if (new_parent) { 3822f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 3823f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 38240d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 38250d358f22SYinghai Lu } 38260d358f22SYinghai Lu 3827bdd4034dSRabin Vincent if (dev->class) { 38288a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 38298a82472fSCornelia Huck if (error) { 38308a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 38318a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 38328a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 3833c744aeaeSCornelia Huck if (new_parent) 3834f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 38350d358f22SYinghai Lu dev->parent = old_parent; 38360d358f22SYinghai Lu if (old_parent) { 3837f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 3838f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 38390d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 38400d358f22SYinghai Lu } 38418a82472fSCornelia Huck } 384263b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 38438a82472fSCornelia Huck put_device(new_parent); 38448a82472fSCornelia Huck goto out; 38458a82472fSCornelia Huck } 3846bdd4034dSRabin Vincent } 3847ffa6a705SCornelia Huck switch (dpm_order) { 3848ffa6a705SCornelia Huck case DPM_ORDER_NONE: 3849ffa6a705SCornelia Huck break; 3850ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 3851ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 385252cdbdd4SGrygorii Strashko devices_kset_move_after(dev, new_parent); 3853ffa6a705SCornelia Huck break; 3854ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 3855ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 385652cdbdd4SGrygorii Strashko devices_kset_move_before(new_parent, dev); 3857ffa6a705SCornelia Huck break; 3858ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 3859ffa6a705SCornelia Huck device_pm_move_last(dev); 386052cdbdd4SGrygorii Strashko devices_kset_move_last(dev); 3861ffa6a705SCornelia Huck break; 3862ffa6a705SCornelia Huck } 3863bdd4034dSRabin Vincent 38648a82472fSCornelia Huck put_device(old_parent); 38658a82472fSCornelia Huck out: 3866ffa6a705SCornelia Huck device_pm_unlock(); 38678a82472fSCornelia Huck put_device(dev); 38688a82472fSCornelia Huck return error; 38698a82472fSCornelia Huck } 38708a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 387137b0c020SGreg Kroah-Hartman 3872b8f33e5dSChristian Brauner static int device_attrs_change_owner(struct device *dev, kuid_t kuid, 3873b8f33e5dSChristian Brauner kgid_t kgid) 3874b8f33e5dSChristian Brauner { 3875b8f33e5dSChristian Brauner struct kobject *kobj = &dev->kobj; 3876b8f33e5dSChristian Brauner struct class *class = dev->class; 3877b8f33e5dSChristian Brauner const struct device_type *type = dev->type; 3878b8f33e5dSChristian Brauner int error; 3879b8f33e5dSChristian Brauner 3880b8f33e5dSChristian Brauner if (class) { 3881b8f33e5dSChristian Brauner /* 3882b8f33e5dSChristian Brauner * Change the device groups of the device class for @dev to 3883b8f33e5dSChristian Brauner * @kuid/@kgid. 3884b8f33e5dSChristian Brauner */ 3885b8f33e5dSChristian Brauner error = sysfs_groups_change_owner(kobj, class->dev_groups, kuid, 3886b8f33e5dSChristian Brauner kgid); 3887b8f33e5dSChristian Brauner if (error) 3888b8f33e5dSChristian Brauner return error; 3889b8f33e5dSChristian Brauner } 3890b8f33e5dSChristian Brauner 3891b8f33e5dSChristian Brauner if (type) { 3892b8f33e5dSChristian Brauner /* 3893b8f33e5dSChristian Brauner * Change the device groups of the device type for @dev to 3894b8f33e5dSChristian Brauner * @kuid/@kgid. 3895b8f33e5dSChristian Brauner */ 3896b8f33e5dSChristian Brauner error = sysfs_groups_change_owner(kobj, type->groups, kuid, 3897b8f33e5dSChristian Brauner kgid); 3898b8f33e5dSChristian Brauner if (error) 3899b8f33e5dSChristian Brauner return error; 3900b8f33e5dSChristian Brauner } 3901b8f33e5dSChristian Brauner 3902b8f33e5dSChristian Brauner /* Change the device groups of @dev to @kuid/@kgid. */ 3903b8f33e5dSChristian Brauner error = sysfs_groups_change_owner(kobj, dev->groups, kuid, kgid); 3904b8f33e5dSChristian Brauner if (error) 3905b8f33e5dSChristian Brauner return error; 3906b8f33e5dSChristian Brauner 3907b8f33e5dSChristian Brauner if (device_supports_offline(dev) && !dev->offline_disabled) { 3908b8f33e5dSChristian Brauner /* Change online device attributes of @dev to @kuid/@kgid. */ 3909b8f33e5dSChristian Brauner error = sysfs_file_change_owner(kobj, dev_attr_online.attr.name, 3910b8f33e5dSChristian Brauner kuid, kgid); 3911b8f33e5dSChristian Brauner if (error) 3912b8f33e5dSChristian Brauner return error; 3913b8f33e5dSChristian Brauner } 3914b8f33e5dSChristian Brauner 3915b8f33e5dSChristian Brauner return 0; 3916b8f33e5dSChristian Brauner } 3917b8f33e5dSChristian Brauner 3918b8f33e5dSChristian Brauner /** 3919b8f33e5dSChristian Brauner * device_change_owner - change the owner of an existing device. 3920b8f33e5dSChristian Brauner * @dev: device. 3921b8f33e5dSChristian Brauner * @kuid: new owner's kuid 3922b8f33e5dSChristian Brauner * @kgid: new owner's kgid 3923b8f33e5dSChristian Brauner * 3924b8f33e5dSChristian Brauner * This changes the owner of @dev and its corresponding sysfs entries to 3925b8f33e5dSChristian Brauner * @kuid/@kgid. This function closely mirrors how @dev was added via driver 3926b8f33e5dSChristian Brauner * core. 3927b8f33e5dSChristian Brauner * 3928b8f33e5dSChristian Brauner * Returns 0 on success or error code on failure. 3929b8f33e5dSChristian Brauner */ 3930b8f33e5dSChristian Brauner int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) 3931b8f33e5dSChristian Brauner { 3932b8f33e5dSChristian Brauner int error; 3933b8f33e5dSChristian Brauner struct kobject *kobj = &dev->kobj; 3934b8f33e5dSChristian Brauner 3935b8f33e5dSChristian Brauner dev = get_device(dev); 3936b8f33e5dSChristian Brauner if (!dev) 3937b8f33e5dSChristian Brauner return -EINVAL; 3938b8f33e5dSChristian Brauner 3939b8f33e5dSChristian Brauner /* 3940b8f33e5dSChristian Brauner * Change the kobject and the default attributes and groups of the 3941b8f33e5dSChristian Brauner * ktype associated with it to @kuid/@kgid. 3942b8f33e5dSChristian Brauner */ 3943b8f33e5dSChristian Brauner error = sysfs_change_owner(kobj, kuid, kgid); 3944b8f33e5dSChristian Brauner if (error) 3945b8f33e5dSChristian Brauner goto out; 3946b8f33e5dSChristian Brauner 3947b8f33e5dSChristian Brauner /* 3948b8f33e5dSChristian Brauner * Change the uevent file for @dev to the new owner. The uevent file 3949b8f33e5dSChristian Brauner * was created in a separate step when @dev got added and we mirror 3950b8f33e5dSChristian Brauner * that step here. 3951b8f33e5dSChristian Brauner */ 3952b8f33e5dSChristian Brauner error = sysfs_file_change_owner(kobj, dev_attr_uevent.attr.name, kuid, 3953b8f33e5dSChristian Brauner kgid); 3954b8f33e5dSChristian Brauner if (error) 3955b8f33e5dSChristian Brauner goto out; 3956b8f33e5dSChristian Brauner 3957b8f33e5dSChristian Brauner /* 3958b8f33e5dSChristian Brauner * Change the device groups, the device groups associated with the 3959b8f33e5dSChristian Brauner * device class, and the groups associated with the device type of @dev 3960b8f33e5dSChristian Brauner * to @kuid/@kgid. 3961b8f33e5dSChristian Brauner */ 3962b8f33e5dSChristian Brauner error = device_attrs_change_owner(dev, kuid, kgid); 3963b8f33e5dSChristian Brauner if (error) 3964b8f33e5dSChristian Brauner goto out; 3965b8f33e5dSChristian Brauner 39663b52fc5dSChristian Brauner error = dpm_sysfs_change_owner(dev, kuid, kgid); 39673b52fc5dSChristian Brauner if (error) 39683b52fc5dSChristian Brauner goto out; 39693b52fc5dSChristian Brauner 3970b8f33e5dSChristian Brauner #ifdef CONFIG_BLOCK 3971b8f33e5dSChristian Brauner if (sysfs_deprecated && dev->class == &block_class) 3972b8f33e5dSChristian Brauner goto out; 3973b8f33e5dSChristian Brauner #endif 3974b8f33e5dSChristian Brauner 3975b8f33e5dSChristian Brauner /* 3976b8f33e5dSChristian Brauner * Change the owner of the symlink located in the class directory of 3977b8f33e5dSChristian Brauner * the device class associated with @dev which points to the actual 3978b8f33e5dSChristian Brauner * directory entry for @dev to @kuid/@kgid. This ensures that the 3979b8f33e5dSChristian Brauner * symlink shows the same permissions as its target. 3980b8f33e5dSChristian Brauner */ 3981b8f33e5dSChristian Brauner error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj, 3982b8f33e5dSChristian Brauner dev_name(dev), kuid, kgid); 3983b8f33e5dSChristian Brauner if (error) 3984b8f33e5dSChristian Brauner goto out; 3985b8f33e5dSChristian Brauner 3986b8f33e5dSChristian Brauner out: 3987b8f33e5dSChristian Brauner put_device(dev); 3988b8f33e5dSChristian Brauner return error; 3989b8f33e5dSChristian Brauner } 3990b8f33e5dSChristian Brauner EXPORT_SYMBOL_GPL(device_change_owner); 3991b8f33e5dSChristian Brauner 399237b0c020SGreg Kroah-Hartman /** 399337b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 399437b0c020SGreg Kroah-Hartman */ 399537b0c020SGreg Kroah-Hartman void device_shutdown(void) 399637b0c020SGreg Kroah-Hartman { 3997f123db8eSBenson Leung struct device *dev, *parent; 399837b0c020SGreg Kroah-Hartman 39993297c8fcSPingfan Liu wait_for_device_probe(); 40003297c8fcSPingfan Liu device_block_probing(); 40013297c8fcSPingfan Liu 400265650b35SRafael J. Wysocki cpufreq_suspend(); 400365650b35SRafael J. Wysocki 40046245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 40056245838fSHugh Daschbach /* 40066245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 40076245838fSHugh Daschbach * Beware that device unplug events may also start pulling 40086245838fSHugh Daschbach * devices offline, even as the system is shutting down. 40096245838fSHugh Daschbach */ 40106245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 40116245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 40126245838fSHugh Daschbach kobj.entry); 4013d1c6c030SMing Lei 4014d1c6c030SMing Lei /* 4015d1c6c030SMing Lei * hold reference count of device's parent to 4016d1c6c030SMing Lei * prevent it from being freed because parent's 4017d1c6c030SMing Lei * lock is to be held 4018d1c6c030SMing Lei */ 4019f123db8eSBenson Leung parent = get_device(dev->parent); 40206245838fSHugh Daschbach get_device(dev); 40216245838fSHugh Daschbach /* 40226245838fSHugh Daschbach * Make sure the device is off the kset list, in the 40236245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 40246245838fSHugh Daschbach */ 40256245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 40266245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 4027fe6b91f4SAlan Stern 4028d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 4029f123db8eSBenson Leung if (parent) 4030f123db8eSBenson Leung device_lock(parent); 4031d1c6c030SMing Lei device_lock(dev); 4032d1c6c030SMing Lei 4033fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 4034fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 4035fe6b91f4SAlan Stern pm_runtime_barrier(dev); 40366245838fSHugh Daschbach 40377521621eSMichal Suchanek if (dev->class && dev->class->shutdown_pre) { 4038f77af151SJosh Zimmerman if (initcall_debug) 40397521621eSMichal Suchanek dev_info(dev, "shutdown_pre\n"); 40407521621eSMichal Suchanek dev->class->shutdown_pre(dev); 40417521621eSMichal Suchanek } 40427521621eSMichal Suchanek if (dev->bus && dev->bus->shutdown) { 40430246c4faSShuoX Liu if (initcall_debug) 40440246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 404537b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 404637b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 40470246c4faSShuoX Liu if (initcall_debug) 40480246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 404937b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 405037b0c020SGreg Kroah-Hartman } 4051d1c6c030SMing Lei 4052d1c6c030SMing Lei device_unlock(dev); 4053f123db8eSBenson Leung if (parent) 4054f123db8eSBenson Leung device_unlock(parent); 4055d1c6c030SMing Lei 40566245838fSHugh Daschbach put_device(dev); 4057f123db8eSBenson Leung put_device(parent); 40586245838fSHugh Daschbach 40596245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 406037b0c020SGreg Kroah-Hartman } 40616245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 406237b0c020SGreg Kroah-Hartman } 406399bcf217SJoe Perches 406499bcf217SJoe Perches /* 406599bcf217SJoe Perches * Device logging functions 406699bcf217SJoe Perches */ 406799bcf217SJoe Perches 406899bcf217SJoe Perches #ifdef CONFIG_PRINTK 4069666f355fSJoe Perches static int 4070666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 407199bcf217SJoe Perches { 4072c4e00daaSKay Sievers const char *subsys; 4073798efc60SJoe Perches size_t pos = 0; 407499bcf217SJoe Perches 4075c4e00daaSKay Sievers if (dev->class) 4076c4e00daaSKay Sievers subsys = dev->class->name; 4077c4e00daaSKay Sievers else if (dev->bus) 4078c4e00daaSKay Sievers subsys = dev->bus->name; 4079c4e00daaSKay Sievers else 4080798efc60SJoe Perches return 0; 4081c4e00daaSKay Sievers 4082798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 4083655e5b7cSBen Hutchings if (pos >= hdrlen) 4084655e5b7cSBen Hutchings goto overflow; 4085c4e00daaSKay Sievers 4086c4e00daaSKay Sievers /* 4087c4e00daaSKay Sievers * Add device identifier DEVICE=: 4088c4e00daaSKay Sievers * b12:8 block dev_t 4089c4e00daaSKay Sievers * c127:3 char dev_t 4090c4e00daaSKay Sievers * n8 netdev ifindex 4091c4e00daaSKay Sievers * +sound:card0 subsystem:devname 4092c4e00daaSKay Sievers */ 4093c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 4094c4e00daaSKay Sievers char c; 4095c4e00daaSKay Sievers 4096c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 4097c4e00daaSKay Sievers c = 'b'; 4098c4e00daaSKay Sievers else 4099c4e00daaSKay Sievers c = 'c'; 4100798efc60SJoe Perches pos++; 4101798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 4102c4e00daaSKay Sievers "DEVICE=%c%u:%u", 4103c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 4104c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 4105c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 4106c4e00daaSKay Sievers 4107798efc60SJoe Perches pos++; 4108798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 4109c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 4110c4e00daaSKay Sievers } else { 4111798efc60SJoe Perches pos++; 4112798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 4113c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 4114c4e00daaSKay Sievers } 4115af7f2158SJim Cromie 4116655e5b7cSBen Hutchings if (pos >= hdrlen) 4117655e5b7cSBen Hutchings goto overflow; 4118655e5b7cSBen Hutchings 4119798efc60SJoe Perches return pos; 4120655e5b7cSBen Hutchings 4121655e5b7cSBen Hutchings overflow: 4122655e5b7cSBen Hutchings dev_WARN(dev, "device/subsystem name too long"); 4123655e5b7cSBen Hutchings return 0; 412499bcf217SJoe Perches } 4125798efc60SJoe Perches 412605e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 412705e4e5b8SJoe Perches const char *fmt, va_list args) 412805e4e5b8SJoe Perches { 412905e4e5b8SJoe Perches char hdr[128]; 413005e4e5b8SJoe Perches size_t hdrlen; 413105e4e5b8SJoe Perches 413205e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 413305e4e5b8SJoe Perches 413405e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 413505e4e5b8SJoe Perches } 413605e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 413705e4e5b8SJoe Perches 413805e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 413905e4e5b8SJoe Perches { 414005e4e5b8SJoe Perches va_list args; 414105e4e5b8SJoe Perches int r; 414205e4e5b8SJoe Perches 414305e4e5b8SJoe Perches va_start(args, fmt); 414405e4e5b8SJoe Perches 414505e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 414605e4e5b8SJoe Perches 414705e4e5b8SJoe Perches va_end(args); 414805e4e5b8SJoe Perches 414905e4e5b8SJoe Perches return r; 415005e4e5b8SJoe Perches } 415105e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 415205e4e5b8SJoe Perches 4153d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev, 4154798efc60SJoe Perches struct va_format *vaf) 4155798efc60SJoe Perches { 4156d1f1052cSJoe Perches if (dev) 4157d1f1052cSJoe Perches dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", 4158798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 4159d1f1052cSJoe Perches else 4160d1f1052cSJoe Perches printk("%s(NULL device *): %pV", level, vaf); 4161798efc60SJoe Perches } 416299bcf217SJoe Perches 4163d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev, 416499bcf217SJoe Perches const char *fmt, ...) 416599bcf217SJoe Perches { 416699bcf217SJoe Perches struct va_format vaf; 416799bcf217SJoe Perches va_list args; 416899bcf217SJoe Perches 416999bcf217SJoe Perches va_start(args, fmt); 417099bcf217SJoe Perches 417199bcf217SJoe Perches vaf.fmt = fmt; 417299bcf217SJoe Perches vaf.va = &args; 417399bcf217SJoe Perches 4174d1f1052cSJoe Perches __dev_printk(level, dev, &vaf); 4175798efc60SJoe Perches 417699bcf217SJoe Perches va_end(args); 417799bcf217SJoe Perches } 417899bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 417999bcf217SJoe Perches 418099bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 4181d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...) \ 418299bcf217SJoe Perches { \ 418399bcf217SJoe Perches struct va_format vaf; \ 418499bcf217SJoe Perches va_list args; \ 418599bcf217SJoe Perches \ 418699bcf217SJoe Perches va_start(args, fmt); \ 418799bcf217SJoe Perches \ 418899bcf217SJoe Perches vaf.fmt = fmt; \ 418999bcf217SJoe Perches vaf.va = &args; \ 419099bcf217SJoe Perches \ 4191d1f1052cSJoe Perches __dev_printk(kern_level, dev, &vaf); \ 4192798efc60SJoe Perches \ 419399bcf217SJoe Perches va_end(args); \ 419499bcf217SJoe Perches } \ 419599bcf217SJoe Perches EXPORT_SYMBOL(func); 419699bcf217SJoe Perches 4197663336eeSJoe Perches define_dev_printk_level(_dev_emerg, KERN_EMERG); 4198663336eeSJoe Perches define_dev_printk_level(_dev_alert, KERN_ALERT); 4199663336eeSJoe Perches define_dev_printk_level(_dev_crit, KERN_CRIT); 4200663336eeSJoe Perches define_dev_printk_level(_dev_err, KERN_ERR); 4201663336eeSJoe Perches define_dev_printk_level(_dev_warn, KERN_WARNING); 4202663336eeSJoe Perches define_dev_printk_level(_dev_notice, KERN_NOTICE); 420399bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 420499bcf217SJoe Perches 420599bcf217SJoe Perches #endif 420697badf87SRafael J. Wysocki 4207a787e540SAndrzej Hajda /** 4208a787e540SAndrzej Hajda * dev_err_probe - probe error check and log helper 4209a787e540SAndrzej Hajda * @dev: the pointer to the struct device 4210a787e540SAndrzej Hajda * @err: error value to test 4211a787e540SAndrzej Hajda * @fmt: printf-style format string 4212a787e540SAndrzej Hajda * @...: arguments as specified in the format string 4213a787e540SAndrzej Hajda * 4214a787e540SAndrzej Hajda * This helper implements common pattern present in probe functions for error 4215a787e540SAndrzej Hajda * checking: print debug or error message depending if the error value is 4216a787e540SAndrzej Hajda * -EPROBE_DEFER and propagate error upwards. 4217d090b70eSAndrzej Hajda * In case of -EPROBE_DEFER it sets also defer probe reason, which can be 4218d090b70eSAndrzej Hajda * checked later by reading devices_deferred debugfs attribute. 4219a787e540SAndrzej Hajda * It replaces code sequence: 4220a787e540SAndrzej Hajda * if (err != -EPROBE_DEFER) 4221a787e540SAndrzej Hajda * dev_err(dev, ...); 4222a787e540SAndrzej Hajda * else 4223a787e540SAndrzej Hajda * dev_dbg(dev, ...); 4224a787e540SAndrzej Hajda * return err; 4225a787e540SAndrzej Hajda * with 4226a787e540SAndrzej Hajda * return dev_err_probe(dev, err, ...); 4227a787e540SAndrzej Hajda * 4228a787e540SAndrzej Hajda * Returns @err. 4229a787e540SAndrzej Hajda * 4230a787e540SAndrzej Hajda */ 4231a787e540SAndrzej Hajda int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) 4232a787e540SAndrzej Hajda { 4233a787e540SAndrzej Hajda struct va_format vaf; 4234a787e540SAndrzej Hajda va_list args; 4235a787e540SAndrzej Hajda 4236a787e540SAndrzej Hajda va_start(args, fmt); 4237a787e540SAndrzej Hajda vaf.fmt = fmt; 4238a787e540SAndrzej Hajda vaf.va = &args; 4239a787e540SAndrzej Hajda 4240d090b70eSAndrzej Hajda if (err != -EPROBE_DEFER) { 4241693a8e93SMichał Mirosław dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 4242d090b70eSAndrzej Hajda } else { 4243d090b70eSAndrzej Hajda device_set_deferred_probe_reason(dev, &vaf); 4244693a8e93SMichał Mirosław dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 4245d090b70eSAndrzej Hajda } 4246a787e540SAndrzej Hajda 4247a787e540SAndrzej Hajda va_end(args); 4248a787e540SAndrzej Hajda 4249a787e540SAndrzej Hajda return err; 4250a787e540SAndrzej Hajda } 4251a787e540SAndrzej Hajda EXPORT_SYMBOL_GPL(dev_err_probe); 4252a787e540SAndrzej Hajda 425397badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 425497badf87SRafael J. Wysocki { 425597badf87SRafael J. Wysocki return fwnode && !IS_ERR(fwnode->secondary); 425697badf87SRafael J. Wysocki } 425797badf87SRafael J. Wysocki 425897badf87SRafael J. Wysocki /** 425997badf87SRafael J. Wysocki * set_primary_fwnode - Change the primary firmware node of a given device. 426097badf87SRafael J. Wysocki * @dev: Device to handle. 426197badf87SRafael J. Wysocki * @fwnode: New primary firmware node of the device. 426297badf87SRafael J. Wysocki * 426397badf87SRafael J. Wysocki * Set the device's firmware node pointer to @fwnode, but if a secondary 426497badf87SRafael J. Wysocki * firmware node of the device is present, preserve it. 426597badf87SRafael J. Wysocki */ 426697badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 426797badf87SRafael J. Wysocki { 426897badf87SRafael J. Wysocki struct fwnode_handle *fn = dev->fwnode; 426997badf87SRafael J. Wysocki 4270c15e1bddSHeikki Krogerus if (fwnode) { 427197badf87SRafael J. Wysocki if (fwnode_is_primary(fn)) 427297badf87SRafael J. Wysocki fn = fn->secondary; 427397badf87SRafael J. Wysocki 427455f89a8aSMika Westerberg if (fn) { 427555f89a8aSMika Westerberg WARN_ON(fwnode->secondary); 427697badf87SRafael J. Wysocki fwnode->secondary = fn; 427755f89a8aSMika Westerberg } 427897badf87SRafael J. Wysocki dev->fwnode = fwnode; 427997badf87SRafael J. Wysocki } else { 4280c15e1bddSHeikki Krogerus if (fwnode_is_primary(fn)) { 4281c15e1bddSHeikki Krogerus dev->fwnode = fn->secondary; 4282c15e1bddSHeikki Krogerus fn->secondary = NULL; 4283c15e1bddSHeikki Krogerus } else { 4284c15e1bddSHeikki Krogerus dev->fwnode = NULL; 4285c15e1bddSHeikki Krogerus } 428697badf87SRafael J. Wysocki } 428797badf87SRafael J. Wysocki } 428897badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode); 428997badf87SRafael J. Wysocki 429097badf87SRafael J. Wysocki /** 429197badf87SRafael J. Wysocki * set_secondary_fwnode - Change the secondary firmware node of a given device. 429297badf87SRafael J. Wysocki * @dev: Device to handle. 429397badf87SRafael J. Wysocki * @fwnode: New secondary firmware node of the device. 429497badf87SRafael J. Wysocki * 429597badf87SRafael J. Wysocki * If a primary firmware node of the device is present, set its secondary 429697badf87SRafael J. Wysocki * pointer to @fwnode. Otherwise, set the device's firmware node pointer to 429797badf87SRafael J. Wysocki * @fwnode. 429897badf87SRafael J. Wysocki */ 429997badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 430097badf87SRafael J. Wysocki { 430197badf87SRafael J. Wysocki if (fwnode) 430297badf87SRafael J. Wysocki fwnode->secondary = ERR_PTR(-ENODEV); 430397badf87SRafael J. Wysocki 430497badf87SRafael J. Wysocki if (fwnode_is_primary(dev->fwnode)) 430597badf87SRafael J. Wysocki dev->fwnode->secondary = fwnode; 430697badf87SRafael J. Wysocki else 430797badf87SRafael J. Wysocki dev->fwnode = fwnode; 430897badf87SRafael J. Wysocki } 430996489ae1SAndy Shevchenko EXPORT_SYMBOL_GPL(set_secondary_fwnode); 43104e75e1d7SJohan Hovold 43114e75e1d7SJohan Hovold /** 43124e75e1d7SJohan Hovold * device_set_of_node_from_dev - reuse device-tree node of another device 43134e75e1d7SJohan Hovold * @dev: device whose device-tree node is being set 43144e75e1d7SJohan Hovold * @dev2: device whose device-tree node is being reused 43154e75e1d7SJohan Hovold * 43164e75e1d7SJohan Hovold * Takes another reference to the new device-tree node after first dropping 43174e75e1d7SJohan Hovold * any reference held to the old node. 43184e75e1d7SJohan Hovold */ 43194e75e1d7SJohan Hovold void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) 43204e75e1d7SJohan Hovold { 43214e75e1d7SJohan Hovold of_node_put(dev->of_node); 43224e75e1d7SJohan Hovold dev->of_node = of_node_get(dev2->of_node); 43234e75e1d7SJohan Hovold dev->of_node_reused = true; 43244e75e1d7SJohan Hovold } 43254e75e1d7SJohan Hovold EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); 432665b66682SSuzuki K Poulose 43276cda08a2SSuzuki K Poulose int device_match_name(struct device *dev, const void *name) 43286cda08a2SSuzuki K Poulose { 43296cda08a2SSuzuki K Poulose return sysfs_streq(dev_name(dev), name); 43306cda08a2SSuzuki K Poulose } 43316cda08a2SSuzuki K Poulose EXPORT_SYMBOL_GPL(device_match_name); 43326cda08a2SSuzuki K Poulose 433365b66682SSuzuki K Poulose int device_match_of_node(struct device *dev, const void *np) 433465b66682SSuzuki K Poulose { 433565b66682SSuzuki K Poulose return dev->of_node == np; 433665b66682SSuzuki K Poulose } 433765b66682SSuzuki K Poulose EXPORT_SYMBOL_GPL(device_match_of_node); 433867843bbaSSuzuki K Poulose 433967843bbaSSuzuki K Poulose int device_match_fwnode(struct device *dev, const void *fwnode) 434067843bbaSSuzuki K Poulose { 434167843bbaSSuzuki K Poulose return dev_fwnode(dev) == fwnode; 434267843bbaSSuzuki K Poulose } 434367843bbaSSuzuki K Poulose EXPORT_SYMBOL_GPL(device_match_fwnode); 43444495dfddSSuzuki K Poulose 43454495dfddSSuzuki K Poulose int device_match_devt(struct device *dev, const void *pdevt) 43464495dfddSSuzuki K Poulose { 43474495dfddSSuzuki K Poulose return dev->devt == *(dev_t *)pdevt; 43484495dfddSSuzuki K Poulose } 43494495dfddSSuzuki K Poulose EXPORT_SYMBOL_GPL(device_match_devt); 435000500147SSuzuki K Poulose 435100500147SSuzuki K Poulose int device_match_acpi_dev(struct device *dev, const void *adev) 435200500147SSuzuki K Poulose { 435300500147SSuzuki K Poulose return ACPI_COMPANION(dev) == adev; 435400500147SSuzuki K Poulose } 435500500147SSuzuki K Poulose EXPORT_SYMBOL(device_match_acpi_dev); 43566bf85ba9SSuzuki K Poulose 43576bf85ba9SSuzuki K Poulose int device_match_any(struct device *dev, const void *unused) 43586bf85ba9SSuzuki K Poulose { 43596bf85ba9SSuzuki K Poulose return 1; 43606bf85ba9SSuzuki K Poulose } 43616bf85ba9SSuzuki K Poulose EXPORT_SYMBOL_GPL(device_match_any); 4362