xref: /openbmc/linux/drivers/base/core.c (revision 15cfb094)
1989d42e8SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * drivers/base/core.c - core driver model code (device registration, etc)
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Copyright (c) 2002-3 Patrick Mochel
61da177e4SLinus Torvalds  * Copyright (c) 2002-3 Open Source Development Labs
764bb5d2cSGreg Kroah-Hartman  * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
864bb5d2cSGreg Kroah-Hartman  * Copyright (c) 2006 Novell, Inc.
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
117847a145SHeikki Krogerus #include <linux/acpi.h>
121da177e4SLinus Torvalds #include <linux/device.h>
131da177e4SLinus Torvalds #include <linux/err.h>
1497badf87SRafael J. Wysocki #include <linux/fwnode.h>
151da177e4SLinus Torvalds #include <linux/init.h>
161da177e4SLinus Torvalds #include <linux/module.h>
171da177e4SLinus Torvalds #include <linux/slab.h>
181da177e4SLinus Torvalds #include <linux/string.h>
1923681e47SGreg Kroah-Hartman #include <linux/kdev_t.h>
20116af378SBenjamin Herrenschmidt #include <linux/notifier.h>
2107d57a32SGrant Likely #include <linux/of.h>
2207d57a32SGrant Likely #include <linux/of_device.h>
23da231fd5SKay Sievers #include <linux/genhd.h>
24f75b1c60SDave Young #include <linux/mutex.h>
25af8db150SPeter Chen #include <linux/pm_runtime.h>
26c4e00daaSKay Sievers #include <linux/netdevice.h>
27174cd4b1SIngo Molnar #include <linux/sched/signal.h>
2863967685SGreg Kroah-Hartman #include <linux/sysfs.h>
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #include "base.h"
311da177e4SLinus Torvalds #include "power/power.h"
321da177e4SLinus Torvalds 
33e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED
34e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2
35e52eec13SAndi Kleen long sysfs_deprecated = 1;
36e52eec13SAndi Kleen #else
37e52eec13SAndi Kleen long sysfs_deprecated = 0;
38e52eec13SAndi Kleen #endif
393454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg)
40e52eec13SAndi Kleen {
4134da5e67SJingoo Han 	return kstrtol(arg, 10, &sysfs_deprecated);
42e52eec13SAndi Kleen }
43e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup);
44e52eec13SAndi Kleen #endif
45e52eec13SAndi Kleen 
469ed98953SRafael J. Wysocki /* Device links support. */
479ed98953SRafael J. Wysocki 
489ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU
499ed98953SRafael J. Wysocki static DEFINE_MUTEX(device_links_lock);
509ed98953SRafael J. Wysocki DEFINE_STATIC_SRCU(device_links_srcu);
519ed98953SRafael J. Wysocki 
529ed98953SRafael J. Wysocki static inline void device_links_write_lock(void)
539ed98953SRafael J. Wysocki {
549ed98953SRafael J. Wysocki 	mutex_lock(&device_links_lock);
559ed98953SRafael J. Wysocki }
569ed98953SRafael J. Wysocki 
579ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void)
589ed98953SRafael J. Wysocki {
599ed98953SRafael J. Wysocki 	mutex_unlock(&device_links_lock);
609ed98953SRafael J. Wysocki }
619ed98953SRafael J. Wysocki 
629ed98953SRafael J. Wysocki int device_links_read_lock(void)
639ed98953SRafael J. Wysocki {
649ed98953SRafael J. Wysocki 	return srcu_read_lock(&device_links_srcu);
659ed98953SRafael J. Wysocki }
669ed98953SRafael J. Wysocki 
679ed98953SRafael J. Wysocki void device_links_read_unlock(int idx)
689ed98953SRafael J. Wysocki {
699ed98953SRafael J. Wysocki 	srcu_read_unlock(&device_links_srcu, idx);
709ed98953SRafael J. Wysocki }
719ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */
729ed98953SRafael J. Wysocki static DECLARE_RWSEM(device_links_lock);
739ed98953SRafael J. Wysocki 
749ed98953SRafael J. Wysocki static inline void device_links_write_lock(void)
759ed98953SRafael J. Wysocki {
769ed98953SRafael J. Wysocki 	down_write(&device_links_lock);
779ed98953SRafael J. Wysocki }
789ed98953SRafael J. Wysocki 
799ed98953SRafael J. Wysocki static inline void device_links_write_unlock(void)
809ed98953SRafael J. Wysocki {
819ed98953SRafael J. Wysocki 	up_write(&device_links_lock);
829ed98953SRafael J. Wysocki }
839ed98953SRafael J. Wysocki 
849ed98953SRafael J. Wysocki int device_links_read_lock(void)
859ed98953SRafael J. Wysocki {
869ed98953SRafael J. Wysocki 	down_read(&device_links_lock);
879ed98953SRafael J. Wysocki 	return 0;
889ed98953SRafael J. Wysocki }
899ed98953SRafael J. Wysocki 
909ed98953SRafael J. Wysocki void device_links_read_unlock(int not_used)
919ed98953SRafael J. Wysocki {
929ed98953SRafael J. Wysocki 	up_read(&device_links_lock);
939ed98953SRafael J. Wysocki }
949ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */
959ed98953SRafael J. Wysocki 
969ed98953SRafael J. Wysocki /**
979ed98953SRafael J. Wysocki  * device_is_dependent - Check if one device depends on another one
989ed98953SRafael J. Wysocki  * @dev: Device to check dependencies for.
999ed98953SRafael J. Wysocki  * @target: Device to check against.
1009ed98953SRafael J. Wysocki  *
1019ed98953SRafael J. Wysocki  * Check if @target depends on @dev or any device dependent on it (its child or
1029ed98953SRafael J. Wysocki  * its consumer etc).  Return 1 if that is the case or 0 otherwise.
1039ed98953SRafael J. Wysocki  */
1049ed98953SRafael J. Wysocki static int device_is_dependent(struct device *dev, void *target)
1059ed98953SRafael J. Wysocki {
1069ed98953SRafael J. Wysocki 	struct device_link *link;
1079ed98953SRafael J. Wysocki 	int ret;
1089ed98953SRafael J. Wysocki 
109e16f4f3eSBenjamin Gaignard 	if (dev == target)
1109ed98953SRafael J. Wysocki 		return 1;
1119ed98953SRafael J. Wysocki 
1129ed98953SRafael J. Wysocki 	ret = device_for_each_child(dev, target, device_is_dependent);
1139ed98953SRafael J. Wysocki 	if (ret)
1149ed98953SRafael J. Wysocki 		return ret;
1159ed98953SRafael J. Wysocki 
1169ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node) {
117e16f4f3eSBenjamin Gaignard 		if (link->consumer == target)
1189ed98953SRafael J. Wysocki 			return 1;
1199ed98953SRafael J. Wysocki 
1209ed98953SRafael J. Wysocki 		ret = device_is_dependent(link->consumer, target);
1219ed98953SRafael J. Wysocki 		if (ret)
1229ed98953SRafael J. Wysocki 			break;
1239ed98953SRafael J. Wysocki 	}
1249ed98953SRafael J. Wysocki 	return ret;
1259ed98953SRafael J. Wysocki }
1269ed98953SRafael J. Wysocki 
1279ed98953SRafael J. Wysocki static int device_reorder_to_tail(struct device *dev, void *not_used)
1289ed98953SRafael J. Wysocki {
1299ed98953SRafael J. Wysocki 	struct device_link *link;
1309ed98953SRafael J. Wysocki 
1319ed98953SRafael J. Wysocki 	/*
1329ed98953SRafael J. Wysocki 	 * Devices that have not been registered yet will be put to the ends
1339ed98953SRafael J. Wysocki 	 * of the lists during the registration, so skip them here.
1349ed98953SRafael J. Wysocki 	 */
1359ed98953SRafael J. Wysocki 	if (device_is_registered(dev))
1369ed98953SRafael J. Wysocki 		devices_kset_move_last(dev);
1379ed98953SRafael J. Wysocki 
1389ed98953SRafael J. Wysocki 	if (device_pm_initialized(dev))
1399ed98953SRafael J. Wysocki 		device_pm_move_last(dev);
1409ed98953SRafael J. Wysocki 
1419ed98953SRafael J. Wysocki 	device_for_each_child(dev, NULL, device_reorder_to_tail);
1429ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node)
1439ed98953SRafael J. Wysocki 		device_reorder_to_tail(link->consumer, NULL);
1449ed98953SRafael J. Wysocki 
1459ed98953SRafael J. Wysocki 	return 0;
1469ed98953SRafael J. Wysocki }
1479ed98953SRafael J. Wysocki 
1489ed98953SRafael J. Wysocki /**
149494fd7b7SFeng Kan  * device_pm_move_to_tail - Move set of devices to the end of device lists
150494fd7b7SFeng Kan  * @dev: Device to move
151494fd7b7SFeng Kan  *
152494fd7b7SFeng Kan  * This is a device_reorder_to_tail() wrapper taking the requisite locks.
153494fd7b7SFeng Kan  *
154494fd7b7SFeng Kan  * It moves the @dev along with all of its children and all of its consumers
155494fd7b7SFeng Kan  * to the ends of the device_kset and dpm_list, recursively.
156494fd7b7SFeng Kan  */
157494fd7b7SFeng Kan void device_pm_move_to_tail(struct device *dev)
158494fd7b7SFeng Kan {
159494fd7b7SFeng Kan 	int idx;
160494fd7b7SFeng Kan 
161494fd7b7SFeng Kan 	idx = device_links_read_lock();
162494fd7b7SFeng Kan 	device_pm_lock();
163494fd7b7SFeng Kan 	device_reorder_to_tail(dev, NULL);
164494fd7b7SFeng Kan 	device_pm_unlock();
165494fd7b7SFeng Kan 	device_links_read_unlock(idx);
166494fd7b7SFeng Kan }
167494fd7b7SFeng Kan 
168e2f3cd83SRafael J. Wysocki static void device_link_rpm_prepare(struct device *consumer,
169e2f3cd83SRafael J. Wysocki 				    struct device *supplier)
170e2f3cd83SRafael J. Wysocki {
171e2f3cd83SRafael J. Wysocki 	pm_runtime_new_link(consumer);
172e2f3cd83SRafael J. Wysocki 	/*
173e2f3cd83SRafael J. Wysocki 	 * If the link is being added by the consumer driver at probe time,
174e2f3cd83SRafael J. Wysocki 	 * balance the decrementation of the supplier's runtime PM usage counter
175e2f3cd83SRafael J. Wysocki 	 * after consumer probe in driver_probe_device().
176e2f3cd83SRafael J. Wysocki 	 */
177e2f3cd83SRafael J. Wysocki 	if (consumer->links.status == DL_DEV_PROBING)
178e2f3cd83SRafael J. Wysocki 		pm_runtime_get_noresume(supplier);
179e2f3cd83SRafael J. Wysocki }
180e2f3cd83SRafael J. Wysocki 
181494fd7b7SFeng Kan /**
1829ed98953SRafael J. Wysocki  * device_link_add - Create a link between two devices.
1839ed98953SRafael J. Wysocki  * @consumer: Consumer end of the link.
1849ed98953SRafael J. Wysocki  * @supplier: Supplier end of the link.
1859ed98953SRafael J. Wysocki  * @flags: Link flags.
1869ed98953SRafael J. Wysocki  *
18721d5c57bSRafael J. Wysocki  * The caller is responsible for the proper synchronization of the link creation
18821d5c57bSRafael J. Wysocki  * with runtime PM.  First, setting the DL_FLAG_PM_RUNTIME flag will cause the
18921d5c57bSRafael J. Wysocki  * runtime PM framework to take the link into account.  Second, if the
19021d5c57bSRafael J. Wysocki  * DL_FLAG_RPM_ACTIVE flag is set in addition to it, the supplier devices will
19121d5c57bSRafael J. Wysocki  * be forced into the active metastate and reference-counted upon the creation
19221d5c57bSRafael J. Wysocki  * of the link.  If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be
19321d5c57bSRafael J. Wysocki  * ignored.
19421d5c57bSRafael J. Wysocki  *
195c8d50986SRafael J. Wysocki  * If the DL_FLAG_AUTOREMOVE_CONSUMER flag is set, the link will be removed
196c8d50986SRafael J. Wysocki  * automatically when the consumer device driver unbinds from it.  Analogously,
197c8d50986SRafael J. Wysocki  * if DL_FLAG_AUTOREMOVE_SUPPLIER is set in @flags, the link will be removed
198c8d50986SRafael J. Wysocki  * automatically when the supplier device driver unbinds from it.
199c8d50986SRafael J. Wysocki  *
200c8d50986SRafael J. Wysocki  * The combination of DL_FLAG_STATELESS and either DL_FLAG_AUTOREMOVE_CONSUMER
201c8d50986SRafael J. Wysocki  * or DL_FLAG_AUTOREMOVE_SUPPLIER set in @flags at the same time is invalid and
202c8d50986SRafael J. Wysocki  * will cause NULL to be returned upfront.
2039ed98953SRafael J. Wysocki  *
2049ed98953SRafael J. Wysocki  * A side effect of the link creation is re-ordering of dpm_list and the
2059ed98953SRafael J. Wysocki  * devices_kset list by moving the consumer device and all devices depending
2069ed98953SRafael J. Wysocki  * on it to the ends of these lists (that does not happen to devices that have
2079ed98953SRafael J. Wysocki  * not been registered when this function is called).
2089ed98953SRafael J. Wysocki  *
2099ed98953SRafael J. Wysocki  * The supplier device is required to be registered when this function is called
2109ed98953SRafael J. Wysocki  * and NULL will be returned if that is not the case.  The consumer device need
21164df1148SLukas Wunner  * not be registered, however.
2129ed98953SRafael J. Wysocki  */
2139ed98953SRafael J. Wysocki struct device_link *device_link_add(struct device *consumer,
2149ed98953SRafael J. Wysocki 				    struct device *supplier, u32 flags)
2159ed98953SRafael J. Wysocki {
2169ed98953SRafael J. Wysocki 	struct device_link *link;
2179ed98953SRafael J. Wysocki 
2189ed98953SRafael J. Wysocki 	if (!consumer || !supplier ||
219c8d50986SRafael J. Wysocki 	    (flags & DL_FLAG_STATELESS &&
220c8d50986SRafael J. Wysocki 	     flags & (DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_AUTOREMOVE_SUPPLIER)))
2219ed98953SRafael J. Wysocki 		return NULL;
2229ed98953SRafael J. Wysocki 
2235db25c9eSRafael J. Wysocki 	if (flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) {
2245db25c9eSRafael J. Wysocki 		if (pm_runtime_get_sync(supplier) < 0) {
2255db25c9eSRafael J. Wysocki 			pm_runtime_put_noidle(supplier);
2265db25c9eSRafael J. Wysocki 			return NULL;
2275db25c9eSRafael J. Wysocki 		}
2285db25c9eSRafael J. Wysocki 	}
2295db25c9eSRafael J. Wysocki 
2309ed98953SRafael J. Wysocki 	device_links_write_lock();
2319ed98953SRafael J. Wysocki 	device_pm_lock();
2329ed98953SRafael J. Wysocki 
2339ed98953SRafael J. Wysocki 	/*
2349ed98953SRafael J. Wysocki 	 * If the supplier has not been fully registered yet or there is a
2359ed98953SRafael J. Wysocki 	 * reverse dependency between the consumer and the supplier already in
2369ed98953SRafael J. Wysocki 	 * the graph, return NULL.
2379ed98953SRafael J. Wysocki 	 */
2389ed98953SRafael J. Wysocki 	if (!device_pm_initialized(supplier)
2399ed98953SRafael J. Wysocki 	    || device_is_dependent(consumer, supplier)) {
2409ed98953SRafael J. Wysocki 		link = NULL;
2419ed98953SRafael J. Wysocki 		goto out;
2429ed98953SRafael J. Wysocki 	}
2439ed98953SRafael J. Wysocki 
244f265df55SRafael J. Wysocki 	list_for_each_entry(link, &supplier->links.consumers, s_node) {
245f265df55SRafael J. Wysocki 		if (link->consumer != consumer)
246f265df55SRafael J. Wysocki 			continue;
247f265df55SRafael J. Wysocki 
248f265df55SRafael J. Wysocki 		/*
249f265df55SRafael J. Wysocki 		 * Don't return a stateless link if the caller wants a stateful
250f265df55SRafael J. Wysocki 		 * one and vice versa.
251f265df55SRafael J. Wysocki 		 */
252f265df55SRafael J. Wysocki 		if (WARN_ON((flags & DL_FLAG_STATELESS) != (link->flags & DL_FLAG_STATELESS))) {
253f265df55SRafael J. Wysocki 			link = NULL;
254f265df55SRafael J. Wysocki 			goto out;
255f265df55SRafael J. Wysocki 		}
256f265df55SRafael J. Wysocki 
257f265df55SRafael J. Wysocki 		if (flags & DL_FLAG_AUTOREMOVE_CONSUMER)
258f265df55SRafael J. Wysocki 			link->flags |= DL_FLAG_AUTOREMOVE_CONSUMER;
259f265df55SRafael J. Wysocki 
260f265df55SRafael J. Wysocki 		if (flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
261f265df55SRafael J. Wysocki 			link->flags |= DL_FLAG_AUTOREMOVE_SUPPLIER;
262f265df55SRafael J. Wysocki 
263e2f3cd83SRafael J. Wysocki 		if (flags & DL_FLAG_PM_RUNTIME) {
264e2f3cd83SRafael J. Wysocki 			if (!(link->flags & DL_FLAG_PM_RUNTIME)) {
265e2f3cd83SRafael J. Wysocki 				device_link_rpm_prepare(consumer, supplier);
266e2f3cd83SRafael J. Wysocki 				link->flags |= DL_FLAG_PM_RUNTIME;
267e2f3cd83SRafael J. Wysocki 			}
268e2f3cd83SRafael J. Wysocki 			if (flags & DL_FLAG_RPM_ACTIVE)
269e2f3cd83SRafael J. Wysocki 				refcount_inc(&link->rpm_active);
270e2f3cd83SRafael J. Wysocki 		}
271e2f3cd83SRafael J. Wysocki 
272ead18c23SLukas Wunner 		kref_get(&link->kref);
2739ed98953SRafael J. Wysocki 		goto out;
274ead18c23SLukas Wunner 	}
2759ed98953SRafael J. Wysocki 
27621d5c57bSRafael J. Wysocki 	link = kzalloc(sizeof(*link), GFP_KERNEL);
2779ed98953SRafael J. Wysocki 	if (!link)
2789ed98953SRafael J. Wysocki 		goto out;
2799ed98953SRafael J. Wysocki 
280e2f3cd83SRafael J. Wysocki 	refcount_set(&link->rpm_active, 1);
281e2f3cd83SRafael J. Wysocki 
282baa8809fSRafael J. Wysocki 	if (flags & DL_FLAG_PM_RUNTIME) {
283e2f3cd83SRafael J. Wysocki 		if (flags & DL_FLAG_RPM_ACTIVE)
284e2f3cd83SRafael J. Wysocki 			refcount_inc(&link->rpm_active);
285e2f3cd83SRafael J. Wysocki 
286e2f3cd83SRafael J. Wysocki 		device_link_rpm_prepare(consumer, supplier);
28721d5c57bSRafael J. Wysocki 	}
288e2f3cd83SRafael J. Wysocki 
2899ed98953SRafael J. Wysocki 	get_device(supplier);
2909ed98953SRafael J. Wysocki 	link->supplier = supplier;
2919ed98953SRafael J. Wysocki 	INIT_LIST_HEAD(&link->s_node);
2929ed98953SRafael J. Wysocki 	get_device(consumer);
2939ed98953SRafael J. Wysocki 	link->consumer = consumer;
2949ed98953SRafael J. Wysocki 	INIT_LIST_HEAD(&link->c_node);
2959ed98953SRafael J. Wysocki 	link->flags = flags;
296ead18c23SLukas Wunner 	kref_init(&link->kref);
2979ed98953SRafael J. Wysocki 
29864df1148SLukas Wunner 	/* Determine the initial link state. */
2999ed98953SRafael J. Wysocki 	if (flags & DL_FLAG_STATELESS) {
3009ed98953SRafael J. Wysocki 		link->status = DL_STATE_NONE;
3019ed98953SRafael J. Wysocki 	} else {
3029ed98953SRafael J. Wysocki 		switch (supplier->links.status) {
30315cfb094SRafael J. Wysocki 		case DL_DEV_PROBING:
3049ed98953SRafael J. Wysocki 			switch (consumer->links.status) {
3059ed98953SRafael J. Wysocki 			case DL_DEV_PROBING:
30621d5c57bSRafael J. Wysocki 				/*
30715cfb094SRafael J. Wysocki 				 * A consumer driver can create a link to a
30815cfb094SRafael J. Wysocki 				 * supplier that has not completed its probing
30915cfb094SRafael J. Wysocki 				 * yet as long as it knows that the supplier is
31015cfb094SRafael J. Wysocki 				 * already functional (for example, it has just
31115cfb094SRafael J. Wysocki 				 * acquired some resources from the supplier).
31221d5c57bSRafael J. Wysocki 				 */
31315cfb094SRafael J. Wysocki 				link->status = DL_STATE_CONSUMER_PROBE;
31415cfb094SRafael J. Wysocki 				break;
31515cfb094SRafael J. Wysocki 			default:
31615cfb094SRafael J. Wysocki 				link->status = DL_STATE_DORMANT;
31715cfb094SRafael J. Wysocki 				break;
31815cfb094SRafael J. Wysocki 			}
31915cfb094SRafael J. Wysocki 			break;
32015cfb094SRafael J. Wysocki 		case DL_DEV_DRIVER_BOUND:
32115cfb094SRafael J. Wysocki 			switch (consumer->links.status) {
32215cfb094SRafael J. Wysocki 			case DL_DEV_PROBING:
3239ed98953SRafael J. Wysocki 				link->status = DL_STATE_CONSUMER_PROBE;
3249ed98953SRafael J. Wysocki 				break;
3259ed98953SRafael J. Wysocki 			case DL_DEV_DRIVER_BOUND:
3269ed98953SRafael J. Wysocki 				link->status = DL_STATE_ACTIVE;
3279ed98953SRafael J. Wysocki 				break;
3289ed98953SRafael J. Wysocki 			default:
3299ed98953SRafael J. Wysocki 				link->status = DL_STATE_AVAILABLE;
3309ed98953SRafael J. Wysocki 				break;
3319ed98953SRafael J. Wysocki 			}
3329ed98953SRafael J. Wysocki 			break;
3339ed98953SRafael J. Wysocki 		case DL_DEV_UNBINDING:
3349ed98953SRafael J. Wysocki 			link->status = DL_STATE_SUPPLIER_UNBIND;
3359ed98953SRafael J. Wysocki 			break;
3369ed98953SRafael J. Wysocki 		default:
3379ed98953SRafael J. Wysocki 			link->status = DL_STATE_DORMANT;
3389ed98953SRafael J. Wysocki 			break;
3399ed98953SRafael J. Wysocki 		}
3409ed98953SRafael J. Wysocki 	}
3419ed98953SRafael J. Wysocki 
3429ed98953SRafael J. Wysocki 	/*
34315cfb094SRafael J. Wysocki 	 * Some callers expect the link creation during consumer driver probe to
34415cfb094SRafael J. Wysocki 	 * resume the supplier even without DL_FLAG_RPM_ACTIVE.
34515cfb094SRafael J. Wysocki 	 */
34615cfb094SRafael J. Wysocki 	if (link->status == DL_STATE_CONSUMER_PROBE &&
34715cfb094SRafael J. Wysocki 	    flags & DL_FLAG_PM_RUNTIME)
34815cfb094SRafael J. Wysocki 		pm_runtime_resume(supplier);
34915cfb094SRafael J. Wysocki 
35015cfb094SRafael J. Wysocki 	/*
3519ed98953SRafael J. Wysocki 	 * Move the consumer and all of the devices depending on it to the end
3529ed98953SRafael J. Wysocki 	 * of dpm_list and the devices_kset list.
3539ed98953SRafael J. Wysocki 	 *
3549ed98953SRafael J. Wysocki 	 * It is necessary to hold dpm_list locked throughout all that or else
3559ed98953SRafael J. Wysocki 	 * we may end up suspending with a wrong ordering of it.
3569ed98953SRafael J. Wysocki 	 */
3579ed98953SRafael J. Wysocki 	device_reorder_to_tail(consumer, NULL);
3589ed98953SRafael J. Wysocki 
3599ed98953SRafael J. Wysocki 	list_add_tail_rcu(&link->s_node, &supplier->links.consumers);
3609ed98953SRafael J. Wysocki 	list_add_tail_rcu(&link->c_node, &consumer->links.suppliers);
3619ed98953SRafael J. Wysocki 
3628a4b3269SJerome Brunet 	dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier));
3639ed98953SRafael J. Wysocki 
3649ed98953SRafael J. Wysocki  out:
3659ed98953SRafael J. Wysocki 	device_pm_unlock();
3669ed98953SRafael J. Wysocki 	device_links_write_unlock();
3675db25c9eSRafael J. Wysocki 
368e2f3cd83SRafael J. Wysocki 	if ((flags & DL_FLAG_PM_RUNTIME && flags & DL_FLAG_RPM_ACTIVE) && !link)
3695db25c9eSRafael J. Wysocki 		pm_runtime_put(supplier);
3705db25c9eSRafael J. Wysocki 
3719ed98953SRafael J. Wysocki 	return link;
3729ed98953SRafael J. Wysocki }
3739ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_add);
3749ed98953SRafael J. Wysocki 
3759ed98953SRafael J. Wysocki static void device_link_free(struct device_link *link)
3769ed98953SRafael J. Wysocki {
3779ed98953SRafael J. Wysocki 	put_device(link->consumer);
3789ed98953SRafael J. Wysocki 	put_device(link->supplier);
3799ed98953SRafael J. Wysocki 	kfree(link);
3809ed98953SRafael J. Wysocki }
3819ed98953SRafael J. Wysocki 
3829ed98953SRafael J. Wysocki #ifdef CONFIG_SRCU
3839ed98953SRafael J. Wysocki static void __device_link_free_srcu(struct rcu_head *rhead)
3849ed98953SRafael J. Wysocki {
3859ed98953SRafael J. Wysocki 	device_link_free(container_of(rhead, struct device_link, rcu_head));
3869ed98953SRafael J. Wysocki }
3879ed98953SRafael J. Wysocki 
388ead18c23SLukas Wunner static void __device_link_del(struct kref *kref)
3899ed98953SRafael J. Wysocki {
390ead18c23SLukas Wunner 	struct device_link *link = container_of(kref, struct device_link, kref);
391ead18c23SLukas Wunner 
3928a4b3269SJerome Brunet 	dev_dbg(link->consumer, "Dropping the link to %s\n",
3939ed98953SRafael J. Wysocki 		dev_name(link->supplier));
3949ed98953SRafael J. Wysocki 
395baa8809fSRafael J. Wysocki 	if (link->flags & DL_FLAG_PM_RUNTIME)
396baa8809fSRafael J. Wysocki 		pm_runtime_drop_link(link->consumer);
397baa8809fSRafael J. Wysocki 
3989ed98953SRafael J. Wysocki 	list_del_rcu(&link->s_node);
3999ed98953SRafael J. Wysocki 	list_del_rcu(&link->c_node);
4009ed98953SRafael J. Wysocki 	call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu);
4019ed98953SRafael J. Wysocki }
4029ed98953SRafael J. Wysocki #else /* !CONFIG_SRCU */
403ead18c23SLukas Wunner static void __device_link_del(struct kref *kref)
4049ed98953SRafael J. Wysocki {
405ead18c23SLukas Wunner 	struct device_link *link = container_of(kref, struct device_link, kref);
406ead18c23SLukas Wunner 
4079ed98953SRafael J. Wysocki 	dev_info(link->consumer, "Dropping the link to %s\n",
4089ed98953SRafael J. Wysocki 		 dev_name(link->supplier));
4099ed98953SRafael J. Wysocki 
410433986c2SLukas Wunner 	if (link->flags & DL_FLAG_PM_RUNTIME)
411433986c2SLukas Wunner 		pm_runtime_drop_link(link->consumer);
412433986c2SLukas Wunner 
4139ed98953SRafael J. Wysocki 	list_del(&link->s_node);
4149ed98953SRafael J. Wysocki 	list_del(&link->c_node);
4159ed98953SRafael J. Wysocki 	device_link_free(link);
4169ed98953SRafael J. Wysocki }
4179ed98953SRafael J. Wysocki #endif /* !CONFIG_SRCU */
4189ed98953SRafael J. Wysocki 
4199ed98953SRafael J. Wysocki /**
4209ed98953SRafael J. Wysocki  * device_link_del - Delete a link between two devices.
4219ed98953SRafael J. Wysocki  * @link: Device link to delete.
4229ed98953SRafael J. Wysocki  *
4239ed98953SRafael J. Wysocki  * The caller must ensure proper synchronization of this function with runtime
424ead18c23SLukas Wunner  * PM.  If the link was added multiple times, it needs to be deleted as often.
425ead18c23SLukas Wunner  * Care is required for hotplugged devices:  Their links are purged on removal
426ead18c23SLukas Wunner  * and calling device_link_del() is then no longer allowed.
4279ed98953SRafael J. Wysocki  */
4289ed98953SRafael J. Wysocki void device_link_del(struct device_link *link)
4299ed98953SRafael J. Wysocki {
4309ed98953SRafael J. Wysocki 	device_links_write_lock();
4319ed98953SRafael J. Wysocki 	device_pm_lock();
432ead18c23SLukas Wunner 	kref_put(&link->kref, __device_link_del);
4339ed98953SRafael J. Wysocki 	device_pm_unlock();
4349ed98953SRafael J. Wysocki 	device_links_write_unlock();
4359ed98953SRafael J. Wysocki }
4369ed98953SRafael J. Wysocki EXPORT_SYMBOL_GPL(device_link_del);
4379ed98953SRafael J. Wysocki 
438d8842211Spascal paillet /**
439d8842211Spascal paillet  * device_link_remove - remove a link between two devices.
440d8842211Spascal paillet  * @consumer: Consumer end of the link.
441d8842211Spascal paillet  * @supplier: Supplier end of the link.
442d8842211Spascal paillet  *
443d8842211Spascal paillet  * The caller must ensure proper synchronization of this function with runtime
444d8842211Spascal paillet  * PM.
445d8842211Spascal paillet  */
446d8842211Spascal paillet void device_link_remove(void *consumer, struct device *supplier)
447d8842211Spascal paillet {
448d8842211Spascal paillet 	struct device_link *link;
449d8842211Spascal paillet 
450d8842211Spascal paillet 	if (WARN_ON(consumer == supplier))
451d8842211Spascal paillet 		return;
452d8842211Spascal paillet 
453d8842211Spascal paillet 	device_links_write_lock();
454d8842211Spascal paillet 	device_pm_lock();
455d8842211Spascal paillet 
456d8842211Spascal paillet 	list_for_each_entry(link, &supplier->links.consumers, s_node) {
457d8842211Spascal paillet 		if (link->consumer == consumer) {
458d8842211Spascal paillet 			kref_put(&link->kref, __device_link_del);
459d8842211Spascal paillet 			break;
460d8842211Spascal paillet 		}
461d8842211Spascal paillet 	}
462d8842211Spascal paillet 
463d8842211Spascal paillet 	device_pm_unlock();
464d8842211Spascal paillet 	device_links_write_unlock();
465d8842211Spascal paillet }
466d8842211Spascal paillet EXPORT_SYMBOL_GPL(device_link_remove);
467d8842211Spascal paillet 
4689ed98953SRafael J. Wysocki static void device_links_missing_supplier(struct device *dev)
4699ed98953SRafael J. Wysocki {
4709ed98953SRafael J. Wysocki 	struct device_link *link;
4719ed98953SRafael J. Wysocki 
4729ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.suppliers, c_node)
4739ed98953SRafael J. Wysocki 		if (link->status == DL_STATE_CONSUMER_PROBE)
4749ed98953SRafael J. Wysocki 			WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
4759ed98953SRafael J. Wysocki }
4769ed98953SRafael J. Wysocki 
4779ed98953SRafael J. Wysocki /**
4789ed98953SRafael J. Wysocki  * device_links_check_suppliers - Check presence of supplier drivers.
4799ed98953SRafael J. Wysocki  * @dev: Consumer device.
4809ed98953SRafael J. Wysocki  *
4819ed98953SRafael J. Wysocki  * Check links from this device to any suppliers.  Walk the list of the device's
4829ed98953SRafael J. Wysocki  * links to suppliers and see if all of them are available.  If not, simply
4839ed98953SRafael J. Wysocki  * return -EPROBE_DEFER.
4849ed98953SRafael J. Wysocki  *
4859ed98953SRafael J. Wysocki  * We need to guarantee that the supplier will not go away after the check has
4869ed98953SRafael J. Wysocki  * been positive here.  It only can go away in __device_release_driver() and
4879ed98953SRafael J. Wysocki  * that function  checks the device's links to consumers.  This means we need to
4889ed98953SRafael J. Wysocki  * mark the link as "consumer probe in progress" to make the supplier removal
4899ed98953SRafael J. Wysocki  * wait for us to complete (or bad things may happen).
4909ed98953SRafael J. Wysocki  *
4919ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
4929ed98953SRafael J. Wysocki  */
4939ed98953SRafael J. Wysocki int device_links_check_suppliers(struct device *dev)
4949ed98953SRafael J. Wysocki {
4959ed98953SRafael J. Wysocki 	struct device_link *link;
4969ed98953SRafael J. Wysocki 	int ret = 0;
4979ed98953SRafael J. Wysocki 
4989ed98953SRafael J. Wysocki 	device_links_write_lock();
4999ed98953SRafael J. Wysocki 
5009ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.suppliers, c_node) {
5019ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
5029ed98953SRafael J. Wysocki 			continue;
5039ed98953SRafael J. Wysocki 
5049ed98953SRafael J. Wysocki 		if (link->status != DL_STATE_AVAILABLE) {
5059ed98953SRafael J. Wysocki 			device_links_missing_supplier(dev);
5069ed98953SRafael J. Wysocki 			ret = -EPROBE_DEFER;
5079ed98953SRafael J. Wysocki 			break;
5089ed98953SRafael J. Wysocki 		}
5099ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_CONSUMER_PROBE);
5109ed98953SRafael J. Wysocki 	}
5119ed98953SRafael J. Wysocki 	dev->links.status = DL_DEV_PROBING;
5129ed98953SRafael J. Wysocki 
5139ed98953SRafael J. Wysocki 	device_links_write_unlock();
5149ed98953SRafael J. Wysocki 	return ret;
5159ed98953SRafael J. Wysocki }
5169ed98953SRafael J. Wysocki 
5179ed98953SRafael J. Wysocki /**
5189ed98953SRafael J. Wysocki  * device_links_driver_bound - Update device links after probing its driver.
5199ed98953SRafael J. Wysocki  * @dev: Device to update the links for.
5209ed98953SRafael J. Wysocki  *
5219ed98953SRafael J. Wysocki  * The probe has been successful, so update links from this device to any
5229ed98953SRafael J. Wysocki  * consumers by changing their status to "available".
5239ed98953SRafael J. Wysocki  *
5249ed98953SRafael J. Wysocki  * Also change the status of @dev's links to suppliers to "active".
5259ed98953SRafael J. Wysocki  *
5269ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
5279ed98953SRafael J. Wysocki  */
5289ed98953SRafael J. Wysocki void device_links_driver_bound(struct device *dev)
5299ed98953SRafael J. Wysocki {
5309ed98953SRafael J. Wysocki 	struct device_link *link;
5319ed98953SRafael J. Wysocki 
5329ed98953SRafael J. Wysocki 	device_links_write_lock();
5339ed98953SRafael J. Wysocki 
5349ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node) {
5359ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
5369ed98953SRafael J. Wysocki 			continue;
5379ed98953SRafael J. Wysocki 
53815cfb094SRafael J. Wysocki 		/*
53915cfb094SRafael J. Wysocki 		 * Links created during consumer probe may be in the "consumer
54015cfb094SRafael J. Wysocki 		 * probe" state to start with if the supplier is still probing
54115cfb094SRafael J. Wysocki 		 * when they are created and they may become "active" if the
54215cfb094SRafael J. Wysocki 		 * consumer probe returns first.  Skip them here.
54315cfb094SRafael J. Wysocki 		 */
54415cfb094SRafael J. Wysocki 		if (link->status == DL_STATE_CONSUMER_PROBE ||
54515cfb094SRafael J. Wysocki 		    link->status == DL_STATE_ACTIVE)
54615cfb094SRafael J. Wysocki 			continue;
54715cfb094SRafael J. Wysocki 
5489ed98953SRafael J. Wysocki 		WARN_ON(link->status != DL_STATE_DORMANT);
5499ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
5509ed98953SRafael J. Wysocki 	}
5519ed98953SRafael J. Wysocki 
5529ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.suppliers, c_node) {
5539ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
5549ed98953SRafael J. Wysocki 			continue;
5559ed98953SRafael J. Wysocki 
5569ed98953SRafael J. Wysocki 		WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
5579ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_ACTIVE);
5589ed98953SRafael J. Wysocki 	}
5599ed98953SRafael J. Wysocki 
5609ed98953SRafael J. Wysocki 	dev->links.status = DL_DEV_DRIVER_BOUND;
5619ed98953SRafael J. Wysocki 
5629ed98953SRafael J. Wysocki 	device_links_write_unlock();
5639ed98953SRafael J. Wysocki }
5649ed98953SRafael J. Wysocki 
5659ed98953SRafael J. Wysocki /**
5669ed98953SRafael J. Wysocki  * __device_links_no_driver - Update links of a device without a driver.
5679ed98953SRafael J. Wysocki  * @dev: Device without a drvier.
5689ed98953SRafael J. Wysocki  *
5699ed98953SRafael J. Wysocki  * Delete all non-persistent links from this device to any suppliers.
5709ed98953SRafael J. Wysocki  *
5719ed98953SRafael J. Wysocki  * Persistent links stay around, but their status is changed to "available",
5729ed98953SRafael J. Wysocki  * unless they already are in the "supplier unbind in progress" state in which
5739ed98953SRafael J. Wysocki  * case they need not be updated.
5749ed98953SRafael J. Wysocki  *
5759ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
5769ed98953SRafael J. Wysocki  */
5779ed98953SRafael J. Wysocki static void __device_links_no_driver(struct device *dev)
5789ed98953SRafael J. Wysocki {
5799ed98953SRafael J. Wysocki 	struct device_link *link, *ln;
5809ed98953SRafael J. Wysocki 
5819ed98953SRafael J. Wysocki 	list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) {
5829ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
5839ed98953SRafael J. Wysocki 			continue;
5849ed98953SRafael J. Wysocki 
585e88728f4SVivek Gautam 		if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER)
5860fe6f787SYong Wu 			__device_link_del(&link->kref);
58715cfb094SRafael J. Wysocki 		else if (link->status == DL_STATE_CONSUMER_PROBE ||
58815cfb094SRafael J. Wysocki 			 link->status == DL_STATE_ACTIVE)
5899ed98953SRafael J. Wysocki 			WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
5909ed98953SRafael J. Wysocki 	}
5919ed98953SRafael J. Wysocki 
5929ed98953SRafael J. Wysocki 	dev->links.status = DL_DEV_NO_DRIVER;
5939ed98953SRafael J. Wysocki }
5949ed98953SRafael J. Wysocki 
59515cfb094SRafael J. Wysocki /**
59615cfb094SRafael J. Wysocki  * device_links_no_driver - Update links after failing driver probe.
59715cfb094SRafael J. Wysocki  * @dev: Device whose driver has just failed to probe.
59815cfb094SRafael J. Wysocki  *
59915cfb094SRafael J. Wysocki  * Clean up leftover links to consumers for @dev and invoke
60015cfb094SRafael J. Wysocki  * %__device_links_no_driver() to update links to suppliers for it as
60115cfb094SRafael J. Wysocki  * appropriate.
60215cfb094SRafael J. Wysocki  *
60315cfb094SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
60415cfb094SRafael J. Wysocki  */
6059ed98953SRafael J. Wysocki void device_links_no_driver(struct device *dev)
6069ed98953SRafael J. Wysocki {
60715cfb094SRafael J. Wysocki 	struct device_link *link;
60815cfb094SRafael J. Wysocki 
6099ed98953SRafael J. Wysocki 	device_links_write_lock();
61015cfb094SRafael J. Wysocki 
61115cfb094SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node) {
61215cfb094SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
61315cfb094SRafael J. Wysocki 			continue;
61415cfb094SRafael J. Wysocki 
61515cfb094SRafael J. Wysocki 		/*
61615cfb094SRafael J. Wysocki 		 * The probe has failed, so if the status of the link is
61715cfb094SRafael J. Wysocki 		 * "consumer probe" or "active", it must have been added by
61815cfb094SRafael J. Wysocki 		 * a probing consumer while this device was still probing.
61915cfb094SRafael J. Wysocki 		 * Change its state to "dormant", as it represents a valid
62015cfb094SRafael J. Wysocki 		 * relationship, but it is not functionally meaningful.
62115cfb094SRafael J. Wysocki 		 */
62215cfb094SRafael J. Wysocki 		if (link->status == DL_STATE_CONSUMER_PROBE ||
62315cfb094SRafael J. Wysocki 		    link->status == DL_STATE_ACTIVE)
62415cfb094SRafael J. Wysocki 			WRITE_ONCE(link->status, DL_STATE_DORMANT);
62515cfb094SRafael J. Wysocki 	}
62615cfb094SRafael J. Wysocki 
6279ed98953SRafael J. Wysocki 	__device_links_no_driver(dev);
62815cfb094SRafael J. Wysocki 
6299ed98953SRafael J. Wysocki 	device_links_write_unlock();
6309ed98953SRafael J. Wysocki }
6319ed98953SRafael J. Wysocki 
6329ed98953SRafael J. Wysocki /**
6339ed98953SRafael J. Wysocki  * device_links_driver_cleanup - Update links after driver removal.
6349ed98953SRafael J. Wysocki  * @dev: Device whose driver has just gone away.
6359ed98953SRafael J. Wysocki  *
6369ed98953SRafael J. Wysocki  * Update links to consumers for @dev by changing their status to "dormant" and
6379ed98953SRafael J. Wysocki  * invoke %__device_links_no_driver() to update links to suppliers for it as
6389ed98953SRafael J. Wysocki  * appropriate.
6399ed98953SRafael J. Wysocki  *
6409ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
6419ed98953SRafael J. Wysocki  */
6429ed98953SRafael J. Wysocki void device_links_driver_cleanup(struct device *dev)
6439ed98953SRafael J. Wysocki {
644c8d50986SRafael J. Wysocki 	struct device_link *link, *ln;
6459ed98953SRafael J. Wysocki 
6469ed98953SRafael J. Wysocki 	device_links_write_lock();
6479ed98953SRafael J. Wysocki 
648c8d50986SRafael J. Wysocki 	list_for_each_entry_safe(link, ln, &dev->links.consumers, s_node) {
6499ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
6509ed98953SRafael J. Wysocki 			continue;
6519ed98953SRafael J. Wysocki 
652e88728f4SVivek Gautam 		WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER);
6539ed98953SRafael J. Wysocki 		WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND);
6541689cac5SVivek Gautam 
6551689cac5SVivek Gautam 		/*
6561689cac5SVivek Gautam 		 * autoremove the links between this @dev and its consumer
6571689cac5SVivek Gautam 		 * devices that are not active, i.e. where the link state
6581689cac5SVivek Gautam 		 * has moved to DL_STATE_SUPPLIER_UNBIND.
6591689cac5SVivek Gautam 		 */
6601689cac5SVivek Gautam 		if (link->status == DL_STATE_SUPPLIER_UNBIND &&
6611689cac5SVivek Gautam 		    link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
6620fe6f787SYong Wu 			__device_link_del(&link->kref);
6631689cac5SVivek Gautam 
6649ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_DORMANT);
6659ed98953SRafael J. Wysocki 	}
6669ed98953SRafael J. Wysocki 
6679ed98953SRafael J. Wysocki 	__device_links_no_driver(dev);
6689ed98953SRafael J. Wysocki 
6699ed98953SRafael J. Wysocki 	device_links_write_unlock();
6709ed98953SRafael J. Wysocki }
6719ed98953SRafael J. Wysocki 
6729ed98953SRafael J. Wysocki /**
6739ed98953SRafael J. Wysocki  * device_links_busy - Check if there are any busy links to consumers.
6749ed98953SRafael J. Wysocki  * @dev: Device to check.
6759ed98953SRafael J. Wysocki  *
6769ed98953SRafael J. Wysocki  * Check each consumer of the device and return 'true' if its link's status
6779ed98953SRafael J. Wysocki  * is one of "consumer probe" or "active" (meaning that the given consumer is
6789ed98953SRafael J. Wysocki  * probing right now or its driver is present).  Otherwise, change the link
6799ed98953SRafael J. Wysocki  * state to "supplier unbind" to prevent the consumer from being probed
6809ed98953SRafael J. Wysocki  * successfully going forward.
6819ed98953SRafael J. Wysocki  *
6829ed98953SRafael J. Wysocki  * Return 'false' if there are no probing or active consumers.
6839ed98953SRafael J. Wysocki  *
6849ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
6859ed98953SRafael J. Wysocki  */
6869ed98953SRafael J. Wysocki bool device_links_busy(struct device *dev)
6879ed98953SRafael J. Wysocki {
6889ed98953SRafael J. Wysocki 	struct device_link *link;
6899ed98953SRafael J. Wysocki 	bool ret = false;
6909ed98953SRafael J. Wysocki 
6919ed98953SRafael J. Wysocki 	device_links_write_lock();
6929ed98953SRafael J. Wysocki 
6939ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node) {
6949ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
6959ed98953SRafael J. Wysocki 			continue;
6969ed98953SRafael J. Wysocki 
6979ed98953SRafael J. Wysocki 		if (link->status == DL_STATE_CONSUMER_PROBE
6989ed98953SRafael J. Wysocki 		    || link->status == DL_STATE_ACTIVE) {
6999ed98953SRafael J. Wysocki 			ret = true;
7009ed98953SRafael J. Wysocki 			break;
7019ed98953SRafael J. Wysocki 		}
7029ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND);
7039ed98953SRafael J. Wysocki 	}
7049ed98953SRafael J. Wysocki 
7059ed98953SRafael J. Wysocki 	dev->links.status = DL_DEV_UNBINDING;
7069ed98953SRafael J. Wysocki 
7079ed98953SRafael J. Wysocki 	device_links_write_unlock();
7089ed98953SRafael J. Wysocki 	return ret;
7099ed98953SRafael J. Wysocki }
7109ed98953SRafael J. Wysocki 
7119ed98953SRafael J. Wysocki /**
7129ed98953SRafael J. Wysocki  * device_links_unbind_consumers - Force unbind consumers of the given device.
7139ed98953SRafael J. Wysocki  * @dev: Device to unbind the consumers of.
7149ed98953SRafael J. Wysocki  *
7159ed98953SRafael J. Wysocki  * Walk the list of links to consumers for @dev and if any of them is in the
7169ed98953SRafael J. Wysocki  * "consumer probe" state, wait for all device probes in progress to complete
7179ed98953SRafael J. Wysocki  * and start over.
7189ed98953SRafael J. Wysocki  *
7199ed98953SRafael J. Wysocki  * If that's not the case, change the status of the link to "supplier unbind"
7209ed98953SRafael J. Wysocki  * and check if the link was in the "active" state.  If so, force the consumer
7219ed98953SRafael J. Wysocki  * driver to unbind and start over (the consumer will not re-probe as we have
7229ed98953SRafael J. Wysocki  * changed the state of the link already).
7239ed98953SRafael J. Wysocki  *
7249ed98953SRafael J. Wysocki  * Links with the DL_FLAG_STATELESS flag set are ignored.
7259ed98953SRafael J. Wysocki  */
7269ed98953SRafael J. Wysocki void device_links_unbind_consumers(struct device *dev)
7279ed98953SRafael J. Wysocki {
7289ed98953SRafael J. Wysocki 	struct device_link *link;
7299ed98953SRafael J. Wysocki 
7309ed98953SRafael J. Wysocki  start:
7319ed98953SRafael J. Wysocki 	device_links_write_lock();
7329ed98953SRafael J. Wysocki 
7339ed98953SRafael J. Wysocki 	list_for_each_entry(link, &dev->links.consumers, s_node) {
7349ed98953SRafael J. Wysocki 		enum device_link_state status;
7359ed98953SRafael J. Wysocki 
7369ed98953SRafael J. Wysocki 		if (link->flags & DL_FLAG_STATELESS)
7379ed98953SRafael J. Wysocki 			continue;
7389ed98953SRafael J. Wysocki 
7399ed98953SRafael J. Wysocki 		status = link->status;
7409ed98953SRafael J. Wysocki 		if (status == DL_STATE_CONSUMER_PROBE) {
7419ed98953SRafael J. Wysocki 			device_links_write_unlock();
7429ed98953SRafael J. Wysocki 
7439ed98953SRafael J. Wysocki 			wait_for_device_probe();
7449ed98953SRafael J. Wysocki 			goto start;
7459ed98953SRafael J. Wysocki 		}
7469ed98953SRafael J. Wysocki 		WRITE_ONCE(link->status, DL_STATE_SUPPLIER_UNBIND);
7479ed98953SRafael J. Wysocki 		if (status == DL_STATE_ACTIVE) {
7489ed98953SRafael J. Wysocki 			struct device *consumer = link->consumer;
7499ed98953SRafael J. Wysocki 
7509ed98953SRafael J. Wysocki 			get_device(consumer);
7519ed98953SRafael J. Wysocki 
7529ed98953SRafael J. Wysocki 			device_links_write_unlock();
7539ed98953SRafael J. Wysocki 
7549ed98953SRafael J. Wysocki 			device_release_driver_internal(consumer, NULL,
7559ed98953SRafael J. Wysocki 						       consumer->parent);
7569ed98953SRafael J. Wysocki 			put_device(consumer);
7579ed98953SRafael J. Wysocki 			goto start;
7589ed98953SRafael J. Wysocki 		}
7599ed98953SRafael J. Wysocki 	}
7609ed98953SRafael J. Wysocki 
7619ed98953SRafael J. Wysocki 	device_links_write_unlock();
7629ed98953SRafael J. Wysocki }
7639ed98953SRafael J. Wysocki 
7649ed98953SRafael J. Wysocki /**
7659ed98953SRafael J. Wysocki  * device_links_purge - Delete existing links to other devices.
7669ed98953SRafael J. Wysocki  * @dev: Target device.
7679ed98953SRafael J. Wysocki  */
7689ed98953SRafael J. Wysocki static void device_links_purge(struct device *dev)
7699ed98953SRafael J. Wysocki {
7709ed98953SRafael J. Wysocki 	struct device_link *link, *ln;
7719ed98953SRafael J. Wysocki 
7729ed98953SRafael J. Wysocki 	/*
7739ed98953SRafael J. Wysocki 	 * Delete all of the remaining links from this device to any other
7749ed98953SRafael J. Wysocki 	 * devices (either consumers or suppliers).
7759ed98953SRafael J. Wysocki 	 */
7769ed98953SRafael J. Wysocki 	device_links_write_lock();
7779ed98953SRafael J. Wysocki 
7789ed98953SRafael J. Wysocki 	list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) {
7799ed98953SRafael J. Wysocki 		WARN_ON(link->status == DL_STATE_ACTIVE);
780ead18c23SLukas Wunner 		__device_link_del(&link->kref);
7819ed98953SRafael J. Wysocki 	}
7829ed98953SRafael J. Wysocki 
7839ed98953SRafael J. Wysocki 	list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) {
7849ed98953SRafael J. Wysocki 		WARN_ON(link->status != DL_STATE_DORMANT &&
7859ed98953SRafael J. Wysocki 			link->status != DL_STATE_NONE);
786ead18c23SLukas Wunner 		__device_link_del(&link->kref);
7879ed98953SRafael J. Wysocki 	}
7889ed98953SRafael J. Wysocki 
7899ed98953SRafael J. Wysocki 	device_links_write_unlock();
7909ed98953SRafael J. Wysocki }
7919ed98953SRafael J. Wysocki 
7929ed98953SRafael J. Wysocki /* Device links support end. */
7939ed98953SRafael J. Wysocki 
7941da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL;
7951da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL;
796e105b8bfSDan Williams static struct kobject *dev_kobj;
797e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj;
798e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj;
7991da177e4SLinus Torvalds 
8005e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock);
8015e33bc41SRafael J. Wysocki 
8025e33bc41SRafael J. Wysocki void lock_device_hotplug(void)
8035e33bc41SRafael J. Wysocki {
8045e33bc41SRafael J. Wysocki 	mutex_lock(&device_hotplug_lock);
8055e33bc41SRafael J. Wysocki }
8065e33bc41SRafael J. Wysocki 
8075e33bc41SRafael J. Wysocki void unlock_device_hotplug(void)
8085e33bc41SRafael J. Wysocki {
8095e33bc41SRafael J. Wysocki 	mutex_unlock(&device_hotplug_lock);
8105e33bc41SRafael J. Wysocki }
8115e33bc41SRafael J. Wysocki 
8125e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void)
8135e33bc41SRafael J. Wysocki {
8145e33bc41SRafael J. Wysocki 	if (mutex_trylock(&device_hotplug_lock))
8155e33bc41SRafael J. Wysocki 		return 0;
8165e33bc41SRafael J. Wysocki 
8175e33bc41SRafael J. Wysocki 	/* Avoid busy looping (5 ms of sleep should do). */
8185e33bc41SRafael J. Wysocki 	msleep(5);
8195e33bc41SRafael J. Wysocki 	return restart_syscall();
8205e33bc41SRafael J. Wysocki }
8215e33bc41SRafael J. Wysocki 
8224e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK
8234e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev)
8244e886c29SGreg Kroah-Hartman {
8254e886c29SGreg Kroah-Hartman 	return !(dev->type == &part_type);
8264e886c29SGreg Kroah-Hartman }
8274e886c29SGreg Kroah-Hartman #else
8284e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev)
8294e886c29SGreg Kroah-Hartman {
8304e886c29SGreg Kroah-Hartman 	return 1;
8314e886c29SGreg Kroah-Hartman }
8324e886c29SGreg Kroah-Hartman #endif
8331da177e4SLinus Torvalds 
83407de0e86SHeikki Krogerus static int
83507de0e86SHeikki Krogerus device_platform_notify(struct device *dev, enum kobject_action action)
83607de0e86SHeikki Krogerus {
8377847a145SHeikki Krogerus 	int ret;
8387847a145SHeikki Krogerus 
8397847a145SHeikki Krogerus 	ret = acpi_platform_notify(dev, action);
8407847a145SHeikki Krogerus 	if (ret)
8417847a145SHeikki Krogerus 		return ret;
8427847a145SHeikki Krogerus 
84359abd836SHeikki Krogerus 	ret = software_node_notify(dev, action);
84459abd836SHeikki Krogerus 	if (ret)
84559abd836SHeikki Krogerus 		return ret;
84659abd836SHeikki Krogerus 
84707de0e86SHeikki Krogerus 	if (platform_notify && action == KOBJ_ADD)
84807de0e86SHeikki Krogerus 		platform_notify(dev);
84907de0e86SHeikki Krogerus 	else if (platform_notify_remove && action == KOBJ_REMOVE)
85007de0e86SHeikki Krogerus 		platform_notify_remove(dev);
85107de0e86SHeikki Krogerus 	return 0;
85207de0e86SHeikki Krogerus }
85307de0e86SHeikki Krogerus 
8543e95637aSAlan Stern /**
8553e95637aSAlan Stern  * dev_driver_string - Return a device's driver name, if at all possible
8563e95637aSAlan Stern  * @dev: struct device to get the name of
8573e95637aSAlan Stern  *
8583e95637aSAlan Stern  * Will return the device's driver's name if it is bound to a device.  If
8599169c012Syan  * the device is not bound to a driver, it will return the name of the bus
8603e95637aSAlan Stern  * it is attached to.  If it is not attached to a bus either, an empty
8613e95637aSAlan Stern  * string will be returned.
8623e95637aSAlan Stern  */
863bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev)
8643e95637aSAlan Stern {
8653589972eSAlan Stern 	struct device_driver *drv;
8663589972eSAlan Stern 
8673589972eSAlan Stern 	/* dev->driver can change to NULL underneath us because of unbinding,
8683589972eSAlan Stern 	 * so be careful about accessing it.  dev->bus and dev->class should
8693589972eSAlan Stern 	 * never change once they are set, so they don't need special care.
8703589972eSAlan Stern 	 */
8716aa7de05SMark Rutland 	drv = READ_ONCE(dev->driver);
8723589972eSAlan Stern 	return drv ? drv->name :
873a456b702SJean Delvare 			(dev->bus ? dev->bus->name :
874a456b702SJean Delvare 			(dev->class ? dev->class->name : ""));
8753e95637aSAlan Stern }
876310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string);
8773e95637aSAlan Stern 
8781da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
8791da177e4SLinus Torvalds 
8804a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
8814a3ad20cSGreg Kroah-Hartman 			     char *buf)
8821da177e4SLinus Torvalds {
8831da177e4SLinus Torvalds 	struct device_attribute *dev_attr = to_dev_attr(attr);
884b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
8854a0c20bfSDmitry Torokhov 	ssize_t ret = -EIO;
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds 	if (dev_attr->show)
88854b6f35cSYani Ioannou 		ret = dev_attr->show(dev, dev_attr, buf);
889815d2d50SAndrew Morton 	if (ret >= (ssize_t)PAGE_SIZE) {
890a52668c6SSergey Senozhatsky 		printk("dev_attr_show: %pS returned bad count\n",
891a52668c6SSergey Senozhatsky 				dev_attr->show);
892815d2d50SAndrew Morton 	}
8931da177e4SLinus Torvalds 	return ret;
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
8964a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
8971da177e4SLinus Torvalds 			      const char *buf, size_t count)
8981da177e4SLinus Torvalds {
8991da177e4SLinus Torvalds 	struct device_attribute *dev_attr = to_dev_attr(attr);
900b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
9014a0c20bfSDmitry Torokhov 	ssize_t ret = -EIO;
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 	if (dev_attr->store)
90454b6f35cSYani Ioannou 		ret = dev_attr->store(dev, dev_attr, buf, count);
9051da177e4SLinus Torvalds 	return ret;
9061da177e4SLinus Torvalds }
9071da177e4SLinus Torvalds 
90852cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = {
9091da177e4SLinus Torvalds 	.show	= dev_attr_show,
9101da177e4SLinus Torvalds 	.store	= dev_attr_store,
9111da177e4SLinus Torvalds };
9121da177e4SLinus Torvalds 
913ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
914ca22e56dSKay Sievers 
915ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev,
916ca22e56dSKay Sievers 			   struct device_attribute *attr,
917ca22e56dSKay Sievers 			   const char *buf, size_t size)
918ca22e56dSKay Sievers {
919ca22e56dSKay Sievers 	struct dev_ext_attribute *ea = to_ext_attr(attr);
920f88184bfSKaitao cheng 	int ret;
921f88184bfSKaitao cheng 	unsigned long new;
922f88184bfSKaitao cheng 
923f88184bfSKaitao cheng 	ret = kstrtoul(buf, 0, &new);
924f88184bfSKaitao cheng 	if (ret)
925f88184bfSKaitao cheng 		return ret;
926ca22e56dSKay Sievers 	*(unsigned long *)(ea->var) = new;
927ca22e56dSKay Sievers 	/* Always return full write size even if we didn't consume all */
928ca22e56dSKay Sievers 	return size;
929ca22e56dSKay Sievers }
930ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong);
931ca22e56dSKay Sievers 
932ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev,
933ca22e56dSKay Sievers 			  struct device_attribute *attr,
934ca22e56dSKay Sievers 			  char *buf)
935ca22e56dSKay Sievers {
936ca22e56dSKay Sievers 	struct dev_ext_attribute *ea = to_ext_attr(attr);
937ca22e56dSKay Sievers 	return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
938ca22e56dSKay Sievers }
939ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong);
940ca22e56dSKay Sievers 
941ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev,
942ca22e56dSKay Sievers 			 struct device_attribute *attr,
943ca22e56dSKay Sievers 			 const char *buf, size_t size)
944ca22e56dSKay Sievers {
945ca22e56dSKay Sievers 	struct dev_ext_attribute *ea = to_ext_attr(attr);
946f88184bfSKaitao cheng 	int ret;
947f88184bfSKaitao cheng 	long new;
948f88184bfSKaitao cheng 
949f88184bfSKaitao cheng 	ret = kstrtol(buf, 0, &new);
950f88184bfSKaitao cheng 	if (ret)
951f88184bfSKaitao cheng 		return ret;
952f88184bfSKaitao cheng 
953f88184bfSKaitao cheng 	if (new > INT_MAX || new < INT_MIN)
954ca22e56dSKay Sievers 		return -EINVAL;
955ca22e56dSKay Sievers 	*(int *)(ea->var) = new;
956ca22e56dSKay Sievers 	/* Always return full write size even if we didn't consume all */
957ca22e56dSKay Sievers 	return size;
958ca22e56dSKay Sievers }
959ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int);
960ca22e56dSKay Sievers 
961ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev,
962ca22e56dSKay Sievers 			struct device_attribute *attr,
963ca22e56dSKay Sievers 			char *buf)
964ca22e56dSKay Sievers {
965ca22e56dSKay Sievers 	struct dev_ext_attribute *ea = to_ext_attr(attr);
966ca22e56dSKay Sievers 
967ca22e56dSKay Sievers 	return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
968ca22e56dSKay Sievers }
969ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int);
9701da177e4SLinus Torvalds 
97191872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
97291872392SBorislav Petkov 			  const char *buf, size_t size)
97391872392SBorislav Petkov {
97491872392SBorislav Petkov 	struct dev_ext_attribute *ea = to_ext_attr(attr);
97591872392SBorislav Petkov 
97691872392SBorislav Petkov 	if (strtobool(buf, ea->var) < 0)
97791872392SBorislav Petkov 		return -EINVAL;
97891872392SBorislav Petkov 
97991872392SBorislav Petkov 	return size;
98091872392SBorislav Petkov }
98191872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool);
98291872392SBorislav Petkov 
98391872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
98491872392SBorislav Petkov 			 char *buf)
98591872392SBorislav Petkov {
98691872392SBorislav Petkov 	struct dev_ext_attribute *ea = to_ext_attr(attr);
98791872392SBorislav Petkov 
98891872392SBorislav Petkov 	return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var));
98991872392SBorislav Petkov }
99091872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool);
99191872392SBorislav Petkov 
9921da177e4SLinus Torvalds /**
9931da177e4SLinus Torvalds  * device_release - free device structure.
9941da177e4SLinus Torvalds  * @kobj: device's kobject.
9951da177e4SLinus Torvalds  *
9961da177e4SLinus Torvalds  * This is called once the reference count for the object
9971da177e4SLinus Torvalds  * reaches 0. We forward the call to the device's release
9981da177e4SLinus Torvalds  * method, which should handle actually freeing the structure.
9991da177e4SLinus Torvalds  */
10001da177e4SLinus Torvalds static void device_release(struct kobject *kobj)
10011da177e4SLinus Torvalds {
1002b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
1003fb069a5dSGreg Kroah-Hartman 	struct device_private *p = dev->p;
10041da177e4SLinus Torvalds 
1005a525a3ddSMing Lei 	/*
1006a525a3ddSMing Lei 	 * Some platform devices are driven without driver attached
1007a525a3ddSMing Lei 	 * and managed resources may have been acquired.  Make sure
1008a525a3ddSMing Lei 	 * all resources are released.
1009a525a3ddSMing Lei 	 *
1010a525a3ddSMing Lei 	 * Drivers still can add resources into device after device
1011a525a3ddSMing Lei 	 * is deleted but alive, so release devres here to avoid
1012a525a3ddSMing Lei 	 * possible memory leak.
1013a525a3ddSMing Lei 	 */
1014a525a3ddSMing Lei 	devres_release_all(dev);
1015a525a3ddSMing Lei 
10161da177e4SLinus Torvalds 	if (dev->release)
10171da177e4SLinus Torvalds 		dev->release(dev);
1018f9f852dfSKay Sievers 	else if (dev->type && dev->type->release)
1019f9f852dfSKay Sievers 		dev->type->release(dev);
10202620efefSGreg Kroah-Hartman 	else if (dev->class && dev->class->dev_release)
10212620efefSGreg Kroah-Hartman 		dev->class->dev_release(dev);
1022f810a5cfSArjan van de Ven 	else
1023186bddb2SEzequiel Garcia 		WARN(1, KERN_ERR "Device '%s' does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
10241e0b2cf9SKay Sievers 			dev_name(dev));
1025fb069a5dSGreg Kroah-Hartman 	kfree(p);
10261da177e4SLinus Torvalds }
10271da177e4SLinus Torvalds 
1028bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj)
1029bc451f20SEric W. Biederman {
1030b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
1031bc451f20SEric W. Biederman 	const void *ns = NULL;
1032bc451f20SEric W. Biederman 
1033bc451f20SEric W. Biederman 	if (dev->class && dev->class->ns_type)
1034bc451f20SEric W. Biederman 		ns = dev->class->namespace(dev);
1035bc451f20SEric W. Biederman 
1036bc451f20SEric W. Biederman 	return ns;
1037bc451f20SEric W. Biederman }
1038bc451f20SEric W. Biederman 
10399944e894SDmitry Torokhov static void device_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
10409944e894SDmitry Torokhov {
10419944e894SDmitry Torokhov 	struct device *dev = kobj_to_dev(kobj);
10429944e894SDmitry Torokhov 
10439944e894SDmitry Torokhov 	if (dev->class && dev->class->get_ownership)
10449944e894SDmitry Torokhov 		dev->class->get_ownership(dev, uid, gid);
10459944e894SDmitry Torokhov }
10469944e894SDmitry Torokhov 
10478f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = {
10481da177e4SLinus Torvalds 	.release	= device_release,
10491da177e4SLinus Torvalds 	.sysfs_ops	= &dev_sysfs_ops,
1050bc451f20SEric W. Biederman 	.namespace	= device_namespace,
10519944e894SDmitry Torokhov 	.get_ownership	= device_get_ownership,
10521da177e4SLinus Torvalds };
10531da177e4SLinus Torvalds 
10541da177e4SLinus Torvalds 
1055312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
10561da177e4SLinus Torvalds {
10571da177e4SLinus Torvalds 	struct kobj_type *ktype = get_ktype(kobj);
10581da177e4SLinus Torvalds 
10598f4afc41SGreg Kroah-Hartman 	if (ktype == &device_ktype) {
1060b0d1f807SLars-Peter Clausen 		struct device *dev = kobj_to_dev(kobj);
10611da177e4SLinus Torvalds 		if (dev->bus)
10621da177e4SLinus Torvalds 			return 1;
106323681e47SGreg Kroah-Hartman 		if (dev->class)
106423681e47SGreg Kroah-Hartman 			return 1;
10651da177e4SLinus Torvalds 	}
10661da177e4SLinus Torvalds 	return 0;
10671da177e4SLinus Torvalds }
10681da177e4SLinus Torvalds 
1069312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
10701da177e4SLinus Torvalds {
1071b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
10721da177e4SLinus Torvalds 
107323681e47SGreg Kroah-Hartman 	if (dev->bus)
10741da177e4SLinus Torvalds 		return dev->bus->name;
107523681e47SGreg Kroah-Hartman 	if (dev->class)
107623681e47SGreg Kroah-Hartman 		return dev->class->name;
107723681e47SGreg Kroah-Hartman 	return NULL;
10781da177e4SLinus Torvalds }
10791da177e4SLinus Torvalds 
10807eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj,
10817eff2e7aSKay Sievers 		      struct kobj_uevent_env *env)
10821da177e4SLinus Torvalds {
1083b0d1f807SLars-Peter Clausen 	struct device *dev = kobj_to_dev(kobj);
10841da177e4SLinus Torvalds 	int retval = 0;
10851da177e4SLinus Torvalds 
10866fcf53acSKay Sievers 	/* add device node properties if present */
108723681e47SGreg Kroah-Hartman 	if (MAJOR(dev->devt)) {
10886fcf53acSKay Sievers 		const char *tmp;
10896fcf53acSKay Sievers 		const char *name;
10902c9ede55SAl Viro 		umode_t mode = 0;
10914e4098a3SGreg Kroah-Hartman 		kuid_t uid = GLOBAL_ROOT_UID;
10924e4098a3SGreg Kroah-Hartman 		kgid_t gid = GLOBAL_ROOT_GID;
10936fcf53acSKay Sievers 
10947eff2e7aSKay Sievers 		add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
10957eff2e7aSKay Sievers 		add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
10963c2670e6SKay Sievers 		name = device_get_devnode(dev, &mode, &uid, &gid, &tmp);
10976fcf53acSKay Sievers 		if (name) {
10986fcf53acSKay Sievers 			add_uevent_var(env, "DEVNAME=%s", name);
1099e454cea2SKay Sievers 			if (mode)
1100e454cea2SKay Sievers 				add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
11014e4098a3SGreg Kroah-Hartman 			if (!uid_eq(uid, GLOBAL_ROOT_UID))
11024e4098a3SGreg Kroah-Hartman 				add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid));
11034e4098a3SGreg Kroah-Hartman 			if (!gid_eq(gid, GLOBAL_ROOT_GID))
11044e4098a3SGreg Kroah-Hartman 				add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid));
11053c2670e6SKay Sievers 			kfree(tmp);
11066fcf53acSKay Sievers 		}
110723681e47SGreg Kroah-Hartman 	}
110823681e47SGreg Kroah-Hartman 
1109414264f9SKay Sievers 	if (dev->type && dev->type->name)
11107eff2e7aSKay Sievers 		add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
1111414264f9SKay Sievers 
1112239378f1SKay Sievers 	if (dev->driver)
11137eff2e7aSKay Sievers 		add_uevent_var(env, "DRIVER=%s", dev->driver->name);
1114239378f1SKay Sievers 
111507d57a32SGrant Likely 	/* Add common DT information about the device */
111607d57a32SGrant Likely 	of_device_uevent(dev, env);
111707d57a32SGrant Likely 
11181da177e4SLinus Torvalds 	/* have the bus specific function add its stuff */
11197eff2e7aSKay Sievers 	if (dev->bus && dev->bus->uevent) {
11207eff2e7aSKay Sievers 		retval = dev->bus->uevent(dev, env);
1121f9f852dfSKay Sievers 		if (retval)
11227dc72b28SGreg Kroah-Hartman 			pr_debug("device: '%s': %s: bus uevent() returned %d\n",
11231e0b2cf9SKay Sievers 				 dev_name(dev), __func__, retval);
11241da177e4SLinus Torvalds 	}
11251da177e4SLinus Torvalds 
11262620efefSGreg Kroah-Hartman 	/* have the class specific function add its stuff */
11277eff2e7aSKay Sievers 	if (dev->class && dev->class->dev_uevent) {
11287eff2e7aSKay Sievers 		retval = dev->class->dev_uevent(dev, env);
1129f9f852dfSKay Sievers 		if (retval)
11307dc72b28SGreg Kroah-Hartman 			pr_debug("device: '%s': %s: class uevent() "
11311e0b2cf9SKay Sievers 				 "returned %d\n", dev_name(dev),
11322b3a302aSHarvey Harrison 				 __func__, retval);
11332620efefSGreg Kroah-Hartman 	}
1134f9f852dfSKay Sievers 
1135eef35c2dSStefan Weil 	/* have the device type specific function add its stuff */
11367eff2e7aSKay Sievers 	if (dev->type && dev->type->uevent) {
11377eff2e7aSKay Sievers 		retval = dev->type->uevent(dev, env);
1138f9f852dfSKay Sievers 		if (retval)
11397dc72b28SGreg Kroah-Hartman 			pr_debug("device: '%s': %s: dev_type uevent() "
11401e0b2cf9SKay Sievers 				 "returned %d\n", dev_name(dev),
11412b3a302aSHarvey Harrison 				 __func__, retval);
11422620efefSGreg Kroah-Hartman 	}
11432620efefSGreg Kroah-Hartman 
11441da177e4SLinus Torvalds 	return retval;
11451da177e4SLinus Torvalds }
11461da177e4SLinus Torvalds 
11479cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = {
1148312c004dSKay Sievers 	.filter =	dev_uevent_filter,
1149312c004dSKay Sievers 	.name =		dev_uevent_name,
1150312c004dSKay Sievers 	.uevent =	dev_uevent,
11511da177e4SLinus Torvalds };
11521da177e4SLinus Torvalds 
1153c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
115416574dccSKay Sievers 			   char *buf)
115516574dccSKay Sievers {
115616574dccSKay Sievers 	struct kobject *top_kobj;
115716574dccSKay Sievers 	struct kset *kset;
11587eff2e7aSKay Sievers 	struct kobj_uevent_env *env = NULL;
115916574dccSKay Sievers 	int i;
116016574dccSKay Sievers 	size_t count = 0;
116116574dccSKay Sievers 	int retval;
116216574dccSKay Sievers 
116316574dccSKay Sievers 	/* search the kset, the device belongs to */
116416574dccSKay Sievers 	top_kobj = &dev->kobj;
11655c5daf65SKay Sievers 	while (!top_kobj->kset && top_kobj->parent)
116616574dccSKay Sievers 		top_kobj = top_kobj->parent;
116716574dccSKay Sievers 	if (!top_kobj->kset)
116816574dccSKay Sievers 		goto out;
11695c5daf65SKay Sievers 
117016574dccSKay Sievers 	kset = top_kobj->kset;
117116574dccSKay Sievers 	if (!kset->uevent_ops || !kset->uevent_ops->uevent)
117216574dccSKay Sievers 		goto out;
117316574dccSKay Sievers 
117416574dccSKay Sievers 	/* respect filter */
117516574dccSKay Sievers 	if (kset->uevent_ops && kset->uevent_ops->filter)
117616574dccSKay Sievers 		if (!kset->uevent_ops->filter(kset, &dev->kobj))
117716574dccSKay Sievers 			goto out;
117816574dccSKay Sievers 
11797eff2e7aSKay Sievers 	env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
11807eff2e7aSKay Sievers 	if (!env)
1181c7308c81SGreg Kroah-Hartman 		return -ENOMEM;
1182c7308c81SGreg Kroah-Hartman 
118316574dccSKay Sievers 	/* let the kset specific function add its keys */
11847eff2e7aSKay Sievers 	retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
118516574dccSKay Sievers 	if (retval)
118616574dccSKay Sievers 		goto out;
118716574dccSKay Sievers 
118816574dccSKay Sievers 	/* copy keys to file */
11897eff2e7aSKay Sievers 	for (i = 0; i < env->envp_idx; i++)
11907eff2e7aSKay Sievers 		count += sprintf(&buf[count], "%s\n", env->envp[i]);
119116574dccSKay Sievers out:
11927eff2e7aSKay Sievers 	kfree(env);
119316574dccSKay Sievers 	return count;
119416574dccSKay Sievers }
119516574dccSKay Sievers 
1196c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
1197a7fd6706SKay Sievers 			    const char *buf, size_t count)
1198a7fd6706SKay Sievers {
1199df44b479SPeter Rajnoha 	int rc;
1200df44b479SPeter Rajnoha 
1201df44b479SPeter Rajnoha 	rc = kobject_synth_uevent(&dev->kobj, buf, count);
1202df44b479SPeter Rajnoha 
1203df44b479SPeter Rajnoha 	if (rc) {
1204f36776faSPeter Rajnoha 		dev_err(dev, "uevent: failed to send synthetic uevent\n");
1205df44b479SPeter Rajnoha 		return rc;
1206df44b479SPeter Rajnoha 	}
120760a96a59SKay Sievers 
1208a7fd6706SKay Sievers 	return count;
1209a7fd6706SKay Sievers }
1210c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent);
1211a7fd6706SKay Sievers 
1212c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr,
12134f3549d7SRafael J. Wysocki 			   char *buf)
12144f3549d7SRafael J. Wysocki {
12154f3549d7SRafael J. Wysocki 	bool val;
12164f3549d7SRafael J. Wysocki 
12175e33bc41SRafael J. Wysocki 	device_lock(dev);
12184f3549d7SRafael J. Wysocki 	val = !dev->offline;
12195e33bc41SRafael J. Wysocki 	device_unlock(dev);
12204f3549d7SRafael J. Wysocki 	return sprintf(buf, "%u\n", val);
12214f3549d7SRafael J. Wysocki }
12224f3549d7SRafael J. Wysocki 
1223c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr,
12244f3549d7SRafael J. Wysocki 			    const char *buf, size_t count)
12254f3549d7SRafael J. Wysocki {
12264f3549d7SRafael J. Wysocki 	bool val;
12274f3549d7SRafael J. Wysocki 	int ret;
12284f3549d7SRafael J. Wysocki 
12294f3549d7SRafael J. Wysocki 	ret = strtobool(buf, &val);
12304f3549d7SRafael J. Wysocki 	if (ret < 0)
12314f3549d7SRafael J. Wysocki 		return ret;
12324f3549d7SRafael J. Wysocki 
12335e33bc41SRafael J. Wysocki 	ret = lock_device_hotplug_sysfs();
12345e33bc41SRafael J. Wysocki 	if (ret)
12355e33bc41SRafael J. Wysocki 		return ret;
12365e33bc41SRafael J. Wysocki 
12374f3549d7SRafael J. Wysocki 	ret = val ? device_online(dev) : device_offline(dev);
12384f3549d7SRafael J. Wysocki 	unlock_device_hotplug();
12394f3549d7SRafael J. Wysocki 	return ret < 0 ? ret : count;
12404f3549d7SRafael J. Wysocki }
1241c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online);
12424f3549d7SRafael J. Wysocki 
1243fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups)
1244621a1672SDmitry Torokhov {
12453e9b2baeSGreg Kroah-Hartman 	return sysfs_create_groups(&dev->kobj, groups);
1246621a1672SDmitry Torokhov }
1247a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_add_groups);
1248621a1672SDmitry Torokhov 
1249fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev,
1250a4dbd674SDavid Brownell 			  const struct attribute_group **groups)
1251621a1672SDmitry Torokhov {
12523e9b2baeSGreg Kroah-Hartman 	sysfs_remove_groups(&dev->kobj, groups);
1253621a1672SDmitry Torokhov }
1254a7670d42SDmitry Torokhov EXPORT_SYMBOL_GPL(device_remove_groups);
1255de0ff00dSGreg Kroah-Hartman 
125657b8ff07SDmitry Torokhov union device_attr_group_devres {
125757b8ff07SDmitry Torokhov 	const struct attribute_group *group;
125857b8ff07SDmitry Torokhov 	const struct attribute_group **groups;
125957b8ff07SDmitry Torokhov };
126057b8ff07SDmitry Torokhov 
126157b8ff07SDmitry Torokhov static int devm_attr_group_match(struct device *dev, void *res, void *data)
126257b8ff07SDmitry Torokhov {
126357b8ff07SDmitry Torokhov 	return ((union device_attr_group_devres *)res)->group == data;
126457b8ff07SDmitry Torokhov }
126557b8ff07SDmitry Torokhov 
126657b8ff07SDmitry Torokhov static void devm_attr_group_remove(struct device *dev, void *res)
126757b8ff07SDmitry Torokhov {
126857b8ff07SDmitry Torokhov 	union device_attr_group_devres *devres = res;
126957b8ff07SDmitry Torokhov 	const struct attribute_group *group = devres->group;
127057b8ff07SDmitry Torokhov 
127157b8ff07SDmitry Torokhov 	dev_dbg(dev, "%s: removing group %p\n", __func__, group);
127257b8ff07SDmitry Torokhov 	sysfs_remove_group(&dev->kobj, group);
127357b8ff07SDmitry Torokhov }
127457b8ff07SDmitry Torokhov 
127557b8ff07SDmitry Torokhov static void devm_attr_groups_remove(struct device *dev, void *res)
127657b8ff07SDmitry Torokhov {
127757b8ff07SDmitry Torokhov 	union device_attr_group_devres *devres = res;
127857b8ff07SDmitry Torokhov 	const struct attribute_group **groups = devres->groups;
127957b8ff07SDmitry Torokhov 
128057b8ff07SDmitry Torokhov 	dev_dbg(dev, "%s: removing groups %p\n", __func__, groups);
128157b8ff07SDmitry Torokhov 	sysfs_remove_groups(&dev->kobj, groups);
128257b8ff07SDmitry Torokhov }
128357b8ff07SDmitry Torokhov 
128457b8ff07SDmitry Torokhov /**
128557b8ff07SDmitry Torokhov  * devm_device_add_group - given a device, create a managed attribute group
128657b8ff07SDmitry Torokhov  * @dev:	The device to create the group for
128757b8ff07SDmitry Torokhov  * @grp:	The attribute group to create
128857b8ff07SDmitry Torokhov  *
128957b8ff07SDmitry Torokhov  * This function creates a group for the first time.  It will explicitly
129057b8ff07SDmitry Torokhov  * warn and error if any of the attribute files being created already exist.
129157b8ff07SDmitry Torokhov  *
129257b8ff07SDmitry Torokhov  * Returns 0 on success or error code on failure.
129357b8ff07SDmitry Torokhov  */
129457b8ff07SDmitry Torokhov int devm_device_add_group(struct device *dev, const struct attribute_group *grp)
129557b8ff07SDmitry Torokhov {
129657b8ff07SDmitry Torokhov 	union device_attr_group_devres *devres;
129757b8ff07SDmitry Torokhov 	int error;
129857b8ff07SDmitry Torokhov 
129957b8ff07SDmitry Torokhov 	devres = devres_alloc(devm_attr_group_remove,
130057b8ff07SDmitry Torokhov 			      sizeof(*devres), GFP_KERNEL);
130157b8ff07SDmitry Torokhov 	if (!devres)
130257b8ff07SDmitry Torokhov 		return -ENOMEM;
130357b8ff07SDmitry Torokhov 
130457b8ff07SDmitry Torokhov 	error = sysfs_create_group(&dev->kobj, grp);
130557b8ff07SDmitry Torokhov 	if (error) {
130657b8ff07SDmitry Torokhov 		devres_free(devres);
130757b8ff07SDmitry Torokhov 		return error;
130857b8ff07SDmitry Torokhov 	}
130957b8ff07SDmitry Torokhov 
131057b8ff07SDmitry Torokhov 	devres->group = grp;
131157b8ff07SDmitry Torokhov 	devres_add(dev, devres);
131257b8ff07SDmitry Torokhov 	return 0;
131357b8ff07SDmitry Torokhov }
131457b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_group);
131557b8ff07SDmitry Torokhov 
131657b8ff07SDmitry Torokhov /**
131757b8ff07SDmitry Torokhov  * devm_device_remove_group: remove a managed group from a device
131857b8ff07SDmitry Torokhov  * @dev:	device to remove the group from
131957b8ff07SDmitry Torokhov  * @grp:	group to remove
132057b8ff07SDmitry Torokhov  *
132157b8ff07SDmitry Torokhov  * This function removes a group of attributes from a device. The attributes
132257b8ff07SDmitry Torokhov  * previously have to have been created for this group, otherwise it will fail.
132357b8ff07SDmitry Torokhov  */
132457b8ff07SDmitry Torokhov void devm_device_remove_group(struct device *dev,
132557b8ff07SDmitry Torokhov 			      const struct attribute_group *grp)
132657b8ff07SDmitry Torokhov {
132757b8ff07SDmitry Torokhov 	WARN_ON(devres_release(dev, devm_attr_group_remove,
132857b8ff07SDmitry Torokhov 			       devm_attr_group_match,
132957b8ff07SDmitry Torokhov 			       /* cast away const */ (void *)grp));
133057b8ff07SDmitry Torokhov }
133157b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_group);
133257b8ff07SDmitry Torokhov 
133357b8ff07SDmitry Torokhov /**
133457b8ff07SDmitry Torokhov  * devm_device_add_groups - create a bunch of managed attribute groups
133557b8ff07SDmitry Torokhov  * @dev:	The device to create the group for
133657b8ff07SDmitry Torokhov  * @groups:	The attribute groups to create, NULL terminated
133757b8ff07SDmitry Torokhov  *
133857b8ff07SDmitry Torokhov  * This function creates a bunch of managed attribute groups.  If an error
133957b8ff07SDmitry Torokhov  * occurs when creating a group, all previously created groups will be
134057b8ff07SDmitry Torokhov  * removed, unwinding everything back to the original state when this
134157b8ff07SDmitry Torokhov  * function was called.  It will explicitly warn and error if any of the
134257b8ff07SDmitry Torokhov  * attribute files being created already exist.
134357b8ff07SDmitry Torokhov  *
134457b8ff07SDmitry Torokhov  * Returns 0 on success or error code from sysfs_create_group on failure.
134557b8ff07SDmitry Torokhov  */
134657b8ff07SDmitry Torokhov int devm_device_add_groups(struct device *dev,
134757b8ff07SDmitry Torokhov 			   const struct attribute_group **groups)
134857b8ff07SDmitry Torokhov {
134957b8ff07SDmitry Torokhov 	union device_attr_group_devres *devres;
135057b8ff07SDmitry Torokhov 	int error;
135157b8ff07SDmitry Torokhov 
135257b8ff07SDmitry Torokhov 	devres = devres_alloc(devm_attr_groups_remove,
135357b8ff07SDmitry Torokhov 			      sizeof(*devres), GFP_KERNEL);
135457b8ff07SDmitry Torokhov 	if (!devres)
135557b8ff07SDmitry Torokhov 		return -ENOMEM;
135657b8ff07SDmitry Torokhov 
135757b8ff07SDmitry Torokhov 	error = sysfs_create_groups(&dev->kobj, groups);
135857b8ff07SDmitry Torokhov 	if (error) {
135957b8ff07SDmitry Torokhov 		devres_free(devres);
136057b8ff07SDmitry Torokhov 		return error;
136157b8ff07SDmitry Torokhov 	}
136257b8ff07SDmitry Torokhov 
136357b8ff07SDmitry Torokhov 	devres->groups = groups;
136457b8ff07SDmitry Torokhov 	devres_add(dev, devres);
136557b8ff07SDmitry Torokhov 	return 0;
136657b8ff07SDmitry Torokhov }
136757b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_add_groups);
136857b8ff07SDmitry Torokhov 
136957b8ff07SDmitry Torokhov /**
137057b8ff07SDmitry Torokhov  * devm_device_remove_groups - remove a list of managed groups
137157b8ff07SDmitry Torokhov  *
137257b8ff07SDmitry Torokhov  * @dev:	The device for the groups to be removed from
137357b8ff07SDmitry Torokhov  * @groups:	NULL terminated list of groups to be removed
137457b8ff07SDmitry Torokhov  *
137557b8ff07SDmitry Torokhov  * If groups is not NULL, remove the specified groups from the device.
137657b8ff07SDmitry Torokhov  */
137757b8ff07SDmitry Torokhov void devm_device_remove_groups(struct device *dev,
137857b8ff07SDmitry Torokhov 			       const struct attribute_group **groups)
137957b8ff07SDmitry Torokhov {
138057b8ff07SDmitry Torokhov 	WARN_ON(devres_release(dev, devm_attr_groups_remove,
138157b8ff07SDmitry Torokhov 			       devm_attr_group_match,
138257b8ff07SDmitry Torokhov 			       /* cast away const */ (void *)groups));
138357b8ff07SDmitry Torokhov }
138457b8ff07SDmitry Torokhov EXPORT_SYMBOL_GPL(devm_device_remove_groups);
13851da177e4SLinus Torvalds 
13862620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev)
13872620efefSGreg Kroah-Hartman {
13882620efefSGreg Kroah-Hartman 	struct class *class = dev->class;
1389aed65af1SStephen Hemminger 	const struct device_type *type = dev->type;
1390621a1672SDmitry Torokhov 	int error;
13912620efefSGreg Kroah-Hartman 
1392621a1672SDmitry Torokhov 	if (class) {
1393d05a6f96SGreg Kroah-Hartman 		error = device_add_groups(dev, class->dev_groups);
13942620efefSGreg Kroah-Hartman 		if (error)
1395621a1672SDmitry Torokhov 			return error;
1396f9f852dfSKay Sievers 	}
1397f9f852dfSKay Sievers 
1398621a1672SDmitry Torokhov 	if (type) {
1399621a1672SDmitry Torokhov 		error = device_add_groups(dev, type->groups);
1400f9f852dfSKay Sievers 		if (error)
1401a6b01dedSGreg Kroah-Hartman 			goto err_remove_class_groups;
1402f9f852dfSKay Sievers 	}
1403621a1672SDmitry Torokhov 
1404621a1672SDmitry Torokhov 	error = device_add_groups(dev, dev->groups);
1405f9f852dfSKay Sievers 	if (error)
1406621a1672SDmitry Torokhov 		goto err_remove_type_groups;
1407621a1672SDmitry Torokhov 
14084f3549d7SRafael J. Wysocki 	if (device_supports_offline(dev) && !dev->offline_disabled) {
1409c5e064a6SGreg Kroah-Hartman 		error = device_create_file(dev, &dev_attr_online);
14104f3549d7SRafael J. Wysocki 		if (error)
1411ecfbf6fdSRafael J. Wysocki 			goto err_remove_dev_groups;
14124f3549d7SRafael J. Wysocki 	}
14134f3549d7SRafael J. Wysocki 
1414621a1672SDmitry Torokhov 	return 0;
1415621a1672SDmitry Torokhov 
1416ecfbf6fdSRafael J. Wysocki  err_remove_dev_groups:
1417ecfbf6fdSRafael J. Wysocki 	device_remove_groups(dev, dev->groups);
1418621a1672SDmitry Torokhov  err_remove_type_groups:
1419621a1672SDmitry Torokhov 	if (type)
1420621a1672SDmitry Torokhov 		device_remove_groups(dev, type->groups);
1421d05a6f96SGreg Kroah-Hartman  err_remove_class_groups:
1422d05a6f96SGreg Kroah-Hartman 	if (class)
1423d05a6f96SGreg Kroah-Hartman 		device_remove_groups(dev, class->dev_groups);
1424f9f852dfSKay Sievers 
14252620efefSGreg Kroah-Hartman 	return error;
14262620efefSGreg Kroah-Hartman }
14272620efefSGreg Kroah-Hartman 
14282620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev)
14292620efefSGreg Kroah-Hartman {
14302620efefSGreg Kroah-Hartman 	struct class *class = dev->class;
1431aed65af1SStephen Hemminger 	const struct device_type *type = dev->type;
14322620efefSGreg Kroah-Hartman 
1433c5e064a6SGreg Kroah-Hartman 	device_remove_file(dev, &dev_attr_online);
1434621a1672SDmitry Torokhov 	device_remove_groups(dev, dev->groups);
1435f9f852dfSKay Sievers 
1436621a1672SDmitry Torokhov 	if (type)
1437621a1672SDmitry Torokhov 		device_remove_groups(dev, type->groups);
1438621a1672SDmitry Torokhov 
1439a6b01dedSGreg Kroah-Hartman 	if (class)
1440d05a6f96SGreg Kroah-Hartman 		device_remove_groups(dev, class->dev_groups);
1441c97415a7SStefan Achatz }
14422620efefSGreg Kroah-Hartman 
1443c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr,
144423681e47SGreg Kroah-Hartman 			char *buf)
144523681e47SGreg Kroah-Hartman {
144623681e47SGreg Kroah-Hartman 	return print_dev_t(buf, dev->devt);
144723681e47SGreg Kroah-Hartman }
1448c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev);
1449ad6a1e1cSTejun Heo 
1450ca22e56dSKay Sievers /* /sys/devices/ */
1451881c6cfdSGreg Kroah-Hartman struct kset *devices_kset;
14521da177e4SLinus Torvalds 
14531da177e4SLinus Torvalds /**
145452cdbdd4SGrygorii Strashko  * devices_kset_move_before - Move device in the devices_kset's list.
145552cdbdd4SGrygorii Strashko  * @deva: Device to move.
145652cdbdd4SGrygorii Strashko  * @devb: Device @deva should come before.
145752cdbdd4SGrygorii Strashko  */
145852cdbdd4SGrygorii Strashko static void devices_kset_move_before(struct device *deva, struct device *devb)
145952cdbdd4SGrygorii Strashko {
146052cdbdd4SGrygorii Strashko 	if (!devices_kset)
146152cdbdd4SGrygorii Strashko 		return;
146252cdbdd4SGrygorii Strashko 	pr_debug("devices_kset: Moving %s before %s\n",
146352cdbdd4SGrygorii Strashko 		 dev_name(deva), dev_name(devb));
146452cdbdd4SGrygorii Strashko 	spin_lock(&devices_kset->list_lock);
146552cdbdd4SGrygorii Strashko 	list_move_tail(&deva->kobj.entry, &devb->kobj.entry);
146652cdbdd4SGrygorii Strashko 	spin_unlock(&devices_kset->list_lock);
146752cdbdd4SGrygorii Strashko }
146852cdbdd4SGrygorii Strashko 
146952cdbdd4SGrygorii Strashko /**
147052cdbdd4SGrygorii Strashko  * devices_kset_move_after - Move device in the devices_kset's list.
147152cdbdd4SGrygorii Strashko  * @deva: Device to move
147252cdbdd4SGrygorii Strashko  * @devb: Device @deva should come after.
147352cdbdd4SGrygorii Strashko  */
147452cdbdd4SGrygorii Strashko static void devices_kset_move_after(struct device *deva, struct device *devb)
147552cdbdd4SGrygorii Strashko {
147652cdbdd4SGrygorii Strashko 	if (!devices_kset)
147752cdbdd4SGrygorii Strashko 		return;
147852cdbdd4SGrygorii Strashko 	pr_debug("devices_kset: Moving %s after %s\n",
147952cdbdd4SGrygorii Strashko 		 dev_name(deva), dev_name(devb));
148052cdbdd4SGrygorii Strashko 	spin_lock(&devices_kset->list_lock);
148152cdbdd4SGrygorii Strashko 	list_move(&deva->kobj.entry, &devb->kobj.entry);
148252cdbdd4SGrygorii Strashko 	spin_unlock(&devices_kset->list_lock);
148352cdbdd4SGrygorii Strashko }
148452cdbdd4SGrygorii Strashko 
148552cdbdd4SGrygorii Strashko /**
148652cdbdd4SGrygorii Strashko  * devices_kset_move_last - move the device to the end of devices_kset's list.
148752cdbdd4SGrygorii Strashko  * @dev: device to move
148852cdbdd4SGrygorii Strashko  */
148952cdbdd4SGrygorii Strashko void devices_kset_move_last(struct device *dev)
149052cdbdd4SGrygorii Strashko {
149152cdbdd4SGrygorii Strashko 	if (!devices_kset)
149252cdbdd4SGrygorii Strashko 		return;
149352cdbdd4SGrygorii Strashko 	pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev));
149452cdbdd4SGrygorii Strashko 	spin_lock(&devices_kset->list_lock);
149552cdbdd4SGrygorii Strashko 	list_move_tail(&dev->kobj.entry, &devices_kset->list);
149652cdbdd4SGrygorii Strashko 	spin_unlock(&devices_kset->list_lock);
149752cdbdd4SGrygorii Strashko }
149852cdbdd4SGrygorii Strashko 
149952cdbdd4SGrygorii Strashko /**
15001da177e4SLinus Torvalds  * device_create_file - create sysfs attribute file for device.
15011da177e4SLinus Torvalds  * @dev: device.
15021da177e4SLinus Torvalds  * @attr: device attribute descriptor.
15031da177e4SLinus Torvalds  */
150426579ab7SPhil Carmody int device_create_file(struct device *dev,
150526579ab7SPhil Carmody 		       const struct device_attribute *attr)
15061da177e4SLinus Torvalds {
15071da177e4SLinus Torvalds 	int error = 0;
15088f46baaaSFelipe Balbi 
15098f46baaaSFelipe Balbi 	if (dev) {
15108f46baaaSFelipe Balbi 		WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
151197521978Sdyoung@redhat.com 			"Attribute %s: write permission without 'store'\n",
151297521978Sdyoung@redhat.com 			attr->attr.name);
15138f46baaaSFelipe Balbi 		WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
151497521978Sdyoung@redhat.com 			"Attribute %s: read permission without 'show'\n",
151597521978Sdyoung@redhat.com 			attr->attr.name);
15161da177e4SLinus Torvalds 		error = sysfs_create_file(&dev->kobj, &attr->attr);
15178f46baaaSFelipe Balbi 	}
15188f46baaaSFelipe Balbi 
15191da177e4SLinus Torvalds 	return error;
15201da177e4SLinus Torvalds }
152186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file);
15221da177e4SLinus Torvalds 
15231da177e4SLinus Torvalds /**
15241da177e4SLinus Torvalds  * device_remove_file - remove sysfs attribute file.
15251da177e4SLinus Torvalds  * @dev: device.
15261da177e4SLinus Torvalds  * @attr: device attribute descriptor.
15271da177e4SLinus Torvalds  */
152826579ab7SPhil Carmody void device_remove_file(struct device *dev,
152926579ab7SPhil Carmody 			const struct device_attribute *attr)
15301da177e4SLinus Torvalds {
15310c98b19fSCornelia Huck 	if (dev)
15321da177e4SLinus Torvalds 		sysfs_remove_file(&dev->kobj, &attr->attr);
15331da177e4SLinus Torvalds }
153486df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file);
15351da177e4SLinus Torvalds 
15362589f188SGreg Kroah-Hartman /**
15376b0afc2aSTejun Heo  * device_remove_file_self - remove sysfs attribute file from its own method.
15386b0afc2aSTejun Heo  * @dev: device.
15396b0afc2aSTejun Heo  * @attr: device attribute descriptor.
15406b0afc2aSTejun Heo  *
15416b0afc2aSTejun Heo  * See kernfs_remove_self() for details.
15426b0afc2aSTejun Heo  */
15436b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev,
15446b0afc2aSTejun Heo 			     const struct device_attribute *attr)
15456b0afc2aSTejun Heo {
15466b0afc2aSTejun Heo 	if (dev)
15476b0afc2aSTejun Heo 		return sysfs_remove_file_self(&dev->kobj, &attr->attr);
15486b0afc2aSTejun Heo 	else
15496b0afc2aSTejun Heo 		return false;
15506b0afc2aSTejun Heo }
15516b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self);
15526b0afc2aSTejun Heo 
15536b0afc2aSTejun Heo /**
15542589f188SGreg Kroah-Hartman  * device_create_bin_file - create sysfs binary attribute file for device.
15552589f188SGreg Kroah-Hartman  * @dev: device.
15562589f188SGreg Kroah-Hartman  * @attr: device binary attribute descriptor.
15572589f188SGreg Kroah-Hartman  */
155866ecb92bSPhil Carmody int device_create_bin_file(struct device *dev,
155966ecb92bSPhil Carmody 			   const struct bin_attribute *attr)
15602589f188SGreg Kroah-Hartman {
15612589f188SGreg Kroah-Hartman 	int error = -EINVAL;
15622589f188SGreg Kroah-Hartman 	if (dev)
15632589f188SGreg Kroah-Hartman 		error = sysfs_create_bin_file(&dev->kobj, attr);
15642589f188SGreg Kroah-Hartman 	return error;
15652589f188SGreg Kroah-Hartman }
15662589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file);
15672589f188SGreg Kroah-Hartman 
15682589f188SGreg Kroah-Hartman /**
15692589f188SGreg Kroah-Hartman  * device_remove_bin_file - remove sysfs binary attribute file
15702589f188SGreg Kroah-Hartman  * @dev: device.
15712589f188SGreg Kroah-Hartman  * @attr: device binary attribute descriptor.
15722589f188SGreg Kroah-Hartman  */
157366ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev,
157466ecb92bSPhil Carmody 			    const struct bin_attribute *attr)
15752589f188SGreg Kroah-Hartman {
15762589f188SGreg Kroah-Hartman 	if (dev)
15772589f188SGreg Kroah-Hartman 		sysfs_remove_bin_file(&dev->kobj, attr);
15782589f188SGreg Kroah-Hartman }
15792589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file);
15802589f188SGreg Kroah-Hartman 
158134bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n)
158234bb61f9SJames Bottomley {
1583f791b8c8SGreg Kroah-Hartman 	struct device_private *p = to_device_private_parent(n);
1584f791b8c8SGreg Kroah-Hartman 	struct device *dev = p->device;
158534bb61f9SJames Bottomley 
158634bb61f9SJames Bottomley 	get_device(dev);
158734bb61f9SJames Bottomley }
158834bb61f9SJames Bottomley 
158934bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n)
159034bb61f9SJames Bottomley {
1591f791b8c8SGreg Kroah-Hartman 	struct device_private *p = to_device_private_parent(n);
1592f791b8c8SGreg Kroah-Hartman 	struct device *dev = p->device;
159334bb61f9SJames Bottomley 
159434bb61f9SJames Bottomley 	put_device(dev);
159534bb61f9SJames Bottomley }
159634bb61f9SJames Bottomley 
15971da177e4SLinus Torvalds /**
15981da177e4SLinus Torvalds  * device_initialize - init device structure.
15991da177e4SLinus Torvalds  * @dev: device.
16001da177e4SLinus Torvalds  *
16015739411aSCornelia Huck  * This prepares the device for use by other layers by initializing
16025739411aSCornelia Huck  * its fields.
16031da177e4SLinus Torvalds  * It is the first half of device_register(), if called by
16045739411aSCornelia Huck  * that function, though it can also be called separately, so one
16055739411aSCornelia Huck  * may use @dev's fields. In particular, get_device()/put_device()
16065739411aSCornelia Huck  * may be used for reference counting of @dev after calling this
16075739411aSCornelia Huck  * function.
16085739411aSCornelia Huck  *
1609b10d5efdSAlan Stern  * All fields in @dev must be initialized by the caller to 0, except
1610b10d5efdSAlan Stern  * for those explicitly set to some other value.  The simplest
1611b10d5efdSAlan Stern  * approach is to use kzalloc() to allocate the structure containing
1612b10d5efdSAlan Stern  * @dev.
1613b10d5efdSAlan Stern  *
16145739411aSCornelia Huck  * NOTE: Use put_device() to give up your reference instead of freeing
16155739411aSCornelia Huck  * @dev directly once you have called this function.
16161da177e4SLinus Torvalds  */
16171da177e4SLinus Torvalds void device_initialize(struct device *dev)
16181da177e4SLinus Torvalds {
1619881c6cfdSGreg Kroah-Hartman 	dev->kobj.kset = devices_kset;
1620f9cb074bSGreg Kroah-Hartman 	kobject_init(&dev->kobj, &device_ktype);
16211da177e4SLinus Torvalds 	INIT_LIST_HEAD(&dev->dma_pools);
16223142788bSThomas Gleixner 	mutex_init(&dev->mutex);
16231704f47bSPeter Zijlstra 	lockdep_set_novalidate_class(&dev->mutex);
16249ac7849eSTejun Heo 	spin_lock_init(&dev->devres_lock);
16259ac7849eSTejun Heo 	INIT_LIST_HEAD(&dev->devres_head);
16263b98aeafSAlan Stern 	device_pm_init(dev);
162787348136SChristoph Hellwig 	set_dev_node(dev, -1);
16284a7cc831SJiang Liu #ifdef CONFIG_GENERIC_MSI_IRQ
16294a7cc831SJiang Liu 	INIT_LIST_HEAD(&dev->msi_list);
16304a7cc831SJiang Liu #endif
16319ed98953SRafael J. Wysocki 	INIT_LIST_HEAD(&dev->links.consumers);
16329ed98953SRafael J. Wysocki 	INIT_LIST_HEAD(&dev->links.suppliers);
16339ed98953SRafael J. Wysocki 	dev->links.status = DL_DEV_NO_DRIVER;
16341da177e4SLinus Torvalds }
163586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize);
16361da177e4SLinus Torvalds 
1637d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev)
1638f0ee61a6SGreg Kroah-Hartman {
1639f0ee61a6SGreg Kroah-Hartman 	static struct kobject *virtual_dir = NULL;
1640f0ee61a6SGreg Kroah-Hartman 
1641f0ee61a6SGreg Kroah-Hartman 	if (!virtual_dir)
16424ff6abffSGreg Kroah-Hartman 		virtual_dir = kobject_create_and_add("virtual",
1643881c6cfdSGreg Kroah-Hartman 						     &devices_kset->kobj);
1644f0ee61a6SGreg Kroah-Hartman 
164586406245SKay Sievers 	return virtual_dir;
1646f0ee61a6SGreg Kroah-Hartman }
1647f0ee61a6SGreg Kroah-Hartman 
1648bc451f20SEric W. Biederman struct class_dir {
1649bc451f20SEric W. Biederman 	struct kobject kobj;
1650bc451f20SEric W. Biederman 	struct class *class;
1651bc451f20SEric W. Biederman };
1652bc451f20SEric W. Biederman 
1653bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj)
1654bc451f20SEric W. Biederman 
1655bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj)
1656bc451f20SEric W. Biederman {
1657bc451f20SEric W. Biederman 	struct class_dir *dir = to_class_dir(kobj);
1658bc451f20SEric W. Biederman 	kfree(dir);
1659bc451f20SEric W. Biederman }
1660bc451f20SEric W. Biederman 
1661bc451f20SEric W. Biederman static const
1662bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj)
1663bc451f20SEric W. Biederman {
1664bc451f20SEric W. Biederman 	struct class_dir *dir = to_class_dir(kobj);
1665bc451f20SEric W. Biederman 	return dir->class->ns_type;
1666bc451f20SEric W. Biederman }
1667bc451f20SEric W. Biederman 
1668bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = {
1669bc451f20SEric W. Biederman 	.release	= class_dir_release,
1670bc451f20SEric W. Biederman 	.sysfs_ops	= &kobj_sysfs_ops,
1671bc451f20SEric W. Biederman 	.child_ns_type	= class_dir_child_ns_type
1672bc451f20SEric W. Biederman };
1673bc451f20SEric W. Biederman 
1674bc451f20SEric W. Biederman static struct kobject *
1675bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
1676bc451f20SEric W. Biederman {
1677bc451f20SEric W. Biederman 	struct class_dir *dir;
1678bc451f20SEric W. Biederman 	int retval;
1679bc451f20SEric W. Biederman 
1680bc451f20SEric W. Biederman 	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
1681bc451f20SEric W. Biederman 	if (!dir)
168284d0c27dSTetsuo Handa 		return ERR_PTR(-ENOMEM);
1683bc451f20SEric W. Biederman 
1684bc451f20SEric W. Biederman 	dir->class = class;
1685bc451f20SEric W. Biederman 	kobject_init(&dir->kobj, &class_dir_ktype);
1686bc451f20SEric W. Biederman 
16876b6e39a6SKay Sievers 	dir->kobj.kset = &class->p->glue_dirs;
1688bc451f20SEric W. Biederman 
1689bc451f20SEric W. Biederman 	retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
1690bc451f20SEric W. Biederman 	if (retval < 0) {
1691bc451f20SEric W. Biederman 		kobject_put(&dir->kobj);
169284d0c27dSTetsuo Handa 		return ERR_PTR(retval);
1693bc451f20SEric W. Biederman 	}
1694bc451f20SEric W. Biederman 	return &dir->kobj;
1695bc451f20SEric W. Biederman }
1696bc451f20SEric W. Biederman 
1697e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex);
1698bc451f20SEric W. Biederman 
1699c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev,
1700c744aeaeSCornelia Huck 					 struct device *parent)
170140fa5422SGreg Kroah-Hartman {
170286406245SKay Sievers 	if (dev->class) {
170386406245SKay Sievers 		struct kobject *kobj = NULL;
170486406245SKay Sievers 		struct kobject *parent_kobj;
170586406245SKay Sievers 		struct kobject *k;
170686406245SKay Sievers 
1707ead454feSRandy Dunlap #ifdef CONFIG_BLOCK
170839aba963SKay Sievers 		/* block disks show up in /sys/block */
1709e52eec13SAndi Kleen 		if (sysfs_deprecated && dev->class == &block_class) {
171039aba963SKay Sievers 			if (parent && parent->class == &block_class)
171139aba963SKay Sievers 				return &parent->kobj;
17126b6e39a6SKay Sievers 			return &block_class.p->subsys.kobj;
171339aba963SKay Sievers 		}
1714ead454feSRandy Dunlap #endif
1715e52eec13SAndi Kleen 
171686406245SKay Sievers 		/*
171786406245SKay Sievers 		 * If we have no parent, we live in "virtual".
17180f4dafc0SKay Sievers 		 * Class-devices with a non class-device as parent, live
17190f4dafc0SKay Sievers 		 * in a "glue" directory to prevent namespace collisions.
172086406245SKay Sievers 		 */
172186406245SKay Sievers 		if (parent == NULL)
172286406245SKay Sievers 			parent_kobj = virtual_device_parent(dev);
172324b1442dSEric W. Biederman 		else if (parent->class && !dev->class->ns_type)
172486406245SKay Sievers 			return &parent->kobj;
172586406245SKay Sievers 		else
172686406245SKay Sievers 			parent_kobj = &parent->kobj;
172786406245SKay Sievers 
172877d3d7c1STejun Heo 		mutex_lock(&gdp_mutex);
172977d3d7c1STejun Heo 
173086406245SKay Sievers 		/* find our class-directory at the parent and reference it */
17316b6e39a6SKay Sievers 		spin_lock(&dev->class->p->glue_dirs.list_lock);
17326b6e39a6SKay Sievers 		list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry)
173386406245SKay Sievers 			if (k->parent == parent_kobj) {
173486406245SKay Sievers 				kobj = kobject_get(k);
173586406245SKay Sievers 				break;
173686406245SKay Sievers 			}
17376b6e39a6SKay Sievers 		spin_unlock(&dev->class->p->glue_dirs.list_lock);
173877d3d7c1STejun Heo 		if (kobj) {
173977d3d7c1STejun Heo 			mutex_unlock(&gdp_mutex);
174086406245SKay Sievers 			return kobj;
174177d3d7c1STejun Heo 		}
174286406245SKay Sievers 
174386406245SKay Sievers 		/* or create a new class-directory at the parent device */
1744bc451f20SEric W. Biederman 		k = class_dir_create_and_add(dev->class, parent_kobj);
17450f4dafc0SKay Sievers 		/* do not emit an uevent for this simple "glue" directory */
174677d3d7c1STejun Heo 		mutex_unlock(&gdp_mutex);
174743968d2fSGreg Kroah-Hartman 		return k;
174886406245SKay Sievers 	}
174986406245SKay Sievers 
1750ca22e56dSKay Sievers 	/* subsystems can specify a default root directory for their devices */
1751ca22e56dSKay Sievers 	if (!parent && dev->bus && dev->bus->dev_root)
1752ca22e56dSKay Sievers 		return &dev->bus->dev_root->kobj;
1753ca22e56dSKay Sievers 
175486406245SKay Sievers 	if (parent)
1755c744aeaeSCornelia Huck 		return &parent->kobj;
1756c744aeaeSCornelia Huck 	return NULL;
1757c744aeaeSCornelia Huck }
1758da231fd5SKay Sievers 
1759cebf8fd1SMing Lei static inline bool live_in_glue_dir(struct kobject *kobj,
1760cebf8fd1SMing Lei 				    struct device *dev)
1761cebf8fd1SMing Lei {
1762cebf8fd1SMing Lei 	if (!kobj || !dev->class ||
1763cebf8fd1SMing Lei 	    kobj->kset != &dev->class->p->glue_dirs)
1764cebf8fd1SMing Lei 		return false;
1765cebf8fd1SMing Lei 	return true;
1766cebf8fd1SMing Lei }
1767cebf8fd1SMing Lei 
1768cebf8fd1SMing Lei static inline struct kobject *get_glue_dir(struct device *dev)
1769cebf8fd1SMing Lei {
1770cebf8fd1SMing Lei 	return dev->kobj.parent;
1771cebf8fd1SMing Lei }
1772cebf8fd1SMing Lei 
1773cebf8fd1SMing Lei /*
1774cebf8fd1SMing Lei  * make sure cleaning up dir as the last step, we need to make
1775cebf8fd1SMing Lei  * sure .release handler of kobject is run with holding the
1776cebf8fd1SMing Lei  * global lock
1777cebf8fd1SMing Lei  */
177863b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
1779da231fd5SKay Sievers {
17800f4dafc0SKay Sievers 	/* see if we live in a "glue" directory */
1781cebf8fd1SMing Lei 	if (!live_in_glue_dir(glue_dir, dev))
1782da231fd5SKay Sievers 		return;
1783da231fd5SKay Sievers 
1784e4a60d13SYijing Wang 	mutex_lock(&gdp_mutex);
1785726e4109SBenjamin Herrenschmidt 	if (!kobject_has_children(glue_dir))
1786726e4109SBenjamin Herrenschmidt 		kobject_del(glue_dir);
17870f4dafc0SKay Sievers 	kobject_put(glue_dir);
1788e4a60d13SYijing Wang 	mutex_unlock(&gdp_mutex);
1789da231fd5SKay Sievers }
179063b6971aSCornelia Huck 
17912ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev)
17922ee97cafSCornelia Huck {
17935590f319SBenjamin Herrenschmidt 	struct device_node *of_node = dev_of_node(dev);
17942ee97cafSCornelia Huck 	int error;
17952ee97cafSCornelia Huck 
17965590f319SBenjamin Herrenschmidt 	if (of_node) {
17970c3c234bSRob Herring 		error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node");
17985590f319SBenjamin Herrenschmidt 		if (error)
17995590f319SBenjamin Herrenschmidt 			dev_warn(dev, "Error %d creating of_node link\n",error);
18005590f319SBenjamin Herrenschmidt 		/* An error here doesn't warrant bringing down the device */
18015590f319SBenjamin Herrenschmidt 	}
18025590f319SBenjamin Herrenschmidt 
18032ee97cafSCornelia Huck 	if (!dev->class)
18042ee97cafSCornelia Huck 		return 0;
1805da231fd5SKay Sievers 
18061fbfee6cSGreg Kroah-Hartman 	error = sysfs_create_link(&dev->kobj,
18076b6e39a6SKay Sievers 				  &dev->class->p->subsys.kobj,
18082ee97cafSCornelia Huck 				  "subsystem");
18092ee97cafSCornelia Huck 	if (error)
18105590f319SBenjamin Herrenschmidt 		goto out_devnode;
1811da231fd5SKay Sievers 
18124e886c29SGreg Kroah-Hartman 	if (dev->parent && device_is_not_partition(dev)) {
18134f01a757SDmitry Torokhov 		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
18144f01a757SDmitry Torokhov 					  "device");
18154f01a757SDmitry Torokhov 		if (error)
181639aba963SKay Sievers 			goto out_subsys;
18172ee97cafSCornelia Huck 	}
181839aba963SKay Sievers 
1819ead454feSRandy Dunlap #ifdef CONFIG_BLOCK
182039aba963SKay Sievers 	/* /sys/block has directories and does not need symlinks */
1821e52eec13SAndi Kleen 	if (sysfs_deprecated && dev->class == &block_class)
182239aba963SKay Sievers 		return 0;
1823ead454feSRandy Dunlap #endif
182439aba963SKay Sievers 
182539aba963SKay Sievers 	/* link in the class directory pointing to the device */
18266b6e39a6SKay Sievers 	error = sysfs_create_link(&dev->class->p->subsys.kobj,
182739aba963SKay Sievers 				  &dev->kobj, dev_name(dev));
182839aba963SKay Sievers 	if (error)
182939aba963SKay Sievers 		goto out_device;
183039aba963SKay Sievers 
18312ee97cafSCornelia Huck 	return 0;
18322ee97cafSCornelia Huck 
183339aba963SKay Sievers out_device:
183439aba963SKay Sievers 	sysfs_remove_link(&dev->kobj, "device");
1835da231fd5SKay Sievers 
18362ee97cafSCornelia Huck out_subsys:
18372ee97cafSCornelia Huck 	sysfs_remove_link(&dev->kobj, "subsystem");
18385590f319SBenjamin Herrenschmidt out_devnode:
18395590f319SBenjamin Herrenschmidt 	sysfs_remove_link(&dev->kobj, "of_node");
18402ee97cafSCornelia Huck 	return error;
18412ee97cafSCornelia Huck }
18422ee97cafSCornelia Huck 
18432ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev)
18442ee97cafSCornelia Huck {
18455590f319SBenjamin Herrenschmidt 	if (dev_of_node(dev))
18465590f319SBenjamin Herrenschmidt 		sysfs_remove_link(&dev->kobj, "of_node");
18475590f319SBenjamin Herrenschmidt 
18482ee97cafSCornelia Huck 	if (!dev->class)
18492ee97cafSCornelia Huck 		return;
1850da231fd5SKay Sievers 
18514e886c29SGreg Kroah-Hartman 	if (dev->parent && device_is_not_partition(dev))
1852da231fd5SKay Sievers 		sysfs_remove_link(&dev->kobj, "device");
18532ee97cafSCornelia Huck 	sysfs_remove_link(&dev->kobj, "subsystem");
1854ead454feSRandy Dunlap #ifdef CONFIG_BLOCK
1855e52eec13SAndi Kleen 	if (sysfs_deprecated && dev->class == &block_class)
185639aba963SKay Sievers 		return;
1857ead454feSRandy Dunlap #endif
18586b6e39a6SKay Sievers 	sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev));
18592ee97cafSCornelia Huck }
18602ee97cafSCornelia Huck 
18611da177e4SLinus Torvalds /**
1862413c239fSStephen Rothwell  * dev_set_name - set a device name
1863413c239fSStephen Rothwell  * @dev: device
186446232366SRandy Dunlap  * @fmt: format string for the device's name
1865413c239fSStephen Rothwell  */
1866413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...)
1867413c239fSStephen Rothwell {
1868413c239fSStephen Rothwell 	va_list vargs;
18691fa5ae85SKay Sievers 	int err;
1870413c239fSStephen Rothwell 
1871413c239fSStephen Rothwell 	va_start(vargs, fmt);
18721fa5ae85SKay Sievers 	err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
1873413c239fSStephen Rothwell 	va_end(vargs);
18741fa5ae85SKay Sievers 	return err;
1875413c239fSStephen Rothwell }
1876413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name);
1877413c239fSStephen Rothwell 
1878413c239fSStephen Rothwell /**
1879e105b8bfSDan Williams  * device_to_dev_kobj - select a /sys/dev/ directory for the device
1880e105b8bfSDan Williams  * @dev: device
1881e105b8bfSDan Williams  *
1882e105b8bfSDan Williams  * By default we select char/ for new entries.  Setting class->dev_obj
1883e105b8bfSDan Williams  * to NULL prevents an entry from being created.  class->dev_kobj must
1884e105b8bfSDan Williams  * be set (or cleared) before any devices are registered to the class
1885e105b8bfSDan Williams  * otherwise device_create_sys_dev_entry() and
18860d4e293cSPeter Korsgaard  * device_remove_sys_dev_entry() will disagree about the presence of
18870d4e293cSPeter Korsgaard  * the link.
1888e105b8bfSDan Williams  */
1889e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev)
1890e105b8bfSDan Williams {
1891e105b8bfSDan Williams 	struct kobject *kobj;
1892e105b8bfSDan Williams 
1893e105b8bfSDan Williams 	if (dev->class)
1894e105b8bfSDan Williams 		kobj = dev->class->dev_kobj;
1895e105b8bfSDan Williams 	else
1896e105b8bfSDan Williams 		kobj = sysfs_dev_char_kobj;
1897e105b8bfSDan Williams 
1898e105b8bfSDan Williams 	return kobj;
1899e105b8bfSDan Williams }
1900e105b8bfSDan Williams 
1901e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev)
1902e105b8bfSDan Williams {
1903e105b8bfSDan Williams 	struct kobject *kobj = device_to_dev_kobj(dev);
1904e105b8bfSDan Williams 	int error = 0;
1905e105b8bfSDan Williams 	char devt_str[15];
1906e105b8bfSDan Williams 
1907e105b8bfSDan Williams 	if (kobj) {
1908e105b8bfSDan Williams 		format_dev_t(devt_str, dev->devt);
1909e105b8bfSDan Williams 		error = sysfs_create_link(kobj, &dev->kobj, devt_str);
1910e105b8bfSDan Williams 	}
1911e105b8bfSDan Williams 
1912e105b8bfSDan Williams 	return error;
1913e105b8bfSDan Williams }
1914e105b8bfSDan Williams 
1915e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev)
1916e105b8bfSDan Williams {
1917e105b8bfSDan Williams 	struct kobject *kobj = device_to_dev_kobj(dev);
1918e105b8bfSDan Williams 	char devt_str[15];
1919e105b8bfSDan Williams 
1920e105b8bfSDan Williams 	if (kobj) {
1921e105b8bfSDan Williams 		format_dev_t(devt_str, dev->devt);
1922e105b8bfSDan Williams 		sysfs_remove_link(kobj, devt_str);
1923e105b8bfSDan Williams 	}
1924e105b8bfSDan Williams }
1925e105b8bfSDan Williams 
192646d3a037SShaokun Zhang static int device_private_init(struct device *dev)
1927b4028437SGreg Kroah-Hartman {
1928b4028437SGreg Kroah-Hartman 	dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
1929b4028437SGreg Kroah-Hartman 	if (!dev->p)
1930b4028437SGreg Kroah-Hartman 		return -ENOMEM;
1931b4028437SGreg Kroah-Hartman 	dev->p->device = dev;
1932b4028437SGreg Kroah-Hartman 	klist_init(&dev->p->klist_children, klist_children_get,
1933b4028437SGreg Kroah-Hartman 		   klist_children_put);
1934ef8a3fd6SGreg Kroah-Hartman 	INIT_LIST_HEAD(&dev->p->deferred_probe);
1935b4028437SGreg Kroah-Hartman 	return 0;
1936b4028437SGreg Kroah-Hartman }
1937b4028437SGreg Kroah-Hartman 
1938e105b8bfSDan Williams /**
19391da177e4SLinus Torvalds  * device_add - add device to device hierarchy.
19401da177e4SLinus Torvalds  * @dev: device.
19411da177e4SLinus Torvalds  *
19421da177e4SLinus Torvalds  * This is part 2 of device_register(), though may be called
19431da177e4SLinus Torvalds  * separately _iff_ device_initialize() has been called separately.
19441da177e4SLinus Torvalds  *
19455739411aSCornelia Huck  * This adds @dev to the kobject hierarchy via kobject_add(), adds it
19461da177e4SLinus Torvalds  * to the global and sibling lists for the device, then
19471da177e4SLinus Torvalds  * adds it to the other relevant subsystems of the driver model.
19485739411aSCornelia Huck  *
1949b10d5efdSAlan Stern  * Do not call this routine or device_register() more than once for
1950b10d5efdSAlan Stern  * any device structure.  The driver model core is not designed to work
1951b10d5efdSAlan Stern  * with devices that get unregistered and then spring back to life.
1952b10d5efdSAlan Stern  * (Among other things, it's very hard to guarantee that all references
1953b10d5efdSAlan Stern  * to the previous incarnation of @dev have been dropped.)  Allocate
1954b10d5efdSAlan Stern  * and register a fresh new struct device instead.
1955b10d5efdSAlan Stern  *
19565739411aSCornelia Huck  * NOTE: _Never_ directly free @dev after calling this function, even
19575739411aSCornelia Huck  * if it returned an error! Always use put_device() to give up your
19585739411aSCornelia Huck  * reference instead.
19591da177e4SLinus Torvalds  */
19601da177e4SLinus Torvalds int device_add(struct device *dev)
19611da177e4SLinus Torvalds {
196235dbf4efSViresh Kumar 	struct device *parent;
1963ca22e56dSKay Sievers 	struct kobject *kobj;
1964c47ed219SGreg Kroah-Hartman 	struct class_interface *class_intf;
1965c906a48aSGreg Kroah-Hartman 	int error = -EINVAL;
1966cebf8fd1SMing Lei 	struct kobject *glue_dir = NULL;
1967775b64d2SRafael J. Wysocki 
19681da177e4SLinus Torvalds 	dev = get_device(dev);
1969c906a48aSGreg Kroah-Hartman 	if (!dev)
1970c906a48aSGreg Kroah-Hartman 		goto done;
1971c906a48aSGreg Kroah-Hartman 
1972fb069a5dSGreg Kroah-Hartman 	if (!dev->p) {
1973b4028437SGreg Kroah-Hartman 		error = device_private_init(dev);
1974b4028437SGreg Kroah-Hartman 		if (error)
1975fb069a5dSGreg Kroah-Hartman 			goto done;
1976fb069a5dSGreg Kroah-Hartman 	}
1977fb069a5dSGreg Kroah-Hartman 
19781fa5ae85SKay Sievers 	/*
19791fa5ae85SKay Sievers 	 * for statically allocated devices, which should all be converted
19801fa5ae85SKay Sievers 	 * some day, we need to initialize the name. We prevent reading back
19811fa5ae85SKay Sievers 	 * the name, and force the use of dev_name()
19821fa5ae85SKay Sievers 	 */
19831fa5ae85SKay Sievers 	if (dev->init_name) {
1984acc0e90fSGreg Kroah-Hartman 		dev_set_name(dev, "%s", dev->init_name);
19851fa5ae85SKay Sievers 		dev->init_name = NULL;
19861fa5ae85SKay Sievers 	}
1987c906a48aSGreg Kroah-Hartman 
1988ca22e56dSKay Sievers 	/* subsystems can specify simple device enumeration */
1989ca22e56dSKay Sievers 	if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
1990ca22e56dSKay Sievers 		dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
1991ca22e56dSKay Sievers 
1992e6309e75SThomas Gleixner 	if (!dev_name(dev)) {
1993e6309e75SThomas Gleixner 		error = -EINVAL;
19945c8563d7SKay Sievers 		goto name_error;
1995e6309e75SThomas Gleixner 	}
19961da177e4SLinus Torvalds 
19971e0b2cf9SKay Sievers 	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
1998c205ef48SGreg Kroah-Hartman 
19991da177e4SLinus Torvalds 	parent = get_device(dev->parent);
2000ca22e56dSKay Sievers 	kobj = get_device_parent(dev, parent);
200184d0c27dSTetsuo Handa 	if (IS_ERR(kobj)) {
200284d0c27dSTetsuo Handa 		error = PTR_ERR(kobj);
200384d0c27dSTetsuo Handa 		goto parent_error;
200484d0c27dSTetsuo Handa 	}
2005ca22e56dSKay Sievers 	if (kobj)
2006ca22e56dSKay Sievers 		dev->kobj.parent = kobj;
20071da177e4SLinus Torvalds 
20080d358f22SYinghai Lu 	/* use parent numa_node */
200956f2de81SZhen Lei 	if (parent && (dev_to_node(dev) == NUMA_NO_NODE))
20100d358f22SYinghai Lu 		set_dev_node(dev, dev_to_node(parent));
20110d358f22SYinghai Lu 
20121da177e4SLinus Torvalds 	/* first, register with generic layer. */
20138a577ffcSKay Sievers 	/* we require the name to be set before, and pass NULL */
20148a577ffcSKay Sievers 	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
2015cebf8fd1SMing Lei 	if (error) {
2016cebf8fd1SMing Lei 		glue_dir = get_glue_dir(dev);
20171da177e4SLinus Torvalds 		goto Error;
2018cebf8fd1SMing Lei 	}
2019a7fd6706SKay Sievers 
202037022644SBrian Walsh 	/* notify platform of device entry */
202107de0e86SHeikki Krogerus 	error = device_platform_notify(dev, KOBJ_ADD);
202207de0e86SHeikki Krogerus 	if (error)
202307de0e86SHeikki Krogerus 		goto platform_error;
202437022644SBrian Walsh 
2025c5e064a6SGreg Kroah-Hartman 	error = device_create_file(dev, &dev_attr_uevent);
2026a306eea4SCornelia Huck 	if (error)
2027a306eea4SCornelia Huck 		goto attrError;
2028a7fd6706SKay Sievers 
20292ee97cafSCornelia Huck 	error = device_add_class_symlinks(dev);
20302ee97cafSCornelia Huck 	if (error)
20312ee97cafSCornelia Huck 		goto SymlinkError;
2032dc0afa83SCornelia Huck 	error = device_add_attrs(dev);
2033dc0afa83SCornelia Huck 	if (error)
20342620efefSGreg Kroah-Hartman 		goto AttrsError;
2035dc0afa83SCornelia Huck 	error = bus_add_device(dev);
2036dc0afa83SCornelia Huck 	if (error)
20371da177e4SLinus Torvalds 		goto BusError;
20383b98aeafSAlan Stern 	error = dpm_sysfs_add(dev);
203957eee3d2SRafael J. Wysocki 	if (error)
20403b98aeafSAlan Stern 		goto DPMError;
20413b98aeafSAlan Stern 	device_pm_add(dev);
2042ec0676eeSAlan Stern 
20430cd75047SSergey Klyaus 	if (MAJOR(dev->devt)) {
20440cd75047SSergey Klyaus 		error = device_create_file(dev, &dev_attr_dev);
20450cd75047SSergey Klyaus 		if (error)
20460cd75047SSergey Klyaus 			goto DevAttrError;
20470cd75047SSergey Klyaus 
20480cd75047SSergey Klyaus 		error = device_create_sys_dev_entry(dev);
20490cd75047SSergey Klyaus 		if (error)
20500cd75047SSergey Klyaus 			goto SysEntryError;
20510cd75047SSergey Klyaus 
20520cd75047SSergey Klyaus 		devtmpfs_create_node(dev);
20530cd75047SSergey Klyaus 	}
20540cd75047SSergey Klyaus 
2055ec0676eeSAlan Stern 	/* Notify clients of device addition.  This call must come
2056268863f4Smajianpeng 	 * after dpm_sysfs_add() and before kobject_uevent().
2057ec0676eeSAlan Stern 	 */
2058ec0676eeSAlan Stern 	if (dev->bus)
2059ec0676eeSAlan Stern 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
2060ec0676eeSAlan Stern 					     BUS_NOTIFY_ADD_DEVICE, dev);
2061ec0676eeSAlan Stern 
206253877d06SKay Sievers 	kobject_uevent(&dev->kobj, KOBJ_ADD);
20632023c610SAlan Stern 	bus_probe_device(dev);
20641da177e4SLinus Torvalds 	if (parent)
2065f791b8c8SGreg Kroah-Hartman 		klist_add_tail(&dev->p->knode_parent,
2066f791b8c8SGreg Kroah-Hartman 			       &parent->p->klist_children);
20671da177e4SLinus Torvalds 
20685d9fd169SGreg Kroah-Hartman 	if (dev->class) {
2069ca22e56dSKay Sievers 		mutex_lock(&dev->class->p->mutex);
2070c47ed219SGreg Kroah-Hartman 		/* tie the class to the device */
2071570d0200SWei Yang 		klist_add_tail(&dev->p->knode_class,
20726b6e39a6SKay Sievers 			       &dev->class->p->klist_devices);
2073c47ed219SGreg Kroah-Hartman 
2074c47ed219SGreg Kroah-Hartman 		/* notify any interfaces that the device is here */
2075184f1f77SGreg Kroah-Hartman 		list_for_each_entry(class_intf,
2076ca22e56dSKay Sievers 				    &dev->class->p->interfaces, node)
2077c47ed219SGreg Kroah-Hartman 			if (class_intf->add_dev)
2078c47ed219SGreg Kroah-Hartman 				class_intf->add_dev(dev, class_intf);
2079ca22e56dSKay Sievers 		mutex_unlock(&dev->class->p->mutex);
20805d9fd169SGreg Kroah-Hartman 	}
2081c906a48aSGreg Kroah-Hartman done:
20821da177e4SLinus Torvalds 	put_device(dev);
20831da177e4SLinus Torvalds 	return error;
20840cd75047SSergey Klyaus  SysEntryError:
20850cd75047SSergey Klyaus 	if (MAJOR(dev->devt))
20860cd75047SSergey Klyaus 		device_remove_file(dev, &dev_attr_dev);
20870cd75047SSergey Klyaus  DevAttrError:
20880cd75047SSergey Klyaus 	device_pm_remove(dev);
20890cd75047SSergey Klyaus 	dpm_sysfs_remove(dev);
20903b98aeafSAlan Stern  DPMError:
209157eee3d2SRafael J. Wysocki 	bus_remove_device(dev);
209257eee3d2SRafael J. Wysocki  BusError:
20932620efefSGreg Kroah-Hartman 	device_remove_attrs(dev);
20942620efefSGreg Kroah-Hartman  AttrsError:
20952ee97cafSCornelia Huck 	device_remove_class_symlinks(dev);
20962ee97cafSCornelia Huck  SymlinkError:
2097c5e064a6SGreg Kroah-Hartman 	device_remove_file(dev, &dev_attr_uevent);
209823681e47SGreg Kroah-Hartman  attrError:
209907de0e86SHeikki Krogerus 	device_platform_notify(dev, KOBJ_REMOVE);
210007de0e86SHeikki Krogerus platform_error:
2101312c004dSKay Sievers 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
2102cebf8fd1SMing Lei 	glue_dir = get_glue_dir(dev);
21031da177e4SLinus Torvalds 	kobject_del(&dev->kobj);
21041da177e4SLinus Torvalds  Error:
2105cebf8fd1SMing Lei 	cleanup_glue_dir(dev, glue_dir);
210684d0c27dSTetsuo Handa parent_error:
21071da177e4SLinus Torvalds 	put_device(parent);
21085c8563d7SKay Sievers name_error:
21095c8563d7SKay Sievers 	kfree(dev->p);
21105c8563d7SKay Sievers 	dev->p = NULL;
2111c906a48aSGreg Kroah-Hartman 	goto done;
21121da177e4SLinus Torvalds }
211386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add);
21141da177e4SLinus Torvalds 
21151da177e4SLinus Torvalds /**
21161da177e4SLinus Torvalds  * device_register - register a device with the system.
21171da177e4SLinus Torvalds  * @dev: pointer to the device structure
21181da177e4SLinus Torvalds  *
21191da177e4SLinus Torvalds  * This happens in two clean steps - initialize the device
21201da177e4SLinus Torvalds  * and add it to the system. The two steps can be called
21211da177e4SLinus Torvalds  * separately, but this is the easiest and most common.
21221da177e4SLinus Torvalds  * I.e. you should only call the two helpers separately if
21231da177e4SLinus Torvalds  * have a clearly defined need to use and refcount the device
21241da177e4SLinus Torvalds  * before it is added to the hierarchy.
21255739411aSCornelia Huck  *
2126b10d5efdSAlan Stern  * For more information, see the kerneldoc for device_initialize()
2127b10d5efdSAlan Stern  * and device_add().
2128b10d5efdSAlan Stern  *
21295739411aSCornelia Huck  * NOTE: _Never_ directly free @dev after calling this function, even
21305739411aSCornelia Huck  * if it returned an error! Always use put_device() to give up the
21315739411aSCornelia Huck  * reference initialized in this function instead.
21321da177e4SLinus Torvalds  */
21331da177e4SLinus Torvalds int device_register(struct device *dev)
21341da177e4SLinus Torvalds {
21351da177e4SLinus Torvalds 	device_initialize(dev);
21361da177e4SLinus Torvalds 	return device_add(dev);
21371da177e4SLinus Torvalds }
213886df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register);
21391da177e4SLinus Torvalds 
21401da177e4SLinus Torvalds /**
21411da177e4SLinus Torvalds  * get_device - increment reference count for device.
21421da177e4SLinus Torvalds  * @dev: device.
21431da177e4SLinus Torvalds  *
21441da177e4SLinus Torvalds  * This simply forwards the call to kobject_get(), though
21451da177e4SLinus Torvalds  * we do take care to provide for the case that we get a NULL
21461da177e4SLinus Torvalds  * pointer passed in.
21471da177e4SLinus Torvalds  */
21481da177e4SLinus Torvalds struct device *get_device(struct device *dev)
21491da177e4SLinus Torvalds {
2150b0d1f807SLars-Peter Clausen 	return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL;
21511da177e4SLinus Torvalds }
215286df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device);
21531da177e4SLinus Torvalds 
21541da177e4SLinus Torvalds /**
21551da177e4SLinus Torvalds  * put_device - decrement reference count.
21561da177e4SLinus Torvalds  * @dev: device in question.
21571da177e4SLinus Torvalds  */
21581da177e4SLinus Torvalds void put_device(struct device *dev)
21591da177e4SLinus Torvalds {
2160edfaa7c3SKay Sievers 	/* might_sleep(); */
21611da177e4SLinus Torvalds 	if (dev)
21621da177e4SLinus Torvalds 		kobject_put(&dev->kobj);
21631da177e4SLinus Torvalds }
216486df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device);
21651da177e4SLinus Torvalds 
21661da177e4SLinus Torvalds /**
21671da177e4SLinus Torvalds  * device_del - delete device from system.
21681da177e4SLinus Torvalds  * @dev: device.
21691da177e4SLinus Torvalds  *
21701da177e4SLinus Torvalds  * This is the first part of the device unregistration
21711da177e4SLinus Torvalds  * sequence. This removes the device from the lists we control
21721da177e4SLinus Torvalds  * from here, has it removed from the other driver model
21731da177e4SLinus Torvalds  * subsystems it was added to in device_add(), and removes it
21741da177e4SLinus Torvalds  * from the kobject hierarchy.
21751da177e4SLinus Torvalds  *
21761da177e4SLinus Torvalds  * NOTE: this should be called manually _iff_ device_add() was
21771da177e4SLinus Torvalds  * also called manually.
21781da177e4SLinus Torvalds  */
21791da177e4SLinus Torvalds void device_del(struct device *dev)
21801da177e4SLinus Torvalds {
21811da177e4SLinus Torvalds 	struct device *parent = dev->parent;
2182cebf8fd1SMing Lei 	struct kobject *glue_dir = NULL;
2183c47ed219SGreg Kroah-Hartman 	struct class_interface *class_intf;
21841da177e4SLinus Torvalds 
21853451a495SAlexander Duyck 	/*
21863451a495SAlexander Duyck 	 * Hold the device lock and set the "dead" flag to guarantee that
21873451a495SAlexander Duyck 	 * the update behavior is consistent with the other bitfields near
21883451a495SAlexander Duyck 	 * it and that we cannot have an asynchronous probe routine trying
21893451a495SAlexander Duyck 	 * to run while we are tearing out the bus/class/sysfs from
21903451a495SAlexander Duyck 	 * underneath the device.
21913451a495SAlexander Duyck 	 */
21923451a495SAlexander Duyck 	device_lock(dev);
21933451a495SAlexander Duyck 	dev->p->dead = true;
21943451a495SAlexander Duyck 	device_unlock(dev);
21953451a495SAlexander Duyck 
2196ec0676eeSAlan Stern 	/* Notify clients of device removal.  This call must come
2197ec0676eeSAlan Stern 	 * before dpm_sysfs_remove().
2198ec0676eeSAlan Stern 	 */
2199ec0676eeSAlan Stern 	if (dev->bus)
2200ec0676eeSAlan Stern 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
2201ec0676eeSAlan Stern 					     BUS_NOTIFY_DEL_DEVICE, dev);
22029ed98953SRafael J. Wysocki 
22033b98aeafSAlan Stern 	dpm_sysfs_remove(dev);
22041da177e4SLinus Torvalds 	if (parent)
2205f791b8c8SGreg Kroah-Hartman 		klist_del(&dev->p->knode_parent);
2206e105b8bfSDan Williams 	if (MAJOR(dev->devt)) {
22072b2af54aSKay Sievers 		devtmpfs_delete_node(dev);
2208e105b8bfSDan Williams 		device_remove_sys_dev_entry(dev);
2209c5e064a6SGreg Kroah-Hartman 		device_remove_file(dev, &dev_attr_dev);
2210e105b8bfSDan Williams 	}
2211b9d9c82bSKay Sievers 	if (dev->class) {
2212da231fd5SKay Sievers 		device_remove_class_symlinks(dev);
221399ef3ef8SKay Sievers 
2214ca22e56dSKay Sievers 		mutex_lock(&dev->class->p->mutex);
2215c47ed219SGreg Kroah-Hartman 		/* notify any interfaces that the device is now gone */
2216184f1f77SGreg Kroah-Hartman 		list_for_each_entry(class_intf,
2217ca22e56dSKay Sievers 				    &dev->class->p->interfaces, node)
2218c47ed219SGreg Kroah-Hartman 			if (class_intf->remove_dev)
2219c47ed219SGreg Kroah-Hartman 				class_intf->remove_dev(dev, class_intf);
2220c47ed219SGreg Kroah-Hartman 		/* remove the device from the class list */
2221570d0200SWei Yang 		klist_del(&dev->p->knode_class);
2222ca22e56dSKay Sievers 		mutex_unlock(&dev->class->p->mutex);
2223b9d9c82bSKay Sievers 	}
2224c5e064a6SGreg Kroah-Hartman 	device_remove_file(dev, &dev_attr_uevent);
22252620efefSGreg Kroah-Hartman 	device_remove_attrs(dev);
222628953533SBenjamin Herrenschmidt 	bus_remove_device(dev);
22274b6d1f12SLongX Zhang 	device_pm_remove(dev);
2228d1c3414cSGrant Likely 	driver_deferred_probe_del(dev);
222907de0e86SHeikki Krogerus 	device_platform_notify(dev, KOBJ_REMOVE);
2230478573c9SLukas Wunner 	device_remove_properties(dev);
22312ec16150SJeffy Chen 	device_links_purge(dev);
22321da177e4SLinus Torvalds 
2233599bad38SJoerg Roedel 	if (dev->bus)
2234599bad38SJoerg Roedel 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
2235599bad38SJoerg Roedel 					     BUS_NOTIFY_REMOVED_DEVICE, dev);
2236312c004dSKay Sievers 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
2237cebf8fd1SMing Lei 	glue_dir = get_glue_dir(dev);
22381da177e4SLinus Torvalds 	kobject_del(&dev->kobj);
2239cebf8fd1SMing Lei 	cleanup_glue_dir(dev, glue_dir);
22401da177e4SLinus Torvalds 	put_device(parent);
22411da177e4SLinus Torvalds }
224286df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del);
22431da177e4SLinus Torvalds 
22441da177e4SLinus Torvalds /**
22451da177e4SLinus Torvalds  * device_unregister - unregister device from system.
22461da177e4SLinus Torvalds  * @dev: device going away.
22471da177e4SLinus Torvalds  *
22481da177e4SLinus Torvalds  * We do this in two parts, like we do device_register(). First,
22491da177e4SLinus Torvalds  * we remove it from all the subsystems with device_del(), then
22501da177e4SLinus Torvalds  * we decrement the reference count via put_device(). If that
22511da177e4SLinus Torvalds  * is the final reference count, the device will be cleaned up
22521da177e4SLinus Torvalds  * via device_release() above. Otherwise, the structure will
22531da177e4SLinus Torvalds  * stick around until the final reference to the device is dropped.
22541da177e4SLinus Torvalds  */
22551da177e4SLinus Torvalds void device_unregister(struct device *dev)
22561da177e4SLinus Torvalds {
22571e0b2cf9SKay Sievers 	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
22581da177e4SLinus Torvalds 	device_del(dev);
22591da177e4SLinus Torvalds 	put_device(dev);
22601da177e4SLinus Torvalds }
226186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister);
22621da177e4SLinus Torvalds 
22633d060aebSAndy Shevchenko static struct device *prev_device(struct klist_iter *i)
22643d060aebSAndy Shevchenko {
22653d060aebSAndy Shevchenko 	struct klist_node *n = klist_prev(i);
22663d060aebSAndy Shevchenko 	struct device *dev = NULL;
22673d060aebSAndy Shevchenko 	struct device_private *p;
22683d060aebSAndy Shevchenko 
22693d060aebSAndy Shevchenko 	if (n) {
22703d060aebSAndy Shevchenko 		p = to_device_private_parent(n);
22713d060aebSAndy Shevchenko 		dev = p->device;
22723d060aebSAndy Shevchenko 	}
22733d060aebSAndy Shevchenko 	return dev;
22743d060aebSAndy Shevchenko }
22753d060aebSAndy Shevchenko 
227636239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i)
227736239577Smochel@digitalimplant.org {
227836239577Smochel@digitalimplant.org 	struct klist_node *n = klist_next(i);
2279f791b8c8SGreg Kroah-Hartman 	struct device *dev = NULL;
2280f791b8c8SGreg Kroah-Hartman 	struct device_private *p;
2281f791b8c8SGreg Kroah-Hartman 
2282f791b8c8SGreg Kroah-Hartman 	if (n) {
2283f791b8c8SGreg Kroah-Hartman 		p = to_device_private_parent(n);
2284f791b8c8SGreg Kroah-Hartman 		dev = p->device;
2285f791b8c8SGreg Kroah-Hartman 	}
2286f791b8c8SGreg Kroah-Hartman 	return dev;
228736239577Smochel@digitalimplant.org }
228836239577Smochel@digitalimplant.org 
22891da177e4SLinus Torvalds /**
2290e454cea2SKay Sievers  * device_get_devnode - path of device node file
22916fcf53acSKay Sievers  * @dev: device
2292e454cea2SKay Sievers  * @mode: returned file access mode
22933c2670e6SKay Sievers  * @uid: returned file owner
22943c2670e6SKay Sievers  * @gid: returned file group
22956fcf53acSKay Sievers  * @tmp: possibly allocated string
22966fcf53acSKay Sievers  *
22976fcf53acSKay Sievers  * Return the relative path of a possible device node.
22986fcf53acSKay Sievers  * Non-default names may need to allocate a memory to compose
22996fcf53acSKay Sievers  * a name. This memory is returned in tmp and needs to be
23006fcf53acSKay Sievers  * freed by the caller.
23016fcf53acSKay Sievers  */
2302e454cea2SKay Sievers const char *device_get_devnode(struct device *dev,
23034e4098a3SGreg Kroah-Hartman 			       umode_t *mode, kuid_t *uid, kgid_t *gid,
23043c2670e6SKay Sievers 			       const char **tmp)
23056fcf53acSKay Sievers {
23066fcf53acSKay Sievers 	char *s;
23076fcf53acSKay Sievers 
23086fcf53acSKay Sievers 	*tmp = NULL;
23096fcf53acSKay Sievers 
23106fcf53acSKay Sievers 	/* the device type may provide a specific name */
2311e454cea2SKay Sievers 	if (dev->type && dev->type->devnode)
23123c2670e6SKay Sievers 		*tmp = dev->type->devnode(dev, mode, uid, gid);
23136fcf53acSKay Sievers 	if (*tmp)
23146fcf53acSKay Sievers 		return *tmp;
23156fcf53acSKay Sievers 
23166fcf53acSKay Sievers 	/* the class may provide a specific name */
2317e454cea2SKay Sievers 	if (dev->class && dev->class->devnode)
2318e454cea2SKay Sievers 		*tmp = dev->class->devnode(dev, mode);
23196fcf53acSKay Sievers 	if (*tmp)
23206fcf53acSKay Sievers 		return *tmp;
23216fcf53acSKay Sievers 
23226fcf53acSKay Sievers 	/* return name without allocation, tmp == NULL */
23236fcf53acSKay Sievers 	if (strchr(dev_name(dev), '!') == NULL)
23246fcf53acSKay Sievers 		return dev_name(dev);
23256fcf53acSKay Sievers 
23266fcf53acSKay Sievers 	/* replace '!' in the name with '/' */
2327a29fd614SRasmus Villemoes 	s = kstrdup(dev_name(dev), GFP_KERNEL);
2328a29fd614SRasmus Villemoes 	if (!s)
23296fcf53acSKay Sievers 		return NULL;
2330a29fd614SRasmus Villemoes 	strreplace(s, '!', '/');
2331a29fd614SRasmus Villemoes 	return *tmp = s;
23326fcf53acSKay Sievers }
23336fcf53acSKay Sievers 
23346fcf53acSKay Sievers /**
23351da177e4SLinus Torvalds  * device_for_each_child - device child iterator.
2336c41455fbSRandy Dunlap  * @parent: parent struct device.
23371da177e4SLinus Torvalds  * @fn: function to be called for each device.
2338f8878dcbSRobert P. J. Day  * @data: data for the callback.
23391da177e4SLinus Torvalds  *
2340c41455fbSRandy Dunlap  * Iterate over @parent's child devices, and call @fn for each,
23411da177e4SLinus Torvalds  * passing it @data.
23421da177e4SLinus Torvalds  *
23431da177e4SLinus Torvalds  * We check the return of @fn each time. If it returns anything
23441da177e4SLinus Torvalds  * other than 0, we break out and return that value.
23451da177e4SLinus Torvalds  */
234636239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data,
23474a3ad20cSGreg Kroah-Hartman 			  int (*fn)(struct device *dev, void *data))
23481da177e4SLinus Torvalds {
234936239577Smochel@digitalimplant.org 	struct klist_iter i;
23501da177e4SLinus Torvalds 	struct device *child;
23511da177e4SLinus Torvalds 	int error = 0;
23521da177e4SLinus Torvalds 
2353014c90dbSGreg Kroah-Hartman 	if (!parent->p)
2354014c90dbSGreg Kroah-Hartman 		return 0;
2355014c90dbSGreg Kroah-Hartman 
2356f791b8c8SGreg Kroah-Hartman 	klist_iter_init(&parent->p->klist_children, &i);
235793ead7c9SGimcuan Hui 	while (!error && (child = next_device(&i)))
235836239577Smochel@digitalimplant.org 		error = fn(child, data);
235936239577Smochel@digitalimplant.org 	klist_iter_exit(&i);
23601da177e4SLinus Torvalds 	return error;
23611da177e4SLinus Torvalds }
236286df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child);
23631da177e4SLinus Torvalds 
23645ab69981SCornelia Huck /**
23653d060aebSAndy Shevchenko  * device_for_each_child_reverse - device child iterator in reversed order.
23663d060aebSAndy Shevchenko  * @parent: parent struct device.
23673d060aebSAndy Shevchenko  * @fn: function to be called for each device.
23683d060aebSAndy Shevchenko  * @data: data for the callback.
23693d060aebSAndy Shevchenko  *
23703d060aebSAndy Shevchenko  * Iterate over @parent's child devices, and call @fn for each,
23713d060aebSAndy Shevchenko  * passing it @data.
23723d060aebSAndy Shevchenko  *
23733d060aebSAndy Shevchenko  * We check the return of @fn each time. If it returns anything
23743d060aebSAndy Shevchenko  * other than 0, we break out and return that value.
23753d060aebSAndy Shevchenko  */
23763d060aebSAndy Shevchenko int device_for_each_child_reverse(struct device *parent, void *data,
23773d060aebSAndy Shevchenko 				  int (*fn)(struct device *dev, void *data))
23783d060aebSAndy Shevchenko {
23793d060aebSAndy Shevchenko 	struct klist_iter i;
23803d060aebSAndy Shevchenko 	struct device *child;
23813d060aebSAndy Shevchenko 	int error = 0;
23823d060aebSAndy Shevchenko 
23833d060aebSAndy Shevchenko 	if (!parent->p)
23843d060aebSAndy Shevchenko 		return 0;
23853d060aebSAndy Shevchenko 
23863d060aebSAndy Shevchenko 	klist_iter_init(&parent->p->klist_children, &i);
23873d060aebSAndy Shevchenko 	while ((child = prev_device(&i)) && !error)
23883d060aebSAndy Shevchenko 		error = fn(child, data);
23893d060aebSAndy Shevchenko 	klist_iter_exit(&i);
23903d060aebSAndy Shevchenko 	return error;
23913d060aebSAndy Shevchenko }
23923d060aebSAndy Shevchenko EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
23933d060aebSAndy Shevchenko 
23943d060aebSAndy Shevchenko /**
23955ab69981SCornelia Huck  * device_find_child - device iterator for locating a particular device.
23965ab69981SCornelia Huck  * @parent: parent struct device
23975ab69981SCornelia Huck  * @match: Callback function to check device
2398f8878dcbSRobert P. J. Day  * @data: Data to pass to match function
23995ab69981SCornelia Huck  *
24005ab69981SCornelia Huck  * This is similar to the device_for_each_child() function above, but it
24015ab69981SCornelia Huck  * returns a reference to a device that is 'found' for later use, as
24025ab69981SCornelia Huck  * determined by the @match callback.
24035ab69981SCornelia Huck  *
24045ab69981SCornelia Huck  * The callback should return 0 if the device doesn't match and non-zero
24055ab69981SCornelia Huck  * if it does.  If the callback returns non-zero and a reference to the
24065ab69981SCornelia Huck  * current device can be obtained, this function will return to the caller
24075ab69981SCornelia Huck  * and not iterate over any more devices.
2408a4e2400aSFederico Vaga  *
2409a4e2400aSFederico Vaga  * NOTE: you will need to drop the reference with put_device() after use.
24105ab69981SCornelia Huck  */
24115ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data,
24124a3ad20cSGreg Kroah-Hartman 				 int (*match)(struct device *dev, void *data))
24135ab69981SCornelia Huck {
24145ab69981SCornelia Huck 	struct klist_iter i;
24155ab69981SCornelia Huck 	struct device *child;
24165ab69981SCornelia Huck 
24175ab69981SCornelia Huck 	if (!parent)
24185ab69981SCornelia Huck 		return NULL;
24195ab69981SCornelia Huck 
2420f791b8c8SGreg Kroah-Hartman 	klist_iter_init(&parent->p->klist_children, &i);
24215ab69981SCornelia Huck 	while ((child = next_device(&i)))
24225ab69981SCornelia Huck 		if (match(child, data) && get_device(child))
24235ab69981SCornelia Huck 			break;
24245ab69981SCornelia Huck 	klist_iter_exit(&i);
24255ab69981SCornelia Huck 	return child;
24265ab69981SCornelia Huck }
242786df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child);
24285ab69981SCornelia Huck 
24291da177e4SLinus Torvalds int __init devices_init(void)
24301da177e4SLinus Torvalds {
2431881c6cfdSGreg Kroah-Hartman 	devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
2432881c6cfdSGreg Kroah-Hartman 	if (!devices_kset)
2433881c6cfdSGreg Kroah-Hartman 		return -ENOMEM;
2434e105b8bfSDan Williams 	dev_kobj = kobject_create_and_add("dev", NULL);
2435e105b8bfSDan Williams 	if (!dev_kobj)
2436e105b8bfSDan Williams 		goto dev_kobj_err;
2437e105b8bfSDan Williams 	sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
2438e105b8bfSDan Williams 	if (!sysfs_dev_block_kobj)
2439e105b8bfSDan Williams 		goto block_kobj_err;
2440e105b8bfSDan Williams 	sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
2441e105b8bfSDan Williams 	if (!sysfs_dev_char_kobj)
2442e105b8bfSDan Williams 		goto char_kobj_err;
2443e105b8bfSDan Williams 
2444881c6cfdSGreg Kroah-Hartman 	return 0;
2445e105b8bfSDan Williams 
2446e105b8bfSDan Williams  char_kobj_err:
2447e105b8bfSDan Williams 	kobject_put(sysfs_dev_block_kobj);
2448e105b8bfSDan Williams  block_kobj_err:
2449e105b8bfSDan Williams 	kobject_put(dev_kobj);
2450e105b8bfSDan Williams  dev_kobj_err:
2451e105b8bfSDan Williams 	kset_unregister(devices_kset);
2452e105b8bfSDan Williams 	return -ENOMEM;
24531da177e4SLinus Torvalds }
24541da177e4SLinus Torvalds 
24554f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used)
24564f3549d7SRafael J. Wysocki {
24574f3549d7SRafael J. Wysocki 	int ret;
24584f3549d7SRafael J. Wysocki 
24594f3549d7SRafael J. Wysocki 	ret = device_for_each_child(dev, NULL, device_check_offline);
24604f3549d7SRafael J. Wysocki 	if (ret)
24614f3549d7SRafael J. Wysocki 		return ret;
24624f3549d7SRafael J. Wysocki 
24634f3549d7SRafael J. Wysocki 	return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
24644f3549d7SRafael J. Wysocki }
24654f3549d7SRafael J. Wysocki 
24664f3549d7SRafael J. Wysocki /**
24674f3549d7SRafael J. Wysocki  * device_offline - Prepare the device for hot-removal.
24684f3549d7SRafael J. Wysocki  * @dev: Device to be put offline.
24694f3549d7SRafael J. Wysocki  *
24704f3549d7SRafael J. Wysocki  * Execute the device bus type's .offline() callback, if present, to prepare
24714f3549d7SRafael J. Wysocki  * the device for a subsequent hot-removal.  If that succeeds, the device must
24724f3549d7SRafael J. Wysocki  * not be used until either it is removed or its bus type's .online() callback
24734f3549d7SRafael J. Wysocki  * is executed.
24744f3549d7SRafael J. Wysocki  *
24754f3549d7SRafael J. Wysocki  * Call under device_hotplug_lock.
24764f3549d7SRafael J. Wysocki  */
24774f3549d7SRafael J. Wysocki int device_offline(struct device *dev)
24784f3549d7SRafael J. Wysocki {
24794f3549d7SRafael J. Wysocki 	int ret;
24804f3549d7SRafael J. Wysocki 
24814f3549d7SRafael J. Wysocki 	if (dev->offline_disabled)
24824f3549d7SRafael J. Wysocki 		return -EPERM;
24834f3549d7SRafael J. Wysocki 
24844f3549d7SRafael J. Wysocki 	ret = device_for_each_child(dev, NULL, device_check_offline);
24854f3549d7SRafael J. Wysocki 	if (ret)
24864f3549d7SRafael J. Wysocki 		return ret;
24874f3549d7SRafael J. Wysocki 
24884f3549d7SRafael J. Wysocki 	device_lock(dev);
24894f3549d7SRafael J. Wysocki 	if (device_supports_offline(dev)) {
24904f3549d7SRafael J. Wysocki 		if (dev->offline) {
24914f3549d7SRafael J. Wysocki 			ret = 1;
24924f3549d7SRafael J. Wysocki 		} else {
24934f3549d7SRafael J. Wysocki 			ret = dev->bus->offline(dev);
24944f3549d7SRafael J. Wysocki 			if (!ret) {
24954f3549d7SRafael J. Wysocki 				kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
24964f3549d7SRafael J. Wysocki 				dev->offline = true;
24974f3549d7SRafael J. Wysocki 			}
24984f3549d7SRafael J. Wysocki 		}
24994f3549d7SRafael J. Wysocki 	}
25004f3549d7SRafael J. Wysocki 	device_unlock(dev);
25014f3549d7SRafael J. Wysocki 
25024f3549d7SRafael J. Wysocki 	return ret;
25034f3549d7SRafael J. Wysocki }
25044f3549d7SRafael J. Wysocki 
25054f3549d7SRafael J. Wysocki /**
25064f3549d7SRafael J. Wysocki  * device_online - Put the device back online after successful device_offline().
25074f3549d7SRafael J. Wysocki  * @dev: Device to be put back online.
25084f3549d7SRafael J. Wysocki  *
25094f3549d7SRafael J. Wysocki  * If device_offline() has been successfully executed for @dev, but the device
25104f3549d7SRafael J. Wysocki  * has not been removed subsequently, execute its bus type's .online() callback
25114f3549d7SRafael J. Wysocki  * to indicate that the device can be used again.
25124f3549d7SRafael J. Wysocki  *
25134f3549d7SRafael J. Wysocki  * Call under device_hotplug_lock.
25144f3549d7SRafael J. Wysocki  */
25154f3549d7SRafael J. Wysocki int device_online(struct device *dev)
25164f3549d7SRafael J. Wysocki {
25174f3549d7SRafael J. Wysocki 	int ret = 0;
25184f3549d7SRafael J. Wysocki 
25194f3549d7SRafael J. Wysocki 	device_lock(dev);
25204f3549d7SRafael J. Wysocki 	if (device_supports_offline(dev)) {
25214f3549d7SRafael J. Wysocki 		if (dev->offline) {
25224f3549d7SRafael J. Wysocki 			ret = dev->bus->online(dev);
25234f3549d7SRafael J. Wysocki 			if (!ret) {
25244f3549d7SRafael J. Wysocki 				kobject_uevent(&dev->kobj, KOBJ_ONLINE);
25254f3549d7SRafael J. Wysocki 				dev->offline = false;
25264f3549d7SRafael J. Wysocki 			}
25274f3549d7SRafael J. Wysocki 		} else {
25284f3549d7SRafael J. Wysocki 			ret = 1;
25294f3549d7SRafael J. Wysocki 		}
25304f3549d7SRafael J. Wysocki 	}
25314f3549d7SRafael J. Wysocki 	device_unlock(dev);
25324f3549d7SRafael J. Wysocki 
25334f3549d7SRafael J. Wysocki 	return ret;
25344f3549d7SRafael J. Wysocki }
25354f3549d7SRafael J. Wysocki 
25367f100d15SKarthigan Srinivasan struct root_device {
25370aa0dc41SMark McLoughlin 	struct device dev;
25380aa0dc41SMark McLoughlin 	struct module *owner;
25390aa0dc41SMark McLoughlin };
25400aa0dc41SMark McLoughlin 
254193058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d)
2542481e2079SFerenc Wagner {
2543481e2079SFerenc Wagner 	return container_of(d, struct root_device, dev);
2544481e2079SFerenc Wagner }
25450aa0dc41SMark McLoughlin 
25460aa0dc41SMark McLoughlin static void root_device_release(struct device *dev)
25470aa0dc41SMark McLoughlin {
25480aa0dc41SMark McLoughlin 	kfree(to_root_device(dev));
25490aa0dc41SMark McLoughlin }
25500aa0dc41SMark McLoughlin 
25510aa0dc41SMark McLoughlin /**
25520aa0dc41SMark McLoughlin  * __root_device_register - allocate and register a root device
25530aa0dc41SMark McLoughlin  * @name: root device name
25540aa0dc41SMark McLoughlin  * @owner: owner module of the root device, usually THIS_MODULE
25550aa0dc41SMark McLoughlin  *
25560aa0dc41SMark McLoughlin  * This function allocates a root device and registers it
25570aa0dc41SMark McLoughlin  * using device_register(). In order to free the returned
25580aa0dc41SMark McLoughlin  * device, use root_device_unregister().
25590aa0dc41SMark McLoughlin  *
25600aa0dc41SMark McLoughlin  * Root devices are dummy devices which allow other devices
25610aa0dc41SMark McLoughlin  * to be grouped under /sys/devices. Use this function to
25620aa0dc41SMark McLoughlin  * allocate a root device and then use it as the parent of
25630aa0dc41SMark McLoughlin  * any device which should appear under /sys/devices/{name}
25640aa0dc41SMark McLoughlin  *
25650aa0dc41SMark McLoughlin  * The /sys/devices/{name} directory will also contain a
25660aa0dc41SMark McLoughlin  * 'module' symlink which points to the @owner directory
25670aa0dc41SMark McLoughlin  * in sysfs.
25680aa0dc41SMark McLoughlin  *
2569f0eae0edSJani Nikula  * Returns &struct device pointer on success, or ERR_PTR() on error.
2570f0eae0edSJani Nikula  *
25710aa0dc41SMark McLoughlin  * Note: You probably want to use root_device_register().
25720aa0dc41SMark McLoughlin  */
25730aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner)
25740aa0dc41SMark McLoughlin {
25750aa0dc41SMark McLoughlin 	struct root_device *root;
25760aa0dc41SMark McLoughlin 	int err = -ENOMEM;
25770aa0dc41SMark McLoughlin 
25780aa0dc41SMark McLoughlin 	root = kzalloc(sizeof(struct root_device), GFP_KERNEL);
25790aa0dc41SMark McLoughlin 	if (!root)
25800aa0dc41SMark McLoughlin 		return ERR_PTR(err);
25810aa0dc41SMark McLoughlin 
2582acc0e90fSGreg Kroah-Hartman 	err = dev_set_name(&root->dev, "%s", name);
25830aa0dc41SMark McLoughlin 	if (err) {
25840aa0dc41SMark McLoughlin 		kfree(root);
25850aa0dc41SMark McLoughlin 		return ERR_PTR(err);
25860aa0dc41SMark McLoughlin 	}
25870aa0dc41SMark McLoughlin 
25880aa0dc41SMark McLoughlin 	root->dev.release = root_device_release;
25890aa0dc41SMark McLoughlin 
25900aa0dc41SMark McLoughlin 	err = device_register(&root->dev);
25910aa0dc41SMark McLoughlin 	if (err) {
25920aa0dc41SMark McLoughlin 		put_device(&root->dev);
25930aa0dc41SMark McLoughlin 		return ERR_PTR(err);
25940aa0dc41SMark McLoughlin 	}
25950aa0dc41SMark McLoughlin 
25961d9e882bSChristoph Egger #ifdef CONFIG_MODULES	/* gotta find a "cleaner" way to do this */
25970aa0dc41SMark McLoughlin 	if (owner) {
25980aa0dc41SMark McLoughlin 		struct module_kobject *mk = &owner->mkobj;
25990aa0dc41SMark McLoughlin 
26000aa0dc41SMark McLoughlin 		err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module");
26010aa0dc41SMark McLoughlin 		if (err) {
26020aa0dc41SMark McLoughlin 			device_unregister(&root->dev);
26030aa0dc41SMark McLoughlin 			return ERR_PTR(err);
26040aa0dc41SMark McLoughlin 		}
26050aa0dc41SMark McLoughlin 		root->owner = owner;
26060aa0dc41SMark McLoughlin 	}
26070aa0dc41SMark McLoughlin #endif
26080aa0dc41SMark McLoughlin 
26090aa0dc41SMark McLoughlin 	return &root->dev;
26100aa0dc41SMark McLoughlin }
26110aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register);
26120aa0dc41SMark McLoughlin 
26130aa0dc41SMark McLoughlin /**
26140aa0dc41SMark McLoughlin  * root_device_unregister - unregister and free a root device
26157cbcf225SRandy Dunlap  * @dev: device going away
26160aa0dc41SMark McLoughlin  *
26170aa0dc41SMark McLoughlin  * This function unregisters and cleans up a device that was created by
26180aa0dc41SMark McLoughlin  * root_device_register().
26190aa0dc41SMark McLoughlin  */
26200aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev)
26210aa0dc41SMark McLoughlin {
26220aa0dc41SMark McLoughlin 	struct root_device *root = to_root_device(dev);
26230aa0dc41SMark McLoughlin 
26240aa0dc41SMark McLoughlin 	if (root->owner)
26250aa0dc41SMark McLoughlin 		sysfs_remove_link(&root->dev.kobj, "module");
26260aa0dc41SMark McLoughlin 
26270aa0dc41SMark McLoughlin 	device_unregister(dev);
26280aa0dc41SMark McLoughlin }
26290aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister);
26300aa0dc41SMark McLoughlin 
263123681e47SGreg Kroah-Hartman 
263223681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev)
263323681e47SGreg Kroah-Hartman {
26341e0b2cf9SKay Sievers 	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
263523681e47SGreg Kroah-Hartman 	kfree(dev);
263623681e47SGreg Kroah-Hartman }
263723681e47SGreg Kroah-Hartman 
26386a8b55d7SMathieu Malaterre static __printf(6, 0) struct device *
263939ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent,
264039ef3112SGuenter Roeck 			   dev_t devt, void *drvdata,
264139ef3112SGuenter Roeck 			   const struct attribute_group **groups,
264239ef3112SGuenter Roeck 			   const char *fmt, va_list args)
264339ef3112SGuenter Roeck {
264439ef3112SGuenter Roeck 	struct device *dev = NULL;
264539ef3112SGuenter Roeck 	int retval = -ENODEV;
264639ef3112SGuenter Roeck 
264739ef3112SGuenter Roeck 	if (class == NULL || IS_ERR(class))
264839ef3112SGuenter Roeck 		goto error;
264939ef3112SGuenter Roeck 
265039ef3112SGuenter Roeck 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
265139ef3112SGuenter Roeck 	if (!dev) {
265239ef3112SGuenter Roeck 		retval = -ENOMEM;
265339ef3112SGuenter Roeck 		goto error;
265439ef3112SGuenter Roeck 	}
265539ef3112SGuenter Roeck 
2656bbc780f8SDavid Herrmann 	device_initialize(dev);
265739ef3112SGuenter Roeck 	dev->devt = devt;
265839ef3112SGuenter Roeck 	dev->class = class;
265939ef3112SGuenter Roeck 	dev->parent = parent;
266039ef3112SGuenter Roeck 	dev->groups = groups;
266139ef3112SGuenter Roeck 	dev->release = device_create_release;
266239ef3112SGuenter Roeck 	dev_set_drvdata(dev, drvdata);
266339ef3112SGuenter Roeck 
266439ef3112SGuenter Roeck 	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
266539ef3112SGuenter Roeck 	if (retval)
266639ef3112SGuenter Roeck 		goto error;
266739ef3112SGuenter Roeck 
2668bbc780f8SDavid Herrmann 	retval = device_add(dev);
266939ef3112SGuenter Roeck 	if (retval)
267039ef3112SGuenter Roeck 		goto error;
267139ef3112SGuenter Roeck 
267239ef3112SGuenter Roeck 	return dev;
267339ef3112SGuenter Roeck 
267439ef3112SGuenter Roeck error:
267539ef3112SGuenter Roeck 	put_device(dev);
267639ef3112SGuenter Roeck 	return ERR_PTR(retval);
267739ef3112SGuenter Roeck }
267839ef3112SGuenter Roeck 
267923681e47SGreg Kroah-Hartman /**
26808882b394SGreg Kroah-Hartman  * device_create_vargs - creates a device and registers it with sysfs
26818882b394SGreg Kroah-Hartman  * @class: pointer to the struct class that this device should be registered to
26828882b394SGreg Kroah-Hartman  * @parent: pointer to the parent struct device of this new device, if any
26838882b394SGreg Kroah-Hartman  * @devt: the dev_t for the char device to be added
26848882b394SGreg Kroah-Hartman  * @drvdata: the data to be added to the device for callbacks
26858882b394SGreg Kroah-Hartman  * @fmt: string for the device's name
26868882b394SGreg Kroah-Hartman  * @args: va_list for the device's name
26878882b394SGreg Kroah-Hartman  *
26888882b394SGreg Kroah-Hartman  * This function can be used by char device classes.  A struct device
26898882b394SGreg Kroah-Hartman  * will be created in sysfs, registered to the specified class.
26908882b394SGreg Kroah-Hartman  *
26918882b394SGreg Kroah-Hartman  * A "dev" file will be created, showing the dev_t for the device, if
26928882b394SGreg Kroah-Hartman  * the dev_t is not 0,0.
26938882b394SGreg Kroah-Hartman  * If a pointer to a parent struct device is passed in, the newly created
26948882b394SGreg Kroah-Hartman  * struct device will be a child of that device in sysfs.
26958882b394SGreg Kroah-Hartman  * The pointer to the struct device will be returned from the call.
26968882b394SGreg Kroah-Hartman  * Any further sysfs files that might be required can be created using this
26978882b394SGreg Kroah-Hartman  * pointer.
26988882b394SGreg Kroah-Hartman  *
2699f0eae0edSJani Nikula  * Returns &struct device pointer on success, or ERR_PTR() on error.
2700f0eae0edSJani Nikula  *
27018882b394SGreg Kroah-Hartman  * Note: the struct class passed to this function must have previously
27028882b394SGreg Kroah-Hartman  * been created with a call to class_create().
27038882b394SGreg Kroah-Hartman  */
27048882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent,
27058882b394SGreg Kroah-Hartman 				   dev_t devt, void *drvdata, const char *fmt,
27068882b394SGreg Kroah-Hartman 				   va_list args)
27078882b394SGreg Kroah-Hartman {
270839ef3112SGuenter Roeck 	return device_create_groups_vargs(class, parent, devt, drvdata, NULL,
270939ef3112SGuenter Roeck 					  fmt, args);
27108882b394SGreg Kroah-Hartman }
27118882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs);
27128882b394SGreg Kroah-Hartman 
27138882b394SGreg Kroah-Hartman /**
27144e106739SGreg Kroah-Hartman  * device_create - creates a device and registers it with sysfs
27158882b394SGreg Kroah-Hartman  * @class: pointer to the struct class that this device should be registered to
27168882b394SGreg Kroah-Hartman  * @parent: pointer to the parent struct device of this new device, if any
27178882b394SGreg Kroah-Hartman  * @devt: the dev_t for the char device to be added
27188882b394SGreg Kroah-Hartman  * @drvdata: the data to be added to the device for callbacks
27198882b394SGreg Kroah-Hartman  * @fmt: string for the device's name
27208882b394SGreg Kroah-Hartman  *
27218882b394SGreg Kroah-Hartman  * This function can be used by char device classes.  A struct device
27228882b394SGreg Kroah-Hartman  * will be created in sysfs, registered to the specified class.
27238882b394SGreg Kroah-Hartman  *
27248882b394SGreg Kroah-Hartman  * A "dev" file will be created, showing the dev_t for the device, if
27258882b394SGreg Kroah-Hartman  * the dev_t is not 0,0.
27268882b394SGreg Kroah-Hartman  * If a pointer to a parent struct device is passed in, the newly created
27278882b394SGreg Kroah-Hartman  * struct device will be a child of that device in sysfs.
27288882b394SGreg Kroah-Hartman  * The pointer to the struct device will be returned from the call.
27298882b394SGreg Kroah-Hartman  * Any further sysfs files that might be required can be created using this
27308882b394SGreg Kroah-Hartman  * pointer.
27318882b394SGreg Kroah-Hartman  *
2732f0eae0edSJani Nikula  * Returns &struct device pointer on success, or ERR_PTR() on error.
2733f0eae0edSJani Nikula  *
27348882b394SGreg Kroah-Hartman  * Note: the struct class passed to this function must have previously
27358882b394SGreg Kroah-Hartman  * been created with a call to class_create().
27368882b394SGreg Kroah-Hartman  */
27374e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent,
27384e106739SGreg Kroah-Hartman 			     dev_t devt, void *drvdata, const char *fmt, ...)
27398882b394SGreg Kroah-Hartman {
27408882b394SGreg Kroah-Hartman 	va_list vargs;
27418882b394SGreg Kroah-Hartman 	struct device *dev;
27428882b394SGreg Kroah-Hartman 
27438882b394SGreg Kroah-Hartman 	va_start(vargs, fmt);
27448882b394SGreg Kroah-Hartman 	dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
27458882b394SGreg Kroah-Hartman 	va_end(vargs);
27468882b394SGreg Kroah-Hartman 	return dev;
27478882b394SGreg Kroah-Hartman }
27484e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create);
27498882b394SGreg Kroah-Hartman 
275039ef3112SGuenter Roeck /**
275139ef3112SGuenter Roeck  * device_create_with_groups - creates a device and registers it with sysfs
275239ef3112SGuenter Roeck  * @class: pointer to the struct class that this device should be registered to
275339ef3112SGuenter Roeck  * @parent: pointer to the parent struct device of this new device, if any
275439ef3112SGuenter Roeck  * @devt: the dev_t for the char device to be added
275539ef3112SGuenter Roeck  * @drvdata: the data to be added to the device for callbacks
275639ef3112SGuenter Roeck  * @groups: NULL-terminated list of attribute groups to be created
275739ef3112SGuenter Roeck  * @fmt: string for the device's name
275839ef3112SGuenter Roeck  *
275939ef3112SGuenter Roeck  * This function can be used by char device classes.  A struct device
276039ef3112SGuenter Roeck  * will be created in sysfs, registered to the specified class.
276139ef3112SGuenter Roeck  * Additional attributes specified in the groups parameter will also
276239ef3112SGuenter Roeck  * be created automatically.
276339ef3112SGuenter Roeck  *
276439ef3112SGuenter Roeck  * A "dev" file will be created, showing the dev_t for the device, if
276539ef3112SGuenter Roeck  * the dev_t is not 0,0.
276639ef3112SGuenter Roeck  * If a pointer to a parent struct device is passed in, the newly created
276739ef3112SGuenter Roeck  * struct device will be a child of that device in sysfs.
276839ef3112SGuenter Roeck  * The pointer to the struct device will be returned from the call.
276939ef3112SGuenter Roeck  * Any further sysfs files that might be required can be created using this
277039ef3112SGuenter Roeck  * pointer.
277139ef3112SGuenter Roeck  *
277239ef3112SGuenter Roeck  * Returns &struct device pointer on success, or ERR_PTR() on error.
277339ef3112SGuenter Roeck  *
277439ef3112SGuenter Roeck  * Note: the struct class passed to this function must have previously
277539ef3112SGuenter Roeck  * been created with a call to class_create().
277639ef3112SGuenter Roeck  */
277739ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class,
277839ef3112SGuenter Roeck 					 struct device *parent, dev_t devt,
277939ef3112SGuenter Roeck 					 void *drvdata,
278039ef3112SGuenter Roeck 					 const struct attribute_group **groups,
278139ef3112SGuenter Roeck 					 const char *fmt, ...)
278239ef3112SGuenter Roeck {
278339ef3112SGuenter Roeck 	va_list vargs;
278439ef3112SGuenter Roeck 	struct device *dev;
278539ef3112SGuenter Roeck 
278639ef3112SGuenter Roeck 	va_start(vargs, fmt);
278739ef3112SGuenter Roeck 	dev = device_create_groups_vargs(class, parent, devt, drvdata, groups,
278839ef3112SGuenter Roeck 					 fmt, vargs);
278939ef3112SGuenter Roeck 	va_end(vargs);
279039ef3112SGuenter Roeck 	return dev;
279139ef3112SGuenter Roeck }
279239ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups);
279339ef3112SGuenter Roeck 
27949f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data)
279523681e47SGreg Kroah-Hartman {
27969f3b795aSMichał Mirosław 	const dev_t *devt = data;
279723681e47SGreg Kroah-Hartman 
2798cd35449bSDave Young 	return dev->devt == *devt;
2799775b64d2SRafael J. Wysocki }
280023681e47SGreg Kroah-Hartman 
2801775b64d2SRafael J. Wysocki /**
2802775b64d2SRafael J. Wysocki  * device_destroy - removes a device that was created with device_create()
2803775b64d2SRafael J. Wysocki  * @class: pointer to the struct class that this device was registered with
2804775b64d2SRafael J. Wysocki  * @devt: the dev_t of the device that was previously registered
2805775b64d2SRafael J. Wysocki  *
2806775b64d2SRafael J. Wysocki  * This call unregisters and cleans up a device that was created with a
2807775b64d2SRafael J. Wysocki  * call to device_create().
2808775b64d2SRafael J. Wysocki  */
2809775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt)
2810775b64d2SRafael J. Wysocki {
2811775b64d2SRafael J. Wysocki 	struct device *dev;
2812775b64d2SRafael J. Wysocki 
2813695794aeSGreg Kroah-Hartman 	dev = class_find_device(class, NULL, &devt, __match_devt);
2814cd35449bSDave Young 	if (dev) {
2815cd35449bSDave Young 		put_device(dev);
281623681e47SGreg Kroah-Hartman 		device_unregister(dev);
281723681e47SGreg Kroah-Hartman 	}
2818cd35449bSDave Young }
281923681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy);
2820a2de48caSGreg Kroah-Hartman 
2821a2de48caSGreg Kroah-Hartman /**
2822a2de48caSGreg Kroah-Hartman  * device_rename - renames a device
2823a2de48caSGreg Kroah-Hartman  * @dev: the pointer to the struct device to be renamed
2824a2de48caSGreg Kroah-Hartman  * @new_name: the new name of the device
2825030c1d2bSEric W. Biederman  *
2826030c1d2bSEric W. Biederman  * It is the responsibility of the caller to provide mutual
2827030c1d2bSEric W. Biederman  * exclusion between two different calls of device_rename
2828030c1d2bSEric W. Biederman  * on the same device to ensure that new_name is valid and
2829030c1d2bSEric W. Biederman  * won't conflict with other devices.
2830c6c0ac66SMichael Ellerman  *
2831a5462516STimur Tabi  * Note: Don't call this function.  Currently, the networking layer calls this
2832a5462516STimur Tabi  * function, but that will change.  The following text from Kay Sievers offers
2833a5462516STimur Tabi  * some insight:
2834a5462516STimur Tabi  *
2835a5462516STimur Tabi  * Renaming devices is racy at many levels, symlinks and other stuff are not
2836a5462516STimur Tabi  * replaced atomically, and you get a "move" uevent, but it's not easy to
2837a5462516STimur Tabi  * connect the event to the old and new device. Device nodes are not renamed at
2838a5462516STimur Tabi  * all, there isn't even support for that in the kernel now.
2839a5462516STimur Tabi  *
2840a5462516STimur Tabi  * In the meantime, during renaming, your target name might be taken by another
2841a5462516STimur Tabi  * driver, creating conflicts. Or the old name is taken directly after you
2842a5462516STimur Tabi  * renamed it -- then you get events for the same DEVPATH, before you even see
2843a5462516STimur Tabi  * the "move" event. It's just a mess, and nothing new should ever rely on
2844a5462516STimur Tabi  * kernel device renaming. Besides that, it's not even implemented now for
2845a5462516STimur Tabi  * other things than (driver-core wise very simple) network devices.
2846a5462516STimur Tabi  *
2847a5462516STimur Tabi  * We are currently about to change network renaming in udev to completely
2848a5462516STimur Tabi  * disallow renaming of devices in the same namespace as the kernel uses,
2849a5462516STimur Tabi  * because we can't solve the problems properly, that arise with swapping names
2850a5462516STimur Tabi  * of multiple interfaces without races. Means, renaming of eth[0-9]* will only
2851a5462516STimur Tabi  * be allowed to some other name than eth[0-9]*, for the aforementioned
2852a5462516STimur Tabi  * reasons.
2853a5462516STimur Tabi  *
2854a5462516STimur Tabi  * Make up a "real" name in the driver before you register anything, or add
2855a5462516STimur Tabi  * some other attributes for userspace to find the device, or use udev to add
2856a5462516STimur Tabi  * symlinks -- but never rename kernel devices later, it's a complete mess. We
2857a5462516STimur Tabi  * don't even want to get into that and try to implement the missing pieces in
2858a5462516STimur Tabi  * the core. We really have other pieces to fix in the driver core mess. :)
2859a2de48caSGreg Kroah-Hartman  */
28606937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name)
2861a2de48caSGreg Kroah-Hartman {
28624b30ee58STejun Heo 	struct kobject *kobj = &dev->kobj;
28632ee97cafSCornelia Huck 	char *old_device_name = NULL;
2864a2de48caSGreg Kroah-Hartman 	int error;
2865a2de48caSGreg Kroah-Hartman 
2866a2de48caSGreg Kroah-Hartman 	dev = get_device(dev);
2867a2de48caSGreg Kroah-Hartman 	if (!dev)
2868a2de48caSGreg Kroah-Hartman 		return -EINVAL;
2869a2de48caSGreg Kroah-Hartman 
287069df7533Sethan.zhao 	dev_dbg(dev, "renaming to %s\n", new_name);
2871a2de48caSGreg Kroah-Hartman 
28721fa5ae85SKay Sievers 	old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
28732ee97cafSCornelia Huck 	if (!old_device_name) {
2874952ab431SJesper Juhl 		error = -ENOMEM;
28752ee97cafSCornelia Huck 		goto out;
2876952ab431SJesper Juhl 	}
2877a2de48caSGreg Kroah-Hartman 
2878f349cf34SEric W. Biederman 	if (dev->class) {
28794b30ee58STejun Heo 		error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj,
28804b30ee58STejun Heo 					     kobj, old_device_name,
28814b30ee58STejun Heo 					     new_name, kobject_namespace(kobj));
2882f349cf34SEric W. Biederman 		if (error)
2883f349cf34SEric W. Biederman 			goto out;
2884f349cf34SEric W. Biederman 	}
288539aba963SKay Sievers 
28864b30ee58STejun Heo 	error = kobject_rename(kobj, new_name);
28871fa5ae85SKay Sievers 	if (error)
28882ee97cafSCornelia Huck 		goto out;
2889a2de48caSGreg Kroah-Hartman 
28902ee97cafSCornelia Huck out:
2891a2de48caSGreg Kroah-Hartman 	put_device(dev);
2892a2de48caSGreg Kroah-Hartman 
28932ee97cafSCornelia Huck 	kfree(old_device_name);
2894a2de48caSGreg Kroah-Hartman 
2895a2de48caSGreg Kroah-Hartman 	return error;
2896a2de48caSGreg Kroah-Hartman }
2897a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename);
28988a82472fSCornelia Huck 
28998a82472fSCornelia Huck static int device_move_class_links(struct device *dev,
29008a82472fSCornelia Huck 				   struct device *old_parent,
29018a82472fSCornelia Huck 				   struct device *new_parent)
29028a82472fSCornelia Huck {
2903f7f3461dSGreg Kroah-Hartman 	int error = 0;
29048a82472fSCornelia Huck 
2905f7f3461dSGreg Kroah-Hartman 	if (old_parent)
2906f7f3461dSGreg Kroah-Hartman 		sysfs_remove_link(&dev->kobj, "device");
2907f7f3461dSGreg Kroah-Hartman 	if (new_parent)
2908f7f3461dSGreg Kroah-Hartman 		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
2909f7f3461dSGreg Kroah-Hartman 					  "device");
2910f7f3461dSGreg Kroah-Hartman 	return error;
29118a82472fSCornelia Huck }
29128a82472fSCornelia Huck 
29138a82472fSCornelia Huck /**
29148a82472fSCornelia Huck  * device_move - moves a device to a new parent
29158a82472fSCornelia Huck  * @dev: the pointer to the struct device to be moved
291613509860SWolfram Sang  * @new_parent: the new parent of the device (can be NULL)
2917ffa6a705SCornelia Huck  * @dpm_order: how to reorder the dpm_list
29188a82472fSCornelia Huck  */
2919ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent,
2920ffa6a705SCornelia Huck 		enum dpm_order dpm_order)
29218a82472fSCornelia Huck {
29228a82472fSCornelia Huck 	int error;
29238a82472fSCornelia Huck 	struct device *old_parent;
2924c744aeaeSCornelia Huck 	struct kobject *new_parent_kobj;
29258a82472fSCornelia Huck 
29268a82472fSCornelia Huck 	dev = get_device(dev);
29278a82472fSCornelia Huck 	if (!dev)
29288a82472fSCornelia Huck 		return -EINVAL;
29298a82472fSCornelia Huck 
2930ffa6a705SCornelia Huck 	device_pm_lock();
29318a82472fSCornelia Huck 	new_parent = get_device(new_parent);
2932c744aeaeSCornelia Huck 	new_parent_kobj = get_device_parent(dev, new_parent);
293384d0c27dSTetsuo Handa 	if (IS_ERR(new_parent_kobj)) {
293484d0c27dSTetsuo Handa 		error = PTR_ERR(new_parent_kobj);
293584d0c27dSTetsuo Handa 		put_device(new_parent);
293684d0c27dSTetsuo Handa 		goto out;
293784d0c27dSTetsuo Handa 	}
293863b6971aSCornelia Huck 
29391e0b2cf9SKay Sievers 	pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev),
29401e0b2cf9SKay Sievers 		 __func__, new_parent ? dev_name(new_parent) : "<NULL>");
2941c744aeaeSCornelia Huck 	error = kobject_move(&dev->kobj, new_parent_kobj);
29428a82472fSCornelia Huck 	if (error) {
294363b6971aSCornelia Huck 		cleanup_glue_dir(dev, new_parent_kobj);
29448a82472fSCornelia Huck 		put_device(new_parent);
29458a82472fSCornelia Huck 		goto out;
29468a82472fSCornelia Huck 	}
29478a82472fSCornelia Huck 	old_parent = dev->parent;
29488a82472fSCornelia Huck 	dev->parent = new_parent;
29498a82472fSCornelia Huck 	if (old_parent)
2950f791b8c8SGreg Kroah-Hartman 		klist_remove(&dev->p->knode_parent);
29510d358f22SYinghai Lu 	if (new_parent) {
2952f791b8c8SGreg Kroah-Hartman 		klist_add_tail(&dev->p->knode_parent,
2953f791b8c8SGreg Kroah-Hartman 			       &new_parent->p->klist_children);
29540d358f22SYinghai Lu 		set_dev_node(dev, dev_to_node(new_parent));
29550d358f22SYinghai Lu 	}
29560d358f22SYinghai Lu 
2957bdd4034dSRabin Vincent 	if (dev->class) {
29588a82472fSCornelia Huck 		error = device_move_class_links(dev, old_parent, new_parent);
29598a82472fSCornelia Huck 		if (error) {
29608a82472fSCornelia Huck 			/* We ignore errors on cleanup since we're hosed anyway... */
29618a82472fSCornelia Huck 			device_move_class_links(dev, new_parent, old_parent);
29628a82472fSCornelia Huck 			if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
2963c744aeaeSCornelia Huck 				if (new_parent)
2964f791b8c8SGreg Kroah-Hartman 					klist_remove(&dev->p->knode_parent);
29650d358f22SYinghai Lu 				dev->parent = old_parent;
29660d358f22SYinghai Lu 				if (old_parent) {
2967f791b8c8SGreg Kroah-Hartman 					klist_add_tail(&dev->p->knode_parent,
2968f791b8c8SGreg Kroah-Hartman 						       &old_parent->p->klist_children);
29690d358f22SYinghai Lu 					set_dev_node(dev, dev_to_node(old_parent));
29700d358f22SYinghai Lu 				}
29718a82472fSCornelia Huck 			}
297263b6971aSCornelia Huck 			cleanup_glue_dir(dev, new_parent_kobj);
29738a82472fSCornelia Huck 			put_device(new_parent);
29748a82472fSCornelia Huck 			goto out;
29758a82472fSCornelia Huck 		}
2976bdd4034dSRabin Vincent 	}
2977ffa6a705SCornelia Huck 	switch (dpm_order) {
2978ffa6a705SCornelia Huck 	case DPM_ORDER_NONE:
2979ffa6a705SCornelia Huck 		break;
2980ffa6a705SCornelia Huck 	case DPM_ORDER_DEV_AFTER_PARENT:
2981ffa6a705SCornelia Huck 		device_pm_move_after(dev, new_parent);
298252cdbdd4SGrygorii Strashko 		devices_kset_move_after(dev, new_parent);
2983ffa6a705SCornelia Huck 		break;
2984ffa6a705SCornelia Huck 	case DPM_ORDER_PARENT_BEFORE_DEV:
2985ffa6a705SCornelia Huck 		device_pm_move_before(new_parent, dev);
298652cdbdd4SGrygorii Strashko 		devices_kset_move_before(new_parent, dev);
2987ffa6a705SCornelia Huck 		break;
2988ffa6a705SCornelia Huck 	case DPM_ORDER_DEV_LAST:
2989ffa6a705SCornelia Huck 		device_pm_move_last(dev);
299052cdbdd4SGrygorii Strashko 		devices_kset_move_last(dev);
2991ffa6a705SCornelia Huck 		break;
2992ffa6a705SCornelia Huck 	}
2993bdd4034dSRabin Vincent 
29948a82472fSCornelia Huck 	put_device(old_parent);
29958a82472fSCornelia Huck out:
2996ffa6a705SCornelia Huck 	device_pm_unlock();
29978a82472fSCornelia Huck 	put_device(dev);
29988a82472fSCornelia Huck 	return error;
29998a82472fSCornelia Huck }
30008a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move);
300137b0c020SGreg Kroah-Hartman 
300237b0c020SGreg Kroah-Hartman /**
300337b0c020SGreg Kroah-Hartman  * device_shutdown - call ->shutdown() on each device to shutdown.
300437b0c020SGreg Kroah-Hartman  */
300537b0c020SGreg Kroah-Hartman void device_shutdown(void)
300637b0c020SGreg Kroah-Hartman {
3007f123db8eSBenson Leung 	struct device *dev, *parent;
300837b0c020SGreg Kroah-Hartman 
30093297c8fcSPingfan Liu 	wait_for_device_probe();
30103297c8fcSPingfan Liu 	device_block_probing();
30113297c8fcSPingfan Liu 
30126245838fSHugh Daschbach 	spin_lock(&devices_kset->list_lock);
30136245838fSHugh Daschbach 	/*
30146245838fSHugh Daschbach 	 * Walk the devices list backward, shutting down each in turn.
30156245838fSHugh Daschbach 	 * Beware that device unplug events may also start pulling
30166245838fSHugh Daschbach 	 * devices offline, even as the system is shutting down.
30176245838fSHugh Daschbach 	 */
30186245838fSHugh Daschbach 	while (!list_empty(&devices_kset->list)) {
30196245838fSHugh Daschbach 		dev = list_entry(devices_kset->list.prev, struct device,
30206245838fSHugh Daschbach 				kobj.entry);
3021d1c6c030SMing Lei 
3022d1c6c030SMing Lei 		/*
3023d1c6c030SMing Lei 		 * hold reference count of device's parent to
3024d1c6c030SMing Lei 		 * prevent it from being freed because parent's
3025d1c6c030SMing Lei 		 * lock is to be held
3026d1c6c030SMing Lei 		 */
3027f123db8eSBenson Leung 		parent = get_device(dev->parent);
30286245838fSHugh Daschbach 		get_device(dev);
30296245838fSHugh Daschbach 		/*
30306245838fSHugh Daschbach 		 * Make sure the device is off the kset list, in the
30316245838fSHugh Daschbach 		 * event that dev->*->shutdown() doesn't remove it.
30326245838fSHugh Daschbach 		 */
30336245838fSHugh Daschbach 		list_del_init(&dev->kobj.entry);
30346245838fSHugh Daschbach 		spin_unlock(&devices_kset->list_lock);
3035fe6b91f4SAlan Stern 
3036d1c6c030SMing Lei 		/* hold lock to avoid race with probe/release */
3037f123db8eSBenson Leung 		if (parent)
3038f123db8eSBenson Leung 			device_lock(parent);
3039d1c6c030SMing Lei 		device_lock(dev);
3040d1c6c030SMing Lei 
3041fe6b91f4SAlan Stern 		/* Don't allow any more runtime suspends */
3042fe6b91f4SAlan Stern 		pm_runtime_get_noresume(dev);
3043fe6b91f4SAlan Stern 		pm_runtime_barrier(dev);
30446245838fSHugh Daschbach 
30457521621eSMichal Suchanek 		if (dev->class && dev->class->shutdown_pre) {
3046f77af151SJosh Zimmerman 			if (initcall_debug)
30477521621eSMichal Suchanek 				dev_info(dev, "shutdown_pre\n");
30487521621eSMichal Suchanek 			dev->class->shutdown_pre(dev);
30497521621eSMichal Suchanek 		}
30507521621eSMichal Suchanek 		if (dev->bus && dev->bus->shutdown) {
30510246c4faSShuoX Liu 			if (initcall_debug)
30520246c4faSShuoX Liu 				dev_info(dev, "shutdown\n");
305337b0c020SGreg Kroah-Hartman 			dev->bus->shutdown(dev);
305437b0c020SGreg Kroah-Hartman 		} else if (dev->driver && dev->driver->shutdown) {
30550246c4faSShuoX Liu 			if (initcall_debug)
30560246c4faSShuoX Liu 				dev_info(dev, "shutdown\n");
305737b0c020SGreg Kroah-Hartman 			dev->driver->shutdown(dev);
305837b0c020SGreg Kroah-Hartman 		}
3059d1c6c030SMing Lei 
3060d1c6c030SMing Lei 		device_unlock(dev);
3061f123db8eSBenson Leung 		if (parent)
3062f123db8eSBenson Leung 			device_unlock(parent);
3063d1c6c030SMing Lei 
30646245838fSHugh Daschbach 		put_device(dev);
3065f123db8eSBenson Leung 		put_device(parent);
30666245838fSHugh Daschbach 
30676245838fSHugh Daschbach 		spin_lock(&devices_kset->list_lock);
306837b0c020SGreg Kroah-Hartman 	}
30696245838fSHugh Daschbach 	spin_unlock(&devices_kset->list_lock);
307037b0c020SGreg Kroah-Hartman }
307199bcf217SJoe Perches 
307299bcf217SJoe Perches /*
307399bcf217SJoe Perches  * Device logging functions
307499bcf217SJoe Perches  */
307599bcf217SJoe Perches 
307699bcf217SJoe Perches #ifdef CONFIG_PRINTK
3077666f355fSJoe Perches static int
3078666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
307999bcf217SJoe Perches {
3080c4e00daaSKay Sievers 	const char *subsys;
3081798efc60SJoe Perches 	size_t pos = 0;
308299bcf217SJoe Perches 
3083c4e00daaSKay Sievers 	if (dev->class)
3084c4e00daaSKay Sievers 		subsys = dev->class->name;
3085c4e00daaSKay Sievers 	else if (dev->bus)
3086c4e00daaSKay Sievers 		subsys = dev->bus->name;
3087c4e00daaSKay Sievers 	else
3088798efc60SJoe Perches 		return 0;
3089c4e00daaSKay Sievers 
3090798efc60SJoe Perches 	pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys);
3091655e5b7cSBen Hutchings 	if (pos >= hdrlen)
3092655e5b7cSBen Hutchings 		goto overflow;
3093c4e00daaSKay Sievers 
3094c4e00daaSKay Sievers 	/*
3095c4e00daaSKay Sievers 	 * Add device identifier DEVICE=:
3096c4e00daaSKay Sievers 	 *   b12:8         block dev_t
3097c4e00daaSKay Sievers 	 *   c127:3        char dev_t
3098c4e00daaSKay Sievers 	 *   n8            netdev ifindex
3099c4e00daaSKay Sievers 	 *   +sound:card0  subsystem:devname
3100c4e00daaSKay Sievers 	 */
3101c4e00daaSKay Sievers 	if (MAJOR(dev->devt)) {
3102c4e00daaSKay Sievers 		char c;
3103c4e00daaSKay Sievers 
3104c4e00daaSKay Sievers 		if (strcmp(subsys, "block") == 0)
3105c4e00daaSKay Sievers 			c = 'b';
3106c4e00daaSKay Sievers 		else
3107c4e00daaSKay Sievers 			c = 'c';
3108798efc60SJoe Perches 		pos++;
3109798efc60SJoe Perches 		pos += snprintf(hdr + pos, hdrlen - pos,
3110c4e00daaSKay Sievers 				"DEVICE=%c%u:%u",
3111c4e00daaSKay Sievers 				c, MAJOR(dev->devt), MINOR(dev->devt));
3112c4e00daaSKay Sievers 	} else if (strcmp(subsys, "net") == 0) {
3113c4e00daaSKay Sievers 		struct net_device *net = to_net_dev(dev);
3114c4e00daaSKay Sievers 
3115798efc60SJoe Perches 		pos++;
3116798efc60SJoe Perches 		pos += snprintf(hdr + pos, hdrlen - pos,
3117c4e00daaSKay Sievers 				"DEVICE=n%u", net->ifindex);
3118c4e00daaSKay Sievers 	} else {
3119798efc60SJoe Perches 		pos++;
3120798efc60SJoe Perches 		pos += snprintf(hdr + pos, hdrlen - pos,
3121c4e00daaSKay Sievers 				"DEVICE=+%s:%s", subsys, dev_name(dev));
3122c4e00daaSKay Sievers 	}
3123af7f2158SJim Cromie 
3124655e5b7cSBen Hutchings 	if (pos >= hdrlen)
3125655e5b7cSBen Hutchings 		goto overflow;
3126655e5b7cSBen Hutchings 
3127798efc60SJoe Perches 	return pos;
3128655e5b7cSBen Hutchings 
3129655e5b7cSBen Hutchings overflow:
3130655e5b7cSBen Hutchings 	dev_WARN(dev, "device/subsystem name too long");
3131655e5b7cSBen Hutchings 	return 0;
313299bcf217SJoe Perches }
3133798efc60SJoe Perches 
313405e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev,
313505e4e5b8SJoe Perches 		     const char *fmt, va_list args)
313605e4e5b8SJoe Perches {
313705e4e5b8SJoe Perches 	char hdr[128];
313805e4e5b8SJoe Perches 	size_t hdrlen;
313905e4e5b8SJoe Perches 
314005e4e5b8SJoe Perches 	hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
314105e4e5b8SJoe Perches 
314205e4e5b8SJoe Perches 	return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args);
314305e4e5b8SJoe Perches }
314405e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit);
314505e4e5b8SJoe Perches 
314605e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
314705e4e5b8SJoe Perches {
314805e4e5b8SJoe Perches 	va_list args;
314905e4e5b8SJoe Perches 	int r;
315005e4e5b8SJoe Perches 
315105e4e5b8SJoe Perches 	va_start(args, fmt);
315205e4e5b8SJoe Perches 
315305e4e5b8SJoe Perches 	r = dev_vprintk_emit(level, dev, fmt, args);
315405e4e5b8SJoe Perches 
315505e4e5b8SJoe Perches 	va_end(args);
315605e4e5b8SJoe Perches 
315705e4e5b8SJoe Perches 	return r;
315805e4e5b8SJoe Perches }
315905e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit);
316005e4e5b8SJoe Perches 
3161d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev,
3162798efc60SJoe Perches 			struct va_format *vaf)
3163798efc60SJoe Perches {
3164d1f1052cSJoe Perches 	if (dev)
3165d1f1052cSJoe Perches 		dev_printk_emit(level[1] - '0', dev, "%s %s: %pV",
3166798efc60SJoe Perches 				dev_driver_string(dev), dev_name(dev), vaf);
3167d1f1052cSJoe Perches 	else
3168d1f1052cSJoe Perches 		printk("%s(NULL device *): %pV", level, vaf);
3169798efc60SJoe Perches }
317099bcf217SJoe Perches 
3171d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev,
317299bcf217SJoe Perches 		const char *fmt, ...)
317399bcf217SJoe Perches {
317499bcf217SJoe Perches 	struct va_format vaf;
317599bcf217SJoe Perches 	va_list args;
317699bcf217SJoe Perches 
317799bcf217SJoe Perches 	va_start(args, fmt);
317899bcf217SJoe Perches 
317999bcf217SJoe Perches 	vaf.fmt = fmt;
318099bcf217SJoe Perches 	vaf.va = &args;
318199bcf217SJoe Perches 
3182d1f1052cSJoe Perches 	__dev_printk(level, dev, &vaf);
3183798efc60SJoe Perches 
318499bcf217SJoe Perches 	va_end(args);
318599bcf217SJoe Perches }
318699bcf217SJoe Perches EXPORT_SYMBOL(dev_printk);
318799bcf217SJoe Perches 
318899bcf217SJoe Perches #define define_dev_printk_level(func, kern_level)		\
3189d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...)	\
319099bcf217SJoe Perches {								\
319199bcf217SJoe Perches 	struct va_format vaf;					\
319299bcf217SJoe Perches 	va_list args;						\
319399bcf217SJoe Perches 								\
319499bcf217SJoe Perches 	va_start(args, fmt);					\
319599bcf217SJoe Perches 								\
319699bcf217SJoe Perches 	vaf.fmt = fmt;						\
319799bcf217SJoe Perches 	vaf.va = &args;						\
319899bcf217SJoe Perches 								\
3199d1f1052cSJoe Perches 	__dev_printk(kern_level, dev, &vaf);			\
3200798efc60SJoe Perches 								\
320199bcf217SJoe Perches 	va_end(args);						\
320299bcf217SJoe Perches }								\
320399bcf217SJoe Perches EXPORT_SYMBOL(func);
320499bcf217SJoe Perches 
3205663336eeSJoe Perches define_dev_printk_level(_dev_emerg, KERN_EMERG);
3206663336eeSJoe Perches define_dev_printk_level(_dev_alert, KERN_ALERT);
3207663336eeSJoe Perches define_dev_printk_level(_dev_crit, KERN_CRIT);
3208663336eeSJoe Perches define_dev_printk_level(_dev_err, KERN_ERR);
3209663336eeSJoe Perches define_dev_printk_level(_dev_warn, KERN_WARNING);
3210663336eeSJoe Perches define_dev_printk_level(_dev_notice, KERN_NOTICE);
321199bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO);
321299bcf217SJoe Perches 
321399bcf217SJoe Perches #endif
321497badf87SRafael J. Wysocki 
321597badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
321697badf87SRafael J. Wysocki {
321797badf87SRafael J. Wysocki 	return fwnode && !IS_ERR(fwnode->secondary);
321897badf87SRafael J. Wysocki }
321997badf87SRafael J. Wysocki 
322097badf87SRafael J. Wysocki /**
322197badf87SRafael J. Wysocki  * set_primary_fwnode - Change the primary firmware node of a given device.
322297badf87SRafael J. Wysocki  * @dev: Device to handle.
322397badf87SRafael J. Wysocki  * @fwnode: New primary firmware node of the device.
322497badf87SRafael J. Wysocki  *
322597badf87SRafael J. Wysocki  * Set the device's firmware node pointer to @fwnode, but if a secondary
322697badf87SRafael J. Wysocki  * firmware node of the device is present, preserve it.
322797badf87SRafael J. Wysocki  */
322897badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
322997badf87SRafael J. Wysocki {
323097badf87SRafael J. Wysocki 	if (fwnode) {
323197badf87SRafael J. Wysocki 		struct fwnode_handle *fn = dev->fwnode;
323297badf87SRafael J. Wysocki 
323397badf87SRafael J. Wysocki 		if (fwnode_is_primary(fn))
323497badf87SRafael J. Wysocki 			fn = fn->secondary;
323597badf87SRafael J. Wysocki 
323655f89a8aSMika Westerberg 		if (fn) {
323755f89a8aSMika Westerberg 			WARN_ON(fwnode->secondary);
323897badf87SRafael J. Wysocki 			fwnode->secondary = fn;
323955f89a8aSMika Westerberg 		}
324097badf87SRafael J. Wysocki 		dev->fwnode = fwnode;
324197badf87SRafael J. Wysocki 	} else {
324297badf87SRafael J. Wysocki 		dev->fwnode = fwnode_is_primary(dev->fwnode) ?
324397badf87SRafael J. Wysocki 			dev->fwnode->secondary : NULL;
324497badf87SRafael J. Wysocki 	}
324597badf87SRafael J. Wysocki }
324697badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode);
324797badf87SRafael J. Wysocki 
324897badf87SRafael J. Wysocki /**
324997badf87SRafael J. Wysocki  * set_secondary_fwnode - Change the secondary firmware node of a given device.
325097badf87SRafael J. Wysocki  * @dev: Device to handle.
325197badf87SRafael J. Wysocki  * @fwnode: New secondary firmware node of the device.
325297badf87SRafael J. Wysocki  *
325397badf87SRafael J. Wysocki  * If a primary firmware node of the device is present, set its secondary
325497badf87SRafael J. Wysocki  * pointer to @fwnode.  Otherwise, set the device's firmware node pointer to
325597badf87SRafael J. Wysocki  * @fwnode.
325697badf87SRafael J. Wysocki  */
325797badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
325897badf87SRafael J. Wysocki {
325997badf87SRafael J. Wysocki 	if (fwnode)
326097badf87SRafael J. Wysocki 		fwnode->secondary = ERR_PTR(-ENODEV);
326197badf87SRafael J. Wysocki 
326297badf87SRafael J. Wysocki 	if (fwnode_is_primary(dev->fwnode))
326397badf87SRafael J. Wysocki 		dev->fwnode->secondary = fwnode;
326497badf87SRafael J. Wysocki 	else
326597badf87SRafael J. Wysocki 		dev->fwnode = fwnode;
326697badf87SRafael J. Wysocki }
32674e75e1d7SJohan Hovold 
32684e75e1d7SJohan Hovold /**
32694e75e1d7SJohan Hovold  * device_set_of_node_from_dev - reuse device-tree node of another device
32704e75e1d7SJohan Hovold  * @dev: device whose device-tree node is being set
32714e75e1d7SJohan Hovold  * @dev2: device whose device-tree node is being reused
32724e75e1d7SJohan Hovold  *
32734e75e1d7SJohan Hovold  * Takes another reference to the new device-tree node after first dropping
32744e75e1d7SJohan Hovold  * any reference held to the old node.
32754e75e1d7SJohan Hovold  */
32764e75e1d7SJohan Hovold void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
32774e75e1d7SJohan Hovold {
32784e75e1d7SJohan Hovold 	of_node_put(dev->of_node);
32794e75e1d7SJohan Hovold 	dev->of_node = of_node_get(dev2->of_node);
32804e75e1d7SJohan Hovold 	dev->of_node_reused = true;
32814e75e1d7SJohan Hovold }
32824e75e1d7SJohan Hovold EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
3283