1989d42e8SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc) 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 61da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 764bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de> 864bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc. 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/device.h> 121da177e4SLinus Torvalds #include <linux/err.h> 1397badf87SRafael J. Wysocki #include <linux/fwnode.h> 141da177e4SLinus Torvalds #include <linux/init.h> 151da177e4SLinus Torvalds #include <linux/module.h> 161da177e4SLinus Torvalds #include <linux/slab.h> 171da177e4SLinus Torvalds #include <linux/string.h> 1823681e47SGreg Kroah-Hartman #include <linux/kdev_t.h> 19116af378SBenjamin Herrenschmidt #include <linux/notifier.h> 2007d57a32SGrant Likely #include <linux/of.h> 2107d57a32SGrant Likely #include <linux/of_device.h> 22da231fd5SKay Sievers #include <linux/genhd.h> 23f75b1c60SDave Young #include <linux/mutex.h> 24af8db150SPeter Chen #include <linux/pm_runtime.h> 25c4e00daaSKay Sievers #include <linux/netdevice.h> 26174cd4b1SIngo Molnar #include <linux/sched/signal.h> 2763967685SGreg Kroah-Hartman #include <linux/sysfs.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include "base.h" 301da177e4SLinus Torvalds #include "power/power.h" 311da177e4SLinus Torvalds 32e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED 33e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2 34e52eec13SAndi Kleen long sysfs_deprecated = 1; 35e52eec13SAndi Kleen #else 36e52eec13SAndi Kleen long sysfs_deprecated = 0; 37e52eec13SAndi Kleen #endif 383454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg) 39e52eec13SAndi Kleen { 4034da5e67SJingoo Han return kstrtol(arg, 10, &sysfs_deprecated); 41e52eec13SAndi Kleen } 42e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup); 43e52eec13SAndi Kleen #endif 44e52eec13SAndi Kleen 459ed98953SRafael J. Wysocki /* Device links support. */ 469ed98953SRafael J. Wysocki 479ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 489ed98953SRafael J. Wysocki static DEFINE_MUTEX(device_links_lock); 499ed98953SRafael J. Wysocki DEFINE_STATIC_SRCU(device_links_srcu); 509ed98953SRafael J. Wysocki 519ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 529ed98953SRafael J. Wysocki { 539ed98953SRafael J. Wysocki mutex_lock(&device_links_lock); 549ed98953SRafael J. Wysocki } 559ed98953SRafael J. Wysocki 569ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 579ed98953SRafael J. Wysocki { 589ed98953SRafael J. Wysocki mutex_unlock(&device_links_lock); 599ed98953SRafael J. Wysocki } 609ed98953SRafael J. Wysocki 619ed98953SRafael J. Wysocki int device_links_read_lock(void) 629ed98953SRafael J. Wysocki { 639ed98953SRafael J. Wysocki return srcu_read_lock(&device_links_srcu); 649ed98953SRafael J. Wysocki } 659ed98953SRafael J. Wysocki 669ed98953SRafael J. Wysocki void device_links_read_unlock(int idx) 679ed98953SRafael J. Wysocki { 689ed98953SRafael J. Wysocki srcu_read_unlock(&device_links_srcu, idx); 699ed98953SRafael J. Wysocki } 709ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 719ed98953SRafael J. Wysocki static DECLARE_RWSEM(device_links_lock); 729ed98953SRafael J. Wysocki 739ed98953SRafael J. Wysocki static inline void device_links_write_lock(void) 749ed98953SRafael J. Wysocki { 759ed98953SRafael J. Wysocki down_write(&device_links_lock); 769ed98953SRafael J. Wysocki } 779ed98953SRafael J. Wysocki 789ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void) 799ed98953SRafael J. Wysocki { 809ed98953SRafael J. Wysocki up_write(&device_links_lock); 819ed98953SRafael J. Wysocki } 829ed98953SRafael J. Wysocki 839ed98953SRafael J. Wysocki int device_links_read_lock(void) 849ed98953SRafael J. Wysocki { 859ed98953SRafael J. Wysocki down_read(&device_links_lock); 869ed98953SRafael J. Wysocki return 0; 879ed98953SRafael J. Wysocki } 889ed98953SRafael J. Wysocki 899ed98953SRafael J. Wysocki void device_links_read_unlock(int not_used) 909ed98953SRafael J. Wysocki { 919ed98953SRafael J. Wysocki up_read(&device_links_lock); 929ed98953SRafael J. Wysocki } 939ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 949ed98953SRafael J. Wysocki 959ed98953SRafael J. Wysocki /** 969ed98953SRafael J. Wysocki * device_is_dependent - Check if one device depends on another one 979ed98953SRafael J. Wysocki * @dev: Device to check dependencies for. 989ed98953SRafael J. Wysocki * @target: Device to check against. 999ed98953SRafael J. Wysocki * 1009ed98953SRafael J. Wysocki * Check if @target depends on @dev or any device dependent on it (its child or 1019ed98953SRafael J. Wysocki * its consumer etc). Return 1 if that is the case or 0 otherwise. 1029ed98953SRafael J. Wysocki */ 1039ed98953SRafael J. Wysocki static int device_is_dependent(struct device *dev, void *target) 1049ed98953SRafael J. Wysocki { 1059ed98953SRafael J. Wysocki struct device_link *link; 1069ed98953SRafael J. Wysocki int ret; 1079ed98953SRafael J. Wysocki 1089ed98953SRafael J. Wysocki if (WARN_ON(dev == target)) 1099ed98953SRafael J. Wysocki return 1; 1109ed98953SRafael J. Wysocki 1119ed98953SRafael J. Wysocki ret = device_for_each_child(dev, target, device_is_dependent); 1129ed98953SRafael J. Wysocki if (ret) 1139ed98953SRafael J. Wysocki return ret; 1149ed98953SRafael J. Wysocki 1159ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 1169ed98953SRafael J. Wysocki if (WARN_ON(link->consumer == target)) 1179ed98953SRafael J. Wysocki return 1; 1189ed98953SRafael J. Wysocki 1199ed98953SRafael J. Wysocki ret = device_is_dependent(link->consumer, target); 1209ed98953SRafael J. Wysocki if (ret) 1219ed98953SRafael J. Wysocki break; 1229ed98953SRafael J. Wysocki } 1239ed98953SRafael J. Wysocki return ret; 1249ed98953SRafael J. Wysocki } 1259ed98953SRafael J. Wysocki 1269ed98953SRafael J. Wysocki static int device_reorder_to_tail(struct device *dev, void *not_used) 1279ed98953SRafael J. Wysocki { 1289ed98953SRafael J. Wysocki struct device_link *link; 1299ed98953SRafael J. Wysocki 1309ed98953SRafael J. Wysocki /* 1319ed98953SRafael J. Wysocki * Devices that have not been registered yet will be put to the ends 1329ed98953SRafael J. Wysocki * of the lists during the registration, so skip them here. 1339ed98953SRafael J. Wysocki */ 1349ed98953SRafael J. Wysocki if (device_is_registered(dev)) 1359ed98953SRafael J. Wysocki devices_kset_move_last(dev); 1369ed98953SRafael J. Wysocki 1379ed98953SRafael J. Wysocki if (device_pm_initialized(dev)) 1389ed98953SRafael J. Wysocki device_pm_move_last(dev); 1399ed98953SRafael J. Wysocki 1409ed98953SRafael J. Wysocki device_for_each_child(dev, NULL, device_reorder_to_tail); 1419ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) 1429ed98953SRafael J. Wysocki device_reorder_to_tail(link->consumer, NULL); 1439ed98953SRafael J. Wysocki 1449ed98953SRafael J. Wysocki return 0; 1459ed98953SRafael J. Wysocki } 1469ed98953SRafael J. Wysocki 1479ed98953SRafael J. Wysocki /** 148494fd7b7SFeng Kan * device_pm_move_to_tail - Move set of devices to the end of device lists 149494fd7b7SFeng Kan * @dev: Device to move 150494fd7b7SFeng Kan * 151494fd7b7SFeng Kan * This is a device_reorder_to_tail() wrapper taking the requisite locks. 152494fd7b7SFeng Kan * 153494fd7b7SFeng Kan * It moves the @dev along with all of its children and all of its consumers 154494fd7b7SFeng Kan * to the ends of the device_kset and dpm_list, recursively. 155494fd7b7SFeng Kan */ 156494fd7b7SFeng Kan void device_pm_move_to_tail(struct device *dev) 157494fd7b7SFeng Kan { 158494fd7b7SFeng Kan int idx; 159494fd7b7SFeng Kan 160494fd7b7SFeng Kan idx = device_links_read_lock(); 161494fd7b7SFeng Kan device_pm_lock(); 162494fd7b7SFeng Kan device_reorder_to_tail(dev, NULL); 163494fd7b7SFeng Kan device_pm_unlock(); 164494fd7b7SFeng Kan device_links_read_unlock(idx); 165494fd7b7SFeng Kan } 166494fd7b7SFeng Kan 167494fd7b7SFeng Kan /** 1689ed98953SRafael J. Wysocki * device_link_add - Create a link between two devices. 1699ed98953SRafael J. Wysocki * @consumer: Consumer end of the link. 1709ed98953SRafael J. Wysocki * @supplier: Supplier end of the link. 1719ed98953SRafael J. Wysocki * @flags: Link flags. 1729ed98953SRafael J. Wysocki * 17321d5c57bSRafael J. Wysocki * The caller is responsible for the proper synchronization of the link creation 17421d5c57bSRafael J. Wysocki * with runtime PM. First, setting the DL_FLAG_PM_RUNTIME flag will cause the 17521d5c57bSRafael J. Wysocki * runtime PM framework to take the link into account. Second, if the 17621d5c57bSRafael J. Wysocki * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will 17721d5c57bSRafael J. Wysocki * be forced into the active metastate and reference-counted upon the creation 17821d5c57bSRafael J. Wysocki * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be 17921d5c57bSRafael J. Wysocki * ignored. 18021d5c57bSRafael J. Wysocki * 1819ed98953SRafael J. Wysocki * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically 1829ed98953SRafael J. Wysocki * when the consumer device driver unbinds from it. The combination of both 1839ed98953SRafael J. Wysocki * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL 1849ed98953SRafael J. Wysocki * to be returned. 1859ed98953SRafael J. Wysocki * 1869ed98953SRafael J. Wysocki * A side effect of the link creation is re-ordering of dpm_list and the 1879ed98953SRafael J. Wysocki * devices_kset list by moving the consumer device and all devices depending 1889ed98953SRafael J. Wysocki * on it to the ends of these lists (that does not happen to devices that have 1899ed98953SRafael J. Wysocki * not been registered when this function is called). 1909ed98953SRafael J. Wysocki * 1919ed98953SRafael J. Wysocki * The supplier device is required to be registered when this function is called 1929ed98953SRafael J. Wysocki * and NULL will be returned if that is not the case. The consumer device need 19364df1148SLukas Wunner * not be registered, however. 1949ed98953SRafael J. Wysocki */ 1959ed98953SRafael J. Wysocki struct device_link *device_link_add(struct device *consumer, 1969ed98953SRafael J. Wysocki struct device *supplier, u32 flags) 1979ed98953SRafael J. Wysocki { 1989ed98953SRafael J. Wysocki struct device_link *link; 1999ed98953SRafael J. Wysocki 2009ed98953SRafael J. Wysocki if (!consumer || !supplier || 2019ed98953SRafael J. Wysocki ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE))) 2029ed98953SRafael J. Wysocki return NULL; 2039ed98953SRafael J. Wysocki 2049ed98953SRafael J. Wysocki device_links_write_lock(); 2059ed98953SRafael J. Wysocki device_pm_lock(); 2069ed98953SRafael J. Wysocki 2079ed98953SRafael J. Wysocki /* 2089ed98953SRafael J. Wysocki * If the supplier has not been fully registered yet or there is a 2099ed98953SRafael J. Wysocki * reverse dependency between the consumer and the supplier already in 2109ed98953SRafael J. Wysocki * the graph, return NULL. 2119ed98953SRafael J. Wysocki */ 2129ed98953SRafael J. Wysocki if (!device_pm_initialized(supplier) 2139ed98953SRafael J. Wysocki || device_is_dependent(consumer, supplier)) { 2149ed98953SRafael J. Wysocki link = NULL; 2159ed98953SRafael J. Wysocki goto out; 2169ed98953SRafael J. Wysocki } 2179ed98953SRafael J. Wysocki 2189ed98953SRafael J. Wysocki list_for_each_entry(link, &supplier->links.consumers, s_node) 219ead18c23SLukas Wunner if (link->consumer == consumer) { 220ead18c23SLukas Wunner kref_get(&link->kref); 2219ed98953SRafael J. Wysocki goto out; 222ead18c23SLukas Wunner } 2239ed98953SRafael J. Wysocki 22421d5c57bSRafael J. Wysocki link = kzalloc(sizeof(*link), GFP_KERNEL); 2259ed98953SRafael J. Wysocki if (!link) 2269ed98953SRafael J. Wysocki goto out; 2279ed98953SRafael J. Wysocki 228baa8809fSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) { 229baa8809fSRafael J. Wysocki if (flags & DL_FLAG_RPM_ACTIVE) { 23021d5c57bSRafael J. Wysocki if (pm_runtime_get_sync(supplier) < 0) { 23121d5c57bSRafael J. Wysocki pm_runtime_put_noidle(supplier); 23221d5c57bSRafael J. Wysocki kfree(link); 23321d5c57bSRafael J. Wysocki link = NULL; 23421d5c57bSRafael J. Wysocki goto out; 23521d5c57bSRafael J. Wysocki } 23621d5c57bSRafael J. Wysocki link->rpm_active = true; 23721d5c57bSRafael J. Wysocki } 238baa8809fSRafael J. Wysocki pm_runtime_new_link(consumer); 23947e5abfbSRafael J. Wysocki /* 24047e5abfbSRafael J. Wysocki * If the link is being added by the consumer driver at probe 24147e5abfbSRafael J. Wysocki * time, balance the decrementation of the supplier's runtime PM 24247e5abfbSRafael J. Wysocki * usage counter after consumer probe in driver_probe_device(). 24347e5abfbSRafael J. Wysocki */ 24447e5abfbSRafael J. Wysocki if (consumer->links.status == DL_DEV_PROBING) 24547e5abfbSRafael J. Wysocki pm_runtime_get_noresume(supplier); 246baa8809fSRafael J. Wysocki } 2479ed98953SRafael J. Wysocki get_device(supplier); 2489ed98953SRafael J. Wysocki link->supplier = supplier; 2499ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->s_node); 2509ed98953SRafael J. Wysocki get_device(consumer); 2519ed98953SRafael J. Wysocki link->consumer = consumer; 2529ed98953SRafael J. Wysocki INIT_LIST_HEAD(&link->c_node); 2539ed98953SRafael J. Wysocki link->flags = flags; 254ead18c23SLukas Wunner kref_init(&link->kref); 2559ed98953SRafael J. Wysocki 25664df1148SLukas Wunner /* Determine the initial link state. */ 2579ed98953SRafael J. Wysocki if (flags & DL_FLAG_STATELESS) { 2589ed98953SRafael J. Wysocki link->status = DL_STATE_NONE; 2599ed98953SRafael J. Wysocki } else { 2609ed98953SRafael J. Wysocki switch (supplier->links.status) { 2619ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2629ed98953SRafael J. Wysocki switch (consumer->links.status) { 2639ed98953SRafael J. Wysocki case DL_DEV_PROBING: 26421d5c57bSRafael J. Wysocki /* 26547e5abfbSRafael J. Wysocki * Some callers expect the link creation during 26647e5abfbSRafael J. Wysocki * consumer driver probe to resume the supplier 26747e5abfbSRafael J. Wysocki * even without DL_FLAG_RPM_ACTIVE. 26821d5c57bSRafael J. Wysocki */ 26921d5c57bSRafael J. Wysocki if (flags & DL_FLAG_PM_RUNTIME) 27047e5abfbSRafael J. Wysocki pm_runtime_resume(supplier); 27121d5c57bSRafael J. Wysocki 2729ed98953SRafael J. Wysocki link->status = DL_STATE_CONSUMER_PROBE; 2739ed98953SRafael J. Wysocki break; 2749ed98953SRafael J. Wysocki case DL_DEV_DRIVER_BOUND: 2759ed98953SRafael J. Wysocki link->status = DL_STATE_ACTIVE; 2769ed98953SRafael J. Wysocki break; 2779ed98953SRafael J. Wysocki default: 2789ed98953SRafael J. Wysocki link->status = DL_STATE_AVAILABLE; 2799ed98953SRafael J. Wysocki break; 2809ed98953SRafael J. Wysocki } 2819ed98953SRafael J. Wysocki break; 2829ed98953SRafael J. Wysocki case DL_DEV_UNBINDING: 2839ed98953SRafael J. Wysocki link->status = DL_STATE_SUPPLIER_UNBIND; 2849ed98953SRafael J. Wysocki break; 2859ed98953SRafael J. Wysocki default: 2869ed98953SRafael J. Wysocki link->status = DL_STATE_DORMANT; 2879ed98953SRafael J. Wysocki break; 2889ed98953SRafael J. Wysocki } 2899ed98953SRafael J. Wysocki } 2909ed98953SRafael J. Wysocki 2919ed98953SRafael J. Wysocki /* 2929ed98953SRafael J. Wysocki * Move the consumer and all of the devices depending on it to the end 2939ed98953SRafael J. Wysocki * of dpm_list and the devices_kset list. 2949ed98953SRafael J. Wysocki * 2959ed98953SRafael J. Wysocki * It is necessary to hold dpm_list locked throughout all that or else 2969ed98953SRafael J. Wysocki * we may end up suspending with a wrong ordering of it. 2979ed98953SRafael J. Wysocki */ 2989ed98953SRafael J. Wysocki device_reorder_to_tail(consumer, NULL); 2999ed98953SRafael J. Wysocki 3009ed98953SRafael J. Wysocki list_add_tail_rcu(&link->s_node, &supplier->links.consumers); 3019ed98953SRafael J. Wysocki list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); 3029ed98953SRafael J. Wysocki 3039ed98953SRafael J. Wysocki dev_info(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); 3049ed98953SRafael J. Wysocki 3059ed98953SRafael J. Wysocki out: 3069ed98953SRafael J. Wysocki device_pm_unlock(); 3079ed98953SRafael J. Wysocki device_links_write_unlock(); 3089ed98953SRafael J. Wysocki return link; 3099ed98953SRafael J. Wysocki } 3109ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_add); 3119ed98953SRafael J. Wysocki 3129ed98953SRafael J. Wysocki static void device_link_free(struct device_link *link) 3139ed98953SRafael J. Wysocki { 3149ed98953SRafael J. Wysocki put_device(link->consumer); 3159ed98953SRafael J. Wysocki put_device(link->supplier); 3169ed98953SRafael J. Wysocki kfree(link); 3179ed98953SRafael J. Wysocki } 3189ed98953SRafael J. Wysocki 3199ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU 3209ed98953SRafael J. Wysocki static void __device_link_free_srcu(struct rcu_head *rhead) 3219ed98953SRafael J. Wysocki { 3229ed98953SRafael J. Wysocki device_link_free(container_of(rhead, struct device_link, rcu_head)); 3239ed98953SRafael J. Wysocki } 3249ed98953SRafael J. Wysocki 325ead18c23SLukas Wunner static void __device_link_del(struct kref *kref) 3269ed98953SRafael J. Wysocki { 327ead18c23SLukas Wunner struct device_link *link = container_of(kref, struct device_link, kref); 328ead18c23SLukas Wunner 3299ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3309ed98953SRafael J. Wysocki dev_name(link->supplier)); 3319ed98953SRafael J. Wysocki 332baa8809fSRafael J. Wysocki if (link->flags & DL_FLAG_PM_RUNTIME) 333baa8809fSRafael J. Wysocki pm_runtime_drop_link(link->consumer); 334baa8809fSRafael J. Wysocki 3359ed98953SRafael J. Wysocki list_del_rcu(&link->s_node); 3369ed98953SRafael J. Wysocki list_del_rcu(&link->c_node); 3379ed98953SRafael J. Wysocki call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); 3389ed98953SRafael J. Wysocki } 3399ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */ 340ead18c23SLukas Wunner static void __device_link_del(struct kref *kref) 3419ed98953SRafael J. Wysocki { 342ead18c23SLukas Wunner struct device_link *link = container_of(kref, struct device_link, kref); 343ead18c23SLukas Wunner 3449ed98953SRafael J. Wysocki dev_info(link->consumer, "Dropping the link to %s\n", 3459ed98953SRafael J. Wysocki dev_name(link->supplier)); 3469ed98953SRafael J. Wysocki 347433986c2SLukas Wunner if (link->flags & DL_FLAG_PM_RUNTIME) 348433986c2SLukas Wunner pm_runtime_drop_link(link->consumer); 349433986c2SLukas Wunner 3509ed98953SRafael J. Wysocki list_del(&link->s_node); 3519ed98953SRafael J. Wysocki list_del(&link->c_node); 3529ed98953SRafael J. Wysocki device_link_free(link); 3539ed98953SRafael J. Wysocki } 3549ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */ 3559ed98953SRafael J. Wysocki 3569ed98953SRafael J. Wysocki /** 3579ed98953SRafael J. Wysocki * device_link_del - Delete a link between two devices. 3589ed98953SRafael J. Wysocki * @link: Device link to delete. 3599ed98953SRafael J. Wysocki * 3609ed98953SRafael J. Wysocki * The caller must ensure proper synchronization of this function with runtime 361ead18c23SLukas Wunner * PM. If the link was added multiple times, it needs to be deleted as often. 362ead18c23SLukas Wunner * Care is required for hotplugged devices: Their links are purged on removal 363ead18c23SLukas Wunner * and calling device_link_del() is then no longer allowed. 3649ed98953SRafael J. Wysocki */ 3659ed98953SRafael J. Wysocki void device_link_del(struct device_link *link) 3669ed98953SRafael J. Wysocki { 3679ed98953SRafael J. Wysocki device_links_write_lock(); 3689ed98953SRafael J. Wysocki device_pm_lock(); 369ead18c23SLukas Wunner kref_put(&link->kref, __device_link_del); 3709ed98953SRafael J. Wysocki device_pm_unlock(); 3719ed98953SRafael J. Wysocki device_links_write_unlock(); 3729ed98953SRafael J. Wysocki } 3739ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_del); 3749ed98953SRafael J. Wysocki 3759ed98953SRafael J. Wysocki static void device_links_missing_supplier(struct device *dev) 3769ed98953SRafael J. Wysocki { 3779ed98953SRafael J. Wysocki struct device_link *link; 3789ed98953SRafael J. Wysocki 3799ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) 3809ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE) 3819ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 3829ed98953SRafael J. Wysocki } 3839ed98953SRafael J. Wysocki 3849ed98953SRafael J. Wysocki /** 3859ed98953SRafael J. Wysocki * device_links_check_suppliers - Check presence of supplier drivers. 3869ed98953SRafael J. Wysocki * @dev: Consumer device. 3879ed98953SRafael J. Wysocki * 3889ed98953SRafael J. Wysocki * Check links from this device to any suppliers. Walk the list of the device's 3899ed98953SRafael J. Wysocki * links to suppliers and see if all of them are available. If not, simply 3909ed98953SRafael J. Wysocki * return -EPROBE_DEFER. 3919ed98953SRafael J. Wysocki * 3929ed98953SRafael J. Wysocki * We need to guarantee that the supplier will not go away after the check has 3939ed98953SRafael J. Wysocki * been positive here. It only can go away in __device_release_driver() and 3949ed98953SRafael J. Wysocki * that function checks the device's links to consumers. This means we need to 3959ed98953SRafael J. Wysocki * mark the link as "consumer probe in progress" to make the supplier removal 3969ed98953SRafael J. Wysocki * wait for us to complete (or bad things may happen). 3979ed98953SRafael J. Wysocki * 3989ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 3999ed98953SRafael J. Wysocki */ 4009ed98953SRafael J. Wysocki int device_links_check_suppliers(struct device *dev) 4019ed98953SRafael J. Wysocki { 4029ed98953SRafael J. Wysocki struct device_link *link; 4039ed98953SRafael J. Wysocki int ret = 0; 4049ed98953SRafael J. Wysocki 4059ed98953SRafael J. Wysocki device_links_write_lock(); 4069ed98953SRafael J. Wysocki 4079ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 4089ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4099ed98953SRafael J. Wysocki continue; 4109ed98953SRafael J. Wysocki 4119ed98953SRafael J. Wysocki if (link->status != DL_STATE_AVAILABLE) { 4129ed98953SRafael J. Wysocki device_links_missing_supplier(dev); 4139ed98953SRafael J. Wysocki ret = -EPROBE_DEFER; 4149ed98953SRafael J. Wysocki break; 4159ed98953SRafael J. Wysocki } 4169ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_CONSUMER_PROBE); 4179ed98953SRafael J. Wysocki } 4189ed98953SRafael J. Wysocki dev->links.status = DL_DEV_PROBING; 4199ed98953SRafael J. Wysocki 4209ed98953SRafael J. Wysocki device_links_write_unlock(); 4219ed98953SRafael J. Wysocki return ret; 4229ed98953SRafael J. Wysocki } 4239ed98953SRafael J. Wysocki 4249ed98953SRafael J. Wysocki /** 4259ed98953SRafael J. Wysocki * device_links_driver_bound - Update device links after probing its driver. 4269ed98953SRafael J. Wysocki * @dev: Device to update the links for. 4279ed98953SRafael J. Wysocki * 4289ed98953SRafael J. Wysocki * The probe has been successful, so update links from this device to any 4299ed98953SRafael J. Wysocki * consumers by changing their status to "available". 4309ed98953SRafael J. Wysocki * 4319ed98953SRafael J. Wysocki * Also change the status of @dev's links to suppliers to "active". 4329ed98953SRafael J. Wysocki * 4339ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4349ed98953SRafael J. Wysocki */ 4359ed98953SRafael J. Wysocki void device_links_driver_bound(struct device *dev) 4369ed98953SRafael J. Wysocki { 4379ed98953SRafael J. Wysocki struct device_link *link; 4389ed98953SRafael J. Wysocki 4399ed98953SRafael J. Wysocki device_links_write_lock(); 4409ed98953SRafael J. Wysocki 4419ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 4429ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4439ed98953SRafael J. Wysocki continue; 4449ed98953SRafael J. Wysocki 4459ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT); 4469ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4479ed98953SRafael J. Wysocki } 4489ed98953SRafael J. Wysocki 4499ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.suppliers, c_node) { 4509ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4519ed98953SRafael J. Wysocki continue; 4529ed98953SRafael J. Wysocki 4539ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); 4549ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_ACTIVE); 4559ed98953SRafael J. Wysocki } 4569ed98953SRafael J. Wysocki 4579ed98953SRafael J. Wysocki dev->links.status = DL_DEV_DRIVER_BOUND; 4589ed98953SRafael J. Wysocki 4599ed98953SRafael J. Wysocki device_links_write_unlock(); 4609ed98953SRafael J. Wysocki } 4619ed98953SRafael J. Wysocki 4629ed98953SRafael J. Wysocki /** 4639ed98953SRafael J. Wysocki * __device_links_no_driver - Update links of a device without a driver. 4649ed98953SRafael J. Wysocki * @dev: Device without a drvier. 4659ed98953SRafael J. Wysocki * 4669ed98953SRafael J. Wysocki * Delete all non-persistent links from this device to any suppliers. 4679ed98953SRafael J. Wysocki * 4689ed98953SRafael J. Wysocki * Persistent links stay around, but their status is changed to "available", 4699ed98953SRafael J. Wysocki * unless they already are in the "supplier unbind in progress" state in which 4709ed98953SRafael J. Wysocki * case they need not be updated. 4719ed98953SRafael J. Wysocki * 4729ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 4739ed98953SRafael J. Wysocki */ 4749ed98953SRafael J. Wysocki static void __device_links_no_driver(struct device *dev) 4759ed98953SRafael J. Wysocki { 4769ed98953SRafael J. Wysocki struct device_link *link, *ln; 4779ed98953SRafael J. Wysocki 4789ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 4799ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 4809ed98953SRafael J. Wysocki continue; 4819ed98953SRafael J. Wysocki 4829ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_AUTOREMOVE) 483ead18c23SLukas Wunner kref_put(&link->kref, __device_link_del); 4849ed98953SRafael J. Wysocki else if (link->status != DL_STATE_SUPPLIER_UNBIND) 4859ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_AVAILABLE); 4869ed98953SRafael J. Wysocki } 4879ed98953SRafael J. Wysocki 4889ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 4899ed98953SRafael J. Wysocki } 4909ed98953SRafael J. Wysocki 4919ed98953SRafael J. Wysocki void device_links_no_driver(struct device *dev) 4929ed98953SRafael J. Wysocki { 4939ed98953SRafael J. Wysocki device_links_write_lock(); 4949ed98953SRafael J. Wysocki __device_links_no_driver(dev); 4959ed98953SRafael J. Wysocki device_links_write_unlock(); 4969ed98953SRafael J. Wysocki } 4979ed98953SRafael J. Wysocki 4989ed98953SRafael J. Wysocki /** 4999ed98953SRafael J. Wysocki * device_links_driver_cleanup - Update links after driver removal. 5009ed98953SRafael J. Wysocki * @dev: Device whose driver has just gone away. 5019ed98953SRafael J. Wysocki * 5029ed98953SRafael J. Wysocki * Update links to consumers for @dev by changing their status to "dormant" and 5039ed98953SRafael J. Wysocki * invoke %__device_links_no_driver() to update links to suppliers for it as 5049ed98953SRafael J. Wysocki * appropriate. 5059ed98953SRafael J. Wysocki * 5069ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5079ed98953SRafael J. Wysocki */ 5089ed98953SRafael J. Wysocki void device_links_driver_cleanup(struct device *dev) 5099ed98953SRafael J. Wysocki { 5109ed98953SRafael J. Wysocki struct device_link *link; 5119ed98953SRafael J. Wysocki 5129ed98953SRafael J. Wysocki device_links_write_lock(); 5139ed98953SRafael J. Wysocki 5149ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5159ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5169ed98953SRafael J. Wysocki continue; 5179ed98953SRafael J. Wysocki 5189ed98953SRafael J. Wysocki WARN_ON(link->flags & DL_FLAG_AUTOREMOVE); 5199ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND); 5209ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_DORMANT); 5219ed98953SRafael J. Wysocki } 5229ed98953SRafael J. Wysocki 5239ed98953SRafael J. Wysocki __device_links_no_driver(dev); 5249ed98953SRafael J. Wysocki 5259ed98953SRafael J. Wysocki device_links_write_unlock(); 5269ed98953SRafael J. Wysocki } 5279ed98953SRafael J. Wysocki 5289ed98953SRafael J. Wysocki /** 5299ed98953SRafael J. Wysocki * device_links_busy - Check if there are any busy links to consumers. 5309ed98953SRafael J. Wysocki * @dev: Device to check. 5319ed98953SRafael J. Wysocki * 5329ed98953SRafael J. Wysocki * Check each consumer of the device and return 'true' if its link's status 5339ed98953SRafael J. Wysocki * is one of "consumer probe" or "active" (meaning that the given consumer is 5349ed98953SRafael J. Wysocki * probing right now or its driver is present). Otherwise, change the link 5359ed98953SRafael J. Wysocki * state to "supplier unbind" to prevent the consumer from being probed 5369ed98953SRafael J. Wysocki * successfully going forward. 5379ed98953SRafael J. Wysocki * 5389ed98953SRafael J. Wysocki * Return 'false' if there are no probing or active consumers. 5399ed98953SRafael J. Wysocki * 5409ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5419ed98953SRafael J. Wysocki */ 5429ed98953SRafael J. Wysocki bool device_links_busy(struct device *dev) 5439ed98953SRafael J. Wysocki { 5449ed98953SRafael J. Wysocki struct device_link *link; 5459ed98953SRafael J. Wysocki bool ret = false; 5469ed98953SRafael J. Wysocki 5479ed98953SRafael J. Wysocki device_links_write_lock(); 5489ed98953SRafael J. Wysocki 5499ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5509ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5519ed98953SRafael J. Wysocki continue; 5529ed98953SRafael J. Wysocki 5539ed98953SRafael J. Wysocki if (link->status == DL_STATE_CONSUMER_PROBE 5549ed98953SRafael J. Wysocki || link->status == DL_STATE_ACTIVE) { 5559ed98953SRafael J. Wysocki ret = true; 5569ed98953SRafael J. Wysocki break; 5579ed98953SRafael J. Wysocki } 5589ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 5599ed98953SRafael J. Wysocki } 5609ed98953SRafael J. Wysocki 5619ed98953SRafael J. Wysocki dev->links.status = DL_DEV_UNBINDING; 5629ed98953SRafael J. Wysocki 5639ed98953SRafael J. Wysocki device_links_write_unlock(); 5649ed98953SRafael J. Wysocki return ret; 5659ed98953SRafael J. Wysocki } 5669ed98953SRafael J. Wysocki 5679ed98953SRafael J. Wysocki /** 5689ed98953SRafael J. Wysocki * device_links_unbind_consumers - Force unbind consumers of the given device. 5699ed98953SRafael J. Wysocki * @dev: Device to unbind the consumers of. 5709ed98953SRafael J. Wysocki * 5719ed98953SRafael J. Wysocki * Walk the list of links to consumers for @dev and if any of them is in the 5729ed98953SRafael J. Wysocki * "consumer probe" state, wait for all device probes in progress to complete 5739ed98953SRafael J. Wysocki * and start over. 5749ed98953SRafael J. Wysocki * 5759ed98953SRafael J. Wysocki * If that's not the case, change the status of the link to "supplier unbind" 5769ed98953SRafael J. Wysocki * and check if the link was in the "active" state. If so, force the consumer 5779ed98953SRafael J. Wysocki * driver to unbind and start over (the consumer will not re-probe as we have 5789ed98953SRafael J. Wysocki * changed the state of the link already). 5799ed98953SRafael J. Wysocki * 5809ed98953SRafael J. Wysocki * Links with the DL_FLAG_STATELESS flag set are ignored. 5819ed98953SRafael J. Wysocki */ 5829ed98953SRafael J. Wysocki void device_links_unbind_consumers(struct device *dev) 5839ed98953SRafael J. Wysocki { 5849ed98953SRafael J. Wysocki struct device_link *link; 5859ed98953SRafael J. Wysocki 5869ed98953SRafael J. Wysocki start: 5879ed98953SRafael J. Wysocki device_links_write_lock(); 5889ed98953SRafael J. Wysocki 5899ed98953SRafael J. Wysocki list_for_each_entry(link, &dev->links.consumers, s_node) { 5909ed98953SRafael J. Wysocki enum device_link_state status; 5919ed98953SRafael J. Wysocki 5929ed98953SRafael J. Wysocki if (link->flags & DL_FLAG_STATELESS) 5939ed98953SRafael J. Wysocki continue; 5949ed98953SRafael J. Wysocki 5959ed98953SRafael J. Wysocki status = link->status; 5969ed98953SRafael J. Wysocki if (status == DL_STATE_CONSUMER_PROBE) { 5979ed98953SRafael J. Wysocki device_links_write_unlock(); 5989ed98953SRafael J. Wysocki 5999ed98953SRafael J. Wysocki wait_for_device_probe(); 6009ed98953SRafael J. Wysocki goto start; 6019ed98953SRafael J. Wysocki } 6029ed98953SRafael J. Wysocki WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND); 6039ed98953SRafael J. Wysocki if (status == DL_STATE_ACTIVE) { 6049ed98953SRafael J. Wysocki struct device *consumer = link->consumer; 6059ed98953SRafael J. Wysocki 6069ed98953SRafael J. Wysocki get_device(consumer); 6079ed98953SRafael J. Wysocki 6089ed98953SRafael J. Wysocki device_links_write_unlock(); 6099ed98953SRafael J. Wysocki 6109ed98953SRafael J. Wysocki device_release_driver_internal(consumer, NULL, 6119ed98953SRafael J. Wysocki consumer->parent); 6129ed98953SRafael J. Wysocki put_device(consumer); 6139ed98953SRafael J. Wysocki goto start; 6149ed98953SRafael J. Wysocki } 6159ed98953SRafael J. Wysocki } 6169ed98953SRafael J. Wysocki 6179ed98953SRafael J. Wysocki device_links_write_unlock(); 6189ed98953SRafael J. Wysocki } 6199ed98953SRafael J. Wysocki 6209ed98953SRafael J. Wysocki /** 6219ed98953SRafael J. Wysocki * device_links_purge - Delete existing links to other devices. 6229ed98953SRafael J. Wysocki * @dev: Target device. 6239ed98953SRafael J. Wysocki */ 6249ed98953SRafael J. Wysocki static void device_links_purge(struct device *dev) 6259ed98953SRafael J. Wysocki { 6269ed98953SRafael J. Wysocki struct device_link *link, *ln; 6279ed98953SRafael J. Wysocki 6289ed98953SRafael J. Wysocki /* 6299ed98953SRafael J. Wysocki * Delete all of the remaining links from this device to any other 6309ed98953SRafael J. Wysocki * devices (either consumers or suppliers). 6319ed98953SRafael J. Wysocki */ 6329ed98953SRafael J. Wysocki device_links_write_lock(); 6339ed98953SRafael J. Wysocki 6349ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { 6359ed98953SRafael J. Wysocki WARN_ON(link->status == DL_STATE_ACTIVE); 636ead18c23SLukas Wunner __device_link_del(&link->kref); 6379ed98953SRafael J. Wysocki } 6389ed98953SRafael J. Wysocki 6399ed98953SRafael J. Wysocki list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) { 6409ed98953SRafael J. Wysocki WARN_ON(link->status != DL_STATE_DORMANT && 6419ed98953SRafael J. Wysocki link->status != DL_STATE_NONE); 642ead18c23SLukas Wunner __device_link_del(&link->kref); 6439ed98953SRafael J. Wysocki } 6449ed98953SRafael J. Wysocki 6459ed98953SRafael J. Wysocki device_links_write_unlock(); 6469ed98953SRafael J. Wysocki } 6479ed98953SRafael J. Wysocki 6489ed98953SRafael J. Wysocki /* Device links support end. */ 6499ed98953SRafael J. Wysocki 6501da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 6511da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 652e105b8bfSDan Williams static struct kobject *dev_kobj; 653e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 654e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 6551da177e4SLinus Torvalds 6565e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 6575e33bc41SRafael J. Wysocki 6585e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 6595e33bc41SRafael J. Wysocki { 6605e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 6615e33bc41SRafael J. Wysocki } 6625e33bc41SRafael J. Wysocki 6635e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 6645e33bc41SRafael J. Wysocki { 6655e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 6665e33bc41SRafael J. Wysocki } 6675e33bc41SRafael J. Wysocki 6685e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 6695e33bc41SRafael J. Wysocki { 6705e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 6715e33bc41SRafael J. Wysocki return 0; 6725e33bc41SRafael J. Wysocki 6735e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 6745e33bc41SRafael J. Wysocki msleep(5); 6755e33bc41SRafael J. Wysocki return restart_syscall(); 6765e33bc41SRafael J. Wysocki } 6775e33bc41SRafael J. Wysocki 6784e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 6794e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6804e886c29SGreg Kroah-Hartman { 6814e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 6824e886c29SGreg Kroah-Hartman } 6834e886c29SGreg Kroah-Hartman #else 6844e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 6854e886c29SGreg Kroah-Hartman { 6864e886c29SGreg Kroah-Hartman return 1; 6874e886c29SGreg Kroah-Hartman } 6884e886c29SGreg Kroah-Hartman #endif 6891da177e4SLinus Torvalds 6903e95637aSAlan Stern /** 6913e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 6923e95637aSAlan Stern * @dev: struct device to get the name of 6933e95637aSAlan Stern * 6943e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 6959169c012Syan * the device is not bound to a driver, it will return the name of the bus 6963e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 6973e95637aSAlan Stern * string will be returned. 6983e95637aSAlan Stern */ 699bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 7003e95637aSAlan Stern { 7013589972eSAlan Stern struct device_driver *drv; 7023589972eSAlan Stern 7033589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 7043589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 7053589972eSAlan Stern * never change once they are set, so they don't need special care. 7063589972eSAlan Stern */ 7076aa7de05SMark Rutland drv = READ_ONCE(dev->driver); 7083589972eSAlan Stern return drv ? drv->name : 709a456b702SJean Delvare (dev->bus ? dev->bus->name : 710a456b702SJean Delvare (dev->class ? dev->class->name : "")); 7113e95637aSAlan Stern } 712310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 7133e95637aSAlan Stern 7141da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 7151da177e4SLinus Torvalds 7164a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 7174a3ad20cSGreg Kroah-Hartman char *buf) 7181da177e4SLinus Torvalds { 7191da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 720b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 7214a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 7221da177e4SLinus Torvalds 7231da177e4SLinus Torvalds if (dev_attr->show) 72454b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 725815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 726a52668c6SSergey Senozhatsky printk("dev_attr_show: %pS returned bad count\n", 727a52668c6SSergey Senozhatsky dev_attr->show); 728815d2d50SAndrew Morton } 7291da177e4SLinus Torvalds return ret; 7301da177e4SLinus Torvalds } 7311da177e4SLinus Torvalds 7324a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 7331da177e4SLinus Torvalds const char *buf, size_t count) 7341da177e4SLinus Torvalds { 7351da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 736b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 7374a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 7381da177e4SLinus Torvalds 7391da177e4SLinus Torvalds if (dev_attr->store) 74054b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 7411da177e4SLinus Torvalds return ret; 7421da177e4SLinus Torvalds } 7431da177e4SLinus Torvalds 74452cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 7451da177e4SLinus Torvalds .show = dev_attr_show, 7461da177e4SLinus Torvalds .store = dev_attr_store, 7471da177e4SLinus Torvalds }; 7481da177e4SLinus Torvalds 749ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 750ca22e56dSKay Sievers 751ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 752ca22e56dSKay Sievers struct device_attribute *attr, 753ca22e56dSKay Sievers const char *buf, size_t size) 754ca22e56dSKay Sievers { 755ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 756ca22e56dSKay Sievers char *end; 757ca22e56dSKay Sievers unsigned long new = simple_strtoul(buf, &end, 0); 758ca22e56dSKay Sievers if (end == buf) 759ca22e56dSKay Sievers return -EINVAL; 760ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 761ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 762ca22e56dSKay Sievers return size; 763ca22e56dSKay Sievers } 764ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 765ca22e56dSKay Sievers 766ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 767ca22e56dSKay Sievers struct device_attribute *attr, 768ca22e56dSKay Sievers char *buf) 769ca22e56dSKay Sievers { 770ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 771ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); 772ca22e56dSKay Sievers } 773ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 774ca22e56dSKay Sievers 775ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 776ca22e56dSKay Sievers struct device_attribute *attr, 777ca22e56dSKay Sievers const char *buf, size_t size) 778ca22e56dSKay Sievers { 779ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 780ca22e56dSKay Sievers char *end; 781ca22e56dSKay Sievers long new = simple_strtol(buf, &end, 0); 782ca22e56dSKay Sievers if (end == buf || new > INT_MAX || new < INT_MIN) 783ca22e56dSKay Sievers return -EINVAL; 784ca22e56dSKay Sievers *(int *)(ea->var) = new; 785ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 786ca22e56dSKay Sievers return size; 787ca22e56dSKay Sievers } 788ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 789ca22e56dSKay Sievers 790ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 791ca22e56dSKay Sievers struct device_attribute *attr, 792ca22e56dSKay Sievers char *buf) 793ca22e56dSKay Sievers { 794ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 795ca22e56dSKay Sievers 796ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); 797ca22e56dSKay Sievers } 798ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 7991da177e4SLinus Torvalds 80091872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 80191872392SBorislav Petkov const char *buf, size_t size) 80291872392SBorislav Petkov { 80391872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 80491872392SBorislav Petkov 80591872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 80691872392SBorislav Petkov return -EINVAL; 80791872392SBorislav Petkov 80891872392SBorislav Petkov return size; 80991872392SBorislav Petkov } 81091872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 81191872392SBorislav Petkov 81291872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 81391872392SBorislav Petkov char *buf) 81491872392SBorislav Petkov { 81591872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 81691872392SBorislav Petkov 81791872392SBorislav Petkov return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); 81891872392SBorislav Petkov } 81991872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 82091872392SBorislav Petkov 8211da177e4SLinus Torvalds /** 8221da177e4SLinus Torvalds * device_release - free device structure. 8231da177e4SLinus Torvalds * @kobj: device's kobject. 8241da177e4SLinus Torvalds * 8251da177e4SLinus Torvalds * This is called once the reference count for the object 8261da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 8271da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 8281da177e4SLinus Torvalds */ 8291da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 8301da177e4SLinus Torvalds { 831b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 832fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 8331da177e4SLinus Torvalds 834a525a3ddSMing Lei /* 835a525a3ddSMing Lei * Some platform devices are driven without driver attached 836a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 837a525a3ddSMing Lei * all resources are released. 838a525a3ddSMing Lei * 839a525a3ddSMing Lei * Drivers still can add resources into device after device 840a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 841a525a3ddSMing Lei * possible memory leak. 842a525a3ddSMing Lei */ 843a525a3ddSMing Lei devres_release_all(dev); 844a525a3ddSMing Lei 8451da177e4SLinus Torvalds if (dev->release) 8461da177e4SLinus Torvalds dev->release(dev); 847f9f852dfSKay Sievers else if (dev->type && dev->type->release) 848f9f852dfSKay Sievers dev->type->release(dev); 8492620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 8502620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 851f810a5cfSArjan van de Ven else 852f810a5cfSArjan van de Ven WARN(1, KERN_ERR "Device '%s' does not have a release() " 8534a3ad20cSGreg Kroah-Hartman "function, it is broken and must be fixed.\n", 8541e0b2cf9SKay Sievers dev_name(dev)); 855fb069a5dSGreg Kroah-Hartman kfree(p); 8561da177e4SLinus Torvalds } 8571da177e4SLinus Torvalds 858bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 859bc451f20SEric W. Biederman { 860b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 861bc451f20SEric W. Biederman const void *ns = NULL; 862bc451f20SEric W. Biederman 863bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 864bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 865bc451f20SEric W. Biederman 866bc451f20SEric W. Biederman return ns; 867bc451f20SEric W. Biederman } 868bc451f20SEric W. Biederman 8698f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 8701da177e4SLinus Torvalds .release = device_release, 8711da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 872bc451f20SEric W. Biederman .namespace = device_namespace, 8731da177e4SLinus Torvalds }; 8741da177e4SLinus Torvalds 8751da177e4SLinus Torvalds 876312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 8771da177e4SLinus Torvalds { 8781da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 8791da177e4SLinus Torvalds 8808f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 881b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8821da177e4SLinus Torvalds if (dev->bus) 8831da177e4SLinus Torvalds return 1; 88423681e47SGreg Kroah-Hartman if (dev->class) 88523681e47SGreg Kroah-Hartman return 1; 8861da177e4SLinus Torvalds } 8871da177e4SLinus Torvalds return 0; 8881da177e4SLinus Torvalds } 8891da177e4SLinus Torvalds 890312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 8911da177e4SLinus Torvalds { 892b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 8931da177e4SLinus Torvalds 89423681e47SGreg Kroah-Hartman if (dev->bus) 8951da177e4SLinus Torvalds return dev->bus->name; 89623681e47SGreg Kroah-Hartman if (dev->class) 89723681e47SGreg Kroah-Hartman return dev->class->name; 89823681e47SGreg Kroah-Hartman return NULL; 8991da177e4SLinus Torvalds } 9001da177e4SLinus Torvalds 9017eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 9027eff2e7aSKay Sievers struct kobj_uevent_env *env) 9031da177e4SLinus Torvalds { 904b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 9051da177e4SLinus Torvalds int retval = 0; 9061da177e4SLinus Torvalds 9076fcf53acSKay Sievers /* add device node properties if present */ 90823681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 9096fcf53acSKay Sievers const char *tmp; 9106fcf53acSKay Sievers const char *name; 9112c9ede55SAl Viro umode_t mode = 0; 9124e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 9134e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 9146fcf53acSKay Sievers 9157eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 9167eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 9173c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 9186fcf53acSKay Sievers if (name) { 9196fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 920e454cea2SKay Sievers if (mode) 921e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 9224e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 9234e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 9244e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 9254e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 9263c2670e6SKay Sievers kfree(tmp); 9276fcf53acSKay Sievers } 92823681e47SGreg Kroah-Hartman } 92923681e47SGreg Kroah-Hartman 930414264f9SKay Sievers if (dev->type && dev->type->name) 9317eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 932414264f9SKay Sievers 933239378f1SKay Sievers if (dev->driver) 9347eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 935239378f1SKay Sievers 93607d57a32SGrant Likely /* Add common DT information about the device */ 93707d57a32SGrant Likely of_device_uevent(dev, env); 93807d57a32SGrant Likely 9391da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 9407eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 9417eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 942f9f852dfSKay Sievers if (retval) 9437dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 9441e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 9451da177e4SLinus Torvalds } 9461da177e4SLinus Torvalds 9472620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 9487eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 9497eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 950f9f852dfSKay Sievers if (retval) 9517dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 9521e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9532b3a302aSHarvey Harrison __func__, retval); 9542620efefSGreg Kroah-Hartman } 955f9f852dfSKay Sievers 956eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 9577eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 9587eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 959f9f852dfSKay Sievers if (retval) 9607dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 9611e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 9622b3a302aSHarvey Harrison __func__, retval); 9632620efefSGreg Kroah-Hartman } 9642620efefSGreg Kroah-Hartman 9651da177e4SLinus Torvalds return retval; 9661da177e4SLinus Torvalds } 9671da177e4SLinus Torvalds 9689cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 969312c004dSKay Sievers .filter = dev_uevent_filter, 970312c004dSKay Sievers .name = dev_uevent_name, 971312c004dSKay Sievers .uevent = dev_uevent, 9721da177e4SLinus Torvalds }; 9731da177e4SLinus Torvalds 974c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 97516574dccSKay Sievers char *buf) 97616574dccSKay Sievers { 97716574dccSKay Sievers struct kobject *top_kobj; 97816574dccSKay Sievers struct kset *kset; 9797eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 98016574dccSKay Sievers int i; 98116574dccSKay Sievers size_t count = 0; 98216574dccSKay Sievers int retval; 98316574dccSKay Sievers 98416574dccSKay Sievers /* search the kset, the device belongs to */ 98516574dccSKay Sievers top_kobj = &dev->kobj; 9865c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 98716574dccSKay Sievers top_kobj = top_kobj->parent; 98816574dccSKay Sievers if (!top_kobj->kset) 98916574dccSKay Sievers goto out; 9905c5daf65SKay Sievers 99116574dccSKay Sievers kset = top_kobj->kset; 99216574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 99316574dccSKay Sievers goto out; 99416574dccSKay Sievers 99516574dccSKay Sievers /* respect filter */ 99616574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 99716574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 99816574dccSKay Sievers goto out; 99916574dccSKay Sievers 10007eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 10017eff2e7aSKay Sievers if (!env) 1002c7308c81SGreg Kroah-Hartman return -ENOMEM; 1003c7308c81SGreg Kroah-Hartman 100416574dccSKay Sievers /* let the kset specific function add its keys */ 10057eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 100616574dccSKay Sievers if (retval) 100716574dccSKay Sievers goto out; 100816574dccSKay Sievers 100916574dccSKay Sievers /* copy keys to file */ 10107eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 10117eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 101216574dccSKay Sievers out: 10137eff2e7aSKay Sievers kfree(env); 101416574dccSKay Sievers return count; 101516574dccSKay Sievers } 101616574dccSKay Sievers 1017c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 1018a7fd6706SKay Sievers const char *buf, size_t count) 1019a7fd6706SKay Sievers { 1020f36776faSPeter Rajnoha if (kobject_synth_uevent(&dev->kobj, buf, count)) 1021f36776faSPeter Rajnoha dev_err(dev, "uevent: failed to send synthetic uevent\n"); 102260a96a59SKay Sievers 1023a7fd6706SKay Sievers return count; 1024a7fd6706SKay Sievers } 1025c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 1026a7fd6706SKay Sievers 1027c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 10284f3549d7SRafael J. Wysocki char *buf) 10294f3549d7SRafael J. Wysocki { 10304f3549d7SRafael J. Wysocki bool val; 10314f3549d7SRafael J. Wysocki 10325e33bc41SRafael J. Wysocki device_lock(dev); 10334f3549d7SRafael J. Wysocki val = !dev->offline; 10345e33bc41SRafael J. Wysocki device_unlock(dev); 10354f3549d7SRafael J. Wysocki return sprintf(buf, "%u\n", val); 10364f3549d7SRafael J. Wysocki } 10374f3549d7SRafael J. Wysocki 1038c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 10394f3549d7SRafael J. Wysocki const char *buf, size_t count) 10404f3549d7SRafael J. Wysocki { 10414f3549d7SRafael J. Wysocki bool val; 10424f3549d7SRafael J. Wysocki int ret; 10434f3549d7SRafael J. Wysocki 10444f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 10454f3549d7SRafael J. Wysocki if (ret < 0) 10464f3549d7SRafael J. Wysocki return ret; 10474f3549d7SRafael J. Wysocki 10485e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 10495e33bc41SRafael J. Wysocki if (ret) 10505e33bc41SRafael J. Wysocki return ret; 10515e33bc41SRafael J. Wysocki 10524f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 10534f3549d7SRafael J. Wysocki unlock_device_hotplug(); 10544f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 10554f3549d7SRafael J. Wysocki } 1056c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 10574f3549d7SRafael J. Wysocki 1058fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 1059621a1672SDmitry Torokhov { 10603e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 1061621a1672SDmitry Torokhov } 1062a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_add_groups); 1063621a1672SDmitry Torokhov 1064fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 1065a4dbd674SDavid Brownell const struct attribute_group **groups) 1066621a1672SDmitry Torokhov { 10673e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 1068621a1672SDmitry Torokhov } 1069a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_remove_groups); 1070de0ff00dSGreg Kroah-Hartman 107157b8ff07SDmitry Torokhov union device_attr_group_devres { 107257b8ff07SDmitry Torokhov const struct attribute_group *group; 107357b8ff07SDmitry Torokhov const struct attribute_group **groups; 107457b8ff07SDmitry Torokhov }; 107557b8ff07SDmitry Torokhov 107657b8ff07SDmitry Torokhov static int devm_attr_group_match(struct device *dev, void *res, void *data) 107757b8ff07SDmitry Torokhov { 107857b8ff07SDmitry Torokhov return ((union device_attr_group_devres *)res)->group == data; 107957b8ff07SDmitry Torokhov } 108057b8ff07SDmitry Torokhov 108157b8ff07SDmitry Torokhov static void devm_attr_group_remove(struct device *dev, void *res) 108257b8ff07SDmitry Torokhov { 108357b8ff07SDmitry Torokhov union device_attr_group_devres *devres = res; 108457b8ff07SDmitry Torokhov const struct attribute_group *group = devres->group; 108557b8ff07SDmitry Torokhov 108657b8ff07SDmitry Torokhov dev_dbg(dev, "%s: removing group %p\n", __func__, group); 108757b8ff07SDmitry Torokhov sysfs_remove_group(&dev->kobj, group); 108857b8ff07SDmitry Torokhov } 108957b8ff07SDmitry Torokhov 109057b8ff07SDmitry Torokhov static void devm_attr_groups_remove(struct device *dev, void *res) 109157b8ff07SDmitry Torokhov { 109257b8ff07SDmitry Torokhov union device_attr_group_devres *devres = res; 109357b8ff07SDmitry Torokhov const struct attribute_group **groups = devres->groups; 109457b8ff07SDmitry Torokhov 109557b8ff07SDmitry Torokhov dev_dbg(dev, "%s: removing groups %p\n", __func__, groups); 109657b8ff07SDmitry Torokhov sysfs_remove_groups(&dev->kobj, groups); 109757b8ff07SDmitry Torokhov } 109857b8ff07SDmitry Torokhov 109957b8ff07SDmitry Torokhov /** 110057b8ff07SDmitry Torokhov * devm_device_add_group - given a device, create a managed attribute group 110157b8ff07SDmitry Torokhov * @dev: The device to create the group for 110257b8ff07SDmitry Torokhov * @grp: The attribute group to create 110357b8ff07SDmitry Torokhov * 110457b8ff07SDmitry Torokhov * This function creates a group for the first time. It will explicitly 110557b8ff07SDmitry Torokhov * warn and error if any of the attribute files being created already exist. 110657b8ff07SDmitry Torokhov * 110757b8ff07SDmitry Torokhov * Returns 0 on success or error code on failure. 110857b8ff07SDmitry Torokhov */ 110957b8ff07SDmitry Torokhov int devm_device_add_group(struct device *dev, const struct attribute_group *grp) 111057b8ff07SDmitry Torokhov { 111157b8ff07SDmitry Torokhov union device_attr_group_devres *devres; 111257b8ff07SDmitry Torokhov int error; 111357b8ff07SDmitry Torokhov 111457b8ff07SDmitry Torokhov devres = devres_alloc(devm_attr_group_remove, 111557b8ff07SDmitry Torokhov sizeof(*devres), GFP_KERNEL); 111657b8ff07SDmitry Torokhov if (!devres) 111757b8ff07SDmitry Torokhov return -ENOMEM; 111857b8ff07SDmitry Torokhov 111957b8ff07SDmitry Torokhov error = sysfs_create_group(&dev->kobj, grp); 112057b8ff07SDmitry Torokhov if (error) { 112157b8ff07SDmitry Torokhov devres_free(devres); 112257b8ff07SDmitry Torokhov return error; 112357b8ff07SDmitry Torokhov } 112457b8ff07SDmitry Torokhov 112557b8ff07SDmitry Torokhov devres->group = grp; 112657b8ff07SDmitry Torokhov devres_add(dev, devres); 112757b8ff07SDmitry Torokhov return 0; 112857b8ff07SDmitry Torokhov } 112957b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_group); 113057b8ff07SDmitry Torokhov 113157b8ff07SDmitry Torokhov /** 113257b8ff07SDmitry Torokhov * devm_device_remove_group: remove a managed group from a device 113357b8ff07SDmitry Torokhov * @dev: device to remove the group from 113457b8ff07SDmitry Torokhov * @grp: group to remove 113557b8ff07SDmitry Torokhov * 113657b8ff07SDmitry Torokhov * This function removes a group of attributes from a device. The attributes 113757b8ff07SDmitry Torokhov * previously have to have been created for this group, otherwise it will fail. 113857b8ff07SDmitry Torokhov */ 113957b8ff07SDmitry Torokhov void devm_device_remove_group(struct device *dev, 114057b8ff07SDmitry Torokhov const struct attribute_group *grp) 114157b8ff07SDmitry Torokhov { 114257b8ff07SDmitry Torokhov WARN_ON(devres_release(dev, devm_attr_group_remove, 114357b8ff07SDmitry Torokhov devm_attr_group_match, 114457b8ff07SDmitry Torokhov /* cast away const */ (void *)grp)); 114557b8ff07SDmitry Torokhov } 114657b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_group); 114757b8ff07SDmitry Torokhov 114857b8ff07SDmitry Torokhov /** 114957b8ff07SDmitry Torokhov * devm_device_add_groups - create a bunch of managed attribute groups 115057b8ff07SDmitry Torokhov * @dev: The device to create the group for 115157b8ff07SDmitry Torokhov * @groups: The attribute groups to create, NULL terminated 115257b8ff07SDmitry Torokhov * 115357b8ff07SDmitry Torokhov * This function creates a bunch of managed attribute groups. If an error 115457b8ff07SDmitry Torokhov * occurs when creating a group, all previously created groups will be 115557b8ff07SDmitry Torokhov * removed, unwinding everything back to the original state when this 115657b8ff07SDmitry Torokhov * function was called. It will explicitly warn and error if any of the 115757b8ff07SDmitry Torokhov * attribute files being created already exist. 115857b8ff07SDmitry Torokhov * 115957b8ff07SDmitry Torokhov * Returns 0 on success or error code from sysfs_create_group on failure. 116057b8ff07SDmitry Torokhov */ 116157b8ff07SDmitry Torokhov int devm_device_add_groups(struct device *dev, 116257b8ff07SDmitry Torokhov const struct attribute_group **groups) 116357b8ff07SDmitry Torokhov { 116457b8ff07SDmitry Torokhov union device_attr_group_devres *devres; 116557b8ff07SDmitry Torokhov int error; 116657b8ff07SDmitry Torokhov 116757b8ff07SDmitry Torokhov devres = devres_alloc(devm_attr_groups_remove, 116857b8ff07SDmitry Torokhov sizeof(*devres), GFP_KERNEL); 116957b8ff07SDmitry Torokhov if (!devres) 117057b8ff07SDmitry Torokhov return -ENOMEM; 117157b8ff07SDmitry Torokhov 117257b8ff07SDmitry Torokhov error = sysfs_create_groups(&dev->kobj, groups); 117357b8ff07SDmitry Torokhov if (error) { 117457b8ff07SDmitry Torokhov devres_free(devres); 117557b8ff07SDmitry Torokhov return error; 117657b8ff07SDmitry Torokhov } 117757b8ff07SDmitry Torokhov 117857b8ff07SDmitry Torokhov devres->groups = groups; 117957b8ff07SDmitry Torokhov devres_add(dev, devres); 118057b8ff07SDmitry Torokhov return 0; 118157b8ff07SDmitry Torokhov } 118257b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_groups); 118357b8ff07SDmitry Torokhov 118457b8ff07SDmitry Torokhov /** 118557b8ff07SDmitry Torokhov * devm_device_remove_groups - remove a list of managed groups 118657b8ff07SDmitry Torokhov * 118757b8ff07SDmitry Torokhov * @dev: The device for the groups to be removed from 118857b8ff07SDmitry Torokhov * @groups: NULL terminated list of groups to be removed 118957b8ff07SDmitry Torokhov * 119057b8ff07SDmitry Torokhov * If groups is not NULL, remove the specified groups from the device. 119157b8ff07SDmitry Torokhov */ 119257b8ff07SDmitry Torokhov void devm_device_remove_groups(struct device *dev, 119357b8ff07SDmitry Torokhov const struct attribute_group **groups) 119457b8ff07SDmitry Torokhov { 119557b8ff07SDmitry Torokhov WARN_ON(devres_release(dev, devm_attr_groups_remove, 119657b8ff07SDmitry Torokhov devm_attr_group_match, 119757b8ff07SDmitry Torokhov /* cast away const */ (void *)groups)); 119857b8ff07SDmitry Torokhov } 119957b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_groups); 12001da177e4SLinus Torvalds 12012620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 12022620efefSGreg Kroah-Hartman { 12032620efefSGreg Kroah-Hartman struct class *class = dev->class; 1204aed65af1SStephen Hemminger const struct device_type *type = dev->type; 1205621a1672SDmitry Torokhov int error; 12062620efefSGreg Kroah-Hartman 1207621a1672SDmitry Torokhov if (class) { 1208d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 12092620efefSGreg Kroah-Hartman if (error) 1210621a1672SDmitry Torokhov return error; 1211f9f852dfSKay Sievers } 1212f9f852dfSKay Sievers 1213621a1672SDmitry Torokhov if (type) { 1214621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 1215f9f852dfSKay Sievers if (error) 1216a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 1217f9f852dfSKay Sievers } 1218621a1672SDmitry Torokhov 1219621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 1220f9f852dfSKay Sievers if (error) 1221621a1672SDmitry Torokhov goto err_remove_type_groups; 1222621a1672SDmitry Torokhov 12234f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 1224c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 12254f3549d7SRafael J. Wysocki if (error) 1226ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 12274f3549d7SRafael J. Wysocki } 12284f3549d7SRafael J. Wysocki 1229621a1672SDmitry Torokhov return 0; 1230621a1672SDmitry Torokhov 1231ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 1232ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 1233621a1672SDmitry Torokhov err_remove_type_groups: 1234621a1672SDmitry Torokhov if (type) 1235621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1236d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 1237d05a6f96SGreg Kroah-Hartman if (class) 1238d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1239f9f852dfSKay Sievers 12402620efefSGreg Kroah-Hartman return error; 12412620efefSGreg Kroah-Hartman } 12422620efefSGreg Kroah-Hartman 12432620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 12442620efefSGreg Kroah-Hartman { 12452620efefSGreg Kroah-Hartman struct class *class = dev->class; 1246aed65af1SStephen Hemminger const struct device_type *type = dev->type; 12472620efefSGreg Kroah-Hartman 1248c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 1249621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 1250f9f852dfSKay Sievers 1251621a1672SDmitry Torokhov if (type) 1252621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 1253621a1672SDmitry Torokhov 1254a6b01dedSGreg Kroah-Hartman if (class) 1255d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 1256c97415a7SStefan Achatz } 12572620efefSGreg Kroah-Hartman 1258c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 125923681e47SGreg Kroah-Hartman char *buf) 126023681e47SGreg Kroah-Hartman { 126123681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 126223681e47SGreg Kroah-Hartman } 1263c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 1264ad6a1e1cSTejun Heo 1265ca22e56dSKay Sievers /* /sys/devices/ */ 1266881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 12671da177e4SLinus Torvalds 12681da177e4SLinus Torvalds /** 126952cdbdd4SGrygorii Strashko * devices_kset_move_before - Move device in the devices_kset's list. 127052cdbdd4SGrygorii Strashko * @deva: Device to move. 127152cdbdd4SGrygorii Strashko * @devb: Device @deva should come before. 127252cdbdd4SGrygorii Strashko */ 127352cdbdd4SGrygorii Strashko static void devices_kset_move_before(struct device *deva, struct device *devb) 127452cdbdd4SGrygorii Strashko { 127552cdbdd4SGrygorii Strashko if (!devices_kset) 127652cdbdd4SGrygorii Strashko return; 127752cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s before %s\n", 127852cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 127952cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 128052cdbdd4SGrygorii Strashko list_move_tail(&deva->kobj.entry, &devb->kobj.entry); 128152cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 128252cdbdd4SGrygorii Strashko } 128352cdbdd4SGrygorii Strashko 128452cdbdd4SGrygorii Strashko /** 128552cdbdd4SGrygorii Strashko * devices_kset_move_after - Move device in the devices_kset's list. 128652cdbdd4SGrygorii Strashko * @deva: Device to move 128752cdbdd4SGrygorii Strashko * @devb: Device @deva should come after. 128852cdbdd4SGrygorii Strashko */ 128952cdbdd4SGrygorii Strashko static void devices_kset_move_after(struct device *deva, struct device *devb) 129052cdbdd4SGrygorii Strashko { 129152cdbdd4SGrygorii Strashko if (!devices_kset) 129252cdbdd4SGrygorii Strashko return; 129352cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s after %s\n", 129452cdbdd4SGrygorii Strashko dev_name(deva), dev_name(devb)); 129552cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 129652cdbdd4SGrygorii Strashko list_move(&deva->kobj.entry, &devb->kobj.entry); 129752cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 129852cdbdd4SGrygorii Strashko } 129952cdbdd4SGrygorii Strashko 130052cdbdd4SGrygorii Strashko /** 130152cdbdd4SGrygorii Strashko * devices_kset_move_last - move the device to the end of devices_kset's list. 130252cdbdd4SGrygorii Strashko * @dev: device to move 130352cdbdd4SGrygorii Strashko */ 130452cdbdd4SGrygorii Strashko void devices_kset_move_last(struct device *dev) 130552cdbdd4SGrygorii Strashko { 130652cdbdd4SGrygorii Strashko if (!devices_kset) 130752cdbdd4SGrygorii Strashko return; 130852cdbdd4SGrygorii Strashko pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); 130952cdbdd4SGrygorii Strashko spin_lock(&devices_kset->list_lock); 131052cdbdd4SGrygorii Strashko list_move_tail(&dev->kobj.entry, &devices_kset->list); 131152cdbdd4SGrygorii Strashko spin_unlock(&devices_kset->list_lock); 131252cdbdd4SGrygorii Strashko } 131352cdbdd4SGrygorii Strashko 131452cdbdd4SGrygorii Strashko /** 13151da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 13161da177e4SLinus Torvalds * @dev: device. 13171da177e4SLinus Torvalds * @attr: device attribute descriptor. 13181da177e4SLinus Torvalds */ 131926579ab7SPhil Carmody int device_create_file(struct device *dev, 132026579ab7SPhil Carmody const struct device_attribute *attr) 13211da177e4SLinus Torvalds { 13221da177e4SLinus Torvalds int error = 0; 13238f46baaaSFelipe Balbi 13248f46baaaSFelipe Balbi if (dev) { 13258f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 132697521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 132797521978Sdyoung@redhat.com attr->attr.name); 13288f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 132997521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 133097521978Sdyoung@redhat.com attr->attr.name); 13311da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 13328f46baaaSFelipe Balbi } 13338f46baaaSFelipe Balbi 13341da177e4SLinus Torvalds return error; 13351da177e4SLinus Torvalds } 133686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 13371da177e4SLinus Torvalds 13381da177e4SLinus Torvalds /** 13391da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 13401da177e4SLinus Torvalds * @dev: device. 13411da177e4SLinus Torvalds * @attr: device attribute descriptor. 13421da177e4SLinus Torvalds */ 134326579ab7SPhil Carmody void device_remove_file(struct device *dev, 134426579ab7SPhil Carmody const struct device_attribute *attr) 13451da177e4SLinus Torvalds { 13460c98b19fSCornelia Huck if (dev) 13471da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 13481da177e4SLinus Torvalds } 134986df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 13501da177e4SLinus Torvalds 13512589f188SGreg Kroah-Hartman /** 13526b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 13536b0afc2aSTejun Heo * @dev: device. 13546b0afc2aSTejun Heo * @attr: device attribute descriptor. 13556b0afc2aSTejun Heo * 13566b0afc2aSTejun Heo * See kernfs_remove_self() for details. 13576b0afc2aSTejun Heo */ 13586b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 13596b0afc2aSTejun Heo const struct device_attribute *attr) 13606b0afc2aSTejun Heo { 13616b0afc2aSTejun Heo if (dev) 13626b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 13636b0afc2aSTejun Heo else 13646b0afc2aSTejun Heo return false; 13656b0afc2aSTejun Heo } 13666b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 13676b0afc2aSTejun Heo 13686b0afc2aSTejun Heo /** 13692589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 13702589f188SGreg Kroah-Hartman * @dev: device. 13712589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 13722589f188SGreg Kroah-Hartman */ 137366ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 137466ecb92bSPhil Carmody const struct bin_attribute *attr) 13752589f188SGreg Kroah-Hartman { 13762589f188SGreg Kroah-Hartman int error = -EINVAL; 13772589f188SGreg Kroah-Hartman if (dev) 13782589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 13792589f188SGreg Kroah-Hartman return error; 13802589f188SGreg Kroah-Hartman } 13812589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 13822589f188SGreg Kroah-Hartman 13832589f188SGreg Kroah-Hartman /** 13842589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 13852589f188SGreg Kroah-Hartman * @dev: device. 13862589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 13872589f188SGreg Kroah-Hartman */ 138866ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 138966ecb92bSPhil Carmody const struct bin_attribute *attr) 13902589f188SGreg Kroah-Hartman { 13912589f188SGreg Kroah-Hartman if (dev) 13922589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 13932589f188SGreg Kroah-Hartman } 13942589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 13952589f188SGreg Kroah-Hartman 139634bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 139734bb61f9SJames Bottomley { 1398f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1399f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 140034bb61f9SJames Bottomley 140134bb61f9SJames Bottomley get_device(dev); 140234bb61f9SJames Bottomley } 140334bb61f9SJames Bottomley 140434bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 140534bb61f9SJames Bottomley { 1406f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 1407f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 140834bb61f9SJames Bottomley 140934bb61f9SJames Bottomley put_device(dev); 141034bb61f9SJames Bottomley } 141134bb61f9SJames Bottomley 14121da177e4SLinus Torvalds /** 14131da177e4SLinus Torvalds * device_initialize - init device structure. 14141da177e4SLinus Torvalds * @dev: device. 14151da177e4SLinus Torvalds * 14165739411aSCornelia Huck * This prepares the device for use by other layers by initializing 14175739411aSCornelia Huck * its fields. 14181da177e4SLinus Torvalds * It is the first half of device_register(), if called by 14195739411aSCornelia Huck * that function, though it can also be called separately, so one 14205739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 14215739411aSCornelia Huck * may be used for reference counting of @dev after calling this 14225739411aSCornelia Huck * function. 14235739411aSCornelia Huck * 1424b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 1425b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 1426b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 1427b10d5efdSAlan Stern * @dev. 1428b10d5efdSAlan Stern * 14295739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 14305739411aSCornelia Huck * @dev directly once you have called this function. 14311da177e4SLinus Torvalds */ 14321da177e4SLinus Torvalds void device_initialize(struct device *dev) 14331da177e4SLinus Torvalds { 1434881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 1435f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 14361da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 14373142788bSThomas Gleixner mutex_init(&dev->mutex); 14381704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 14399ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 14409ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 14413b98aeafSAlan Stern device_pm_init(dev); 144287348136SChristoph Hellwig set_dev_node(dev, -1); 14434a7cc831SJiang Liu #ifdef CONFIG_GENERIC_MSI_IRQ 14444a7cc831SJiang Liu INIT_LIST_HEAD(&dev->msi_list); 14454a7cc831SJiang Liu #endif 14469ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.consumers); 14479ed98953SRafael J. Wysocki INIT_LIST_HEAD(&dev->links.suppliers); 14489ed98953SRafael J. Wysocki dev->links.status = DL_DEV_NO_DRIVER; 14491da177e4SLinus Torvalds } 145086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 14511da177e4SLinus Torvalds 1452d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 1453f0ee61a6SGreg Kroah-Hartman { 1454f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 1455f0ee61a6SGreg Kroah-Hartman 1456f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 14574ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 1458881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 1459f0ee61a6SGreg Kroah-Hartman 146086406245SKay Sievers return virtual_dir; 1461f0ee61a6SGreg Kroah-Hartman } 1462f0ee61a6SGreg Kroah-Hartman 1463bc451f20SEric W. Biederman struct class_dir { 1464bc451f20SEric W. Biederman struct kobject kobj; 1465bc451f20SEric W. Biederman struct class *class; 1466bc451f20SEric W. Biederman }; 1467bc451f20SEric W. Biederman 1468bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 1469bc451f20SEric W. Biederman 1470bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 1471bc451f20SEric W. Biederman { 1472bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1473bc451f20SEric W. Biederman kfree(dir); 1474bc451f20SEric W. Biederman } 1475bc451f20SEric W. Biederman 1476bc451f20SEric W. Biederman static const 1477bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 1478bc451f20SEric W. Biederman { 1479bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 1480bc451f20SEric W. Biederman return dir->class->ns_type; 1481bc451f20SEric W. Biederman } 1482bc451f20SEric W. Biederman 1483bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 1484bc451f20SEric W. Biederman .release = class_dir_release, 1485bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 1486bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 1487bc451f20SEric W. Biederman }; 1488bc451f20SEric W. Biederman 1489bc451f20SEric W. Biederman static struct kobject * 1490bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 1491bc451f20SEric W. Biederman { 1492bc451f20SEric W. Biederman struct class_dir *dir; 1493bc451f20SEric W. Biederman int retval; 1494bc451f20SEric W. Biederman 1495bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 1496bc451f20SEric W. Biederman if (!dir) 149784d0c27dSTetsuo Handa return ERR_PTR(-ENOMEM); 1498bc451f20SEric W. Biederman 1499bc451f20SEric W. Biederman dir->class = class; 1500bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 1501bc451f20SEric W. Biederman 15026b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 1503bc451f20SEric W. Biederman 1504bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 1505bc451f20SEric W. Biederman if (retval < 0) { 1506bc451f20SEric W. Biederman kobject_put(&dir->kobj); 150784d0c27dSTetsuo Handa return ERR_PTR(retval); 1508bc451f20SEric W. Biederman } 1509bc451f20SEric W. Biederman return &dir->kobj; 1510bc451f20SEric W. Biederman } 1511bc451f20SEric W. Biederman 1512e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex); 1513bc451f20SEric W. Biederman 1514c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 1515c744aeaeSCornelia Huck struct device *parent) 151640fa5422SGreg Kroah-Hartman { 151786406245SKay Sievers if (dev->class) { 151886406245SKay Sievers struct kobject *kobj = NULL; 151986406245SKay Sievers struct kobject *parent_kobj; 152086406245SKay Sievers struct kobject *k; 152186406245SKay Sievers 1522ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 152339aba963SKay Sievers /* block disks show up in /sys/block */ 1524e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 152539aba963SKay Sievers if (parent && parent->class == &block_class) 152639aba963SKay Sievers return &parent->kobj; 15276b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 152839aba963SKay Sievers } 1529ead454feSRandy Dunlap #endif 1530e52eec13SAndi Kleen 153186406245SKay Sievers /* 153286406245SKay Sievers * If we have no parent, we live in "virtual". 15330f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 15340f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 153586406245SKay Sievers */ 153686406245SKay Sievers if (parent == NULL) 153786406245SKay Sievers parent_kobj = virtual_device_parent(dev); 153824b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 153986406245SKay Sievers return &parent->kobj; 154086406245SKay Sievers else 154186406245SKay Sievers parent_kobj = &parent->kobj; 154286406245SKay Sievers 154377d3d7c1STejun Heo mutex_lock(&gdp_mutex); 154477d3d7c1STejun Heo 154586406245SKay Sievers /* find our class-directory at the parent and reference it */ 15466b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 15476b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 154886406245SKay Sievers if (k->parent == parent_kobj) { 154986406245SKay Sievers kobj = kobject_get(k); 155086406245SKay Sievers break; 155186406245SKay Sievers } 15526b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 155377d3d7c1STejun Heo if (kobj) { 155477d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 155586406245SKay Sievers return kobj; 155677d3d7c1STejun Heo } 155786406245SKay Sievers 155886406245SKay Sievers /* or create a new class-directory at the parent device */ 1559bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 15600f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 156177d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 156243968d2fSGreg Kroah-Hartman return k; 156386406245SKay Sievers } 156486406245SKay Sievers 1565ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 1566ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 1567ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 1568ca22e56dSKay Sievers 156986406245SKay Sievers if (parent) 1570c744aeaeSCornelia Huck return &parent->kobj; 1571c744aeaeSCornelia Huck return NULL; 1572c744aeaeSCornelia Huck } 1573da231fd5SKay Sievers 1574cebf8fd1SMing Lei static inline bool live_in_glue_dir(struct kobject *kobj, 1575cebf8fd1SMing Lei struct device *dev) 1576cebf8fd1SMing Lei { 1577cebf8fd1SMing Lei if (!kobj || !dev->class || 1578cebf8fd1SMing Lei kobj->kset != &dev->class->p->glue_dirs) 1579cebf8fd1SMing Lei return false; 1580cebf8fd1SMing Lei return true; 1581cebf8fd1SMing Lei } 1582cebf8fd1SMing Lei 1583cebf8fd1SMing Lei static inline struct kobject *get_glue_dir(struct device *dev) 1584cebf8fd1SMing Lei { 1585cebf8fd1SMing Lei return dev->kobj.parent; 1586cebf8fd1SMing Lei } 1587cebf8fd1SMing Lei 1588cebf8fd1SMing Lei /* 1589cebf8fd1SMing Lei * make sure cleaning up dir as the last step, we need to make 1590cebf8fd1SMing Lei * sure .release handler of kobject is run with holding the 1591cebf8fd1SMing Lei * global lock 1592cebf8fd1SMing Lei */ 159363b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 1594da231fd5SKay Sievers { 15950f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 1596cebf8fd1SMing Lei if (!live_in_glue_dir(glue_dir, dev)) 1597da231fd5SKay Sievers return; 1598da231fd5SKay Sievers 1599e4a60d13SYijing Wang mutex_lock(&gdp_mutex); 16000f4dafc0SKay Sievers kobject_put(glue_dir); 1601e4a60d13SYijing Wang mutex_unlock(&gdp_mutex); 1602da231fd5SKay Sievers } 160363b6971aSCornelia Huck 16042ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 16052ee97cafSCornelia Huck { 16065590f319SBenjamin Herrenschmidt struct device_node *of_node = dev_of_node(dev); 16072ee97cafSCornelia Huck int error; 16082ee97cafSCornelia Huck 16095590f319SBenjamin Herrenschmidt if (of_node) { 16100c3c234bSRob Herring error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node"); 16115590f319SBenjamin Herrenschmidt if (error) 16125590f319SBenjamin Herrenschmidt dev_warn(dev, "Error %d creating of_node link\n",error); 16135590f319SBenjamin Herrenschmidt /* An error here doesn't warrant bringing down the device */ 16145590f319SBenjamin Herrenschmidt } 16155590f319SBenjamin Herrenschmidt 16162ee97cafSCornelia Huck if (!dev->class) 16172ee97cafSCornelia Huck return 0; 1618da231fd5SKay Sievers 16191fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 16206b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 16212ee97cafSCornelia Huck "subsystem"); 16222ee97cafSCornelia Huck if (error) 16235590f319SBenjamin Herrenschmidt goto out_devnode; 1624da231fd5SKay Sievers 16254e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 16264f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 16274f01a757SDmitry Torokhov "device"); 16284f01a757SDmitry Torokhov if (error) 162939aba963SKay Sievers goto out_subsys; 16302ee97cafSCornelia Huck } 163139aba963SKay Sievers 1632ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 163339aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 1634e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 163539aba963SKay Sievers return 0; 1636ead454feSRandy Dunlap #endif 163739aba963SKay Sievers 163839aba963SKay Sievers /* link in the class directory pointing to the device */ 16396b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 164039aba963SKay Sievers &dev->kobj, dev_name(dev)); 164139aba963SKay Sievers if (error) 164239aba963SKay Sievers goto out_device; 164339aba963SKay Sievers 16442ee97cafSCornelia Huck return 0; 16452ee97cafSCornelia Huck 164639aba963SKay Sievers out_device: 164739aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 1648da231fd5SKay Sievers 16492ee97cafSCornelia Huck out_subsys: 16502ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 16515590f319SBenjamin Herrenschmidt out_devnode: 16525590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 16532ee97cafSCornelia Huck return error; 16542ee97cafSCornelia Huck } 16552ee97cafSCornelia Huck 16562ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 16572ee97cafSCornelia Huck { 16585590f319SBenjamin Herrenschmidt if (dev_of_node(dev)) 16595590f319SBenjamin Herrenschmidt sysfs_remove_link(&dev->kobj, "of_node"); 16605590f319SBenjamin Herrenschmidt 16612ee97cafSCornelia Huck if (!dev->class) 16622ee97cafSCornelia Huck return; 1663da231fd5SKay Sievers 16644e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 1665da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 16662ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 1667ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 1668e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 166939aba963SKay Sievers return; 1670ead454feSRandy Dunlap #endif 16716b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 16722ee97cafSCornelia Huck } 16732ee97cafSCornelia Huck 16741da177e4SLinus Torvalds /** 1675413c239fSStephen Rothwell * dev_set_name - set a device name 1676413c239fSStephen Rothwell * @dev: device 167746232366SRandy Dunlap * @fmt: format string for the device's name 1678413c239fSStephen Rothwell */ 1679413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 1680413c239fSStephen Rothwell { 1681413c239fSStephen Rothwell va_list vargs; 16821fa5ae85SKay Sievers int err; 1683413c239fSStephen Rothwell 1684413c239fSStephen Rothwell va_start(vargs, fmt); 16851fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 1686413c239fSStephen Rothwell va_end(vargs); 16871fa5ae85SKay Sievers return err; 1688413c239fSStephen Rothwell } 1689413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 1690413c239fSStephen Rothwell 1691413c239fSStephen Rothwell /** 1692e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 1693e105b8bfSDan Williams * @dev: device 1694e105b8bfSDan Williams * 1695e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 1696e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 1697e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 1698e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 16990d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 17000d4e293cSPeter Korsgaard * the link. 1701e105b8bfSDan Williams */ 1702e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 1703e105b8bfSDan Williams { 1704e105b8bfSDan Williams struct kobject *kobj; 1705e105b8bfSDan Williams 1706e105b8bfSDan Williams if (dev->class) 1707e105b8bfSDan Williams kobj = dev->class->dev_kobj; 1708e105b8bfSDan Williams else 1709e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 1710e105b8bfSDan Williams 1711e105b8bfSDan Williams return kobj; 1712e105b8bfSDan Williams } 1713e105b8bfSDan Williams 1714e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 1715e105b8bfSDan Williams { 1716e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1717e105b8bfSDan Williams int error = 0; 1718e105b8bfSDan Williams char devt_str[15]; 1719e105b8bfSDan Williams 1720e105b8bfSDan Williams if (kobj) { 1721e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1722e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 1723e105b8bfSDan Williams } 1724e105b8bfSDan Williams 1725e105b8bfSDan Williams return error; 1726e105b8bfSDan Williams } 1727e105b8bfSDan Williams 1728e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 1729e105b8bfSDan Williams { 1730e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 1731e105b8bfSDan Williams char devt_str[15]; 1732e105b8bfSDan Williams 1733e105b8bfSDan Williams if (kobj) { 1734e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 1735e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 1736e105b8bfSDan Williams } 1737e105b8bfSDan Williams } 1738e105b8bfSDan Williams 1739b4028437SGreg Kroah-Hartman int device_private_init(struct device *dev) 1740b4028437SGreg Kroah-Hartman { 1741b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 1742b4028437SGreg Kroah-Hartman if (!dev->p) 1743b4028437SGreg Kroah-Hartman return -ENOMEM; 1744b4028437SGreg Kroah-Hartman dev->p->device = dev; 1745b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 1746b4028437SGreg Kroah-Hartman klist_children_put); 1747ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 1748b4028437SGreg Kroah-Hartman return 0; 1749b4028437SGreg Kroah-Hartman } 1750b4028437SGreg Kroah-Hartman 1751e105b8bfSDan Williams /** 17521da177e4SLinus Torvalds * device_add - add device to device hierarchy. 17531da177e4SLinus Torvalds * @dev: device. 17541da177e4SLinus Torvalds * 17551da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 17561da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 17571da177e4SLinus Torvalds * 17585739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 17591da177e4SLinus Torvalds * to the global and sibling lists for the device, then 17601da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 17615739411aSCornelia Huck * 1762b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 1763b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 1764b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 1765b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 1766b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 1767b10d5efdSAlan Stern * and register a fresh new struct device instead. 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 your 17715739411aSCornelia Huck * reference instead. 17721da177e4SLinus Torvalds */ 17731da177e4SLinus Torvalds int device_add(struct device *dev) 17741da177e4SLinus Torvalds { 177535dbf4efSViresh Kumar struct device *parent; 1776ca22e56dSKay Sievers struct kobject *kobj; 1777c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 1778c906a48aSGreg Kroah-Hartman int error = -EINVAL; 1779cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1780775b64d2SRafael J. Wysocki 17811da177e4SLinus Torvalds dev = get_device(dev); 1782c906a48aSGreg Kroah-Hartman if (!dev) 1783c906a48aSGreg Kroah-Hartman goto done; 1784c906a48aSGreg Kroah-Hartman 1785fb069a5dSGreg Kroah-Hartman if (!dev->p) { 1786b4028437SGreg Kroah-Hartman error = device_private_init(dev); 1787b4028437SGreg Kroah-Hartman if (error) 1788fb069a5dSGreg Kroah-Hartman goto done; 1789fb069a5dSGreg Kroah-Hartman } 1790fb069a5dSGreg Kroah-Hartman 17911fa5ae85SKay Sievers /* 17921fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 17931fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 17941fa5ae85SKay Sievers * the name, and force the use of dev_name() 17951fa5ae85SKay Sievers */ 17961fa5ae85SKay Sievers if (dev->init_name) { 1797acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 17981fa5ae85SKay Sievers dev->init_name = NULL; 17991fa5ae85SKay Sievers } 1800c906a48aSGreg Kroah-Hartman 1801ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 1802ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 1803ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 1804ca22e56dSKay Sievers 1805e6309e75SThomas Gleixner if (!dev_name(dev)) { 1806e6309e75SThomas Gleixner error = -EINVAL; 18075c8563d7SKay Sievers goto name_error; 1808e6309e75SThomas Gleixner } 18091da177e4SLinus Torvalds 18101e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 1811c205ef48SGreg Kroah-Hartman 18121da177e4SLinus Torvalds parent = get_device(dev->parent); 1813ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 181484d0c27dSTetsuo Handa if (IS_ERR(kobj)) { 181584d0c27dSTetsuo Handa error = PTR_ERR(kobj); 181684d0c27dSTetsuo Handa goto parent_error; 181784d0c27dSTetsuo Handa } 1818ca22e56dSKay Sievers if (kobj) 1819ca22e56dSKay Sievers dev->kobj.parent = kobj; 18201da177e4SLinus Torvalds 18210d358f22SYinghai Lu /* use parent numa_node */ 182256f2de81SZhen Lei if (parent && (dev_to_node(dev) == NUMA_NO_NODE)) 18230d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 18240d358f22SYinghai Lu 18251da177e4SLinus Torvalds /* first, register with generic layer. */ 18268a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 18278a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 1828cebf8fd1SMing Lei if (error) { 1829cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 18301da177e4SLinus Torvalds goto Error; 1831cebf8fd1SMing Lei } 1832a7fd6706SKay Sievers 183337022644SBrian Walsh /* notify platform of device entry */ 183437022644SBrian Walsh if (platform_notify) 183537022644SBrian Walsh platform_notify(dev); 183637022644SBrian Walsh 1837c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 1838a306eea4SCornelia Huck if (error) 1839a306eea4SCornelia Huck goto attrError; 1840a7fd6706SKay Sievers 18412ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 18422ee97cafSCornelia Huck if (error) 18432ee97cafSCornelia Huck goto SymlinkError; 1844dc0afa83SCornelia Huck error = device_add_attrs(dev); 1845dc0afa83SCornelia Huck if (error) 18462620efefSGreg Kroah-Hartman goto AttrsError; 1847dc0afa83SCornelia Huck error = bus_add_device(dev); 1848dc0afa83SCornelia Huck if (error) 18491da177e4SLinus Torvalds goto BusError; 18503b98aeafSAlan Stern error = dpm_sysfs_add(dev); 185157eee3d2SRafael J. Wysocki if (error) 18523b98aeafSAlan Stern goto DPMError; 18533b98aeafSAlan Stern device_pm_add(dev); 1854ec0676eeSAlan Stern 18550cd75047SSergey Klyaus if (MAJOR(dev->devt)) { 18560cd75047SSergey Klyaus error = device_create_file(dev, &dev_attr_dev); 18570cd75047SSergey Klyaus if (error) 18580cd75047SSergey Klyaus goto DevAttrError; 18590cd75047SSergey Klyaus 18600cd75047SSergey Klyaus error = device_create_sys_dev_entry(dev); 18610cd75047SSergey Klyaus if (error) 18620cd75047SSergey Klyaus goto SysEntryError; 18630cd75047SSergey Klyaus 18640cd75047SSergey Klyaus devtmpfs_create_node(dev); 18650cd75047SSergey Klyaus } 18660cd75047SSergey Klyaus 1867ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 1868268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 1869ec0676eeSAlan Stern */ 1870ec0676eeSAlan Stern if (dev->bus) 1871ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1872ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 1873ec0676eeSAlan Stern 187453877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 18752023c610SAlan Stern bus_probe_device(dev); 18761da177e4SLinus Torvalds if (parent) 1877f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1878f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 18791da177e4SLinus Torvalds 18805d9fd169SGreg Kroah-Hartman if (dev->class) { 1881ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1882c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 18835a3ceb86STejun Heo klist_add_tail(&dev->knode_class, 18846b6e39a6SKay Sievers &dev->class->p->klist_devices); 1885c47ed219SGreg Kroah-Hartman 1886c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 1887184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1888ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1889c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 1890c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 1891ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 18925d9fd169SGreg Kroah-Hartman } 1893c906a48aSGreg Kroah-Hartman done: 18941da177e4SLinus Torvalds put_device(dev); 18951da177e4SLinus Torvalds return error; 18960cd75047SSergey Klyaus SysEntryError: 18970cd75047SSergey Klyaus if (MAJOR(dev->devt)) 18980cd75047SSergey Klyaus device_remove_file(dev, &dev_attr_dev); 18990cd75047SSergey Klyaus DevAttrError: 19000cd75047SSergey Klyaus device_pm_remove(dev); 19010cd75047SSergey Klyaus dpm_sysfs_remove(dev); 19023b98aeafSAlan Stern DPMError: 190357eee3d2SRafael J. Wysocki bus_remove_device(dev); 190457eee3d2SRafael J. Wysocki BusError: 19052620efefSGreg Kroah-Hartman device_remove_attrs(dev); 19062620efefSGreg Kroah-Hartman AttrsError: 19072ee97cafSCornelia Huck device_remove_class_symlinks(dev); 19082ee97cafSCornelia Huck SymlinkError: 1909c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 191023681e47SGreg Kroah-Hartman attrError: 1911312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1912cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 19131da177e4SLinus Torvalds kobject_del(&dev->kobj); 19141da177e4SLinus Torvalds Error: 1915cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 191684d0c27dSTetsuo Handa parent_error: 19171da177e4SLinus Torvalds put_device(parent); 19185c8563d7SKay Sievers name_error: 19195c8563d7SKay Sievers kfree(dev->p); 19205c8563d7SKay Sievers dev->p = NULL; 1921c906a48aSGreg Kroah-Hartman goto done; 19221da177e4SLinus Torvalds } 192386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 19241da177e4SLinus Torvalds 19251da177e4SLinus Torvalds /** 19261da177e4SLinus Torvalds * device_register - register a device with the system. 19271da177e4SLinus Torvalds * @dev: pointer to the device structure 19281da177e4SLinus Torvalds * 19291da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 19301da177e4SLinus Torvalds * and add it to the system. The two steps can be called 19311da177e4SLinus Torvalds * separately, but this is the easiest and most common. 19321da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 19331da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 19341da177e4SLinus Torvalds * before it is added to the hierarchy. 19355739411aSCornelia Huck * 1936b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 1937b10d5efdSAlan Stern * and device_add(). 1938b10d5efdSAlan Stern * 19395739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 19405739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 19415739411aSCornelia Huck * reference initialized in this function instead. 19421da177e4SLinus Torvalds */ 19431da177e4SLinus Torvalds int device_register(struct device *dev) 19441da177e4SLinus Torvalds { 19451da177e4SLinus Torvalds device_initialize(dev); 19461da177e4SLinus Torvalds return device_add(dev); 19471da177e4SLinus Torvalds } 194886df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 19491da177e4SLinus Torvalds 19501da177e4SLinus Torvalds /** 19511da177e4SLinus Torvalds * get_device - increment reference count for device. 19521da177e4SLinus Torvalds * @dev: device. 19531da177e4SLinus Torvalds * 19541da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 19551da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 19561da177e4SLinus Torvalds * pointer passed in. 19571da177e4SLinus Torvalds */ 19581da177e4SLinus Torvalds struct device *get_device(struct device *dev) 19591da177e4SLinus Torvalds { 1960b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 19611da177e4SLinus Torvalds } 196286df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds /** 19651da177e4SLinus Torvalds * put_device - decrement reference count. 19661da177e4SLinus Torvalds * @dev: device in question. 19671da177e4SLinus Torvalds */ 19681da177e4SLinus Torvalds void put_device(struct device *dev) 19691da177e4SLinus Torvalds { 1970edfaa7c3SKay Sievers /* might_sleep(); */ 19711da177e4SLinus Torvalds if (dev) 19721da177e4SLinus Torvalds kobject_put(&dev->kobj); 19731da177e4SLinus Torvalds } 197486df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 19751da177e4SLinus Torvalds 19761da177e4SLinus Torvalds /** 19771da177e4SLinus Torvalds * device_del - delete device from system. 19781da177e4SLinus Torvalds * @dev: device. 19791da177e4SLinus Torvalds * 19801da177e4SLinus Torvalds * This is the first part of the device unregistration 19811da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 19821da177e4SLinus Torvalds * from here, has it removed from the other driver model 19831da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 19841da177e4SLinus Torvalds * from the kobject hierarchy. 19851da177e4SLinus Torvalds * 19861da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 19871da177e4SLinus Torvalds * also called manually. 19881da177e4SLinus Torvalds */ 19891da177e4SLinus Torvalds void device_del(struct device *dev) 19901da177e4SLinus Torvalds { 19911da177e4SLinus Torvalds struct device *parent = dev->parent; 1992cebf8fd1SMing Lei struct kobject *glue_dir = NULL; 1993c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 19941da177e4SLinus Torvalds 1995ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 1996ec0676eeSAlan Stern * before dpm_sysfs_remove(). 1997ec0676eeSAlan Stern */ 1998ec0676eeSAlan Stern if (dev->bus) 1999ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 2000ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 20019ed98953SRafael J. Wysocki 20023b98aeafSAlan Stern dpm_sysfs_remove(dev); 20031da177e4SLinus Torvalds if (parent) 2004f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 2005e105b8bfSDan Williams if (MAJOR(dev->devt)) { 20062b2af54aSKay Sievers devtmpfs_delete_node(dev); 2007e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 2008c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 2009e105b8bfSDan Williams } 2010b9d9c82bSKay Sievers if (dev->class) { 2011da231fd5SKay Sievers device_remove_class_symlinks(dev); 201299ef3ef8SKay Sievers 2013ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 2014c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 2015184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 2016ca22e56dSKay Sievers &dev->class->p->interfaces, node) 2017c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 2018c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 2019c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 20205a3ceb86STejun Heo klist_del(&dev->knode_class); 2021ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 2022b9d9c82bSKay Sievers } 2023c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 20242620efefSGreg Kroah-Hartman device_remove_attrs(dev); 202528953533SBenjamin Herrenschmidt bus_remove_device(dev); 20264b6d1f12SLongX Zhang device_pm_remove(dev); 2027d1c3414cSGrant Likely driver_deferred_probe_del(dev); 2028478573c9SLukas Wunner device_remove_properties(dev); 20292ec16150SJeffy Chen device_links_purge(dev); 20301da177e4SLinus Torvalds 20311da177e4SLinus Torvalds /* Notify the platform of the removal, in case they 20321da177e4SLinus Torvalds * need to do anything... 20331da177e4SLinus Torvalds */ 20341da177e4SLinus Torvalds if (platform_notify_remove) 20351da177e4SLinus Torvalds platform_notify_remove(dev); 2036599bad38SJoerg Roedel if (dev->bus) 2037599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 2038599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 2039312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 2040cebf8fd1SMing Lei glue_dir = get_glue_dir(dev); 20411da177e4SLinus Torvalds kobject_del(&dev->kobj); 2042cebf8fd1SMing Lei cleanup_glue_dir(dev, glue_dir); 20431da177e4SLinus Torvalds put_device(parent); 20441da177e4SLinus Torvalds } 204586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 20461da177e4SLinus Torvalds 20471da177e4SLinus Torvalds /** 20481da177e4SLinus Torvalds * device_unregister - unregister device from system. 20491da177e4SLinus Torvalds * @dev: device going away. 20501da177e4SLinus Torvalds * 20511da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 20521da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 20531da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 20541da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 20551da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 20561da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 20571da177e4SLinus Torvalds */ 20581da177e4SLinus Torvalds void device_unregister(struct device *dev) 20591da177e4SLinus Torvalds { 20601e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 20611da177e4SLinus Torvalds device_del(dev); 20621da177e4SLinus Torvalds put_device(dev); 20631da177e4SLinus Torvalds } 206486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 20651da177e4SLinus Torvalds 20663d060aebSAndy Shevchenko static struct device *prev_device(struct klist_iter *i) 20673d060aebSAndy Shevchenko { 20683d060aebSAndy Shevchenko struct klist_node *n = klist_prev(i); 20693d060aebSAndy Shevchenko struct device *dev = NULL; 20703d060aebSAndy Shevchenko struct device_private *p; 20713d060aebSAndy Shevchenko 20723d060aebSAndy Shevchenko if (n) { 20733d060aebSAndy Shevchenko p = to_device_private_parent(n); 20743d060aebSAndy Shevchenko dev = p->device; 20753d060aebSAndy Shevchenko } 20763d060aebSAndy Shevchenko return dev; 20773d060aebSAndy Shevchenko } 20783d060aebSAndy Shevchenko 207936239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 208036239577Smochel@digitalimplant.org { 208136239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 2082f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 2083f791b8c8SGreg Kroah-Hartman struct device_private *p; 2084f791b8c8SGreg Kroah-Hartman 2085f791b8c8SGreg Kroah-Hartman if (n) { 2086f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 2087f791b8c8SGreg Kroah-Hartman dev = p->device; 2088f791b8c8SGreg Kroah-Hartman } 2089f791b8c8SGreg Kroah-Hartman return dev; 209036239577Smochel@digitalimplant.org } 209136239577Smochel@digitalimplant.org 20921da177e4SLinus Torvalds /** 2093e454cea2SKay Sievers * device_get_devnode - path of device node file 20946fcf53acSKay Sievers * @dev: device 2095e454cea2SKay Sievers * @mode: returned file access mode 20963c2670e6SKay Sievers * @uid: returned file owner 20973c2670e6SKay Sievers * @gid: returned file group 20986fcf53acSKay Sievers * @tmp: possibly allocated string 20996fcf53acSKay Sievers * 21006fcf53acSKay Sievers * Return the relative path of a possible device node. 21016fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 21026fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 21036fcf53acSKay Sievers * freed by the caller. 21046fcf53acSKay Sievers */ 2105e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 21064e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 21073c2670e6SKay Sievers const char **tmp) 21086fcf53acSKay Sievers { 21096fcf53acSKay Sievers char *s; 21106fcf53acSKay Sievers 21116fcf53acSKay Sievers *tmp = NULL; 21126fcf53acSKay Sievers 21136fcf53acSKay Sievers /* the device type may provide a specific name */ 2114e454cea2SKay Sievers if (dev->type && dev->type->devnode) 21153c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 21166fcf53acSKay Sievers if (*tmp) 21176fcf53acSKay Sievers return *tmp; 21186fcf53acSKay Sievers 21196fcf53acSKay Sievers /* the class may provide a specific name */ 2120e454cea2SKay Sievers if (dev->class && dev->class->devnode) 2121e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 21226fcf53acSKay Sievers if (*tmp) 21236fcf53acSKay Sievers return *tmp; 21246fcf53acSKay Sievers 21256fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 21266fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 21276fcf53acSKay Sievers return dev_name(dev); 21286fcf53acSKay Sievers 21296fcf53acSKay Sievers /* replace '!' in the name with '/' */ 2130a29fd614SRasmus Villemoes s = kstrdup(dev_name(dev), GFP_KERNEL); 2131a29fd614SRasmus Villemoes if (!s) 21326fcf53acSKay Sievers return NULL; 2133a29fd614SRasmus Villemoes strreplace(s, '!', '/'); 2134a29fd614SRasmus Villemoes return *tmp = s; 21356fcf53acSKay Sievers } 21366fcf53acSKay Sievers 21376fcf53acSKay Sievers /** 21381da177e4SLinus Torvalds * device_for_each_child - device child iterator. 2139c41455fbSRandy Dunlap * @parent: parent struct device. 21401da177e4SLinus Torvalds * @fn: function to be called for each device. 2141f8878dcbSRobert P. J. Day * @data: data for the callback. 21421da177e4SLinus Torvalds * 2143c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 21441da177e4SLinus Torvalds * passing it @data. 21451da177e4SLinus Torvalds * 21461da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 21471da177e4SLinus Torvalds * other than 0, we break out and return that value. 21481da177e4SLinus Torvalds */ 214936239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 21504a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 21511da177e4SLinus Torvalds { 215236239577Smochel@digitalimplant.org struct klist_iter i; 21531da177e4SLinus Torvalds struct device *child; 21541da177e4SLinus Torvalds int error = 0; 21551da177e4SLinus Torvalds 2156014c90dbSGreg Kroah-Hartman if (!parent->p) 2157014c90dbSGreg Kroah-Hartman return 0; 2158014c90dbSGreg Kroah-Hartman 2159f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 216093ead7c9SGimcuan Hui while (!error && (child = next_device(&i))) 216136239577Smochel@digitalimplant.org error = fn(child, data); 216236239577Smochel@digitalimplant.org klist_iter_exit(&i); 21631da177e4SLinus Torvalds return error; 21641da177e4SLinus Torvalds } 216586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 21661da177e4SLinus Torvalds 21675ab69981SCornelia Huck /** 21683d060aebSAndy Shevchenko * device_for_each_child_reverse - device child iterator in reversed order. 21693d060aebSAndy Shevchenko * @parent: parent struct device. 21703d060aebSAndy Shevchenko * @fn: function to be called for each device. 21713d060aebSAndy Shevchenko * @data: data for the callback. 21723d060aebSAndy Shevchenko * 21733d060aebSAndy Shevchenko * Iterate over @parent's child devices, and call @fn for each, 21743d060aebSAndy Shevchenko * passing it @data. 21753d060aebSAndy Shevchenko * 21763d060aebSAndy Shevchenko * We check the return of @fn each time. If it returns anything 21773d060aebSAndy Shevchenko * other than 0, we break out and return that value. 21783d060aebSAndy Shevchenko */ 21793d060aebSAndy Shevchenko int device_for_each_child_reverse(struct device *parent, void *data, 21803d060aebSAndy Shevchenko int (*fn)(struct device *dev, void *data)) 21813d060aebSAndy Shevchenko { 21823d060aebSAndy Shevchenko struct klist_iter i; 21833d060aebSAndy Shevchenko struct device *child; 21843d060aebSAndy Shevchenko int error = 0; 21853d060aebSAndy Shevchenko 21863d060aebSAndy Shevchenko if (!parent->p) 21873d060aebSAndy Shevchenko return 0; 21883d060aebSAndy Shevchenko 21893d060aebSAndy Shevchenko klist_iter_init(&parent->p->klist_children, &i); 21903d060aebSAndy Shevchenko while ((child = prev_device(&i)) && !error) 21913d060aebSAndy Shevchenko error = fn(child, data); 21923d060aebSAndy Shevchenko klist_iter_exit(&i); 21933d060aebSAndy Shevchenko return error; 21943d060aebSAndy Shevchenko } 21953d060aebSAndy Shevchenko EXPORT_SYMBOL_GPL(device_for_each_child_reverse); 21963d060aebSAndy Shevchenko 21973d060aebSAndy Shevchenko /** 21985ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 21995ab69981SCornelia Huck * @parent: parent struct device 22005ab69981SCornelia Huck * @match: Callback function to check device 2201f8878dcbSRobert P. J. Day * @data: Data to pass to match function 22025ab69981SCornelia Huck * 22035ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 22045ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 22055ab69981SCornelia Huck * determined by the @match callback. 22065ab69981SCornelia Huck * 22075ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 22085ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 22095ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 22105ab69981SCornelia Huck * and not iterate over any more devices. 2211a4e2400aSFederico Vaga * 2212a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 22135ab69981SCornelia Huck */ 22145ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 22154a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 22165ab69981SCornelia Huck { 22175ab69981SCornelia Huck struct klist_iter i; 22185ab69981SCornelia Huck struct device *child; 22195ab69981SCornelia Huck 22205ab69981SCornelia Huck if (!parent) 22215ab69981SCornelia Huck return NULL; 22225ab69981SCornelia Huck 2223f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 22245ab69981SCornelia Huck while ((child = next_device(&i))) 22255ab69981SCornelia Huck if (match(child, data) && get_device(child)) 22265ab69981SCornelia Huck break; 22275ab69981SCornelia Huck klist_iter_exit(&i); 22285ab69981SCornelia Huck return child; 22295ab69981SCornelia Huck } 223086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 22315ab69981SCornelia Huck 22321da177e4SLinus Torvalds int __init devices_init(void) 22331da177e4SLinus Torvalds { 2234881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 2235881c6cfdSGreg Kroah-Hartman if (!devices_kset) 2236881c6cfdSGreg Kroah-Hartman return -ENOMEM; 2237e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 2238e105b8bfSDan Williams if (!dev_kobj) 2239e105b8bfSDan Williams goto dev_kobj_err; 2240e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 2241e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 2242e105b8bfSDan Williams goto block_kobj_err; 2243e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 2244e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 2245e105b8bfSDan Williams goto char_kobj_err; 2246e105b8bfSDan Williams 2247881c6cfdSGreg Kroah-Hartman return 0; 2248e105b8bfSDan Williams 2249e105b8bfSDan Williams char_kobj_err: 2250e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 2251e105b8bfSDan Williams block_kobj_err: 2252e105b8bfSDan Williams kobject_put(dev_kobj); 2253e105b8bfSDan Williams dev_kobj_err: 2254e105b8bfSDan Williams kset_unregister(devices_kset); 2255e105b8bfSDan Williams return -ENOMEM; 22561da177e4SLinus Torvalds } 22571da177e4SLinus Torvalds 22584f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 22594f3549d7SRafael J. Wysocki { 22604f3549d7SRafael J. Wysocki int ret; 22614f3549d7SRafael J. Wysocki 22624f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 22634f3549d7SRafael J. Wysocki if (ret) 22644f3549d7SRafael J. Wysocki return ret; 22654f3549d7SRafael J. Wysocki 22664f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 22674f3549d7SRafael J. Wysocki } 22684f3549d7SRafael J. Wysocki 22694f3549d7SRafael J. Wysocki /** 22704f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 22714f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 22724f3549d7SRafael J. Wysocki * 22734f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 22744f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 22754f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 22764f3549d7SRafael J. Wysocki * is executed. 22774f3549d7SRafael J. Wysocki * 22784f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 22794f3549d7SRafael J. Wysocki */ 22804f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 22814f3549d7SRafael J. Wysocki { 22824f3549d7SRafael J. Wysocki int ret; 22834f3549d7SRafael J. Wysocki 22844f3549d7SRafael J. Wysocki if (dev->offline_disabled) 22854f3549d7SRafael J. Wysocki return -EPERM; 22864f3549d7SRafael J. Wysocki 22874f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 22884f3549d7SRafael J. Wysocki if (ret) 22894f3549d7SRafael J. Wysocki return ret; 22904f3549d7SRafael J. Wysocki 22914f3549d7SRafael J. Wysocki device_lock(dev); 22924f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 22934f3549d7SRafael J. Wysocki if (dev->offline) { 22944f3549d7SRafael J. Wysocki ret = 1; 22954f3549d7SRafael J. Wysocki } else { 22964f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 22974f3549d7SRafael J. Wysocki if (!ret) { 22984f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 22994f3549d7SRafael J. Wysocki dev->offline = true; 23004f3549d7SRafael J. Wysocki } 23014f3549d7SRafael J. Wysocki } 23024f3549d7SRafael J. Wysocki } 23034f3549d7SRafael J. Wysocki device_unlock(dev); 23044f3549d7SRafael J. Wysocki 23054f3549d7SRafael J. Wysocki return ret; 23064f3549d7SRafael J. Wysocki } 23074f3549d7SRafael J. Wysocki 23084f3549d7SRafael J. Wysocki /** 23094f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 23104f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 23114f3549d7SRafael J. Wysocki * 23124f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 23134f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 23144f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 23154f3549d7SRafael J. Wysocki * 23164f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 23174f3549d7SRafael J. Wysocki */ 23184f3549d7SRafael J. Wysocki int device_online(struct device *dev) 23194f3549d7SRafael J. Wysocki { 23204f3549d7SRafael J. Wysocki int ret = 0; 23214f3549d7SRafael J. Wysocki 23224f3549d7SRafael J. Wysocki device_lock(dev); 23234f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 23244f3549d7SRafael J. Wysocki if (dev->offline) { 23254f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 23264f3549d7SRafael J. Wysocki if (!ret) { 23274f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 23284f3549d7SRafael J. Wysocki dev->offline = false; 23294f3549d7SRafael J. Wysocki } 23304f3549d7SRafael J. Wysocki } else { 23314f3549d7SRafael J. Wysocki ret = 1; 23324f3549d7SRafael J. Wysocki } 23334f3549d7SRafael J. Wysocki } 23344f3549d7SRafael J. Wysocki device_unlock(dev); 23354f3549d7SRafael J. Wysocki 23364f3549d7SRafael J. Wysocki return ret; 23374f3549d7SRafael J. Wysocki } 23384f3549d7SRafael J. Wysocki 23397f100d15SKarthigan Srinivasan struct root_device { 23400aa0dc41SMark McLoughlin struct device dev; 23410aa0dc41SMark McLoughlin struct module *owner; 23420aa0dc41SMark McLoughlin }; 23430aa0dc41SMark McLoughlin 234493058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 2345481e2079SFerenc Wagner { 2346481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 2347481e2079SFerenc Wagner } 23480aa0dc41SMark McLoughlin 23490aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 23500aa0dc41SMark McLoughlin { 23510aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 23520aa0dc41SMark McLoughlin } 23530aa0dc41SMark McLoughlin 23540aa0dc41SMark McLoughlin /** 23550aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 23560aa0dc41SMark McLoughlin * @name: root device name 23570aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 23580aa0dc41SMark McLoughlin * 23590aa0dc41SMark McLoughlin * This function allocates a root device and registers it 23600aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 23610aa0dc41SMark McLoughlin * device, use root_device_unregister(). 23620aa0dc41SMark McLoughlin * 23630aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 23640aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 23650aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 23660aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 23670aa0dc41SMark McLoughlin * 23680aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 23690aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 23700aa0dc41SMark McLoughlin * in sysfs. 23710aa0dc41SMark McLoughlin * 2372f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2373f0eae0edSJani Nikula * 23740aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 23750aa0dc41SMark McLoughlin */ 23760aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 23770aa0dc41SMark McLoughlin { 23780aa0dc41SMark McLoughlin struct root_device *root; 23790aa0dc41SMark McLoughlin int err = -ENOMEM; 23800aa0dc41SMark McLoughlin 23810aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 23820aa0dc41SMark McLoughlin if (!root) 23830aa0dc41SMark McLoughlin return ERR_PTR(err); 23840aa0dc41SMark McLoughlin 2385acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 23860aa0dc41SMark McLoughlin if (err) { 23870aa0dc41SMark McLoughlin kfree(root); 23880aa0dc41SMark McLoughlin return ERR_PTR(err); 23890aa0dc41SMark McLoughlin } 23900aa0dc41SMark McLoughlin 23910aa0dc41SMark McLoughlin root->dev.release = root_device_release; 23920aa0dc41SMark McLoughlin 23930aa0dc41SMark McLoughlin err = device_register(&root->dev); 23940aa0dc41SMark McLoughlin if (err) { 23950aa0dc41SMark McLoughlin put_device(&root->dev); 23960aa0dc41SMark McLoughlin return ERR_PTR(err); 23970aa0dc41SMark McLoughlin } 23980aa0dc41SMark McLoughlin 23991d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 24000aa0dc41SMark McLoughlin if (owner) { 24010aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 24020aa0dc41SMark McLoughlin 24030aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 24040aa0dc41SMark McLoughlin if (err) { 24050aa0dc41SMark McLoughlin device_unregister(&root->dev); 24060aa0dc41SMark McLoughlin return ERR_PTR(err); 24070aa0dc41SMark McLoughlin } 24080aa0dc41SMark McLoughlin root->owner = owner; 24090aa0dc41SMark McLoughlin } 24100aa0dc41SMark McLoughlin #endif 24110aa0dc41SMark McLoughlin 24120aa0dc41SMark McLoughlin return &root->dev; 24130aa0dc41SMark McLoughlin } 24140aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 24150aa0dc41SMark McLoughlin 24160aa0dc41SMark McLoughlin /** 24170aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 24187cbcf225SRandy Dunlap * @dev: device going away 24190aa0dc41SMark McLoughlin * 24200aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 24210aa0dc41SMark McLoughlin * root_device_register(). 24220aa0dc41SMark McLoughlin */ 24230aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 24240aa0dc41SMark McLoughlin { 24250aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 24260aa0dc41SMark McLoughlin 24270aa0dc41SMark McLoughlin if (root->owner) 24280aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 24290aa0dc41SMark McLoughlin 24300aa0dc41SMark McLoughlin device_unregister(dev); 24310aa0dc41SMark McLoughlin } 24320aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 24330aa0dc41SMark McLoughlin 243423681e47SGreg Kroah-Hartman 243523681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 243623681e47SGreg Kroah-Hartman { 24371e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 243823681e47SGreg Kroah-Hartman kfree(dev); 243923681e47SGreg Kroah-Hartman } 244023681e47SGreg Kroah-Hartman 24416a8b55d7SMathieu Malaterre static __printf(6, 0) struct device * 244239ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 244339ef3112SGuenter Roeck dev_t devt, void *drvdata, 244439ef3112SGuenter Roeck const struct attribute_group **groups, 244539ef3112SGuenter Roeck const char *fmt, va_list args) 244639ef3112SGuenter Roeck { 244739ef3112SGuenter Roeck struct device *dev = NULL; 244839ef3112SGuenter Roeck int retval = -ENODEV; 244939ef3112SGuenter Roeck 245039ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 245139ef3112SGuenter Roeck goto error; 245239ef3112SGuenter Roeck 245339ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 245439ef3112SGuenter Roeck if (!dev) { 245539ef3112SGuenter Roeck retval = -ENOMEM; 245639ef3112SGuenter Roeck goto error; 245739ef3112SGuenter Roeck } 245839ef3112SGuenter Roeck 2459bbc780f8SDavid Herrmann device_initialize(dev); 246039ef3112SGuenter Roeck dev->devt = devt; 246139ef3112SGuenter Roeck dev->class = class; 246239ef3112SGuenter Roeck dev->parent = parent; 246339ef3112SGuenter Roeck dev->groups = groups; 246439ef3112SGuenter Roeck dev->release = device_create_release; 246539ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 246639ef3112SGuenter Roeck 246739ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 246839ef3112SGuenter Roeck if (retval) 246939ef3112SGuenter Roeck goto error; 247039ef3112SGuenter Roeck 2471bbc780f8SDavid Herrmann retval = device_add(dev); 247239ef3112SGuenter Roeck if (retval) 247339ef3112SGuenter Roeck goto error; 247439ef3112SGuenter Roeck 247539ef3112SGuenter Roeck return dev; 247639ef3112SGuenter Roeck 247739ef3112SGuenter Roeck error: 247839ef3112SGuenter Roeck put_device(dev); 247939ef3112SGuenter Roeck return ERR_PTR(retval); 248039ef3112SGuenter Roeck } 248139ef3112SGuenter Roeck 248223681e47SGreg Kroah-Hartman /** 24838882b394SGreg Kroah-Hartman * device_create_vargs - creates a device and registers it with sysfs 24848882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 24858882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 24868882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 24878882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 24888882b394SGreg Kroah-Hartman * @fmt: string for the device's name 24898882b394SGreg Kroah-Hartman * @args: va_list for the device's name 24908882b394SGreg Kroah-Hartman * 24918882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 24928882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 24938882b394SGreg Kroah-Hartman * 24948882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 24958882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 24968882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 24978882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 24988882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 24998882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 25008882b394SGreg Kroah-Hartman * pointer. 25018882b394SGreg Kroah-Hartman * 2502f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2503f0eae0edSJani Nikula * 25048882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 25058882b394SGreg Kroah-Hartman * been created with a call to class_create(). 25068882b394SGreg Kroah-Hartman */ 25078882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent, 25088882b394SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, 25098882b394SGreg Kroah-Hartman va_list args) 25108882b394SGreg Kroah-Hartman { 251139ef3112SGuenter Roeck return device_create_groups_vargs(class, parent, devt, drvdata, NULL, 251239ef3112SGuenter Roeck fmt, args); 25138882b394SGreg Kroah-Hartman } 25148882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs); 25158882b394SGreg Kroah-Hartman 25168882b394SGreg Kroah-Hartman /** 25174e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 25188882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 25198882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 25208882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 25218882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 25228882b394SGreg Kroah-Hartman * @fmt: string for the device's name 25238882b394SGreg Kroah-Hartman * 25248882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 25258882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 25268882b394SGreg Kroah-Hartman * 25278882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 25288882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 25298882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 25308882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 25318882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 25328882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 25338882b394SGreg Kroah-Hartman * pointer. 25348882b394SGreg Kroah-Hartman * 2535f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 2536f0eae0edSJani Nikula * 25378882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 25388882b394SGreg Kroah-Hartman * been created with a call to class_create(). 25398882b394SGreg Kroah-Hartman */ 25404e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 25414e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 25428882b394SGreg Kroah-Hartman { 25438882b394SGreg Kroah-Hartman va_list vargs; 25448882b394SGreg Kroah-Hartman struct device *dev; 25458882b394SGreg Kroah-Hartman 25468882b394SGreg Kroah-Hartman va_start(vargs, fmt); 25478882b394SGreg Kroah-Hartman dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); 25488882b394SGreg Kroah-Hartman va_end(vargs); 25498882b394SGreg Kroah-Hartman return dev; 25508882b394SGreg Kroah-Hartman } 25514e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 25528882b394SGreg Kroah-Hartman 255339ef3112SGuenter Roeck /** 255439ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 255539ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 255639ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 255739ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 255839ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 255939ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 256039ef3112SGuenter Roeck * @fmt: string for the device's name 256139ef3112SGuenter Roeck * 256239ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 256339ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 256439ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 256539ef3112SGuenter Roeck * be created automatically. 256639ef3112SGuenter Roeck * 256739ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 256839ef3112SGuenter Roeck * the dev_t is not 0,0. 256939ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 257039ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 257139ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 257239ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 257339ef3112SGuenter Roeck * pointer. 257439ef3112SGuenter Roeck * 257539ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 257639ef3112SGuenter Roeck * 257739ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 257839ef3112SGuenter Roeck * been created with a call to class_create(). 257939ef3112SGuenter Roeck */ 258039ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 258139ef3112SGuenter Roeck struct device *parent, dev_t devt, 258239ef3112SGuenter Roeck void *drvdata, 258339ef3112SGuenter Roeck const struct attribute_group **groups, 258439ef3112SGuenter Roeck const char *fmt, ...) 258539ef3112SGuenter Roeck { 258639ef3112SGuenter Roeck va_list vargs; 258739ef3112SGuenter Roeck struct device *dev; 258839ef3112SGuenter Roeck 258939ef3112SGuenter Roeck va_start(vargs, fmt); 259039ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 259139ef3112SGuenter Roeck fmt, vargs); 259239ef3112SGuenter Roeck va_end(vargs); 259339ef3112SGuenter Roeck return dev; 259439ef3112SGuenter Roeck } 259539ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 259639ef3112SGuenter Roeck 25979f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data) 259823681e47SGreg Kroah-Hartman { 25999f3b795aSMichał Mirosław const dev_t *devt = data; 260023681e47SGreg Kroah-Hartman 2601cd35449bSDave Young return dev->devt == *devt; 2602775b64d2SRafael J. Wysocki } 260323681e47SGreg Kroah-Hartman 2604775b64d2SRafael J. Wysocki /** 2605775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 2606775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 2607775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 2608775b64d2SRafael J. Wysocki * 2609775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 2610775b64d2SRafael J. Wysocki * call to device_create(). 2611775b64d2SRafael J. Wysocki */ 2612775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 2613775b64d2SRafael J. Wysocki { 2614775b64d2SRafael J. Wysocki struct device *dev; 2615775b64d2SRafael J. Wysocki 2616695794aeSGreg Kroah-Hartman dev = class_find_device(class, NULL, &devt, __match_devt); 2617cd35449bSDave Young if (dev) { 2618cd35449bSDave Young put_device(dev); 261923681e47SGreg Kroah-Hartman device_unregister(dev); 262023681e47SGreg Kroah-Hartman } 2621cd35449bSDave Young } 262223681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 2623a2de48caSGreg Kroah-Hartman 2624a2de48caSGreg Kroah-Hartman /** 2625a2de48caSGreg Kroah-Hartman * device_rename - renames a device 2626a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 2627a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 2628030c1d2bSEric W. Biederman * 2629030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 2630030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 2631030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 2632030c1d2bSEric W. Biederman * won't conflict with other devices. 2633c6c0ac66SMichael Ellerman * 2634a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 2635a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 2636a5462516STimur Tabi * some insight: 2637a5462516STimur Tabi * 2638a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 2639a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 2640a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 2641a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 2642a5462516STimur Tabi * 2643a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 2644a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 2645a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 2646a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 2647a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 2648a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 2649a5462516STimur Tabi * 2650a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 2651a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 2652a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 2653a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 2654a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 2655a5462516STimur Tabi * reasons. 2656a5462516STimur Tabi * 2657a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 2658a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 2659a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 2660a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 2661a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 2662a2de48caSGreg Kroah-Hartman */ 26636937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 2664a2de48caSGreg Kroah-Hartman { 26654b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 26662ee97cafSCornelia Huck char *old_device_name = NULL; 2667a2de48caSGreg Kroah-Hartman int error; 2668a2de48caSGreg Kroah-Hartman 2669a2de48caSGreg Kroah-Hartman dev = get_device(dev); 2670a2de48caSGreg Kroah-Hartman if (!dev) 2671a2de48caSGreg Kroah-Hartman return -EINVAL; 2672a2de48caSGreg Kroah-Hartman 267369df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 2674a2de48caSGreg Kroah-Hartman 26751fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 26762ee97cafSCornelia Huck if (!old_device_name) { 2677952ab431SJesper Juhl error = -ENOMEM; 26782ee97cafSCornelia Huck goto out; 2679952ab431SJesper Juhl } 2680a2de48caSGreg Kroah-Hartman 2681f349cf34SEric W. Biederman if (dev->class) { 26824b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 26834b30ee58STejun Heo kobj, old_device_name, 26844b30ee58STejun Heo new_name, kobject_namespace(kobj)); 2685f349cf34SEric W. Biederman if (error) 2686f349cf34SEric W. Biederman goto out; 2687f349cf34SEric W. Biederman } 268839aba963SKay Sievers 26894b30ee58STejun Heo error = kobject_rename(kobj, new_name); 26901fa5ae85SKay Sievers if (error) 26912ee97cafSCornelia Huck goto out; 2692a2de48caSGreg Kroah-Hartman 26932ee97cafSCornelia Huck out: 2694a2de48caSGreg Kroah-Hartman put_device(dev); 2695a2de48caSGreg Kroah-Hartman 26962ee97cafSCornelia Huck kfree(old_device_name); 2697a2de48caSGreg Kroah-Hartman 2698a2de48caSGreg Kroah-Hartman return error; 2699a2de48caSGreg Kroah-Hartman } 2700a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 27018a82472fSCornelia Huck 27028a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 27038a82472fSCornelia Huck struct device *old_parent, 27048a82472fSCornelia Huck struct device *new_parent) 27058a82472fSCornelia Huck { 2706f7f3461dSGreg Kroah-Hartman int error = 0; 27078a82472fSCornelia Huck 2708f7f3461dSGreg Kroah-Hartman if (old_parent) 2709f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 2710f7f3461dSGreg Kroah-Hartman if (new_parent) 2711f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 2712f7f3461dSGreg Kroah-Hartman "device"); 2713f7f3461dSGreg Kroah-Hartman return error; 27148a82472fSCornelia Huck } 27158a82472fSCornelia Huck 27168a82472fSCornelia Huck /** 27178a82472fSCornelia Huck * device_move - moves a device to a new parent 27188a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 271913509860SWolfram Sang * @new_parent: the new parent of the device (can be NULL) 2720ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 27218a82472fSCornelia Huck */ 2722ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 2723ffa6a705SCornelia Huck enum dpm_order dpm_order) 27248a82472fSCornelia Huck { 27258a82472fSCornelia Huck int error; 27268a82472fSCornelia Huck struct device *old_parent; 2727c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 27288a82472fSCornelia Huck 27298a82472fSCornelia Huck dev = get_device(dev); 27308a82472fSCornelia Huck if (!dev) 27318a82472fSCornelia Huck return -EINVAL; 27328a82472fSCornelia Huck 2733ffa6a705SCornelia Huck device_pm_lock(); 27348a82472fSCornelia Huck new_parent = get_device(new_parent); 2735c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 273684d0c27dSTetsuo Handa if (IS_ERR(new_parent_kobj)) { 273784d0c27dSTetsuo Handa error = PTR_ERR(new_parent_kobj); 273884d0c27dSTetsuo Handa put_device(new_parent); 273984d0c27dSTetsuo Handa goto out; 274084d0c27dSTetsuo Handa } 274163b6971aSCornelia Huck 27421e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 27431e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 2744c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 27458a82472fSCornelia Huck if (error) { 274663b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 27478a82472fSCornelia Huck put_device(new_parent); 27488a82472fSCornelia Huck goto out; 27498a82472fSCornelia Huck } 27508a82472fSCornelia Huck old_parent = dev->parent; 27518a82472fSCornelia Huck dev->parent = new_parent; 27528a82472fSCornelia Huck if (old_parent) 2753f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 27540d358f22SYinghai Lu if (new_parent) { 2755f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2756f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 27570d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 27580d358f22SYinghai Lu } 27590d358f22SYinghai Lu 2760bdd4034dSRabin Vincent if (dev->class) { 27618a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 27628a82472fSCornelia Huck if (error) { 27638a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 27648a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 27658a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 2766c744aeaeSCornelia Huck if (new_parent) 2767f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 27680d358f22SYinghai Lu dev->parent = old_parent; 27690d358f22SYinghai Lu if (old_parent) { 2770f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 2771f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 27720d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 27730d358f22SYinghai Lu } 27748a82472fSCornelia Huck } 277563b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 27768a82472fSCornelia Huck put_device(new_parent); 27778a82472fSCornelia Huck goto out; 27788a82472fSCornelia Huck } 2779bdd4034dSRabin Vincent } 2780ffa6a705SCornelia Huck switch (dpm_order) { 2781ffa6a705SCornelia Huck case DPM_ORDER_NONE: 2782ffa6a705SCornelia Huck break; 2783ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 2784ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 278552cdbdd4SGrygorii Strashko devices_kset_move_after(dev, new_parent); 2786ffa6a705SCornelia Huck break; 2787ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 2788ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 278952cdbdd4SGrygorii Strashko devices_kset_move_before(new_parent, dev); 2790ffa6a705SCornelia Huck break; 2791ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 2792ffa6a705SCornelia Huck device_pm_move_last(dev); 279352cdbdd4SGrygorii Strashko devices_kset_move_last(dev); 2794ffa6a705SCornelia Huck break; 2795ffa6a705SCornelia Huck } 2796bdd4034dSRabin Vincent 27978a82472fSCornelia Huck put_device(old_parent); 27988a82472fSCornelia Huck out: 2799ffa6a705SCornelia Huck device_pm_unlock(); 28008a82472fSCornelia Huck put_device(dev); 28018a82472fSCornelia Huck return error; 28028a82472fSCornelia Huck } 28038a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 280437b0c020SGreg Kroah-Hartman 280537b0c020SGreg Kroah-Hartman /** 280637b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 280737b0c020SGreg Kroah-Hartman */ 280837b0c020SGreg Kroah-Hartman void device_shutdown(void) 280937b0c020SGreg Kroah-Hartman { 2810f123db8eSBenson Leung struct device *dev, *parent; 281137b0c020SGreg Kroah-Hartman 28126245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 28136245838fSHugh Daschbach /* 28146245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 28156245838fSHugh Daschbach * Beware that device unplug events may also start pulling 28166245838fSHugh Daschbach * devices offline, even as the system is shutting down. 28176245838fSHugh Daschbach */ 28186245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 28196245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 28206245838fSHugh Daschbach kobj.entry); 2821d1c6c030SMing Lei 2822d1c6c030SMing Lei /* 2823d1c6c030SMing Lei * hold reference count of device's parent to 2824d1c6c030SMing Lei * prevent it from being freed because parent's 2825d1c6c030SMing Lei * lock is to be held 2826d1c6c030SMing Lei */ 2827f123db8eSBenson Leung parent = get_device(dev->parent); 28286245838fSHugh Daschbach get_device(dev); 28296245838fSHugh Daschbach /* 28306245838fSHugh Daschbach * Make sure the device is off the kset list, in the 28316245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 28326245838fSHugh Daschbach */ 28336245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 28346245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 2835fe6b91f4SAlan Stern 2836d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 2837f123db8eSBenson Leung if (parent) 2838f123db8eSBenson Leung device_lock(parent); 2839d1c6c030SMing Lei device_lock(dev); 2840d1c6c030SMing Lei 2841fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 2842fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 2843fe6b91f4SAlan Stern pm_runtime_barrier(dev); 28446245838fSHugh Daschbach 28457521621eSMichal Suchanek if (dev->class && dev->class->shutdown_pre) { 2846f77af151SJosh Zimmerman if (initcall_debug) 28477521621eSMichal Suchanek dev_info(dev, "shutdown_pre\n"); 28487521621eSMichal Suchanek dev->class->shutdown_pre(dev); 28497521621eSMichal Suchanek } 28507521621eSMichal Suchanek if (dev->bus && dev->bus->shutdown) { 28510246c4faSShuoX Liu if (initcall_debug) 28520246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 285337b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 285437b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 28550246c4faSShuoX Liu if (initcall_debug) 28560246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 285737b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 285837b0c020SGreg Kroah-Hartman } 2859d1c6c030SMing Lei 2860d1c6c030SMing Lei device_unlock(dev); 2861f123db8eSBenson Leung if (parent) 2862f123db8eSBenson Leung device_unlock(parent); 2863d1c6c030SMing Lei 28646245838fSHugh Daschbach put_device(dev); 2865f123db8eSBenson Leung put_device(parent); 28666245838fSHugh Daschbach 28676245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 286837b0c020SGreg Kroah-Hartman } 28696245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 287037b0c020SGreg Kroah-Hartman } 287199bcf217SJoe Perches 287299bcf217SJoe Perches /* 287399bcf217SJoe Perches * Device logging functions 287499bcf217SJoe Perches */ 287599bcf217SJoe Perches 287699bcf217SJoe Perches #ifdef CONFIG_PRINTK 2877666f355fSJoe Perches static int 2878666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 287999bcf217SJoe Perches { 2880c4e00daaSKay Sievers const char *subsys; 2881798efc60SJoe Perches size_t pos = 0; 288299bcf217SJoe Perches 2883c4e00daaSKay Sievers if (dev->class) 2884c4e00daaSKay Sievers subsys = dev->class->name; 2885c4e00daaSKay Sievers else if (dev->bus) 2886c4e00daaSKay Sievers subsys = dev->bus->name; 2887c4e00daaSKay Sievers else 2888798efc60SJoe Perches return 0; 2889c4e00daaSKay Sievers 2890798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 2891655e5b7cSBen Hutchings if (pos >= hdrlen) 2892655e5b7cSBen Hutchings goto overflow; 2893c4e00daaSKay Sievers 2894c4e00daaSKay Sievers /* 2895c4e00daaSKay Sievers * Add device identifier DEVICE=: 2896c4e00daaSKay Sievers * b12:8 block dev_t 2897c4e00daaSKay Sievers * c127:3 char dev_t 2898c4e00daaSKay Sievers * n8 netdev ifindex 2899c4e00daaSKay Sievers * +sound:card0 subsystem:devname 2900c4e00daaSKay Sievers */ 2901c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 2902c4e00daaSKay Sievers char c; 2903c4e00daaSKay Sievers 2904c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 2905c4e00daaSKay Sievers c = 'b'; 2906c4e00daaSKay Sievers else 2907c4e00daaSKay Sievers c = 'c'; 2908798efc60SJoe Perches pos++; 2909798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2910c4e00daaSKay Sievers "DEVICE=%c%u:%u", 2911c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 2912c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 2913c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 2914c4e00daaSKay Sievers 2915798efc60SJoe Perches pos++; 2916798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2917c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 2918c4e00daaSKay Sievers } else { 2919798efc60SJoe Perches pos++; 2920798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2921c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 2922c4e00daaSKay Sievers } 2923af7f2158SJim Cromie 2924655e5b7cSBen Hutchings if (pos >= hdrlen) 2925655e5b7cSBen Hutchings goto overflow; 2926655e5b7cSBen Hutchings 2927798efc60SJoe Perches return pos; 2928655e5b7cSBen Hutchings 2929655e5b7cSBen Hutchings overflow: 2930655e5b7cSBen Hutchings dev_WARN(dev, "device/subsystem name too long"); 2931655e5b7cSBen Hutchings return 0; 293299bcf217SJoe Perches } 2933798efc60SJoe Perches 293405e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 293505e4e5b8SJoe Perches const char *fmt, va_list args) 293605e4e5b8SJoe Perches { 293705e4e5b8SJoe Perches char hdr[128]; 293805e4e5b8SJoe Perches size_t hdrlen; 293905e4e5b8SJoe Perches 294005e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 294105e4e5b8SJoe Perches 294205e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 294305e4e5b8SJoe Perches } 294405e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 294505e4e5b8SJoe Perches 294605e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 294705e4e5b8SJoe Perches { 294805e4e5b8SJoe Perches va_list args; 294905e4e5b8SJoe Perches int r; 295005e4e5b8SJoe Perches 295105e4e5b8SJoe Perches va_start(args, fmt); 295205e4e5b8SJoe Perches 295305e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 295405e4e5b8SJoe Perches 295505e4e5b8SJoe Perches va_end(args); 295605e4e5b8SJoe Perches 295705e4e5b8SJoe Perches return r; 295805e4e5b8SJoe Perches } 295905e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 296005e4e5b8SJoe Perches 2961d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev, 2962798efc60SJoe Perches struct va_format *vaf) 2963798efc60SJoe Perches { 2964d1f1052cSJoe Perches if (dev) 2965d1f1052cSJoe Perches dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", 2966798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 2967d1f1052cSJoe Perches else 2968d1f1052cSJoe Perches printk("%s(NULL device *): %pV", level, vaf); 2969798efc60SJoe Perches } 297099bcf217SJoe Perches 2971d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev, 297299bcf217SJoe Perches const char *fmt, ...) 297399bcf217SJoe Perches { 297499bcf217SJoe Perches struct va_format vaf; 297599bcf217SJoe Perches va_list args; 297699bcf217SJoe Perches 297799bcf217SJoe Perches va_start(args, fmt); 297899bcf217SJoe Perches 297999bcf217SJoe Perches vaf.fmt = fmt; 298099bcf217SJoe Perches vaf.va = &args; 298199bcf217SJoe Perches 2982d1f1052cSJoe Perches __dev_printk(level, dev, &vaf); 2983798efc60SJoe Perches 298499bcf217SJoe Perches va_end(args); 298599bcf217SJoe Perches } 298699bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 298799bcf217SJoe Perches 298899bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 2989d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...) \ 299099bcf217SJoe Perches { \ 299199bcf217SJoe Perches struct va_format vaf; \ 299299bcf217SJoe Perches va_list args; \ 299399bcf217SJoe Perches \ 299499bcf217SJoe Perches va_start(args, fmt); \ 299599bcf217SJoe Perches \ 299699bcf217SJoe Perches vaf.fmt = fmt; \ 299799bcf217SJoe Perches vaf.va = &args; \ 299899bcf217SJoe Perches \ 2999d1f1052cSJoe Perches __dev_printk(kern_level, dev, &vaf); \ 3000798efc60SJoe Perches \ 300199bcf217SJoe Perches va_end(args); \ 300299bcf217SJoe Perches } \ 300399bcf217SJoe Perches EXPORT_SYMBOL(func); 300499bcf217SJoe Perches 300599bcf217SJoe Perches define_dev_printk_level(dev_emerg, KERN_EMERG); 300699bcf217SJoe Perches define_dev_printk_level(dev_alert, KERN_ALERT); 300799bcf217SJoe Perches define_dev_printk_level(dev_crit, KERN_CRIT); 300899bcf217SJoe Perches define_dev_printk_level(dev_err, KERN_ERR); 300999bcf217SJoe Perches define_dev_printk_level(dev_warn, KERN_WARNING); 301099bcf217SJoe Perches define_dev_printk_level(dev_notice, KERN_NOTICE); 301199bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 301299bcf217SJoe Perches 301399bcf217SJoe Perches #endif 301497badf87SRafael J. Wysocki 301597badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 301697badf87SRafael J. Wysocki { 301797badf87SRafael J. Wysocki return fwnode && !IS_ERR(fwnode->secondary); 301897badf87SRafael J. Wysocki } 301997badf87SRafael J. Wysocki 302097badf87SRafael J. Wysocki /** 302197badf87SRafael J. Wysocki * set_primary_fwnode - Change the primary firmware node of a given device. 302297badf87SRafael J. Wysocki * @dev: Device to handle. 302397badf87SRafael J. Wysocki * @fwnode: New primary firmware node of the device. 302497badf87SRafael J. Wysocki * 302597badf87SRafael J. Wysocki * Set the device's firmware node pointer to @fwnode, but if a secondary 302697badf87SRafael J. Wysocki * firmware node of the device is present, preserve it. 302797badf87SRafael J. Wysocki */ 302897badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 302997badf87SRafael J. Wysocki { 303097badf87SRafael J. Wysocki if (fwnode) { 303197badf87SRafael J. Wysocki struct fwnode_handle *fn = dev->fwnode; 303297badf87SRafael J. Wysocki 303397badf87SRafael J. Wysocki if (fwnode_is_primary(fn)) 303497badf87SRafael J. Wysocki fn = fn->secondary; 303597badf87SRafael J. Wysocki 303655f89a8aSMika Westerberg if (fn) { 303755f89a8aSMika Westerberg WARN_ON(fwnode->secondary); 303897badf87SRafael J. Wysocki fwnode->secondary = fn; 303955f89a8aSMika Westerberg } 304097badf87SRafael J. Wysocki dev->fwnode = fwnode; 304197badf87SRafael J. Wysocki } else { 304297badf87SRafael J. Wysocki dev->fwnode = fwnode_is_primary(dev->fwnode) ? 304397badf87SRafael J. Wysocki dev->fwnode->secondary : NULL; 304497badf87SRafael J. Wysocki } 304597badf87SRafael J. Wysocki } 304697badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode); 304797badf87SRafael J. Wysocki 304897badf87SRafael J. Wysocki /** 304997badf87SRafael J. Wysocki * set_secondary_fwnode - Change the secondary firmware node of a given device. 305097badf87SRafael J. Wysocki * @dev: Device to handle. 305197badf87SRafael J. Wysocki * @fwnode: New secondary firmware node of the device. 305297badf87SRafael J. Wysocki * 305397badf87SRafael J. Wysocki * If a primary firmware node of the device is present, set its secondary 305497badf87SRafael J. Wysocki * pointer to @fwnode. Otherwise, set the device's firmware node pointer to 305597badf87SRafael J. Wysocki * @fwnode. 305697badf87SRafael J. Wysocki */ 305797badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 305897badf87SRafael J. Wysocki { 305997badf87SRafael J. Wysocki if (fwnode) 306097badf87SRafael J. Wysocki fwnode->secondary = ERR_PTR(-ENODEV); 306197badf87SRafael J. Wysocki 306297badf87SRafael J. Wysocki if (fwnode_is_primary(dev->fwnode)) 306397badf87SRafael J. Wysocki dev->fwnode->secondary = fwnode; 306497badf87SRafael J. Wysocki else 306597badf87SRafael J. Wysocki dev->fwnode = fwnode; 306697badf87SRafael J. Wysocki } 30674e75e1d7SJohan Hovold 30684e75e1d7SJohan Hovold /** 30694e75e1d7SJohan Hovold * device_set_of_node_from_dev - reuse device-tree node of another device 30704e75e1d7SJohan Hovold * @dev: device whose device-tree node is being set 30714e75e1d7SJohan Hovold * @dev2: device whose device-tree node is being reused 30724e75e1d7SJohan Hovold * 30734e75e1d7SJohan Hovold * Takes another reference to the new device-tree node after first dropping 30744e75e1d7SJohan Hovold * any reference held to the old node. 30754e75e1d7SJohan Hovold */ 30764e75e1d7SJohan Hovold void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) 30774e75e1d7SJohan Hovold { 30784e75e1d7SJohan Hovold of_node_put(dev->of_node); 30794e75e1d7SJohan Hovold dev->of_node = of_node_get(dev2->of_node); 30804e75e1d7SJohan Hovold dev->of_node_reused = true; 30814e75e1d7SJohan Hovold } 30824e75e1d7SJohan Hovold EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); 3083