core.c revision 8a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc)
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs
664bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
764bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc.
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is released under the GPLv2
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/err.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
1923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman#include <linux/kdev_t.h>
20116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt#include <linux/notifier.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/semaphore.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "base.h"
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "power/power.h"
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint (*platform_notify)(struct device * dev) = NULL;
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint (*platform_notify_remove)(struct device * dev) = NULL;
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sysfs bindings for devices.
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
343e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern/**
353e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * dev_driver_string - Return a device's driver name, if at all possible
363e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * @dev: struct device to get the name of
373e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern *
383e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * Will return the device's driver's name if it is bound to a device.  If
393e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * the device is not bound to a device, it will return the name of the bus
403e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * it is attached to.  If it is not attached to a bus either, an empty
413e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern * string will be returned.
423e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern */
433e95637a48820ff8bedb33e6439def96ccff1de5Alan Sternconst char *dev_driver_string(struct device *dev)
443e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern{
453e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern	return dev->driver ? dev->driver->name :
463e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern			(dev->bus ? dev->bus->name : "");
473e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern}
48310a922d4307ed38b37982a6f93b11fdf3b8dcb1Matthew WilcoxEXPORT_SYMBOL(dev_driver_string);
493e95637a48820ff8bedb33e6439def96ccff1de5Alan Stern
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define to_dev(obj) container_of(obj, struct device, kobj)
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device_attribute * dev_attr = to_dev_attr(attr);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device * dev = to_dev(kobj);
584a0c20bf8c0fe2116f8fd7d3da6122bf8a01f026Dmitry Torokhov	ssize_t ret = -EIO;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev_attr->show)
6154b6f35c99974e99e64c05c2895718355123c55fYani Ioannou		ret = dev_attr->show(dev, dev_attr, buf);
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdev_attr_store(struct kobject * kobj, struct attribute * attr,
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       const char * buf, size_t count)
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device_attribute * dev_attr = to_dev_attr(attr);
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device * dev = to_dev(kobj);
714a0c20bf8c0fe2116f8fd7d3da6122bf8a01f026Dmitry Torokhov	ssize_t ret = -EIO;
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev_attr->store)
7454b6f35c99974e99e64c05c2895718355123c55fYani Ioannou		ret = dev_attr->store(dev, dev_attr, buf, count);
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sysfs_ops dev_sysfs_ops = {
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.show	= dev_attr_show,
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.store	= dev_attr_store,
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_release - free device structure.
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@kobj:	device's kobject.
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This is called once the reference count for the object
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	reaches 0. We forward the call to the device's release
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	method, which should handle actually freeing the structure.
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void device_release(struct kobject * kobj)
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device * dev = to_dev(kobj);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev->release)
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev->release(dev);
982620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	else if (dev->class && dev->class->dev_release)
992620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		dev->class->dev_release(dev);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_ERR "Device '%s' does not have a release() function, "
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"it is broken and must be fixed.\n",
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dev->bus_id);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		WARN_ON(1);
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct kobj_type ktype_device = {
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.release	= device_release,
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.sysfs_ops	= &dev_sysfs_ops,
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
114312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sieversstatic int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct kobj_type *ktype = get_ktype(kobj);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ktype == &ktype_device) {
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct device *dev = to_dev(kobj);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dev->bus)
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;
12223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		if (dev->class)
12323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			return 1;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
128312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sieversstatic const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *dev = to_dev(kobj);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (dev->bus)
13323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		return dev->bus->name;
13423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (dev->class)
13523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		return dev->class->name;
13623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	return NULL;
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
139312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sieversstatic int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int num_envp, char *buffer, int buffer_size)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *dev = to_dev(kobj);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int length = 0;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int retval = 0;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	/* add the major/minor if present */
14823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (MAJOR(dev->devt)) {
14923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		add_uevent_var(envp, num_envp, &i,
15023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			       buffer, buffer_size, &length,
15123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			       "MAJOR=%u", MAJOR(dev->devt));
15223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		add_uevent_var(envp, num_envp, &i,
15323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			       buffer, buffer_size, &length,
15423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			       "MINOR=%u", MINOR(dev->devt));
15523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	}
15623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
157a87cb2ac4a78c590583b52a3ed196adc6c25b6c9Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
158d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers	/* add bus name (same as SUBSYSTEM, deprecated) */
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev->bus)
160312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers		add_uevent_var(envp, num_envp, &i,
161312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers			       buffer, buffer_size, &length,
162312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers			       "PHYSDEVBUS=%s", dev->bus->name);
163a87cb2ac4a78c590583b52a3ed196adc6c25b6c9Kay Sievers#endif
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
165d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers	/* add driver name (PHYSDEV* values are deprecated)*/
166d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers	if (dev->driver) {
167d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers		add_uevent_var(envp, num_envp, &i,
168d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers			       buffer, buffer_size, &length,
169d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers			       "DRIVER=%s", dev->driver->name);
170a87cb2ac4a78c590583b52a3ed196adc6c25b6c9Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
171312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers		add_uevent_var(envp, num_envp, &i,
172312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers			       buffer, buffer_size, &length,
173312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers			       "PHYSDEVDRIVER=%s", dev->driver->name);
174a87cb2ac4a78c590583b52a3ed196adc6c25b6c9Kay Sievers#endif
175d81d9d6b9f7d0af7d4341951d48d296681878f7aKay Sievers	}
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* terminate, set to next free slot, shrink available space */
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	envp[i] = NULL;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	envp = &envp[i];
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	num_envp -= i;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer = &buffer[length];
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer_size -= length;
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
184312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	if (dev->bus && dev->bus->uevent) {
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* have the bus specific function add its stuff */
186312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers		retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (retval) {
188312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers			pr_debug ("%s - uevent() returned %d\n",
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  __FUNCTION__, retval);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1932620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (dev->class && dev->class->dev_uevent) {
1942620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		/* have the class specific function add its stuff */
1952620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
1962620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman			if (retval) {
1972620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman				pr_debug("%s - dev_uevent() returned %d\n",
1982620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman					 __FUNCTION__, retval);
1992620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		}
2002620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	}
2012620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return retval;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
205312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sieversstatic struct kset_uevent_ops device_uevent_ops = {
206312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	.filter =	dev_uevent_filter,
207312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	.name =		dev_uevent_name,
208312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	.uevent =	dev_uevent,
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sieversstatic ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
212a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers			    const char *buf, size_t count)
213a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers{
214312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	kobject_uevent(&dev->kobj, KOBJ_ADD);
215a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	return count;
216a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers}
217a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers
218de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartmanstatic int device_add_groups(struct device *dev)
219de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman{
220de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	int i;
221de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	int error = 0;
222de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman
223de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	if (dev->groups) {
224de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman		for (i = 0; dev->groups[i]; i++) {
225de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman			error = sysfs_create_group(&dev->kobj, dev->groups[i]);
226de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman			if (error) {
227de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman				while (--i >= 0)
228de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman					sysfs_remove_group(&dev->kobj, dev->groups[i]);
229de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman				goto out;
230de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman			}
231de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman		}
232de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	}
233de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartmanout:
234de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	return error;
235de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman}
236de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman
237de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartmanstatic void device_remove_groups(struct device *dev)
238de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman{
239de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	int i;
240de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	if (dev->groups) {
241de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman		for (i = 0; dev->groups[i]; i++) {
242de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman			sysfs_remove_group(&dev->kobj, dev->groups[i]);
243de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman		}
244de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	}
245de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman}
246de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman
2472620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartmanstatic int device_add_attrs(struct device *dev)
2482620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman{
2492620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	struct class *class = dev->class;
2502620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	int error = 0;
2512620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	int i;
2522620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2532620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (!class)
2542620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		return 0;
2552620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2562620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (class->dev_attrs) {
2572620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		for (i = 0; attr_name(class->dev_attrs[i]); i++) {
2582620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman			error = device_create_file(dev, &class->dev_attrs[i]);
2592620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman			if (error)
2602620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman				break;
2612620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		}
2622620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	}
2632620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (error)
2642620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		while (--i >= 0)
2652620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman			device_remove_file(dev, &class->dev_attrs[i]);
2662620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	return error;
2672620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman}
2682620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2692620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartmanstatic void device_remove_attrs(struct device *dev)
2702620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman{
2712620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	struct class *class = dev->class;
2722620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	int i;
2732620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2742620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (!class)
2752620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		return;
2762620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2772620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if (class->dev_attrs) {
2782620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		for (i = 0; attr_name(class->dev_attrs[i]); i++)
2792620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman			device_remove_file(dev, &class->dev_attrs[i]);
2802620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	}
2812620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman}
2822620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
2832620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman
28423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartmanstatic ssize_t show_dev(struct device *dev, struct device_attribute *attr,
28523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			char *buf)
28623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman{
28723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	return print_dev_t(buf, dev->devt);
28823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman}
28923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
2900863afb32b77fc89c7110b3d10fb048cb56bb1b5Martin Waitz/*
2910863afb32b77fc89c7110b3d10fb048cb56bb1b5Martin Waitz *	devices_subsys - structure to be registered with kobject core.
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
294312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sieversdecl_subsys(devices, &ktype_device, &device_uevent_ops);
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_create_file - create sysfs attribute file for device.
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@attr:	device attribute descriptor.
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint device_create_file(struct device * dev, struct device_attribute * attr)
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (get_device(dev)) {
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		error = sysfs_create_file(&dev->kobj, &attr->attr);
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(dev);
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_remove_file - remove sysfs attribute file.
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@attr:	device attribute descriptor.
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid device_remove_file(struct device * dev, struct device_attribute * attr)
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (get_device(dev)) {
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sysfs_remove_file(&dev->kobj, &attr->attr);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(dev);
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3272589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman/**
3282589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device.
3292589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * @dev: device.
3302589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * @attr: device binary attribute descriptor.
3312589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman */
3322589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartmanint device_create_bin_file(struct device *dev, struct bin_attribute *attr)
3332589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman{
3342589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman	int error = -EINVAL;
3352589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman	if (dev)
3362589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman		error = sysfs_create_bin_file(&dev->kobj, attr);
3372589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman	return error;
3382589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman}
3392589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-HartmanEXPORT_SYMBOL_GPL(device_create_bin_file);
3402589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman
3412589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman/**
3422589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file
3432589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * @dev: device.
3442589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman * @attr: device binary attribute descriptor.
3452589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman */
3462589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartmanvoid device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
3472589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman{
3482589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman	if (dev)
3492589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman		sysfs_remove_bin_file(&dev->kobj, attr);
3502589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman}
3512589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-HartmanEXPORT_SYMBOL_GPL(device_remove_bin_file);
3522589f1887b0bf9f08ec3d7f3c5705ccb7c628076Greg Kroah-Hartman
35334bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomleystatic void klist_children_get(struct klist_node *n)
35434bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley{
35534bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley	struct device *dev = container_of(n, struct device, knode_parent);
35634bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley
35734bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley	get_device(dev);
35834bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley}
35934bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley
36034bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomleystatic void klist_children_put(struct klist_node *n)
36134bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley{
36234bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley	struct device *dev = container_of(n, struct device, knode_parent);
36334bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley
36434bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley	put_device(dev);
36534bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley}
36634bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_initialize - init device structure.
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This prepares the device for use by other layers,
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	including adding it to the device hierarchy.
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	It is the first half of device_register(), if called by
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	that, though it can also be called separately, so one
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	may use @dev's fields (e.g. the refcount).
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid device_initialize(struct device *dev)
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobj_set_kset_s(dev, devices_subsys);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobject_init(&dev->kobj);
38334bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley	klist_init(&dev->klist_children, klist_children_get,
38434bb61f9ddabd7a7f909cbfb05592eb775f6662aJames Bottomley		   klist_children_put);
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&dev->dma_pools);
38623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	INIT_LIST_HEAD(&dev->node);
387af70316af182f4716cc5eec7e0d27fc731d164bdPatrick Mochel	init_MUTEX(&dev->sem);
3880ac85241ebc7bf6b86ab498960cc121d53ef69aeDavid Brownell	device_init_wakeup(dev, 0);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
39140fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman#ifdef CONFIG_SYSFS_DEPRECATED
392af9e0765362151b27372c14d9d6dc417184182d3Adrian Bunkstatic int setup_parent(struct device *dev, struct device *parent)
39340fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman{
39440fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	/* Set the parent to the class, not the parent device */
39540fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	/* this keeps sysfs from having a symlink to make old udevs happy */
39640fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	if (dev->class)
39740fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		dev->kobj.parent = &dev->class->subsys.kset.kobj;
39840fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	else if (parent)
39940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		dev->kobj.parent = &parent->kobj;
40040fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman
40140fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	return 0;
40240fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman}
40340fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman#else
404f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartmanstatic int virtual_device_parent(struct device *dev)
405f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman{
406f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman	if (!dev->class)
407f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman		return -ENODEV;
408f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman
409f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman	if (!dev->class->virtual_dir) {
410f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman		static struct kobject *virtual_dir = NULL;
411f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman
412f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman		if (!virtual_dir)
413f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman			virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual");
414f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman		dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
415f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman	}
416f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman
417f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman	dev->kobj.parent = dev->class->virtual_dir;
418f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman	return 0;
419f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman}
420f0ee61a6cecd100301a60d99feb187776533b2a2Greg Kroah-Hartman
421af9e0765362151b27372c14d9d6dc417184182d3Adrian Bunkstatic int setup_parent(struct device *dev, struct device *parent)
42240fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman{
42340fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	int error;
42440fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman
42540fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	/* if this is a class device, and has no parent, create one */
42640fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	if ((dev->class) && (parent == NULL)) {
42740fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		error = virtual_device_parent(dev);
42840fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		if (error)
42940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman			return error;
43040fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	} else if (parent)
43140fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		dev->kobj.parent = &parent->kobj;
43240fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman
43340fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	return 0;
43440fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman}
43540fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman#endif
43640fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_add - add device to device hierarchy.
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This is part 2 of device_register(), though may be called
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	separately _iff_ device_initialize() has been called separately.
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This adds it to the kobject hierarchy via kobject_add(), adds it
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	to the global and sibling lists for the device, then
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	adds it to the other relevant subsystems of the driver model.
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint device_add(struct device *dev)
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *parent = NULL;
451e9a7d305faec364ba973d6c22c9b1e802ef79204Greg Kroah-Hartman	char *class_name = NULL;
452c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman	struct class_interface *class_intf;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = -EINVAL;
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev = get_device(dev);
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev || !strlen(dev->bus_id))
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto Error;
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
45940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
460c205ef4880273d2de4ee5388d4e52227ff688cc4Greg Kroah-Hartman
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	parent = get_device(dev->parent);
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46340fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	error = setup_parent(dev, parent);
46440fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	if (error)
46540fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		goto Error;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* first, register with generic layer. */
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobject_set_name(&dev->kobj, "%s", dev->bus_id);
46940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	error = kobject_add(&dev->kobj);
47040fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman	if (error)
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto Error;
472a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers
473370226449ced358e52d198081120826ef52c166bBrian Walsh	/* notify platform of device entry */
474370226449ced358e52d198081120826ef52c166bBrian Walsh	if (platform_notify)
475370226449ced358e52d198081120826ef52c166bBrian Walsh		platform_notify(dev);
476370226449ced358e52d198081120826ef52c166bBrian Walsh
477116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt	/* notify clients of device entry (new way) */
478116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt	if (dev->bus)
479116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt		blocking_notifier_call_chain(&dev->bus->bus_notifier,
480116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt					     BUS_NOTIFY_ADD_DEVICE, dev);
481116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt
482a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	dev->uevent_attr.attr.name = "uevent";
483a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	dev->uevent_attr.attr.mode = S_IWUSR;
484a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	if (dev->driver)
485a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers		dev->uevent_attr.attr.owner = dev->driver->owner;
486a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	dev->uevent_attr.store = store_uevent;
487a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck	error = device_create_file(dev, &dev->uevent_attr);
488a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck	if (error)
489a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck		goto attrError;
490a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers
49123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (MAJOR(dev->devt)) {
49223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		struct device_attribute *attr;
49323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
49423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		if (!attr) {
49523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			error = -ENOMEM;
496a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck			goto ueventattrError;
49723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		}
49823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		attr->attr.name = "dev";
49923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		attr->attr.mode = S_IRUGO;
50023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		if (dev->driver)
50123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			attr->attr.owner = dev->driver->owner;
50223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		attr->show = show_dev;
50323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		error = device_create_file(dev, attr);
50423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		if (error) {
50523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			kfree(attr);
506a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck			goto ueventattrError;
50723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		}
50823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
50923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		dev->devt_attr = attr;
51023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	}
51123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
512b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers	if (dev->class) {
513b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers		sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj,
514b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers				  "subsystem");
51540fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		/* If this is not a "fake" compatible device, then create the
51640fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		 * symlink from the class to the device. */
51740fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
51840fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman			sysfs_create_link(&dev->class->subsys.kset.kobj,
51940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman					  &dev->kobj, dev->bus_id);
52099ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
52164bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman		if (parent) {
52264bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman			sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
52364bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman			class_name = make_class_name(dev->class->name, &dev->kobj);
52464bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman			sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
52564bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman		}
52699ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#endif
527b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers	}
52823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
5292620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	if ((error = device_add_attrs(dev)))
5302620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman		goto AttrsError;
531de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	if ((error = device_add_groups(dev)))
532de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman		goto GroupError;
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((error = device_pm_add(dev)))
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto PMError;
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((error = bus_add_device(dev)))
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto BusError;
53753877d06d53a412d901bb323f080296c363d8b51Kay Sievers	kobject_uevent(&dev->kobj, KOBJ_ADD);
538f70fa6296c2ec8f541f0a9b406ccc2d9d127d639Alan Stern	if ((error = bus_attach_device(dev)))
539f70fa6296c2ec8f541f0a9b406ccc2d9d127d639Alan Stern		goto AttachError;
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (parent)
541d856f1e337782326c638c70c0b4df2b909350decJames Bottomley		klist_add_tail(&dev->knode_parent, &parent->klist_children);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5435d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman	if (dev->class) {
5445d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		down(&dev->class->sem);
545c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		/* tie the class to the device */
5465d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		list_add_tail(&dev->node, &dev->class->devices);
547c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman
548c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		/* notify any interfaces that the device is here */
549c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		list_for_each_entry(class_intf, &dev->class->interfaces, node)
550c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman			if (class_intf->add_dev)
551c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman				class_intf->add_dev(dev, class_intf);
5525d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		up(&dev->class->sem);
5535d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman	}
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Done:
555e9a7d305faec364ba973d6c22c9b1e802ef79204Greg Kroah-Hartman 	kfree(class_name);
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(dev);
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
558f70fa6296c2ec8f541f0a9b406ccc2d9d127d639Alan Stern AttachError:
559f70fa6296c2ec8f541f0a9b406ccc2d9d127d639Alan Stern	bus_remove_device(dev);
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BusError:
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	device_pm_remove(dev);
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PMError:
563116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt	if (dev->bus)
564116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt		blocking_notifier_call_chain(&dev->bus->bus_notifier,
565116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt					     BUS_NOTIFY_DEL_DEVICE, dev);
566de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	device_remove_groups(dev);
567de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman GroupError:
5682620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman 	device_remove_attrs(dev);
5692620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman AttrsError:
57023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (dev->devt_attr) {
57123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		device_remove_file(dev, dev->devt_attr);
57223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		kfree(dev->devt_attr);
57323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	}
574a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck ueventattrError:
575a306eea40952e6365301e8a2f7d5ffa9c6a1921bCornelia Huck	device_remove_file(dev, &dev->uevent_attr);
57623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman attrError:
577312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobject_del(&dev->kobj);
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Error:
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (parent)
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(parent);
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	goto Done;
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_register - register a device with the system.
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	pointer to the device structure
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This happens in two clean steps - initialize the device
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	and add it to the system. The two steps can be called
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	separately, but this is the easiest and most common.
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	I.e. you should only call the two helpers separately if
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	have a clearly defined need to use and refcount the device
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	before it is added to the hierarchy.
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint device_register(struct device *dev)
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	device_initialize(dev);
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return device_add(dev);
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	get_device - increment reference count for device.
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This simply forwards the call to kobject_get(), though
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	we do take care to provide for the case that we get a NULL
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	pointer passed in.
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct device * get_device(struct device * dev)
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	put_device - decrement reference count.
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device in question.
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid put_device(struct device * dev)
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev)
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kobject_put(&dev->kobj);
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_del - delete device from system.
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device.
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This is the first part of the device unregistration
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	sequence. This removes the device from the lists we control
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	from here, has it removed from the other driver model
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	subsystems it was added to in device_add(), and removes it
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	from the kobject hierarchy.
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	NOTE: this should be called manually _iff_ device_add() was
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	also called manually.
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid device_del(struct device * dev)
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device * parent = dev->parent;
648c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman	struct class_interface *class_intf;
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (parent)
651d62c0f9fd2d3943a3eca85b490d86e1605000ccbPatrick Mochel		klist_del(&dev->knode_parent);
65282189b9807e05ea8d1f69de5bf92eaf244a0eb12Catalin Marinas	if (dev->devt_attr) {
65323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		device_remove_file(dev, dev->devt_attr);
65482189b9807e05ea8d1f69de5bf92eaf244a0eb12Catalin Marinas		kfree(dev->devt_attr);
65582189b9807e05ea8d1f69de5bf92eaf244a0eb12Catalin Marinas	}
656b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers	if (dev->class) {
657b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers		sysfs_remove_link(&dev->kobj, "subsystem");
65840fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		/* If this is not a "fake" compatible device, remove the
65940fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		 * symlink from the class to the device. */
66040fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
66140fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman			sysfs_remove_link(&dev->class->subsys.kset.kobj,
66240fa54226f518a9bc97ed1d711c0016e416e3782Greg Kroah-Hartman					  dev->bus_id);
66399ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
66464bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman		if (parent) {
66599ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers			char *class_name = make_class_name(dev->class->name,
66699ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers							   &dev->kobj);
66764bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman			sysfs_remove_link(&dev->parent->kobj, class_name);
66899ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers			kfree(class_name);
66999ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers			sysfs_remove_link(&dev->kobj, "device");
67064bb5d2c116478dba7501d2acf078ed74ba30c1fGreg Kroah-Hartman		}
67199ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#endif
67299ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers
6735d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		down(&dev->class->sem);
674c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		/* notify any interfaces that the device is now gone */
675c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		list_for_each_entry(class_intf, &dev->class->interfaces, node)
676c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman			if (class_intf->remove_dev)
677c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman				class_intf->remove_dev(dev, class_intf);
678c47ed219ba81632595e9f02e27318151fec16c9eGreg Kroah-Hartman		/* remove the device from the class list */
6795d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		list_del_init(&dev->node);
6805d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman		up(&dev->class->sem);
681b9d9c82b4d081feb464f62dfc786c8621d09ecd2Kay Sievers	}
682a7fd67062efc5b0fc9a61368c607fa92d1d57f9eKay Sievers	device_remove_file(dev, &dev->uevent_attr);
683de0ff00d723fd821d372496e2c084805644aa5e1Greg Kroah-Hartman	device_remove_groups(dev);
6842620efef7029bb040430f50f0fc148f2d5e002adGreg Kroah-Hartman	device_remove_attrs(dev);
685289535334646796fe41f199718e4a731f7411a92Benjamin Herrenschmidt	bus_remove_device(dev);
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Notify the platform of the removal, in case they
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * need to do anything...
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (platform_notify_remove)
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		platform_notify_remove(dev);
692116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt	if (dev->bus)
693116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt		blocking_notifier_call_chain(&dev->bus->bus_notifier,
694116af378201ef793424cd10508ccf18b06d8a021Benjamin Herrenschmidt					     BUS_NOTIFY_DEL_DEVICE, dev);
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	device_pm_remove(dev);
696312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kobject_del(&dev->kobj);
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (parent)
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(parent);
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_unregister - unregister device from system.
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	device going away.
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	We do this in two parts, like we do device_register(). First,
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	we remove it from all the subsystems with device_del(), then
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	we decrement the reference count via put_device(). If that
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	is the final reference count, the device will be cleaned up
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	via device_release() above. Otherwise, the structure will
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	stick around until the final reference to the device is dropped.
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid device_unregister(struct device * dev)
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id);
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	device_del(dev);
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(dev);
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
72136239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochelstatic struct device * next_device(struct klist_iter * i)
72236239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel{
72336239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	struct klist_node * n = klist_next(i);
72436239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	return n ? container_of(n, struct device, knode_parent) : NULL;
72536239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel}
72636239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_for_each_child - device child iterator.
729c41455fbac06712992da491844449775cf9a8c80Randy Dunlap *	@parent: parent struct device.
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@data:	data for the callback.
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@fn:	function to be called for each device.
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
733c41455fbac06712992da491844449775cf9a8c80Randy Dunlap *	Iterate over @parent's child devices, and call @fn for each,
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	passing it @data.
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	We check the return of @fn each time. If it returns anything
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	other than 0, we break out and return that value.
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
73936239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochelint device_for_each_child(struct device * parent, void * data,
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int (*fn)(struct device *, void *))
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
74236239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	struct klist_iter i;
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device * child;
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
74636239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	klist_iter_init(&parent->klist_children, &i);
74736239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	while ((child = next_device(&i)) && !error)
74836239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel		error = fn(child, data);
74936239577cfb6b9a7c111209536b54200b0252ebfPatrick Mochel	klist_iter_exit(&i);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7535ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck/**
7545ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * device_find_child - device iterator for locating a particular device.
7555ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * @parent: parent struct device
7565ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * @data: Data to pass to match function
7575ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * @match: Callback function to check device
7585ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck *
7595ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * This is similar to the device_for_each_child() function above, but it
7605ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * returns a reference to a device that is 'found' for later use, as
7615ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * determined by the @match callback.
7625ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck *
7635ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * The callback should return 0 if the device doesn't match and non-zero
7645ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * if it does.  If the callback returns non-zero and a reference to the
7655ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * current device can be obtained, this function will return to the caller
7665ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck * and not iterate over any more devices.
7675ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck */
7685ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huckstruct device * device_find_child(struct device *parent, void *data,
7695ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck				  int (*match)(struct device *, void *))
7705ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck{
7715ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	struct klist_iter i;
7725ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	struct device *child;
7735ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck
7745ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	if (!parent)
7755ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck		return NULL;
7765ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck
7775ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	klist_iter_init(&parent->klist_children, &i);
7785ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	while ((child = next_device(&i)))
7795ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck		if (match(child, data) && get_device(child))
7805ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck			break;
7815ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	klist_iter_exit(&i);
7825ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck	return child;
7835ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck}
7845ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia Huck
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init devices_init(void)
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return subsystem_register(&devices_subsys);
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_for_each_child);
7915ab699810d46011ad2195c5916f3cbc684bfe3eeCornelia HuckEXPORT_SYMBOL_GPL(device_find_child);
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_initialize);
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_add);
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_register);
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_del);
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_unregister);
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(get_device);
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(put_device);
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_create_file);
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL(device_remove_file);
80423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
80523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
80623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartmanstatic void device_create_release(struct device *dev)
80723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman{
80823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id);
80923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	kfree(dev);
81023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman}
81123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
81223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman/**
81323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs
81442734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @class: pointer to the struct class that this device should be registered to
81542734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @parent: pointer to the parent struct device of this new device, if any
81642734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @devt: the dev_t for the char device to be added
81742734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @fmt: string for the device's name
81842734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar *
81942734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * This function can be used by char device classes.  A struct device
82042734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * will be created in sysfs, registered to the specified class.
82123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman *
82223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if
82323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * the dev_t is not 0,0.
82442734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * If a pointer to a parent struct device is passed in, the newly created
82542734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * struct device will be a child of that device in sysfs.
82642734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * The pointer to the struct device will be returned from the call.
82742734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * Any further sysfs files that might be required can be created using this
82823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * pointer.
82923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman *
83023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * Note: the struct class passed to this function must have previously
83123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * been created with a call to class_create().
83223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman */
83323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartmanstruct device *device_create(struct class *class, struct device *parent,
8345cbe5f8a5897470698222ac9924429056e57d84cGreg Kroah-Hartman			     dev_t devt, const char *fmt, ...)
83523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman{
83623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	va_list args;
83723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	struct device *dev = NULL;
83823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	int retval = -ENODEV;
83923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
84023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (class == NULL || IS_ERR(class))
84123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		goto error;
84223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
84323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
84423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (!dev) {
84523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		retval = -ENOMEM;
84623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		goto error;
84723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	}
84823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
84923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	dev->devt = devt;
85023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	dev->class = class;
85123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	dev->parent = parent;
85223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	dev->release = device_create_release;
85323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
85423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	va_start(args, fmt);
85523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
85623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	va_end(args);
85723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	retval = device_register(dev);
85823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	if (retval)
85923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		goto error;
86023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
86123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	return dev;
86223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
86323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartmanerror:
86423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	kfree(dev);
86523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	return ERR_PTR(retval);
86623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman}
86723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-HartmanEXPORT_SYMBOL_GPL(device_create);
86823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
86923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman/**
87023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman * device_destroy - removes a device that was created with device_create()
87142734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @class: pointer to the struct class that this device was registered with
87242734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * @devt: the dev_t of the device that was previously registered
87323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman *
87442734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * This call unregisters and cleans up a device that was created with a
87542734dafa43e453a8b6769a5ebd3a01ffc1fd116Henrik Kretzschmar * call to device_create().
87623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman */
87723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartmanvoid device_destroy(struct class *class, dev_t devt)
87823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman{
87923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	struct device *dev = NULL;
88023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	struct device *dev_tmp;
88123681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
88223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	down(&class->sem);
88323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	list_for_each_entry(dev_tmp, &class->devices, node) {
88423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		if (dev_tmp->devt == devt) {
88523681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			dev = dev_tmp;
88623681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman			break;
88723681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		}
88823681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	}
88923681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman	up(&class->sem);
89023681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman
8915d9fd169c9fbdaecdc430431e59bf94ff40b93d3Greg Kroah-Hartman	if (dev)
89223681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman		device_unregister(dev);
89323681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-Hartman}
89423681e479129854305da1da32f7f1eaf635ef22cGreg Kroah-HartmanEXPORT_SYMBOL_GPL(device_destroy);
895a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
896a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman/**
897a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman * device_rename - renames a device
898a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed
899a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman * @new_name: the new name of the device
900a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman */
901a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartmanint device_rename(struct device *dev, char *new_name)
902a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman{
903a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	char *old_class_name = NULL;
904a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	char *new_class_name = NULL;
905a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	char *old_symlink_name = NULL;
906a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	int error;
907a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
908a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	dev = get_device(dev);
909a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	if (!dev)
910a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		return -EINVAL;
911a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
912a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name);
913a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
91499ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
915a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	if ((dev->class) && (dev->parent))
916a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		old_class_name = make_class_name(dev->class->name, &dev->kobj);
91799ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#endif
918a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
919a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	if (dev->class) {
920a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
921952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl		if (!old_symlink_name) {
922952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl			error = -ENOMEM;
923952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl			goto out_free_old_class;
924952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl		}
925a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
926a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	}
927a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
928a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
929a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
930a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	error = kobject_rename(&dev->kobj, new_name);
931a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
93299ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#ifdef CONFIG_SYSFS_DEPRECATED
933a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	if (old_class_name) {
934a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		new_class_name = make_class_name(dev->class->name, &dev->kobj);
935a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		if (new_class_name) {
936a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman			sysfs_create_link(&dev->parent->kobj, &dev->kobj,
937a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman					  new_class_name);
938a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman			sysfs_remove_link(&dev->parent->kobj, old_class_name);
939a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		}
940a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	}
94199ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers#endif
94299ef3ef8d5f2f5b5312627127ad63df27c0d0d05Kay Sievers
943a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	if (dev->class) {
944a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		sysfs_remove_link(&dev->class->subsys.kset.kobj,
945a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman				  old_symlink_name);
946a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman		sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
947a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman				  dev->bus_id);
948a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	}
949a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	put_device(dev);
950a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
951a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	kfree(new_class_name);
952a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	kfree(old_symlink_name);
953952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl out_free_old_class:
954952ab431cd36c7ab573f685af8679c3677cbdc29Jesper Juhl	kfree(old_class_name);
955a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman
956a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman	return error;
957a2de48cace5d0993da6cfa28b276ae724dc3569bGreg Kroah-Hartman}
9588a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
9598a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
9608a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckstatic int device_move_class_links(struct device *dev,
9618a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck				   struct device *old_parent,
9628a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck				   struct device *new_parent)
9638a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck{
9648a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck#ifdef CONFIG_SYSFS_DEPRECATED
9658a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	int error;
9668a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	char *class_name;
9678a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
9688a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	class_name = make_class_name(dev->class->name, &dev->kobj);
9698a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!class_name) {
9708a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		error = PTR_ERR(class_name);
9718a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		class_name = NULL;
9728a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
9738a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
9748a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (old_parent) {
9758a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		sysfs_remove_link(&dev->kobj, "device");
9768a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		sysfs_remove_link(&old_parent->kobj, class_name);
9778a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
9788a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device");
9798a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (error)
9808a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
9818a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name);
9828a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (error)
9838a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		sysfs_remove_link(&dev->kobj, "device");
9848a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckout:
9858a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	kfree(class_name);
9868a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	return error;
9878a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck#else
9888a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	return 0;
9898a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck#endif
9908a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck}
9918a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
9928a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck/**
9938a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck * device_move - moves a device to a new parent
9948a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck * @dev: the pointer to the struct device to be moved
9958a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck * @new_parent: the new parent of the device
9968a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck */
9978a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckint device_move(struct device *dev, struct device *new_parent)
9988a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck{
9998a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	int error;
10008a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	struct device *old_parent;
10018a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
10028a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	dev = get_device(dev);
10038a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!dev)
10048a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		return -EINVAL;
10058a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
10068a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!device_is_registered(dev)) {
10078a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		error = -EINVAL;
10088a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
10098a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
10108a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	new_parent = get_device(new_parent);
10118a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!new_parent) {
10128a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		error = -EINVAL;
10138a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
10148a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
10158a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
10168a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		new_parent->bus_id);
10178a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	error = kobject_move(&dev->kobj, &new_parent->kobj);
10188a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (error) {
10198a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		put_device(new_parent);
10208a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
10218a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
10228a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	old_parent = dev->parent;
10238a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	dev->parent = new_parent;
10248a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (old_parent)
10258a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		klist_del(&dev->knode_parent);
10268a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
10278a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (!dev->class)
10288a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out_put;
10298a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	error = device_move_class_links(dev, old_parent, new_parent);
10308a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	if (error) {
10318a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		/* We ignore errors on cleanup since we're hosed anyway... */
10328a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		device_move_class_links(dev, new_parent, old_parent);
10338a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
10348a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck			klist_del(&dev->knode_parent);
10358a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck			if (old_parent)
10368a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck				klist_add_tail(&dev->knode_parent,
10378a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck					       &old_parent->klist_children);
10388a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		}
10398a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		put_device(new_parent);
10408a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck		goto out;
10418a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	}
10428a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckout_put:
10438a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	put_device(old_parent);
10448a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huckout:
10458a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	put_device(dev);
10468a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck	return error;
10478a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck}
10488a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia Huck
10498a82472f86bf693b8e91ed56c9ca4f62fbbdcfa3Cornelia HuckEXPORT_SYMBOL_GPL(device_move);
1050