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> 29174cd4b1SIngo Molnar #include <linux/sched/signal.h> 3063967685SGreg Kroah-Hartman #include <linux/sysfs.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #include "base.h" 331da177e4SLinus Torvalds #include "power/power.h" 341da177e4SLinus Torvalds 35e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED 36e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2 37e52eec13SAndi Kleen long sysfs_deprecated = 1; 38e52eec13SAndi Kleen #else 39e52eec13SAndi Kleen long sysfs_deprecated = 0; 40e52eec13SAndi Kleen #endif 413454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg) 42e52eec13SAndi Kleen { 4334da5e67SJingoo Han return kstrtol(arg, 10, &sysfs_deprecated); 44e52eec13SAndi Kleen } 45e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup); 46e52eec13SAndi Kleen #endif 47e52eec13SAndi Kleen 489ed98953SRafael J. Wysocki /* Device links support. */ 499ed98953SRafael J. Wysocki 509ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 519ed98953SRafael J. Wysocki static DEFINE_MUTEX(device_links_lock); 529ed98953SRafael J. Wysocki DEFINE_STATIC_SRCU(device_links_srcu); 539ed98953SRafael J. Wysocki 549ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 559ed98953SRafael J. Wysocki { 569ed98953SRafael J. Wysocki mutex_lock(&device_links_lock); 579ed98953SRafael J. Wysocki } 589ed98953SRafael J. Wysocki 599ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 609ed98953SRafael J. Wysocki { 619ed98953SRafael J. Wysocki mutex_unlock(&device_links_lock); 629ed98953SRafael J. Wysocki } 639ed98953SRafael J. Wysocki 649ed98953SRafael J. Wysocki int device_links_read_lock(void) 659ed98953SRafael J. Wysocki { 669ed98953SRafael J. Wysocki return srcu_read_lock(&device_links_srcu); 679ed98953SRafael J. Wysocki } 689ed98953SRafael J. Wysocki 699ed98953SRafael J. Wysocki void device_links_read_unlock(int idx) 709ed98953SRafael J. Wysocki { 719ed98953SRafael J. Wysocki srcu_read_unlock(&device_links_srcu, idx); 729ed98953SRafael J. Wysocki } 739ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 749ed98953SRafael J. Wysocki static DECLARE_RWSEM(device_links_lock); 759ed98953SRafael J. Wysocki 769ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 779ed98953SRafael J. Wysocki { 789ed98953SRafael J. Wysocki down_write(&device_links_lock); 799ed98953SRafael J. Wysocki } 809ed98953SRafael J. Wysocki 819ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 829ed98953SRafael J. Wysocki { 839ed98953SRafael J. Wysocki up_write(&device_links_lock); 849ed98953SRafael J. Wysocki } 859ed98953SRafael J. Wysocki 869ed98953SRafael J. Wysocki int device_links_read_lock(void) 879ed98953SRafael J. Wysocki { 889ed98953SRafael J. Wysocki down_read(&device_links_lock); 899ed98953SRafael J. Wysocki return 0; 909ed98953SRafael J. Wysocki } 919ed98953SRafael J. Wysocki 929ed98953SRafael J. Wysocki void device_links_read_unlock(int not_used) 939ed98953SRafael J. Wysocki { 949ed98953SRafael J. Wysocki up_read(&device_links_lock); 959ed98953SRafael J. Wysocki } 969ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 979ed98953SRafael J. Wysocki 989ed98953SRafael J. Wysocki /** 999ed98953SRafael J. Wysocki * device_is_dependent - Check if one device depends on another one 1009ed98953SRafael J. Wysocki * @dev: Device to check dependencies for. 1019ed98953SRafael J. Wysocki * @target: Device to check against. 1029ed98953SRafael J. Wysocki * 1039ed98953SRafael J. Wysocki * Check if @target depends on @dev or any device dependent on it (its child or 1049ed98953SRafael J. Wysocki * its consumer etc). Return 1 if that is the case or 0 otherwise. 1059ed98953SRafael J. Wysocki */ 1069ed98953SRafael J. Wysocki static int device_is_dependent(struct device *dev, void *target) 1079ed98953SRafael J. Wysocki { 1089ed98953SRafael J. Wysocki struct device_link *link; 1099ed98953SRafael J. Wysocki int ret; 1109ed98953SRafael J. Wysocki 1119ed98953SRafael J. Wysocki if (WARN_ON(dev == target)) 1129ed98953SRafael J. Wysocki return 1; 1139ed98953SRafael J. Wysocki 1149ed98953SRafael J. Wysocki ret = device_for_each_child(dev, target, device_is_dependent); 1159ed98953SRafael J. Wysocki if (ret) 1169ed98953SRafael J. Wysocki return ret; 1179ed98953SRafael J. Wysocki 1189ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1199ed98953SRafael J. Wysocki if (WARN_ON(link->consumer == target)) 1209ed98953SRafael J. Wysocki return 1; 1219ed98953SRafael J. Wysocki 1229ed98953SRafael J. Wysocki ret = device_is_dependent(link->consumer, target); 1239ed98953SRafael J. Wysocki if (ret) 1249ed98953SRafael J. Wysocki break; 1259ed98953SRafael J. Wysocki } 1269ed98953SRafael J. Wysocki return ret; 1279ed98953SRafael J. Wysocki } 1289ed98953SRafael J. Wysocki 1299ed98953SRafael J. Wysocki static int device_reorder_to_tail(struct device *dev, void *not_used) 1309ed98953SRafael J. Wysocki { 1319ed98953SRafael J. Wysocki struct device_link *link; 1329ed98953SRafael J. Wysocki 1339ed98953SRafael J. Wysocki /* 1349ed98953SRafael J. Wysocki * Devices that have not been registered yet will be put to the ends 1359ed98953SRafael J. Wysocki * of the lists during the registration, so skip them here. 1369ed98953SRafael J. Wysocki */ 1379ed98953SRafael J. Wysocki if (device_is_registered(dev)) 1389ed98953SRafael J. Wysocki devices_kset_move_last(dev); 1399ed98953SRafael J. Wysocki 1409ed98953SRafael J. Wysocki if (device_pm_initialized(dev)) 1419ed98953SRafael J. Wysocki device_pm_move_last(dev); 1429ed98953SRafael J. Wysocki 1439ed98953SRafael J. Wysocki device_for_each_child(dev, NULL, device_reorder_to_tail); 1449ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) 1459ed98953SRafael J. Wysocki device_reorder_to_tail(link->consumer, NULL); 1469ed98953SRafael J. Wysocki 1479ed98953SRafael J. Wysocki return 0; 1489ed98953SRafael J. Wysocki } 1499ed98953SRafael J. Wysocki 1509ed98953SRafael J. Wysocki /** 1519ed98953SRafael J. Wysocki * device_link_add - Create a link between two devices. 1529ed98953SRafael J. Wysocki * @consumer: Consumer end of the link. 1539ed98953SRafael J. Wysocki * @supplier: Supplier end of the link. 1549ed98953SRafael J. Wysocki * @flags: Link flags. 1559ed98953SRafael J. Wysocki * 15621d5c57bSRafael J. Wysocki * The caller is responsible for the proper synchronization of the link creation 15721d5c57bSRafael J. Wysocki * with runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause the 15821d5c57bSRafael J. Wysocki * runtime PM framework to take the link into account. Second, if the 15921d5c57bSRafael J. Wysocki * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will 16021d5c57bSRafael J. Wysocki * be forced into the active metastate and reference-counted upon the creation 16121d5c57bSRafael J. Wysocki * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be 16221d5c57bSRafael J. Wysocki * ignored. 16321d5c57bSRafael J. Wysocki * 1649ed98953SRafael J. Wysocki * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically 1659ed98953SRafael J. Wysocki * when the consumer device driver unbinds from it. The combination of both 1669ed98953SRafael J. Wysocki * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL 1679ed98953SRafael J. Wysocki * to be returned. 1689ed98953SRafael J. Wysocki * 1699ed98953SRafael J. Wysocki * A side effect of the link creation is re-ordering of dpm_list and the 1709ed98953SRafael J. Wysocki * devices_kset list by moving the consumer device and all devices depending 1719ed98953SRafael J. Wysocki * on it to the ends of these lists (that does not happen to devices that have 1729ed98953SRafael J. Wysocki * not been registered when this function is called). 1739ed98953SRafael J. Wysocki * 1749ed98953SRafael J. Wysocki * The supplier device is required to be registered when this function is called 1759ed98953SRafael J. Wysocki * and NULL will be returned if that is not the case. The consumer device need 17664df1148SLukas Wunner * not be registered, however. 1779ed98953SRafael J. Wysocki */ 1789ed98953SRafael J. Wysocki struct device_link *device_link_add(struct device *consumer, 1799ed98953SRafael J. Wysocki struct device *supplier, u32 flags) 1809ed98953SRafael J. Wysocki { 1819ed98953SRafael J. Wysocki struct device_link *link; 1829ed98953SRafael J. Wysocki 1839ed98953SRafael J. Wysocki if (!consumer || !supplier || 1849ed98953SRafael J. Wysocki ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE))) 1859ed98953SRafael J. Wysocki return NULL; 1869ed98953SRafael J. Wysocki 1879ed98953SRafael J. Wysocki device_links_write_lock(); 1889ed98953SRafael J. Wysocki device_pm_lock(); 1899ed98953SRafael J. Wysocki 1909ed98953SRafael J. Wysocki /* 1919ed98953SRafael J. Wysocki * If the supplier has not been fully registered yet or there is a 1929ed98953SRafael J. Wysocki * reverse dependency between the consumer and the supplier already in 1939ed98953SRafael J. Wysocki * the graph, return NULL. 1949ed98953SRafael J. Wysocki */ 1959ed98953SRafael J. Wysocki if (!device_pm_initialized(supplier) 1969ed98953SRafael J. Wysocki || device_is_dependent(consumer, supplier)) { 1979ed98953SRafael J. Wysocki link = NULL; 1989ed98953SRafael J. Wysocki goto out; 1999ed98953SRafael J. Wysocki } 2009ed98953SRafael J. Wysocki 2019ed98953SRafael J. Wysocki list_for_each_entry(link, &supplier->links.consumers, s_node) 2029ed98953SRafael J. Wysocki if (link->consumer == consumer) 2039ed98953SRafael J. Wysocki goto out; 2049ed98953SRafael J. Wysocki 20521d5c57bSRafael J. Wysocki link = kzalloc(sizeof(*link), GFP_KERNEL); 2069ed98953SRafael J. Wysocki if (!link) 2079ed98953SRafael J. Wysocki goto out; 2089ed98953SRafael J. Wysocki 209baa8809fSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) { 210baa8809fSRafael J. Wysocki if (flags & DL_FLAG_RPM_ACTIVE) { 21121d5c57bSRafael J. Wysocki if (pm_runtime_get_sync(supplier) < 0) { 21221d5c57bSRafael J. Wysocki pm_runtime_put_noidle(supplier); 21321d5c57bSRafael J. Wysocki kfree(link); 21421d5c57bSRafael J. Wysocki link = NULL; 21521d5c57bSRafael J. Wysocki goto out; 21621d5c57bSRafael J. Wysocki } 21721d5c57bSRafael J. Wysocki link->rpm_active = true; 21821d5c57bSRafael J. Wysocki } 219baa8809fSRafael J. Wysocki pm_runtime_new_link(consumer); 220baa8809fSRafael J. Wysocki } 2219ed98953SRafael J. Wysocki get_device(supplier); 2229ed98953SRafael J. Wysocki link->supplier = supplier; 2239ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->s_node); 2249ed98953SRafael J. Wysocki get_device(consumer); 2259ed98953SRafael J. Wysocki link->consumer = consumer; 2269ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->c_node); 2279ed98953SRafael J. Wysocki link->flags = flags; 2289ed98953SRafael J. Wysocki 22964df1148SLukas Wunner /* Determine the initial link state. */ 2309ed98953SRafael J. Wysocki if (flags & DL_FLAG_STATELESS) { 2319ed98953SRafael J. Wysocki link->status = DL_STATE_NONE; 2329ed98953SRafael J. Wysocki } else { 2339ed98953SRafael J. Wysocki switch (supplier->links.status) { 2349ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2359ed98953SRafael J. Wysocki switch (consumer->links.status) { 2369ed98953SRafael J. Wysocki case DL_DEV_PROBING: 23721d5c57bSRafael J. Wysocki /* 23821d5c57bSRafael J. Wysocki * Balance the decrementation of the supplier's 23921d5c57bSRafael J. Wysocki * runtime PM usage counter after consumer probe 24021d5c57bSRafael J. Wysocki * in driver_probe_device(). 24121d5c57bSRafael J. Wysocki */ 24221d5c57bSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) 24321d5c57bSRafael J. Wysocki pm_runtime_get_sync(supplier); 24421d5c57bSRafael J. Wysocki 2459ed98953SRafael J. Wysocki link->status = DL_STATE_CONSUMER_PROBE; 2469ed98953SRafael J. Wysocki break; 2479ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2489ed98953SRafael J. Wysocki link->status = DL_STATE_ACTIVE; 2499ed98953SRafael J. Wysocki break; 2509ed98953SRafael J. Wysocki default: 2519ed98953SRafael J. Wysocki link->status = DL_STATE_AVAILABLE; 2529ed98953SRafael J. Wysocki break; 2539ed98953SRafael J. Wysocki } 2549ed98953SRafael J. Wysocki break; 2559ed98953SRafael J. Wysocki case DL_DEV_UNBINDING: 2569ed98953SRafael J. Wysocki link->status = DL_STATE_SUPPLIER_UNBIND; 2579ed98953SRafael J. Wysocki break; 2589ed98953SRafael J. Wysocki default: 2599ed98953SRafael J. Wysocki link->status = DL_STATE_DORMANT; 2609ed98953SRafael J. Wysocki break; 2619ed98953SRafael J. Wysocki } 2629ed98953SRafael J. Wysocki } 2639ed98953SRafael J. Wysocki 2649ed98953SRafael J. Wysocki /* 2659ed98953SRafael J. Wysocki * Move the consumer and all of the devices depending on it to the end 2669ed98953SRafael J. Wysocki * of dpm_list and the devices_kset list. 2679ed98953SRafael J. Wysocki * 2689ed98953SRafael J. Wysocki * It is necessary to hold dpm_list locked throughout all that or else 2699ed98953SRafael J. Wysocki * we may end up suspending with a wrong ordering of it. 2709ed98953SRafael J. Wysocki */ 2719ed98953SRafael J. Wysocki device_reorder_to_tail(consumer, NULL); 2729ed98953SRafael J. Wysocki 2739ed98953SRafael J. Wysocki list_add_tail_rcu(&link->s_node, &supplier->links.consumers); 2749ed98953SRafael J. Wysocki list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); 2759ed98953SRafael J. Wysocki 2769ed98953SRafael J. Wysocki dev_info(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); 2779ed98953SRafael J. Wysocki 2789ed98953SRafael J. Wysocki out: 2799ed98953SRafael J. Wysocki device_pm_unlock(); 2809ed98953SRafael J. Wysocki device_links_write_unlock(); 2819ed98953SRafael J. Wysocki return link; 2829ed98953SRafael J. Wysocki } 2839ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_add); 2849ed98953SRafael J. Wysocki 2859ed98953SRafael J. Wysocki static void device_link_free(struct device_link *link) 2869ed98953SRafael J. Wysocki { 2879ed98953SRafael J. Wysocki put_device(link->consumer); 2889ed98953SRafael J. Wysocki put_device(link->supplier); 2899ed98953SRafael J. Wysocki kfree(link); 2909ed98953SRafael J. Wysocki } 2919ed98953SRafael J. Wysocki 2929ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 2939ed98953SRafael J. Wysocki static void __device_link_free_srcu(struct rcu_head *rhead) 2949ed98953SRafael J. Wysocki { 2959ed98953SRafael J. Wysocki device_link_free(container_of(rhead, struct device_link, rcu_head)); 2969ed98953SRafael J. Wysocki } 2979ed98953SRafael J. Wysocki 2989ed98953SRafael J. Wysocki static void __device_link_del(struct device_link *link) 2999ed98953SRafael J. Wysocki { 3009ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3019ed98953SRafael J. Wysocki dev_name(link->supplier)); 3029ed98953SRafael J. Wysocki 303baa8809fSRafael J. Wysocki if (link->flags & DL_FLAG_PM_RUNTIME) 304baa8809fSRafael J. Wysocki pm_runtime_drop_link(link->consumer); 305baa8809fSRafael J. Wysocki 3069ed98953SRafael J. Wysocki list_del_rcu(&link->s_node); 3079ed98953SRafael J. Wysocki list_del_rcu(&link->c_node); 3089ed98953SRafael J. Wysocki call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); 3099ed98953SRafael J. Wysocki } 3109ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 3119ed98953SRafael J. Wysocki static void __device_link_del(struct device_link *link) 3129ed98953SRafael J. Wysocki { 3139ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3149ed98953SRafael J. Wysocki dev_name(link->supplier)); 3159ed98953SRafael J. Wysocki 3169ed98953SRafael J. Wysocki list_del(&link->s_node); 3179ed98953SRafael J. Wysocki list_del(&link->c_node); 3189ed98953SRafael J. Wysocki device_link_free(link); 3199ed98953SRafael J. Wysocki } 3209ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 3219ed98953SRafael J. Wysocki 3229ed98953SRafael J. Wysocki /** 3239ed98953SRafael J. Wysocki * device_link_del - Delete a link between two devices. 3249ed98953SRafael J. Wysocki * @link: Device link to delete. 3259ed98953SRafael J. Wysocki * 3269ed98953SRafael J. Wysocki * The caller must ensure proper synchronization of this function with runtime 3279ed98953SRafael J. Wysocki * PM. 3289ed98953SRafael J. Wysocki */ 3299ed98953SRafael J. Wysocki void device_link_del(struct device_link *link) 3309ed98953SRafael J. Wysocki { 3319ed98953SRafael J. Wysocki device_links_write_lock(); 3329ed98953SRafael J. Wysocki device_pm_lock(); 3339ed98953SRafael J. Wysocki __device_link_del(link); 3349ed98953SRafael J. Wysocki device_pm_unlock(); 3359ed98953SRafael J. Wysocki device_links_write_unlock(); 3369ed98953SRafael J. Wysocki } 3379ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_del); 3389ed98953SRafael J. Wysocki 3399ed98953SRafael J. Wysocki static void device_links_missing_supplier(struct device *dev) 3409ed98953SRafael J. Wysocki { 3419ed98953SRafael J. Wysocki struct device_link *link; 3429ed98953SRafael J. Wysocki 3439ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) 3449ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE) 3459ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 3469ed98953SRafael J. Wysocki } 3479ed98953SRafael J. Wysocki 3489ed98953SRafael J. Wysocki /** 3499ed98953SRafael J. Wysocki * device_links_check_suppliers - Check presence of supplier drivers. 3509ed98953SRafael J. Wysocki * @dev: Consumer device. 3519ed98953SRafael J. Wysocki * 3529ed98953SRafael J. Wysocki * Check links from this device to any suppliers. Walk the list of the device's 3539ed98953SRafael J. Wysocki * links to suppliers and see if all of them are available. If not, simply 3549ed98953SRafael J. Wysocki * return -EPROBE_DEFER. 3559ed98953SRafael J. Wysocki * 3569ed98953SRafael J. Wysocki * We need to guarantee that the supplier will not go away after the check has 3579ed98953SRafael J. Wysocki * been positive here. It only can go away in __device_release_driver() and 3589ed98953SRafael J. Wysocki * that function checks the device's links to consumers. This means we need to 3599ed98953SRafael J. Wysocki * mark the link as "consumer probe in progress" to make the supplier removal 3609ed98953SRafael J. Wysocki * wait for us to complete (or bad things may happen). 3619ed98953SRafael J. Wysocki * 3629ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 3639ed98953SRafael J. Wysocki */ 3649ed98953SRafael J. Wysocki int device_links_check_suppliers(struct device *dev) 3659ed98953SRafael J. Wysocki { 3669ed98953SRafael J. Wysocki struct device_link *link; 3679ed98953SRafael J. Wysocki int ret = 0; 3689ed98953SRafael J. Wysocki 3699ed98953SRafael J. Wysocki device_links_write_lock(); 3709ed98953SRafael J. Wysocki 3719ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 3729ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 3739ed98953SRafael J. Wysocki continue; 3749ed98953SRafael J. Wysocki 3759ed98953SRafael J. Wysocki if (link->status != DL_STATE_AVAILABLE) { 3769ed98953SRafael J. Wysocki device_links_missing_supplier(dev); 3779ed98953SRafael J. Wysocki ret = -EPROBE_DEFER; 3789ed98953SRafael J. Wysocki break; 3799ed98953SRafael J. Wysocki } 3809ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_CONSUMER_PROBE); 3819ed98953SRafael J. Wysocki } 3829ed98953SRafael J. Wysocki dev->links.status = DL_DEV_PROBING; 3839ed98953SRafael J. Wysocki 3849ed98953SRafael J. Wysocki device_links_write_unlock(); 3859ed98953SRafael J. Wysocki return ret; 3869ed98953SRafael J. Wysocki } 3879ed98953SRafael J. Wysocki 3889ed98953SRafael J. Wysocki /** 3899ed98953SRafael J. Wysocki * device_links_driver_bound - Update device links after probing its driver. 3909ed98953SRafael J. Wysocki * @dev: Device to update the links for. 3919ed98953SRafael J. Wysocki * 3929ed98953SRafael J. Wysocki * The probe has been successful, so update links from this device to any 3939ed98953SRafael J. Wysocki * consumers by changing their status to "available". 3949ed98953SRafael J. Wysocki * 3959ed98953SRafael J. Wysocki * Also change the status of @dev's links to suppliers to "active". 3969ed98953SRafael J. Wysocki * 3979ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 3989ed98953SRafael J. Wysocki */ 3999ed98953SRafael J. Wysocki void device_links_driver_bound(struct device *dev) 4009ed98953SRafael J. Wysocki { 4019ed98953SRafael J. Wysocki struct device_link *link; 4029ed98953SRafael J. Wysocki 4039ed98953SRafael J. Wysocki device_links_write_lock(); 4049ed98953SRafael J. Wysocki 4059ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 4069ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4079ed98953SRafael J. Wysocki continue; 4089ed98953SRafael J. Wysocki 4099ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT); 4109ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4119ed98953SRafael J. Wysocki } 4129ed98953SRafael J. Wysocki 4139ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 4149ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4159ed98953SRafael J. Wysocki continue; 4169ed98953SRafael J. Wysocki 4179ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); 4189ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_ACTIVE); 4199ed98953SRafael J. Wysocki } 4209ed98953SRafael J. Wysocki 4219ed98953SRafael J. Wysocki dev->links.status = DL_DEV_DRIVER_BOUND; 4229ed98953SRafael J. Wysocki 4239ed98953SRafael J. Wysocki device_links_write_unlock(); 4249ed98953SRafael J. Wysocki } 4259ed98953SRafael J. Wysocki 4269ed98953SRafael J. Wysocki /** 4279ed98953SRafael J. Wysocki * __device_links_no_driver - Update links of a device without a driver. 4289ed98953SRafael J. Wysocki * @dev: Device without a drvier. 4299ed98953SRafael J. Wysocki * 4309ed98953SRafael J. Wysocki * Delete all non-persistent links from this device to any suppliers. 4319ed98953SRafael J. Wysocki * 4329ed98953SRafael J. Wysocki * Persistent links stay around, but their status is changed to "available", 4339ed98953SRafael J. Wysocki * unless they already are in the "supplier unbind in progress" state in which 4349ed98953SRafael J. Wysocki * case they need not be updated. 4359ed98953SRafael J. Wysocki * 4369ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4379ed98953SRafael J. Wysocki */ 4389ed98953SRafael J. Wysocki static void __device_links_no_driver(struct device *dev) 4399ed98953SRafael J. Wysocki { 4409ed98953SRafael J. Wysocki struct device_link *link, *ln; 4419ed98953SRafael J. Wysocki 4429ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 4439ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4449ed98953SRafael J. Wysocki continue; 4459ed98953SRafael J. Wysocki 4469ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_AUTOREMOVE) 4479ed98953SRafael J. Wysocki __device_link_del(link); 4489ed98953SRafael J. Wysocki else if (link->status != DL_STATE_SUPPLIER_UNBIND) 4499ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4509ed98953SRafael J. Wysocki } 4519ed98953SRafael J. Wysocki 4529ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 4539ed98953SRafael J. Wysocki } 4549ed98953SRafael J. Wysocki 4559ed98953SRafael J. Wysocki void device_links_no_driver(struct device *dev) 4569ed98953SRafael J. Wysocki { 4579ed98953SRafael J. Wysocki device_links_write_lock(); 4589ed98953SRafael J. Wysocki __device_links_no_driver(dev); 4599ed98953SRafael J. Wysocki device_links_write_unlock(); 4609ed98953SRafael J. Wysocki } 4619ed98953SRafael J. Wysocki 4629ed98953SRafael J. Wysocki /** 4639ed98953SRafael J. Wysocki * device_links_driver_cleanup - Update links after driver removal. 4649ed98953SRafael J. Wysocki * @dev: Device whose driver has just gone away. 4659ed98953SRafael J. Wysocki * 4669ed98953SRafael J. Wysocki * Update links to consumers for @dev by changing their status to "dormant" and 4679ed98953SRafael J. Wysocki * invoke %__device_links_no_driver() to update links to suppliers for it as 4689ed98953SRafael J. Wysocki * appropriate. 4699ed98953SRafael J. Wysocki * 4709ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4719ed98953SRafael J. Wysocki */ 4729ed98953SRafael J. Wysocki void device_links_driver_cleanup(struct device *dev) 4739ed98953SRafael J. Wysocki { 4749ed98953SRafael J. Wysocki struct device_link *link; 4759ed98953SRafael J. Wysocki 4769ed98953SRafael J. Wysocki device_links_write_lock(); 4779ed98953SRafael J. Wysocki 4789ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 4799ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4809ed98953SRafael J. Wysocki continue; 4819ed98953SRafael J. Wysocki 4829ed98953SRafael J. Wysocki WARN_ON(link->flags & DL_FLAG_AUTOREMOVE); 4839ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND); 4849ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_DORMANT); 4859ed98953SRafael J. Wysocki } 4869ed98953SRafael J. Wysocki 4879ed98953SRafael J. Wysocki __device_links_no_driver(dev); 4889ed98953SRafael J. Wysocki 4899ed98953SRafael J. Wysocki device_links_write_unlock(); 4909ed98953SRafael J. Wysocki } 4919ed98953SRafael J. Wysocki 4929ed98953SRafael J. Wysocki /** 4939ed98953SRafael J. Wysocki * device_links_busy - Check if there are any busy links to consumers. 4949ed98953SRafael J. Wysocki * @dev: Device to check. 4959ed98953SRafael J. Wysocki * 4969ed98953SRafael J. Wysocki * Check each consumer of the device and return 'true' if its link's status 4979ed98953SRafael J. Wysocki * is one of "consumer probe" or "active" (meaning that the given consumer is 4989ed98953SRafael J. Wysocki * probing right now or its driver is present). Otherwise, change the link 4999ed98953SRafael J. Wysocki * state to "supplier unbind" to prevent the consumer from being probed 5009ed98953SRafael J. Wysocki * successfully going forward. 5019ed98953SRafael J. Wysocki * 5029ed98953SRafael J. Wysocki * Return 'false' if there are no probing or active consumers. 5039ed98953SRafael J. Wysocki * 5049ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5059ed98953SRafael J. Wysocki */ 5069ed98953SRafael J. Wysocki bool device_links_busy(struct device *dev) 5079ed98953SRafael J. Wysocki { 5089ed98953SRafael J. Wysocki struct device_link *link; 5099ed98953SRafael J. Wysocki bool ret = false; 5109ed98953SRafael J. Wysocki 5119ed98953SRafael J. Wysocki device_links_write_lock(); 5129ed98953SRafael J. Wysocki 5139ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5149ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5159ed98953SRafael J. Wysocki continue; 5169ed98953SRafael J. Wysocki 5179ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE 5189ed98953SRafael J. Wysocki || link->status == DL_STATE_ACTIVE) { 5199ed98953SRafael J. Wysocki ret = true; 5209ed98953SRafael J. Wysocki break; 5219ed98953SRafael J. Wysocki } 5229ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 5239ed98953SRafael J. Wysocki } 5249ed98953SRafael J. Wysocki 5259ed98953SRafael J. Wysocki dev->links.status = DL_DEV_UNBINDING; 5269ed98953SRafael J. Wysocki 5279ed98953SRafael J. Wysocki device_links_write_unlock(); 5289ed98953SRafael J. Wysocki return ret; 5299ed98953SRafael J. Wysocki } 5309ed98953SRafael J. Wysocki 5319ed98953SRafael J. Wysocki /** 5329ed98953SRafael J. Wysocki * device_links_unbind_consumers - Force unbind consumers of the given device. 5339ed98953SRafael J. Wysocki * @dev: Device to unbind the consumers of. 5349ed98953SRafael J. Wysocki * 5359ed98953SRafael J. Wysocki * Walk the list of links to consumers for @dev and if any of them is in the 5369ed98953SRafael J. Wysocki * "consumer probe" state, wait for all device probes in progress to complete 5379ed98953SRafael J. Wysocki * and start over. 5389ed98953SRafael J. Wysocki * 5399ed98953SRafael J. Wysocki * If that's not the case, change the status of the link to "supplier unbind" 5409ed98953SRafael J. Wysocki * and check if the link was in the "active" state. If so, force the consumer 5419ed98953SRafael J. Wysocki * driver to unbind and start over (the consumer will not re-probe as we have 5429ed98953SRafael J. Wysocki * changed the state of the link already). 5439ed98953SRafael J. Wysocki * 5449ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5459ed98953SRafael J. Wysocki */ 5469ed98953SRafael J. Wysocki void device_links_unbind_consumers(struct device *dev) 5479ed98953SRafael J. Wysocki { 5489ed98953SRafael J. Wysocki struct device_link *link; 5499ed98953SRafael J. Wysocki 5509ed98953SRafael J. Wysocki start: 5519ed98953SRafael J. Wysocki device_links_write_lock(); 5529ed98953SRafael J. Wysocki 5539ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5549ed98953SRafael J. Wysocki enum device_link_state status; 5559ed98953SRafael J. Wysocki 5569ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5579ed98953SRafael J. Wysocki continue; 5589ed98953SRafael J. Wysocki 5599ed98953SRafael J. Wysocki status = link->status; 5609ed98953SRafael J. Wysocki if (status == DL_STATE_CONSUMER_PROBE) { 5619ed98953SRafael J. Wysocki device_links_write_unlock(); 5629ed98953SRafael J. Wysocki 5639ed98953SRafael J. Wysocki wait_for_device_probe(); 5649ed98953SRafael J. Wysocki goto start; 5659ed98953SRafael J. Wysocki } 5669ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 5679ed98953SRafael J. Wysocki if (status == DL_STATE_ACTIVE) { 5689ed98953SRafael J. Wysocki struct device *consumer = link->consumer; 5699ed98953SRafael J. Wysocki 5709ed98953SRafael J. Wysocki get_device(consumer); 5719ed98953SRafael J. Wysocki 5729ed98953SRafael J. Wysocki device_links_write_unlock(); 5739ed98953SRafael J. Wysocki 5749ed98953SRafael J. Wysocki device_release_driver_internal(consumer, NULL, 5759ed98953SRafael J. Wysocki consumer->parent); 5769ed98953SRafael J. Wysocki put_device(consumer); 5779ed98953SRafael J. Wysocki goto start; 5789ed98953SRafael J. Wysocki } 5799ed98953SRafael J. Wysocki } 5809ed98953SRafael J. Wysocki 5819ed98953SRafael J. Wysocki device_links_write_unlock(); 5829ed98953SRafael J. Wysocki } 5839ed98953SRafael J. Wysocki 5849ed98953SRafael J. Wysocki /** 5859ed98953SRafael J. Wysocki * device_links_purge - Delete existing links to other devices. 5869ed98953SRafael J. Wysocki * @dev: Target device. 5879ed98953SRafael J. Wysocki */ 5889ed98953SRafael J. Wysocki static void device_links_purge(struct device *dev) 5899ed98953SRafael J. Wysocki { 5909ed98953SRafael J. Wysocki struct device_link *link, *ln; 5919ed98953SRafael J. Wysocki 5929ed98953SRafael J. Wysocki /* 5939ed98953SRafael J. Wysocki * Delete all of the remaining links from this device to any other 5949ed98953SRafael J. Wysocki * devices (either consumers or suppliers). 5959ed98953SRafael J. Wysocki */ 5969ed98953SRafael J. Wysocki device_links_write_lock(); 5979ed98953SRafael J. Wysocki 5989ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 5999ed98953SRafael J. Wysocki WARN_ON(link->status == DL_STATE_ACTIVE); 6009ed98953SRafael J. Wysocki __device_link_del(link); 6019ed98953SRafael J. Wysocki } 6029ed98953SRafael J. Wysocki 6039ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) { 6049ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT && 6059ed98953SRafael J. Wysocki link->status != DL_STATE_NONE); 6069ed98953SRafael J. Wysocki __device_link_del(link); 6079ed98953SRafael J. Wysocki } 6089ed98953SRafael J. Wysocki 6099ed98953SRafael J. Wysocki device_links_write_unlock(); 6109ed98953SRafael J. Wysocki } 6119ed98953SRafael J. Wysocki 6129ed98953SRafael J. Wysocki /* Device links support end. */ 6139ed98953SRafael J. Wysocki 6141da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 6151da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 616e105b8bfSDan Williams static struct kobject *dev_kobj; 617e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 618e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 6191da177e4SLinus Torvalds 6205e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 6215e33bc41SRafael J. Wysocki 6225e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 6235e33bc41SRafael J. Wysocki { 6245e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 6255e33bc41SRafael J. Wysocki } 6265e33bc41SRafael J. Wysocki 6275e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 6285e33bc41SRafael J. Wysocki { 6295e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 6305e33bc41SRafael J. Wysocki } 6315e33bc41SRafael J. Wysocki 6325e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 6335e33bc41SRafael J. Wysocki { 6345e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 6355e33bc41SRafael J. Wysocki return 0; 6365e33bc41SRafael J. Wysocki 6375e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 6385e33bc41SRafael J. Wysocki msleep(5); 6395e33bc41SRafael J. Wysocki return restart_syscall(); 6405e33bc41SRafael J. Wysocki } 6415e33bc41SRafael J. Wysocki 6424e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 6434e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6444e886c29SGreg Kroah-Hartman { 6454e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 6464e886c29SGreg Kroah-Hartman } 6474e886c29SGreg Kroah-Hartman #else 6484e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6494e886c29SGreg Kroah-Hartman { 6504e886c29SGreg Kroah-Hartman return 1; 6514e886c29SGreg Kroah-Hartman } 6524e886c29SGreg Kroah-Hartman #endif 6531da177e4SLinus Torvalds 6543e95637aSAlan Stern /** 6553e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 6563e95637aSAlan Stern * @dev: struct device to get the name of 6573e95637aSAlan Stern * 6583e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 6599169c012Syan * the device is not bound to a driver, it will return the name of the bus 6603e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 6613e95637aSAlan Stern * string will be returned. 6623e95637aSAlan Stern */ 663bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 6643e95637aSAlan Stern { 6653589972eSAlan Stern struct device_driver *drv; 6663589972eSAlan Stern 6673589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 6683589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 6693589972eSAlan Stern * never change once they are set, so they don't need special care. 6703589972eSAlan Stern */ 6713589972eSAlan Stern drv = ACCESS_ONCE(dev->driver); 6723589972eSAlan Stern return drv ? drv->name : 673a456b702SJean Delvare (dev->bus ? dev->bus->name : 674a456b702SJean Delvare (dev->class ? dev->class->name : "")); 6753e95637aSAlan Stern } 676310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 6773e95637aSAlan Stern 6781da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 6791da177e4SLinus Torvalds 6804a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 6814a3ad20cSGreg Kroah-Hartman char *buf) 6821da177e4SLinus Torvalds { 6831da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 684b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 6854a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 6861da177e4SLinus Torvalds 6871da177e4SLinus Torvalds if (dev_attr->show) 68854b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 689815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 69053a9c87eSGreg Kroah-Hartman print_symbol("dev_attr_show: %s returned bad count\n", 69153a9c87eSGreg Kroah-Hartman (unsigned long)dev_attr->show); 692815d2d50SAndrew Morton } 6931da177e4SLinus Torvalds return ret; 6941da177e4SLinus Torvalds } 6951da177e4SLinus Torvalds 6964a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 6971da177e4SLinus Torvalds const char *buf, size_t count) 6981da177e4SLinus Torvalds { 6991da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 700b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 7014a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds if (dev_attr->store) 70454b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 7051da177e4SLinus Torvalds return ret; 7061da177e4SLinus Torvalds } 7071da177e4SLinus Torvalds 70852cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 7091da177e4SLinus Torvalds .show = dev_attr_show, 7101da177e4SLinus Torvalds .store = dev_attr_store, 7111da177e4SLinus Torvalds }; 7121da177e4SLinus Torvalds 713ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 714ca22e56dSKay Sievers 715ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 716ca22e56dSKay Sievers struct device_attribute *attr, 717ca22e56dSKay Sievers const char *buf, size_t size) 718ca22e56dSKay Sievers { 719ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 720ca22e56dSKay Sievers char *end; 721ca22e56dSKay Sievers unsigned long new = simple_strtoul(buf, &end, 0); 722ca22e56dSKay Sievers if (end == buf) 723ca22e56dSKay Sievers return -EINVAL; 724ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 725ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 726ca22e56dSKay Sievers return size; 727ca22e56dSKay Sievers } 728ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 729ca22e56dSKay Sievers 730ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 731ca22e56dSKay Sievers struct device_attribute *attr, 732ca22e56dSKay Sievers char *buf) 733ca22e56dSKay Sievers { 734ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 735ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); 736ca22e56dSKay Sievers } 737ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 738ca22e56dSKay Sievers 739ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 740ca22e56dSKay Sievers struct device_attribute *attr, 741ca22e56dSKay Sievers const char *buf, size_t size) 742ca22e56dSKay Sievers { 743ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 744ca22e56dSKay Sievers char *end; 745ca22e56dSKay Sievers long new = simple_strtol(buf, &end, 0); 746ca22e56dSKay Sievers if (end == buf || new > INT_MAX || new < INT_MIN) 747ca22e56dSKay Sievers return -EINVAL; 748ca22e56dSKay Sievers *(int *)(ea->var) = new; 749ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 750ca22e56dSKay Sievers return size; 751ca22e56dSKay Sievers } 752ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 753ca22e56dSKay Sievers 754ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 755ca22e56dSKay Sievers struct device_attribute *attr, 756ca22e56dSKay Sievers char *buf) 757ca22e56dSKay Sievers { 758ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 759ca22e56dSKay Sievers 760ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); 761ca22e56dSKay Sievers } 762ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 7631da177e4SLinus Torvalds 76491872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 76591872392SBorislav Petkov const char *buf, size_t size) 76691872392SBorislav Petkov { 76791872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 76891872392SBorislav Petkov 76991872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 77091872392SBorislav Petkov return -EINVAL; 77191872392SBorislav Petkov 77291872392SBorislav Petkov return size; 77391872392SBorislav Petkov } 77491872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 77591872392SBorislav Petkov 77691872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 77791872392SBorislav Petkov char *buf) 77891872392SBorislav Petkov { 77991872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 78091872392SBorislav Petkov 78191872392SBorislav Petkov return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); 78291872392SBorislav Petkov } 78391872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 78491872392SBorislav Petkov 7851da177e4SLinus Torvalds /** 7861da177e4SLinus Torvalds * device_release - free device structure. 7871da177e4SLinus Torvalds * @kobj: device's kobject. 7881da177e4SLinus Torvalds * 7891da177e4SLinus Torvalds * This is called once the reference count for the object 7901da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 7911da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 7921da177e4SLinus Torvalds */ 7931da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 7941da177e4SLinus Torvalds { 795b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 796fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 7971da177e4SLinus Torvalds 798a525a3ddSMing Lei /* 799a525a3ddSMing Lei * Some platform devices are driven without driver attached 800a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 801a525a3ddSMing Lei * all resources are released. 802a525a3ddSMing Lei * 803a525a3ddSMing Lei * Drivers still can add resources into device after device 804a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 805a525a3ddSMing Lei * possible memory leak. 806a525a3ddSMing Lei */ 807a525a3ddSMing Lei devres_release_all(dev); 808a525a3ddSMing Lei 8091da177e4SLinus Torvalds if (dev->release) 8101da177e4SLinus Torvalds dev->release(dev); 811f9f852dfSKay Sievers else if (dev->type && dev->type->release) 812f9f852dfSKay Sievers dev->type->release(dev); 8132620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 8142620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 815f810a5cfSArjan van de Ven else 816f810a5cfSArjan van de Ven WARN(1, KERN_ERR "Device '%s' does not have a release() " 8174a3ad20cSGreg Kroah-Hartman "function, it is broken and must be fixed.\n", 8181e0b2cf9SKay Sievers dev_name(dev)); 819fb069a5dSGreg Kroah-Hartman kfree(p); 8201da177e4SLinus Torvalds } 8211da177e4SLinus Torvalds 822bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 823bc451f20SEric W. Biederman { 824b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 825bc451f20SEric W. Biederman const void *ns = NULL; 826bc451f20SEric W. Biederman 827bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 828bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 829bc451f20SEric W. Biederman 830bc451f20SEric W. Biederman return ns; 831bc451f20SEric W. Biederman } 832bc451f20SEric W. Biederman 8338f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 8341da177e4SLinus Torvalds .release = device_release, 8351da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 836bc451f20SEric W. Biederman .namespace = device_namespace, 8371da177e4SLinus Torvalds }; 8381da177e4SLinus Torvalds 8391da177e4SLinus Torvalds 840312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 8411da177e4SLinus Torvalds { 8421da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 8431da177e4SLinus Torvalds 8448f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 845b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8461da177e4SLinus Torvalds if (dev->bus) 8471da177e4SLinus Torvalds return 1; 84823681e47SGreg Kroah-Hartman if (dev->class) 84923681e47SGreg Kroah-Hartman return 1; 8501da177e4SLinus Torvalds } 8511da177e4SLinus Torvalds return 0; 8521da177e4SLinus Torvalds } 8531da177e4SLinus Torvalds 854312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 8551da177e4SLinus Torvalds { 856b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8571da177e4SLinus Torvalds 85823681e47SGreg Kroah-Hartman if (dev->bus) 8591da177e4SLinus Torvalds return dev->bus->name; 86023681e47SGreg Kroah-Hartman if (dev->class) 86123681e47SGreg Kroah-Hartman return dev->class->name; 86223681e47SGreg Kroah-Hartman return NULL; 8631da177e4SLinus Torvalds } 8641da177e4SLinus Torvalds 8657eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 8667eff2e7aSKay Sievers struct kobj_uevent_env *env) 8671da177e4SLinus Torvalds { 868b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8691da177e4SLinus Torvalds int retval = 0; 8701da177e4SLinus Torvalds 8716fcf53acSKay Sievers /* add device node properties if present */ 87223681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 8736fcf53acSKay Sievers const char *tmp; 8746fcf53acSKay Sievers const char *name; 8752c9ede55SAl Viro umode_t mode = 0; 8764e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 8774e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 8786fcf53acSKay Sievers 8797eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 8807eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 8813c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 8826fcf53acSKay Sievers if (name) { 8836fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 884e454cea2SKay Sievers if (mode) 885e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 8864e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 8874e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 8884e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 8894e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 8903c2670e6SKay Sievers kfree(tmp); 8916fcf53acSKay Sievers } 89223681e47SGreg Kroah-Hartman } 89323681e47SGreg Kroah-Hartman 894414264f9SKay Sievers if (dev->type && dev->type->name) 8957eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 896414264f9SKay Sievers 897239378f1SKay Sievers if (dev->driver) 8987eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 899239378f1SKay Sievers 90007d57a32SGrant Likely /* Add common DT information about the device */ 90107d57a32SGrant Likely of_device_uevent(dev, env); 90207d57a32SGrant Likely 9031da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 9047eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 9057eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 906f9f852dfSKay Sievers if (retval) 9077dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 9081e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 9091da177e4SLinus Torvalds } 9101da177e4SLinus Torvalds 9112620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 9127eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 9137eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 914f9f852dfSKay Sievers if (retval) 9157dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 9161e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9172b3a302aSHarvey Harrison __func__, retval); 9182620efefSGreg Kroah-Hartman } 919f9f852dfSKay Sievers 920eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 9217eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 9227eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 923f9f852dfSKay Sievers if (retval) 9247dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 9251e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9262b3a302aSHarvey Harrison __func__, retval); 9272620efefSGreg Kroah-Hartman } 9282620efefSGreg Kroah-Hartman 9291da177e4SLinus Torvalds return retval; 9301da177e4SLinus Torvalds } 9311da177e4SLinus Torvalds 9329cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 933312c004dSKay Sievers .filter = dev_uevent_filter, 934312c004dSKay Sievers .name = dev_uevent_name, 935312c004dSKay Sievers .uevent = dev_uevent, 9361da177e4SLinus Torvalds }; 9371da177e4SLinus Torvalds 938c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 93916574dccSKay Sievers char *buf) 94016574dccSKay Sievers { 94116574dccSKay Sievers struct kobject *top_kobj; 94216574dccSKay Sievers struct kset *kset; 9437eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 94416574dccSKay Sievers int i; 94516574dccSKay Sievers size_t count = 0; 94616574dccSKay Sievers int retval; 94716574dccSKay Sievers 94816574dccSKay Sievers /* search the kset, the device belongs to */ 94916574dccSKay Sievers top_kobj = &dev->kobj; 9505c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 95116574dccSKay Sievers top_kobj = top_kobj->parent; 95216574dccSKay Sievers if (!top_kobj->kset) 95316574dccSKay Sievers goto out; 9545c5daf65SKay Sievers 95516574dccSKay Sievers kset = top_kobj->kset; 95616574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 95716574dccSKay Sievers goto out; 95816574dccSKay Sievers 95916574dccSKay Sievers /* respect filter */ 96016574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 96116574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 96216574dccSKay Sievers goto out; 96316574dccSKay Sievers 9647eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 9657eff2e7aSKay Sievers if (!env) 966c7308c81SGreg Kroah-Hartman return -ENOMEM; 967c7308c81SGreg Kroah-Hartman 96816574dccSKay Sievers /* let the kset specific function add its keys */ 9697eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 97016574dccSKay Sievers if (retval) 97116574dccSKay Sievers goto out; 97216574dccSKay Sievers 97316574dccSKay Sievers /* copy keys to file */ 9747eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 9757eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 97616574dccSKay Sievers out: 9777eff2e7aSKay Sievers kfree(env); 97816574dccSKay Sievers return count; 97916574dccSKay Sievers } 98016574dccSKay Sievers 981c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 982a7fd6706SKay Sievers const char *buf, size_t count) 983a7fd6706SKay Sievers { 98460a96a59SKay Sievers enum kobject_action action; 98560a96a59SKay Sievers 9863f5468c9SKay Sievers if (kobject_action_type(buf, count, &action) == 0) 98760a96a59SKay Sievers kobject_uevent(&dev->kobj, action); 9883f5468c9SKay Sievers else 9893f5468c9SKay Sievers dev_err(dev, "uevent: unknown action-string\n"); 990a7fd6706SKay Sievers return count; 991a7fd6706SKay Sievers } 992c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 993a7fd6706SKay Sievers 994c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 9954f3549d7SRafael J. Wysocki char *buf) 9964f3549d7SRafael J. Wysocki { 9974f3549d7SRafael J. Wysocki bool val; 9984f3549d7SRafael J. Wysocki 9995e33bc41SRafael J. Wysocki device_lock(dev); 10004f3549d7SRafael J. Wysocki val = !dev->offline; 10015e33bc41SRafael J. Wysocki device_unlock(dev); 10024f3549d7SRafael J. Wysocki return sprintf(buf, "%u\n", val); 10034f3549d7SRafael J. Wysocki } 10044f3549d7SRafael J. Wysocki 1005c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 10064f3549d7SRafael J. Wysocki const char *buf, size_t count) 10074f3549d7SRafael J. Wysocki { 10084f3549d7SRafael J. Wysocki bool val; 10094f3549d7SRafael J. Wysocki int ret; 10104f3549d7SRafael J. Wysocki 10114f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 10124f3549d7SRafael J. Wysocki if (ret < 0) 10134f3549d7SRafael J. Wysocki return ret; 10144f3549d7SRafael J. Wysocki 10155e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 10165e33bc41SRafael J. Wysocki if (ret) 10175e33bc41SRafael J. Wysocki return ret; 10185e33bc41SRafael J. Wysocki 10194f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 10204f3549d7SRafael J. Wysocki unlock_device_hotplug(); 10214f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 10224f3549d7SRafael J. Wysocki } 1023c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 10244f3549d7SRafael J. Wysocki 1025fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 1026621a1672SDmitry Torokhov { 10273e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 1028621a1672SDmitry Torokhov } 1029621a1672SDmitry Torokhov 1030fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 1031a4dbd674SDavid Brownell const struct attribute_group **groups) 1032621a1672SDmitry Torokhov { 10333e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 1034621a1672SDmitry Torokhov } 1035de0ff00dSGreg Kroah-Hartman 10362620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 10372620efefSGreg Kroah-Hartman { 10382620efefSGreg Kroah-Hartman struct class *class = dev->class; 1039aed65af1SStephen Hemminger const struct device_type *type = dev->type; 1040621a1672SDmitry Torokhov int error; 10412620efefSGreg Kroah-Hartman 1042621a1672SDmitry Torokhov if (class) { 1043d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 10442620efefSGreg Kroah-Hartman if (error) 1045621a1672SDmitry Torokhov return error; 1046f9f852dfSKay Sievers } 1047f9f852dfSKay Sievers 1048621a1672SDmitry Torokhov if (type) { 1049621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 1050f9f852dfSKay Sievers if (error) 1051a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 1052f9f852dfSKay Sievers } 1053621a1672SDmitry Torokhov 1054621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 1055f9f852dfSKay Sievers if (error) 1056621a1672SDmitry Torokhov goto err_remove_type_groups; 1057621a1672SDmitry Torokhov 10584f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 1059c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 10604f3549d7SRafael J. Wysocki if (error) 1061ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 10624f3549d7SRafael J. Wysocki } 10634f3549d7SRafael J. Wysocki 1064621a1672SDmitry Torokhov return 0; 1065621a1672SDmitry Torokhov 1066ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 1067ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 1068621a1672SDmitry Torokhov err_remove_type_groups: 1069621a1672SDmitry Torokhov if (type) 1070621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1071d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 1072d05a6f96SGreg Kroah-Hartman if (class) 1073d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1074f9f852dfSKay Sievers 10752620efefSGreg Kroah-Hartman return error; 10762620efefSGreg Kroah-Hartman } 10772620efefSGreg Kroah-Hartman 10782620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 10792620efefSGreg Kroah-Hartman { 10802620efefSGreg Kroah-Hartman struct class *class = dev->class; 1081aed65af1SStephen Hemminger const struct device_type *type = dev->type; 10822620efefSGreg Kroah-Hartman 1083c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 1084621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 1085f9f852dfSKay Sievers 1086621a1672SDmitry Torokhov if (type) 1087621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1088621a1672SDmitry Torokhov 1089a6b01dedSGreg Kroah-Hartman if (class) 1090d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1091c97415a7SStefan Achatz } 10922620efefSGreg Kroah-Hartman 1093c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 109423681e47SGreg Kroah-Hartman char *buf) 109523681e47SGreg Kroah-Hartman { 109623681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 109723681e47SGreg Kroah-Hartman } 1098c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 1099ad6a1e1cSTejun Heo 1100ca22e56dSKay Sievers /* /sys/devices/ */ 1101881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 11021da177e4SLinus Torvalds 11031da177e4SLinus Torvalds /** 110452cdbdd4SGrygorii Strashko * devices_kset_move_before - Move device in the devices_kset's list. 110552cdbdd4SGrygorii Strashko * @deva: Device to move. 110652cdbdd4SGrygorii Strashko * @devb: Device @deva should come before. 110752cdbdd4SGrygorii Strashko */ 110852cdbdd4SGrygorii Strashko static void devices_kset_move_before(struct device *deva, struct device *devb) 110952cdbdd4SGrygorii Strashko { 111052cdbdd4SGrygorii Strashko if (!devices_kset) 111152cdbdd4SGrygorii Strashko return; 111252cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s before %s\n", 111352cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 111452cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 111552cdbdd4SGrygorii Strashko list_move_tail(&deva->kobj.entry, &devb->kobj.entry); 111652cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 111752cdbdd4SGrygorii Strashko } 111852cdbdd4SGrygorii Strashko 111952cdbdd4SGrygorii Strashko /** 112052cdbdd4SGrygorii Strashko * devices_kset_move_after - Move device in the devices_kset's list. 112152cdbdd4SGrygorii Strashko * @deva: Device to move 112252cdbdd4SGrygorii Strashko * @devb: Device @deva should come after. 112352cdbdd4SGrygorii Strashko */ 112452cdbdd4SGrygorii Strashko static void devices_kset_move_after(struct device *deva, struct device *devb) 112552cdbdd4SGrygorii Strashko { 112652cdbdd4SGrygorii Strashko if (!devices_kset) 112752cdbdd4SGrygorii Strashko return; 112852cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s after %s\n", 112952cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 113052cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 113152cdbdd4SGrygorii Strashko list_move(&deva->kobj.entry, &devb->kobj.entry); 113252cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 113352cdbdd4SGrygorii Strashko } 113452cdbdd4SGrygorii Strashko 113552cdbdd4SGrygorii Strashko /** 113652cdbdd4SGrygorii Strashko * devices_kset_move_last - move the device to the end of devices_kset's list. 113752cdbdd4SGrygorii Strashko * @dev: device to move 113852cdbdd4SGrygorii Strashko */ 113952cdbdd4SGrygorii Strashko void devices_kset_move_last(struct device *dev) 114052cdbdd4SGrygorii Strashko { 114152cdbdd4SGrygorii Strashko if (!devices_kset) 114252cdbdd4SGrygorii Strashko return; 114352cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); 114452cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 114552cdbdd4SGrygorii Strashko list_move_tail(&dev->kobj.entry, &devices_kset->list); 114652cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 114752cdbdd4SGrygorii Strashko } 114852cdbdd4SGrygorii Strashko 114952cdbdd4SGrygorii Strashko /** 11501da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 11511da177e4SLinus Torvalds * @dev: device. 11521da177e4SLinus Torvalds * @attr: device attribute descriptor. 11531da177e4SLinus Torvalds */ 115426579ab7SPhil Carmody int device_create_file(struct device *dev, 115526579ab7SPhil Carmody const struct device_attribute *attr) 11561da177e4SLinus Torvalds { 11571da177e4SLinus Torvalds int error = 0; 11588f46baaaSFelipe Balbi 11598f46baaaSFelipe Balbi if (dev) { 11608f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 116197521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 116297521978Sdyoung@redhat.com attr->attr.name); 11638f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 116497521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 116597521978Sdyoung@redhat.com attr->attr.name); 11661da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 11678f46baaaSFelipe Balbi } 11688f46baaaSFelipe Balbi 11691da177e4SLinus Torvalds return error; 11701da177e4SLinus Torvalds } 117186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 11721da177e4SLinus Torvalds 11731da177e4SLinus Torvalds /** 11741da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 11751da177e4SLinus Torvalds * @dev: device. 11761da177e4SLinus Torvalds * @attr: device attribute descriptor. 11771da177e4SLinus Torvalds */ 117826579ab7SPhil Carmody void device_remove_file(struct device *dev, 117926579ab7SPhil Carmody const struct device_attribute *attr) 11801da177e4SLinus Torvalds { 11810c98b19fSCornelia Huck if (dev) 11821da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 11831da177e4SLinus Torvalds } 118486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 11851da177e4SLinus Torvalds 11862589f188SGreg Kroah-Hartman /** 11876b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 11886b0afc2aSTejun Heo * @dev: device. 11896b0afc2aSTejun Heo * @attr: device attribute descriptor. 11906b0afc2aSTejun Heo * 11916b0afc2aSTejun Heo * See kernfs_remove_self() for details. 11926b0afc2aSTejun Heo */ 11936b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 11946b0afc2aSTejun Heo const struct device_attribute *attr) 11956b0afc2aSTejun Heo { 11966b0afc2aSTejun Heo if (dev) 11976b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 11986b0afc2aSTejun Heo else 11996b0afc2aSTejun Heo return false; 12006b0afc2aSTejun Heo } 12016b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 12026b0afc2aSTejun Heo 12036b0afc2aSTejun Heo /** 12042589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 12052589f188SGreg Kroah-Hartman * @dev: device. 12062589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 12072589f188SGreg Kroah-Hartman */ 120866ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 120966ecb92bSPhil Carmody const struct bin_attribute *attr) 12102589f188SGreg Kroah-Hartman { 12112589f188SGreg Kroah-Hartman int error = -EINVAL; 12122589f188SGreg Kroah-Hartman if (dev) 12132589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 12142589f188SGreg Kroah-Hartman return error; 12152589f188SGreg Kroah-Hartman } 12162589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 12172589f188SGreg Kroah-Hartman 12182589f188SGreg Kroah-Hartman /** 12192589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 12202589f188SGreg Kroah-Hartman * @dev: device. 12212589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 12222589f188SGreg Kroah-Hartman */ 122366ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 122466ecb92bSPhil Carmody const struct bin_attribute *attr) 12252589f188SGreg Kroah-Hartman { 12262589f188SGreg Kroah-Hartman if (dev) 12272589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 12282589f188SGreg Kroah-Hartman } 12292589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 12302589f188SGreg Kroah-Hartman 123134bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 123234bb61f9SJames Bottomley { 1233f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1234f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 123534bb61f9SJames Bottomley 123634bb61f9SJames Bottomley get_device(dev); 123734bb61f9SJames Bottomley } 123834bb61f9SJames Bottomley 123934bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 124034bb61f9SJames Bottomley { 1241f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1242f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 124334bb61f9SJames Bottomley 124434bb61f9SJames Bottomley put_device(dev); 124534bb61f9SJames Bottomley } 124634bb61f9SJames Bottomley 12471da177e4SLinus Torvalds /** 12481da177e4SLinus Torvalds * device_initialize - init device structure. 12491da177e4SLinus Torvalds * @dev: device. 12501da177e4SLinus Torvalds * 12515739411aSCornelia Huck * This prepares the device for use by other layers by initializing 12525739411aSCornelia Huck * its fields. 12531da177e4SLinus Torvalds * It is the first half of device_register(), if called by 12545739411aSCornelia Huck * that function, though it can also be called separately, so one 12555739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 12565739411aSCornelia Huck * may be used for reference counting of @dev after calling this 12575739411aSCornelia Huck * function. 12585739411aSCornelia Huck * 1259b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 1260b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 1261b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 1262b10d5efdSAlan Stern * @dev. 1263b10d5efdSAlan Stern * 12645739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 12655739411aSCornelia Huck * @dev directly once you have called this function. 12661da177e4SLinus Torvalds */ 12671da177e4SLinus Torvalds void device_initialize(struct device *dev) 12681da177e4SLinus Torvalds { 1269881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 1270f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 12711da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 12723142788bSThomas Gleixner mutex_init(&dev->mutex); 12731704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 12749ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 12759ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 12763b98aeafSAlan Stern device_pm_init(dev); 127787348136SChristoph Hellwig set_dev_node(dev, -1); 12784a7cc831SJiang Liu #ifdef CONFIG_GENERIC_MSI_IRQ 12794a7cc831SJiang Liu INIT_LIST_HEAD(&dev->msi_list); 12804a7cc831SJiang Liu #endif 12819ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.consumers); 12829ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.suppliers); 12839ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 12841da177e4SLinus Torvalds } 128586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 12861da177e4SLinus Torvalds 1287d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 1288f0ee61a6SGreg Kroah-Hartman { 1289f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 1290f0ee61a6SGreg Kroah-Hartman 1291f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 12924ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 1293881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 1294f0ee61a6SGreg Kroah-Hartman 129586406245SKay Sievers return virtual_dir; 1296f0ee61a6SGreg Kroah-Hartman } 1297f0ee61a6SGreg Kroah-Hartman 1298bc451f20SEric W. Biederman struct class_dir { 1299bc451f20SEric W. Biederman struct kobject kobj; 1300bc451f20SEric W. Biederman struct class *class; 1301bc451f20SEric W. Biederman }; 1302bc451f20SEric W. Biederman 1303bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 1304bc451f20SEric W. Biederman 1305bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 1306bc451f20SEric W. Biederman { 1307bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1308bc451f20SEric W. Biederman kfree(dir); 1309bc451f20SEric W. Biederman } 1310bc451f20SEric W. Biederman 1311bc451f20SEric W. Biederman static const 1312bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 1313bc451f20SEric W. Biederman { 1314bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1315bc451f20SEric W. Biederman return dir->class->ns_type; 1316bc451f20SEric W. Biederman } 1317bc451f20SEric W. Biederman 1318bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 1319bc451f20SEric W. Biederman .release = class_dir_release, 1320bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 1321bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 1322bc451f20SEric W. Biederman }; 1323bc451f20SEric W. Biederman 1324bc451f20SEric W. Biederman static struct kobject * 1325bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 1326bc451f20SEric W. Biederman { 1327bc451f20SEric W. Biederman struct class_dir *dir; 1328bc451f20SEric W. Biederman int retval; 1329bc451f20SEric W. Biederman 1330bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 1331bc451f20SEric W. Biederman if (!dir) 1332bc451f20SEric W. Biederman return NULL; 1333bc451f20SEric W. Biederman 1334bc451f20SEric W. Biederman dir->class = class; 1335bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 1336bc451f20SEric W. Biederman 13376b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 1338bc451f20SEric W. Biederman 1339bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 1340bc451f20SEric W. Biederman if (retval < 0) { 1341bc451f20SEric W. Biederman kobject_put(&dir->kobj); 1342bc451f20SEric W. Biederman return NULL; 1343bc451f20SEric W. Biederman } 1344bc451f20SEric W. Biederman return &dir->kobj; 1345bc451f20SEric W. Biederman } 1346bc451f20SEric W. Biederman 1347e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex); 1348bc451f20SEric W. Biederman 1349c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 1350c744aeaeSCornelia Huck struct device *parent) 135140fa5422SGreg Kroah-Hartman { 135286406245SKay Sievers if (dev->class) { 135386406245SKay Sievers struct kobject *kobj = NULL; 135486406245SKay Sievers struct kobject *parent_kobj; 135586406245SKay Sievers struct kobject *k; 135686406245SKay Sievers 1357ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 135839aba963SKay Sievers /* block disks show up in /sys/block */ 1359e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 136039aba963SKay Sievers if (parent && parent->class == &block_class) 136139aba963SKay Sievers return &parent->kobj; 13626b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 136339aba963SKay Sievers } 1364ead454feSRandy Dunlap #endif 1365e52eec13SAndi Kleen 136686406245SKay Sievers /* 136786406245SKay Sievers * If we have no parent, we live in "virtual". 13680f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 13690f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 137086406245SKay Sievers */ 137186406245SKay Sievers if (parent == NULL) 137286406245SKay Sievers parent_kobj = virtual_device_parent(dev); 137324b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 137486406245SKay Sievers return &parent->kobj; 137586406245SKay Sievers else 137686406245SKay Sievers parent_kobj = &parent->kobj; 137786406245SKay Sievers 137877d3d7c1STejun Heo mutex_lock(&gdp_mutex); 137977d3d7c1STejun Heo 138086406245SKay Sievers /* find our class-directory at the parent and reference it */ 13816b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 13826b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 138386406245SKay Sievers if (k->parent == parent_kobj) { 138486406245SKay Sievers kobj = kobject_get(k); 138586406245SKay Sievers break; 138686406245SKay Sievers } 13876b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 138877d3d7c1STejun Heo if (kobj) { 138977d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 139086406245SKay Sievers return kobj; 139177d3d7c1STejun Heo } 139286406245SKay Sievers 139386406245SKay Sievers /* or create a new class-directory at the parent device */ 1394bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 13950f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 139677d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 139743968d2fSGreg Kroah-Hartman return k; 139886406245SKay Sievers } 139986406245SKay Sievers 1400ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 1401ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 1402ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 1403ca22e56dSKay Sievers 140486406245SKay Sievers if (parent) 1405c744aeaeSCornelia Huck return &parent->kobj; 1406c744aeaeSCornelia Huck return NULL; 1407c744aeaeSCornelia Huck } 1408da231fd5SKay Sievers 1409cebf8fd1SMing Lei static inline bool live_in_glue_dir(struct kobject *kobj, 1410cebf8fd1SMing Lei struct device *dev) 1411cebf8fd1SMing Lei { 1412cebf8fd1SMing Lei if (!kobj || !dev->class || 1413cebf8fd1SMing Lei kobj->kset != &dev->class->p->glue_dirs) 1414cebf8fd1SMing Lei return false; 1415cebf8fd1SMing Lei return true; 1416cebf8fd1SMing Lei } 1417cebf8fd1SMing Lei 1418cebf8fd1SMing Lei static inline struct kobject *get_glue_dir(struct device *dev) 1419cebf8fd1SMing Lei { 1420cebf8fd1SMing Lei return dev->kobj.parent; 1421cebf8fd1SMing Lei } 1422cebf8fd1SMing Lei 1423cebf8fd1SMing Lei /* 1424cebf8fd1SMing Lei * make sure cleaning up dir as the last step, we need to make 1425cebf8fd1SMing Lei * sure .release handler of kobject is run with holding the 1426cebf8fd1SMing Lei * global lock 1427cebf8fd1SMing Lei */ 142863b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 1429da231fd5SKay Sievers { 14300f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 1431cebf8fd1SMing Lei if (!live_in_glue_dir(glue_dir, dev)) 1432da231fd5SKay Sievers return; 1433da231fd5SKay Sievers 1434e4a60d13SYijing Wang mutex_lock(&gdp_mutex); 14350f4dafc0SKay Sievers kobject_put(glue_dir); 1436e4a60d13SYijing Wang mutex_unlock(&gdp_mutex); 1437da231fd5SKay Sievers } 143863b6971aSCornelia Huck 14392ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 14402ee97cafSCornelia Huck { 14415590f319SBenjamin Herrenschmidt struct device_node *of_node = dev_of_node(dev); 14422ee97cafSCornelia Huck int error; 14432ee97cafSCornelia Huck 14445590f319SBenjamin Herrenschmidt if (of_node) { 14455590f319SBenjamin Herrenschmidt error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node"); 14465590f319SBenjamin Herrenschmidt if (error) 14475590f319SBenjamin Herrenschmidt dev_warn(dev, "Error %d creating of_node link\n",error); 14485590f319SBenjamin Herrenschmidt /* An error here doesn't warrant bringing down the device */ 14495590f319SBenjamin Herrenschmidt } 14505590f319SBenjamin Herrenschmidt 14512ee97cafSCornelia Huck if (!dev->class) 14522ee97cafSCornelia Huck return 0; 1453da231fd5SKay Sievers 14541fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 14556b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 14562ee97cafSCornelia Huck "subsystem"); 14572ee97cafSCornelia Huck if (error) 14585590f319SBenjamin Herrenschmidt goto out_devnode; 1459da231fd5SKay Sievers 14604e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 14614f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 14624f01a757SDmitry Torokhov "device"); 14634f01a757SDmitry Torokhov if (error) 146439aba963SKay Sievers goto out_subsys; 14652ee97cafSCornelia Huck } 146639aba963SKay Sievers 1467ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 146839aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 1469e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 147039aba963SKay Sievers return 0; 1471ead454feSRandy Dunlap #endif 147239aba963SKay Sievers 147339aba963SKay Sievers /* link in the class directory pointing to the device */ 14746b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 147539aba963SKay Sievers &dev->kobj, dev_name(dev)); 147639aba963SKay Sievers if (error) 147739aba963SKay Sievers goto out_device; 147839aba963SKay Sievers 14792ee97cafSCornelia Huck return 0; 14802ee97cafSCornelia Huck 148139aba963SKay Sievers out_device: 148239aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 1483da231fd5SKay Sievers 14842ee97cafSCornelia Huck out_subsys: 14852ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 14865590f319SBenjamin Herrenschmidt out_devnode: 14875590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 14882ee97cafSCornelia Huck return error; 14892ee97cafSCornelia Huck } 14902ee97cafSCornelia Huck 14912ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 14922ee97cafSCornelia Huck { 14935590f319SBenjamin Herrenschmidt if (dev_of_node(dev)) 14945590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 14955590f319SBenjamin Herrenschmidt 14962ee97cafSCornelia Huck if (!dev->class) 14972ee97cafSCornelia Huck return; 1498da231fd5SKay Sievers 14994e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 1500da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 15012ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 1502ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 1503e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 150439aba963SKay Sievers return; 1505ead454feSRandy Dunlap #endif 15066b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 15072ee97cafSCornelia Huck } 15082ee97cafSCornelia Huck 15091da177e4SLinus Torvalds /** 1510413c239fSStephen Rothwell * dev_set_name - set a device name 1511413c239fSStephen Rothwell * @dev: device 151246232366SRandy Dunlap * @fmt: format string for the device's name 1513413c239fSStephen Rothwell */ 1514413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 1515413c239fSStephen Rothwell { 1516413c239fSStephen Rothwell va_list vargs; 15171fa5ae85SKay Sievers int err; 1518413c239fSStephen Rothwell 1519413c239fSStephen Rothwell va_start(vargs, fmt); 15201fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 1521413c239fSStephen Rothwell va_end(vargs); 15221fa5ae85SKay Sievers return err; 1523413c239fSStephen Rothwell } 1524413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 1525413c239fSStephen Rothwell 1526413c239fSStephen Rothwell /** 1527e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 1528e105b8bfSDan Williams * @dev: device 1529e105b8bfSDan Williams * 1530e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 1531e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 1532e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 1533e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 15340d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 15350d4e293cSPeter Korsgaard * the link. 1536e105b8bfSDan Williams */ 1537e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 1538e105b8bfSDan Williams { 1539e105b8bfSDan Williams struct kobject *kobj; 1540e105b8bfSDan Williams 1541e105b8bfSDan Williams if (dev->class) 1542e105b8bfSDan Williams kobj = dev->class->dev_kobj; 1543e105b8bfSDan Williams else 1544e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 1545e105b8bfSDan Williams 1546e105b8bfSDan Williams return kobj; 1547e105b8bfSDan Williams } 1548e105b8bfSDan Williams 1549e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 1550e105b8bfSDan Williams { 1551e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1552e105b8bfSDan Williams int error = 0; 1553e105b8bfSDan Williams char devt_str[15]; 1554e105b8bfSDan Williams 1555e105b8bfSDan Williams if (kobj) { 1556e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1557e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 1558e105b8bfSDan Williams } 1559e105b8bfSDan Williams 1560e105b8bfSDan Williams return error; 1561e105b8bfSDan Williams } 1562e105b8bfSDan Williams 1563e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 1564e105b8bfSDan Williams { 1565e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1566e105b8bfSDan Williams char devt_str[15]; 1567e105b8bfSDan Williams 1568e105b8bfSDan Williams if (kobj) { 1569e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1570e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 1571e105b8bfSDan Williams } 1572e105b8bfSDan Williams } 1573e105b8bfSDan Williams 1574b4028437SGreg Kroah-Hartman int device_private_init(struct device *dev) 1575b4028437SGreg Kroah-Hartman { 1576b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 1577b4028437SGreg Kroah-Hartman if (!dev->p) 1578b4028437SGreg Kroah-Hartman return -ENOMEM; 1579b4028437SGreg Kroah-Hartman dev->p->device = dev; 1580b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 1581b4028437SGreg Kroah-Hartman klist_children_put); 1582ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 1583b4028437SGreg Kroah-Hartman return 0; 1584b4028437SGreg Kroah-Hartman } 1585b4028437SGreg Kroah-Hartman 1586e105b8bfSDan Williams /** 15871da177e4SLinus Torvalds * device_add - add device to device hierarchy. 15881da177e4SLinus Torvalds * @dev: device. 15891da177e4SLinus Torvalds * 15901da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 15911da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 15921da177e4SLinus Torvalds * 15935739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 15941da177e4SLinus Torvalds * to the global and sibling lists for the device, then 15951da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 15965739411aSCornelia Huck * 1597b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 1598b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 1599b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 1600b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 1601b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 1602b10d5efdSAlan Stern * and register a fresh new struct device instead. 1603b10d5efdSAlan Stern * 16045739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 16055739411aSCornelia Huck * if it returned an error! Always use put_device() to give up your 16065739411aSCornelia Huck * reference instead. 16071da177e4SLinus Torvalds */ 16081da177e4SLinus Torvalds int device_add(struct device *dev) 16091da177e4SLinus Torvalds { 161035dbf4efSViresh Kumar struct device *parent; 1611ca22e56dSKay Sievers struct kobject *kobj; 1612c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 1613c906a48aSGreg Kroah-Hartman int error = -EINVAL; 1614cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1615775b64d2SRafael J. Wysocki 16161da177e4SLinus Torvalds dev = get_device(dev); 1617c906a48aSGreg Kroah-Hartman if (!dev) 1618c906a48aSGreg Kroah-Hartman goto done; 1619c906a48aSGreg Kroah-Hartman 1620fb069a5dSGreg Kroah-Hartman if (!dev->p) { 1621b4028437SGreg Kroah-Hartman error = device_private_init(dev); 1622b4028437SGreg Kroah-Hartman if (error) 1623fb069a5dSGreg Kroah-Hartman goto done; 1624fb069a5dSGreg Kroah-Hartman } 1625fb069a5dSGreg Kroah-Hartman 16261fa5ae85SKay Sievers /* 16271fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 16281fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 16291fa5ae85SKay Sievers * the name, and force the use of dev_name() 16301fa5ae85SKay Sievers */ 16311fa5ae85SKay Sievers if (dev->init_name) { 1632acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 16331fa5ae85SKay Sievers dev->init_name = NULL; 16341fa5ae85SKay Sievers } 1635c906a48aSGreg Kroah-Hartman 1636ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 1637ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 1638ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 1639ca22e56dSKay Sievers 1640e6309e75SThomas Gleixner if (!dev_name(dev)) { 1641e6309e75SThomas Gleixner error = -EINVAL; 16425c8563d7SKay Sievers goto name_error; 1643e6309e75SThomas Gleixner } 16441da177e4SLinus Torvalds 16451e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 1646c205ef48SGreg Kroah-Hartman 16471da177e4SLinus Torvalds parent = get_device(dev->parent); 1648ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 1649ca22e56dSKay Sievers if (kobj) 1650ca22e56dSKay Sievers dev->kobj.parent = kobj; 16511da177e4SLinus Torvalds 16520d358f22SYinghai Lu /* use parent numa_node */ 165356f2de81SZhen Lei if (parent && (dev_to_node(dev) == NUMA_NO_NODE)) 16540d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 16550d358f22SYinghai Lu 16561da177e4SLinus Torvalds /* first, register with generic layer. */ 16578a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 16588a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 1659cebf8fd1SMing Lei if (error) { 1660cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 16611da177e4SLinus Torvalds goto Error; 1662cebf8fd1SMing Lei } 1663a7fd6706SKay Sievers 166437022644SBrian Walsh /* notify platform of device entry */ 166537022644SBrian Walsh if (platform_notify) 166637022644SBrian Walsh platform_notify(dev); 166737022644SBrian Walsh 1668c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 1669a306eea4SCornelia Huck if (error) 1670a306eea4SCornelia Huck goto attrError; 1671a7fd6706SKay Sievers 16722ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 16732ee97cafSCornelia Huck if (error) 16742ee97cafSCornelia Huck goto SymlinkError; 1675dc0afa83SCornelia Huck error = device_add_attrs(dev); 1676dc0afa83SCornelia Huck if (error) 16772620efefSGreg Kroah-Hartman goto AttrsError; 1678dc0afa83SCornelia Huck error = bus_add_device(dev); 1679dc0afa83SCornelia Huck if (error) 16801da177e4SLinus Torvalds goto BusError; 16813b98aeafSAlan Stern error = dpm_sysfs_add(dev); 168257eee3d2SRafael J. Wysocki if (error) 16833b98aeafSAlan Stern goto DPMError; 16843b98aeafSAlan Stern device_pm_add(dev); 1685ec0676eeSAlan Stern 16860cd75047SSergey Klyaus if (MAJOR(dev->devt)) { 16870cd75047SSergey Klyaus error = device_create_file(dev, &dev_attr_dev); 16880cd75047SSergey Klyaus if (error) 16890cd75047SSergey Klyaus goto DevAttrError; 16900cd75047SSergey Klyaus 16910cd75047SSergey Klyaus error = device_create_sys_dev_entry(dev); 16920cd75047SSergey Klyaus if (error) 16930cd75047SSergey Klyaus goto SysEntryError; 16940cd75047SSergey Klyaus 16950cd75047SSergey Klyaus devtmpfs_create_node(dev); 16960cd75047SSergey Klyaus } 16970cd75047SSergey Klyaus 1698ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 1699268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 1700ec0676eeSAlan Stern */ 1701ec0676eeSAlan Stern if (dev->bus) 1702ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1703ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 1704ec0676eeSAlan Stern 170553877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 17062023c610SAlan Stern bus_probe_device(dev); 17071da177e4SLinus Torvalds if (parent) 1708f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1709f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 17101da177e4SLinus Torvalds 17115d9fd169SGreg Kroah-Hartman if (dev->class) { 1712ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1713c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 17145a3ceb86STejun Heo klist_add_tail(&dev->knode_class, 17156b6e39a6SKay Sievers &dev->class->p->klist_devices); 1716c47ed219SGreg Kroah-Hartman 1717c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 1718184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1719ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1720c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 1721c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 1722ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 17235d9fd169SGreg Kroah-Hartman } 1724c906a48aSGreg Kroah-Hartman done: 17251da177e4SLinus Torvalds put_device(dev); 17261da177e4SLinus Torvalds return error; 17270cd75047SSergey Klyaus SysEntryError: 17280cd75047SSergey Klyaus if (MAJOR(dev->devt)) 17290cd75047SSergey Klyaus device_remove_file(dev, &dev_attr_dev); 17300cd75047SSergey Klyaus DevAttrError: 17310cd75047SSergey Klyaus device_pm_remove(dev); 17320cd75047SSergey Klyaus dpm_sysfs_remove(dev); 17333b98aeafSAlan Stern DPMError: 173457eee3d2SRafael J. Wysocki bus_remove_device(dev); 173557eee3d2SRafael J. Wysocki BusError: 17362620efefSGreg Kroah-Hartman device_remove_attrs(dev); 17372620efefSGreg Kroah-Hartman AttrsError: 17382ee97cafSCornelia Huck device_remove_class_symlinks(dev); 17392ee97cafSCornelia Huck SymlinkError: 1740c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 174123681e47SGreg Kroah-Hartman attrError: 1742312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1743cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 17441da177e4SLinus Torvalds kobject_del(&dev->kobj); 17451da177e4SLinus Torvalds Error: 1746cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 17471da177e4SLinus Torvalds put_device(parent); 17485c8563d7SKay Sievers name_error: 17495c8563d7SKay Sievers kfree(dev->p); 17505c8563d7SKay Sievers dev->p = NULL; 1751c906a48aSGreg Kroah-Hartman goto done; 17521da177e4SLinus Torvalds } 175386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 17541da177e4SLinus Torvalds 17551da177e4SLinus Torvalds /** 17561da177e4SLinus Torvalds * device_register - register a device with the system. 17571da177e4SLinus Torvalds * @dev: pointer to the device structure 17581da177e4SLinus Torvalds * 17591da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 17601da177e4SLinus Torvalds * and add it to the system. The two steps can be called 17611da177e4SLinus Torvalds * separately, but this is the easiest and most common. 17621da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 17631da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 17641da177e4SLinus Torvalds * before it is added to the hierarchy. 17655739411aSCornelia Huck * 1766b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 1767b10d5efdSAlan Stern * and device_add(). 1768b10d5efdSAlan Stern * 17695739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 17705739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 17715739411aSCornelia Huck * reference initialized in this function instead. 17721da177e4SLinus Torvalds */ 17731da177e4SLinus Torvalds int device_register(struct device *dev) 17741da177e4SLinus Torvalds { 17751da177e4SLinus Torvalds device_initialize(dev); 17761da177e4SLinus Torvalds return device_add(dev); 17771da177e4SLinus Torvalds } 177886df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 17791da177e4SLinus Torvalds 17801da177e4SLinus Torvalds /** 17811da177e4SLinus Torvalds * get_device - increment reference count for device. 17821da177e4SLinus Torvalds * @dev: device. 17831da177e4SLinus Torvalds * 17841da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 17851da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 17861da177e4SLinus Torvalds * pointer passed in. 17871da177e4SLinus Torvalds */ 17881da177e4SLinus Torvalds struct device *get_device(struct device *dev) 17891da177e4SLinus Torvalds { 1790b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 17911da177e4SLinus Torvalds } 179286df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 17931da177e4SLinus Torvalds 17941da177e4SLinus Torvalds /** 17951da177e4SLinus Torvalds * put_device - decrement reference count. 17961da177e4SLinus Torvalds * @dev: device in question. 17971da177e4SLinus Torvalds */ 17981da177e4SLinus Torvalds void put_device(struct device *dev) 17991da177e4SLinus Torvalds { 1800edfaa7c3SKay Sievers /* might_sleep(); */ 18011da177e4SLinus Torvalds if (dev) 18021da177e4SLinus Torvalds kobject_put(&dev->kobj); 18031da177e4SLinus Torvalds } 180486df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 18051da177e4SLinus Torvalds 18061da177e4SLinus Torvalds /** 18071da177e4SLinus Torvalds * device_del - delete device from system. 18081da177e4SLinus Torvalds * @dev: device. 18091da177e4SLinus Torvalds * 18101da177e4SLinus Torvalds * This is the first part of the device unregistration 18111da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 18121da177e4SLinus Torvalds * from here, has it removed from the other driver model 18131da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 18141da177e4SLinus Torvalds * from the kobject hierarchy. 18151da177e4SLinus Torvalds * 18161da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 18171da177e4SLinus Torvalds * also called manually. 18181da177e4SLinus Torvalds */ 18191da177e4SLinus Torvalds void device_del(struct device *dev) 18201da177e4SLinus Torvalds { 18211da177e4SLinus Torvalds struct device *parent = dev->parent; 1822cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1823c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 18241da177e4SLinus Torvalds 1825ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 1826ec0676eeSAlan Stern * before dpm_sysfs_remove(). 1827ec0676eeSAlan Stern */ 1828ec0676eeSAlan Stern if (dev->bus) 1829ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1830ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 18319ed98953SRafael J. Wysocki 18329ed98953SRafael J. Wysocki device_links_purge(dev); 18333b98aeafSAlan Stern dpm_sysfs_remove(dev); 18341da177e4SLinus Torvalds if (parent) 1835f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 1836e105b8bfSDan Williams if (MAJOR(dev->devt)) { 18372b2af54aSKay Sievers devtmpfs_delete_node(dev); 1838e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 1839c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 1840e105b8bfSDan Williams } 1841b9d9c82bSKay Sievers if (dev->class) { 1842da231fd5SKay Sievers device_remove_class_symlinks(dev); 184399ef3ef8SKay Sievers 1844ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1845c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 1846184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1847ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1848c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 1849c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 1850c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 18515a3ceb86STejun Heo klist_del(&dev->knode_class); 1852ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 1853b9d9c82bSKay Sievers } 1854c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 18552620efefSGreg Kroah-Hartman device_remove_attrs(dev); 185628953533SBenjamin Herrenschmidt bus_remove_device(dev); 18574b6d1f12SLongX Zhang device_pm_remove(dev); 1858d1c3414cSGrant Likely driver_deferred_probe_del(dev); 1859478573c9SLukas Wunner device_remove_properties(dev); 18601da177e4SLinus Torvalds 18611da177e4SLinus Torvalds /* Notify the platform of the removal, in case they 18621da177e4SLinus Torvalds * need to do anything... 18631da177e4SLinus Torvalds */ 18641da177e4SLinus Torvalds if (platform_notify_remove) 18651da177e4SLinus Torvalds platform_notify_remove(dev); 1866599bad38SJoerg Roedel if (dev->bus) 1867599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1868599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 1869312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1870cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 18711da177e4SLinus Torvalds kobject_del(&dev->kobj); 1872cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 18731da177e4SLinus Torvalds put_device(parent); 18741da177e4SLinus Torvalds } 187586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 18761da177e4SLinus Torvalds 18771da177e4SLinus Torvalds /** 18781da177e4SLinus Torvalds * device_unregister - unregister device from system. 18791da177e4SLinus Torvalds * @dev: device going away. 18801da177e4SLinus Torvalds * 18811da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 18821da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 18831da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 18841da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 18851da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 18861da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 18871da177e4SLinus Torvalds */ 18881da177e4SLinus Torvalds void device_unregister(struct device *dev) 18891da177e4SLinus Torvalds { 18901e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 18911da177e4SLinus Torvalds device_del(dev); 18921da177e4SLinus Torvalds put_device(dev); 18931da177e4SLinus Torvalds } 189486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 18951da177e4SLinus Torvalds 18963d060aebSAndy Shevchenko static struct device *prev_device(struct klist_iter *i) 18973d060aebSAndy Shevchenko { 18983d060aebSAndy Shevchenko struct klist_node *n = klist_prev(i); 18993d060aebSAndy Shevchenko struct device *dev = NULL; 19003d060aebSAndy Shevchenko struct device_private *p; 19013d060aebSAndy Shevchenko 19023d060aebSAndy Shevchenko if (n) { 19033d060aebSAndy Shevchenko p = to_device_private_parent(n); 19043d060aebSAndy Shevchenko dev = p->device; 19053d060aebSAndy Shevchenko } 19063d060aebSAndy Shevchenko return dev; 19073d060aebSAndy Shevchenko } 19083d060aebSAndy Shevchenko 190936239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 191036239577Smochel@digitalimplant.org { 191136239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 1912f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 1913f791b8c8SGreg Kroah-Hartman struct device_private *p; 1914f791b8c8SGreg Kroah-Hartman 1915f791b8c8SGreg Kroah-Hartman if (n) { 1916f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 1917f791b8c8SGreg Kroah-Hartman dev = p->device; 1918f791b8c8SGreg Kroah-Hartman } 1919f791b8c8SGreg Kroah-Hartman return dev; 192036239577Smochel@digitalimplant.org } 192136239577Smochel@digitalimplant.org 19221da177e4SLinus Torvalds /** 1923e454cea2SKay Sievers * device_get_devnode - path of device node file 19246fcf53acSKay Sievers * @dev: device 1925e454cea2SKay Sievers * @mode: returned file access mode 19263c2670e6SKay Sievers * @uid: returned file owner 19273c2670e6SKay Sievers * @gid: returned file group 19286fcf53acSKay Sievers * @tmp: possibly allocated string 19296fcf53acSKay Sievers * 19306fcf53acSKay Sievers * Return the relative path of a possible device node. 19316fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 19326fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 19336fcf53acSKay Sievers * freed by the caller. 19346fcf53acSKay Sievers */ 1935e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 19364e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 19373c2670e6SKay Sievers const char **tmp) 19386fcf53acSKay Sievers { 19396fcf53acSKay Sievers char *s; 19406fcf53acSKay Sievers 19416fcf53acSKay Sievers *tmp = NULL; 19426fcf53acSKay Sievers 19436fcf53acSKay Sievers /* the device type may provide a specific name */ 1944e454cea2SKay Sievers if (dev->type && dev->type->devnode) 19453c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 19466fcf53acSKay Sievers if (*tmp) 19476fcf53acSKay Sievers return *tmp; 19486fcf53acSKay Sievers 19496fcf53acSKay Sievers /* the class may provide a specific name */ 1950e454cea2SKay Sievers if (dev->class && dev->class->devnode) 1951e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 19526fcf53acSKay Sievers if (*tmp) 19536fcf53acSKay Sievers return *tmp; 19546fcf53acSKay Sievers 19556fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 19566fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 19576fcf53acSKay Sievers return dev_name(dev); 19586fcf53acSKay Sievers 19596fcf53acSKay Sievers /* replace '!' in the name with '/' */ 1960a29fd614SRasmus Villemoes s = kstrdup(dev_name(dev), GFP_KERNEL); 1961a29fd614SRasmus Villemoes if (!s) 19626fcf53acSKay Sievers return NULL; 1963a29fd614SRasmus Villemoes strreplace(s, '!', '/'); 1964a29fd614SRasmus Villemoes return *tmp = s; 19656fcf53acSKay Sievers } 19666fcf53acSKay Sievers 19676fcf53acSKay Sievers /** 19681da177e4SLinus Torvalds * device_for_each_child - device child iterator. 1969c41455fbSRandy Dunlap * @parent: parent struct device. 19701da177e4SLinus Torvalds * @fn: function to be called for each device. 1971f8878dcbSRobert P. J. Day * @data: data for the callback. 19721da177e4SLinus Torvalds * 1973c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 19741da177e4SLinus Torvalds * passing it @data. 19751da177e4SLinus Torvalds * 19761da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 19771da177e4SLinus Torvalds * other than 0, we break out and return that value. 19781da177e4SLinus Torvalds */ 197936239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 19804a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 19811da177e4SLinus Torvalds { 198236239577Smochel@digitalimplant.org struct klist_iter i; 19831da177e4SLinus Torvalds struct device *child; 19841da177e4SLinus Torvalds int error = 0; 19851da177e4SLinus Torvalds 1986014c90dbSGreg Kroah-Hartman if (!parent->p) 1987014c90dbSGreg Kroah-Hartman return 0; 1988014c90dbSGreg Kroah-Hartman 1989f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 199036239577Smochel@digitalimplant.org while ((child = next_device(&i)) && !error) 199136239577Smochel@digitalimplant.org error = fn(child, data); 199236239577Smochel@digitalimplant.org klist_iter_exit(&i); 19931da177e4SLinus Torvalds return error; 19941da177e4SLinus Torvalds } 199586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 19961da177e4SLinus Torvalds 19975ab69981SCornelia Huck /** 19983d060aebSAndy Shevchenko * device_for_each_child_reverse - device child iterator in reversed order. 19993d060aebSAndy Shevchenko * @parent: parent struct device. 20003d060aebSAndy Shevchenko * @fn: function to be called for each device. 20013d060aebSAndy Shevchenko * @data: data for the callback. 20023d060aebSAndy Shevchenko * 20033d060aebSAndy Shevchenko * Iterate over @parent's child devices, and call @fn for each, 20043d060aebSAndy Shevchenko * passing it @data. 20053d060aebSAndy Shevchenko * 20063d060aebSAndy Shevchenko * We check the return of @fn each time. If it returns anything 20073d060aebSAndy Shevchenko * other than 0, we break out and return that value. 20083d060aebSAndy Shevchenko */ 20093d060aebSAndy Shevchenko int device_for_each_child_reverse(struct device *parent, void *data, 20103d060aebSAndy Shevchenko int (*fn)(struct device *dev, void *data)) 20113d060aebSAndy Shevchenko { 20123d060aebSAndy Shevchenko struct klist_iter i; 20133d060aebSAndy Shevchenko struct device *child; 20143d060aebSAndy Shevchenko int error = 0; 20153d060aebSAndy Shevchenko 20163d060aebSAndy Shevchenko if (!parent->p) 20173d060aebSAndy Shevchenko return 0; 20183d060aebSAndy Shevchenko 20193d060aebSAndy Shevchenko klist_iter_init(&parent->p->klist_children, &i); 20203d060aebSAndy Shevchenko while ((child = prev_device(&i)) && !error) 20213d060aebSAndy Shevchenko error = fn(child, data); 20223d060aebSAndy Shevchenko klist_iter_exit(&i); 20233d060aebSAndy Shevchenko return error; 20243d060aebSAndy Shevchenko } 20253d060aebSAndy Shevchenko EXPORT_SYMBOL_GPL(device_for_each_child_reverse); 20263d060aebSAndy Shevchenko 20273d060aebSAndy Shevchenko /** 20285ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 20295ab69981SCornelia Huck * @parent: parent struct device 20305ab69981SCornelia Huck * @match: Callback function to check device 2031f8878dcbSRobert P. J. Day * @data: Data to pass to match function 20325ab69981SCornelia Huck * 20335ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 20345ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 20355ab69981SCornelia Huck * determined by the @match callback. 20365ab69981SCornelia Huck * 20375ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 20385ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 20395ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 20405ab69981SCornelia Huck * and not iterate over any more devices. 2041a4e2400aSFederico Vaga * 2042a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 20435ab69981SCornelia Huck */ 20445ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 20454a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 20465ab69981SCornelia Huck { 20475ab69981SCornelia Huck struct klist_iter i; 20485ab69981SCornelia Huck struct device *child; 20495ab69981SCornelia Huck 20505ab69981SCornelia Huck if (!parent) 20515ab69981SCornelia Huck return NULL; 20525ab69981SCornelia Huck 2053f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 20545ab69981SCornelia Huck while ((child = next_device(&i))) 20555ab69981SCornelia Huck if (match(child, data) && get_device(child)) 20565ab69981SCornelia Huck break; 20575ab69981SCornelia Huck klist_iter_exit(&i); 20585ab69981SCornelia Huck return child; 20595ab69981SCornelia Huck } 206086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 20615ab69981SCornelia Huck 20621da177e4SLinus Torvalds int __init devices_init(void) 20631da177e4SLinus Torvalds { 2064881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 2065881c6cfdSGreg Kroah-Hartman if (!devices_kset) 2066881c6cfdSGreg Kroah-Hartman return -ENOMEM; 2067e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 2068e105b8bfSDan Williams if (!dev_kobj) 2069e105b8bfSDan Williams goto dev_kobj_err; 2070e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 2071e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 2072e105b8bfSDan Williams goto block_kobj_err; 2073e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 2074e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 2075e105b8bfSDan Williams goto char_kobj_err; 2076e105b8bfSDan Williams 2077881c6cfdSGreg Kroah-Hartman return 0; 2078e105b8bfSDan Williams 2079e105b8bfSDan Williams char_kobj_err: 2080e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 2081e105b8bfSDan Williams block_kobj_err: 2082e105b8bfSDan Williams kobject_put(dev_kobj); 2083e105b8bfSDan Williams dev_kobj_err: 2084e105b8bfSDan Williams kset_unregister(devices_kset); 2085e105b8bfSDan Williams return -ENOMEM; 20861da177e4SLinus Torvalds } 20871da177e4SLinus Torvalds 20884f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 20894f3549d7SRafael J. Wysocki { 20904f3549d7SRafael J. Wysocki int ret; 20914f3549d7SRafael J. Wysocki 20924f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 20934f3549d7SRafael J. Wysocki if (ret) 20944f3549d7SRafael J. Wysocki return ret; 20954f3549d7SRafael J. Wysocki 20964f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 20974f3549d7SRafael J. Wysocki } 20984f3549d7SRafael J. Wysocki 20994f3549d7SRafael J. Wysocki /** 21004f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 21014f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 21024f3549d7SRafael J. Wysocki * 21034f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 21044f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 21054f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 21064f3549d7SRafael J. Wysocki * is executed. 21074f3549d7SRafael J. Wysocki * 21084f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 21094f3549d7SRafael J. Wysocki */ 21104f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 21114f3549d7SRafael J. Wysocki { 21124f3549d7SRafael J. Wysocki int ret; 21134f3549d7SRafael J. Wysocki 21144f3549d7SRafael J. Wysocki if (dev->offline_disabled) 21154f3549d7SRafael J. Wysocki return -EPERM; 21164f3549d7SRafael J. Wysocki 21174f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 21184f3549d7SRafael J. Wysocki if (ret) 21194f3549d7SRafael J. Wysocki return ret; 21204f3549d7SRafael J. Wysocki 21214f3549d7SRafael J. Wysocki device_lock(dev); 21224f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 21234f3549d7SRafael J. Wysocki if (dev->offline) { 21244f3549d7SRafael J. Wysocki ret = 1; 21254f3549d7SRafael J. Wysocki } else { 21264f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 21274f3549d7SRafael J. Wysocki if (!ret) { 21284f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 21294f3549d7SRafael J. Wysocki dev->offline = true; 21304f3549d7SRafael J. Wysocki } 21314f3549d7SRafael J. Wysocki } 21324f3549d7SRafael J. Wysocki } 21334f3549d7SRafael J. Wysocki device_unlock(dev); 21344f3549d7SRafael J. Wysocki 21354f3549d7SRafael J. Wysocki return ret; 21364f3549d7SRafael J. Wysocki } 21374f3549d7SRafael J. Wysocki 21384f3549d7SRafael J. Wysocki /** 21394f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 21404f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 21414f3549d7SRafael J. Wysocki * 21424f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 21434f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 21444f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 21454f3549d7SRafael J. Wysocki * 21464f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 21474f3549d7SRafael J. Wysocki */ 21484f3549d7SRafael J. Wysocki int device_online(struct device *dev) 21494f3549d7SRafael J. Wysocki { 21504f3549d7SRafael J. Wysocki int ret = 0; 21514f3549d7SRafael J. Wysocki 21524f3549d7SRafael J. Wysocki device_lock(dev); 21534f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 21544f3549d7SRafael J. Wysocki if (dev->offline) { 21554f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 21564f3549d7SRafael J. Wysocki if (!ret) { 21574f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 21584f3549d7SRafael J. Wysocki dev->offline = false; 21594f3549d7SRafael J. Wysocki } 21604f3549d7SRafael J. Wysocki } else { 21614f3549d7SRafael J. Wysocki ret = 1; 21624f3549d7SRafael J. Wysocki } 21634f3549d7SRafael J. Wysocki } 21644f3549d7SRafael J. Wysocki device_unlock(dev); 21654f3549d7SRafael J. Wysocki 21664f3549d7SRafael J. Wysocki return ret; 21674f3549d7SRafael J. Wysocki } 21684f3549d7SRafael J. Wysocki 21697f100d15SKarthigan Srinivasan struct root_device { 21700aa0dc41SMark McLoughlin struct device dev; 21710aa0dc41SMark McLoughlin struct module *owner; 21720aa0dc41SMark McLoughlin }; 21730aa0dc41SMark McLoughlin 217493058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 2175481e2079SFerenc Wagner { 2176481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 2177481e2079SFerenc Wagner } 21780aa0dc41SMark McLoughlin 21790aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 21800aa0dc41SMark McLoughlin { 21810aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 21820aa0dc41SMark McLoughlin } 21830aa0dc41SMark McLoughlin 21840aa0dc41SMark McLoughlin /** 21850aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 21860aa0dc41SMark McLoughlin * @name: root device name 21870aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 21880aa0dc41SMark McLoughlin * 21890aa0dc41SMark McLoughlin * This function allocates a root device and registers it 21900aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 21910aa0dc41SMark McLoughlin * device, use root_device_unregister(). 21920aa0dc41SMark McLoughlin * 21930aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 21940aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 21950aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 21960aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 21970aa0dc41SMark McLoughlin * 21980aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 21990aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 22000aa0dc41SMark McLoughlin * in sysfs. 22010aa0dc41SMark McLoughlin * 2202f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2203f0eae0edSJani Nikula * 22040aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 22050aa0dc41SMark McLoughlin */ 22060aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 22070aa0dc41SMark McLoughlin { 22080aa0dc41SMark McLoughlin struct root_device *root; 22090aa0dc41SMark McLoughlin int err = -ENOMEM; 22100aa0dc41SMark McLoughlin 22110aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 22120aa0dc41SMark McLoughlin if (!root) 22130aa0dc41SMark McLoughlin return ERR_PTR(err); 22140aa0dc41SMark McLoughlin 2215acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 22160aa0dc41SMark McLoughlin if (err) { 22170aa0dc41SMark McLoughlin kfree(root); 22180aa0dc41SMark McLoughlin return ERR_PTR(err); 22190aa0dc41SMark McLoughlin } 22200aa0dc41SMark McLoughlin 22210aa0dc41SMark McLoughlin root->dev.release = root_device_release; 22220aa0dc41SMark McLoughlin 22230aa0dc41SMark McLoughlin err = device_register(&root->dev); 22240aa0dc41SMark McLoughlin if (err) { 22250aa0dc41SMark McLoughlin put_device(&root->dev); 22260aa0dc41SMark McLoughlin return ERR_PTR(err); 22270aa0dc41SMark McLoughlin } 22280aa0dc41SMark McLoughlin 22291d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 22300aa0dc41SMark McLoughlin if (owner) { 22310aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 22320aa0dc41SMark McLoughlin 22330aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 22340aa0dc41SMark McLoughlin if (err) { 22350aa0dc41SMark McLoughlin device_unregister(&root->dev); 22360aa0dc41SMark McLoughlin return ERR_PTR(err); 22370aa0dc41SMark McLoughlin } 22380aa0dc41SMark McLoughlin root->owner = owner; 22390aa0dc41SMark McLoughlin } 22400aa0dc41SMark McLoughlin #endif 22410aa0dc41SMark McLoughlin 22420aa0dc41SMark McLoughlin return &root->dev; 22430aa0dc41SMark McLoughlin } 22440aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 22450aa0dc41SMark McLoughlin 22460aa0dc41SMark McLoughlin /** 22470aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 22487cbcf225SRandy Dunlap * @dev: device going away 22490aa0dc41SMark McLoughlin * 22500aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 22510aa0dc41SMark McLoughlin * root_device_register(). 22520aa0dc41SMark McLoughlin */ 22530aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 22540aa0dc41SMark McLoughlin { 22550aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 22560aa0dc41SMark McLoughlin 22570aa0dc41SMark McLoughlin if (root->owner) 22580aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 22590aa0dc41SMark McLoughlin 22600aa0dc41SMark McLoughlin device_unregister(dev); 22610aa0dc41SMark McLoughlin } 22620aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 22630aa0dc41SMark McLoughlin 226423681e47SGreg Kroah-Hartman 226523681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 226623681e47SGreg Kroah-Hartman { 22671e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 226823681e47SGreg Kroah-Hartman kfree(dev); 226923681e47SGreg Kroah-Hartman } 227023681e47SGreg Kroah-Hartman 227139ef3112SGuenter Roeck static struct device * 227239ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 227339ef3112SGuenter Roeck dev_t devt, void *drvdata, 227439ef3112SGuenter Roeck const struct attribute_group **groups, 227539ef3112SGuenter Roeck const char *fmt, va_list args) 227639ef3112SGuenter Roeck { 227739ef3112SGuenter Roeck struct device *dev = NULL; 227839ef3112SGuenter Roeck int retval = -ENODEV; 227939ef3112SGuenter Roeck 228039ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 228139ef3112SGuenter Roeck goto error; 228239ef3112SGuenter Roeck 228339ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 228439ef3112SGuenter Roeck if (!dev) { 228539ef3112SGuenter Roeck retval = -ENOMEM; 228639ef3112SGuenter Roeck goto error; 228739ef3112SGuenter Roeck } 228839ef3112SGuenter Roeck 2289bbc780f8SDavid Herrmann device_initialize(dev); 229039ef3112SGuenter Roeck dev->devt = devt; 229139ef3112SGuenter Roeck dev->class = class; 229239ef3112SGuenter Roeck dev->parent = parent; 229339ef3112SGuenter Roeck dev->groups = groups; 229439ef3112SGuenter Roeck dev->release = device_create_release; 229539ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 229639ef3112SGuenter Roeck 229739ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 229839ef3112SGuenter Roeck if (retval) 229939ef3112SGuenter Roeck goto error; 230039ef3112SGuenter Roeck 2301bbc780f8SDavid Herrmann retval = device_add(dev); 230239ef3112SGuenter Roeck if (retval) 230339ef3112SGuenter Roeck goto error; 230439ef3112SGuenter Roeck 230539ef3112SGuenter Roeck return dev; 230639ef3112SGuenter Roeck 230739ef3112SGuenter Roeck error: 230839ef3112SGuenter Roeck put_device(dev); 230939ef3112SGuenter Roeck return ERR_PTR(retval); 231039ef3112SGuenter Roeck } 231139ef3112SGuenter Roeck 231223681e47SGreg Kroah-Hartman /** 23138882b394SGreg Kroah-Hartman * device_create_vargs - creates a device and registers it with sysfs 23148882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 23158882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 23168882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 23178882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 23188882b394SGreg Kroah-Hartman * @fmt: string for the device's name 23198882b394SGreg Kroah-Hartman * @args: va_list for the device's name 23208882b394SGreg Kroah-Hartman * 23218882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 23228882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 23238882b394SGreg Kroah-Hartman * 23248882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 23258882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 23268882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 23278882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 23288882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 23298882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 23308882b394SGreg Kroah-Hartman * pointer. 23318882b394SGreg Kroah-Hartman * 2332f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2333f0eae0edSJani Nikula * 23348882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 23358882b394SGreg Kroah-Hartman * been created with a call to class_create(). 23368882b394SGreg Kroah-Hartman */ 23378882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent, 23388882b394SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, 23398882b394SGreg Kroah-Hartman va_list args) 23408882b394SGreg Kroah-Hartman { 234139ef3112SGuenter Roeck return device_create_groups_vargs(class, parent, devt, drvdata, NULL, 234239ef3112SGuenter Roeck fmt, args); 23438882b394SGreg Kroah-Hartman } 23448882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs); 23458882b394SGreg Kroah-Hartman 23468882b394SGreg Kroah-Hartman /** 23474e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 23488882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 23498882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 23508882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 23518882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 23528882b394SGreg Kroah-Hartman * @fmt: string for the device's name 23538882b394SGreg Kroah-Hartman * 23548882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 23558882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 23568882b394SGreg Kroah-Hartman * 23578882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 23588882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 23598882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 23608882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 23618882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 23628882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 23638882b394SGreg Kroah-Hartman * pointer. 23648882b394SGreg Kroah-Hartman * 2365f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2366f0eae0edSJani Nikula * 23678882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 23688882b394SGreg Kroah-Hartman * been created with a call to class_create(). 23698882b394SGreg Kroah-Hartman */ 23704e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 23714e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 23728882b394SGreg Kroah-Hartman { 23738882b394SGreg Kroah-Hartman va_list vargs; 23748882b394SGreg Kroah-Hartman struct device *dev; 23758882b394SGreg Kroah-Hartman 23768882b394SGreg Kroah-Hartman va_start(vargs, fmt); 23778882b394SGreg Kroah-Hartman dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); 23788882b394SGreg Kroah-Hartman va_end(vargs); 23798882b394SGreg Kroah-Hartman return dev; 23808882b394SGreg Kroah-Hartman } 23814e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 23828882b394SGreg Kroah-Hartman 238339ef3112SGuenter Roeck /** 238439ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 238539ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 238639ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 238739ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 238839ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 238939ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 239039ef3112SGuenter Roeck * @fmt: string for the device's name 239139ef3112SGuenter Roeck * 239239ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 239339ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 239439ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 239539ef3112SGuenter Roeck * be created automatically. 239639ef3112SGuenter Roeck * 239739ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 239839ef3112SGuenter Roeck * the dev_t is not 0,0. 239939ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 240039ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 240139ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 240239ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 240339ef3112SGuenter Roeck * pointer. 240439ef3112SGuenter Roeck * 240539ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 240639ef3112SGuenter Roeck * 240739ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 240839ef3112SGuenter Roeck * been created with a call to class_create(). 240939ef3112SGuenter Roeck */ 241039ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 241139ef3112SGuenter Roeck struct device *parent, dev_t devt, 241239ef3112SGuenter Roeck void *drvdata, 241339ef3112SGuenter Roeck const struct attribute_group **groups, 241439ef3112SGuenter Roeck const char *fmt, ...) 241539ef3112SGuenter Roeck { 241639ef3112SGuenter Roeck va_list vargs; 241739ef3112SGuenter Roeck struct device *dev; 241839ef3112SGuenter Roeck 241939ef3112SGuenter Roeck va_start(vargs, fmt); 242039ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 242139ef3112SGuenter Roeck fmt, vargs); 242239ef3112SGuenter Roeck va_end(vargs); 242339ef3112SGuenter Roeck return dev; 242439ef3112SGuenter Roeck } 242539ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 242639ef3112SGuenter Roeck 24279f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data) 242823681e47SGreg Kroah-Hartman { 24299f3b795aSMichał Mirosław const dev_t *devt = data; 243023681e47SGreg Kroah-Hartman 2431cd35449bSDave Young return dev->devt == *devt; 2432775b64d2SRafael J. Wysocki } 243323681e47SGreg Kroah-Hartman 2434775b64d2SRafael J. Wysocki /** 2435775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 2436775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 2437775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 2438775b64d2SRafael J. Wysocki * 2439775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 2440775b64d2SRafael J. Wysocki * call to device_create(). 2441775b64d2SRafael J. Wysocki */ 2442775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 2443775b64d2SRafael J. Wysocki { 2444775b64d2SRafael J. Wysocki struct device *dev; 2445775b64d2SRafael J. Wysocki 2446695794aeSGreg Kroah-Hartman dev = class_find_device(class, NULL, &devt, __match_devt); 2447cd35449bSDave Young if (dev) { 2448cd35449bSDave Young put_device(dev); 244923681e47SGreg Kroah-Hartman device_unregister(dev); 245023681e47SGreg Kroah-Hartman } 2451cd35449bSDave Young } 245223681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 2453a2de48caSGreg Kroah-Hartman 2454a2de48caSGreg Kroah-Hartman /** 2455a2de48caSGreg Kroah-Hartman * device_rename - renames a device 2456a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 2457a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 2458030c1d2bSEric W. Biederman * 2459030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 2460030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 2461030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 2462030c1d2bSEric W. Biederman * won't conflict with other devices. 2463c6c0ac66SMichael Ellerman * 2464a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 2465a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 2466a5462516STimur Tabi * some insight: 2467a5462516STimur Tabi * 2468a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 2469a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 2470a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 2471a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 2472a5462516STimur Tabi * 2473a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 2474a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 2475a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 2476a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 2477a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 2478a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 2479a5462516STimur Tabi * 2480a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 2481a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 2482a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 2483a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 2484a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 2485a5462516STimur Tabi * reasons. 2486a5462516STimur Tabi * 2487a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 2488a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 2489a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 2490a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 2491a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 2492a2de48caSGreg Kroah-Hartman */ 24936937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 2494a2de48caSGreg Kroah-Hartman { 24954b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 24962ee97cafSCornelia Huck char *old_device_name = NULL; 2497a2de48caSGreg Kroah-Hartman int error; 2498a2de48caSGreg Kroah-Hartman 2499a2de48caSGreg Kroah-Hartman dev = get_device(dev); 2500a2de48caSGreg Kroah-Hartman if (!dev) 2501a2de48caSGreg Kroah-Hartman return -EINVAL; 2502a2de48caSGreg Kroah-Hartman 250369df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 2504a2de48caSGreg Kroah-Hartman 25051fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 25062ee97cafSCornelia Huck if (!old_device_name) { 2507952ab431SJesper Juhl error = -ENOMEM; 25082ee97cafSCornelia Huck goto out; 2509952ab431SJesper Juhl } 2510a2de48caSGreg Kroah-Hartman 2511f349cf34SEric W. Biederman if (dev->class) { 25124b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 25134b30ee58STejun Heo kobj, old_device_name, 25144b30ee58STejun Heo new_name, kobject_namespace(kobj)); 2515f349cf34SEric W. Biederman if (error) 2516f349cf34SEric W. Biederman goto out; 2517f349cf34SEric W. Biederman } 251839aba963SKay Sievers 25194b30ee58STejun Heo error = kobject_rename(kobj, new_name); 25201fa5ae85SKay Sievers if (error) 25212ee97cafSCornelia Huck goto out; 2522a2de48caSGreg Kroah-Hartman 25232ee97cafSCornelia Huck out: 2524a2de48caSGreg Kroah-Hartman put_device(dev); 2525a2de48caSGreg Kroah-Hartman 25262ee97cafSCornelia Huck kfree(old_device_name); 2527a2de48caSGreg Kroah-Hartman 2528a2de48caSGreg Kroah-Hartman return error; 2529a2de48caSGreg Kroah-Hartman } 2530a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 25318a82472fSCornelia Huck 25328a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 25338a82472fSCornelia Huck struct device *old_parent, 25348a82472fSCornelia Huck struct device *new_parent) 25358a82472fSCornelia Huck { 2536f7f3461dSGreg Kroah-Hartman int error = 0; 25378a82472fSCornelia Huck 2538f7f3461dSGreg Kroah-Hartman if (old_parent) 2539f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 2540f7f3461dSGreg Kroah-Hartman if (new_parent) 2541f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 2542f7f3461dSGreg Kroah-Hartman "device"); 2543f7f3461dSGreg Kroah-Hartman return error; 25448a82472fSCornelia Huck } 25458a82472fSCornelia Huck 25468a82472fSCornelia Huck /** 25478a82472fSCornelia Huck * device_move - moves a device to a new parent 25488a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 2549c744aeaeSCornelia Huck * @new_parent: the new parent of the device (can by NULL) 2550ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 25518a82472fSCornelia Huck */ 2552ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 2553ffa6a705SCornelia Huck enum dpm_order dpm_order) 25548a82472fSCornelia Huck { 25558a82472fSCornelia Huck int error; 25568a82472fSCornelia Huck struct device *old_parent; 2557c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 25588a82472fSCornelia Huck 25598a82472fSCornelia Huck dev = get_device(dev); 25608a82472fSCornelia Huck if (!dev) 25618a82472fSCornelia Huck return -EINVAL; 25628a82472fSCornelia Huck 2563ffa6a705SCornelia Huck device_pm_lock(); 25648a82472fSCornelia Huck new_parent = get_device(new_parent); 2565c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 256663b6971aSCornelia Huck 25671e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 25681e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 2569c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 25708a82472fSCornelia Huck if (error) { 257163b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 25728a82472fSCornelia Huck put_device(new_parent); 25738a82472fSCornelia Huck goto out; 25748a82472fSCornelia Huck } 25758a82472fSCornelia Huck old_parent = dev->parent; 25768a82472fSCornelia Huck dev->parent = new_parent; 25778a82472fSCornelia Huck if (old_parent) 2578f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 25790d358f22SYinghai Lu if (new_parent) { 2580f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2581f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 25820d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 25830d358f22SYinghai Lu } 25840d358f22SYinghai Lu 2585bdd4034dSRabin Vincent if (dev->class) { 25868a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 25878a82472fSCornelia Huck if (error) { 25888a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 25898a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 25908a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 2591c744aeaeSCornelia Huck if (new_parent) 2592f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 25930d358f22SYinghai Lu dev->parent = old_parent; 25940d358f22SYinghai Lu if (old_parent) { 2595f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2596f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 25970d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 25980d358f22SYinghai Lu } 25998a82472fSCornelia Huck } 260063b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 26018a82472fSCornelia Huck put_device(new_parent); 26028a82472fSCornelia Huck goto out; 26038a82472fSCornelia Huck } 2604bdd4034dSRabin Vincent } 2605ffa6a705SCornelia Huck switch (dpm_order) { 2606ffa6a705SCornelia Huck case DPM_ORDER_NONE: 2607ffa6a705SCornelia Huck break; 2608ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 2609ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 261052cdbdd4SGrygorii Strashko devices_kset_move_after(dev, new_parent); 2611ffa6a705SCornelia Huck break; 2612ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 2613ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 261452cdbdd4SGrygorii Strashko devices_kset_move_before(new_parent, dev); 2615ffa6a705SCornelia Huck break; 2616ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 2617ffa6a705SCornelia Huck device_pm_move_last(dev); 261852cdbdd4SGrygorii Strashko devices_kset_move_last(dev); 2619ffa6a705SCornelia Huck break; 2620ffa6a705SCornelia Huck } 2621bdd4034dSRabin Vincent 26228a82472fSCornelia Huck put_device(old_parent); 26238a82472fSCornelia Huck out: 2624ffa6a705SCornelia Huck device_pm_unlock(); 26258a82472fSCornelia Huck put_device(dev); 26268a82472fSCornelia Huck return error; 26278a82472fSCornelia Huck } 26288a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 262937b0c020SGreg Kroah-Hartman 263037b0c020SGreg Kroah-Hartman /** 263137b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 263237b0c020SGreg Kroah-Hartman */ 263337b0c020SGreg Kroah-Hartman void device_shutdown(void) 263437b0c020SGreg Kroah-Hartman { 2635f123db8eSBenson Leung struct device *dev, *parent; 263637b0c020SGreg Kroah-Hartman 26376245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 26386245838fSHugh Daschbach /* 26396245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 26406245838fSHugh Daschbach * Beware that device unplug events may also start pulling 26416245838fSHugh Daschbach * devices offline, even as the system is shutting down. 26426245838fSHugh Daschbach */ 26436245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 26446245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 26456245838fSHugh Daschbach kobj.entry); 2646d1c6c030SMing Lei 2647d1c6c030SMing Lei /* 2648d1c6c030SMing Lei * hold reference count of device's parent to 2649d1c6c030SMing Lei * prevent it from being freed because parent's 2650d1c6c030SMing Lei * lock is to be held 2651d1c6c030SMing Lei */ 2652f123db8eSBenson Leung parent = get_device(dev->parent); 26536245838fSHugh Daschbach get_device(dev); 26546245838fSHugh Daschbach /* 26556245838fSHugh Daschbach * Make sure the device is off the kset list, in the 26566245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 26576245838fSHugh Daschbach */ 26586245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 26596245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 2660fe6b91f4SAlan Stern 2661d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 2662f123db8eSBenson Leung if (parent) 2663f123db8eSBenson Leung device_lock(parent); 2664d1c6c030SMing Lei device_lock(dev); 2665d1c6c030SMing Lei 2666fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 2667fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 2668fe6b91f4SAlan Stern pm_runtime_barrier(dev); 26696245838fSHugh Daschbach 267037b0c020SGreg Kroah-Hartman if (dev->bus && dev->bus->shutdown) { 26710246c4faSShuoX Liu if (initcall_debug) 26720246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 267337b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 267437b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 26750246c4faSShuoX Liu if (initcall_debug) 26760246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 267737b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 267837b0c020SGreg Kroah-Hartman } 2679d1c6c030SMing Lei 2680d1c6c030SMing Lei device_unlock(dev); 2681f123db8eSBenson Leung if (parent) 2682f123db8eSBenson Leung device_unlock(parent); 2683d1c6c030SMing Lei 26846245838fSHugh Daschbach put_device(dev); 2685f123db8eSBenson Leung put_device(parent); 26866245838fSHugh Daschbach 26876245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 268837b0c020SGreg Kroah-Hartman } 26896245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 269037b0c020SGreg Kroah-Hartman } 269199bcf217SJoe Perches 269299bcf217SJoe Perches /* 269399bcf217SJoe Perches * Device logging functions 269499bcf217SJoe Perches */ 269599bcf217SJoe Perches 269699bcf217SJoe Perches #ifdef CONFIG_PRINTK 2697666f355fSJoe Perches static int 2698666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 269999bcf217SJoe Perches { 2700c4e00daaSKay Sievers const char *subsys; 2701798efc60SJoe Perches size_t pos = 0; 270299bcf217SJoe Perches 2703c4e00daaSKay Sievers if (dev->class) 2704c4e00daaSKay Sievers subsys = dev->class->name; 2705c4e00daaSKay Sievers else if (dev->bus) 2706c4e00daaSKay Sievers subsys = dev->bus->name; 2707c4e00daaSKay Sievers else 2708798efc60SJoe Perches return 0; 2709c4e00daaSKay Sievers 2710798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 2711655e5b7cSBen Hutchings if (pos >= hdrlen) 2712655e5b7cSBen Hutchings goto overflow; 2713c4e00daaSKay Sievers 2714c4e00daaSKay Sievers /* 2715c4e00daaSKay Sievers * Add device identifier DEVICE=: 2716c4e00daaSKay Sievers * b12:8 block dev_t 2717c4e00daaSKay Sievers * c127:3 char dev_t 2718c4e00daaSKay Sievers * n8 netdev ifindex 2719c4e00daaSKay Sievers * +sound:card0 subsystem:devname 2720c4e00daaSKay Sievers */ 2721c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 2722c4e00daaSKay Sievers char c; 2723c4e00daaSKay Sievers 2724c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 2725c4e00daaSKay Sievers c = 'b'; 2726c4e00daaSKay Sievers else 2727c4e00daaSKay Sievers c = 'c'; 2728798efc60SJoe Perches pos++; 2729798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2730c4e00daaSKay Sievers "DEVICE=%c%u:%u", 2731c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 2732c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 2733c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 2734c4e00daaSKay Sievers 2735798efc60SJoe Perches pos++; 2736798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2737c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 2738c4e00daaSKay Sievers } else { 2739798efc60SJoe Perches pos++; 2740798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2741c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 2742c4e00daaSKay Sievers } 2743af7f2158SJim Cromie 2744655e5b7cSBen Hutchings if (pos >= hdrlen) 2745655e5b7cSBen Hutchings goto overflow; 2746655e5b7cSBen Hutchings 2747798efc60SJoe Perches return pos; 2748655e5b7cSBen Hutchings 2749655e5b7cSBen Hutchings overflow: 2750655e5b7cSBen Hutchings dev_WARN(dev, "device/subsystem name too long"); 2751655e5b7cSBen Hutchings return 0; 275299bcf217SJoe Perches } 2753798efc60SJoe Perches 275405e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 275505e4e5b8SJoe Perches const char *fmt, va_list args) 275605e4e5b8SJoe Perches { 275705e4e5b8SJoe Perches char hdr[128]; 275805e4e5b8SJoe Perches size_t hdrlen; 275905e4e5b8SJoe Perches 276005e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 276105e4e5b8SJoe Perches 276205e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 276305e4e5b8SJoe Perches } 276405e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 276505e4e5b8SJoe Perches 276605e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 276705e4e5b8SJoe Perches { 276805e4e5b8SJoe Perches va_list args; 276905e4e5b8SJoe Perches int r; 277005e4e5b8SJoe Perches 277105e4e5b8SJoe Perches va_start(args, fmt); 277205e4e5b8SJoe Perches 277305e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 277405e4e5b8SJoe Perches 277505e4e5b8SJoe Perches va_end(args); 277605e4e5b8SJoe Perches 277705e4e5b8SJoe Perches return r; 277805e4e5b8SJoe Perches } 277905e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 278005e4e5b8SJoe Perches 2781d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev, 2782798efc60SJoe Perches struct va_format *vaf) 2783798efc60SJoe Perches { 2784d1f1052cSJoe Perches if (dev) 2785d1f1052cSJoe Perches dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", 2786798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 2787d1f1052cSJoe Perches else 2788d1f1052cSJoe Perches printk("%s(NULL device *): %pV", level, vaf); 2789798efc60SJoe Perches } 279099bcf217SJoe Perches 2791d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev, 279299bcf217SJoe Perches const char *fmt, ...) 279399bcf217SJoe Perches { 279499bcf217SJoe Perches struct va_format vaf; 279599bcf217SJoe Perches va_list args; 279699bcf217SJoe Perches 279799bcf217SJoe Perches va_start(args, fmt); 279899bcf217SJoe Perches 279999bcf217SJoe Perches vaf.fmt = fmt; 280099bcf217SJoe Perches vaf.va = &args; 280199bcf217SJoe Perches 2802d1f1052cSJoe Perches __dev_printk(level, dev, &vaf); 2803798efc60SJoe Perches 280499bcf217SJoe Perches va_end(args); 280599bcf217SJoe Perches } 280699bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 280799bcf217SJoe Perches 280899bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 2809d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...) \ 281099bcf217SJoe Perches { \ 281199bcf217SJoe Perches struct va_format vaf; \ 281299bcf217SJoe Perches va_list args; \ 281399bcf217SJoe Perches \ 281499bcf217SJoe Perches va_start(args, fmt); \ 281599bcf217SJoe Perches \ 281699bcf217SJoe Perches vaf.fmt = fmt; \ 281799bcf217SJoe Perches vaf.va = &args; \ 281899bcf217SJoe Perches \ 2819d1f1052cSJoe Perches __dev_printk(kern_level, dev, &vaf); \ 2820798efc60SJoe Perches \ 282199bcf217SJoe Perches va_end(args); \ 282299bcf217SJoe Perches } \ 282399bcf217SJoe Perches EXPORT_SYMBOL(func); 282499bcf217SJoe Perches 282599bcf217SJoe Perches define_dev_printk_level(dev_emerg, KERN_EMERG); 282699bcf217SJoe Perches define_dev_printk_level(dev_alert, KERN_ALERT); 282799bcf217SJoe Perches define_dev_printk_level(dev_crit, KERN_CRIT); 282899bcf217SJoe Perches define_dev_printk_level(dev_err, KERN_ERR); 282999bcf217SJoe Perches define_dev_printk_level(dev_warn, KERN_WARNING); 283099bcf217SJoe Perches define_dev_printk_level(dev_notice, KERN_NOTICE); 283199bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 283299bcf217SJoe Perches 283399bcf217SJoe Perches #endif 283497badf87SRafael J. Wysocki 283597badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 283697badf87SRafael J. Wysocki { 283797badf87SRafael J. Wysocki return fwnode && !IS_ERR(fwnode->secondary); 283897badf87SRafael J. Wysocki } 283997badf87SRafael J. Wysocki 284097badf87SRafael J. Wysocki /** 284197badf87SRafael J. Wysocki * set_primary_fwnode - Change the primary firmware node of a given device. 284297badf87SRafael J. Wysocki * @dev: Device to handle. 284397badf87SRafael J. Wysocki * @fwnode: New primary firmware node of the device. 284497badf87SRafael J. Wysocki * 284597badf87SRafael J. Wysocki * Set the device's firmware node pointer to @fwnode, but if a secondary 284697badf87SRafael J. Wysocki * firmware node of the device is present, preserve it. 284797badf87SRafael J. Wysocki */ 284897badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 284997badf87SRafael J. Wysocki { 285097badf87SRafael J. Wysocki if (fwnode) { 285197badf87SRafael J. Wysocki struct fwnode_handle *fn = dev->fwnode; 285297badf87SRafael J. Wysocki 285397badf87SRafael J. Wysocki if (fwnode_is_primary(fn)) 285497badf87SRafael J. Wysocki fn = fn->secondary; 285597badf87SRafael J. Wysocki 285655f89a8aSMika Westerberg if (fn) { 285755f89a8aSMika Westerberg WARN_ON(fwnode->secondary); 285897badf87SRafael J. Wysocki fwnode->secondary = fn; 285955f89a8aSMika Westerberg } 286097badf87SRafael J. Wysocki dev->fwnode = fwnode; 286197badf87SRafael J. Wysocki } else { 286297badf87SRafael J. Wysocki dev->fwnode = fwnode_is_primary(dev->fwnode) ? 286397badf87SRafael J. Wysocki dev->fwnode->secondary : NULL; 286497badf87SRafael J. Wysocki } 286597badf87SRafael J. Wysocki } 286697badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode); 286797badf87SRafael J. Wysocki 286897badf87SRafael J. Wysocki /** 286997badf87SRafael J. Wysocki * set_secondary_fwnode - Change the secondary firmware node of a given device. 287097badf87SRafael J. Wysocki * @dev: Device to handle. 287197badf87SRafael J. Wysocki * @fwnode: New secondary firmware node of the device. 287297badf87SRafael J. Wysocki * 287397badf87SRafael J. Wysocki * If a primary firmware node of the device is present, set its secondary 287497badf87SRafael J. Wysocki * pointer to @fwnode. Otherwise, set the device's firmware node pointer to 287597badf87SRafael J. Wysocki * @fwnode. 287697badf87SRafael J. Wysocki */ 287797badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 287897badf87SRafael J. Wysocki { 287997badf87SRafael J. Wysocki if (fwnode) 288097badf87SRafael J. Wysocki fwnode->secondary = ERR_PTR(-ENODEV); 288197badf87SRafael J. Wysocki 288297badf87SRafael J. Wysocki if (fwnode_is_primary(dev->fwnode)) 288397badf87SRafael J. Wysocki dev->fwnode->secondary = fwnode; 288497badf87SRafael J. Wysocki else 288597badf87SRafael J. Wysocki dev->fwnode = fwnode; 288697badf87SRafael J. Wysocki } 28874e75e1d7SJohan Hovold 28884e75e1d7SJohan Hovold /** 28894e75e1d7SJohan Hovold * device_set_of_node_from_dev - reuse device-tree node of another device 28904e75e1d7SJohan Hovold * @dev: device whose device-tree node is being set 28914e75e1d7SJohan Hovold * @dev2: device whose device-tree node is being reused 28924e75e1d7SJohan Hovold * 28934e75e1d7SJohan Hovold * Takes another reference to the new device-tree node after first dropping 28944e75e1d7SJohan Hovold * any reference held to the old node. 28954e75e1d7SJohan Hovold */ 28964e75e1d7SJohan Hovold void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) 28974e75e1d7SJohan Hovold { 28984e75e1d7SJohan Hovold of_node_put(dev->of_node); 28994e75e1d7SJohan Hovold dev->of_node = of_node_get(dev2->of_node); 29004e75e1d7SJohan Hovold dev->of_node_reused = true; 29014e75e1d7SJohan Hovold } 29024e75e1d7SJohan Hovold EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); 2903