11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc) 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 664bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de> 764bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * This file is released under the GPLv2 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds #include <linux/device.h> 141da177e4SLinus Torvalds #include <linux/err.h> 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> 24815d2d50SAndrew Morton #include <linux/kallsyms.h> 25f75b1c60SDave Young #include <linux/mutex.h> 26af8db150SPeter Chen #include <linux/pm_runtime.h> 27c4e00daaSKay Sievers #include <linux/netdevice.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 461da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 471da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 48e105b8bfSDan Williams static struct kobject *dev_kobj; 49e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 50e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 511da177e4SLinus Torvalds 525e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 535e33bc41SRafael J. Wysocki 545e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 555e33bc41SRafael J. Wysocki { 565e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 575e33bc41SRafael J. Wysocki } 585e33bc41SRafael J. Wysocki 595e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 605e33bc41SRafael J. Wysocki { 615e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 625e33bc41SRafael J. Wysocki } 635e33bc41SRafael J. Wysocki 645e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 655e33bc41SRafael J. Wysocki { 665e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 675e33bc41SRafael J. Wysocki return 0; 685e33bc41SRafael J. Wysocki 695e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 705e33bc41SRafael J. Wysocki msleep(5); 715e33bc41SRafael J. Wysocki return restart_syscall(); 725e33bc41SRafael J. Wysocki } 735e33bc41SRafael J. Wysocki 744e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 754e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 764e886c29SGreg Kroah-Hartman { 774e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 784e886c29SGreg Kroah-Hartman } 794e886c29SGreg Kroah-Hartman #else 804e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 814e886c29SGreg Kroah-Hartman { 824e886c29SGreg Kroah-Hartman return 1; 834e886c29SGreg Kroah-Hartman } 844e886c29SGreg Kroah-Hartman #endif 851da177e4SLinus Torvalds 863e95637aSAlan Stern /** 873e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 883e95637aSAlan Stern * @dev: struct device to get the name of 893e95637aSAlan Stern * 903e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 919169c012Syan * the device is not bound to a driver, it will return the name of the bus 923e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 933e95637aSAlan Stern * string will be returned. 943e95637aSAlan Stern */ 95bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 963e95637aSAlan Stern { 973589972eSAlan Stern struct device_driver *drv; 983589972eSAlan Stern 993589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 1003589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 1013589972eSAlan Stern * never change once they are set, so they don't need special care. 1023589972eSAlan Stern */ 1033589972eSAlan Stern drv = ACCESS_ONCE(dev->driver); 1043589972eSAlan Stern return drv ? drv->name : 105a456b702SJean Delvare (dev->bus ? dev->bus->name : 106a456b702SJean Delvare (dev->class ? dev->class->name : "")); 1073e95637aSAlan Stern } 108310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 1093e95637aSAlan Stern 1101da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 1111da177e4SLinus Torvalds 1124a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 1134a3ad20cSGreg Kroah-Hartman char *buf) 1141da177e4SLinus Torvalds { 1151da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 116b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1174a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds if (dev_attr->show) 12054b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 121815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 12253a9c87eSGreg Kroah-Hartman print_symbol("dev_attr_show: %s returned bad count\n", 12353a9c87eSGreg Kroah-Hartman (unsigned long)dev_attr->show); 124815d2d50SAndrew Morton } 1251da177e4SLinus Torvalds return ret; 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds 1284a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 1291da177e4SLinus Torvalds const char *buf, size_t count) 1301da177e4SLinus Torvalds { 1311da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 132b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1334a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds if (dev_attr->store) 13654b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 1371da177e4SLinus Torvalds return ret; 1381da177e4SLinus Torvalds } 1391da177e4SLinus Torvalds 14052cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 1411da177e4SLinus Torvalds .show = dev_attr_show, 1421da177e4SLinus Torvalds .store = dev_attr_store, 1431da177e4SLinus Torvalds }; 1441da177e4SLinus Torvalds 145ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 146ca22e56dSKay Sievers 147ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 148ca22e56dSKay Sievers struct device_attribute *attr, 149ca22e56dSKay Sievers const char *buf, size_t size) 150ca22e56dSKay Sievers { 151ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 152ca22e56dSKay Sievers char *end; 153ca22e56dSKay Sievers unsigned long new = simple_strtoul(buf, &end, 0); 154ca22e56dSKay Sievers if (end == buf) 155ca22e56dSKay Sievers return -EINVAL; 156ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 157ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 158ca22e56dSKay Sievers return size; 159ca22e56dSKay Sievers } 160ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 161ca22e56dSKay Sievers 162ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 163ca22e56dSKay Sievers struct device_attribute *attr, 164ca22e56dSKay Sievers char *buf) 165ca22e56dSKay Sievers { 166ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 167ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); 168ca22e56dSKay Sievers } 169ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 170ca22e56dSKay Sievers 171ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 172ca22e56dSKay Sievers struct device_attribute *attr, 173ca22e56dSKay Sievers const char *buf, size_t size) 174ca22e56dSKay Sievers { 175ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 176ca22e56dSKay Sievers char *end; 177ca22e56dSKay Sievers long new = simple_strtol(buf, &end, 0); 178ca22e56dSKay Sievers if (end == buf || new > INT_MAX || new < INT_MIN) 179ca22e56dSKay Sievers return -EINVAL; 180ca22e56dSKay Sievers *(int *)(ea->var) = new; 181ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 182ca22e56dSKay Sievers return size; 183ca22e56dSKay Sievers } 184ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 185ca22e56dSKay Sievers 186ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 187ca22e56dSKay Sievers struct device_attribute *attr, 188ca22e56dSKay Sievers char *buf) 189ca22e56dSKay Sievers { 190ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 191ca22e56dSKay Sievers 192ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); 193ca22e56dSKay Sievers } 194ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 1951da177e4SLinus Torvalds 19691872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 19791872392SBorislav Petkov const char *buf, size_t size) 19891872392SBorislav Petkov { 19991872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 20091872392SBorislav Petkov 20191872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 20291872392SBorislav Petkov return -EINVAL; 20391872392SBorislav Petkov 20491872392SBorislav Petkov return size; 20591872392SBorislav Petkov } 20691872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 20791872392SBorislav Petkov 20891872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 20991872392SBorislav Petkov char *buf) 21091872392SBorislav Petkov { 21191872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 21291872392SBorislav Petkov 21391872392SBorislav Petkov return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); 21491872392SBorislav Petkov } 21591872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 21691872392SBorislav Petkov 2171da177e4SLinus Torvalds /** 2181da177e4SLinus Torvalds * device_release - free device structure. 2191da177e4SLinus Torvalds * @kobj: device's kobject. 2201da177e4SLinus Torvalds * 2211da177e4SLinus Torvalds * This is called once the reference count for the object 2221da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 2231da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 2241da177e4SLinus Torvalds */ 2251da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 2261da177e4SLinus Torvalds { 227b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 228fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 2291da177e4SLinus Torvalds 230a525a3ddSMing Lei /* 231a525a3ddSMing Lei * Some platform devices are driven without driver attached 232a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 233a525a3ddSMing Lei * all resources are released. 234a525a3ddSMing Lei * 235a525a3ddSMing Lei * Drivers still can add resources into device after device 236a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 237a525a3ddSMing Lei * possible memory leak. 238a525a3ddSMing Lei */ 239a525a3ddSMing Lei devres_release_all(dev); 240a525a3ddSMing Lei 2411da177e4SLinus Torvalds if (dev->release) 2421da177e4SLinus Torvalds dev->release(dev); 243f9f852dfSKay Sievers else if (dev->type && dev->type->release) 244f9f852dfSKay Sievers dev->type->release(dev); 2452620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 2462620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 247f810a5cfSArjan van de Ven else 248f810a5cfSArjan van de Ven WARN(1, KERN_ERR "Device '%s' does not have a release() " 2494a3ad20cSGreg Kroah-Hartman "function, it is broken and must be fixed.\n", 2501e0b2cf9SKay Sievers dev_name(dev)); 251fb069a5dSGreg Kroah-Hartman kfree(p); 2521da177e4SLinus Torvalds } 2531da177e4SLinus Torvalds 254bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 255bc451f20SEric W. Biederman { 256b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 257bc451f20SEric W. Biederman const void *ns = NULL; 258bc451f20SEric W. Biederman 259bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 260bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 261bc451f20SEric W. Biederman 262bc451f20SEric W. Biederman return ns; 263bc451f20SEric W. Biederman } 264bc451f20SEric W. Biederman 2658f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 2661da177e4SLinus Torvalds .release = device_release, 2671da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 268bc451f20SEric W. Biederman .namespace = device_namespace, 2691da177e4SLinus Torvalds }; 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds 272312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 2731da177e4SLinus Torvalds { 2741da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 2751da177e4SLinus Torvalds 2768f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 277b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 2781da177e4SLinus Torvalds if (dev->bus) 2791da177e4SLinus Torvalds return 1; 28023681e47SGreg Kroah-Hartman if (dev->class) 28123681e47SGreg Kroah-Hartman return 1; 2821da177e4SLinus Torvalds } 2831da177e4SLinus Torvalds return 0; 2841da177e4SLinus Torvalds } 2851da177e4SLinus Torvalds 286312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 2871da177e4SLinus Torvalds { 288b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 2891da177e4SLinus Torvalds 29023681e47SGreg Kroah-Hartman if (dev->bus) 2911da177e4SLinus Torvalds return dev->bus->name; 29223681e47SGreg Kroah-Hartman if (dev->class) 29323681e47SGreg Kroah-Hartman return dev->class->name; 29423681e47SGreg Kroah-Hartman return NULL; 2951da177e4SLinus Torvalds } 2961da177e4SLinus Torvalds 2977eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 2987eff2e7aSKay Sievers struct kobj_uevent_env *env) 2991da177e4SLinus Torvalds { 300b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 3011da177e4SLinus Torvalds int retval = 0; 3021da177e4SLinus Torvalds 3036fcf53acSKay Sievers /* add device node properties if present */ 30423681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 3056fcf53acSKay Sievers const char *tmp; 3066fcf53acSKay Sievers const char *name; 3072c9ede55SAl Viro umode_t mode = 0; 3084e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 3094e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 3106fcf53acSKay Sievers 3117eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 3127eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 3133c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 3146fcf53acSKay Sievers if (name) { 3156fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 316e454cea2SKay Sievers if (mode) 317e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 3184e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 3194e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 3204e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 3214e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 3223c2670e6SKay Sievers kfree(tmp); 3236fcf53acSKay Sievers } 32423681e47SGreg Kroah-Hartman } 32523681e47SGreg Kroah-Hartman 326414264f9SKay Sievers if (dev->type && dev->type->name) 3277eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 328414264f9SKay Sievers 329239378f1SKay Sievers if (dev->driver) 3307eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 331239378f1SKay Sievers 33207d57a32SGrant Likely /* Add common DT information about the device */ 33307d57a32SGrant Likely of_device_uevent(dev, env); 33407d57a32SGrant Likely 3351da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 3367eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 3377eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 338f9f852dfSKay Sievers if (retval) 3397dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 3401e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 3411da177e4SLinus Torvalds } 3421da177e4SLinus Torvalds 3432620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 3447eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 3457eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 346f9f852dfSKay Sievers if (retval) 3477dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 3481e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 3492b3a302aSHarvey Harrison __func__, retval); 3502620efefSGreg Kroah-Hartman } 351f9f852dfSKay Sievers 352eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 3537eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 3547eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 355f9f852dfSKay Sievers if (retval) 3567dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 3571e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 3582b3a302aSHarvey Harrison __func__, retval); 3592620efefSGreg Kroah-Hartman } 3602620efefSGreg Kroah-Hartman 3611da177e4SLinus Torvalds return retval; 3621da177e4SLinus Torvalds } 3631da177e4SLinus Torvalds 3649cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 365312c004dSKay Sievers .filter = dev_uevent_filter, 366312c004dSKay Sievers .name = dev_uevent_name, 367312c004dSKay Sievers .uevent = dev_uevent, 3681da177e4SLinus Torvalds }; 3691da177e4SLinus Torvalds 370c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 37116574dccSKay Sievers char *buf) 37216574dccSKay Sievers { 37316574dccSKay Sievers struct kobject *top_kobj; 37416574dccSKay Sievers struct kset *kset; 3757eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 37616574dccSKay Sievers int i; 37716574dccSKay Sievers size_t count = 0; 37816574dccSKay Sievers int retval; 37916574dccSKay Sievers 38016574dccSKay Sievers /* search the kset, the device belongs to */ 38116574dccSKay Sievers top_kobj = &dev->kobj; 3825c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 38316574dccSKay Sievers top_kobj = top_kobj->parent; 38416574dccSKay Sievers if (!top_kobj->kset) 38516574dccSKay Sievers goto out; 3865c5daf65SKay Sievers 38716574dccSKay Sievers kset = top_kobj->kset; 38816574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 38916574dccSKay Sievers goto out; 39016574dccSKay Sievers 39116574dccSKay Sievers /* respect filter */ 39216574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 39316574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 39416574dccSKay Sievers goto out; 39516574dccSKay Sievers 3967eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 3977eff2e7aSKay Sievers if (!env) 398c7308c81SGreg Kroah-Hartman return -ENOMEM; 399c7308c81SGreg Kroah-Hartman 40016574dccSKay Sievers /* let the kset specific function add its keys */ 4017eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 40216574dccSKay Sievers if (retval) 40316574dccSKay Sievers goto out; 40416574dccSKay Sievers 40516574dccSKay Sievers /* copy keys to file */ 4067eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 4077eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 40816574dccSKay Sievers out: 4097eff2e7aSKay Sievers kfree(env); 41016574dccSKay Sievers return count; 41116574dccSKay Sievers } 41216574dccSKay Sievers 413c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 414a7fd6706SKay Sievers const char *buf, size_t count) 415a7fd6706SKay Sievers { 41660a96a59SKay Sievers enum kobject_action action; 41760a96a59SKay Sievers 4183f5468c9SKay Sievers if (kobject_action_type(buf, count, &action) == 0) 41960a96a59SKay Sievers kobject_uevent(&dev->kobj, action); 4203f5468c9SKay Sievers else 4213f5468c9SKay Sievers dev_err(dev, "uevent: unknown action-string\n"); 422a7fd6706SKay Sievers return count; 423a7fd6706SKay Sievers } 424c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 425a7fd6706SKay Sievers 426c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 4274f3549d7SRafael J. Wysocki char *buf) 4284f3549d7SRafael J. Wysocki { 4294f3549d7SRafael J. Wysocki bool val; 4304f3549d7SRafael J. Wysocki 4315e33bc41SRafael J. Wysocki device_lock(dev); 4324f3549d7SRafael J. Wysocki val = !dev->offline; 4335e33bc41SRafael J. Wysocki device_unlock(dev); 4344f3549d7SRafael J. Wysocki return sprintf(buf, "%u\n", val); 4354f3549d7SRafael J. Wysocki } 4364f3549d7SRafael J. Wysocki 437c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 4384f3549d7SRafael J. Wysocki const char *buf, size_t count) 4394f3549d7SRafael J. Wysocki { 4404f3549d7SRafael J. Wysocki bool val; 4414f3549d7SRafael J. Wysocki int ret; 4424f3549d7SRafael J. Wysocki 4434f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 4444f3549d7SRafael J. Wysocki if (ret < 0) 4454f3549d7SRafael J. Wysocki return ret; 4464f3549d7SRafael J. Wysocki 4475e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 4485e33bc41SRafael J. Wysocki if (ret) 4495e33bc41SRafael J. Wysocki return ret; 4505e33bc41SRafael J. Wysocki 4514f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 4524f3549d7SRafael J. Wysocki unlock_device_hotplug(); 4534f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 4544f3549d7SRafael J. Wysocki } 455c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 4564f3549d7SRafael J. Wysocki 457fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 458621a1672SDmitry Torokhov { 4593e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 460621a1672SDmitry Torokhov } 461621a1672SDmitry Torokhov 462fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 463a4dbd674SDavid Brownell const struct attribute_group **groups) 464621a1672SDmitry Torokhov { 4653e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 466621a1672SDmitry Torokhov } 467de0ff00dSGreg Kroah-Hartman 4682620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 4692620efefSGreg Kroah-Hartman { 4702620efefSGreg Kroah-Hartman struct class *class = dev->class; 471aed65af1SStephen Hemminger const struct device_type *type = dev->type; 472621a1672SDmitry Torokhov int error; 4732620efefSGreg Kroah-Hartman 474621a1672SDmitry Torokhov if (class) { 475d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 4762620efefSGreg Kroah-Hartman if (error) 477621a1672SDmitry Torokhov return error; 478f9f852dfSKay Sievers } 479f9f852dfSKay Sievers 480621a1672SDmitry Torokhov if (type) { 481621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 482f9f852dfSKay Sievers if (error) 483a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 484f9f852dfSKay Sievers } 485621a1672SDmitry Torokhov 486621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 487f9f852dfSKay Sievers if (error) 488621a1672SDmitry Torokhov goto err_remove_type_groups; 489621a1672SDmitry Torokhov 4904f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 491c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 4924f3549d7SRafael J. Wysocki if (error) 493ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 4944f3549d7SRafael J. Wysocki } 4954f3549d7SRafael J. Wysocki 496621a1672SDmitry Torokhov return 0; 497621a1672SDmitry Torokhov 498ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 499ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 500621a1672SDmitry Torokhov err_remove_type_groups: 501621a1672SDmitry Torokhov if (type) 502621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 503d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 504d05a6f96SGreg Kroah-Hartman if (class) 505d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 506f9f852dfSKay Sievers 5072620efefSGreg Kroah-Hartman return error; 5082620efefSGreg Kroah-Hartman } 5092620efefSGreg Kroah-Hartman 5102620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 5112620efefSGreg Kroah-Hartman { 5122620efefSGreg Kroah-Hartman struct class *class = dev->class; 513aed65af1SStephen Hemminger const struct device_type *type = dev->type; 5142620efefSGreg Kroah-Hartman 515c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 516621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 517f9f852dfSKay Sievers 518621a1672SDmitry Torokhov if (type) 519621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 520621a1672SDmitry Torokhov 521a6b01dedSGreg Kroah-Hartman if (class) 522d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 523c97415a7SStefan Achatz } 5242620efefSGreg Kroah-Hartman 525c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 52623681e47SGreg Kroah-Hartman char *buf) 52723681e47SGreg Kroah-Hartman { 52823681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 52923681e47SGreg Kroah-Hartman } 530c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 531ad6a1e1cSTejun Heo 532ca22e56dSKay Sievers /* /sys/devices/ */ 533881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds /** 5361da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 5371da177e4SLinus Torvalds * @dev: device. 5381da177e4SLinus Torvalds * @attr: device attribute descriptor. 5391da177e4SLinus Torvalds */ 54026579ab7SPhil Carmody int device_create_file(struct device *dev, 54126579ab7SPhil Carmody const struct device_attribute *attr) 5421da177e4SLinus Torvalds { 5431da177e4SLinus Torvalds int error = 0; 5448f46baaaSFelipe Balbi 5458f46baaaSFelipe Balbi if (dev) { 5468f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 54797521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 54897521978Sdyoung@redhat.com attr->attr.name); 5498f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 55097521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 55197521978Sdyoung@redhat.com attr->attr.name); 5521da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 5538f46baaaSFelipe Balbi } 5548f46baaaSFelipe Balbi 5551da177e4SLinus Torvalds return error; 5561da177e4SLinus Torvalds } 55786df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds /** 5601da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 5611da177e4SLinus Torvalds * @dev: device. 5621da177e4SLinus Torvalds * @attr: device attribute descriptor. 5631da177e4SLinus Torvalds */ 56426579ab7SPhil Carmody void device_remove_file(struct device *dev, 56526579ab7SPhil Carmody const struct device_attribute *attr) 5661da177e4SLinus Torvalds { 5670c98b19fSCornelia Huck if (dev) 5681da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 5691da177e4SLinus Torvalds } 57086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 5711da177e4SLinus Torvalds 5722589f188SGreg Kroah-Hartman /** 5736b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 5746b0afc2aSTejun Heo * @dev: device. 5756b0afc2aSTejun Heo * @attr: device attribute descriptor. 5766b0afc2aSTejun Heo * 5776b0afc2aSTejun Heo * See kernfs_remove_self() for details. 5786b0afc2aSTejun Heo */ 5796b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 5806b0afc2aSTejun Heo const struct device_attribute *attr) 5816b0afc2aSTejun Heo { 5826b0afc2aSTejun Heo if (dev) 5836b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 5846b0afc2aSTejun Heo else 5856b0afc2aSTejun Heo return false; 5866b0afc2aSTejun Heo } 5876b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 5886b0afc2aSTejun Heo 5896b0afc2aSTejun Heo /** 5902589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 5912589f188SGreg Kroah-Hartman * @dev: device. 5922589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 5932589f188SGreg Kroah-Hartman */ 59466ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 59566ecb92bSPhil Carmody const struct bin_attribute *attr) 5962589f188SGreg Kroah-Hartman { 5972589f188SGreg Kroah-Hartman int error = -EINVAL; 5982589f188SGreg Kroah-Hartman if (dev) 5992589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 6002589f188SGreg Kroah-Hartman return error; 6012589f188SGreg Kroah-Hartman } 6022589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 6032589f188SGreg Kroah-Hartman 6042589f188SGreg Kroah-Hartman /** 6052589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 6062589f188SGreg Kroah-Hartman * @dev: device. 6072589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 6082589f188SGreg Kroah-Hartman */ 60966ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 61066ecb92bSPhil Carmody const struct bin_attribute *attr) 6112589f188SGreg Kroah-Hartman { 6122589f188SGreg Kroah-Hartman if (dev) 6132589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 6142589f188SGreg Kroah-Hartman } 6152589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 6162589f188SGreg Kroah-Hartman 61734bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 61834bb61f9SJames Bottomley { 619f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 620f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 62134bb61f9SJames Bottomley 62234bb61f9SJames Bottomley get_device(dev); 62334bb61f9SJames Bottomley } 62434bb61f9SJames Bottomley 62534bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 62634bb61f9SJames Bottomley { 627f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 628f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 62934bb61f9SJames Bottomley 63034bb61f9SJames Bottomley put_device(dev); 63134bb61f9SJames Bottomley } 63234bb61f9SJames Bottomley 6331da177e4SLinus Torvalds /** 6341da177e4SLinus Torvalds * device_initialize - init device structure. 6351da177e4SLinus Torvalds * @dev: device. 6361da177e4SLinus Torvalds * 6375739411aSCornelia Huck * This prepares the device for use by other layers by initializing 6385739411aSCornelia Huck * its fields. 6391da177e4SLinus Torvalds * It is the first half of device_register(), if called by 6405739411aSCornelia Huck * that function, though it can also be called separately, so one 6415739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 6425739411aSCornelia Huck * may be used for reference counting of @dev after calling this 6435739411aSCornelia Huck * function. 6445739411aSCornelia Huck * 645b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 646b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 647b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 648b10d5efdSAlan Stern * @dev. 649b10d5efdSAlan Stern * 6505739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 6515739411aSCornelia Huck * @dev directly once you have called this function. 6521da177e4SLinus Torvalds */ 6531da177e4SLinus Torvalds void device_initialize(struct device *dev) 6541da177e4SLinus Torvalds { 655881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 656f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 6571da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 6583142788bSThomas Gleixner mutex_init(&dev->mutex); 6591704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 6609ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 6619ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 6623b98aeafSAlan Stern device_pm_init(dev); 66387348136SChristoph Hellwig set_dev_node(dev, -1); 6641da177e4SLinus Torvalds } 66586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 6661da177e4SLinus Torvalds 667d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 668f0ee61a6SGreg Kroah-Hartman { 669f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 670f0ee61a6SGreg Kroah-Hartman 671f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 6724ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 673881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 674f0ee61a6SGreg Kroah-Hartman 67586406245SKay Sievers return virtual_dir; 676f0ee61a6SGreg Kroah-Hartman } 677f0ee61a6SGreg Kroah-Hartman 678bc451f20SEric W. Biederman struct class_dir { 679bc451f20SEric W. Biederman struct kobject kobj; 680bc451f20SEric W. Biederman struct class *class; 681bc451f20SEric W. Biederman }; 682bc451f20SEric W. Biederman 683bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 684bc451f20SEric W. Biederman 685bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 686bc451f20SEric W. Biederman { 687bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 688bc451f20SEric W. Biederman kfree(dir); 689bc451f20SEric W. Biederman } 690bc451f20SEric W. Biederman 691bc451f20SEric W. Biederman static const 692bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 693bc451f20SEric W. Biederman { 694bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 695bc451f20SEric W. Biederman return dir->class->ns_type; 696bc451f20SEric W. Biederman } 697bc451f20SEric W. Biederman 698bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 699bc451f20SEric W. Biederman .release = class_dir_release, 700bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 701bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 702bc451f20SEric W. Biederman }; 703bc451f20SEric W. Biederman 704bc451f20SEric W. Biederman static struct kobject * 705bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 706bc451f20SEric W. Biederman { 707bc451f20SEric W. Biederman struct class_dir *dir; 708bc451f20SEric W. Biederman int retval; 709bc451f20SEric W. Biederman 710bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 711bc451f20SEric W. Biederman if (!dir) 712bc451f20SEric W. Biederman return NULL; 713bc451f20SEric W. Biederman 714bc451f20SEric W. Biederman dir->class = class; 715bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 716bc451f20SEric W. Biederman 7176b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 718bc451f20SEric W. Biederman 719bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 720bc451f20SEric W. Biederman if (retval < 0) { 721bc451f20SEric W. Biederman kobject_put(&dir->kobj); 722bc451f20SEric W. Biederman return NULL; 723bc451f20SEric W. Biederman } 724bc451f20SEric W. Biederman return &dir->kobj; 725bc451f20SEric W. Biederman } 726bc451f20SEric W. Biederman 727bc451f20SEric W. Biederman 728c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 729c744aeaeSCornelia Huck struct device *parent) 73040fa5422SGreg Kroah-Hartman { 73186406245SKay Sievers if (dev->class) { 73277d3d7c1STejun Heo static DEFINE_MUTEX(gdp_mutex); 73386406245SKay Sievers struct kobject *kobj = NULL; 73486406245SKay Sievers struct kobject *parent_kobj; 73586406245SKay Sievers struct kobject *k; 73686406245SKay Sievers 737ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 73839aba963SKay Sievers /* block disks show up in /sys/block */ 739e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 74039aba963SKay Sievers if (parent && parent->class == &block_class) 74139aba963SKay Sievers return &parent->kobj; 7426b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 74339aba963SKay Sievers } 744ead454feSRandy Dunlap #endif 745e52eec13SAndi Kleen 74686406245SKay Sievers /* 74786406245SKay Sievers * If we have no parent, we live in "virtual". 7480f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 7490f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 75086406245SKay Sievers */ 75186406245SKay Sievers if (parent == NULL) 75286406245SKay Sievers parent_kobj = virtual_device_parent(dev); 75324b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 75486406245SKay Sievers return &parent->kobj; 75586406245SKay Sievers else 75686406245SKay Sievers parent_kobj = &parent->kobj; 75786406245SKay Sievers 75877d3d7c1STejun Heo mutex_lock(&gdp_mutex); 75977d3d7c1STejun Heo 76086406245SKay Sievers /* find our class-directory at the parent and reference it */ 7616b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 7626b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 76386406245SKay Sievers if (k->parent == parent_kobj) { 76486406245SKay Sievers kobj = kobject_get(k); 76586406245SKay Sievers break; 76686406245SKay Sievers } 7676b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 76877d3d7c1STejun Heo if (kobj) { 76977d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 77086406245SKay Sievers return kobj; 77177d3d7c1STejun Heo } 77286406245SKay Sievers 77386406245SKay Sievers /* or create a new class-directory at the parent device */ 774bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 7750f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 77677d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 77743968d2fSGreg Kroah-Hartman return k; 77886406245SKay Sievers } 77986406245SKay Sievers 780ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 781ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 782ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 783ca22e56dSKay Sievers 78486406245SKay Sievers if (parent) 785c744aeaeSCornelia Huck return &parent->kobj; 786c744aeaeSCornelia Huck return NULL; 787c744aeaeSCornelia Huck } 788da231fd5SKay Sievers 78963b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 790da231fd5SKay Sievers { 7910f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 792c1fe539aSCornelia Huck if (!glue_dir || !dev->class || 7936b6e39a6SKay Sievers glue_dir->kset != &dev->class->p->glue_dirs) 794da231fd5SKay Sievers return; 795da231fd5SKay Sievers 7960f4dafc0SKay Sievers kobject_put(glue_dir); 797da231fd5SKay Sievers } 79863b6971aSCornelia Huck 79963b6971aSCornelia Huck static void cleanup_device_parent(struct device *dev) 80063b6971aSCornelia Huck { 80163b6971aSCornelia Huck cleanup_glue_dir(dev, dev->kobj.parent); 80263b6971aSCornelia Huck } 80386406245SKay Sievers 8042ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 8052ee97cafSCornelia Huck { 8062ee97cafSCornelia Huck int error; 8072ee97cafSCornelia Huck 8082ee97cafSCornelia Huck if (!dev->class) 8092ee97cafSCornelia Huck return 0; 810da231fd5SKay Sievers 8111fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 8126b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 8132ee97cafSCornelia Huck "subsystem"); 8142ee97cafSCornelia Huck if (error) 8152ee97cafSCornelia Huck goto out; 816da231fd5SKay Sievers 8174e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 8184f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 8194f01a757SDmitry Torokhov "device"); 8204f01a757SDmitry Torokhov if (error) 82139aba963SKay Sievers goto out_subsys; 8222ee97cafSCornelia Huck } 82339aba963SKay Sievers 824ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 82539aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 826e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 82739aba963SKay Sievers return 0; 828ead454feSRandy Dunlap #endif 82939aba963SKay Sievers 83039aba963SKay Sievers /* link in the class directory pointing to the device */ 8316b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 83239aba963SKay Sievers &dev->kobj, dev_name(dev)); 83339aba963SKay Sievers if (error) 83439aba963SKay Sievers goto out_device; 83539aba963SKay Sievers 8362ee97cafSCornelia Huck return 0; 8372ee97cafSCornelia Huck 83839aba963SKay Sievers out_device: 83939aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 840da231fd5SKay Sievers 8412ee97cafSCornelia Huck out_subsys: 8422ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 8432ee97cafSCornelia Huck out: 8442ee97cafSCornelia Huck return error; 8452ee97cafSCornelia Huck } 8462ee97cafSCornelia Huck 8472ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 8482ee97cafSCornelia Huck { 8492ee97cafSCornelia Huck if (!dev->class) 8502ee97cafSCornelia Huck return; 851da231fd5SKay Sievers 8524e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 853da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 8542ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 855ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 856e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 85739aba963SKay Sievers return; 858ead454feSRandy Dunlap #endif 8596b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 8602ee97cafSCornelia Huck } 8612ee97cafSCornelia Huck 8621da177e4SLinus Torvalds /** 863413c239fSStephen Rothwell * dev_set_name - set a device name 864413c239fSStephen Rothwell * @dev: device 86546232366SRandy Dunlap * @fmt: format string for the device's name 866413c239fSStephen Rothwell */ 867413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 868413c239fSStephen Rothwell { 869413c239fSStephen Rothwell va_list vargs; 8701fa5ae85SKay Sievers int err; 871413c239fSStephen Rothwell 872413c239fSStephen Rothwell va_start(vargs, fmt); 8731fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 874413c239fSStephen Rothwell va_end(vargs); 8751fa5ae85SKay Sievers return err; 876413c239fSStephen Rothwell } 877413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 878413c239fSStephen Rothwell 879413c239fSStephen Rothwell /** 880e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 881e105b8bfSDan Williams * @dev: device 882e105b8bfSDan Williams * 883e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 884e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 885e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 886e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 8870d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 8880d4e293cSPeter Korsgaard * the link. 889e105b8bfSDan Williams */ 890e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 891e105b8bfSDan Williams { 892e105b8bfSDan Williams struct kobject *kobj; 893e105b8bfSDan Williams 894e105b8bfSDan Williams if (dev->class) 895e105b8bfSDan Williams kobj = dev->class->dev_kobj; 896e105b8bfSDan Williams else 897e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 898e105b8bfSDan Williams 899e105b8bfSDan Williams return kobj; 900e105b8bfSDan Williams } 901e105b8bfSDan Williams 902e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 903e105b8bfSDan Williams { 904e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 905e105b8bfSDan Williams int error = 0; 906e105b8bfSDan Williams char devt_str[15]; 907e105b8bfSDan Williams 908e105b8bfSDan Williams if (kobj) { 909e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 910e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 911e105b8bfSDan Williams } 912e105b8bfSDan Williams 913e105b8bfSDan Williams return error; 914e105b8bfSDan Williams } 915e105b8bfSDan Williams 916e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 917e105b8bfSDan Williams { 918e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 919e105b8bfSDan Williams char devt_str[15]; 920e105b8bfSDan Williams 921e105b8bfSDan Williams if (kobj) { 922e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 923e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 924e105b8bfSDan Williams } 925e105b8bfSDan Williams } 926e105b8bfSDan Williams 927b4028437SGreg Kroah-Hartman int device_private_init(struct device *dev) 928b4028437SGreg Kroah-Hartman { 929b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 930b4028437SGreg Kroah-Hartman if (!dev->p) 931b4028437SGreg Kroah-Hartman return -ENOMEM; 932b4028437SGreg Kroah-Hartman dev->p->device = dev; 933b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 934b4028437SGreg Kroah-Hartman klist_children_put); 935ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 936b4028437SGreg Kroah-Hartman return 0; 937b4028437SGreg Kroah-Hartman } 938b4028437SGreg Kroah-Hartman 939e105b8bfSDan Williams /** 9401da177e4SLinus Torvalds * device_add - add device to device hierarchy. 9411da177e4SLinus Torvalds * @dev: device. 9421da177e4SLinus Torvalds * 9431da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 9441da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 9451da177e4SLinus Torvalds * 9465739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 9471da177e4SLinus Torvalds * to the global and sibling lists for the device, then 9481da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 9495739411aSCornelia Huck * 950b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 951b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 952b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 953b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 954b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 955b10d5efdSAlan Stern * and register a fresh new struct device instead. 956b10d5efdSAlan Stern * 9575739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 9585739411aSCornelia Huck * if it returned an error! Always use put_device() to give up your 9595739411aSCornelia Huck * reference instead. 9601da177e4SLinus Torvalds */ 9611da177e4SLinus Torvalds int device_add(struct device *dev) 9621da177e4SLinus Torvalds { 9631da177e4SLinus Torvalds struct device *parent = NULL; 964ca22e56dSKay Sievers struct kobject *kobj; 965c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 966c906a48aSGreg Kroah-Hartman int error = -EINVAL; 967775b64d2SRafael J. Wysocki 9681da177e4SLinus Torvalds dev = get_device(dev); 969c906a48aSGreg Kroah-Hartman if (!dev) 970c906a48aSGreg Kroah-Hartman goto done; 971c906a48aSGreg Kroah-Hartman 972fb069a5dSGreg Kroah-Hartman if (!dev->p) { 973b4028437SGreg Kroah-Hartman error = device_private_init(dev); 974b4028437SGreg Kroah-Hartman if (error) 975fb069a5dSGreg Kroah-Hartman goto done; 976fb069a5dSGreg Kroah-Hartman } 977fb069a5dSGreg Kroah-Hartman 9781fa5ae85SKay Sievers /* 9791fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 9801fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 9811fa5ae85SKay Sievers * the name, and force the use of dev_name() 9821fa5ae85SKay Sievers */ 9831fa5ae85SKay Sievers if (dev->init_name) { 984acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 9851fa5ae85SKay Sievers dev->init_name = NULL; 9861fa5ae85SKay Sievers } 987c906a48aSGreg Kroah-Hartman 988ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 989ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 990ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 991ca22e56dSKay Sievers 992e6309e75SThomas Gleixner if (!dev_name(dev)) { 993e6309e75SThomas Gleixner error = -EINVAL; 9945c8563d7SKay Sievers goto name_error; 995e6309e75SThomas Gleixner } 9961da177e4SLinus Torvalds 9971e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 998c205ef48SGreg Kroah-Hartman 9991da177e4SLinus Torvalds parent = get_device(dev->parent); 1000ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 1001ca22e56dSKay Sievers if (kobj) 1002ca22e56dSKay Sievers dev->kobj.parent = kobj; 10031da177e4SLinus Torvalds 10040d358f22SYinghai Lu /* use parent numa_node */ 10050d358f22SYinghai Lu if (parent) 10060d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 10070d358f22SYinghai Lu 10081da177e4SLinus Torvalds /* first, register with generic layer. */ 10098a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 10108a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 101140fa5422SGreg Kroah-Hartman if (error) 10121da177e4SLinus Torvalds goto Error; 1013a7fd6706SKay Sievers 101437022644SBrian Walsh /* notify platform of device entry */ 101537022644SBrian Walsh if (platform_notify) 101637022644SBrian Walsh platform_notify(dev); 101737022644SBrian Walsh 1018c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 1019a306eea4SCornelia Huck if (error) 1020a306eea4SCornelia Huck goto attrError; 1021a7fd6706SKay Sievers 102223681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 1023c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_dev); 1024ad6a1e1cSTejun Heo if (error) 1025a306eea4SCornelia Huck goto ueventattrError; 1026e105b8bfSDan Williams 1027e105b8bfSDan Williams error = device_create_sys_dev_entry(dev); 1028e105b8bfSDan Williams if (error) 1029e105b8bfSDan Williams goto devtattrError; 10302b2af54aSKay Sievers 10312b2af54aSKay Sievers devtmpfs_create_node(dev); 103223681e47SGreg Kroah-Hartman } 103323681e47SGreg Kroah-Hartman 10342ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 10352ee97cafSCornelia Huck if (error) 10362ee97cafSCornelia Huck goto SymlinkError; 1037dc0afa83SCornelia Huck error = device_add_attrs(dev); 1038dc0afa83SCornelia Huck if (error) 10392620efefSGreg Kroah-Hartman goto AttrsError; 1040dc0afa83SCornelia Huck error = bus_add_device(dev); 1041dc0afa83SCornelia Huck if (error) 10421da177e4SLinus Torvalds goto BusError; 10433b98aeafSAlan Stern error = dpm_sysfs_add(dev); 104457eee3d2SRafael J. Wysocki if (error) 10453b98aeafSAlan Stern goto DPMError; 10463b98aeafSAlan Stern device_pm_add(dev); 1047ec0676eeSAlan Stern 1048ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 1049268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 1050ec0676eeSAlan Stern */ 1051ec0676eeSAlan Stern if (dev->bus) 1052ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1053ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 1054ec0676eeSAlan Stern 105553877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 10562023c610SAlan Stern bus_probe_device(dev); 10571da177e4SLinus Torvalds if (parent) 1058f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1059f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 10601da177e4SLinus Torvalds 10615d9fd169SGreg Kroah-Hartman if (dev->class) { 1062ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1063c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 10645a3ceb86STejun Heo klist_add_tail(&dev->knode_class, 10656b6e39a6SKay Sievers &dev->class->p->klist_devices); 1066c47ed219SGreg Kroah-Hartman 1067c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 1068184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1069ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1070c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 1071c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 1072ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 10735d9fd169SGreg Kroah-Hartman } 1074c906a48aSGreg Kroah-Hartman done: 10751da177e4SLinus Torvalds put_device(dev); 10761da177e4SLinus Torvalds return error; 10773b98aeafSAlan Stern DPMError: 107857eee3d2SRafael J. Wysocki bus_remove_device(dev); 107957eee3d2SRafael J. Wysocki BusError: 10802620efefSGreg Kroah-Hartman device_remove_attrs(dev); 10812620efefSGreg Kroah-Hartman AttrsError: 10822ee97cafSCornelia Huck device_remove_class_symlinks(dev); 10832ee97cafSCornelia Huck SymlinkError: 1084ad6a1e1cSTejun Heo if (MAJOR(dev->devt)) 1085ad72956dSKay Sievers devtmpfs_delete_node(dev); 1086ad72956dSKay Sievers if (MAJOR(dev->devt)) 1087e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 1088e105b8bfSDan Williams devtattrError: 1089e105b8bfSDan Williams if (MAJOR(dev->devt)) 1090c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 1091a306eea4SCornelia Huck ueventattrError: 1092c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 109323681e47SGreg Kroah-Hartman attrError: 1094312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 10951da177e4SLinus Torvalds kobject_del(&dev->kobj); 10961da177e4SLinus Torvalds Error: 109763b6971aSCornelia Huck cleanup_device_parent(dev); 10981da177e4SLinus Torvalds if (parent) 10991da177e4SLinus Torvalds put_device(parent); 11005c8563d7SKay Sievers name_error: 11015c8563d7SKay Sievers kfree(dev->p); 11025c8563d7SKay Sievers dev->p = NULL; 1103c906a48aSGreg Kroah-Hartman goto done; 11041da177e4SLinus Torvalds } 110586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 11061da177e4SLinus Torvalds 11071da177e4SLinus Torvalds /** 11081da177e4SLinus Torvalds * device_register - register a device with the system. 11091da177e4SLinus Torvalds * @dev: pointer to the device structure 11101da177e4SLinus Torvalds * 11111da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 11121da177e4SLinus Torvalds * and add it to the system. The two steps can be called 11131da177e4SLinus Torvalds * separately, but this is the easiest and most common. 11141da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 11151da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 11161da177e4SLinus Torvalds * before it is added to the hierarchy. 11175739411aSCornelia Huck * 1118b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 1119b10d5efdSAlan Stern * and device_add(). 1120b10d5efdSAlan Stern * 11215739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 11225739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 11235739411aSCornelia Huck * reference initialized in this function instead. 11241da177e4SLinus Torvalds */ 11251da177e4SLinus Torvalds int device_register(struct device *dev) 11261da177e4SLinus Torvalds { 11271da177e4SLinus Torvalds device_initialize(dev); 11281da177e4SLinus Torvalds return device_add(dev); 11291da177e4SLinus Torvalds } 113086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 11311da177e4SLinus Torvalds 11321da177e4SLinus Torvalds /** 11331da177e4SLinus Torvalds * get_device - increment reference count for device. 11341da177e4SLinus Torvalds * @dev: device. 11351da177e4SLinus Torvalds * 11361da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 11371da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 11381da177e4SLinus Torvalds * pointer passed in. 11391da177e4SLinus Torvalds */ 11401da177e4SLinus Torvalds struct device *get_device(struct device *dev) 11411da177e4SLinus Torvalds { 1142b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 11431da177e4SLinus Torvalds } 114486df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 11451da177e4SLinus Torvalds 11461da177e4SLinus Torvalds /** 11471da177e4SLinus Torvalds * put_device - decrement reference count. 11481da177e4SLinus Torvalds * @dev: device in question. 11491da177e4SLinus Torvalds */ 11501da177e4SLinus Torvalds void put_device(struct device *dev) 11511da177e4SLinus Torvalds { 1152edfaa7c3SKay Sievers /* might_sleep(); */ 11531da177e4SLinus Torvalds if (dev) 11541da177e4SLinus Torvalds kobject_put(&dev->kobj); 11551da177e4SLinus Torvalds } 115686df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 11571da177e4SLinus Torvalds 11581da177e4SLinus Torvalds /** 11591da177e4SLinus Torvalds * device_del - delete device from system. 11601da177e4SLinus Torvalds * @dev: device. 11611da177e4SLinus Torvalds * 11621da177e4SLinus Torvalds * This is the first part of the device unregistration 11631da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 11641da177e4SLinus Torvalds * from here, has it removed from the other driver model 11651da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 11661da177e4SLinus Torvalds * from the kobject hierarchy. 11671da177e4SLinus Torvalds * 11681da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 11691da177e4SLinus Torvalds * also called manually. 11701da177e4SLinus Torvalds */ 11711da177e4SLinus Torvalds void device_del(struct device *dev) 11721da177e4SLinus Torvalds { 11731da177e4SLinus Torvalds struct device *parent = dev->parent; 1174c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 11751da177e4SLinus Torvalds 1176ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 1177ec0676eeSAlan Stern * before dpm_sysfs_remove(). 1178ec0676eeSAlan Stern */ 1179ec0676eeSAlan Stern if (dev->bus) 1180ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1181ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 11823b98aeafSAlan Stern dpm_sysfs_remove(dev); 11831da177e4SLinus Torvalds if (parent) 1184f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 1185e105b8bfSDan Williams if (MAJOR(dev->devt)) { 11862b2af54aSKay Sievers devtmpfs_delete_node(dev); 1187e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 1188c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 1189e105b8bfSDan Williams } 1190b9d9c82bSKay Sievers if (dev->class) { 1191da231fd5SKay Sievers device_remove_class_symlinks(dev); 119299ef3ef8SKay Sievers 1193ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1194c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 1195184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1196ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1197c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 1198c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 1199c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 12005a3ceb86STejun Heo klist_del(&dev->knode_class); 1201ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 1202b9d9c82bSKay Sievers } 1203c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 12042620efefSGreg Kroah-Hartman device_remove_attrs(dev); 120528953533SBenjamin Herrenschmidt bus_remove_device(dev); 12064b6d1f12SLongX Zhang device_pm_remove(dev); 1207d1c3414cSGrant Likely driver_deferred_probe_del(dev); 12081da177e4SLinus Torvalds 12091da177e4SLinus Torvalds /* Notify the platform of the removal, in case they 12101da177e4SLinus Torvalds * need to do anything... 12111da177e4SLinus Torvalds */ 12121da177e4SLinus Torvalds if (platform_notify_remove) 12131da177e4SLinus Torvalds platform_notify_remove(dev); 1214599bad38SJoerg Roedel if (dev->bus) 1215599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1216599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 1217312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1218da231fd5SKay Sievers cleanup_device_parent(dev); 12191da177e4SLinus Torvalds kobject_del(&dev->kobj); 12201da177e4SLinus Torvalds put_device(parent); 12211da177e4SLinus Torvalds } 122286df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds /** 12251da177e4SLinus Torvalds * device_unregister - unregister device from system. 12261da177e4SLinus Torvalds * @dev: device going away. 12271da177e4SLinus Torvalds * 12281da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 12291da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 12301da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 12311da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 12321da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 12331da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 12341da177e4SLinus Torvalds */ 12351da177e4SLinus Torvalds void device_unregister(struct device *dev) 12361da177e4SLinus Torvalds { 12371e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 12381da177e4SLinus Torvalds device_del(dev); 12391da177e4SLinus Torvalds put_device(dev); 12401da177e4SLinus Torvalds } 124186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 12421da177e4SLinus Torvalds 124336239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 124436239577Smochel@digitalimplant.org { 124536239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 1246f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 1247f791b8c8SGreg Kroah-Hartman struct device_private *p; 1248f791b8c8SGreg Kroah-Hartman 1249f791b8c8SGreg Kroah-Hartman if (n) { 1250f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 1251f791b8c8SGreg Kroah-Hartman dev = p->device; 1252f791b8c8SGreg Kroah-Hartman } 1253f791b8c8SGreg Kroah-Hartman return dev; 125436239577Smochel@digitalimplant.org } 125536239577Smochel@digitalimplant.org 12561da177e4SLinus Torvalds /** 1257e454cea2SKay Sievers * device_get_devnode - path of device node file 12586fcf53acSKay Sievers * @dev: device 1259e454cea2SKay Sievers * @mode: returned file access mode 12603c2670e6SKay Sievers * @uid: returned file owner 12613c2670e6SKay Sievers * @gid: returned file group 12626fcf53acSKay Sievers * @tmp: possibly allocated string 12636fcf53acSKay Sievers * 12646fcf53acSKay Sievers * Return the relative path of a possible device node. 12656fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 12666fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 12676fcf53acSKay Sievers * freed by the caller. 12686fcf53acSKay Sievers */ 1269e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 12704e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 12713c2670e6SKay Sievers const char **tmp) 12726fcf53acSKay Sievers { 12736fcf53acSKay Sievers char *s; 12746fcf53acSKay Sievers 12756fcf53acSKay Sievers *tmp = NULL; 12766fcf53acSKay Sievers 12776fcf53acSKay Sievers /* the device type may provide a specific name */ 1278e454cea2SKay Sievers if (dev->type && dev->type->devnode) 12793c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 12806fcf53acSKay Sievers if (*tmp) 12816fcf53acSKay Sievers return *tmp; 12826fcf53acSKay Sievers 12836fcf53acSKay Sievers /* the class may provide a specific name */ 1284e454cea2SKay Sievers if (dev->class && dev->class->devnode) 1285e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 12866fcf53acSKay Sievers if (*tmp) 12876fcf53acSKay Sievers return *tmp; 12886fcf53acSKay Sievers 12896fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 12906fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 12916fcf53acSKay Sievers return dev_name(dev); 12926fcf53acSKay Sievers 12936fcf53acSKay Sievers /* replace '!' in the name with '/' */ 12946fcf53acSKay Sievers *tmp = kstrdup(dev_name(dev), GFP_KERNEL); 12956fcf53acSKay Sievers if (!*tmp) 12966fcf53acSKay Sievers return NULL; 12976fcf53acSKay Sievers while ((s = strchr(*tmp, '!'))) 12986fcf53acSKay Sievers s[0] = '/'; 12996fcf53acSKay Sievers return *tmp; 13006fcf53acSKay Sievers } 13016fcf53acSKay Sievers 13026fcf53acSKay Sievers /** 13031da177e4SLinus Torvalds * device_for_each_child - device child iterator. 1304c41455fbSRandy Dunlap * @parent: parent struct device. 13051da177e4SLinus Torvalds * @fn: function to be called for each device. 1306f8878dcbSRobert P. J. Day * @data: data for the callback. 13071da177e4SLinus Torvalds * 1308c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 13091da177e4SLinus Torvalds * passing it @data. 13101da177e4SLinus Torvalds * 13111da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 13121da177e4SLinus Torvalds * other than 0, we break out and return that value. 13131da177e4SLinus Torvalds */ 131436239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 13154a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 13161da177e4SLinus Torvalds { 131736239577Smochel@digitalimplant.org struct klist_iter i; 13181da177e4SLinus Torvalds struct device *child; 13191da177e4SLinus Torvalds int error = 0; 13201da177e4SLinus Torvalds 1321014c90dbSGreg Kroah-Hartman if (!parent->p) 1322014c90dbSGreg Kroah-Hartman return 0; 1323014c90dbSGreg Kroah-Hartman 1324f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 132536239577Smochel@digitalimplant.org while ((child = next_device(&i)) && !error) 132636239577Smochel@digitalimplant.org error = fn(child, data); 132736239577Smochel@digitalimplant.org klist_iter_exit(&i); 13281da177e4SLinus Torvalds return error; 13291da177e4SLinus Torvalds } 133086df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 13311da177e4SLinus Torvalds 13325ab69981SCornelia Huck /** 13335ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 13345ab69981SCornelia Huck * @parent: parent struct device 13355ab69981SCornelia Huck * @match: Callback function to check device 1336f8878dcbSRobert P. J. Day * @data: Data to pass to match function 13375ab69981SCornelia Huck * 13385ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 13395ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 13405ab69981SCornelia Huck * determined by the @match callback. 13415ab69981SCornelia Huck * 13425ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 13435ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 13445ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 13455ab69981SCornelia Huck * and not iterate over any more devices. 1346a4e2400aSFederico Vaga * 1347a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 13485ab69981SCornelia Huck */ 13495ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 13504a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 13515ab69981SCornelia Huck { 13525ab69981SCornelia Huck struct klist_iter i; 13535ab69981SCornelia Huck struct device *child; 13545ab69981SCornelia Huck 13555ab69981SCornelia Huck if (!parent) 13565ab69981SCornelia Huck return NULL; 13575ab69981SCornelia Huck 1358f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 13595ab69981SCornelia Huck while ((child = next_device(&i))) 13605ab69981SCornelia Huck if (match(child, data) && get_device(child)) 13615ab69981SCornelia Huck break; 13625ab69981SCornelia Huck klist_iter_exit(&i); 13635ab69981SCornelia Huck return child; 13645ab69981SCornelia Huck } 136586df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 13665ab69981SCornelia Huck 13671da177e4SLinus Torvalds int __init devices_init(void) 13681da177e4SLinus Torvalds { 1369881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 1370881c6cfdSGreg Kroah-Hartman if (!devices_kset) 1371881c6cfdSGreg Kroah-Hartman return -ENOMEM; 1372e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 1373e105b8bfSDan Williams if (!dev_kobj) 1374e105b8bfSDan Williams goto dev_kobj_err; 1375e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 1376e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 1377e105b8bfSDan Williams goto block_kobj_err; 1378e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 1379e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 1380e105b8bfSDan Williams goto char_kobj_err; 1381e105b8bfSDan Williams 1382881c6cfdSGreg Kroah-Hartman return 0; 1383e105b8bfSDan Williams 1384e105b8bfSDan Williams char_kobj_err: 1385e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 1386e105b8bfSDan Williams block_kobj_err: 1387e105b8bfSDan Williams kobject_put(dev_kobj); 1388e105b8bfSDan Williams dev_kobj_err: 1389e105b8bfSDan Williams kset_unregister(devices_kset); 1390e105b8bfSDan Williams return -ENOMEM; 13911da177e4SLinus Torvalds } 13921da177e4SLinus Torvalds 13934f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 13944f3549d7SRafael J. Wysocki { 13954f3549d7SRafael J. Wysocki int ret; 13964f3549d7SRafael J. Wysocki 13974f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 13984f3549d7SRafael J. Wysocki if (ret) 13994f3549d7SRafael J. Wysocki return ret; 14004f3549d7SRafael J. Wysocki 14014f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 14024f3549d7SRafael J. Wysocki } 14034f3549d7SRafael J. Wysocki 14044f3549d7SRafael J. Wysocki /** 14054f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 14064f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 14074f3549d7SRafael J. Wysocki * 14084f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 14094f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 14104f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 14114f3549d7SRafael J. Wysocki * is executed. 14124f3549d7SRafael J. Wysocki * 14134f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 14144f3549d7SRafael J. Wysocki */ 14154f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 14164f3549d7SRafael J. Wysocki { 14174f3549d7SRafael J. Wysocki int ret; 14184f3549d7SRafael J. Wysocki 14194f3549d7SRafael J. Wysocki if (dev->offline_disabled) 14204f3549d7SRafael J. Wysocki return -EPERM; 14214f3549d7SRafael J. Wysocki 14224f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 14234f3549d7SRafael J. Wysocki if (ret) 14244f3549d7SRafael J. Wysocki return ret; 14254f3549d7SRafael J. Wysocki 14264f3549d7SRafael J. Wysocki device_lock(dev); 14274f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 14284f3549d7SRafael J. Wysocki if (dev->offline) { 14294f3549d7SRafael J. Wysocki ret = 1; 14304f3549d7SRafael J. Wysocki } else { 14314f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 14324f3549d7SRafael J. Wysocki if (!ret) { 14334f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 14344f3549d7SRafael J. Wysocki dev->offline = true; 14354f3549d7SRafael J. Wysocki } 14364f3549d7SRafael J. Wysocki } 14374f3549d7SRafael J. Wysocki } 14384f3549d7SRafael J. Wysocki device_unlock(dev); 14394f3549d7SRafael J. Wysocki 14404f3549d7SRafael J. Wysocki return ret; 14414f3549d7SRafael J. Wysocki } 14424f3549d7SRafael J. Wysocki 14434f3549d7SRafael J. Wysocki /** 14444f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 14454f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 14464f3549d7SRafael J. Wysocki * 14474f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 14484f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 14494f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 14504f3549d7SRafael J. Wysocki * 14514f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 14524f3549d7SRafael J. Wysocki */ 14534f3549d7SRafael J. Wysocki int device_online(struct device *dev) 14544f3549d7SRafael J. Wysocki { 14554f3549d7SRafael J. Wysocki int ret = 0; 14564f3549d7SRafael J. Wysocki 14574f3549d7SRafael J. Wysocki device_lock(dev); 14584f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 14594f3549d7SRafael J. Wysocki if (dev->offline) { 14604f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 14614f3549d7SRafael J. Wysocki if (!ret) { 14624f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 14634f3549d7SRafael J. Wysocki dev->offline = false; 14644f3549d7SRafael J. Wysocki } 14654f3549d7SRafael J. Wysocki } else { 14664f3549d7SRafael J. Wysocki ret = 1; 14674f3549d7SRafael J. Wysocki } 14684f3549d7SRafael J. Wysocki } 14694f3549d7SRafael J. Wysocki device_unlock(dev); 14704f3549d7SRafael J. Wysocki 14714f3549d7SRafael J. Wysocki return ret; 14724f3549d7SRafael J. Wysocki } 14734f3549d7SRafael J. Wysocki 14747f100d15SKarthigan Srinivasan struct root_device { 14750aa0dc41SMark McLoughlin struct device dev; 14760aa0dc41SMark McLoughlin struct module *owner; 14770aa0dc41SMark McLoughlin }; 14780aa0dc41SMark McLoughlin 147993058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 1480481e2079SFerenc Wagner { 1481481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 1482481e2079SFerenc Wagner } 14830aa0dc41SMark McLoughlin 14840aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 14850aa0dc41SMark McLoughlin { 14860aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 14870aa0dc41SMark McLoughlin } 14880aa0dc41SMark McLoughlin 14890aa0dc41SMark McLoughlin /** 14900aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 14910aa0dc41SMark McLoughlin * @name: root device name 14920aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 14930aa0dc41SMark McLoughlin * 14940aa0dc41SMark McLoughlin * This function allocates a root device and registers it 14950aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 14960aa0dc41SMark McLoughlin * device, use root_device_unregister(). 14970aa0dc41SMark McLoughlin * 14980aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 14990aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 15000aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 15010aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 15020aa0dc41SMark McLoughlin * 15030aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 15040aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 15050aa0dc41SMark McLoughlin * in sysfs. 15060aa0dc41SMark McLoughlin * 1507f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1508f0eae0edSJani Nikula * 15090aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 15100aa0dc41SMark McLoughlin */ 15110aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 15120aa0dc41SMark McLoughlin { 15130aa0dc41SMark McLoughlin struct root_device *root; 15140aa0dc41SMark McLoughlin int err = -ENOMEM; 15150aa0dc41SMark McLoughlin 15160aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 15170aa0dc41SMark McLoughlin if (!root) 15180aa0dc41SMark McLoughlin return ERR_PTR(err); 15190aa0dc41SMark McLoughlin 1520acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 15210aa0dc41SMark McLoughlin if (err) { 15220aa0dc41SMark McLoughlin kfree(root); 15230aa0dc41SMark McLoughlin return ERR_PTR(err); 15240aa0dc41SMark McLoughlin } 15250aa0dc41SMark McLoughlin 15260aa0dc41SMark McLoughlin root->dev.release = root_device_release; 15270aa0dc41SMark McLoughlin 15280aa0dc41SMark McLoughlin err = device_register(&root->dev); 15290aa0dc41SMark McLoughlin if (err) { 15300aa0dc41SMark McLoughlin put_device(&root->dev); 15310aa0dc41SMark McLoughlin return ERR_PTR(err); 15320aa0dc41SMark McLoughlin } 15330aa0dc41SMark McLoughlin 15341d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 15350aa0dc41SMark McLoughlin if (owner) { 15360aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 15370aa0dc41SMark McLoughlin 15380aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 15390aa0dc41SMark McLoughlin if (err) { 15400aa0dc41SMark McLoughlin device_unregister(&root->dev); 15410aa0dc41SMark McLoughlin return ERR_PTR(err); 15420aa0dc41SMark McLoughlin } 15430aa0dc41SMark McLoughlin root->owner = owner; 15440aa0dc41SMark McLoughlin } 15450aa0dc41SMark McLoughlin #endif 15460aa0dc41SMark McLoughlin 15470aa0dc41SMark McLoughlin return &root->dev; 15480aa0dc41SMark McLoughlin } 15490aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 15500aa0dc41SMark McLoughlin 15510aa0dc41SMark McLoughlin /** 15520aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 15537cbcf225SRandy Dunlap * @dev: device going away 15540aa0dc41SMark McLoughlin * 15550aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 15560aa0dc41SMark McLoughlin * root_device_register(). 15570aa0dc41SMark McLoughlin */ 15580aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 15590aa0dc41SMark McLoughlin { 15600aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 15610aa0dc41SMark McLoughlin 15620aa0dc41SMark McLoughlin if (root->owner) 15630aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 15640aa0dc41SMark McLoughlin 15650aa0dc41SMark McLoughlin device_unregister(dev); 15660aa0dc41SMark McLoughlin } 15670aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 15680aa0dc41SMark McLoughlin 156923681e47SGreg Kroah-Hartman 157023681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 157123681e47SGreg Kroah-Hartman { 15721e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 157323681e47SGreg Kroah-Hartman kfree(dev); 157423681e47SGreg Kroah-Hartman } 157523681e47SGreg Kroah-Hartman 157639ef3112SGuenter Roeck static struct device * 157739ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 157839ef3112SGuenter Roeck dev_t devt, void *drvdata, 157939ef3112SGuenter Roeck const struct attribute_group **groups, 158039ef3112SGuenter Roeck const char *fmt, va_list args) 158139ef3112SGuenter Roeck { 158239ef3112SGuenter Roeck struct device *dev = NULL; 158339ef3112SGuenter Roeck int retval = -ENODEV; 158439ef3112SGuenter Roeck 158539ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 158639ef3112SGuenter Roeck goto error; 158739ef3112SGuenter Roeck 158839ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 158939ef3112SGuenter Roeck if (!dev) { 159039ef3112SGuenter Roeck retval = -ENOMEM; 159139ef3112SGuenter Roeck goto error; 159239ef3112SGuenter Roeck } 159339ef3112SGuenter Roeck 1594bbc780f8SDavid Herrmann device_initialize(dev); 159539ef3112SGuenter Roeck dev->devt = devt; 159639ef3112SGuenter Roeck dev->class = class; 159739ef3112SGuenter Roeck dev->parent = parent; 159839ef3112SGuenter Roeck dev->groups = groups; 159939ef3112SGuenter Roeck dev->release = device_create_release; 160039ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 160139ef3112SGuenter Roeck 160239ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 160339ef3112SGuenter Roeck if (retval) 160439ef3112SGuenter Roeck goto error; 160539ef3112SGuenter Roeck 1606bbc780f8SDavid Herrmann retval = device_add(dev); 160739ef3112SGuenter Roeck if (retval) 160839ef3112SGuenter Roeck goto error; 160939ef3112SGuenter Roeck 161039ef3112SGuenter Roeck return dev; 161139ef3112SGuenter Roeck 161239ef3112SGuenter Roeck error: 161339ef3112SGuenter Roeck put_device(dev); 161439ef3112SGuenter Roeck return ERR_PTR(retval); 161539ef3112SGuenter Roeck } 161639ef3112SGuenter Roeck 161723681e47SGreg Kroah-Hartman /** 16188882b394SGreg Kroah-Hartman * device_create_vargs - creates a device and registers it with sysfs 16198882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 16208882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 16218882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 16228882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 16238882b394SGreg Kroah-Hartman * @fmt: string for the device's name 16248882b394SGreg Kroah-Hartman * @args: va_list for the device's name 16258882b394SGreg Kroah-Hartman * 16268882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 16278882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 16288882b394SGreg Kroah-Hartman * 16298882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 16308882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 16318882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 16328882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 16338882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 16348882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 16358882b394SGreg Kroah-Hartman * pointer. 16368882b394SGreg Kroah-Hartman * 1637f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1638f0eae0edSJani Nikula * 16398882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 16408882b394SGreg Kroah-Hartman * been created with a call to class_create(). 16418882b394SGreg Kroah-Hartman */ 16428882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent, 16438882b394SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, 16448882b394SGreg Kroah-Hartman va_list args) 16458882b394SGreg Kroah-Hartman { 164639ef3112SGuenter Roeck return device_create_groups_vargs(class, parent, devt, drvdata, NULL, 164739ef3112SGuenter Roeck fmt, args); 16488882b394SGreg Kroah-Hartman } 16498882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs); 16508882b394SGreg Kroah-Hartman 16518882b394SGreg Kroah-Hartman /** 16524e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 16538882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 16548882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 16558882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 16568882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 16578882b394SGreg Kroah-Hartman * @fmt: string for the device's name 16588882b394SGreg Kroah-Hartman * 16598882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 16608882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 16618882b394SGreg Kroah-Hartman * 16628882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 16638882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 16648882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 16658882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 16668882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 16678882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 16688882b394SGreg Kroah-Hartman * pointer. 16698882b394SGreg Kroah-Hartman * 1670f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1671f0eae0edSJani Nikula * 16728882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 16738882b394SGreg Kroah-Hartman * been created with a call to class_create(). 16748882b394SGreg Kroah-Hartman */ 16754e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 16764e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 16778882b394SGreg Kroah-Hartman { 16788882b394SGreg Kroah-Hartman va_list vargs; 16798882b394SGreg Kroah-Hartman struct device *dev; 16808882b394SGreg Kroah-Hartman 16818882b394SGreg Kroah-Hartman va_start(vargs, fmt); 16828882b394SGreg Kroah-Hartman dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); 16838882b394SGreg Kroah-Hartman va_end(vargs); 16848882b394SGreg Kroah-Hartman return dev; 16858882b394SGreg Kroah-Hartman } 16864e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 16878882b394SGreg Kroah-Hartman 168839ef3112SGuenter Roeck /** 168939ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 169039ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 169139ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 169239ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 169339ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 169439ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 169539ef3112SGuenter Roeck * @fmt: string for the device's name 169639ef3112SGuenter Roeck * 169739ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 169839ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 169939ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 170039ef3112SGuenter Roeck * be created automatically. 170139ef3112SGuenter Roeck * 170239ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 170339ef3112SGuenter Roeck * the dev_t is not 0,0. 170439ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 170539ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 170639ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 170739ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 170839ef3112SGuenter Roeck * pointer. 170939ef3112SGuenter Roeck * 171039ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 171139ef3112SGuenter Roeck * 171239ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 171339ef3112SGuenter Roeck * been created with a call to class_create(). 171439ef3112SGuenter Roeck */ 171539ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 171639ef3112SGuenter Roeck struct device *parent, dev_t devt, 171739ef3112SGuenter Roeck void *drvdata, 171839ef3112SGuenter Roeck const struct attribute_group **groups, 171939ef3112SGuenter Roeck const char *fmt, ...) 172039ef3112SGuenter Roeck { 172139ef3112SGuenter Roeck va_list vargs; 172239ef3112SGuenter Roeck struct device *dev; 172339ef3112SGuenter Roeck 172439ef3112SGuenter Roeck va_start(vargs, fmt); 172539ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 172639ef3112SGuenter Roeck fmt, vargs); 172739ef3112SGuenter Roeck va_end(vargs); 172839ef3112SGuenter Roeck return dev; 172939ef3112SGuenter Roeck } 173039ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 173139ef3112SGuenter Roeck 17329f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data) 173323681e47SGreg Kroah-Hartman { 17349f3b795aSMichał Mirosław const dev_t *devt = data; 173523681e47SGreg Kroah-Hartman 1736cd35449bSDave Young return dev->devt == *devt; 1737775b64d2SRafael J. Wysocki } 173823681e47SGreg Kroah-Hartman 1739775b64d2SRafael J. Wysocki /** 1740775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 1741775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 1742775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 1743775b64d2SRafael J. Wysocki * 1744775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 1745775b64d2SRafael J. Wysocki * call to device_create(). 1746775b64d2SRafael J. Wysocki */ 1747775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 1748775b64d2SRafael J. Wysocki { 1749775b64d2SRafael J. Wysocki struct device *dev; 1750775b64d2SRafael J. Wysocki 1751695794aeSGreg Kroah-Hartman dev = class_find_device(class, NULL, &devt, __match_devt); 1752cd35449bSDave Young if (dev) { 1753cd35449bSDave Young put_device(dev); 175423681e47SGreg Kroah-Hartman device_unregister(dev); 175523681e47SGreg Kroah-Hartman } 1756cd35449bSDave Young } 175723681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 1758a2de48caSGreg Kroah-Hartman 1759a2de48caSGreg Kroah-Hartman /** 1760a2de48caSGreg Kroah-Hartman * device_rename - renames a device 1761a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 1762a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 1763030c1d2bSEric W. Biederman * 1764030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 1765030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 1766030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 1767030c1d2bSEric W. Biederman * won't conflict with other devices. 1768c6c0ac66SMichael Ellerman * 1769a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 1770a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 1771a5462516STimur Tabi * some insight: 1772a5462516STimur Tabi * 1773a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 1774a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 1775a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 1776a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 1777a5462516STimur Tabi * 1778a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 1779a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 1780a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 1781a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 1782a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 1783a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 1784a5462516STimur Tabi * 1785a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 1786a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 1787a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 1788a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 1789a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 1790a5462516STimur Tabi * reasons. 1791a5462516STimur Tabi * 1792a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 1793a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 1794a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 1795a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 1796a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 1797a2de48caSGreg Kroah-Hartman */ 17986937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 1799a2de48caSGreg Kroah-Hartman { 18004b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 18012ee97cafSCornelia Huck char *old_device_name = NULL; 1802a2de48caSGreg Kroah-Hartman int error; 1803a2de48caSGreg Kroah-Hartman 1804a2de48caSGreg Kroah-Hartman dev = get_device(dev); 1805a2de48caSGreg Kroah-Hartman if (!dev) 1806a2de48caSGreg Kroah-Hartman return -EINVAL; 1807a2de48caSGreg Kroah-Hartman 180869df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 1809a2de48caSGreg Kroah-Hartman 18101fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 18112ee97cafSCornelia Huck if (!old_device_name) { 1812952ab431SJesper Juhl error = -ENOMEM; 18132ee97cafSCornelia Huck goto out; 1814952ab431SJesper Juhl } 1815a2de48caSGreg Kroah-Hartman 1816f349cf34SEric W. Biederman if (dev->class) { 18174b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 18184b30ee58STejun Heo kobj, old_device_name, 18194b30ee58STejun Heo new_name, kobject_namespace(kobj)); 1820f349cf34SEric W. Biederman if (error) 1821f349cf34SEric W. Biederman goto out; 1822f349cf34SEric W. Biederman } 182339aba963SKay Sievers 18244b30ee58STejun Heo error = kobject_rename(kobj, new_name); 18251fa5ae85SKay Sievers if (error) 18262ee97cafSCornelia Huck goto out; 1827a2de48caSGreg Kroah-Hartman 18282ee97cafSCornelia Huck out: 1829a2de48caSGreg Kroah-Hartman put_device(dev); 1830a2de48caSGreg Kroah-Hartman 18312ee97cafSCornelia Huck kfree(old_device_name); 1832a2de48caSGreg Kroah-Hartman 1833a2de48caSGreg Kroah-Hartman return error; 1834a2de48caSGreg Kroah-Hartman } 1835a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 18368a82472fSCornelia Huck 18378a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 18388a82472fSCornelia Huck struct device *old_parent, 18398a82472fSCornelia Huck struct device *new_parent) 18408a82472fSCornelia Huck { 1841f7f3461dSGreg Kroah-Hartman int error = 0; 18428a82472fSCornelia Huck 1843f7f3461dSGreg Kroah-Hartman if (old_parent) 1844f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 1845f7f3461dSGreg Kroah-Hartman if (new_parent) 1846f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 1847f7f3461dSGreg Kroah-Hartman "device"); 1848f7f3461dSGreg Kroah-Hartman return error; 18498a82472fSCornelia Huck } 18508a82472fSCornelia Huck 18518a82472fSCornelia Huck /** 18528a82472fSCornelia Huck * device_move - moves a device to a new parent 18538a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 1854c744aeaeSCornelia Huck * @new_parent: the new parent of the device (can by NULL) 1855ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 18568a82472fSCornelia Huck */ 1857ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 1858ffa6a705SCornelia Huck enum dpm_order dpm_order) 18598a82472fSCornelia Huck { 18608a82472fSCornelia Huck int error; 18618a82472fSCornelia Huck struct device *old_parent; 1862c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 18638a82472fSCornelia Huck 18648a82472fSCornelia Huck dev = get_device(dev); 18658a82472fSCornelia Huck if (!dev) 18668a82472fSCornelia Huck return -EINVAL; 18678a82472fSCornelia Huck 1868ffa6a705SCornelia Huck device_pm_lock(); 18698a82472fSCornelia Huck new_parent = get_device(new_parent); 1870c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 187163b6971aSCornelia Huck 18721e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 18731e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 1874c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 18758a82472fSCornelia Huck if (error) { 187663b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 18778a82472fSCornelia Huck put_device(new_parent); 18788a82472fSCornelia Huck goto out; 18798a82472fSCornelia Huck } 18808a82472fSCornelia Huck old_parent = dev->parent; 18818a82472fSCornelia Huck dev->parent = new_parent; 18828a82472fSCornelia Huck if (old_parent) 1883f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 18840d358f22SYinghai Lu if (new_parent) { 1885f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1886f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 18870d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 18880d358f22SYinghai Lu } 18890d358f22SYinghai Lu 1890bdd4034dSRabin Vincent if (dev->class) { 18918a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 18928a82472fSCornelia Huck if (error) { 18938a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 18948a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 18958a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 1896c744aeaeSCornelia Huck if (new_parent) 1897f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 18980d358f22SYinghai Lu dev->parent = old_parent; 18990d358f22SYinghai Lu if (old_parent) { 1900f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1901f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 19020d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 19030d358f22SYinghai Lu } 19048a82472fSCornelia Huck } 190563b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 19068a82472fSCornelia Huck put_device(new_parent); 19078a82472fSCornelia Huck goto out; 19088a82472fSCornelia Huck } 1909bdd4034dSRabin Vincent } 1910ffa6a705SCornelia Huck switch (dpm_order) { 1911ffa6a705SCornelia Huck case DPM_ORDER_NONE: 1912ffa6a705SCornelia Huck break; 1913ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 1914ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 1915ffa6a705SCornelia Huck break; 1916ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 1917ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 1918ffa6a705SCornelia Huck break; 1919ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 1920ffa6a705SCornelia Huck device_pm_move_last(dev); 1921ffa6a705SCornelia Huck break; 1922ffa6a705SCornelia Huck } 1923bdd4034dSRabin Vincent 19248a82472fSCornelia Huck put_device(old_parent); 19258a82472fSCornelia Huck out: 1926ffa6a705SCornelia Huck device_pm_unlock(); 19278a82472fSCornelia Huck put_device(dev); 19288a82472fSCornelia Huck return error; 19298a82472fSCornelia Huck } 19308a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 193137b0c020SGreg Kroah-Hartman 193237b0c020SGreg Kroah-Hartman /** 193337b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 193437b0c020SGreg Kroah-Hartman */ 193537b0c020SGreg Kroah-Hartman void device_shutdown(void) 193637b0c020SGreg Kroah-Hartman { 1937f123db8eSBenson Leung struct device *dev, *parent; 193837b0c020SGreg Kroah-Hartman 19396245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 19406245838fSHugh Daschbach /* 19416245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 19426245838fSHugh Daschbach * Beware that device unplug events may also start pulling 19436245838fSHugh Daschbach * devices offline, even as the system is shutting down. 19446245838fSHugh Daschbach */ 19456245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 19466245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 19476245838fSHugh Daschbach kobj.entry); 1948d1c6c030SMing Lei 1949d1c6c030SMing Lei /* 1950d1c6c030SMing Lei * hold reference count of device's parent to 1951d1c6c030SMing Lei * prevent it from being freed because parent's 1952d1c6c030SMing Lei * lock is to be held 1953d1c6c030SMing Lei */ 1954f123db8eSBenson Leung parent = get_device(dev->parent); 19556245838fSHugh Daschbach get_device(dev); 19566245838fSHugh Daschbach /* 19576245838fSHugh Daschbach * Make sure the device is off the kset list, in the 19586245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 19596245838fSHugh Daschbach */ 19606245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 19616245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 1962fe6b91f4SAlan Stern 1963d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 1964f123db8eSBenson Leung if (parent) 1965f123db8eSBenson Leung device_lock(parent); 1966d1c6c030SMing Lei device_lock(dev); 1967d1c6c030SMing Lei 1968fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 1969fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 1970fe6b91f4SAlan Stern pm_runtime_barrier(dev); 19716245838fSHugh Daschbach 197237b0c020SGreg Kroah-Hartman if (dev->bus && dev->bus->shutdown) { 19730246c4faSShuoX Liu if (initcall_debug) 19740246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 197537b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 197637b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 19770246c4faSShuoX Liu if (initcall_debug) 19780246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 197937b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 198037b0c020SGreg Kroah-Hartman } 1981d1c6c030SMing Lei 1982d1c6c030SMing Lei device_unlock(dev); 1983f123db8eSBenson Leung if (parent) 1984f123db8eSBenson Leung device_unlock(parent); 1985d1c6c030SMing Lei 19866245838fSHugh Daschbach put_device(dev); 1987f123db8eSBenson Leung put_device(parent); 19886245838fSHugh Daschbach 19896245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 199037b0c020SGreg Kroah-Hartman } 19916245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 199237b0c020SGreg Kroah-Hartman } 199399bcf217SJoe Perches 199499bcf217SJoe Perches /* 199599bcf217SJoe Perches * Device logging functions 199699bcf217SJoe Perches */ 199799bcf217SJoe Perches 199899bcf217SJoe Perches #ifdef CONFIG_PRINTK 1999666f355fSJoe Perches static int 2000666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 200199bcf217SJoe Perches { 2002c4e00daaSKay Sievers const char *subsys; 2003798efc60SJoe Perches size_t pos = 0; 200499bcf217SJoe Perches 2005c4e00daaSKay Sievers if (dev->class) 2006c4e00daaSKay Sievers subsys = dev->class->name; 2007c4e00daaSKay Sievers else if (dev->bus) 2008c4e00daaSKay Sievers subsys = dev->bus->name; 2009c4e00daaSKay Sievers else 2010798efc60SJoe Perches return 0; 2011c4e00daaSKay Sievers 2012798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 2013c4e00daaSKay Sievers 2014c4e00daaSKay Sievers /* 2015c4e00daaSKay Sievers * Add device identifier DEVICE=: 2016c4e00daaSKay Sievers * b12:8 block dev_t 2017c4e00daaSKay Sievers * c127:3 char dev_t 2018c4e00daaSKay Sievers * n8 netdev ifindex 2019c4e00daaSKay Sievers * +sound:card0 subsystem:devname 2020c4e00daaSKay Sievers */ 2021c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 2022c4e00daaSKay Sievers char c; 2023c4e00daaSKay Sievers 2024c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 2025c4e00daaSKay Sievers c = 'b'; 2026c4e00daaSKay Sievers else 2027c4e00daaSKay Sievers c = 'c'; 2028798efc60SJoe Perches pos++; 2029798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2030c4e00daaSKay Sievers "DEVICE=%c%u:%u", 2031c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 2032c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 2033c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 2034c4e00daaSKay Sievers 2035798efc60SJoe Perches pos++; 2036798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2037c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 2038c4e00daaSKay Sievers } else { 2039798efc60SJoe Perches pos++; 2040798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2041c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 2042c4e00daaSKay Sievers } 2043af7f2158SJim Cromie 2044798efc60SJoe Perches return pos; 204599bcf217SJoe Perches } 2046798efc60SJoe Perches 204705e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 204805e4e5b8SJoe Perches const char *fmt, va_list args) 204905e4e5b8SJoe Perches { 205005e4e5b8SJoe Perches char hdr[128]; 205105e4e5b8SJoe Perches size_t hdrlen; 205205e4e5b8SJoe Perches 205305e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 205405e4e5b8SJoe Perches 205505e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 205605e4e5b8SJoe Perches } 205705e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 205805e4e5b8SJoe Perches 205905e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 206005e4e5b8SJoe Perches { 206105e4e5b8SJoe Perches va_list args; 206205e4e5b8SJoe Perches int r; 206305e4e5b8SJoe Perches 206405e4e5b8SJoe Perches va_start(args, fmt); 206505e4e5b8SJoe Perches 206605e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 206705e4e5b8SJoe Perches 206805e4e5b8SJoe Perches va_end(args); 206905e4e5b8SJoe Perches 207005e4e5b8SJoe Perches return r; 207105e4e5b8SJoe Perches } 207205e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 207305e4e5b8SJoe Perches 2074798efc60SJoe Perches static int __dev_printk(const char *level, const struct device *dev, 2075798efc60SJoe Perches struct va_format *vaf) 2076798efc60SJoe Perches { 2077798efc60SJoe Perches if (!dev) 2078798efc60SJoe Perches return printk("%s(NULL device *): %pV", level, vaf); 2079798efc60SJoe Perches 2080666f355fSJoe Perches return dev_printk_emit(level[1] - '0', dev, 2081798efc60SJoe Perches "%s %s: %pV", 2082798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 2083798efc60SJoe Perches } 208499bcf217SJoe Perches 208599bcf217SJoe Perches int dev_printk(const char *level, const struct device *dev, 208699bcf217SJoe Perches const char *fmt, ...) 208799bcf217SJoe Perches { 208899bcf217SJoe Perches struct va_format vaf; 208999bcf217SJoe Perches va_list args; 209099bcf217SJoe Perches int r; 209199bcf217SJoe Perches 209299bcf217SJoe Perches va_start(args, fmt); 209399bcf217SJoe Perches 209499bcf217SJoe Perches vaf.fmt = fmt; 209599bcf217SJoe Perches vaf.va = &args; 209699bcf217SJoe Perches 209799bcf217SJoe Perches r = __dev_printk(level, dev, &vaf); 2098798efc60SJoe Perches 209999bcf217SJoe Perches va_end(args); 210099bcf217SJoe Perches 210199bcf217SJoe Perches return r; 210299bcf217SJoe Perches } 210399bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 210499bcf217SJoe Perches 210599bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 210699bcf217SJoe Perches int func(const struct device *dev, const char *fmt, ...) \ 210799bcf217SJoe Perches { \ 210899bcf217SJoe Perches struct va_format vaf; \ 210999bcf217SJoe Perches va_list args; \ 211099bcf217SJoe Perches int r; \ 211199bcf217SJoe Perches \ 211299bcf217SJoe Perches va_start(args, fmt); \ 211399bcf217SJoe Perches \ 211499bcf217SJoe Perches vaf.fmt = fmt; \ 211599bcf217SJoe Perches vaf.va = &args; \ 211699bcf217SJoe Perches \ 211799bcf217SJoe Perches r = __dev_printk(kern_level, dev, &vaf); \ 2118798efc60SJoe Perches \ 211999bcf217SJoe Perches va_end(args); \ 212099bcf217SJoe Perches \ 212199bcf217SJoe Perches return r; \ 212299bcf217SJoe Perches } \ 212399bcf217SJoe Perches EXPORT_SYMBOL(func); 212499bcf217SJoe Perches 212599bcf217SJoe Perches define_dev_printk_level(dev_emerg, KERN_EMERG); 212699bcf217SJoe Perches define_dev_printk_level(dev_alert, KERN_ALERT); 212799bcf217SJoe Perches define_dev_printk_level(dev_crit, KERN_CRIT); 212899bcf217SJoe Perches define_dev_printk_level(dev_err, KERN_ERR); 212999bcf217SJoe Perches define_dev_printk_level(dev_warn, KERN_WARNING); 213099bcf217SJoe Perches define_dev_printk_level(dev_notice, KERN_NOTICE); 213199bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 213299bcf217SJoe Perches 213399bcf217SJoe Perches #endif 2134