11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc) 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 664bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de> 764bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * This file is released under the GPLv2 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds 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> 25815d2d50SAndrew Morton #include <linux/kallsyms.h> 26f75b1c60SDave Young #include <linux/mutex.h> 27af8db150SPeter Chen #include <linux/pm_runtime.h> 28c4e00daaSKay Sievers #include <linux/netdevice.h> 2963967685SGreg Kroah-Hartman #include <linux/sysfs.h> 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds #include "base.h" 321da177e4SLinus Torvalds #include "power/power.h" 331da177e4SLinus Torvalds 34e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED 35e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2 36e52eec13SAndi Kleen long sysfs_deprecated = 1; 37e52eec13SAndi Kleen #else 38e52eec13SAndi Kleen long sysfs_deprecated = 0; 39e52eec13SAndi Kleen #endif 403454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg) 41e52eec13SAndi Kleen { 4234da5e67SJingoo Han return kstrtol(arg, 10, &sysfs_deprecated); 43e52eec13SAndi Kleen } 44e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup); 45e52eec13SAndi Kleen #endif 46e52eec13SAndi Kleen 479ed98953SRafael J. Wysocki /* Device links support. */ 489ed98953SRafael J. Wysocki 499ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 509ed98953SRafael J. Wysocki static DEFINE_MUTEX(device_links_lock); 519ed98953SRafael J. Wysocki DEFINE_STATIC_SRCU(device_links_srcu); 529ed98953SRafael J. Wysocki 539ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 549ed98953SRafael J. Wysocki { 559ed98953SRafael J. Wysocki mutex_lock(&device_links_lock); 569ed98953SRafael J. Wysocki } 579ed98953SRafael J. Wysocki 589ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 599ed98953SRafael J. Wysocki { 609ed98953SRafael J. Wysocki mutex_unlock(&device_links_lock); 619ed98953SRafael J. Wysocki } 629ed98953SRafael J. Wysocki 639ed98953SRafael J. Wysocki int device_links_read_lock(void) 649ed98953SRafael J. Wysocki { 659ed98953SRafael J. Wysocki return srcu_read_lock(&device_links_srcu); 669ed98953SRafael J. Wysocki } 679ed98953SRafael J. Wysocki 689ed98953SRafael J. Wysocki void device_links_read_unlock(int idx) 699ed98953SRafael J. Wysocki { 709ed98953SRafael J. Wysocki srcu_read_unlock(&device_links_srcu, idx); 719ed98953SRafael J. Wysocki } 729ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 739ed98953SRafael J. Wysocki static DECLARE_RWSEM(device_links_lock); 749ed98953SRafael J. Wysocki 759ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 769ed98953SRafael J. Wysocki { 779ed98953SRafael J. Wysocki down_write(&device_links_lock); 789ed98953SRafael J. Wysocki } 799ed98953SRafael J. Wysocki 809ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 819ed98953SRafael J. Wysocki { 829ed98953SRafael J. Wysocki up_write(&device_links_lock); 839ed98953SRafael J. Wysocki } 849ed98953SRafael J. Wysocki 859ed98953SRafael J. Wysocki int device_links_read_lock(void) 869ed98953SRafael J. Wysocki { 879ed98953SRafael J. Wysocki down_read(&device_links_lock); 889ed98953SRafael J. Wysocki return 0; 899ed98953SRafael J. Wysocki } 909ed98953SRafael J. Wysocki 919ed98953SRafael J. Wysocki void device_links_read_unlock(int not_used) 929ed98953SRafael J. Wysocki { 939ed98953SRafael J. Wysocki up_read(&device_links_lock); 949ed98953SRafael J. Wysocki } 959ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 969ed98953SRafael J. Wysocki 979ed98953SRafael J. Wysocki /** 989ed98953SRafael J. Wysocki * device_is_dependent - Check if one device depends on another one 999ed98953SRafael J. Wysocki * @dev: Device to check dependencies for. 1009ed98953SRafael J. Wysocki * @target: Device to check against. 1019ed98953SRafael J. Wysocki * 1029ed98953SRafael J. Wysocki * Check if @target depends on @dev or any device dependent on it (its child or 1039ed98953SRafael J. Wysocki * its consumer etc). Return 1 if that is the case or 0 otherwise. 1049ed98953SRafael J. Wysocki */ 1059ed98953SRafael J. Wysocki static int device_is_dependent(struct device *dev, void *target) 1069ed98953SRafael J. Wysocki { 1079ed98953SRafael J. Wysocki struct device_link *link; 1089ed98953SRafael J. Wysocki int ret; 1099ed98953SRafael J. Wysocki 1109ed98953SRafael J. Wysocki if (WARN_ON(dev == target)) 1119ed98953SRafael J. Wysocki return 1; 1129ed98953SRafael J. Wysocki 1139ed98953SRafael J. Wysocki ret = device_for_each_child(dev, target, device_is_dependent); 1149ed98953SRafael J. Wysocki if (ret) 1159ed98953SRafael J. Wysocki return ret; 1169ed98953SRafael J. Wysocki 1179ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1189ed98953SRafael J. Wysocki if (WARN_ON(link->consumer == target)) 1199ed98953SRafael J. Wysocki return 1; 1209ed98953SRafael J. Wysocki 1219ed98953SRafael J. Wysocki ret = device_is_dependent(link->consumer, target); 1229ed98953SRafael J. Wysocki if (ret) 1239ed98953SRafael J. Wysocki break; 1249ed98953SRafael J. Wysocki } 1259ed98953SRafael J. Wysocki return ret; 1269ed98953SRafael J. Wysocki } 1279ed98953SRafael J. Wysocki 1289ed98953SRafael J. Wysocki static int device_reorder_to_tail(struct device *dev, void *not_used) 1299ed98953SRafael J. Wysocki { 1309ed98953SRafael J. Wysocki struct device_link *link; 1319ed98953SRafael J. Wysocki 1329ed98953SRafael J. Wysocki /* 1339ed98953SRafael J. Wysocki * Devices that have not been registered yet will be put to the ends 1349ed98953SRafael J. Wysocki * of the lists during the registration, so skip them here. 1359ed98953SRafael J. Wysocki */ 1369ed98953SRafael J. Wysocki if (device_is_registered(dev)) 1379ed98953SRafael J. Wysocki devices_kset_move_last(dev); 1389ed98953SRafael J. Wysocki 1399ed98953SRafael J. Wysocki if (device_pm_initialized(dev)) 1409ed98953SRafael J. Wysocki device_pm_move_last(dev); 1419ed98953SRafael J. Wysocki 1429ed98953SRafael J. Wysocki device_for_each_child(dev, NULL, device_reorder_to_tail); 1439ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) 1449ed98953SRafael J. Wysocki device_reorder_to_tail(link->consumer, NULL); 1459ed98953SRafael J. Wysocki 1469ed98953SRafael J. Wysocki return 0; 1479ed98953SRafael J. Wysocki } 1489ed98953SRafael J. Wysocki 1499ed98953SRafael J. Wysocki /** 1509ed98953SRafael J. Wysocki * device_link_add - Create a link between two devices. 1519ed98953SRafael J. Wysocki * @consumer: Consumer end of the link. 1529ed98953SRafael J. Wysocki * @supplier: Supplier end of the link. 1539ed98953SRafael J. Wysocki * @flags: Link flags. 1549ed98953SRafael J. Wysocki * 15521d5c57bSRafael J. Wysocki * The caller is responsible for the proper synchronization of the link creation 15621d5c57bSRafael J. Wysocki * with runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause the 15721d5c57bSRafael J. Wysocki * runtime PM framework to take the link into account. Second, if the 15821d5c57bSRafael J. Wysocki * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will 15921d5c57bSRafael J. Wysocki * be forced into the active metastate and reference-counted upon the creation 16021d5c57bSRafael J. Wysocki * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be 16121d5c57bSRafael J. Wysocki * ignored. 16221d5c57bSRafael J. Wysocki * 1639ed98953SRafael J. Wysocki * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically 1649ed98953SRafael J. Wysocki * when the consumer device driver unbinds from it. The combination of both 1659ed98953SRafael J. Wysocki * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL 1669ed98953SRafael J. Wysocki * to be returned. 1679ed98953SRafael J. Wysocki * 1689ed98953SRafael J. Wysocki * A side effect of the link creation is re-ordering of dpm_list and the 1699ed98953SRafael J. Wysocki * devices_kset list by moving the consumer device and all devices depending 1709ed98953SRafael J. Wysocki * on it to the ends of these lists (that does not happen to devices that have 1719ed98953SRafael J. Wysocki * not been registered when this function is called). 1729ed98953SRafael J. Wysocki * 1739ed98953SRafael J. Wysocki * The supplier device is required to be registered when this function is called 1749ed98953SRafael J. Wysocki * and NULL will be returned if that is not the case. The consumer device need 17564df1148SLukas Wunner * not be registered, however. 1769ed98953SRafael J. Wysocki */ 1779ed98953SRafael J. Wysocki struct device_link *device_link_add(struct device *consumer, 1789ed98953SRafael J. Wysocki struct device *supplier, u32 flags) 1799ed98953SRafael J. Wysocki { 1809ed98953SRafael J. Wysocki struct device_link *link; 1819ed98953SRafael J. Wysocki 1829ed98953SRafael J. Wysocki if (!consumer || !supplier || 1839ed98953SRafael J. Wysocki ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE))) 1849ed98953SRafael J. Wysocki return NULL; 1859ed98953SRafael J. Wysocki 1869ed98953SRafael J. Wysocki device_links_write_lock(); 1879ed98953SRafael J. Wysocki device_pm_lock(); 1889ed98953SRafael J. Wysocki 1899ed98953SRafael J. Wysocki /* 1909ed98953SRafael J. Wysocki * If the supplier has not been fully registered yet or there is a 1919ed98953SRafael J. Wysocki * reverse dependency between the consumer and the supplier already in 1929ed98953SRafael J. Wysocki * the graph, return NULL. 1939ed98953SRafael J. Wysocki */ 1949ed98953SRafael J. Wysocki if (!device_pm_initialized(supplier) 1959ed98953SRafael J. Wysocki || device_is_dependent(consumer, supplier)) { 1969ed98953SRafael J. Wysocki link = NULL; 1979ed98953SRafael J. Wysocki goto out; 1989ed98953SRafael J. Wysocki } 1999ed98953SRafael J. Wysocki 2009ed98953SRafael J. Wysocki list_for_each_entry(link, &supplier->links.consumers, s_node) 2019ed98953SRafael J. Wysocki if (link->consumer == consumer) 2029ed98953SRafael J. Wysocki goto out; 2039ed98953SRafael J. Wysocki 20421d5c57bSRafael J. Wysocki link = kzalloc(sizeof(*link), GFP_KERNEL); 2059ed98953SRafael J. Wysocki if (!link) 2069ed98953SRafael J. Wysocki goto out; 2079ed98953SRafael J. Wysocki 208baa8809fSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) { 209baa8809fSRafael J. Wysocki if (flags & DL_FLAG_RPM_ACTIVE) { 21021d5c57bSRafael J. Wysocki if (pm_runtime_get_sync(supplier) < 0) { 21121d5c57bSRafael J. Wysocki pm_runtime_put_noidle(supplier); 21221d5c57bSRafael J. Wysocki kfree(link); 21321d5c57bSRafael J. Wysocki link = NULL; 21421d5c57bSRafael J. Wysocki goto out; 21521d5c57bSRafael J. Wysocki } 21621d5c57bSRafael J. Wysocki link->rpm_active = true; 21721d5c57bSRafael J. Wysocki } 218baa8809fSRafael J. Wysocki pm_runtime_new_link(consumer); 219baa8809fSRafael J. Wysocki } 2209ed98953SRafael J. Wysocki get_device(supplier); 2219ed98953SRafael J. Wysocki link->supplier = supplier; 2229ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->s_node); 2239ed98953SRafael J. Wysocki get_device(consumer); 2249ed98953SRafael J. Wysocki link->consumer = consumer; 2259ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->c_node); 2269ed98953SRafael J. Wysocki link->flags = flags; 2279ed98953SRafael J. Wysocki 22864df1148SLukas Wunner /* Determine the initial link state. */ 2299ed98953SRafael J. Wysocki if (flags & DL_FLAG_STATELESS) { 2309ed98953SRafael J. Wysocki link->status = DL_STATE_NONE; 2319ed98953SRafael J. Wysocki } else { 2329ed98953SRafael J. Wysocki switch (supplier->links.status) { 2339ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2349ed98953SRafael J. Wysocki switch (consumer->links.status) { 2359ed98953SRafael J. Wysocki case DL_DEV_PROBING: 23621d5c57bSRafael J. Wysocki /* 23721d5c57bSRafael J. Wysocki * Balance the decrementation of the supplier's 23821d5c57bSRafael J. Wysocki * runtime PM usage counter after consumer probe 23921d5c57bSRafael J. Wysocki * in driver_probe_device(). 24021d5c57bSRafael J. Wysocki */ 24121d5c57bSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) 24221d5c57bSRafael J. Wysocki pm_runtime_get_sync(supplier); 24321d5c57bSRafael J. Wysocki 2449ed98953SRafael J. Wysocki link->status = DL_STATE_CONSUMER_PROBE; 2459ed98953SRafael J. Wysocki break; 2469ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2479ed98953SRafael J. Wysocki link->status = DL_STATE_ACTIVE; 2489ed98953SRafael J. Wysocki break; 2499ed98953SRafael J. Wysocki default: 2509ed98953SRafael J. Wysocki link->status = DL_STATE_AVAILABLE; 2519ed98953SRafael J. Wysocki break; 2529ed98953SRafael J. Wysocki } 2539ed98953SRafael J. Wysocki break; 2549ed98953SRafael J. Wysocki case DL_DEV_UNBINDING: 2559ed98953SRafael J. Wysocki link->status = DL_STATE_SUPPLIER_UNBIND; 2569ed98953SRafael J. Wysocki break; 2579ed98953SRafael J. Wysocki default: 2589ed98953SRafael J. Wysocki link->status = DL_STATE_DORMANT; 2599ed98953SRafael J. Wysocki break; 2609ed98953SRafael J. Wysocki } 2619ed98953SRafael J. Wysocki } 2629ed98953SRafael J. Wysocki 2639ed98953SRafael J. Wysocki /* 2649ed98953SRafael J. Wysocki * Move the consumer and all of the devices depending on it to the end 2659ed98953SRafael J. Wysocki * of dpm_list and the devices_kset list. 2669ed98953SRafael J. Wysocki * 2679ed98953SRafael J. Wysocki * It is necessary to hold dpm_list locked throughout all that or else 2689ed98953SRafael J. Wysocki * we may end up suspending with a wrong ordering of it. 2699ed98953SRafael J. Wysocki */ 2709ed98953SRafael J. Wysocki device_reorder_to_tail(consumer, NULL); 2719ed98953SRafael J. Wysocki 2729ed98953SRafael J. Wysocki list_add_tail_rcu(&link->s_node, &supplier->links.consumers); 2739ed98953SRafael J. Wysocki list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); 2749ed98953SRafael J. Wysocki 2759ed98953SRafael J. Wysocki dev_info(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); 2769ed98953SRafael J. Wysocki 2779ed98953SRafael J. Wysocki out: 2789ed98953SRafael J. Wysocki device_pm_unlock(); 2799ed98953SRafael J. Wysocki device_links_write_unlock(); 2809ed98953SRafael J. Wysocki return link; 2819ed98953SRafael J. Wysocki } 2829ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_add); 2839ed98953SRafael J. Wysocki 2849ed98953SRafael J. Wysocki static void device_link_free(struct device_link *link) 2859ed98953SRafael J. Wysocki { 2869ed98953SRafael J. Wysocki put_device(link->consumer); 2879ed98953SRafael J. Wysocki put_device(link->supplier); 2889ed98953SRafael J. Wysocki kfree(link); 2899ed98953SRafael J. Wysocki } 2909ed98953SRafael J. Wysocki 2919ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 2929ed98953SRafael J. Wysocki static void __device_link_free_srcu(struct rcu_head *rhead) 2939ed98953SRafael J. Wysocki { 2949ed98953SRafael J. Wysocki device_link_free(container_of(rhead, struct device_link, rcu_head)); 2959ed98953SRafael J. Wysocki } 2969ed98953SRafael J. Wysocki 2979ed98953SRafael J. Wysocki static void __device_link_del(struct device_link *link) 2989ed98953SRafael J. Wysocki { 2999ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3009ed98953SRafael J. Wysocki dev_name(link->supplier)); 3019ed98953SRafael J. Wysocki 302baa8809fSRafael J. Wysocki if (link->flags & DL_FLAG_PM_RUNTIME) 303baa8809fSRafael J. Wysocki pm_runtime_drop_link(link->consumer); 304baa8809fSRafael J. Wysocki 3059ed98953SRafael J. Wysocki list_del_rcu(&link->s_node); 3069ed98953SRafael J. Wysocki list_del_rcu(&link->c_node); 3079ed98953SRafael J. Wysocki call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); 3089ed98953SRafael J. Wysocki } 3099ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 3109ed98953SRafael J. Wysocki static void __device_link_del(struct device_link *link) 3119ed98953SRafael J. Wysocki { 3129ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3139ed98953SRafael J. Wysocki dev_name(link->supplier)); 3149ed98953SRafael J. Wysocki 3159ed98953SRafael J. Wysocki list_del(&link->s_node); 3169ed98953SRafael J. Wysocki list_del(&link->c_node); 3179ed98953SRafael J. Wysocki device_link_free(link); 3189ed98953SRafael J. Wysocki } 3199ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 3209ed98953SRafael J. Wysocki 3219ed98953SRafael J. Wysocki /** 3229ed98953SRafael J. Wysocki * device_link_del - Delete a link between two devices. 3239ed98953SRafael J. Wysocki * @link: Device link to delete. 3249ed98953SRafael J. Wysocki * 3259ed98953SRafael J. Wysocki * The caller must ensure proper synchronization of this function with runtime 3269ed98953SRafael J. Wysocki * PM. 3279ed98953SRafael J. Wysocki */ 3289ed98953SRafael J. Wysocki void device_link_del(struct device_link *link) 3299ed98953SRafael J. Wysocki { 3309ed98953SRafael J. Wysocki device_links_write_lock(); 3319ed98953SRafael J. Wysocki device_pm_lock(); 3329ed98953SRafael J. Wysocki __device_link_del(link); 3339ed98953SRafael J. Wysocki device_pm_unlock(); 3349ed98953SRafael J. Wysocki device_links_write_unlock(); 3359ed98953SRafael J. Wysocki } 3369ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_del); 3379ed98953SRafael J. Wysocki 3389ed98953SRafael J. Wysocki static void device_links_missing_supplier(struct device *dev) 3399ed98953SRafael J. Wysocki { 3409ed98953SRafael J. Wysocki struct device_link *link; 3419ed98953SRafael J. Wysocki 3429ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) 3439ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE) 3449ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 3459ed98953SRafael J. Wysocki } 3469ed98953SRafael J. Wysocki 3479ed98953SRafael J. Wysocki /** 3489ed98953SRafael J. Wysocki * device_links_check_suppliers - Check presence of supplier drivers. 3499ed98953SRafael J. Wysocki * @dev: Consumer device. 3509ed98953SRafael J. Wysocki * 3519ed98953SRafael J. Wysocki * Check links from this device to any suppliers. Walk the list of the device's 3529ed98953SRafael J. Wysocki * links to suppliers and see if all of them are available. If not, simply 3539ed98953SRafael J. Wysocki * return -EPROBE_DEFER. 3549ed98953SRafael J. Wysocki * 3559ed98953SRafael J. Wysocki * We need to guarantee that the supplier will not go away after the check has 3569ed98953SRafael J. Wysocki * been positive here. It only can go away in __device_release_driver() and 3579ed98953SRafael J. Wysocki * that function checks the device's links to consumers. This means we need to 3589ed98953SRafael J. Wysocki * mark the link as "consumer probe in progress" to make the supplier removal 3599ed98953SRafael J. Wysocki * wait for us to complete (or bad things may happen). 3609ed98953SRafael J. Wysocki * 3619ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 3629ed98953SRafael J. Wysocki */ 3639ed98953SRafael J. Wysocki int device_links_check_suppliers(struct device *dev) 3649ed98953SRafael J. Wysocki { 3659ed98953SRafael J. Wysocki struct device_link *link; 3669ed98953SRafael J. Wysocki int ret = 0; 3679ed98953SRafael J. Wysocki 3689ed98953SRafael J. Wysocki device_links_write_lock(); 3699ed98953SRafael J. Wysocki 3709ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 3719ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 3729ed98953SRafael J. Wysocki continue; 3739ed98953SRafael J. Wysocki 3749ed98953SRafael J. Wysocki if (link->status != DL_STATE_AVAILABLE) { 3759ed98953SRafael J. Wysocki device_links_missing_supplier(dev); 3769ed98953SRafael J. Wysocki ret = -EPROBE_DEFER; 3779ed98953SRafael J. Wysocki break; 3789ed98953SRafael J. Wysocki } 3799ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_CONSUMER_PROBE); 3809ed98953SRafael J. Wysocki } 3819ed98953SRafael J. Wysocki dev->links.status = DL_DEV_PROBING; 3829ed98953SRafael J. Wysocki 3839ed98953SRafael J. Wysocki device_links_write_unlock(); 3849ed98953SRafael J. Wysocki return ret; 3859ed98953SRafael J. Wysocki } 3869ed98953SRafael J. Wysocki 3879ed98953SRafael J. Wysocki /** 3889ed98953SRafael J. Wysocki * device_links_driver_bound - Update device links after probing its driver. 3899ed98953SRafael J. Wysocki * @dev: Device to update the links for. 3909ed98953SRafael J. Wysocki * 3919ed98953SRafael J. Wysocki * The probe has been successful, so update links from this device to any 3929ed98953SRafael J. Wysocki * consumers by changing their status to "available". 3939ed98953SRafael J. Wysocki * 3949ed98953SRafael J. Wysocki * Also change the status of @dev's links to suppliers to "active". 3959ed98953SRafael J. Wysocki * 3969ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 3979ed98953SRafael J. Wysocki */ 3989ed98953SRafael J. Wysocki void device_links_driver_bound(struct device *dev) 3999ed98953SRafael J. Wysocki { 4009ed98953SRafael J. Wysocki struct device_link *link; 4019ed98953SRafael J. Wysocki 4029ed98953SRafael J. Wysocki device_links_write_lock(); 4039ed98953SRafael J. Wysocki 4049ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 4059ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4069ed98953SRafael J. Wysocki continue; 4079ed98953SRafael J. Wysocki 4089ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT); 4099ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4109ed98953SRafael J. Wysocki } 4119ed98953SRafael J. Wysocki 4129ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 4139ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4149ed98953SRafael J. Wysocki continue; 4159ed98953SRafael J. Wysocki 4169ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); 4179ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_ACTIVE); 4189ed98953SRafael J. Wysocki } 4199ed98953SRafael J. Wysocki 4209ed98953SRafael J. Wysocki dev->links.status = DL_DEV_DRIVER_BOUND; 4219ed98953SRafael J. Wysocki 4229ed98953SRafael J. Wysocki device_links_write_unlock(); 4239ed98953SRafael J. Wysocki } 4249ed98953SRafael J. Wysocki 4259ed98953SRafael J. Wysocki /** 4269ed98953SRafael J. Wysocki * __device_links_no_driver - Update links of a device without a driver. 4279ed98953SRafael J. Wysocki * @dev: Device without a drvier. 4289ed98953SRafael J. Wysocki * 4299ed98953SRafael J. Wysocki * Delete all non-persistent links from this device to any suppliers. 4309ed98953SRafael J. Wysocki * 4319ed98953SRafael J. Wysocki * Persistent links stay around, but their status is changed to "available", 4329ed98953SRafael J. Wysocki * unless they already are in the "supplier unbind in progress" state in which 4339ed98953SRafael J. Wysocki * case they need not be updated. 4349ed98953SRafael J. Wysocki * 4359ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4369ed98953SRafael J. Wysocki */ 4379ed98953SRafael J. Wysocki static void __device_links_no_driver(struct device *dev) 4389ed98953SRafael J. Wysocki { 4399ed98953SRafael J. Wysocki struct device_link *link, *ln; 4409ed98953SRafael J. Wysocki 4419ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 4429ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4439ed98953SRafael J. Wysocki continue; 4449ed98953SRafael J. Wysocki 4459ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_AUTOREMOVE) 4469ed98953SRafael J. Wysocki __device_link_del(link); 4479ed98953SRafael J. Wysocki else if (link->status != DL_STATE_SUPPLIER_UNBIND) 4489ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4499ed98953SRafael J. Wysocki } 4509ed98953SRafael J. Wysocki 4519ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 4529ed98953SRafael J. Wysocki } 4539ed98953SRafael J. Wysocki 4549ed98953SRafael J. Wysocki void device_links_no_driver(struct device *dev) 4559ed98953SRafael J. Wysocki { 4569ed98953SRafael J. Wysocki device_links_write_lock(); 4579ed98953SRafael J. Wysocki __device_links_no_driver(dev); 4589ed98953SRafael J. Wysocki device_links_write_unlock(); 4599ed98953SRafael J. Wysocki } 4609ed98953SRafael J. Wysocki 4619ed98953SRafael J. Wysocki /** 4629ed98953SRafael J. Wysocki * device_links_driver_cleanup - Update links after driver removal. 4639ed98953SRafael J. Wysocki * @dev: Device whose driver has just gone away. 4649ed98953SRafael J. Wysocki * 4659ed98953SRafael J. Wysocki * Update links to consumers for @dev by changing their status to "dormant" and 4669ed98953SRafael J. Wysocki * invoke %__device_links_no_driver() to update links to suppliers for it as 4679ed98953SRafael J. Wysocki * appropriate. 4689ed98953SRafael J. Wysocki * 4699ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4709ed98953SRafael J. Wysocki */ 4719ed98953SRafael J. Wysocki void device_links_driver_cleanup(struct device *dev) 4729ed98953SRafael J. Wysocki { 4739ed98953SRafael J. Wysocki struct device_link *link; 4749ed98953SRafael J. Wysocki 4759ed98953SRafael J. Wysocki device_links_write_lock(); 4769ed98953SRafael J. Wysocki 4779ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 4789ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4799ed98953SRafael J. Wysocki continue; 4809ed98953SRafael J. Wysocki 4819ed98953SRafael J. Wysocki WARN_ON(link->flags & DL_FLAG_AUTOREMOVE); 4829ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND); 4839ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_DORMANT); 4849ed98953SRafael J. Wysocki } 4859ed98953SRafael J. Wysocki 4869ed98953SRafael J. Wysocki __device_links_no_driver(dev); 4879ed98953SRafael J. Wysocki 4889ed98953SRafael J. Wysocki device_links_write_unlock(); 4899ed98953SRafael J. Wysocki } 4909ed98953SRafael J. Wysocki 4919ed98953SRafael J. Wysocki /** 4929ed98953SRafael J. Wysocki * device_links_busy - Check if there are any busy links to consumers. 4939ed98953SRafael J. Wysocki * @dev: Device to check. 4949ed98953SRafael J. Wysocki * 4959ed98953SRafael J. Wysocki * Check each consumer of the device and return 'true' if its link's status 4969ed98953SRafael J. Wysocki * is one of "consumer probe" or "active" (meaning that the given consumer is 4979ed98953SRafael J. Wysocki * probing right now or its driver is present). Otherwise, change the link 4989ed98953SRafael J. Wysocki * state to "supplier unbind" to prevent the consumer from being probed 4999ed98953SRafael J. Wysocki * successfully going forward. 5009ed98953SRafael J. Wysocki * 5019ed98953SRafael J. Wysocki * Return 'false' if there are no probing or active consumers. 5029ed98953SRafael J. Wysocki * 5039ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5049ed98953SRafael J. Wysocki */ 5059ed98953SRafael J. Wysocki bool device_links_busy(struct device *dev) 5069ed98953SRafael J. Wysocki { 5079ed98953SRafael J. Wysocki struct device_link *link; 5089ed98953SRafael J. Wysocki bool ret = false; 5099ed98953SRafael J. Wysocki 5109ed98953SRafael J. Wysocki device_links_write_lock(); 5119ed98953SRafael J. Wysocki 5129ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5139ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5149ed98953SRafael J. Wysocki continue; 5159ed98953SRafael J. Wysocki 5169ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE 5179ed98953SRafael J. Wysocki || link->status == DL_STATE_ACTIVE) { 5189ed98953SRafael J. Wysocki ret = true; 5199ed98953SRafael J. Wysocki break; 5209ed98953SRafael J. Wysocki } 5219ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 5229ed98953SRafael J. Wysocki } 5239ed98953SRafael J. Wysocki 5249ed98953SRafael J. Wysocki dev->links.status = DL_DEV_UNBINDING; 5259ed98953SRafael J. Wysocki 5269ed98953SRafael J. Wysocki device_links_write_unlock(); 5279ed98953SRafael J. Wysocki return ret; 5289ed98953SRafael J. Wysocki } 5299ed98953SRafael J. Wysocki 5309ed98953SRafael J. Wysocki /** 5319ed98953SRafael J. Wysocki * device_links_unbind_consumers - Force unbind consumers of the given device. 5329ed98953SRafael J. Wysocki * @dev: Device to unbind the consumers of. 5339ed98953SRafael J. Wysocki * 5349ed98953SRafael J. Wysocki * Walk the list of links to consumers for @dev and if any of them is in the 5359ed98953SRafael J. Wysocki * "consumer probe" state, wait for all device probes in progress to complete 5369ed98953SRafael J. Wysocki * and start over. 5379ed98953SRafael J. Wysocki * 5389ed98953SRafael J. Wysocki * If that's not the case, change the status of the link to "supplier unbind" 5399ed98953SRafael J. Wysocki * and check if the link was in the "active" state. If so, force the consumer 5409ed98953SRafael J. Wysocki * driver to unbind and start over (the consumer will not re-probe as we have 5419ed98953SRafael J. Wysocki * changed the state of the link already). 5429ed98953SRafael J. Wysocki * 5439ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5449ed98953SRafael J. Wysocki */ 5459ed98953SRafael J. Wysocki void device_links_unbind_consumers(struct device *dev) 5469ed98953SRafael J. Wysocki { 5479ed98953SRafael J. Wysocki struct device_link *link; 5489ed98953SRafael J. Wysocki 5499ed98953SRafael J. Wysocki start: 5509ed98953SRafael J. Wysocki device_links_write_lock(); 5519ed98953SRafael J. Wysocki 5529ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5539ed98953SRafael J. Wysocki enum device_link_state status; 5549ed98953SRafael J. Wysocki 5559ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5569ed98953SRafael J. Wysocki continue; 5579ed98953SRafael J. Wysocki 5589ed98953SRafael J. Wysocki status = link->status; 5599ed98953SRafael J. Wysocki if (status == DL_STATE_CONSUMER_PROBE) { 5609ed98953SRafael J. Wysocki device_links_write_unlock(); 5619ed98953SRafael J. Wysocki 5629ed98953SRafael J. Wysocki wait_for_device_probe(); 5639ed98953SRafael J. Wysocki goto start; 5649ed98953SRafael J. Wysocki } 5659ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 5669ed98953SRafael J. Wysocki if (status == DL_STATE_ACTIVE) { 5679ed98953SRafael J. Wysocki struct device *consumer = link->consumer; 5689ed98953SRafael J. Wysocki 5699ed98953SRafael J. Wysocki get_device(consumer); 5709ed98953SRafael J. Wysocki 5719ed98953SRafael J. Wysocki device_links_write_unlock(); 5729ed98953SRafael J. Wysocki 5739ed98953SRafael J. Wysocki device_release_driver_internal(consumer, NULL, 5749ed98953SRafael J. Wysocki consumer->parent); 5759ed98953SRafael J. Wysocki put_device(consumer); 5769ed98953SRafael J. Wysocki goto start; 5779ed98953SRafael J. Wysocki } 5789ed98953SRafael J. Wysocki } 5799ed98953SRafael J. Wysocki 5809ed98953SRafael J. Wysocki device_links_write_unlock(); 5819ed98953SRafael J. Wysocki } 5829ed98953SRafael J. Wysocki 5839ed98953SRafael J. Wysocki /** 5849ed98953SRafael J. Wysocki * device_links_purge - Delete existing links to other devices. 5859ed98953SRafael J. Wysocki * @dev: Target device. 5869ed98953SRafael J. Wysocki */ 5879ed98953SRafael J. Wysocki static void device_links_purge(struct device *dev) 5889ed98953SRafael J. Wysocki { 5899ed98953SRafael J. Wysocki struct device_link *link, *ln; 5909ed98953SRafael J. Wysocki 5919ed98953SRafael J. Wysocki /* 5929ed98953SRafael J. Wysocki * Delete all of the remaining links from this device to any other 5939ed98953SRafael J. Wysocki * devices (either consumers or suppliers). 5949ed98953SRafael J. Wysocki */ 5959ed98953SRafael J. Wysocki device_links_write_lock(); 5969ed98953SRafael J. Wysocki 5979ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 5989ed98953SRafael J. Wysocki WARN_ON(link->status == DL_STATE_ACTIVE); 5999ed98953SRafael J. Wysocki __device_link_del(link); 6009ed98953SRafael J. Wysocki } 6019ed98953SRafael J. Wysocki 6029ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) { 6039ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT && 6049ed98953SRafael J. Wysocki link->status != DL_STATE_NONE); 6059ed98953SRafael J. Wysocki __device_link_del(link); 6069ed98953SRafael J. Wysocki } 6079ed98953SRafael J. Wysocki 6089ed98953SRafael J. Wysocki device_links_write_unlock(); 6099ed98953SRafael J. Wysocki } 6109ed98953SRafael J. Wysocki 6119ed98953SRafael J. Wysocki /* Device links support end. */ 6129ed98953SRafael J. Wysocki 6131da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 6141da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 615e105b8bfSDan Williams static struct kobject *dev_kobj; 616e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 617e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 6181da177e4SLinus Torvalds 6195e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 6205e33bc41SRafael J. Wysocki 6215e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 6225e33bc41SRafael J. Wysocki { 6235e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 6245e33bc41SRafael J. Wysocki } 6255e33bc41SRafael J. Wysocki 6265e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 6275e33bc41SRafael J. Wysocki { 6285e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 6295e33bc41SRafael J. Wysocki } 6305e33bc41SRafael J. Wysocki 6315e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 6325e33bc41SRafael J. Wysocki { 6335e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 6345e33bc41SRafael J. Wysocki return 0; 6355e33bc41SRafael J. Wysocki 6365e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 6375e33bc41SRafael J. Wysocki msleep(5); 6385e33bc41SRafael J. Wysocki return restart_syscall(); 6395e33bc41SRafael J. Wysocki } 6405e33bc41SRafael J. Wysocki 6414e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 6424e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6434e886c29SGreg Kroah-Hartman { 6444e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 6454e886c29SGreg Kroah-Hartman } 6464e886c29SGreg Kroah-Hartman #else 6474e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6484e886c29SGreg Kroah-Hartman { 6494e886c29SGreg Kroah-Hartman return 1; 6504e886c29SGreg Kroah-Hartman } 6514e886c29SGreg Kroah-Hartman #endif 6521da177e4SLinus Torvalds 6533e95637aSAlan Stern /** 6543e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 6553e95637aSAlan Stern * @dev: struct device to get the name of 6563e95637aSAlan Stern * 6573e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 6589169c012Syan * the device is not bound to a driver, it will return the name of the bus 6593e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 6603e95637aSAlan Stern * string will be returned. 6613e95637aSAlan Stern */ 662bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 6633e95637aSAlan Stern { 6643589972eSAlan Stern struct device_driver *drv; 6653589972eSAlan Stern 6663589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 6673589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 6683589972eSAlan Stern * never change once they are set, so they don't need special care. 6693589972eSAlan Stern */ 6703589972eSAlan Stern drv = ACCESS_ONCE(dev->driver); 6713589972eSAlan Stern return drv ? drv->name : 672a456b702SJean Delvare (dev->bus ? dev->bus->name : 673a456b702SJean Delvare (dev->class ? dev->class->name : "")); 6743e95637aSAlan Stern } 675310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 6763e95637aSAlan Stern 6771da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 6781da177e4SLinus Torvalds 6794a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 6804a3ad20cSGreg Kroah-Hartman char *buf) 6811da177e4SLinus Torvalds { 6821da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 683b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 6844a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds if (dev_attr->show) 68754b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 688815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 68953a9c87eSGreg Kroah-Hartman print_symbol("dev_attr_show: %s returned bad count\n", 69053a9c87eSGreg Kroah-Hartman (unsigned long)dev_attr->show); 691815d2d50SAndrew Morton } 6921da177e4SLinus Torvalds return ret; 6931da177e4SLinus Torvalds } 6941da177e4SLinus Torvalds 6954a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 6961da177e4SLinus Torvalds const char *buf, size_t count) 6971da177e4SLinus Torvalds { 6981da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 699b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 7004a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 7011da177e4SLinus Torvalds 7021da177e4SLinus Torvalds if (dev_attr->store) 70354b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 7041da177e4SLinus Torvalds return ret; 7051da177e4SLinus Torvalds } 7061da177e4SLinus Torvalds 70752cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 7081da177e4SLinus Torvalds .show = dev_attr_show, 7091da177e4SLinus Torvalds .store = dev_attr_store, 7101da177e4SLinus Torvalds }; 7111da177e4SLinus Torvalds 712ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 713ca22e56dSKay Sievers 714ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 715ca22e56dSKay Sievers struct device_attribute *attr, 716ca22e56dSKay Sievers const char *buf, size_t size) 717ca22e56dSKay Sievers { 718ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 719ca22e56dSKay Sievers char *end; 720ca22e56dSKay Sievers unsigned long new = simple_strtoul(buf, &end, 0); 721ca22e56dSKay Sievers if (end == buf) 722ca22e56dSKay Sievers return -EINVAL; 723ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 724ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 725ca22e56dSKay Sievers return size; 726ca22e56dSKay Sievers } 727ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 728ca22e56dSKay Sievers 729ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 730ca22e56dSKay Sievers struct device_attribute *attr, 731ca22e56dSKay Sievers char *buf) 732ca22e56dSKay Sievers { 733ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 734ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); 735ca22e56dSKay Sievers } 736ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 737ca22e56dSKay Sievers 738ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 739ca22e56dSKay Sievers struct device_attribute *attr, 740ca22e56dSKay Sievers const char *buf, size_t size) 741ca22e56dSKay Sievers { 742ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 743ca22e56dSKay Sievers char *end; 744ca22e56dSKay Sievers long new = simple_strtol(buf, &end, 0); 745ca22e56dSKay Sievers if (end == buf || new > INT_MAX || new < INT_MIN) 746ca22e56dSKay Sievers return -EINVAL; 747ca22e56dSKay Sievers *(int *)(ea->var) = new; 748ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 749ca22e56dSKay Sievers return size; 750ca22e56dSKay Sievers } 751ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 752ca22e56dSKay Sievers 753ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 754ca22e56dSKay Sievers struct device_attribute *attr, 755ca22e56dSKay Sievers char *buf) 756ca22e56dSKay Sievers { 757ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 758ca22e56dSKay Sievers 759ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); 760ca22e56dSKay Sievers } 761ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 7621da177e4SLinus Torvalds 76391872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 76491872392SBorislav Petkov const char *buf, size_t size) 76591872392SBorislav Petkov { 76691872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 76791872392SBorislav Petkov 76891872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 76991872392SBorislav Petkov return -EINVAL; 77091872392SBorislav Petkov 77191872392SBorislav Petkov return size; 77291872392SBorislav Petkov } 77391872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 77491872392SBorislav Petkov 77591872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 77691872392SBorislav Petkov char *buf) 77791872392SBorislav Petkov { 77891872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 77991872392SBorislav Petkov 78091872392SBorislav Petkov return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); 78191872392SBorislav Petkov } 78291872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 78391872392SBorislav Petkov 7841da177e4SLinus Torvalds /** 7851da177e4SLinus Torvalds * device_release - free device structure. 7861da177e4SLinus Torvalds * @kobj: device's kobject. 7871da177e4SLinus Torvalds * 7881da177e4SLinus Torvalds * This is called once the reference count for the object 7891da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 7901da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 7911da177e4SLinus Torvalds */ 7921da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 7931da177e4SLinus Torvalds { 794b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 795fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 7961da177e4SLinus Torvalds 797a525a3ddSMing Lei /* 798a525a3ddSMing Lei * Some platform devices are driven without driver attached 799a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 800a525a3ddSMing Lei * all resources are released. 801a525a3ddSMing Lei * 802a525a3ddSMing Lei * Drivers still can add resources into device after device 803a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 804a525a3ddSMing Lei * possible memory leak. 805a525a3ddSMing Lei */ 806a525a3ddSMing Lei devres_release_all(dev); 807a525a3ddSMing Lei 8081da177e4SLinus Torvalds if (dev->release) 8091da177e4SLinus Torvalds dev->release(dev); 810f9f852dfSKay Sievers else if (dev->type && dev->type->release) 811f9f852dfSKay Sievers dev->type->release(dev); 8122620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 8132620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 814f810a5cfSArjan van de Ven else 815f810a5cfSArjan van de Ven WARN(1, KERN_ERR "Device '%s' does not have a release() " 8164a3ad20cSGreg Kroah-Hartman "function, it is broken and must be fixed.\n", 8171e0b2cf9SKay Sievers dev_name(dev)); 818fb069a5dSGreg Kroah-Hartman kfree(p); 8191da177e4SLinus Torvalds } 8201da177e4SLinus Torvalds 821bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 822bc451f20SEric W. Biederman { 823b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 824bc451f20SEric W. Biederman const void *ns = NULL; 825bc451f20SEric W. Biederman 826bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 827bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 828bc451f20SEric W. Biederman 829bc451f20SEric W. Biederman return ns; 830bc451f20SEric W. Biederman } 831bc451f20SEric W. Biederman 8328f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 8331da177e4SLinus Torvalds .release = device_release, 8341da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 835bc451f20SEric W. Biederman .namespace = device_namespace, 8361da177e4SLinus Torvalds }; 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds 839312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 8401da177e4SLinus Torvalds { 8411da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 8421da177e4SLinus Torvalds 8438f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 844b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8451da177e4SLinus Torvalds if (dev->bus) 8461da177e4SLinus Torvalds return 1; 84723681e47SGreg Kroah-Hartman if (dev->class) 84823681e47SGreg Kroah-Hartman return 1; 8491da177e4SLinus Torvalds } 8501da177e4SLinus Torvalds return 0; 8511da177e4SLinus Torvalds } 8521da177e4SLinus Torvalds 853312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 8541da177e4SLinus Torvalds { 855b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8561da177e4SLinus Torvalds 85723681e47SGreg Kroah-Hartman if (dev->bus) 8581da177e4SLinus Torvalds return dev->bus->name; 85923681e47SGreg Kroah-Hartman if (dev->class) 86023681e47SGreg Kroah-Hartman return dev->class->name; 86123681e47SGreg Kroah-Hartman return NULL; 8621da177e4SLinus Torvalds } 8631da177e4SLinus Torvalds 8647eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 8657eff2e7aSKay Sievers struct kobj_uevent_env *env) 8661da177e4SLinus Torvalds { 867b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8681da177e4SLinus Torvalds int retval = 0; 8691da177e4SLinus Torvalds 8706fcf53acSKay Sievers /* add device node properties if present */ 87123681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 8726fcf53acSKay Sievers const char *tmp; 8736fcf53acSKay Sievers const char *name; 8742c9ede55SAl Viro umode_t mode = 0; 8754e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 8764e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 8776fcf53acSKay Sievers 8787eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 8797eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 8803c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 8816fcf53acSKay Sievers if (name) { 8826fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 883e454cea2SKay Sievers if (mode) 884e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 8854e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 8864e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 8874e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 8884e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 8893c2670e6SKay Sievers kfree(tmp); 8906fcf53acSKay Sievers } 89123681e47SGreg Kroah-Hartman } 89223681e47SGreg Kroah-Hartman 893414264f9SKay Sievers if (dev->type && dev->type->name) 8947eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 895414264f9SKay Sievers 896239378f1SKay Sievers if (dev->driver) 8977eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 898239378f1SKay Sievers 89907d57a32SGrant Likely /* Add common DT information about the device */ 90007d57a32SGrant Likely of_device_uevent(dev, env); 90107d57a32SGrant Likely 9021da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 9037eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 9047eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 905f9f852dfSKay Sievers if (retval) 9067dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 9071e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 9081da177e4SLinus Torvalds } 9091da177e4SLinus Torvalds 9102620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 9117eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 9127eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 913f9f852dfSKay Sievers if (retval) 9147dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 9151e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9162b3a302aSHarvey Harrison __func__, retval); 9172620efefSGreg Kroah-Hartman } 918f9f852dfSKay Sievers 919eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 9207eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 9217eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 922f9f852dfSKay Sievers if (retval) 9237dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 9241e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9252b3a302aSHarvey Harrison __func__, retval); 9262620efefSGreg Kroah-Hartman } 9272620efefSGreg Kroah-Hartman 9281da177e4SLinus Torvalds return retval; 9291da177e4SLinus Torvalds } 9301da177e4SLinus Torvalds 9319cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 932312c004dSKay Sievers .filter = dev_uevent_filter, 933312c004dSKay Sievers .name = dev_uevent_name, 934312c004dSKay Sievers .uevent = dev_uevent, 9351da177e4SLinus Torvalds }; 9361da177e4SLinus Torvalds 937c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 93816574dccSKay Sievers char *buf) 93916574dccSKay Sievers { 94016574dccSKay Sievers struct kobject *top_kobj; 94116574dccSKay Sievers struct kset *kset; 9427eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 94316574dccSKay Sievers int i; 94416574dccSKay Sievers size_t count = 0; 94516574dccSKay Sievers int retval; 94616574dccSKay Sievers 94716574dccSKay Sievers /* search the kset, the device belongs to */ 94816574dccSKay Sievers top_kobj = &dev->kobj; 9495c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 95016574dccSKay Sievers top_kobj = top_kobj->parent; 95116574dccSKay Sievers if (!top_kobj->kset) 95216574dccSKay Sievers goto out; 9535c5daf65SKay Sievers 95416574dccSKay Sievers kset = top_kobj->kset; 95516574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 95616574dccSKay Sievers goto out; 95716574dccSKay Sievers 95816574dccSKay Sievers /* respect filter */ 95916574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 96016574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 96116574dccSKay Sievers goto out; 96216574dccSKay Sievers 9637eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 9647eff2e7aSKay Sievers if (!env) 965c7308c81SGreg Kroah-Hartman return -ENOMEM; 966c7308c81SGreg Kroah-Hartman 96716574dccSKay Sievers /* let the kset specific function add its keys */ 9687eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 96916574dccSKay Sievers if (retval) 97016574dccSKay Sievers goto out; 97116574dccSKay Sievers 97216574dccSKay Sievers /* copy keys to file */ 9737eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 9747eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 97516574dccSKay Sievers out: 9767eff2e7aSKay Sievers kfree(env); 97716574dccSKay Sievers return count; 97816574dccSKay Sievers } 97916574dccSKay Sievers 980c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 981a7fd6706SKay Sievers const char *buf, size_t count) 982a7fd6706SKay Sievers { 98360a96a59SKay Sievers enum kobject_action action; 98460a96a59SKay Sievers 9853f5468c9SKay Sievers if (kobject_action_type(buf, count, &action) == 0) 98660a96a59SKay Sievers kobject_uevent(&dev->kobj, action); 9873f5468c9SKay Sievers else 9883f5468c9SKay Sievers dev_err(dev, "uevent: unknown action-string\n"); 989a7fd6706SKay Sievers return count; 990a7fd6706SKay Sievers } 991c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 992a7fd6706SKay Sievers 993c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 9944f3549d7SRafael J. Wysocki char *buf) 9954f3549d7SRafael J. Wysocki { 9964f3549d7SRafael J. Wysocki bool val; 9974f3549d7SRafael J. Wysocki 9985e33bc41SRafael J. Wysocki device_lock(dev); 9994f3549d7SRafael J. Wysocki val = !dev->offline; 10005e33bc41SRafael J. Wysocki device_unlock(dev); 10014f3549d7SRafael J. Wysocki return sprintf(buf, "%u\n", val); 10024f3549d7SRafael J. Wysocki } 10034f3549d7SRafael J. Wysocki 1004c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 10054f3549d7SRafael J. Wysocki const char *buf, size_t count) 10064f3549d7SRafael J. Wysocki { 10074f3549d7SRafael J. Wysocki bool val; 10084f3549d7SRafael J. Wysocki int ret; 10094f3549d7SRafael J. Wysocki 10104f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 10114f3549d7SRafael J. Wysocki if (ret < 0) 10124f3549d7SRafael J. Wysocki return ret; 10134f3549d7SRafael J. Wysocki 10145e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 10155e33bc41SRafael J. Wysocki if (ret) 10165e33bc41SRafael J. Wysocki return ret; 10175e33bc41SRafael J. Wysocki 10184f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 10194f3549d7SRafael J. Wysocki unlock_device_hotplug(); 10204f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 10214f3549d7SRafael J. Wysocki } 1022c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 10234f3549d7SRafael J. Wysocki 1024fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 1025621a1672SDmitry Torokhov { 10263e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 1027621a1672SDmitry Torokhov } 1028621a1672SDmitry Torokhov 1029fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 1030a4dbd674SDavid Brownell const struct attribute_group **groups) 1031621a1672SDmitry Torokhov { 10323e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 1033621a1672SDmitry Torokhov } 1034de0ff00dSGreg Kroah-Hartman 10352620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 10362620efefSGreg Kroah-Hartman { 10372620efefSGreg Kroah-Hartman struct class *class = dev->class; 1038aed65af1SStephen Hemminger const struct device_type *type = dev->type; 1039621a1672SDmitry Torokhov int error; 10402620efefSGreg Kroah-Hartman 1041621a1672SDmitry Torokhov if (class) { 1042d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 10432620efefSGreg Kroah-Hartman if (error) 1044621a1672SDmitry Torokhov return error; 1045f9f852dfSKay Sievers } 1046f9f852dfSKay Sievers 1047621a1672SDmitry Torokhov if (type) { 1048621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 1049f9f852dfSKay Sievers if (error) 1050a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 1051f9f852dfSKay Sievers } 1052621a1672SDmitry Torokhov 1053621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 1054f9f852dfSKay Sievers if (error) 1055621a1672SDmitry Torokhov goto err_remove_type_groups; 1056621a1672SDmitry Torokhov 10574f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 1058c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 10594f3549d7SRafael J. Wysocki if (error) 1060ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 10614f3549d7SRafael J. Wysocki } 10624f3549d7SRafael J. Wysocki 10636751667aSBen Hutchings error = device_create_file(dev, &dev_attr_deferred_probe); 10646751667aSBen Hutchings if (error) 10656751667aSBen Hutchings goto err_remove_online; 10666751667aSBen Hutchings 1067621a1672SDmitry Torokhov return 0; 1068621a1672SDmitry Torokhov 10696751667aSBen Hutchings err_remove_online: 10706751667aSBen Hutchings device_remove_file(dev, &dev_attr_online); 1071ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 1072ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 1073621a1672SDmitry Torokhov err_remove_type_groups: 1074621a1672SDmitry Torokhov if (type) 1075621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1076d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 1077d05a6f96SGreg Kroah-Hartman if (class) 1078d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1079f9f852dfSKay Sievers 10802620efefSGreg Kroah-Hartman return error; 10812620efefSGreg Kroah-Hartman } 10822620efefSGreg Kroah-Hartman 10832620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 10842620efefSGreg Kroah-Hartman { 10852620efefSGreg Kroah-Hartman struct class *class = dev->class; 1086aed65af1SStephen Hemminger const struct device_type *type = dev->type; 10872620efefSGreg Kroah-Hartman 10886751667aSBen Hutchings device_remove_file(dev, &dev_attr_deferred_probe); 1089c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 1090621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 1091f9f852dfSKay Sievers 1092621a1672SDmitry Torokhov if (type) 1093621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1094621a1672SDmitry Torokhov 1095a6b01dedSGreg Kroah-Hartman if (class) 1096d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1097c97415a7SStefan Achatz } 10982620efefSGreg Kroah-Hartman 1099c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 110023681e47SGreg Kroah-Hartman char *buf) 110123681e47SGreg Kroah-Hartman { 110223681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 110323681e47SGreg Kroah-Hartman } 1104c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 1105ad6a1e1cSTejun Heo 1106ca22e56dSKay Sievers /* /sys/devices/ */ 1107881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 11081da177e4SLinus Torvalds 11091da177e4SLinus Torvalds /** 111052cdbdd4SGrygorii Strashko * devices_kset_move_before - Move device in the devices_kset's list. 111152cdbdd4SGrygorii Strashko * @deva: Device to move. 111252cdbdd4SGrygorii Strashko * @devb: Device @deva should come before. 111352cdbdd4SGrygorii Strashko */ 111452cdbdd4SGrygorii Strashko static void devices_kset_move_before(struct device *deva, struct device *devb) 111552cdbdd4SGrygorii Strashko { 111652cdbdd4SGrygorii Strashko if (!devices_kset) 111752cdbdd4SGrygorii Strashko return; 111852cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s before %s\n", 111952cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 112052cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 112152cdbdd4SGrygorii Strashko list_move_tail(&deva->kobj.entry, &devb->kobj.entry); 112252cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 112352cdbdd4SGrygorii Strashko } 112452cdbdd4SGrygorii Strashko 112552cdbdd4SGrygorii Strashko /** 112652cdbdd4SGrygorii Strashko * devices_kset_move_after - Move device in the devices_kset's list. 112752cdbdd4SGrygorii Strashko * @deva: Device to move 112852cdbdd4SGrygorii Strashko * @devb: Device @deva should come after. 112952cdbdd4SGrygorii Strashko */ 113052cdbdd4SGrygorii Strashko static void devices_kset_move_after(struct device *deva, struct device *devb) 113152cdbdd4SGrygorii Strashko { 113252cdbdd4SGrygorii Strashko if (!devices_kset) 113352cdbdd4SGrygorii Strashko return; 113452cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s after %s\n", 113552cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 113652cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 113752cdbdd4SGrygorii Strashko list_move(&deva->kobj.entry, &devb->kobj.entry); 113852cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 113952cdbdd4SGrygorii Strashko } 114052cdbdd4SGrygorii Strashko 114152cdbdd4SGrygorii Strashko /** 114252cdbdd4SGrygorii Strashko * devices_kset_move_last - move the device to the end of devices_kset's list. 114352cdbdd4SGrygorii Strashko * @dev: device to move 114452cdbdd4SGrygorii Strashko */ 114552cdbdd4SGrygorii Strashko void devices_kset_move_last(struct device *dev) 114652cdbdd4SGrygorii Strashko { 114752cdbdd4SGrygorii Strashko if (!devices_kset) 114852cdbdd4SGrygorii Strashko return; 114952cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); 115052cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 115152cdbdd4SGrygorii Strashko list_move_tail(&dev->kobj.entry, &devices_kset->list); 115252cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 115352cdbdd4SGrygorii Strashko } 115452cdbdd4SGrygorii Strashko 115552cdbdd4SGrygorii Strashko /** 11561da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 11571da177e4SLinus Torvalds * @dev: device. 11581da177e4SLinus Torvalds * @attr: device attribute descriptor. 11591da177e4SLinus Torvalds */ 116026579ab7SPhil Carmody int device_create_file(struct device *dev, 116126579ab7SPhil Carmody const struct device_attribute *attr) 11621da177e4SLinus Torvalds { 11631da177e4SLinus Torvalds int error = 0; 11648f46baaaSFelipe Balbi 11658f46baaaSFelipe Balbi if (dev) { 11668f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 116797521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 116897521978Sdyoung@redhat.com attr->attr.name); 11698f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 117097521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 117197521978Sdyoung@redhat.com attr->attr.name); 11721da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 11738f46baaaSFelipe Balbi } 11748f46baaaSFelipe Balbi 11751da177e4SLinus Torvalds return error; 11761da177e4SLinus Torvalds } 117786df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 11781da177e4SLinus Torvalds 11791da177e4SLinus Torvalds /** 11801da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 11811da177e4SLinus Torvalds * @dev: device. 11821da177e4SLinus Torvalds * @attr: device attribute descriptor. 11831da177e4SLinus Torvalds */ 118426579ab7SPhil Carmody void device_remove_file(struct device *dev, 118526579ab7SPhil Carmody const struct device_attribute *attr) 11861da177e4SLinus Torvalds { 11870c98b19fSCornelia Huck if (dev) 11881da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 11891da177e4SLinus Torvalds } 119086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 11911da177e4SLinus Torvalds 11922589f188SGreg Kroah-Hartman /** 11936b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 11946b0afc2aSTejun Heo * @dev: device. 11956b0afc2aSTejun Heo * @attr: device attribute descriptor. 11966b0afc2aSTejun Heo * 11976b0afc2aSTejun Heo * See kernfs_remove_self() for details. 11986b0afc2aSTejun Heo */ 11996b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 12006b0afc2aSTejun Heo const struct device_attribute *attr) 12016b0afc2aSTejun Heo { 12026b0afc2aSTejun Heo if (dev) 12036b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 12046b0afc2aSTejun Heo else 12056b0afc2aSTejun Heo return false; 12066b0afc2aSTejun Heo } 12076b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 12086b0afc2aSTejun Heo 12096b0afc2aSTejun Heo /** 12102589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 12112589f188SGreg Kroah-Hartman * @dev: device. 12122589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 12132589f188SGreg Kroah-Hartman */ 121466ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 121566ecb92bSPhil Carmody const struct bin_attribute *attr) 12162589f188SGreg Kroah-Hartman { 12172589f188SGreg Kroah-Hartman int error = -EINVAL; 12182589f188SGreg Kroah-Hartman if (dev) 12192589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 12202589f188SGreg Kroah-Hartman return error; 12212589f188SGreg Kroah-Hartman } 12222589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 12232589f188SGreg Kroah-Hartman 12242589f188SGreg Kroah-Hartman /** 12252589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 12262589f188SGreg Kroah-Hartman * @dev: device. 12272589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 12282589f188SGreg Kroah-Hartman */ 122966ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 123066ecb92bSPhil Carmody const struct bin_attribute *attr) 12312589f188SGreg Kroah-Hartman { 12322589f188SGreg Kroah-Hartman if (dev) 12332589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 12342589f188SGreg Kroah-Hartman } 12352589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 12362589f188SGreg Kroah-Hartman 123734bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 123834bb61f9SJames Bottomley { 1239f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1240f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 124134bb61f9SJames Bottomley 124234bb61f9SJames Bottomley get_device(dev); 124334bb61f9SJames Bottomley } 124434bb61f9SJames Bottomley 124534bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 124634bb61f9SJames Bottomley { 1247f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1248f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 124934bb61f9SJames Bottomley 125034bb61f9SJames Bottomley put_device(dev); 125134bb61f9SJames Bottomley } 125234bb61f9SJames Bottomley 12531da177e4SLinus Torvalds /** 12541da177e4SLinus Torvalds * device_initialize - init device structure. 12551da177e4SLinus Torvalds * @dev: device. 12561da177e4SLinus Torvalds * 12575739411aSCornelia Huck * This prepares the device for use by other layers by initializing 12585739411aSCornelia Huck * its fields. 12591da177e4SLinus Torvalds * It is the first half of device_register(), if called by 12605739411aSCornelia Huck * that function, though it can also be called separately, so one 12615739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 12625739411aSCornelia Huck * may be used for reference counting of @dev after calling this 12635739411aSCornelia Huck * function. 12645739411aSCornelia Huck * 1265b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 1266b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 1267b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 1268b10d5efdSAlan Stern * @dev. 1269b10d5efdSAlan Stern * 12705739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 12715739411aSCornelia Huck * @dev directly once you have called this function. 12721da177e4SLinus Torvalds */ 12731da177e4SLinus Torvalds void device_initialize(struct device *dev) 12741da177e4SLinus Torvalds { 1275881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 1276f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 12771da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 12783142788bSThomas Gleixner mutex_init(&dev->mutex); 12791704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 12809ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 12819ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 12823b98aeafSAlan Stern device_pm_init(dev); 128387348136SChristoph Hellwig set_dev_node(dev, -1); 12844a7cc831SJiang Liu #ifdef CONFIG_GENERIC_MSI_IRQ 12854a7cc831SJiang Liu INIT_LIST_HEAD(&dev->msi_list); 12864a7cc831SJiang Liu #endif 12879ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.consumers); 12889ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.suppliers); 12899ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 12901da177e4SLinus Torvalds } 129186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 12921da177e4SLinus Torvalds 1293d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 1294f0ee61a6SGreg Kroah-Hartman { 1295f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 1296f0ee61a6SGreg Kroah-Hartman 1297f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 12984ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 1299881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 1300f0ee61a6SGreg Kroah-Hartman 130186406245SKay Sievers return virtual_dir; 1302f0ee61a6SGreg Kroah-Hartman } 1303f0ee61a6SGreg Kroah-Hartman 1304bc451f20SEric W. Biederman struct class_dir { 1305bc451f20SEric W. Biederman struct kobject kobj; 1306bc451f20SEric W. Biederman struct class *class; 1307bc451f20SEric W. Biederman }; 1308bc451f20SEric W. Biederman 1309bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 1310bc451f20SEric W. Biederman 1311bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 1312bc451f20SEric W. Biederman { 1313bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1314bc451f20SEric W. Biederman kfree(dir); 1315bc451f20SEric W. Biederman } 1316bc451f20SEric W. Biederman 1317bc451f20SEric W. Biederman static const 1318bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 1319bc451f20SEric W. Biederman { 1320bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1321bc451f20SEric W. Biederman return dir->class->ns_type; 1322bc451f20SEric W. Biederman } 1323bc451f20SEric W. Biederman 1324bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 1325bc451f20SEric W. Biederman .release = class_dir_release, 1326bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 1327bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 1328bc451f20SEric W. Biederman }; 1329bc451f20SEric W. Biederman 1330bc451f20SEric W. Biederman static struct kobject * 1331bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 1332bc451f20SEric W. Biederman { 1333bc451f20SEric W. Biederman struct class_dir *dir; 1334bc451f20SEric W. Biederman int retval; 1335bc451f20SEric W. Biederman 1336bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 1337bc451f20SEric W. Biederman if (!dir) 1338bc451f20SEric W. Biederman return NULL; 1339bc451f20SEric W. Biederman 1340bc451f20SEric W. Biederman dir->class = class; 1341bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 1342bc451f20SEric W. Biederman 13436b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 1344bc451f20SEric W. Biederman 1345bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 1346bc451f20SEric W. Biederman if (retval < 0) { 1347bc451f20SEric W. Biederman kobject_put(&dir->kobj); 1348bc451f20SEric W. Biederman return NULL; 1349bc451f20SEric W. Biederman } 1350bc451f20SEric W. Biederman return &dir->kobj; 1351bc451f20SEric W. Biederman } 1352bc451f20SEric W. Biederman 1353e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex); 1354bc451f20SEric W. Biederman 1355c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 1356c744aeaeSCornelia Huck struct device *parent) 135740fa5422SGreg Kroah-Hartman { 135886406245SKay Sievers if (dev->class) { 135986406245SKay Sievers struct kobject *kobj = NULL; 136086406245SKay Sievers struct kobject *parent_kobj; 136186406245SKay Sievers struct kobject *k; 136286406245SKay Sievers 1363ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 136439aba963SKay Sievers /* block disks show up in /sys/block */ 1365e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 136639aba963SKay Sievers if (parent && parent->class == &block_class) 136739aba963SKay Sievers return &parent->kobj; 13686b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 136939aba963SKay Sievers } 1370ead454feSRandy Dunlap #endif 1371e52eec13SAndi Kleen 137286406245SKay Sievers /* 137386406245SKay Sievers * If we have no parent, we live in "virtual". 13740f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 13750f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 137686406245SKay Sievers */ 137786406245SKay Sievers if (parent == NULL) 137886406245SKay Sievers parent_kobj = virtual_device_parent(dev); 137924b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 138086406245SKay Sievers return &parent->kobj; 138186406245SKay Sievers else 138286406245SKay Sievers parent_kobj = &parent->kobj; 138386406245SKay Sievers 138477d3d7c1STejun Heo mutex_lock(&gdp_mutex); 138577d3d7c1STejun Heo 138686406245SKay Sievers /* find our class-directory at the parent and reference it */ 13876b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 13886b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 138986406245SKay Sievers if (k->parent == parent_kobj) { 139086406245SKay Sievers kobj = kobject_get(k); 139186406245SKay Sievers break; 139286406245SKay Sievers } 13936b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 139477d3d7c1STejun Heo if (kobj) { 139577d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 139686406245SKay Sievers return kobj; 139777d3d7c1STejun Heo } 139886406245SKay Sievers 139986406245SKay Sievers /* or create a new class-directory at the parent device */ 1400bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 14010f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 140277d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 140343968d2fSGreg Kroah-Hartman return k; 140486406245SKay Sievers } 140586406245SKay Sievers 1406ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 1407ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 1408ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 1409ca22e56dSKay Sievers 141086406245SKay Sievers if (parent) 1411c744aeaeSCornelia Huck return &parent->kobj; 1412c744aeaeSCornelia Huck return NULL; 1413c744aeaeSCornelia Huck } 1414da231fd5SKay Sievers 1415cebf8fd1SMing Lei static inline bool live_in_glue_dir(struct kobject *kobj, 1416cebf8fd1SMing Lei struct device *dev) 1417cebf8fd1SMing Lei { 1418cebf8fd1SMing Lei if (!kobj || !dev->class || 1419cebf8fd1SMing Lei kobj->kset != &dev->class->p->glue_dirs) 1420cebf8fd1SMing Lei return false; 1421cebf8fd1SMing Lei return true; 1422cebf8fd1SMing Lei } 1423cebf8fd1SMing Lei 1424cebf8fd1SMing Lei static inline struct kobject *get_glue_dir(struct device *dev) 1425cebf8fd1SMing Lei { 1426cebf8fd1SMing Lei return dev->kobj.parent; 1427cebf8fd1SMing Lei } 1428cebf8fd1SMing Lei 1429cebf8fd1SMing Lei /* 1430cebf8fd1SMing Lei * make sure cleaning up dir as the last step, we need to make 1431cebf8fd1SMing Lei * sure .release handler of kobject is run with holding the 1432cebf8fd1SMing Lei * global lock 1433cebf8fd1SMing Lei */ 143463b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 1435da231fd5SKay Sievers { 14360f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 1437cebf8fd1SMing Lei if (!live_in_glue_dir(glue_dir, dev)) 1438da231fd5SKay Sievers return; 1439da231fd5SKay Sievers 1440e4a60d13SYijing Wang mutex_lock(&gdp_mutex); 14410f4dafc0SKay Sievers kobject_put(glue_dir); 1442e4a60d13SYijing Wang mutex_unlock(&gdp_mutex); 1443da231fd5SKay Sievers } 144463b6971aSCornelia Huck 14452ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 14462ee97cafSCornelia Huck { 14475590f319SBenjamin Herrenschmidt struct device_node *of_node = dev_of_node(dev); 14482ee97cafSCornelia Huck int error; 14492ee97cafSCornelia Huck 14505590f319SBenjamin Herrenschmidt if (of_node) { 14515590f319SBenjamin Herrenschmidt error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node"); 14525590f319SBenjamin Herrenschmidt if (error) 14535590f319SBenjamin Herrenschmidt dev_warn(dev, "Error %d creating of_node link\n",error); 14545590f319SBenjamin Herrenschmidt /* An error here doesn't warrant bringing down the device */ 14555590f319SBenjamin Herrenschmidt } 14565590f319SBenjamin Herrenschmidt 14572ee97cafSCornelia Huck if (!dev->class) 14582ee97cafSCornelia Huck return 0; 1459da231fd5SKay Sievers 14601fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 14616b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 14622ee97cafSCornelia Huck "subsystem"); 14632ee97cafSCornelia Huck if (error) 14645590f319SBenjamin Herrenschmidt goto out_devnode; 1465da231fd5SKay Sievers 14664e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 14674f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 14684f01a757SDmitry Torokhov "device"); 14694f01a757SDmitry Torokhov if (error) 147039aba963SKay Sievers goto out_subsys; 14712ee97cafSCornelia Huck } 147239aba963SKay Sievers 1473ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 147439aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 1475e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 147639aba963SKay Sievers return 0; 1477ead454feSRandy Dunlap #endif 147839aba963SKay Sievers 147939aba963SKay Sievers /* link in the class directory pointing to the device */ 14806b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 148139aba963SKay Sievers &dev->kobj, dev_name(dev)); 148239aba963SKay Sievers if (error) 148339aba963SKay Sievers goto out_device; 148439aba963SKay Sievers 14852ee97cafSCornelia Huck return 0; 14862ee97cafSCornelia Huck 148739aba963SKay Sievers out_device: 148839aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 1489da231fd5SKay Sievers 14902ee97cafSCornelia Huck out_subsys: 14912ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 14925590f319SBenjamin Herrenschmidt out_devnode: 14935590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 14942ee97cafSCornelia Huck return error; 14952ee97cafSCornelia Huck } 14962ee97cafSCornelia Huck 14972ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 14982ee97cafSCornelia Huck { 14995590f319SBenjamin Herrenschmidt if (dev_of_node(dev)) 15005590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 15015590f319SBenjamin Herrenschmidt 15022ee97cafSCornelia Huck if (!dev->class) 15032ee97cafSCornelia Huck return; 1504da231fd5SKay Sievers 15054e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 1506da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 15072ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 1508ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 1509e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 151039aba963SKay Sievers return; 1511ead454feSRandy Dunlap #endif 15126b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 15132ee97cafSCornelia Huck } 15142ee97cafSCornelia Huck 15151da177e4SLinus Torvalds /** 1516413c239fSStephen Rothwell * dev_set_name - set a device name 1517413c239fSStephen Rothwell * @dev: device 151846232366SRandy Dunlap * @fmt: format string for the device's name 1519413c239fSStephen Rothwell */ 1520413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 1521413c239fSStephen Rothwell { 1522413c239fSStephen Rothwell va_list vargs; 15231fa5ae85SKay Sievers int err; 1524413c239fSStephen Rothwell 1525413c239fSStephen Rothwell va_start(vargs, fmt); 15261fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 1527413c239fSStephen Rothwell va_end(vargs); 15281fa5ae85SKay Sievers return err; 1529413c239fSStephen Rothwell } 1530413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 1531413c239fSStephen Rothwell 1532413c239fSStephen Rothwell /** 1533e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 1534e105b8bfSDan Williams * @dev: device 1535e105b8bfSDan Williams * 1536e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 1537e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 1538e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 1539e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 15400d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 15410d4e293cSPeter Korsgaard * the link. 1542e105b8bfSDan Williams */ 1543e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 1544e105b8bfSDan Williams { 1545e105b8bfSDan Williams struct kobject *kobj; 1546e105b8bfSDan Williams 1547e105b8bfSDan Williams if (dev->class) 1548e105b8bfSDan Williams kobj = dev->class->dev_kobj; 1549e105b8bfSDan Williams else 1550e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 1551e105b8bfSDan Williams 1552e105b8bfSDan Williams return kobj; 1553e105b8bfSDan Williams } 1554e105b8bfSDan Williams 1555e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 1556e105b8bfSDan Williams { 1557e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1558e105b8bfSDan Williams int error = 0; 1559e105b8bfSDan Williams char devt_str[15]; 1560e105b8bfSDan Williams 1561e105b8bfSDan Williams if (kobj) { 1562e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1563e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 1564e105b8bfSDan Williams } 1565e105b8bfSDan Williams 1566e105b8bfSDan Williams return error; 1567e105b8bfSDan Williams } 1568e105b8bfSDan Williams 1569e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 1570e105b8bfSDan Williams { 1571e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1572e105b8bfSDan Williams char devt_str[15]; 1573e105b8bfSDan Williams 1574e105b8bfSDan Williams if (kobj) { 1575e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1576e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 1577e105b8bfSDan Williams } 1578e105b8bfSDan Williams } 1579e105b8bfSDan Williams 1580b4028437SGreg Kroah-Hartman int device_private_init(struct device *dev) 1581b4028437SGreg Kroah-Hartman { 1582b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 1583b4028437SGreg Kroah-Hartman if (!dev->p) 1584b4028437SGreg Kroah-Hartman return -ENOMEM; 1585b4028437SGreg Kroah-Hartman dev->p->device = dev; 1586b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 1587b4028437SGreg Kroah-Hartman klist_children_put); 1588ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 1589b4028437SGreg Kroah-Hartman return 0; 1590b4028437SGreg Kroah-Hartman } 1591b4028437SGreg Kroah-Hartman 1592e105b8bfSDan Williams /** 15931da177e4SLinus Torvalds * device_add - add device to device hierarchy. 15941da177e4SLinus Torvalds * @dev: device. 15951da177e4SLinus Torvalds * 15961da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 15971da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 15981da177e4SLinus Torvalds * 15995739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 16001da177e4SLinus Torvalds * to the global and sibling lists for the device, then 16011da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 16025739411aSCornelia Huck * 1603b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 1604b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 1605b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 1606b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 1607b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 1608b10d5efdSAlan Stern * and register a fresh new struct device instead. 1609b10d5efdSAlan Stern * 16105739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 16115739411aSCornelia Huck * if it returned an error! Always use put_device() to give up your 16125739411aSCornelia Huck * reference instead. 16131da177e4SLinus Torvalds */ 16141da177e4SLinus Torvalds int device_add(struct device *dev) 16151da177e4SLinus Torvalds { 16161da177e4SLinus Torvalds struct device *parent = NULL; 1617ca22e56dSKay Sievers struct kobject *kobj; 1618c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 1619c906a48aSGreg Kroah-Hartman int error = -EINVAL; 1620cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1621775b64d2SRafael J. Wysocki 16221da177e4SLinus Torvalds dev = get_device(dev); 1623c906a48aSGreg Kroah-Hartman if (!dev) 1624c906a48aSGreg Kroah-Hartman goto done; 1625c906a48aSGreg Kroah-Hartman 1626fb069a5dSGreg Kroah-Hartman if (!dev->p) { 1627b4028437SGreg Kroah-Hartman error = device_private_init(dev); 1628b4028437SGreg Kroah-Hartman if (error) 1629fb069a5dSGreg Kroah-Hartman goto done; 1630fb069a5dSGreg Kroah-Hartman } 1631fb069a5dSGreg Kroah-Hartman 16321fa5ae85SKay Sievers /* 16331fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 16341fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 16351fa5ae85SKay Sievers * the name, and force the use of dev_name() 16361fa5ae85SKay Sievers */ 16371fa5ae85SKay Sievers if (dev->init_name) { 1638acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 16391fa5ae85SKay Sievers dev->init_name = NULL; 16401fa5ae85SKay Sievers } 1641c906a48aSGreg Kroah-Hartman 1642ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 1643ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 1644ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 1645ca22e56dSKay Sievers 1646e6309e75SThomas Gleixner if (!dev_name(dev)) { 1647e6309e75SThomas Gleixner error = -EINVAL; 16485c8563d7SKay Sievers goto name_error; 1649e6309e75SThomas Gleixner } 16501da177e4SLinus Torvalds 16511e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 1652c205ef48SGreg Kroah-Hartman 16531da177e4SLinus Torvalds parent = get_device(dev->parent); 1654ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 1655ca22e56dSKay Sievers if (kobj) 1656ca22e56dSKay Sievers dev->kobj.parent = kobj; 16571da177e4SLinus Torvalds 16580d358f22SYinghai Lu /* use parent numa_node */ 165956f2de81SZhen Lei if (parent && (dev_to_node(dev) == NUMA_NO_NODE)) 16600d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 16610d358f22SYinghai Lu 16621da177e4SLinus Torvalds /* first, register with generic layer. */ 16638a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 16648a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 1665cebf8fd1SMing Lei if (error) { 1666cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 16671da177e4SLinus Torvalds goto Error; 1668cebf8fd1SMing Lei } 1669a7fd6706SKay Sievers 167037022644SBrian Walsh /* notify platform of device entry */ 167137022644SBrian Walsh if (platform_notify) 167237022644SBrian Walsh platform_notify(dev); 167337022644SBrian Walsh 1674c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 1675a306eea4SCornelia Huck if (error) 1676a306eea4SCornelia Huck goto attrError; 1677a7fd6706SKay Sievers 16782ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 16792ee97cafSCornelia Huck if (error) 16802ee97cafSCornelia Huck goto SymlinkError; 1681dc0afa83SCornelia Huck error = device_add_attrs(dev); 1682dc0afa83SCornelia Huck if (error) 16832620efefSGreg Kroah-Hartman goto AttrsError; 1684dc0afa83SCornelia Huck error = bus_add_device(dev); 1685dc0afa83SCornelia Huck if (error) 16861da177e4SLinus Torvalds goto BusError; 16873b98aeafSAlan Stern error = dpm_sysfs_add(dev); 168857eee3d2SRafael J. Wysocki if (error) 16893b98aeafSAlan Stern goto DPMError; 16903b98aeafSAlan Stern device_pm_add(dev); 1691ec0676eeSAlan Stern 16920cd75047SSergey Klyaus if (MAJOR(dev->devt)) { 16930cd75047SSergey Klyaus error = device_create_file(dev, &dev_attr_dev); 16940cd75047SSergey Klyaus if (error) 16950cd75047SSergey Klyaus goto DevAttrError; 16960cd75047SSergey Klyaus 16970cd75047SSergey Klyaus error = device_create_sys_dev_entry(dev); 16980cd75047SSergey Klyaus if (error) 16990cd75047SSergey Klyaus goto SysEntryError; 17000cd75047SSergey Klyaus 17010cd75047SSergey Klyaus devtmpfs_create_node(dev); 17020cd75047SSergey Klyaus } 17030cd75047SSergey Klyaus 1704ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 1705268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 1706ec0676eeSAlan Stern */ 1707ec0676eeSAlan Stern if (dev->bus) 1708ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1709ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 1710ec0676eeSAlan Stern 171153877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 17122023c610SAlan Stern bus_probe_device(dev); 17131da177e4SLinus Torvalds if (parent) 1714f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1715f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 17161da177e4SLinus Torvalds 17175d9fd169SGreg Kroah-Hartman if (dev->class) { 1718ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1719c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 17205a3ceb86STejun Heo klist_add_tail(&dev->knode_class, 17216b6e39a6SKay Sievers &dev->class->p->klist_devices); 1722c47ed219SGreg Kroah-Hartman 1723c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 1724184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1725ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1726c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 1727c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 1728ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 17295d9fd169SGreg Kroah-Hartman } 1730c906a48aSGreg Kroah-Hartman done: 17311da177e4SLinus Torvalds put_device(dev); 17321da177e4SLinus Torvalds return error; 17330cd75047SSergey Klyaus SysEntryError: 17340cd75047SSergey Klyaus if (MAJOR(dev->devt)) 17350cd75047SSergey Klyaus device_remove_file(dev, &dev_attr_dev); 17360cd75047SSergey Klyaus DevAttrError: 17370cd75047SSergey Klyaus device_pm_remove(dev); 17380cd75047SSergey Klyaus dpm_sysfs_remove(dev); 17393b98aeafSAlan Stern DPMError: 174057eee3d2SRafael J. Wysocki bus_remove_device(dev); 174157eee3d2SRafael J. Wysocki BusError: 17422620efefSGreg Kroah-Hartman device_remove_attrs(dev); 17432620efefSGreg Kroah-Hartman AttrsError: 17442ee97cafSCornelia Huck device_remove_class_symlinks(dev); 17452ee97cafSCornelia Huck SymlinkError: 1746c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 174723681e47SGreg Kroah-Hartman attrError: 1748312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1749cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 17501da177e4SLinus Torvalds kobject_del(&dev->kobj); 17511da177e4SLinus Torvalds Error: 1752cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 17531da177e4SLinus Torvalds put_device(parent); 17545c8563d7SKay Sievers name_error: 17555c8563d7SKay Sievers kfree(dev->p); 17565c8563d7SKay Sievers dev->p = NULL; 1757c906a48aSGreg Kroah-Hartman goto done; 17581da177e4SLinus Torvalds } 175986df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 17601da177e4SLinus Torvalds 17611da177e4SLinus Torvalds /** 17621da177e4SLinus Torvalds * device_register - register a device with the system. 17631da177e4SLinus Torvalds * @dev: pointer to the device structure 17641da177e4SLinus Torvalds * 17651da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 17661da177e4SLinus Torvalds * and add it to the system. The two steps can be called 17671da177e4SLinus Torvalds * separately, but this is the easiest and most common. 17681da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 17691da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 17701da177e4SLinus Torvalds * before it is added to the hierarchy. 17715739411aSCornelia Huck * 1772b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 1773b10d5efdSAlan Stern * and device_add(). 1774b10d5efdSAlan Stern * 17755739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 17765739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 17775739411aSCornelia Huck * reference initialized in this function instead. 17781da177e4SLinus Torvalds */ 17791da177e4SLinus Torvalds int device_register(struct device *dev) 17801da177e4SLinus Torvalds { 17811da177e4SLinus Torvalds device_initialize(dev); 17821da177e4SLinus Torvalds return device_add(dev); 17831da177e4SLinus Torvalds } 178486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 17851da177e4SLinus Torvalds 17861da177e4SLinus Torvalds /** 17871da177e4SLinus Torvalds * get_device - increment reference count for device. 17881da177e4SLinus Torvalds * @dev: device. 17891da177e4SLinus Torvalds * 17901da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 17911da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 17921da177e4SLinus Torvalds * pointer passed in. 17931da177e4SLinus Torvalds */ 17941da177e4SLinus Torvalds struct device *get_device(struct device *dev) 17951da177e4SLinus Torvalds { 1796b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 17971da177e4SLinus Torvalds } 179886df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 17991da177e4SLinus Torvalds 18001da177e4SLinus Torvalds /** 18011da177e4SLinus Torvalds * put_device - decrement reference count. 18021da177e4SLinus Torvalds * @dev: device in question. 18031da177e4SLinus Torvalds */ 18041da177e4SLinus Torvalds void put_device(struct device *dev) 18051da177e4SLinus Torvalds { 1806edfaa7c3SKay Sievers /* might_sleep(); */ 18071da177e4SLinus Torvalds if (dev) 18081da177e4SLinus Torvalds kobject_put(&dev->kobj); 18091da177e4SLinus Torvalds } 181086df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 18111da177e4SLinus Torvalds 18121da177e4SLinus Torvalds /** 18131da177e4SLinus Torvalds * device_del - delete device from system. 18141da177e4SLinus Torvalds * @dev: device. 18151da177e4SLinus Torvalds * 18161da177e4SLinus Torvalds * This is the first part of the device unregistration 18171da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 18181da177e4SLinus Torvalds * from here, has it removed from the other driver model 18191da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 18201da177e4SLinus Torvalds * from the kobject hierarchy. 18211da177e4SLinus Torvalds * 18221da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 18231da177e4SLinus Torvalds * also called manually. 18241da177e4SLinus Torvalds */ 18251da177e4SLinus Torvalds void device_del(struct device *dev) 18261da177e4SLinus Torvalds { 18271da177e4SLinus Torvalds struct device *parent = dev->parent; 1828cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1829c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 18301da177e4SLinus Torvalds 1831ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 1832ec0676eeSAlan Stern * before dpm_sysfs_remove(). 1833ec0676eeSAlan Stern */ 1834ec0676eeSAlan Stern if (dev->bus) 1835ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1836ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 18379ed98953SRafael J. Wysocki 18389ed98953SRafael J. Wysocki device_links_purge(dev); 18393b98aeafSAlan Stern dpm_sysfs_remove(dev); 18401da177e4SLinus Torvalds if (parent) 1841f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 1842e105b8bfSDan Williams if (MAJOR(dev->devt)) { 18432b2af54aSKay Sievers devtmpfs_delete_node(dev); 1844e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 1845c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 1846e105b8bfSDan Williams } 1847b9d9c82bSKay Sievers if (dev->class) { 1848da231fd5SKay Sievers device_remove_class_symlinks(dev); 184999ef3ef8SKay Sievers 1850ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1851c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 1852184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1853ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1854c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 1855c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 1856c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 18575a3ceb86STejun Heo klist_del(&dev->knode_class); 1858ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 1859b9d9c82bSKay Sievers } 1860c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 18612620efefSGreg Kroah-Hartman device_remove_attrs(dev); 186228953533SBenjamin Herrenschmidt bus_remove_device(dev); 18634b6d1f12SLongX Zhang device_pm_remove(dev); 1864d1c3414cSGrant Likely driver_deferred_probe_del(dev); 1865478573c9SLukas Wunner device_remove_properties(dev); 18661da177e4SLinus Torvalds 18671da177e4SLinus Torvalds /* Notify the platform of the removal, in case they 18681da177e4SLinus Torvalds * need to do anything... 18691da177e4SLinus Torvalds */ 18701da177e4SLinus Torvalds if (platform_notify_remove) 18711da177e4SLinus Torvalds platform_notify_remove(dev); 1872599bad38SJoerg Roedel if (dev->bus) 1873599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1874599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 1875312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1876cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 18771da177e4SLinus Torvalds kobject_del(&dev->kobj); 1878cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 18791da177e4SLinus Torvalds put_device(parent); 18801da177e4SLinus Torvalds } 188186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 18821da177e4SLinus Torvalds 18831da177e4SLinus Torvalds /** 18841da177e4SLinus Torvalds * device_unregister - unregister device from system. 18851da177e4SLinus Torvalds * @dev: device going away. 18861da177e4SLinus Torvalds * 18871da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 18881da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 18891da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 18901da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 18911da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 18921da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 18931da177e4SLinus Torvalds */ 18941da177e4SLinus Torvalds void device_unregister(struct device *dev) 18951da177e4SLinus Torvalds { 18961e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 18971da177e4SLinus Torvalds device_del(dev); 18981da177e4SLinus Torvalds put_device(dev); 18991da177e4SLinus Torvalds } 190086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 19011da177e4SLinus Torvalds 19023d060aebSAndy Shevchenko static struct device *prev_device(struct klist_iter *i) 19033d060aebSAndy Shevchenko { 19043d060aebSAndy Shevchenko struct klist_node *n = klist_prev(i); 19053d060aebSAndy Shevchenko struct device *dev = NULL; 19063d060aebSAndy Shevchenko struct device_private *p; 19073d060aebSAndy Shevchenko 19083d060aebSAndy Shevchenko if (n) { 19093d060aebSAndy Shevchenko p = to_device_private_parent(n); 19103d060aebSAndy Shevchenko dev = p->device; 19113d060aebSAndy Shevchenko } 19123d060aebSAndy Shevchenko return dev; 19133d060aebSAndy Shevchenko } 19143d060aebSAndy Shevchenko 191536239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 191636239577Smochel@digitalimplant.org { 191736239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 1918f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 1919f791b8c8SGreg Kroah-Hartman struct device_private *p; 1920f791b8c8SGreg Kroah-Hartman 1921f791b8c8SGreg Kroah-Hartman if (n) { 1922f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 1923f791b8c8SGreg Kroah-Hartman dev = p->device; 1924f791b8c8SGreg Kroah-Hartman } 1925f791b8c8SGreg Kroah-Hartman return dev; 192636239577Smochel@digitalimplant.org } 192736239577Smochel@digitalimplant.org 19281da177e4SLinus Torvalds /** 1929e454cea2SKay Sievers * device_get_devnode - path of device node file 19306fcf53acSKay Sievers * @dev: device 1931e454cea2SKay Sievers * @mode: returned file access mode 19323c2670e6SKay Sievers * @uid: returned file owner 19333c2670e6SKay Sievers * @gid: returned file group 19346fcf53acSKay Sievers * @tmp: possibly allocated string 19356fcf53acSKay Sievers * 19366fcf53acSKay Sievers * Return the relative path of a possible device node. 19376fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 19386fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 19396fcf53acSKay Sievers * freed by the caller. 19406fcf53acSKay Sievers */ 1941e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 19424e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 19433c2670e6SKay Sievers const char **tmp) 19446fcf53acSKay Sievers { 19456fcf53acSKay Sievers char *s; 19466fcf53acSKay Sievers 19476fcf53acSKay Sievers *tmp = NULL; 19486fcf53acSKay Sievers 19496fcf53acSKay Sievers /* the device type may provide a specific name */ 1950e454cea2SKay Sievers if (dev->type && dev->type->devnode) 19513c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 19526fcf53acSKay Sievers if (*tmp) 19536fcf53acSKay Sievers return *tmp; 19546fcf53acSKay Sievers 19556fcf53acSKay Sievers /* the class may provide a specific name */ 1956e454cea2SKay Sievers if (dev->class && dev->class->devnode) 1957e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 19586fcf53acSKay Sievers if (*tmp) 19596fcf53acSKay Sievers return *tmp; 19606fcf53acSKay Sievers 19616fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 19626fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 19636fcf53acSKay Sievers return dev_name(dev); 19646fcf53acSKay Sievers 19656fcf53acSKay Sievers /* replace '!' in the name with '/' */ 1966a29fd614SRasmus Villemoes s = kstrdup(dev_name(dev), GFP_KERNEL); 1967a29fd614SRasmus Villemoes if (!s) 19686fcf53acSKay Sievers return NULL; 1969a29fd614SRasmus Villemoes strreplace(s, '!', '/'); 1970a29fd614SRasmus Villemoes return *tmp = s; 19716fcf53acSKay Sievers } 19726fcf53acSKay Sievers 19736fcf53acSKay Sievers /** 19741da177e4SLinus Torvalds * device_for_each_child - device child iterator. 1975c41455fbSRandy Dunlap * @parent: parent struct device. 19761da177e4SLinus Torvalds * @fn: function to be called for each device. 1977f8878dcbSRobert P. J. Day * @data: data for the callback. 19781da177e4SLinus Torvalds * 1979c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 19801da177e4SLinus Torvalds * passing it @data. 19811da177e4SLinus Torvalds * 19821da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 19831da177e4SLinus Torvalds * other than 0, we break out and return that value. 19841da177e4SLinus Torvalds */ 198536239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 19864a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 19871da177e4SLinus Torvalds { 198836239577Smochel@digitalimplant.org struct klist_iter i; 19891da177e4SLinus Torvalds struct device *child; 19901da177e4SLinus Torvalds int error = 0; 19911da177e4SLinus Torvalds 1992014c90dbSGreg Kroah-Hartman if (!parent->p) 1993014c90dbSGreg Kroah-Hartman return 0; 1994014c90dbSGreg Kroah-Hartman 1995f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 199636239577Smochel@digitalimplant.org while ((child = next_device(&i)) && !error) 199736239577Smochel@digitalimplant.org error = fn(child, data); 199836239577Smochel@digitalimplant.org klist_iter_exit(&i); 19991da177e4SLinus Torvalds return error; 20001da177e4SLinus Torvalds } 200186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 20021da177e4SLinus Torvalds 20035ab69981SCornelia Huck /** 20043d060aebSAndy Shevchenko * device_for_each_child_reverse - device child iterator in reversed order. 20053d060aebSAndy Shevchenko * @parent: parent struct device. 20063d060aebSAndy Shevchenko * @fn: function to be called for each device. 20073d060aebSAndy Shevchenko * @data: data for the callback. 20083d060aebSAndy Shevchenko * 20093d060aebSAndy Shevchenko * Iterate over @parent's child devices, and call @fn for each, 20103d060aebSAndy Shevchenko * passing it @data. 20113d060aebSAndy Shevchenko * 20123d060aebSAndy Shevchenko * We check the return of @fn each time. If it returns anything 20133d060aebSAndy Shevchenko * other than 0, we break out and return that value. 20143d060aebSAndy Shevchenko */ 20153d060aebSAndy Shevchenko int device_for_each_child_reverse(struct device *parent, void *data, 20163d060aebSAndy Shevchenko int (*fn)(struct device *dev, void *data)) 20173d060aebSAndy Shevchenko { 20183d060aebSAndy Shevchenko struct klist_iter i; 20193d060aebSAndy Shevchenko struct device *child; 20203d060aebSAndy Shevchenko int error = 0; 20213d060aebSAndy Shevchenko 20223d060aebSAndy Shevchenko if (!parent->p) 20233d060aebSAndy Shevchenko return 0; 20243d060aebSAndy Shevchenko 20253d060aebSAndy Shevchenko klist_iter_init(&parent->p->klist_children, &i); 20263d060aebSAndy Shevchenko while ((child = prev_device(&i)) && !error) 20273d060aebSAndy Shevchenko error = fn(child, data); 20283d060aebSAndy Shevchenko klist_iter_exit(&i); 20293d060aebSAndy Shevchenko return error; 20303d060aebSAndy Shevchenko } 20313d060aebSAndy Shevchenko EXPORT_SYMBOL_GPL(device_for_each_child_reverse); 20323d060aebSAndy Shevchenko 20333d060aebSAndy Shevchenko /** 20345ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 20355ab69981SCornelia Huck * @parent: parent struct device 20365ab69981SCornelia Huck * @match: Callback function to check device 2037f8878dcbSRobert P. J. Day * @data: Data to pass to match function 20385ab69981SCornelia Huck * 20395ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 20405ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 20415ab69981SCornelia Huck * determined by the @match callback. 20425ab69981SCornelia Huck * 20435ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 20445ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 20455ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 20465ab69981SCornelia Huck * and not iterate over any more devices. 2047a4e2400aSFederico Vaga * 2048a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 20495ab69981SCornelia Huck */ 20505ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 20514a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 20525ab69981SCornelia Huck { 20535ab69981SCornelia Huck struct klist_iter i; 20545ab69981SCornelia Huck struct device *child; 20555ab69981SCornelia Huck 20565ab69981SCornelia Huck if (!parent) 20575ab69981SCornelia Huck return NULL; 20585ab69981SCornelia Huck 2059f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 20605ab69981SCornelia Huck while ((child = next_device(&i))) 20615ab69981SCornelia Huck if (match(child, data) && get_device(child)) 20625ab69981SCornelia Huck break; 20635ab69981SCornelia Huck klist_iter_exit(&i); 20645ab69981SCornelia Huck return child; 20655ab69981SCornelia Huck } 206686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 20675ab69981SCornelia Huck 20681da177e4SLinus Torvalds int __init devices_init(void) 20691da177e4SLinus Torvalds { 2070881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 2071881c6cfdSGreg Kroah-Hartman if (!devices_kset) 2072881c6cfdSGreg Kroah-Hartman return -ENOMEM; 2073e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 2074e105b8bfSDan Williams if (!dev_kobj) 2075e105b8bfSDan Williams goto dev_kobj_err; 2076e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 2077e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 2078e105b8bfSDan Williams goto block_kobj_err; 2079e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 2080e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 2081e105b8bfSDan Williams goto char_kobj_err; 2082e105b8bfSDan Williams 2083881c6cfdSGreg Kroah-Hartman return 0; 2084e105b8bfSDan Williams 2085e105b8bfSDan Williams char_kobj_err: 2086e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 2087e105b8bfSDan Williams block_kobj_err: 2088e105b8bfSDan Williams kobject_put(dev_kobj); 2089e105b8bfSDan Williams dev_kobj_err: 2090e105b8bfSDan Williams kset_unregister(devices_kset); 2091e105b8bfSDan Williams return -ENOMEM; 20921da177e4SLinus Torvalds } 20931da177e4SLinus Torvalds 20944f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 20954f3549d7SRafael J. Wysocki { 20964f3549d7SRafael J. Wysocki int ret; 20974f3549d7SRafael J. Wysocki 20984f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 20994f3549d7SRafael J. Wysocki if (ret) 21004f3549d7SRafael J. Wysocki return ret; 21014f3549d7SRafael J. Wysocki 21024f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 21034f3549d7SRafael J. Wysocki } 21044f3549d7SRafael J. Wysocki 21054f3549d7SRafael J. Wysocki /** 21064f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 21074f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 21084f3549d7SRafael J. Wysocki * 21094f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 21104f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 21114f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 21124f3549d7SRafael J. Wysocki * is executed. 21134f3549d7SRafael J. Wysocki * 21144f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 21154f3549d7SRafael J. Wysocki */ 21164f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 21174f3549d7SRafael J. Wysocki { 21184f3549d7SRafael J. Wysocki int ret; 21194f3549d7SRafael J. Wysocki 21204f3549d7SRafael J. Wysocki if (dev->offline_disabled) 21214f3549d7SRafael J. Wysocki return -EPERM; 21224f3549d7SRafael J. Wysocki 21234f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 21244f3549d7SRafael J. Wysocki if (ret) 21254f3549d7SRafael J. Wysocki return ret; 21264f3549d7SRafael J. Wysocki 21274f3549d7SRafael J. Wysocki device_lock(dev); 21284f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 21294f3549d7SRafael J. Wysocki if (dev->offline) { 21304f3549d7SRafael J. Wysocki ret = 1; 21314f3549d7SRafael J. Wysocki } else { 21324f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 21334f3549d7SRafael J. Wysocki if (!ret) { 21344f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 21354f3549d7SRafael J. Wysocki dev->offline = true; 21364f3549d7SRafael J. Wysocki } 21374f3549d7SRafael J. Wysocki } 21384f3549d7SRafael J. Wysocki } 21394f3549d7SRafael J. Wysocki device_unlock(dev); 21404f3549d7SRafael J. Wysocki 21414f3549d7SRafael J. Wysocki return ret; 21424f3549d7SRafael J. Wysocki } 21434f3549d7SRafael J. Wysocki 21444f3549d7SRafael J. Wysocki /** 21454f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 21464f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 21474f3549d7SRafael J. Wysocki * 21484f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 21494f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 21504f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 21514f3549d7SRafael J. Wysocki * 21524f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 21534f3549d7SRafael J. Wysocki */ 21544f3549d7SRafael J. Wysocki int device_online(struct device *dev) 21554f3549d7SRafael J. Wysocki { 21564f3549d7SRafael J. Wysocki int ret = 0; 21574f3549d7SRafael J. Wysocki 21584f3549d7SRafael J. Wysocki device_lock(dev); 21594f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 21604f3549d7SRafael J. Wysocki if (dev->offline) { 21614f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 21624f3549d7SRafael J. Wysocki if (!ret) { 21634f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 21644f3549d7SRafael J. Wysocki dev->offline = false; 21654f3549d7SRafael J. Wysocki } 21664f3549d7SRafael J. Wysocki } else { 21674f3549d7SRafael J. Wysocki ret = 1; 21684f3549d7SRafael J. Wysocki } 21694f3549d7SRafael J. Wysocki } 21704f3549d7SRafael J. Wysocki device_unlock(dev); 21714f3549d7SRafael J. Wysocki 21724f3549d7SRafael J. Wysocki return ret; 21734f3549d7SRafael J. Wysocki } 21744f3549d7SRafael J. Wysocki 21757f100d15SKarthigan Srinivasan struct root_device { 21760aa0dc41SMark McLoughlin struct device dev; 21770aa0dc41SMark McLoughlin struct module *owner; 21780aa0dc41SMark McLoughlin }; 21790aa0dc41SMark McLoughlin 218093058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 2181481e2079SFerenc Wagner { 2182481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 2183481e2079SFerenc Wagner } 21840aa0dc41SMark McLoughlin 21850aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 21860aa0dc41SMark McLoughlin { 21870aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 21880aa0dc41SMark McLoughlin } 21890aa0dc41SMark McLoughlin 21900aa0dc41SMark McLoughlin /** 21910aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 21920aa0dc41SMark McLoughlin * @name: root device name 21930aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 21940aa0dc41SMark McLoughlin * 21950aa0dc41SMark McLoughlin * This function allocates a root device and registers it 21960aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 21970aa0dc41SMark McLoughlin * device, use root_device_unregister(). 21980aa0dc41SMark McLoughlin * 21990aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 22000aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 22010aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 22020aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 22030aa0dc41SMark McLoughlin * 22040aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 22050aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 22060aa0dc41SMark McLoughlin * in sysfs. 22070aa0dc41SMark McLoughlin * 2208f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2209f0eae0edSJani Nikula * 22100aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 22110aa0dc41SMark McLoughlin */ 22120aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 22130aa0dc41SMark McLoughlin { 22140aa0dc41SMark McLoughlin struct root_device *root; 22150aa0dc41SMark McLoughlin int err = -ENOMEM; 22160aa0dc41SMark McLoughlin 22170aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 22180aa0dc41SMark McLoughlin if (!root) 22190aa0dc41SMark McLoughlin return ERR_PTR(err); 22200aa0dc41SMark McLoughlin 2221acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 22220aa0dc41SMark McLoughlin if (err) { 22230aa0dc41SMark McLoughlin kfree(root); 22240aa0dc41SMark McLoughlin return ERR_PTR(err); 22250aa0dc41SMark McLoughlin } 22260aa0dc41SMark McLoughlin 22270aa0dc41SMark McLoughlin root->dev.release = root_device_release; 22280aa0dc41SMark McLoughlin 22290aa0dc41SMark McLoughlin err = device_register(&root->dev); 22300aa0dc41SMark McLoughlin if (err) { 22310aa0dc41SMark McLoughlin put_device(&root->dev); 22320aa0dc41SMark McLoughlin return ERR_PTR(err); 22330aa0dc41SMark McLoughlin } 22340aa0dc41SMark McLoughlin 22351d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 22360aa0dc41SMark McLoughlin if (owner) { 22370aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 22380aa0dc41SMark McLoughlin 22390aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 22400aa0dc41SMark McLoughlin if (err) { 22410aa0dc41SMark McLoughlin device_unregister(&root->dev); 22420aa0dc41SMark McLoughlin return ERR_PTR(err); 22430aa0dc41SMark McLoughlin } 22440aa0dc41SMark McLoughlin root->owner = owner; 22450aa0dc41SMark McLoughlin } 22460aa0dc41SMark McLoughlin #endif 22470aa0dc41SMark McLoughlin 22480aa0dc41SMark McLoughlin return &root->dev; 22490aa0dc41SMark McLoughlin } 22500aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 22510aa0dc41SMark McLoughlin 22520aa0dc41SMark McLoughlin /** 22530aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 22547cbcf225SRandy Dunlap * @dev: device going away 22550aa0dc41SMark McLoughlin * 22560aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 22570aa0dc41SMark McLoughlin * root_device_register(). 22580aa0dc41SMark McLoughlin */ 22590aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 22600aa0dc41SMark McLoughlin { 22610aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 22620aa0dc41SMark McLoughlin 22630aa0dc41SMark McLoughlin if (root->owner) 22640aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 22650aa0dc41SMark McLoughlin 22660aa0dc41SMark McLoughlin device_unregister(dev); 22670aa0dc41SMark McLoughlin } 22680aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 22690aa0dc41SMark McLoughlin 227023681e47SGreg Kroah-Hartman 227123681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 227223681e47SGreg Kroah-Hartman { 22731e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 227423681e47SGreg Kroah-Hartman kfree(dev); 227523681e47SGreg Kroah-Hartman } 227623681e47SGreg Kroah-Hartman 227739ef3112SGuenter Roeck static struct device * 227839ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 227939ef3112SGuenter Roeck dev_t devt, void *drvdata, 228039ef3112SGuenter Roeck const struct attribute_group **groups, 228139ef3112SGuenter Roeck const char *fmt, va_list args) 228239ef3112SGuenter Roeck { 228339ef3112SGuenter Roeck struct device *dev = NULL; 228439ef3112SGuenter Roeck int retval = -ENODEV; 228539ef3112SGuenter Roeck 228639ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 228739ef3112SGuenter Roeck goto error; 228839ef3112SGuenter Roeck 228939ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 229039ef3112SGuenter Roeck if (!dev) { 229139ef3112SGuenter Roeck retval = -ENOMEM; 229239ef3112SGuenter Roeck goto error; 229339ef3112SGuenter Roeck } 229439ef3112SGuenter Roeck 2295bbc780f8SDavid Herrmann device_initialize(dev); 229639ef3112SGuenter Roeck dev->devt = devt; 229739ef3112SGuenter Roeck dev->class = class; 229839ef3112SGuenter Roeck dev->parent = parent; 229939ef3112SGuenter Roeck dev->groups = groups; 230039ef3112SGuenter Roeck dev->release = device_create_release; 230139ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 230239ef3112SGuenter Roeck 230339ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 230439ef3112SGuenter Roeck if (retval) 230539ef3112SGuenter Roeck goto error; 230639ef3112SGuenter Roeck 2307bbc780f8SDavid Herrmann retval = device_add(dev); 230839ef3112SGuenter Roeck if (retval) 230939ef3112SGuenter Roeck goto error; 231039ef3112SGuenter Roeck 231139ef3112SGuenter Roeck return dev; 231239ef3112SGuenter Roeck 231339ef3112SGuenter Roeck error: 231439ef3112SGuenter Roeck put_device(dev); 231539ef3112SGuenter Roeck return ERR_PTR(retval); 231639ef3112SGuenter Roeck } 231739ef3112SGuenter Roeck 231823681e47SGreg Kroah-Hartman /** 23198882b394SGreg Kroah-Hartman * device_create_vargs - creates a device and registers it with sysfs 23208882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 23218882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 23228882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 23238882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 23248882b394SGreg Kroah-Hartman * @fmt: string for the device's name 23258882b394SGreg Kroah-Hartman * @args: va_list for the device's name 23268882b394SGreg Kroah-Hartman * 23278882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 23288882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 23298882b394SGreg Kroah-Hartman * 23308882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 23318882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 23328882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 23338882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 23348882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 23358882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 23368882b394SGreg Kroah-Hartman * pointer. 23378882b394SGreg Kroah-Hartman * 2338f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2339f0eae0edSJani Nikula * 23408882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 23418882b394SGreg Kroah-Hartman * been created with a call to class_create(). 23428882b394SGreg Kroah-Hartman */ 23438882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent, 23448882b394SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, 23458882b394SGreg Kroah-Hartman va_list args) 23468882b394SGreg Kroah-Hartman { 234739ef3112SGuenter Roeck return device_create_groups_vargs(class, parent, devt, drvdata, NULL, 234839ef3112SGuenter Roeck fmt, args); 23498882b394SGreg Kroah-Hartman } 23508882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs); 23518882b394SGreg Kroah-Hartman 23528882b394SGreg Kroah-Hartman /** 23534e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 23548882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 23558882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 23568882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 23578882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 23588882b394SGreg Kroah-Hartman * @fmt: string for the device's name 23598882b394SGreg Kroah-Hartman * 23608882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 23618882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 23628882b394SGreg Kroah-Hartman * 23638882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 23648882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 23658882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 23668882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 23678882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 23688882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 23698882b394SGreg Kroah-Hartman * pointer. 23708882b394SGreg Kroah-Hartman * 2371f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2372f0eae0edSJani Nikula * 23738882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 23748882b394SGreg Kroah-Hartman * been created with a call to class_create(). 23758882b394SGreg Kroah-Hartman */ 23764e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 23774e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 23788882b394SGreg Kroah-Hartman { 23798882b394SGreg Kroah-Hartman va_list vargs; 23808882b394SGreg Kroah-Hartman struct device *dev; 23818882b394SGreg Kroah-Hartman 23828882b394SGreg Kroah-Hartman va_start(vargs, fmt); 23838882b394SGreg Kroah-Hartman dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); 23848882b394SGreg Kroah-Hartman va_end(vargs); 23858882b394SGreg Kroah-Hartman return dev; 23868882b394SGreg Kroah-Hartman } 23874e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 23888882b394SGreg Kroah-Hartman 238939ef3112SGuenter Roeck /** 239039ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 239139ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 239239ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 239339ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 239439ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 239539ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 239639ef3112SGuenter Roeck * @fmt: string for the device's name 239739ef3112SGuenter Roeck * 239839ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 239939ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 240039ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 240139ef3112SGuenter Roeck * be created automatically. 240239ef3112SGuenter Roeck * 240339ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 240439ef3112SGuenter Roeck * the dev_t is not 0,0. 240539ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 240639ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 240739ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 240839ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 240939ef3112SGuenter Roeck * pointer. 241039ef3112SGuenter Roeck * 241139ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 241239ef3112SGuenter Roeck * 241339ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 241439ef3112SGuenter Roeck * been created with a call to class_create(). 241539ef3112SGuenter Roeck */ 241639ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 241739ef3112SGuenter Roeck struct device *parent, dev_t devt, 241839ef3112SGuenter Roeck void *drvdata, 241939ef3112SGuenter Roeck const struct attribute_group **groups, 242039ef3112SGuenter Roeck const char *fmt, ...) 242139ef3112SGuenter Roeck { 242239ef3112SGuenter Roeck va_list vargs; 242339ef3112SGuenter Roeck struct device *dev; 242439ef3112SGuenter Roeck 242539ef3112SGuenter Roeck va_start(vargs, fmt); 242639ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 242739ef3112SGuenter Roeck fmt, vargs); 242839ef3112SGuenter Roeck va_end(vargs); 242939ef3112SGuenter Roeck return dev; 243039ef3112SGuenter Roeck } 243139ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 243239ef3112SGuenter Roeck 24339f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data) 243423681e47SGreg Kroah-Hartman { 24359f3b795aSMichał Mirosław const dev_t *devt = data; 243623681e47SGreg Kroah-Hartman 2437cd35449bSDave Young return dev->devt == *devt; 2438775b64d2SRafael J. Wysocki } 243923681e47SGreg Kroah-Hartman 2440775b64d2SRafael J. Wysocki /** 2441775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 2442775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 2443775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 2444775b64d2SRafael J. Wysocki * 2445775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 2446775b64d2SRafael J. Wysocki * call to device_create(). 2447775b64d2SRafael J. Wysocki */ 2448775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 2449775b64d2SRafael J. Wysocki { 2450775b64d2SRafael J. Wysocki struct device *dev; 2451775b64d2SRafael J. Wysocki 2452695794aeSGreg Kroah-Hartman dev = class_find_device(class, NULL, &devt, __match_devt); 2453cd35449bSDave Young if (dev) { 2454cd35449bSDave Young put_device(dev); 245523681e47SGreg Kroah-Hartman device_unregister(dev); 245623681e47SGreg Kroah-Hartman } 2457cd35449bSDave Young } 245823681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 2459a2de48caSGreg Kroah-Hartman 2460a2de48caSGreg Kroah-Hartman /** 2461a2de48caSGreg Kroah-Hartman * device_rename - renames a device 2462a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 2463a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 2464030c1d2bSEric W. Biederman * 2465030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 2466030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 2467030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 2468030c1d2bSEric W. Biederman * won't conflict with other devices. 2469c6c0ac66SMichael Ellerman * 2470a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 2471a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 2472a5462516STimur Tabi * some insight: 2473a5462516STimur Tabi * 2474a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 2475a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 2476a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 2477a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 2478a5462516STimur Tabi * 2479a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 2480a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 2481a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 2482a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 2483a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 2484a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 2485a5462516STimur Tabi * 2486a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 2487a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 2488a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 2489a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 2490a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 2491a5462516STimur Tabi * reasons. 2492a5462516STimur Tabi * 2493a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 2494a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 2495a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 2496a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 2497a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 2498a2de48caSGreg Kroah-Hartman */ 24996937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 2500a2de48caSGreg Kroah-Hartman { 25014b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 25022ee97cafSCornelia Huck char *old_device_name = NULL; 2503a2de48caSGreg Kroah-Hartman int error; 2504a2de48caSGreg Kroah-Hartman 2505a2de48caSGreg Kroah-Hartman dev = get_device(dev); 2506a2de48caSGreg Kroah-Hartman if (!dev) 2507a2de48caSGreg Kroah-Hartman return -EINVAL; 2508a2de48caSGreg Kroah-Hartman 250969df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 2510a2de48caSGreg Kroah-Hartman 25111fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 25122ee97cafSCornelia Huck if (!old_device_name) { 2513952ab431SJesper Juhl error = -ENOMEM; 25142ee97cafSCornelia Huck goto out; 2515952ab431SJesper Juhl } 2516a2de48caSGreg Kroah-Hartman 2517f349cf34SEric W. Biederman if (dev->class) { 25184b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 25194b30ee58STejun Heo kobj, old_device_name, 25204b30ee58STejun Heo new_name, kobject_namespace(kobj)); 2521f349cf34SEric W. Biederman if (error) 2522f349cf34SEric W. Biederman goto out; 2523f349cf34SEric W. Biederman } 252439aba963SKay Sievers 25254b30ee58STejun Heo error = kobject_rename(kobj, new_name); 25261fa5ae85SKay Sievers if (error) 25272ee97cafSCornelia Huck goto out; 2528a2de48caSGreg Kroah-Hartman 25292ee97cafSCornelia Huck out: 2530a2de48caSGreg Kroah-Hartman put_device(dev); 2531a2de48caSGreg Kroah-Hartman 25322ee97cafSCornelia Huck kfree(old_device_name); 2533a2de48caSGreg Kroah-Hartman 2534a2de48caSGreg Kroah-Hartman return error; 2535a2de48caSGreg Kroah-Hartman } 2536a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 25378a82472fSCornelia Huck 25388a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 25398a82472fSCornelia Huck struct device *old_parent, 25408a82472fSCornelia Huck struct device *new_parent) 25418a82472fSCornelia Huck { 2542f7f3461dSGreg Kroah-Hartman int error = 0; 25438a82472fSCornelia Huck 2544f7f3461dSGreg Kroah-Hartman if (old_parent) 2545f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 2546f7f3461dSGreg Kroah-Hartman if (new_parent) 2547f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 2548f7f3461dSGreg Kroah-Hartman "device"); 2549f7f3461dSGreg Kroah-Hartman return error; 25508a82472fSCornelia Huck } 25518a82472fSCornelia Huck 25528a82472fSCornelia Huck /** 25538a82472fSCornelia Huck * device_move - moves a device to a new parent 25548a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 2555c744aeaeSCornelia Huck * @new_parent: the new parent of the device (can by NULL) 2556ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 25578a82472fSCornelia Huck */ 2558ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 2559ffa6a705SCornelia Huck enum dpm_order dpm_order) 25608a82472fSCornelia Huck { 25618a82472fSCornelia Huck int error; 25628a82472fSCornelia Huck struct device *old_parent; 2563c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 25648a82472fSCornelia Huck 25658a82472fSCornelia Huck dev = get_device(dev); 25668a82472fSCornelia Huck if (!dev) 25678a82472fSCornelia Huck return -EINVAL; 25688a82472fSCornelia Huck 2569ffa6a705SCornelia Huck device_pm_lock(); 25708a82472fSCornelia Huck new_parent = get_device(new_parent); 2571c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 257263b6971aSCornelia Huck 25731e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 25741e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 2575c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 25768a82472fSCornelia Huck if (error) { 257763b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 25788a82472fSCornelia Huck put_device(new_parent); 25798a82472fSCornelia Huck goto out; 25808a82472fSCornelia Huck } 25818a82472fSCornelia Huck old_parent = dev->parent; 25828a82472fSCornelia Huck dev->parent = new_parent; 25838a82472fSCornelia Huck if (old_parent) 2584f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 25850d358f22SYinghai Lu if (new_parent) { 2586f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2587f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 25880d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 25890d358f22SYinghai Lu } 25900d358f22SYinghai Lu 2591bdd4034dSRabin Vincent if (dev->class) { 25928a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 25938a82472fSCornelia Huck if (error) { 25948a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 25958a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 25968a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 2597c744aeaeSCornelia Huck if (new_parent) 2598f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 25990d358f22SYinghai Lu dev->parent = old_parent; 26000d358f22SYinghai Lu if (old_parent) { 2601f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2602f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 26030d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 26040d358f22SYinghai Lu } 26058a82472fSCornelia Huck } 260663b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 26078a82472fSCornelia Huck put_device(new_parent); 26088a82472fSCornelia Huck goto out; 26098a82472fSCornelia Huck } 2610bdd4034dSRabin Vincent } 2611ffa6a705SCornelia Huck switch (dpm_order) { 2612ffa6a705SCornelia Huck case DPM_ORDER_NONE: 2613ffa6a705SCornelia Huck break; 2614ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 2615ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 261652cdbdd4SGrygorii Strashko devices_kset_move_after(dev, new_parent); 2617ffa6a705SCornelia Huck break; 2618ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 2619ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 262052cdbdd4SGrygorii Strashko devices_kset_move_before(new_parent, dev); 2621ffa6a705SCornelia Huck break; 2622ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 2623ffa6a705SCornelia Huck device_pm_move_last(dev); 262452cdbdd4SGrygorii Strashko devices_kset_move_last(dev); 2625ffa6a705SCornelia Huck break; 2626ffa6a705SCornelia Huck } 2627bdd4034dSRabin Vincent 26288a82472fSCornelia Huck put_device(old_parent); 26298a82472fSCornelia Huck out: 2630ffa6a705SCornelia Huck device_pm_unlock(); 26318a82472fSCornelia Huck put_device(dev); 26328a82472fSCornelia Huck return error; 26338a82472fSCornelia Huck } 26348a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 263537b0c020SGreg Kroah-Hartman 263637b0c020SGreg Kroah-Hartman /** 263737b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 263837b0c020SGreg Kroah-Hartman */ 263937b0c020SGreg Kroah-Hartman void device_shutdown(void) 264037b0c020SGreg Kroah-Hartman { 2641f123db8eSBenson Leung struct device *dev, *parent; 264237b0c020SGreg Kroah-Hartman 26436245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 26446245838fSHugh Daschbach /* 26456245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 26466245838fSHugh Daschbach * Beware that device unplug events may also start pulling 26476245838fSHugh Daschbach * devices offline, even as the system is shutting down. 26486245838fSHugh Daschbach */ 26496245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 26506245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 26516245838fSHugh Daschbach kobj.entry); 2652d1c6c030SMing Lei 2653d1c6c030SMing Lei /* 2654d1c6c030SMing Lei * hold reference count of device's parent to 2655d1c6c030SMing Lei * prevent it from being freed because parent's 2656d1c6c030SMing Lei * lock is to be held 2657d1c6c030SMing Lei */ 2658f123db8eSBenson Leung parent = get_device(dev->parent); 26596245838fSHugh Daschbach get_device(dev); 26606245838fSHugh Daschbach /* 26616245838fSHugh Daschbach * Make sure the device is off the kset list, in the 26626245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 26636245838fSHugh Daschbach */ 26646245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 26656245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 2666fe6b91f4SAlan Stern 2667d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 2668f123db8eSBenson Leung if (parent) 2669f123db8eSBenson Leung device_lock(parent); 2670d1c6c030SMing Lei device_lock(dev); 2671d1c6c030SMing Lei 2672fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 2673fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 2674fe6b91f4SAlan Stern pm_runtime_barrier(dev); 26756245838fSHugh Daschbach 267637b0c020SGreg Kroah-Hartman if (dev->bus && dev->bus->shutdown) { 26770246c4faSShuoX Liu if (initcall_debug) 26780246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 267937b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 268037b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 26810246c4faSShuoX Liu if (initcall_debug) 26820246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 268337b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 268437b0c020SGreg Kroah-Hartman } 2685d1c6c030SMing Lei 2686d1c6c030SMing Lei device_unlock(dev); 2687f123db8eSBenson Leung if (parent) 2688f123db8eSBenson Leung device_unlock(parent); 2689d1c6c030SMing Lei 26906245838fSHugh Daschbach put_device(dev); 2691f123db8eSBenson Leung put_device(parent); 26926245838fSHugh Daschbach 26936245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 269437b0c020SGreg Kroah-Hartman } 26956245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 269637b0c020SGreg Kroah-Hartman } 269799bcf217SJoe Perches 269899bcf217SJoe Perches /* 269999bcf217SJoe Perches * Device logging functions 270099bcf217SJoe Perches */ 270199bcf217SJoe Perches 270299bcf217SJoe Perches #ifdef CONFIG_PRINTK 2703666f355fSJoe Perches static int 2704666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 270599bcf217SJoe Perches { 2706c4e00daaSKay Sievers const char *subsys; 2707798efc60SJoe Perches size_t pos = 0; 270899bcf217SJoe Perches 2709c4e00daaSKay Sievers if (dev->class) 2710c4e00daaSKay Sievers subsys = dev->class->name; 2711c4e00daaSKay Sievers else if (dev->bus) 2712c4e00daaSKay Sievers subsys = dev->bus->name; 2713c4e00daaSKay Sievers else 2714798efc60SJoe Perches return 0; 2715c4e00daaSKay Sievers 2716798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 2717655e5b7cSBen Hutchings if (pos >= hdrlen) 2718655e5b7cSBen Hutchings goto overflow; 2719c4e00daaSKay Sievers 2720c4e00daaSKay Sievers /* 2721c4e00daaSKay Sievers * Add device identifier DEVICE=: 2722c4e00daaSKay Sievers * b12:8 block dev_t 2723c4e00daaSKay Sievers * c127:3 char dev_t 2724c4e00daaSKay Sievers * n8 netdev ifindex 2725c4e00daaSKay Sievers * +sound:card0 subsystem:devname 2726c4e00daaSKay Sievers */ 2727c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 2728c4e00daaSKay Sievers char c; 2729c4e00daaSKay Sievers 2730c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 2731c4e00daaSKay Sievers c = 'b'; 2732c4e00daaSKay Sievers else 2733c4e00daaSKay Sievers c = 'c'; 2734798efc60SJoe Perches pos++; 2735798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2736c4e00daaSKay Sievers "DEVICE=%c%u:%u", 2737c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 2738c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 2739c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 2740c4e00daaSKay Sievers 2741798efc60SJoe Perches pos++; 2742798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2743c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 2744c4e00daaSKay Sievers } else { 2745798efc60SJoe Perches pos++; 2746798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2747c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 2748c4e00daaSKay Sievers } 2749af7f2158SJim Cromie 2750655e5b7cSBen Hutchings if (pos >= hdrlen) 2751655e5b7cSBen Hutchings goto overflow; 2752655e5b7cSBen Hutchings 2753798efc60SJoe Perches return pos; 2754655e5b7cSBen Hutchings 2755655e5b7cSBen Hutchings overflow: 2756655e5b7cSBen Hutchings dev_WARN(dev, "device/subsystem name too long"); 2757655e5b7cSBen Hutchings return 0; 275899bcf217SJoe Perches } 2759798efc60SJoe Perches 276005e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 276105e4e5b8SJoe Perches const char *fmt, va_list args) 276205e4e5b8SJoe Perches { 276305e4e5b8SJoe Perches char hdr[128]; 276405e4e5b8SJoe Perches size_t hdrlen; 276505e4e5b8SJoe Perches 276605e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 276705e4e5b8SJoe Perches 276805e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 276905e4e5b8SJoe Perches } 277005e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 277105e4e5b8SJoe Perches 277205e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 277305e4e5b8SJoe Perches { 277405e4e5b8SJoe Perches va_list args; 277505e4e5b8SJoe Perches int r; 277605e4e5b8SJoe Perches 277705e4e5b8SJoe Perches va_start(args, fmt); 277805e4e5b8SJoe Perches 277905e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 278005e4e5b8SJoe Perches 278105e4e5b8SJoe Perches va_end(args); 278205e4e5b8SJoe Perches 278305e4e5b8SJoe Perches return r; 278405e4e5b8SJoe Perches } 278505e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 278605e4e5b8SJoe Perches 2787d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev, 2788798efc60SJoe Perches struct va_format *vaf) 2789798efc60SJoe Perches { 2790d1f1052cSJoe Perches if (dev) 2791d1f1052cSJoe Perches dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", 2792798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 2793d1f1052cSJoe Perches else 2794d1f1052cSJoe Perches printk("%s(NULL device *): %pV", level, vaf); 2795798efc60SJoe Perches } 279699bcf217SJoe Perches 2797d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev, 279899bcf217SJoe Perches const char *fmt, ...) 279999bcf217SJoe Perches { 280099bcf217SJoe Perches struct va_format vaf; 280199bcf217SJoe Perches va_list args; 280299bcf217SJoe Perches 280399bcf217SJoe Perches va_start(args, fmt); 280499bcf217SJoe Perches 280599bcf217SJoe Perches vaf.fmt = fmt; 280699bcf217SJoe Perches vaf.va = &args; 280799bcf217SJoe Perches 2808d1f1052cSJoe Perches __dev_printk(level, dev, &vaf); 2809798efc60SJoe Perches 281099bcf217SJoe Perches va_end(args); 281199bcf217SJoe Perches } 281299bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 281399bcf217SJoe Perches 281499bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 2815d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...) \ 281699bcf217SJoe Perches { \ 281799bcf217SJoe Perches struct va_format vaf; \ 281899bcf217SJoe Perches va_list args; \ 281999bcf217SJoe Perches \ 282099bcf217SJoe Perches va_start(args, fmt); \ 282199bcf217SJoe Perches \ 282299bcf217SJoe Perches vaf.fmt = fmt; \ 282399bcf217SJoe Perches vaf.va = &args; \ 282499bcf217SJoe Perches \ 2825d1f1052cSJoe Perches __dev_printk(kern_level, dev, &vaf); \ 2826798efc60SJoe Perches \ 282799bcf217SJoe Perches va_end(args); \ 282899bcf217SJoe Perches } \ 282999bcf217SJoe Perches EXPORT_SYMBOL(func); 283099bcf217SJoe Perches 283199bcf217SJoe Perches define_dev_printk_level(dev_emerg, KERN_EMERG); 283299bcf217SJoe Perches define_dev_printk_level(dev_alert, KERN_ALERT); 283399bcf217SJoe Perches define_dev_printk_level(dev_crit, KERN_CRIT); 283499bcf217SJoe Perches define_dev_printk_level(dev_err, KERN_ERR); 283599bcf217SJoe Perches define_dev_printk_level(dev_warn, KERN_WARNING); 283699bcf217SJoe Perches define_dev_printk_level(dev_notice, KERN_NOTICE); 283799bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 283899bcf217SJoe Perches 283999bcf217SJoe Perches #endif 284097badf87SRafael J. Wysocki 284197badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 284297badf87SRafael J. Wysocki { 284397badf87SRafael J. Wysocki return fwnode && !IS_ERR(fwnode->secondary); 284497badf87SRafael J. Wysocki } 284597badf87SRafael J. Wysocki 284697badf87SRafael J. Wysocki /** 284797badf87SRafael J. Wysocki * set_primary_fwnode - Change the primary firmware node of a given device. 284897badf87SRafael J. Wysocki * @dev: Device to handle. 284997badf87SRafael J. Wysocki * @fwnode: New primary firmware node of the device. 285097badf87SRafael J. Wysocki * 285197badf87SRafael J. Wysocki * Set the device's firmware node pointer to @fwnode, but if a secondary 285297badf87SRafael J. Wysocki * firmware node of the device is present, preserve it. 285397badf87SRafael J. Wysocki */ 285497badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 285597badf87SRafael J. Wysocki { 285697badf87SRafael J. Wysocki if (fwnode) { 285797badf87SRafael J. Wysocki struct fwnode_handle *fn = dev->fwnode; 285897badf87SRafael J. Wysocki 285997badf87SRafael J. Wysocki if (fwnode_is_primary(fn)) 286097badf87SRafael J. Wysocki fn = fn->secondary; 286197badf87SRafael J. Wysocki 286255f89a8aSMika Westerberg if (fn) { 286355f89a8aSMika Westerberg WARN_ON(fwnode->secondary); 286497badf87SRafael J. Wysocki fwnode->secondary = fn; 286555f89a8aSMika Westerberg } 286697badf87SRafael J. Wysocki dev->fwnode = fwnode; 286797badf87SRafael J. Wysocki } else { 286897badf87SRafael J. Wysocki dev->fwnode = fwnode_is_primary(dev->fwnode) ? 286997badf87SRafael J. Wysocki dev->fwnode->secondary : NULL; 287097badf87SRafael J. Wysocki } 287197badf87SRafael J. Wysocki } 287297badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode); 287397badf87SRafael J. Wysocki 287497badf87SRafael J. Wysocki /** 287597badf87SRafael J. Wysocki * set_secondary_fwnode - Change the secondary firmware node of a given device. 287697badf87SRafael J. Wysocki * @dev: Device to handle. 287797badf87SRafael J. Wysocki * @fwnode: New secondary firmware node of the device. 287897badf87SRafael J. Wysocki * 287997badf87SRafael J. Wysocki * If a primary firmware node of the device is present, set its secondary 288097badf87SRafael J. Wysocki * pointer to @fwnode. Otherwise, set the device's firmware node pointer to 288197badf87SRafael J. Wysocki * @fwnode. 288297badf87SRafael J. Wysocki */ 288397badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 288497badf87SRafael J. Wysocki { 288597badf87SRafael J. Wysocki if (fwnode) 288697badf87SRafael J. Wysocki fwnode->secondary = ERR_PTR(-ENODEV); 288797badf87SRafael J. Wysocki 288897badf87SRafael J. Wysocki if (fwnode_is_primary(dev->fwnode)) 288997badf87SRafael J. Wysocki dev->fwnode->secondary = fwnode; 289097badf87SRafael J. Wysocki else 289197badf87SRafael J. Wysocki dev->fwnode = fwnode; 289297badf87SRafael J. Wysocki } 2893