11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * drivers/base/core.c - core driver model code (device registration, etc) 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 664bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de> 764bb5d2cSGreg Kroah-Hartman * Copyright (c) 2006 Novell, Inc. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * This file is released under the GPLv2 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds #include <linux/device.h> 141da177e4SLinus Torvalds #include <linux/err.h> 1597badf87SRafael J. Wysocki #include <linux/fwnode.h> 161da177e4SLinus Torvalds #include <linux/init.h> 171da177e4SLinus Torvalds #include <linux/module.h> 181da177e4SLinus Torvalds #include <linux/slab.h> 191da177e4SLinus Torvalds #include <linux/string.h> 2023681e47SGreg Kroah-Hartman #include <linux/kdev_t.h> 21116af378SBenjamin Herrenschmidt #include <linux/notifier.h> 2207d57a32SGrant Likely #include <linux/of.h> 2307d57a32SGrant Likely #include <linux/of_device.h> 24da231fd5SKay Sievers #include <linux/genhd.h> 25815d2d50SAndrew Morton #include <linux/kallsyms.h> 26f75b1c60SDave Young #include <linux/mutex.h> 27af8db150SPeter Chen #include <linux/pm_runtime.h> 28c4e00daaSKay Sievers #include <linux/netdevice.h> 2963967685SGreg Kroah-Hartman #include <linux/sysfs.h> 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds #include "base.h" 321da177e4SLinus Torvalds #include "power/power.h" 331da177e4SLinus Torvalds 34e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED 35e52eec13SAndi Kleen #ifdef CONFIG_SYSFS_DEPRECATED_V2 36e52eec13SAndi Kleen long sysfs_deprecated = 1; 37e52eec13SAndi Kleen #else 38e52eec13SAndi Kleen long sysfs_deprecated = 0; 39e52eec13SAndi Kleen #endif 403454bf96SHanjun Guo static int __init sysfs_deprecated_setup(char *arg) 41e52eec13SAndi Kleen { 4234da5e67SJingoo Han return kstrtol(arg, 10, &sysfs_deprecated); 43e52eec13SAndi Kleen } 44e52eec13SAndi Kleen early_param("sysfs.deprecated", sysfs_deprecated_setup); 45e52eec13SAndi Kleen #endif 46e52eec13SAndi Kleen 471da177e4SLinus Torvalds int (*platform_notify)(struct device *dev) = NULL; 481da177e4SLinus Torvalds int (*platform_notify_remove)(struct device *dev) = NULL; 49e105b8bfSDan Williams static struct kobject *dev_kobj; 50e105b8bfSDan Williams struct kobject *sysfs_dev_char_kobj; 51e105b8bfSDan Williams struct kobject *sysfs_dev_block_kobj; 521da177e4SLinus Torvalds 535e33bc41SRafael J. Wysocki static DEFINE_MUTEX(device_hotplug_lock); 545e33bc41SRafael J. Wysocki 555e33bc41SRafael J. Wysocki void lock_device_hotplug(void) 565e33bc41SRafael J. Wysocki { 575e33bc41SRafael J. Wysocki mutex_lock(&device_hotplug_lock); 585e33bc41SRafael J. Wysocki } 595e33bc41SRafael J. Wysocki 605e33bc41SRafael J. Wysocki void unlock_device_hotplug(void) 615e33bc41SRafael J. Wysocki { 625e33bc41SRafael J. Wysocki mutex_unlock(&device_hotplug_lock); 635e33bc41SRafael J. Wysocki } 645e33bc41SRafael J. Wysocki 655e33bc41SRafael J. Wysocki int lock_device_hotplug_sysfs(void) 665e33bc41SRafael J. Wysocki { 675e33bc41SRafael J. Wysocki if (mutex_trylock(&device_hotplug_lock)) 685e33bc41SRafael J. Wysocki return 0; 695e33bc41SRafael J. Wysocki 705e33bc41SRafael J. Wysocki /* Avoid busy looping (5 ms of sleep should do). */ 715e33bc41SRafael J. Wysocki msleep(5); 725e33bc41SRafael J. Wysocki return restart_syscall(); 735e33bc41SRafael J. Wysocki } 745e33bc41SRafael J. Wysocki 754e886c29SGreg Kroah-Hartman #ifdef CONFIG_BLOCK 764e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 774e886c29SGreg Kroah-Hartman { 784e886c29SGreg Kroah-Hartman return !(dev->type == &part_type); 794e886c29SGreg Kroah-Hartman } 804e886c29SGreg Kroah-Hartman #else 814e886c29SGreg Kroah-Hartman static inline int device_is_not_partition(struct device *dev) 824e886c29SGreg Kroah-Hartman { 834e886c29SGreg Kroah-Hartman return 1; 844e886c29SGreg Kroah-Hartman } 854e886c29SGreg Kroah-Hartman #endif 861da177e4SLinus Torvalds 873e95637aSAlan Stern /** 883e95637aSAlan Stern * dev_driver_string - Return a device's driver name, if at all possible 893e95637aSAlan Stern * @dev: struct device to get the name of 903e95637aSAlan Stern * 913e95637aSAlan Stern * Will return the device's driver's name if it is bound to a device. If 929169c012Syan * the device is not bound to a driver, it will return the name of the bus 933e95637aSAlan Stern * it is attached to. If it is not attached to a bus either, an empty 943e95637aSAlan Stern * string will be returned. 953e95637aSAlan Stern */ 96bf9ca69fSJean Delvare const char *dev_driver_string(const struct device *dev) 973e95637aSAlan Stern { 983589972eSAlan Stern struct device_driver *drv; 993589972eSAlan Stern 1003589972eSAlan Stern /* dev->driver can change to NULL underneath us because of unbinding, 1013589972eSAlan Stern * so be careful about accessing it. dev->bus and dev->class should 1023589972eSAlan Stern * never change once they are set, so they don't need special care. 1033589972eSAlan Stern */ 1043589972eSAlan Stern drv = ACCESS_ONCE(dev->driver); 1053589972eSAlan Stern return drv ? drv->name : 106a456b702SJean Delvare (dev->bus ? dev->bus->name : 107a456b702SJean Delvare (dev->class ? dev->class->name : "")); 1083e95637aSAlan Stern } 109310a922dSMatthew Wilcox EXPORT_SYMBOL(dev_driver_string); 1103e95637aSAlan Stern 1111da177e4SLinus Torvalds #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 1121da177e4SLinus Torvalds 1134a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, 1144a3ad20cSGreg Kroah-Hartman char *buf) 1151da177e4SLinus Torvalds { 1161da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 117b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1184a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds if (dev_attr->show) 12154b6f35cSYani Ioannou ret = dev_attr->show(dev, dev_attr, buf); 122815d2d50SAndrew Morton if (ret >= (ssize_t)PAGE_SIZE) { 12353a9c87eSGreg Kroah-Hartman print_symbol("dev_attr_show: %s returned bad count\n", 12453a9c87eSGreg Kroah-Hartman (unsigned long)dev_attr->show); 125815d2d50SAndrew Morton } 1261da177e4SLinus Torvalds return ret; 1271da177e4SLinus Torvalds } 1281da177e4SLinus Torvalds 1294a3ad20cSGreg Kroah-Hartman static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, 1301da177e4SLinus Torvalds const char *buf, size_t count) 1311da177e4SLinus Torvalds { 1321da177e4SLinus Torvalds struct device_attribute *dev_attr = to_dev_attr(attr); 133b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 1344a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds if (dev_attr->store) 13754b6f35cSYani Ioannou ret = dev_attr->store(dev, dev_attr, buf, count); 1381da177e4SLinus Torvalds return ret; 1391da177e4SLinus Torvalds } 1401da177e4SLinus Torvalds 14152cf25d0SEmese Revfy static const struct sysfs_ops dev_sysfs_ops = { 1421da177e4SLinus Torvalds .show = dev_attr_show, 1431da177e4SLinus Torvalds .store = dev_attr_store, 1441da177e4SLinus Torvalds }; 1451da177e4SLinus Torvalds 146ca22e56dSKay Sievers #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) 147ca22e56dSKay Sievers 148ca22e56dSKay Sievers ssize_t device_store_ulong(struct device *dev, 149ca22e56dSKay Sievers struct device_attribute *attr, 150ca22e56dSKay Sievers const char *buf, size_t size) 151ca22e56dSKay Sievers { 152ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 153ca22e56dSKay Sievers char *end; 154ca22e56dSKay Sievers unsigned long new = simple_strtoul(buf, &end, 0); 155ca22e56dSKay Sievers if (end == buf) 156ca22e56dSKay Sievers return -EINVAL; 157ca22e56dSKay Sievers *(unsigned long *)(ea->var) = new; 158ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 159ca22e56dSKay Sievers return size; 160ca22e56dSKay Sievers } 161ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_ulong); 162ca22e56dSKay Sievers 163ca22e56dSKay Sievers ssize_t device_show_ulong(struct device *dev, 164ca22e56dSKay Sievers struct device_attribute *attr, 165ca22e56dSKay Sievers char *buf) 166ca22e56dSKay Sievers { 167ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 168ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); 169ca22e56dSKay Sievers } 170ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_ulong); 171ca22e56dSKay Sievers 172ca22e56dSKay Sievers ssize_t device_store_int(struct device *dev, 173ca22e56dSKay Sievers struct device_attribute *attr, 174ca22e56dSKay Sievers const char *buf, size_t size) 175ca22e56dSKay Sievers { 176ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 177ca22e56dSKay Sievers char *end; 178ca22e56dSKay Sievers long new = simple_strtol(buf, &end, 0); 179ca22e56dSKay Sievers if (end == buf || new > INT_MAX || new < INT_MIN) 180ca22e56dSKay Sievers return -EINVAL; 181ca22e56dSKay Sievers *(int *)(ea->var) = new; 182ca22e56dSKay Sievers /* Always return full write size even if we didn't consume all */ 183ca22e56dSKay Sievers return size; 184ca22e56dSKay Sievers } 185ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_store_int); 186ca22e56dSKay Sievers 187ca22e56dSKay Sievers ssize_t device_show_int(struct device *dev, 188ca22e56dSKay Sievers struct device_attribute *attr, 189ca22e56dSKay Sievers char *buf) 190ca22e56dSKay Sievers { 191ca22e56dSKay Sievers struct dev_ext_attribute *ea = to_ext_attr(attr); 192ca22e56dSKay Sievers 193ca22e56dSKay Sievers return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); 194ca22e56dSKay Sievers } 195ca22e56dSKay Sievers EXPORT_SYMBOL_GPL(device_show_int); 1961da177e4SLinus Torvalds 19791872392SBorislav Petkov ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 19891872392SBorislav Petkov const char *buf, size_t size) 19991872392SBorislav Petkov { 20091872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 20191872392SBorislav Petkov 20291872392SBorislav Petkov if (strtobool(buf, ea->var) < 0) 20391872392SBorislav Petkov return -EINVAL; 20491872392SBorislav Petkov 20591872392SBorislav Petkov return size; 20691872392SBorislav Petkov } 20791872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_store_bool); 20891872392SBorislav Petkov 20991872392SBorislav Petkov ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, 21091872392SBorislav Petkov char *buf) 21191872392SBorislav Petkov { 21291872392SBorislav Petkov struct dev_ext_attribute *ea = to_ext_attr(attr); 21391872392SBorislav Petkov 21491872392SBorislav Petkov return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); 21591872392SBorislav Petkov } 21691872392SBorislav Petkov EXPORT_SYMBOL_GPL(device_show_bool); 21791872392SBorislav Petkov 2181da177e4SLinus Torvalds /** 2191da177e4SLinus Torvalds * device_release - free device structure. 2201da177e4SLinus Torvalds * @kobj: device's kobject. 2211da177e4SLinus Torvalds * 2221da177e4SLinus Torvalds * This is called once the reference count for the object 2231da177e4SLinus Torvalds * reaches 0. We forward the call to the device's release 2241da177e4SLinus Torvalds * method, which should handle actually freeing the structure. 2251da177e4SLinus Torvalds */ 2261da177e4SLinus Torvalds static void device_release(struct kobject *kobj) 2271da177e4SLinus Torvalds { 228b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 229fb069a5dSGreg Kroah-Hartman struct device_private *p = dev->p; 2301da177e4SLinus Torvalds 231a525a3ddSMing Lei /* 232a525a3ddSMing Lei * Some platform devices are driven without driver attached 233a525a3ddSMing Lei * and managed resources may have been acquired. Make sure 234a525a3ddSMing Lei * all resources are released. 235a525a3ddSMing Lei * 236a525a3ddSMing Lei * Drivers still can add resources into device after device 237a525a3ddSMing Lei * is deleted but alive, so release devres here to avoid 238a525a3ddSMing Lei * possible memory leak. 239a525a3ddSMing Lei */ 240a525a3ddSMing Lei devres_release_all(dev); 241a525a3ddSMing Lei 2421da177e4SLinus Torvalds if (dev->release) 2431da177e4SLinus Torvalds dev->release(dev); 244f9f852dfSKay Sievers else if (dev->type && dev->type->release) 245f9f852dfSKay Sievers dev->type->release(dev); 2462620efefSGreg Kroah-Hartman else if (dev->class && dev->class->dev_release) 2472620efefSGreg Kroah-Hartman dev->class->dev_release(dev); 248f810a5cfSArjan van de Ven else 249f810a5cfSArjan van de Ven WARN(1, KERN_ERR "Device '%s' does not have a release() " 2504a3ad20cSGreg Kroah-Hartman "function, it is broken and must be fixed.\n", 2511e0b2cf9SKay Sievers dev_name(dev)); 252fb069a5dSGreg Kroah-Hartman kfree(p); 2531da177e4SLinus Torvalds } 2541da177e4SLinus Torvalds 255bc451f20SEric W. Biederman static const void *device_namespace(struct kobject *kobj) 256bc451f20SEric W. Biederman { 257b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 258bc451f20SEric W. Biederman const void *ns = NULL; 259bc451f20SEric W. Biederman 260bc451f20SEric W. Biederman if (dev->class && dev->class->ns_type) 261bc451f20SEric W. Biederman ns = dev->class->namespace(dev); 262bc451f20SEric W. Biederman 263bc451f20SEric W. Biederman return ns; 264bc451f20SEric W. Biederman } 265bc451f20SEric W. Biederman 2668f4afc41SGreg Kroah-Hartman static struct kobj_type device_ktype = { 2671da177e4SLinus Torvalds .release = device_release, 2681da177e4SLinus Torvalds .sysfs_ops = &dev_sysfs_ops, 269bc451f20SEric W. Biederman .namespace = device_namespace, 2701da177e4SLinus Torvalds }; 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds 273312c004dSKay Sievers static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) 2741da177e4SLinus Torvalds { 2751da177e4SLinus Torvalds struct kobj_type *ktype = get_ktype(kobj); 2761da177e4SLinus Torvalds 2778f4afc41SGreg Kroah-Hartman if (ktype == &device_ktype) { 278b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 2791da177e4SLinus Torvalds if (dev->bus) 2801da177e4SLinus Torvalds return 1; 28123681e47SGreg Kroah-Hartman if (dev->class) 28223681e47SGreg Kroah-Hartman return 1; 2831da177e4SLinus Torvalds } 2841da177e4SLinus Torvalds return 0; 2851da177e4SLinus Torvalds } 2861da177e4SLinus Torvalds 287312c004dSKay Sievers static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) 2881da177e4SLinus Torvalds { 289b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 2901da177e4SLinus Torvalds 29123681e47SGreg Kroah-Hartman if (dev->bus) 2921da177e4SLinus Torvalds return dev->bus->name; 29323681e47SGreg Kroah-Hartman if (dev->class) 29423681e47SGreg Kroah-Hartman return dev->class->name; 29523681e47SGreg Kroah-Hartman return NULL; 2961da177e4SLinus Torvalds } 2971da177e4SLinus Torvalds 2987eff2e7aSKay Sievers static int dev_uevent(struct kset *kset, struct kobject *kobj, 2997eff2e7aSKay Sievers struct kobj_uevent_env *env) 3001da177e4SLinus Torvalds { 301b0d1f807SLars-Peter Clausen struct device *dev = kobj_to_dev(kobj); 3021da177e4SLinus Torvalds int retval = 0; 3031da177e4SLinus Torvalds 3046fcf53acSKay Sievers /* add device node properties if present */ 30523681e47SGreg Kroah-Hartman if (MAJOR(dev->devt)) { 3066fcf53acSKay Sievers const char *tmp; 3076fcf53acSKay Sievers const char *name; 3082c9ede55SAl Viro umode_t mode = 0; 3094e4098a3SGreg Kroah-Hartman kuid_t uid = GLOBAL_ROOT_UID; 3104e4098a3SGreg Kroah-Hartman kgid_t gid = GLOBAL_ROOT_GID; 3116fcf53acSKay Sievers 3127eff2e7aSKay Sievers add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 3137eff2e7aSKay Sievers add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 3143c2670e6SKay Sievers name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); 3156fcf53acSKay Sievers if (name) { 3166fcf53acSKay Sievers add_uevent_var(env, "DEVNAME=%s", name); 317e454cea2SKay Sievers if (mode) 318e454cea2SKay Sievers add_uevent_var(env, "DEVMODE=%#o", mode & 0777); 3194e4098a3SGreg Kroah-Hartman if (!uid_eq(uid, GLOBAL_ROOT_UID)) 3204e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 3214e4098a3SGreg Kroah-Hartman if (!gid_eq(gid, GLOBAL_ROOT_GID)) 3224e4098a3SGreg Kroah-Hartman add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 3233c2670e6SKay Sievers kfree(tmp); 3246fcf53acSKay Sievers } 32523681e47SGreg Kroah-Hartman } 32623681e47SGreg Kroah-Hartman 327414264f9SKay Sievers if (dev->type && dev->type->name) 3287eff2e7aSKay Sievers add_uevent_var(env, "DEVTYPE=%s", dev->type->name); 329414264f9SKay Sievers 330239378f1SKay Sievers if (dev->driver) 3317eff2e7aSKay Sievers add_uevent_var(env, "DRIVER=%s", dev->driver->name); 332239378f1SKay Sievers 33307d57a32SGrant Likely /* Add common DT information about the device */ 33407d57a32SGrant Likely of_device_uevent(dev, env); 33507d57a32SGrant Likely 3361da177e4SLinus Torvalds /* have the bus specific function add its stuff */ 3377eff2e7aSKay Sievers if (dev->bus && dev->bus->uevent) { 3387eff2e7aSKay Sievers retval = dev->bus->uevent(dev, env); 339f9f852dfSKay Sievers if (retval) 3407dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: bus uevent() returned %d\n", 3411e0b2cf9SKay Sievers dev_name(dev), __func__, retval); 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 3442620efefSGreg Kroah-Hartman /* have the class specific function add its stuff */ 3457eff2e7aSKay Sievers if (dev->class && dev->class->dev_uevent) { 3467eff2e7aSKay Sievers retval = dev->class->dev_uevent(dev, env); 347f9f852dfSKay Sievers if (retval) 3487dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: class uevent() " 3491e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 3502b3a302aSHarvey Harrison __func__, retval); 3512620efefSGreg Kroah-Hartman } 352f9f852dfSKay Sievers 353eef35c2dSStefan Weil /* have the device type specific function add its stuff */ 3547eff2e7aSKay Sievers if (dev->type && dev->type->uevent) { 3557eff2e7aSKay Sievers retval = dev->type->uevent(dev, env); 356f9f852dfSKay Sievers if (retval) 3577dc72b28SGreg Kroah-Hartman pr_debug("device: '%s': %s: dev_type uevent() " 3581e0b2cf9SKay Sievers "returned %d\n", dev_name(dev), 3592b3a302aSHarvey Harrison __func__, retval); 3602620efefSGreg Kroah-Hartman } 3612620efefSGreg Kroah-Hartman 3621da177e4SLinus Torvalds return retval; 3631da177e4SLinus Torvalds } 3641da177e4SLinus Torvalds 3659cd43611SEmese Revfy static const struct kset_uevent_ops device_uevent_ops = { 366312c004dSKay Sievers .filter = dev_uevent_filter, 367312c004dSKay Sievers .name = dev_uevent_name, 368312c004dSKay Sievers .uevent = dev_uevent, 3691da177e4SLinus Torvalds }; 3701da177e4SLinus Torvalds 371c5e064a6SGreg Kroah-Hartman static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, 37216574dccSKay Sievers char *buf) 37316574dccSKay Sievers { 37416574dccSKay Sievers struct kobject *top_kobj; 37516574dccSKay Sievers struct kset *kset; 3767eff2e7aSKay Sievers struct kobj_uevent_env *env = NULL; 37716574dccSKay Sievers int i; 37816574dccSKay Sievers size_t count = 0; 37916574dccSKay Sievers int retval; 38016574dccSKay Sievers 38116574dccSKay Sievers /* search the kset, the device belongs to */ 38216574dccSKay Sievers top_kobj = &dev->kobj; 3835c5daf65SKay Sievers while (!top_kobj->kset && top_kobj->parent) 38416574dccSKay Sievers top_kobj = top_kobj->parent; 38516574dccSKay Sievers if (!top_kobj->kset) 38616574dccSKay Sievers goto out; 3875c5daf65SKay Sievers 38816574dccSKay Sievers kset = top_kobj->kset; 38916574dccSKay Sievers if (!kset->uevent_ops || !kset->uevent_ops->uevent) 39016574dccSKay Sievers goto out; 39116574dccSKay Sievers 39216574dccSKay Sievers /* respect filter */ 39316574dccSKay Sievers if (kset->uevent_ops && kset->uevent_ops->filter) 39416574dccSKay Sievers if (!kset->uevent_ops->filter(kset, &dev->kobj)) 39516574dccSKay Sievers goto out; 39616574dccSKay Sievers 3977eff2e7aSKay Sievers env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); 3987eff2e7aSKay Sievers if (!env) 399c7308c81SGreg Kroah-Hartman return -ENOMEM; 400c7308c81SGreg Kroah-Hartman 40116574dccSKay Sievers /* let the kset specific function add its keys */ 4027eff2e7aSKay Sievers retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); 40316574dccSKay Sievers if (retval) 40416574dccSKay Sievers goto out; 40516574dccSKay Sievers 40616574dccSKay Sievers /* copy keys to file */ 4077eff2e7aSKay Sievers for (i = 0; i < env->envp_idx; i++) 4087eff2e7aSKay Sievers count += sprintf(&buf[count], "%s\n", env->envp[i]); 40916574dccSKay Sievers out: 4107eff2e7aSKay Sievers kfree(env); 41116574dccSKay Sievers return count; 41216574dccSKay Sievers } 41316574dccSKay Sievers 414c5e064a6SGreg Kroah-Hartman static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, 415a7fd6706SKay Sievers const char *buf, size_t count) 416a7fd6706SKay Sievers { 41760a96a59SKay Sievers enum kobject_action action; 41860a96a59SKay Sievers 4193f5468c9SKay Sievers if (kobject_action_type(buf, count, &action) == 0) 42060a96a59SKay Sievers kobject_uevent(&dev->kobj, action); 4213f5468c9SKay Sievers else 4223f5468c9SKay Sievers dev_err(dev, "uevent: unknown action-string\n"); 423a7fd6706SKay Sievers return count; 424a7fd6706SKay Sievers } 425c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(uevent); 426a7fd6706SKay Sievers 427c5e064a6SGreg Kroah-Hartman static ssize_t online_show(struct device *dev, struct device_attribute *attr, 4284f3549d7SRafael J. Wysocki char *buf) 4294f3549d7SRafael J. Wysocki { 4304f3549d7SRafael J. Wysocki bool val; 4314f3549d7SRafael J. Wysocki 4325e33bc41SRafael J. Wysocki device_lock(dev); 4334f3549d7SRafael J. Wysocki val = !dev->offline; 4345e33bc41SRafael J. Wysocki device_unlock(dev); 4354f3549d7SRafael J. Wysocki return sprintf(buf, "%u\n", val); 4364f3549d7SRafael J. Wysocki } 4374f3549d7SRafael J. Wysocki 438c5e064a6SGreg Kroah-Hartman static ssize_t online_store(struct device *dev, struct device_attribute *attr, 4394f3549d7SRafael J. Wysocki const char *buf, size_t count) 4404f3549d7SRafael J. Wysocki { 4414f3549d7SRafael J. Wysocki bool val; 4424f3549d7SRafael J. Wysocki int ret; 4434f3549d7SRafael J. Wysocki 4444f3549d7SRafael J. Wysocki ret = strtobool(buf, &val); 4454f3549d7SRafael J. Wysocki if (ret < 0) 4464f3549d7SRafael J. Wysocki return ret; 4474f3549d7SRafael J. Wysocki 4485e33bc41SRafael J. Wysocki ret = lock_device_hotplug_sysfs(); 4495e33bc41SRafael J. Wysocki if (ret) 4505e33bc41SRafael J. Wysocki return ret; 4515e33bc41SRafael J. Wysocki 4524f3549d7SRafael J. Wysocki ret = val ? device_online(dev) : device_offline(dev); 4534f3549d7SRafael J. Wysocki unlock_device_hotplug(); 4544f3549d7SRafael J. Wysocki return ret < 0 ? ret : count; 4554f3549d7SRafael J. Wysocki } 456c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RW(online); 4574f3549d7SRafael J. Wysocki 458fa6fdb33SGreg Kroah-Hartman int device_add_groups(struct device *dev, const struct attribute_group **groups) 459621a1672SDmitry Torokhov { 4603e9b2baeSGreg Kroah-Hartman return sysfs_create_groups(&dev->kobj, groups); 461621a1672SDmitry Torokhov } 462621a1672SDmitry Torokhov 463fa6fdb33SGreg Kroah-Hartman void device_remove_groups(struct device *dev, 464a4dbd674SDavid Brownell const struct attribute_group **groups) 465621a1672SDmitry Torokhov { 4663e9b2baeSGreg Kroah-Hartman sysfs_remove_groups(&dev->kobj, groups); 467621a1672SDmitry Torokhov } 468de0ff00dSGreg Kroah-Hartman 4692620efefSGreg Kroah-Hartman static int device_add_attrs(struct device *dev) 4702620efefSGreg Kroah-Hartman { 4712620efefSGreg Kroah-Hartman struct class *class = dev->class; 472aed65af1SStephen Hemminger const struct device_type *type = dev->type; 473621a1672SDmitry Torokhov int error; 4742620efefSGreg Kroah-Hartman 475621a1672SDmitry Torokhov if (class) { 476d05a6f96SGreg Kroah-Hartman error = device_add_groups(dev, class->dev_groups); 4772620efefSGreg Kroah-Hartman if (error) 478621a1672SDmitry Torokhov return error; 479f9f852dfSKay Sievers } 480f9f852dfSKay Sievers 481621a1672SDmitry Torokhov if (type) { 482621a1672SDmitry Torokhov error = device_add_groups(dev, type->groups); 483f9f852dfSKay Sievers if (error) 484a6b01dedSGreg Kroah-Hartman goto err_remove_class_groups; 485f9f852dfSKay Sievers } 486621a1672SDmitry Torokhov 487621a1672SDmitry Torokhov error = device_add_groups(dev, dev->groups); 488f9f852dfSKay Sievers if (error) 489621a1672SDmitry Torokhov goto err_remove_type_groups; 490621a1672SDmitry Torokhov 4914f3549d7SRafael J. Wysocki if (device_supports_offline(dev) && !dev->offline_disabled) { 492c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_online); 4934f3549d7SRafael J. Wysocki if (error) 494ecfbf6fdSRafael J. Wysocki goto err_remove_dev_groups; 4954f3549d7SRafael J. Wysocki } 4964f3549d7SRafael J. Wysocki 497621a1672SDmitry Torokhov return 0; 498621a1672SDmitry Torokhov 499ecfbf6fdSRafael J. Wysocki err_remove_dev_groups: 500ecfbf6fdSRafael J. Wysocki device_remove_groups(dev, dev->groups); 501621a1672SDmitry Torokhov err_remove_type_groups: 502621a1672SDmitry Torokhov if (type) 503621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 504d05a6f96SGreg Kroah-Hartman err_remove_class_groups: 505d05a6f96SGreg Kroah-Hartman if (class) 506d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 507f9f852dfSKay Sievers 5082620efefSGreg Kroah-Hartman return error; 5092620efefSGreg Kroah-Hartman } 5102620efefSGreg Kroah-Hartman 5112620efefSGreg Kroah-Hartman static void device_remove_attrs(struct device *dev) 5122620efefSGreg Kroah-Hartman { 5132620efefSGreg Kroah-Hartman struct class *class = dev->class; 514aed65af1SStephen Hemminger const struct device_type *type = dev->type; 5152620efefSGreg Kroah-Hartman 516c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_online); 517621a1672SDmitry Torokhov device_remove_groups(dev, dev->groups); 518f9f852dfSKay Sievers 519621a1672SDmitry Torokhov if (type) 520621a1672SDmitry Torokhov device_remove_groups(dev, type->groups); 521621a1672SDmitry Torokhov 522a6b01dedSGreg Kroah-Hartman if (class) 523d05a6f96SGreg Kroah-Hartman device_remove_groups(dev, class->dev_groups); 524c97415a7SStefan Achatz } 5252620efefSGreg Kroah-Hartman 526c5e064a6SGreg Kroah-Hartman static ssize_t dev_show(struct device *dev, struct device_attribute *attr, 52723681e47SGreg Kroah-Hartman char *buf) 52823681e47SGreg Kroah-Hartman { 52923681e47SGreg Kroah-Hartman return print_dev_t(buf, dev->devt); 53023681e47SGreg Kroah-Hartman } 531c5e064a6SGreg Kroah-Hartman static DEVICE_ATTR_RO(dev); 532ad6a1e1cSTejun Heo 533ca22e56dSKay Sievers /* /sys/devices/ */ 534881c6cfdSGreg Kroah-Hartman struct kset *devices_kset; 5351da177e4SLinus Torvalds 5361da177e4SLinus Torvalds /** 5371da177e4SLinus Torvalds * device_create_file - create sysfs attribute file for device. 5381da177e4SLinus Torvalds * @dev: device. 5391da177e4SLinus Torvalds * @attr: device attribute descriptor. 5401da177e4SLinus Torvalds */ 54126579ab7SPhil Carmody int device_create_file(struct device *dev, 54226579ab7SPhil Carmody const struct device_attribute *attr) 5431da177e4SLinus Torvalds { 5441da177e4SLinus Torvalds int error = 0; 5458f46baaaSFelipe Balbi 5468f46baaaSFelipe Balbi if (dev) { 5478f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IWUGO) && !attr->store), 54897521978Sdyoung@redhat.com "Attribute %s: write permission without 'store'\n", 54997521978Sdyoung@redhat.com attr->attr.name); 5508f46baaaSFelipe Balbi WARN(((attr->attr.mode & S_IRUGO) && !attr->show), 55197521978Sdyoung@redhat.com "Attribute %s: read permission without 'show'\n", 55297521978Sdyoung@redhat.com attr->attr.name); 5531da177e4SLinus Torvalds error = sysfs_create_file(&dev->kobj, &attr->attr); 5548f46baaaSFelipe Balbi } 5558f46baaaSFelipe Balbi 5561da177e4SLinus Torvalds return error; 5571da177e4SLinus Torvalds } 55886df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_create_file); 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds /** 5611da177e4SLinus Torvalds * device_remove_file - remove sysfs attribute file. 5621da177e4SLinus Torvalds * @dev: device. 5631da177e4SLinus Torvalds * @attr: device attribute descriptor. 5641da177e4SLinus Torvalds */ 56526579ab7SPhil Carmody void device_remove_file(struct device *dev, 56626579ab7SPhil Carmody const struct device_attribute *attr) 5671da177e4SLinus Torvalds { 5680c98b19fSCornelia Huck if (dev) 5691da177e4SLinus Torvalds sysfs_remove_file(&dev->kobj, &attr->attr); 5701da177e4SLinus Torvalds } 57186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_remove_file); 5721da177e4SLinus Torvalds 5732589f188SGreg Kroah-Hartman /** 5746b0afc2aSTejun Heo * device_remove_file_self - remove sysfs attribute file from its own method. 5756b0afc2aSTejun Heo * @dev: device. 5766b0afc2aSTejun Heo * @attr: device attribute descriptor. 5776b0afc2aSTejun Heo * 5786b0afc2aSTejun Heo * See kernfs_remove_self() for details. 5796b0afc2aSTejun Heo */ 5806b0afc2aSTejun Heo bool device_remove_file_self(struct device *dev, 5816b0afc2aSTejun Heo const struct device_attribute *attr) 5826b0afc2aSTejun Heo { 5836b0afc2aSTejun Heo if (dev) 5846b0afc2aSTejun Heo return sysfs_remove_file_self(&dev->kobj, &attr->attr); 5856b0afc2aSTejun Heo else 5866b0afc2aSTejun Heo return false; 5876b0afc2aSTejun Heo } 5886b0afc2aSTejun Heo EXPORT_SYMBOL_GPL(device_remove_file_self); 5896b0afc2aSTejun Heo 5906b0afc2aSTejun Heo /** 5912589f188SGreg Kroah-Hartman * device_create_bin_file - create sysfs binary attribute file for device. 5922589f188SGreg Kroah-Hartman * @dev: device. 5932589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 5942589f188SGreg Kroah-Hartman */ 59566ecb92bSPhil Carmody int device_create_bin_file(struct device *dev, 59666ecb92bSPhil Carmody const struct bin_attribute *attr) 5972589f188SGreg Kroah-Hartman { 5982589f188SGreg Kroah-Hartman int error = -EINVAL; 5992589f188SGreg Kroah-Hartman if (dev) 6002589f188SGreg Kroah-Hartman error = sysfs_create_bin_file(&dev->kobj, attr); 6012589f188SGreg Kroah-Hartman return error; 6022589f188SGreg Kroah-Hartman } 6032589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_bin_file); 6042589f188SGreg Kroah-Hartman 6052589f188SGreg Kroah-Hartman /** 6062589f188SGreg Kroah-Hartman * device_remove_bin_file - remove sysfs binary attribute file 6072589f188SGreg Kroah-Hartman * @dev: device. 6082589f188SGreg Kroah-Hartman * @attr: device binary attribute descriptor. 6092589f188SGreg Kroah-Hartman */ 61066ecb92bSPhil Carmody void device_remove_bin_file(struct device *dev, 61166ecb92bSPhil Carmody const struct bin_attribute *attr) 6122589f188SGreg Kroah-Hartman { 6132589f188SGreg Kroah-Hartman if (dev) 6142589f188SGreg Kroah-Hartman sysfs_remove_bin_file(&dev->kobj, attr); 6152589f188SGreg Kroah-Hartman } 6162589f188SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_remove_bin_file); 6172589f188SGreg Kroah-Hartman 61834bb61f9SJames Bottomley static void klist_children_get(struct klist_node *n) 61934bb61f9SJames Bottomley { 620f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 621f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 62234bb61f9SJames Bottomley 62334bb61f9SJames Bottomley get_device(dev); 62434bb61f9SJames Bottomley } 62534bb61f9SJames Bottomley 62634bb61f9SJames Bottomley static void klist_children_put(struct klist_node *n) 62734bb61f9SJames Bottomley { 628f791b8c8SGreg Kroah-Hartman struct device_private *p = to_device_private_parent(n); 629f791b8c8SGreg Kroah-Hartman struct device *dev = p->device; 63034bb61f9SJames Bottomley 63134bb61f9SJames Bottomley put_device(dev); 63234bb61f9SJames Bottomley } 63334bb61f9SJames Bottomley 6341da177e4SLinus Torvalds /** 6351da177e4SLinus Torvalds * device_initialize - init device structure. 6361da177e4SLinus Torvalds * @dev: device. 6371da177e4SLinus Torvalds * 6385739411aSCornelia Huck * This prepares the device for use by other layers by initializing 6395739411aSCornelia Huck * its fields. 6401da177e4SLinus Torvalds * It is the first half of device_register(), if called by 6415739411aSCornelia Huck * that function, though it can also be called separately, so one 6425739411aSCornelia Huck * may use @dev's fields. In particular, get_device()/put_device() 6435739411aSCornelia Huck * may be used for reference counting of @dev after calling this 6445739411aSCornelia Huck * function. 6455739411aSCornelia Huck * 646b10d5efdSAlan Stern * All fields in @dev must be initialized by the caller to 0, except 647b10d5efdSAlan Stern * for those explicitly set to some other value. The simplest 648b10d5efdSAlan Stern * approach is to use kzalloc() to allocate the structure containing 649b10d5efdSAlan Stern * @dev. 650b10d5efdSAlan Stern * 6515739411aSCornelia Huck * NOTE: Use put_device() to give up your reference instead of freeing 6525739411aSCornelia Huck * @dev directly once you have called this function. 6531da177e4SLinus Torvalds */ 6541da177e4SLinus Torvalds void device_initialize(struct device *dev) 6551da177e4SLinus Torvalds { 656881c6cfdSGreg Kroah-Hartman dev->kobj.kset = devices_kset; 657f9cb074bSGreg Kroah-Hartman kobject_init(&dev->kobj, &device_ktype); 6581da177e4SLinus Torvalds INIT_LIST_HEAD(&dev->dma_pools); 6593142788bSThomas Gleixner mutex_init(&dev->mutex); 6601704f47bSPeter Zijlstra lockdep_set_novalidate_class(&dev->mutex); 6619ac7849eSTejun Heo spin_lock_init(&dev->devres_lock); 6629ac7849eSTejun Heo INIT_LIST_HEAD(&dev->devres_head); 6633b98aeafSAlan Stern device_pm_init(dev); 66487348136SChristoph Hellwig set_dev_node(dev, -1); 6651da177e4SLinus Torvalds } 66686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_initialize); 6671da177e4SLinus Torvalds 668d73ce004STejun Heo struct kobject *virtual_device_parent(struct device *dev) 669f0ee61a6SGreg Kroah-Hartman { 670f0ee61a6SGreg Kroah-Hartman static struct kobject *virtual_dir = NULL; 671f0ee61a6SGreg Kroah-Hartman 672f0ee61a6SGreg Kroah-Hartman if (!virtual_dir) 6734ff6abffSGreg Kroah-Hartman virtual_dir = kobject_create_and_add("virtual", 674881c6cfdSGreg Kroah-Hartman &devices_kset->kobj); 675f0ee61a6SGreg Kroah-Hartman 67686406245SKay Sievers return virtual_dir; 677f0ee61a6SGreg Kroah-Hartman } 678f0ee61a6SGreg Kroah-Hartman 679bc451f20SEric W. Biederman struct class_dir { 680bc451f20SEric W. Biederman struct kobject kobj; 681bc451f20SEric W. Biederman struct class *class; 682bc451f20SEric W. Biederman }; 683bc451f20SEric W. Biederman 684bc451f20SEric W. Biederman #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) 685bc451f20SEric W. Biederman 686bc451f20SEric W. Biederman static void class_dir_release(struct kobject *kobj) 687bc451f20SEric W. Biederman { 688bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 689bc451f20SEric W. Biederman kfree(dir); 690bc451f20SEric W. Biederman } 691bc451f20SEric W. Biederman 692bc451f20SEric W. Biederman static const 693bc451f20SEric W. Biederman struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) 694bc451f20SEric W. Biederman { 695bc451f20SEric W. Biederman struct class_dir *dir = to_class_dir(kobj); 696bc451f20SEric W. Biederman return dir->class->ns_type; 697bc451f20SEric W. Biederman } 698bc451f20SEric W. Biederman 699bc451f20SEric W. Biederman static struct kobj_type class_dir_ktype = { 700bc451f20SEric W. Biederman .release = class_dir_release, 701bc451f20SEric W. Biederman .sysfs_ops = &kobj_sysfs_ops, 702bc451f20SEric W. Biederman .child_ns_type = class_dir_child_ns_type 703bc451f20SEric W. Biederman }; 704bc451f20SEric W. Biederman 705bc451f20SEric W. Biederman static struct kobject * 706bc451f20SEric W. Biederman class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) 707bc451f20SEric W. Biederman { 708bc451f20SEric W. Biederman struct class_dir *dir; 709bc451f20SEric W. Biederman int retval; 710bc451f20SEric W. Biederman 711bc451f20SEric W. Biederman dir = kzalloc(sizeof(*dir), GFP_KERNEL); 712bc451f20SEric W. Biederman if (!dir) 713bc451f20SEric W. Biederman return NULL; 714bc451f20SEric W. Biederman 715bc451f20SEric W. Biederman dir->class = class; 716bc451f20SEric W. Biederman kobject_init(&dir->kobj, &class_dir_ktype); 717bc451f20SEric W. Biederman 7186b6e39a6SKay Sievers dir->kobj.kset = &class->p->glue_dirs; 719bc451f20SEric W. Biederman 720bc451f20SEric W. Biederman retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); 721bc451f20SEric W. Biederman if (retval < 0) { 722bc451f20SEric W. Biederman kobject_put(&dir->kobj); 723bc451f20SEric W. Biederman return NULL; 724bc451f20SEric W. Biederman } 725bc451f20SEric W. Biederman return &dir->kobj; 726bc451f20SEric W. Biederman } 727bc451f20SEric W. Biederman 728e4a60d13SYijing Wang static DEFINE_MUTEX(gdp_mutex); 729bc451f20SEric W. Biederman 730c744aeaeSCornelia Huck static struct kobject *get_device_parent(struct device *dev, 731c744aeaeSCornelia Huck struct device *parent) 73240fa5422SGreg Kroah-Hartman { 73386406245SKay Sievers if (dev->class) { 73486406245SKay Sievers struct kobject *kobj = NULL; 73586406245SKay Sievers struct kobject *parent_kobj; 73686406245SKay Sievers struct kobject *k; 73786406245SKay Sievers 738ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 73939aba963SKay Sievers /* block disks show up in /sys/block */ 740e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) { 74139aba963SKay Sievers if (parent && parent->class == &block_class) 74239aba963SKay Sievers return &parent->kobj; 7436b6e39a6SKay Sievers return &block_class.p->subsys.kobj; 74439aba963SKay Sievers } 745ead454feSRandy Dunlap #endif 746e52eec13SAndi Kleen 74786406245SKay Sievers /* 74886406245SKay Sievers * If we have no parent, we live in "virtual". 7490f4dafc0SKay Sievers * Class-devices with a non class-device as parent, live 7500f4dafc0SKay Sievers * in a "glue" directory to prevent namespace collisions. 75186406245SKay Sievers */ 75286406245SKay Sievers if (parent == NULL) 75386406245SKay Sievers parent_kobj = virtual_device_parent(dev); 75424b1442dSEric W. Biederman else if (parent->class && !dev->class->ns_type) 75586406245SKay Sievers return &parent->kobj; 75686406245SKay Sievers else 75786406245SKay Sievers parent_kobj = &parent->kobj; 75886406245SKay Sievers 75977d3d7c1STejun Heo mutex_lock(&gdp_mutex); 76077d3d7c1STejun Heo 76186406245SKay Sievers /* find our class-directory at the parent and reference it */ 7626b6e39a6SKay Sievers spin_lock(&dev->class->p->glue_dirs.list_lock); 7636b6e39a6SKay Sievers list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) 76486406245SKay Sievers if (k->parent == parent_kobj) { 76586406245SKay Sievers kobj = kobject_get(k); 76686406245SKay Sievers break; 76786406245SKay Sievers } 7686b6e39a6SKay Sievers spin_unlock(&dev->class->p->glue_dirs.list_lock); 76977d3d7c1STejun Heo if (kobj) { 77077d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 77186406245SKay Sievers return kobj; 77277d3d7c1STejun Heo } 77386406245SKay Sievers 77486406245SKay Sievers /* or create a new class-directory at the parent device */ 775bc451f20SEric W. Biederman k = class_dir_create_and_add(dev->class, parent_kobj); 7760f4dafc0SKay Sievers /* do not emit an uevent for this simple "glue" directory */ 77777d3d7c1STejun Heo mutex_unlock(&gdp_mutex); 77843968d2fSGreg Kroah-Hartman return k; 77986406245SKay Sievers } 78086406245SKay Sievers 781ca22e56dSKay Sievers /* subsystems can specify a default root directory for their devices */ 782ca22e56dSKay Sievers if (!parent && dev->bus && dev->bus->dev_root) 783ca22e56dSKay Sievers return &dev->bus->dev_root->kobj; 784ca22e56dSKay Sievers 78586406245SKay Sievers if (parent) 786c744aeaeSCornelia Huck return &parent->kobj; 787c744aeaeSCornelia Huck return NULL; 788c744aeaeSCornelia Huck } 789da231fd5SKay Sievers 79063b6971aSCornelia Huck static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 791da231fd5SKay Sievers { 7920f4dafc0SKay Sievers /* see if we live in a "glue" directory */ 793c1fe539aSCornelia Huck if (!glue_dir || !dev->class || 7946b6e39a6SKay Sievers glue_dir->kset != &dev->class->p->glue_dirs) 795da231fd5SKay Sievers return; 796da231fd5SKay Sievers 797e4a60d13SYijing Wang mutex_lock(&gdp_mutex); 7980f4dafc0SKay Sievers kobject_put(glue_dir); 799e4a60d13SYijing Wang mutex_unlock(&gdp_mutex); 800da231fd5SKay Sievers } 80163b6971aSCornelia Huck 80263b6971aSCornelia Huck static void cleanup_device_parent(struct device *dev) 80363b6971aSCornelia Huck { 80463b6971aSCornelia Huck cleanup_glue_dir(dev, dev->kobj.parent); 80563b6971aSCornelia Huck } 80686406245SKay Sievers 8072ee97cafSCornelia Huck static int device_add_class_symlinks(struct device *dev) 8082ee97cafSCornelia Huck { 8092ee97cafSCornelia Huck int error; 8102ee97cafSCornelia Huck 8112ee97cafSCornelia Huck if (!dev->class) 8122ee97cafSCornelia Huck return 0; 813da231fd5SKay Sievers 8141fbfee6cSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, 8156b6e39a6SKay Sievers &dev->class->p->subsys.kobj, 8162ee97cafSCornelia Huck "subsystem"); 8172ee97cafSCornelia Huck if (error) 8182ee97cafSCornelia Huck goto out; 819da231fd5SKay Sievers 8204e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) { 8214f01a757SDmitry Torokhov error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 8224f01a757SDmitry Torokhov "device"); 8234f01a757SDmitry Torokhov if (error) 82439aba963SKay Sievers goto out_subsys; 8252ee97cafSCornelia Huck } 82639aba963SKay Sievers 827ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 82839aba963SKay Sievers /* /sys/block has directories and does not need symlinks */ 829e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 83039aba963SKay Sievers return 0; 831ead454feSRandy Dunlap #endif 83239aba963SKay Sievers 83339aba963SKay Sievers /* link in the class directory pointing to the device */ 8346b6e39a6SKay Sievers error = sysfs_create_link(&dev->class->p->subsys.kobj, 83539aba963SKay Sievers &dev->kobj, dev_name(dev)); 83639aba963SKay Sievers if (error) 83739aba963SKay Sievers goto out_device; 83839aba963SKay Sievers 8392ee97cafSCornelia Huck return 0; 8402ee97cafSCornelia Huck 84139aba963SKay Sievers out_device: 84239aba963SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 843da231fd5SKay Sievers 8442ee97cafSCornelia Huck out_subsys: 8452ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 8462ee97cafSCornelia Huck out: 8472ee97cafSCornelia Huck return error; 8482ee97cafSCornelia Huck } 8492ee97cafSCornelia Huck 8502ee97cafSCornelia Huck static void device_remove_class_symlinks(struct device *dev) 8512ee97cafSCornelia Huck { 8522ee97cafSCornelia Huck if (!dev->class) 8532ee97cafSCornelia Huck return; 854da231fd5SKay Sievers 8554e886c29SGreg Kroah-Hartman if (dev->parent && device_is_not_partition(dev)) 856da231fd5SKay Sievers sysfs_remove_link(&dev->kobj, "device"); 8572ee97cafSCornelia Huck sysfs_remove_link(&dev->kobj, "subsystem"); 858ead454feSRandy Dunlap #ifdef CONFIG_BLOCK 859e52eec13SAndi Kleen if (sysfs_deprecated && dev->class == &block_class) 86039aba963SKay Sievers return; 861ead454feSRandy Dunlap #endif 8626b6e39a6SKay Sievers sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); 8632ee97cafSCornelia Huck } 8642ee97cafSCornelia Huck 8651da177e4SLinus Torvalds /** 866413c239fSStephen Rothwell * dev_set_name - set a device name 867413c239fSStephen Rothwell * @dev: device 86846232366SRandy Dunlap * @fmt: format string for the device's name 869413c239fSStephen Rothwell */ 870413c239fSStephen Rothwell int dev_set_name(struct device *dev, const char *fmt, ...) 871413c239fSStephen Rothwell { 872413c239fSStephen Rothwell va_list vargs; 8731fa5ae85SKay Sievers int err; 874413c239fSStephen Rothwell 875413c239fSStephen Rothwell va_start(vargs, fmt); 8761fa5ae85SKay Sievers err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); 877413c239fSStephen Rothwell va_end(vargs); 8781fa5ae85SKay Sievers return err; 879413c239fSStephen Rothwell } 880413c239fSStephen Rothwell EXPORT_SYMBOL_GPL(dev_set_name); 881413c239fSStephen Rothwell 882413c239fSStephen Rothwell /** 883e105b8bfSDan Williams * device_to_dev_kobj - select a /sys/dev/ directory for the device 884e105b8bfSDan Williams * @dev: device 885e105b8bfSDan Williams * 886e105b8bfSDan Williams * By default we select char/ for new entries. Setting class->dev_obj 887e105b8bfSDan Williams * to NULL prevents an entry from being created. class->dev_kobj must 888e105b8bfSDan Williams * be set (or cleared) before any devices are registered to the class 889e105b8bfSDan Williams * otherwise device_create_sys_dev_entry() and 8900d4e293cSPeter Korsgaard * device_remove_sys_dev_entry() will disagree about the presence of 8910d4e293cSPeter Korsgaard * the link. 892e105b8bfSDan Williams */ 893e105b8bfSDan Williams static struct kobject *device_to_dev_kobj(struct device *dev) 894e105b8bfSDan Williams { 895e105b8bfSDan Williams struct kobject *kobj; 896e105b8bfSDan Williams 897e105b8bfSDan Williams if (dev->class) 898e105b8bfSDan Williams kobj = dev->class->dev_kobj; 899e105b8bfSDan Williams else 900e105b8bfSDan Williams kobj = sysfs_dev_char_kobj; 901e105b8bfSDan Williams 902e105b8bfSDan Williams return kobj; 903e105b8bfSDan Williams } 904e105b8bfSDan Williams 905e105b8bfSDan Williams static int device_create_sys_dev_entry(struct device *dev) 906e105b8bfSDan Williams { 907e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 908e105b8bfSDan Williams int error = 0; 909e105b8bfSDan Williams char devt_str[15]; 910e105b8bfSDan Williams 911e105b8bfSDan Williams if (kobj) { 912e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 913e105b8bfSDan Williams error = sysfs_create_link(kobj, &dev->kobj, devt_str); 914e105b8bfSDan Williams } 915e105b8bfSDan Williams 916e105b8bfSDan Williams return error; 917e105b8bfSDan Williams } 918e105b8bfSDan Williams 919e105b8bfSDan Williams static void device_remove_sys_dev_entry(struct device *dev) 920e105b8bfSDan Williams { 921e105b8bfSDan Williams struct kobject *kobj = device_to_dev_kobj(dev); 922e105b8bfSDan Williams char devt_str[15]; 923e105b8bfSDan Williams 924e105b8bfSDan Williams if (kobj) { 925e105b8bfSDan Williams format_dev_t(devt_str, dev->devt); 926e105b8bfSDan Williams sysfs_remove_link(kobj, devt_str); 927e105b8bfSDan Williams } 928e105b8bfSDan Williams } 929e105b8bfSDan Williams 930b4028437SGreg Kroah-Hartman int device_private_init(struct device *dev) 931b4028437SGreg Kroah-Hartman { 932b4028437SGreg Kroah-Hartman dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); 933b4028437SGreg Kroah-Hartman if (!dev->p) 934b4028437SGreg Kroah-Hartman return -ENOMEM; 935b4028437SGreg Kroah-Hartman dev->p->device = dev; 936b4028437SGreg Kroah-Hartman klist_init(&dev->p->klist_children, klist_children_get, 937b4028437SGreg Kroah-Hartman klist_children_put); 938ef8a3fd6SGreg Kroah-Hartman INIT_LIST_HEAD(&dev->p->deferred_probe); 939b4028437SGreg Kroah-Hartman return 0; 940b4028437SGreg Kroah-Hartman } 941b4028437SGreg Kroah-Hartman 942e105b8bfSDan Williams /** 9431da177e4SLinus Torvalds * device_add - add device to device hierarchy. 9441da177e4SLinus Torvalds * @dev: device. 9451da177e4SLinus Torvalds * 9461da177e4SLinus Torvalds * This is part 2 of device_register(), though may be called 9471da177e4SLinus Torvalds * separately _iff_ device_initialize() has been called separately. 9481da177e4SLinus Torvalds * 9495739411aSCornelia Huck * This adds @dev to the kobject hierarchy via kobject_add(), adds it 9501da177e4SLinus Torvalds * to the global and sibling lists for the device, then 9511da177e4SLinus Torvalds * adds it to the other relevant subsystems of the driver model. 9525739411aSCornelia Huck * 953b10d5efdSAlan Stern * Do not call this routine or device_register() more than once for 954b10d5efdSAlan Stern * any device structure. The driver model core is not designed to work 955b10d5efdSAlan Stern * with devices that get unregistered and then spring back to life. 956b10d5efdSAlan Stern * (Among other things, it's very hard to guarantee that all references 957b10d5efdSAlan Stern * to the previous incarnation of @dev have been dropped.) Allocate 958b10d5efdSAlan Stern * and register a fresh new struct device instead. 959b10d5efdSAlan Stern * 9605739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 9615739411aSCornelia Huck * if it returned an error! Always use put_device() to give up your 9625739411aSCornelia Huck * reference instead. 9631da177e4SLinus Torvalds */ 9641da177e4SLinus Torvalds int device_add(struct device *dev) 9651da177e4SLinus Torvalds { 9661da177e4SLinus Torvalds struct device *parent = NULL; 967ca22e56dSKay Sievers struct kobject *kobj; 968c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 969c906a48aSGreg Kroah-Hartman int error = -EINVAL; 970775b64d2SRafael J. Wysocki 9711da177e4SLinus Torvalds dev = get_device(dev); 972c906a48aSGreg Kroah-Hartman if (!dev) 973c906a48aSGreg Kroah-Hartman goto done; 974c906a48aSGreg Kroah-Hartman 975fb069a5dSGreg Kroah-Hartman if (!dev->p) { 976b4028437SGreg Kroah-Hartman error = device_private_init(dev); 977b4028437SGreg Kroah-Hartman if (error) 978fb069a5dSGreg Kroah-Hartman goto done; 979fb069a5dSGreg Kroah-Hartman } 980fb069a5dSGreg Kroah-Hartman 9811fa5ae85SKay Sievers /* 9821fa5ae85SKay Sievers * for statically allocated devices, which should all be converted 9831fa5ae85SKay Sievers * some day, we need to initialize the name. We prevent reading back 9841fa5ae85SKay Sievers * the name, and force the use of dev_name() 9851fa5ae85SKay Sievers */ 9861fa5ae85SKay Sievers if (dev->init_name) { 987acc0e90fSGreg Kroah-Hartman dev_set_name(dev, "%s", dev->init_name); 9881fa5ae85SKay Sievers dev->init_name = NULL; 9891fa5ae85SKay Sievers } 990c906a48aSGreg Kroah-Hartman 991ca22e56dSKay Sievers /* subsystems can specify simple device enumeration */ 992ca22e56dSKay Sievers if (!dev_name(dev) && dev->bus && dev->bus->dev_name) 993ca22e56dSKay Sievers dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); 994ca22e56dSKay Sievers 995e6309e75SThomas Gleixner if (!dev_name(dev)) { 996e6309e75SThomas Gleixner error = -EINVAL; 9975c8563d7SKay Sievers goto name_error; 998e6309e75SThomas Gleixner } 9991da177e4SLinus Torvalds 10001e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 1001c205ef48SGreg Kroah-Hartman 10021da177e4SLinus Torvalds parent = get_device(dev->parent); 1003ca22e56dSKay Sievers kobj = get_device_parent(dev, parent); 1004ca22e56dSKay Sievers if (kobj) 1005ca22e56dSKay Sievers dev->kobj.parent = kobj; 10061da177e4SLinus Torvalds 10070d358f22SYinghai Lu /* use parent numa_node */ 10080d358f22SYinghai Lu if (parent) 10090d358f22SYinghai Lu set_dev_node(dev, dev_to_node(parent)); 10100d358f22SYinghai Lu 10111da177e4SLinus Torvalds /* first, register with generic layer. */ 10128a577ffcSKay Sievers /* we require the name to be set before, and pass NULL */ 10138a577ffcSKay Sievers error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 101440fa5422SGreg Kroah-Hartman if (error) 10151da177e4SLinus Torvalds goto Error; 1016a7fd6706SKay Sievers 101737022644SBrian Walsh /* notify platform of device entry */ 101837022644SBrian Walsh if (platform_notify) 101937022644SBrian Walsh platform_notify(dev); 102037022644SBrian Walsh 1021c5e064a6SGreg Kroah-Hartman error = device_create_file(dev, &dev_attr_uevent); 1022a306eea4SCornelia Huck if (error) 1023a306eea4SCornelia Huck goto attrError; 1024a7fd6706SKay Sievers 10252ee97cafSCornelia Huck error = device_add_class_symlinks(dev); 10262ee97cafSCornelia Huck if (error) 10272ee97cafSCornelia Huck goto SymlinkError; 1028dc0afa83SCornelia Huck error = device_add_attrs(dev); 1029dc0afa83SCornelia Huck if (error) 10302620efefSGreg Kroah-Hartman goto AttrsError; 1031dc0afa83SCornelia Huck error = bus_add_device(dev); 1032dc0afa83SCornelia Huck if (error) 10331da177e4SLinus Torvalds goto BusError; 10343b98aeafSAlan Stern error = dpm_sysfs_add(dev); 103557eee3d2SRafael J. Wysocki if (error) 10363b98aeafSAlan Stern goto DPMError; 10373b98aeafSAlan Stern device_pm_add(dev); 1038ec0676eeSAlan Stern 10390cd75047SSergey Klyaus if (MAJOR(dev->devt)) { 10400cd75047SSergey Klyaus error = device_create_file(dev, &dev_attr_dev); 10410cd75047SSergey Klyaus if (error) 10420cd75047SSergey Klyaus goto DevAttrError; 10430cd75047SSergey Klyaus 10440cd75047SSergey Klyaus error = device_create_sys_dev_entry(dev); 10450cd75047SSergey Klyaus if (error) 10460cd75047SSergey Klyaus goto SysEntryError; 10470cd75047SSergey Klyaus 10480cd75047SSergey Klyaus devtmpfs_create_node(dev); 10490cd75047SSergey Klyaus } 10500cd75047SSergey Klyaus 1051ec0676eeSAlan Stern /* Notify clients of device addition. This call must come 1052268863f4Smajianpeng * after dpm_sysfs_add() and before kobject_uevent(). 1053ec0676eeSAlan Stern */ 1054ec0676eeSAlan Stern if (dev->bus) 1055ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1056ec0676eeSAlan Stern BUS_NOTIFY_ADD_DEVICE, dev); 1057ec0676eeSAlan Stern 105853877d06SKay Sievers kobject_uevent(&dev->kobj, KOBJ_ADD); 10592023c610SAlan Stern bus_probe_device(dev); 10601da177e4SLinus Torvalds if (parent) 1061f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1062f791b8c8SGreg Kroah-Hartman &parent->p->klist_children); 10631da177e4SLinus Torvalds 10645d9fd169SGreg Kroah-Hartman if (dev->class) { 1065ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1066c47ed219SGreg Kroah-Hartman /* tie the class to the device */ 10675a3ceb86STejun Heo klist_add_tail(&dev->knode_class, 10686b6e39a6SKay Sievers &dev->class->p->klist_devices); 1069c47ed219SGreg Kroah-Hartman 1070c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is here */ 1071184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1072ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1073c47ed219SGreg Kroah-Hartman if (class_intf->add_dev) 1074c47ed219SGreg Kroah-Hartman class_intf->add_dev(dev, class_intf); 1075ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 10765d9fd169SGreg Kroah-Hartman } 1077c906a48aSGreg Kroah-Hartman done: 10781da177e4SLinus Torvalds put_device(dev); 10791da177e4SLinus Torvalds return error; 10800cd75047SSergey Klyaus SysEntryError: 10810cd75047SSergey Klyaus if (MAJOR(dev->devt)) 10820cd75047SSergey Klyaus device_remove_file(dev, &dev_attr_dev); 10830cd75047SSergey Klyaus DevAttrError: 10840cd75047SSergey Klyaus device_pm_remove(dev); 10850cd75047SSergey Klyaus dpm_sysfs_remove(dev); 10863b98aeafSAlan Stern DPMError: 108757eee3d2SRafael J. Wysocki bus_remove_device(dev); 108857eee3d2SRafael J. Wysocki BusError: 10892620efefSGreg Kroah-Hartman device_remove_attrs(dev); 10902620efefSGreg Kroah-Hartman AttrsError: 10912ee97cafSCornelia Huck device_remove_class_symlinks(dev); 10922ee97cafSCornelia Huck SymlinkError: 1093c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 109423681e47SGreg Kroah-Hartman attrError: 1095312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 10961da177e4SLinus Torvalds kobject_del(&dev->kobj); 10971da177e4SLinus Torvalds Error: 109863b6971aSCornelia Huck cleanup_device_parent(dev); 10991da177e4SLinus Torvalds if (parent) 11001da177e4SLinus Torvalds put_device(parent); 11015c8563d7SKay Sievers name_error: 11025c8563d7SKay Sievers kfree(dev->p); 11035c8563d7SKay Sievers dev->p = NULL; 1104c906a48aSGreg Kroah-Hartman goto done; 11051da177e4SLinus Torvalds } 110686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_add); 11071da177e4SLinus Torvalds 11081da177e4SLinus Torvalds /** 11091da177e4SLinus Torvalds * device_register - register a device with the system. 11101da177e4SLinus Torvalds * @dev: pointer to the device structure 11111da177e4SLinus Torvalds * 11121da177e4SLinus Torvalds * This happens in two clean steps - initialize the device 11131da177e4SLinus Torvalds * and add it to the system. The two steps can be called 11141da177e4SLinus Torvalds * separately, but this is the easiest and most common. 11151da177e4SLinus Torvalds * I.e. you should only call the two helpers separately if 11161da177e4SLinus Torvalds * have a clearly defined need to use and refcount the device 11171da177e4SLinus Torvalds * before it is added to the hierarchy. 11185739411aSCornelia Huck * 1119b10d5efdSAlan Stern * For more information, see the kerneldoc for device_initialize() 1120b10d5efdSAlan Stern * and device_add(). 1121b10d5efdSAlan Stern * 11225739411aSCornelia Huck * NOTE: _Never_ directly free @dev after calling this function, even 11235739411aSCornelia Huck * if it returned an error! Always use put_device() to give up the 11245739411aSCornelia Huck * reference initialized in this function instead. 11251da177e4SLinus Torvalds */ 11261da177e4SLinus Torvalds int device_register(struct device *dev) 11271da177e4SLinus Torvalds { 11281da177e4SLinus Torvalds device_initialize(dev); 11291da177e4SLinus Torvalds return device_add(dev); 11301da177e4SLinus Torvalds } 113186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_register); 11321da177e4SLinus Torvalds 11331da177e4SLinus Torvalds /** 11341da177e4SLinus Torvalds * get_device - increment reference count for device. 11351da177e4SLinus Torvalds * @dev: device. 11361da177e4SLinus Torvalds * 11371da177e4SLinus Torvalds * This simply forwards the call to kobject_get(), though 11381da177e4SLinus Torvalds * we do take care to provide for the case that we get a NULL 11391da177e4SLinus Torvalds * pointer passed in. 11401da177e4SLinus Torvalds */ 11411da177e4SLinus Torvalds struct device *get_device(struct device *dev) 11421da177e4SLinus Torvalds { 1143b0d1f807SLars-Peter Clausen return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; 11441da177e4SLinus Torvalds } 114586df2687SDavid Graham White EXPORT_SYMBOL_GPL(get_device); 11461da177e4SLinus Torvalds 11471da177e4SLinus Torvalds /** 11481da177e4SLinus Torvalds * put_device - decrement reference count. 11491da177e4SLinus Torvalds * @dev: device in question. 11501da177e4SLinus Torvalds */ 11511da177e4SLinus Torvalds void put_device(struct device *dev) 11521da177e4SLinus Torvalds { 1153edfaa7c3SKay Sievers /* might_sleep(); */ 11541da177e4SLinus Torvalds if (dev) 11551da177e4SLinus Torvalds kobject_put(&dev->kobj); 11561da177e4SLinus Torvalds } 115786df2687SDavid Graham White EXPORT_SYMBOL_GPL(put_device); 11581da177e4SLinus Torvalds 11591da177e4SLinus Torvalds /** 11601da177e4SLinus Torvalds * device_del - delete device from system. 11611da177e4SLinus Torvalds * @dev: device. 11621da177e4SLinus Torvalds * 11631da177e4SLinus Torvalds * This is the first part of the device unregistration 11641da177e4SLinus Torvalds * sequence. This removes the device from the lists we control 11651da177e4SLinus Torvalds * from here, has it removed from the other driver model 11661da177e4SLinus Torvalds * subsystems it was added to in device_add(), and removes it 11671da177e4SLinus Torvalds * from the kobject hierarchy. 11681da177e4SLinus Torvalds * 11691da177e4SLinus Torvalds * NOTE: this should be called manually _iff_ device_add() was 11701da177e4SLinus Torvalds * also called manually. 11711da177e4SLinus Torvalds */ 11721da177e4SLinus Torvalds void device_del(struct device *dev) 11731da177e4SLinus Torvalds { 11741da177e4SLinus Torvalds struct device *parent = dev->parent; 1175c47ed219SGreg Kroah-Hartman struct class_interface *class_intf; 11761da177e4SLinus Torvalds 1177ec0676eeSAlan Stern /* Notify clients of device removal. This call must come 1178ec0676eeSAlan Stern * before dpm_sysfs_remove(). 1179ec0676eeSAlan Stern */ 1180ec0676eeSAlan Stern if (dev->bus) 1181ec0676eeSAlan Stern blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1182ec0676eeSAlan Stern BUS_NOTIFY_DEL_DEVICE, dev); 11833b98aeafSAlan Stern dpm_sysfs_remove(dev); 11841da177e4SLinus Torvalds if (parent) 1185f791b8c8SGreg Kroah-Hartman klist_del(&dev->p->knode_parent); 1186e105b8bfSDan Williams if (MAJOR(dev->devt)) { 11872b2af54aSKay Sievers devtmpfs_delete_node(dev); 1188e105b8bfSDan Williams device_remove_sys_dev_entry(dev); 1189c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_dev); 1190e105b8bfSDan Williams } 1191b9d9c82bSKay Sievers if (dev->class) { 1192da231fd5SKay Sievers device_remove_class_symlinks(dev); 119399ef3ef8SKay Sievers 1194ca22e56dSKay Sievers mutex_lock(&dev->class->p->mutex); 1195c47ed219SGreg Kroah-Hartman /* notify any interfaces that the device is now gone */ 1196184f1f77SGreg Kroah-Hartman list_for_each_entry(class_intf, 1197ca22e56dSKay Sievers &dev->class->p->interfaces, node) 1198c47ed219SGreg Kroah-Hartman if (class_intf->remove_dev) 1199c47ed219SGreg Kroah-Hartman class_intf->remove_dev(dev, class_intf); 1200c47ed219SGreg Kroah-Hartman /* remove the device from the class list */ 12015a3ceb86STejun Heo klist_del(&dev->knode_class); 1202ca22e56dSKay Sievers mutex_unlock(&dev->class->p->mutex); 1203b9d9c82bSKay Sievers } 1204c5e064a6SGreg Kroah-Hartman device_remove_file(dev, &dev_attr_uevent); 12052620efefSGreg Kroah-Hartman device_remove_attrs(dev); 120628953533SBenjamin Herrenschmidt bus_remove_device(dev); 12074b6d1f12SLongX Zhang device_pm_remove(dev); 1208d1c3414cSGrant Likely driver_deferred_probe_del(dev); 12091da177e4SLinus Torvalds 12101da177e4SLinus Torvalds /* Notify the platform of the removal, in case they 12111da177e4SLinus Torvalds * need to do anything... 12121da177e4SLinus Torvalds */ 12131da177e4SLinus Torvalds if (platform_notify_remove) 12141da177e4SLinus Torvalds platform_notify_remove(dev); 1215599bad38SJoerg Roedel if (dev->bus) 1216599bad38SJoerg Roedel blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1217599bad38SJoerg Roedel BUS_NOTIFY_REMOVED_DEVICE, dev); 1218312c004dSKay Sievers kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1219da231fd5SKay Sievers cleanup_device_parent(dev); 12201da177e4SLinus Torvalds kobject_del(&dev->kobj); 12211da177e4SLinus Torvalds put_device(parent); 12221da177e4SLinus Torvalds } 122386df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_del); 12241da177e4SLinus Torvalds 12251da177e4SLinus Torvalds /** 12261da177e4SLinus Torvalds * device_unregister - unregister device from system. 12271da177e4SLinus Torvalds * @dev: device going away. 12281da177e4SLinus Torvalds * 12291da177e4SLinus Torvalds * We do this in two parts, like we do device_register(). First, 12301da177e4SLinus Torvalds * we remove it from all the subsystems with device_del(), then 12311da177e4SLinus Torvalds * we decrement the reference count via put_device(). If that 12321da177e4SLinus Torvalds * is the final reference count, the device will be cleaned up 12331da177e4SLinus Torvalds * via device_release() above. Otherwise, the structure will 12341da177e4SLinus Torvalds * stick around until the final reference to the device is dropped. 12351da177e4SLinus Torvalds */ 12361da177e4SLinus Torvalds void device_unregister(struct device *dev) 12371da177e4SLinus Torvalds { 12381e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 12391da177e4SLinus Torvalds device_del(dev); 12401da177e4SLinus Torvalds put_device(dev); 12411da177e4SLinus Torvalds } 124286df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_unregister); 12431da177e4SLinus Torvalds 124436239577Smochel@digitalimplant.org static struct device *next_device(struct klist_iter *i) 124536239577Smochel@digitalimplant.org { 124636239577Smochel@digitalimplant.org struct klist_node *n = klist_next(i); 1247f791b8c8SGreg Kroah-Hartman struct device *dev = NULL; 1248f791b8c8SGreg Kroah-Hartman struct device_private *p; 1249f791b8c8SGreg Kroah-Hartman 1250f791b8c8SGreg Kroah-Hartman if (n) { 1251f791b8c8SGreg Kroah-Hartman p = to_device_private_parent(n); 1252f791b8c8SGreg Kroah-Hartman dev = p->device; 1253f791b8c8SGreg Kroah-Hartman } 1254f791b8c8SGreg Kroah-Hartman return dev; 125536239577Smochel@digitalimplant.org } 125636239577Smochel@digitalimplant.org 12571da177e4SLinus Torvalds /** 1258e454cea2SKay Sievers * device_get_devnode - path of device node file 12596fcf53acSKay Sievers * @dev: device 1260e454cea2SKay Sievers * @mode: returned file access mode 12613c2670e6SKay Sievers * @uid: returned file owner 12623c2670e6SKay Sievers * @gid: returned file group 12636fcf53acSKay Sievers * @tmp: possibly allocated string 12646fcf53acSKay Sievers * 12656fcf53acSKay Sievers * Return the relative path of a possible device node. 12666fcf53acSKay Sievers * Non-default names may need to allocate a memory to compose 12676fcf53acSKay Sievers * a name. This memory is returned in tmp and needs to be 12686fcf53acSKay Sievers * freed by the caller. 12696fcf53acSKay Sievers */ 1270e454cea2SKay Sievers const char *device_get_devnode(struct device *dev, 12714e4098a3SGreg Kroah-Hartman umode_t *mode, kuid_t *uid, kgid_t *gid, 12723c2670e6SKay Sievers const char **tmp) 12736fcf53acSKay Sievers { 12746fcf53acSKay Sievers char *s; 12756fcf53acSKay Sievers 12766fcf53acSKay Sievers *tmp = NULL; 12776fcf53acSKay Sievers 12786fcf53acSKay Sievers /* the device type may provide a specific name */ 1279e454cea2SKay Sievers if (dev->type && dev->type->devnode) 12803c2670e6SKay Sievers *tmp = dev->type->devnode(dev, mode, uid, gid); 12816fcf53acSKay Sievers if (*tmp) 12826fcf53acSKay Sievers return *tmp; 12836fcf53acSKay Sievers 12846fcf53acSKay Sievers /* the class may provide a specific name */ 1285e454cea2SKay Sievers if (dev->class && dev->class->devnode) 1286e454cea2SKay Sievers *tmp = dev->class->devnode(dev, mode); 12876fcf53acSKay Sievers if (*tmp) 12886fcf53acSKay Sievers return *tmp; 12896fcf53acSKay Sievers 12906fcf53acSKay Sievers /* return name without allocation, tmp == NULL */ 12916fcf53acSKay Sievers if (strchr(dev_name(dev), '!') == NULL) 12926fcf53acSKay Sievers return dev_name(dev); 12936fcf53acSKay Sievers 12946fcf53acSKay Sievers /* replace '!' in the name with '/' */ 12956fcf53acSKay Sievers *tmp = kstrdup(dev_name(dev), GFP_KERNEL); 12966fcf53acSKay Sievers if (!*tmp) 12976fcf53acSKay Sievers return NULL; 12986fcf53acSKay Sievers while ((s = strchr(*tmp, '!'))) 12996fcf53acSKay Sievers s[0] = '/'; 13006fcf53acSKay Sievers return *tmp; 13016fcf53acSKay Sievers } 13026fcf53acSKay Sievers 13036fcf53acSKay Sievers /** 13041da177e4SLinus Torvalds * device_for_each_child - device child iterator. 1305c41455fbSRandy Dunlap * @parent: parent struct device. 13061da177e4SLinus Torvalds * @fn: function to be called for each device. 1307f8878dcbSRobert P. J. Day * @data: data for the callback. 13081da177e4SLinus Torvalds * 1309c41455fbSRandy Dunlap * Iterate over @parent's child devices, and call @fn for each, 13101da177e4SLinus Torvalds * passing it @data. 13111da177e4SLinus Torvalds * 13121da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 13131da177e4SLinus Torvalds * other than 0, we break out and return that value. 13141da177e4SLinus Torvalds */ 131536239577Smochel@digitalimplant.org int device_for_each_child(struct device *parent, void *data, 13164a3ad20cSGreg Kroah-Hartman int (*fn)(struct device *dev, void *data)) 13171da177e4SLinus Torvalds { 131836239577Smochel@digitalimplant.org struct klist_iter i; 13191da177e4SLinus Torvalds struct device *child; 13201da177e4SLinus Torvalds int error = 0; 13211da177e4SLinus Torvalds 1322014c90dbSGreg Kroah-Hartman if (!parent->p) 1323014c90dbSGreg Kroah-Hartman return 0; 1324014c90dbSGreg Kroah-Hartman 1325f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 132636239577Smochel@digitalimplant.org while ((child = next_device(&i)) && !error) 132736239577Smochel@digitalimplant.org error = fn(child, data); 132836239577Smochel@digitalimplant.org klist_iter_exit(&i); 13291da177e4SLinus Torvalds return error; 13301da177e4SLinus Torvalds } 133186df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_for_each_child); 13321da177e4SLinus Torvalds 13335ab69981SCornelia Huck /** 13345ab69981SCornelia Huck * device_find_child - device iterator for locating a particular device. 13355ab69981SCornelia Huck * @parent: parent struct device 13365ab69981SCornelia Huck * @match: Callback function to check device 1337f8878dcbSRobert P. J. Day * @data: Data to pass to match function 13385ab69981SCornelia Huck * 13395ab69981SCornelia Huck * This is similar to the device_for_each_child() function above, but it 13405ab69981SCornelia Huck * returns a reference to a device that is 'found' for later use, as 13415ab69981SCornelia Huck * determined by the @match callback. 13425ab69981SCornelia Huck * 13435ab69981SCornelia Huck * The callback should return 0 if the device doesn't match and non-zero 13445ab69981SCornelia Huck * if it does. If the callback returns non-zero and a reference to the 13455ab69981SCornelia Huck * current device can be obtained, this function will return to the caller 13465ab69981SCornelia Huck * and not iterate over any more devices. 1347a4e2400aSFederico Vaga * 1348a4e2400aSFederico Vaga * NOTE: you will need to drop the reference with put_device() after use. 13495ab69981SCornelia Huck */ 13505ab69981SCornelia Huck struct device *device_find_child(struct device *parent, void *data, 13514a3ad20cSGreg Kroah-Hartman int (*match)(struct device *dev, void *data)) 13525ab69981SCornelia Huck { 13535ab69981SCornelia Huck struct klist_iter i; 13545ab69981SCornelia Huck struct device *child; 13555ab69981SCornelia Huck 13565ab69981SCornelia Huck if (!parent) 13575ab69981SCornelia Huck return NULL; 13585ab69981SCornelia Huck 1359f791b8c8SGreg Kroah-Hartman klist_iter_init(&parent->p->klist_children, &i); 13605ab69981SCornelia Huck while ((child = next_device(&i))) 13615ab69981SCornelia Huck if (match(child, data) && get_device(child)) 13625ab69981SCornelia Huck break; 13635ab69981SCornelia Huck klist_iter_exit(&i); 13645ab69981SCornelia Huck return child; 13655ab69981SCornelia Huck } 136686df2687SDavid Graham White EXPORT_SYMBOL_GPL(device_find_child); 13675ab69981SCornelia Huck 13681da177e4SLinus Torvalds int __init devices_init(void) 13691da177e4SLinus Torvalds { 1370881c6cfdSGreg Kroah-Hartman devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 1371881c6cfdSGreg Kroah-Hartman if (!devices_kset) 1372881c6cfdSGreg Kroah-Hartman return -ENOMEM; 1373e105b8bfSDan Williams dev_kobj = kobject_create_and_add("dev", NULL); 1374e105b8bfSDan Williams if (!dev_kobj) 1375e105b8bfSDan Williams goto dev_kobj_err; 1376e105b8bfSDan Williams sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 1377e105b8bfSDan Williams if (!sysfs_dev_block_kobj) 1378e105b8bfSDan Williams goto block_kobj_err; 1379e105b8bfSDan Williams sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 1380e105b8bfSDan Williams if (!sysfs_dev_char_kobj) 1381e105b8bfSDan Williams goto char_kobj_err; 1382e105b8bfSDan Williams 1383881c6cfdSGreg Kroah-Hartman return 0; 1384e105b8bfSDan Williams 1385e105b8bfSDan Williams char_kobj_err: 1386e105b8bfSDan Williams kobject_put(sysfs_dev_block_kobj); 1387e105b8bfSDan Williams block_kobj_err: 1388e105b8bfSDan Williams kobject_put(dev_kobj); 1389e105b8bfSDan Williams dev_kobj_err: 1390e105b8bfSDan Williams kset_unregister(devices_kset); 1391e105b8bfSDan Williams return -ENOMEM; 13921da177e4SLinus Torvalds } 13931da177e4SLinus Torvalds 13944f3549d7SRafael J. Wysocki static int device_check_offline(struct device *dev, void *not_used) 13954f3549d7SRafael J. Wysocki { 13964f3549d7SRafael J. Wysocki int ret; 13974f3549d7SRafael J. Wysocki 13984f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 13994f3549d7SRafael J. Wysocki if (ret) 14004f3549d7SRafael J. Wysocki return ret; 14014f3549d7SRafael J. Wysocki 14024f3549d7SRafael J. Wysocki return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; 14034f3549d7SRafael J. Wysocki } 14044f3549d7SRafael J. Wysocki 14054f3549d7SRafael J. Wysocki /** 14064f3549d7SRafael J. Wysocki * device_offline - Prepare the device for hot-removal. 14074f3549d7SRafael J. Wysocki * @dev: Device to be put offline. 14084f3549d7SRafael J. Wysocki * 14094f3549d7SRafael J. Wysocki * Execute the device bus type's .offline() callback, if present, to prepare 14104f3549d7SRafael J. Wysocki * the device for a subsequent hot-removal. If that succeeds, the device must 14114f3549d7SRafael J. Wysocki * not be used until either it is removed or its bus type's .online() callback 14124f3549d7SRafael J. Wysocki * is executed. 14134f3549d7SRafael J. Wysocki * 14144f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 14154f3549d7SRafael J. Wysocki */ 14164f3549d7SRafael J. Wysocki int device_offline(struct device *dev) 14174f3549d7SRafael J. Wysocki { 14184f3549d7SRafael J. Wysocki int ret; 14194f3549d7SRafael J. Wysocki 14204f3549d7SRafael J. Wysocki if (dev->offline_disabled) 14214f3549d7SRafael J. Wysocki return -EPERM; 14224f3549d7SRafael J. Wysocki 14234f3549d7SRafael J. Wysocki ret = device_for_each_child(dev, NULL, device_check_offline); 14244f3549d7SRafael J. Wysocki if (ret) 14254f3549d7SRafael J. Wysocki return ret; 14264f3549d7SRafael J. Wysocki 14274f3549d7SRafael J. Wysocki device_lock(dev); 14284f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 14294f3549d7SRafael J. Wysocki if (dev->offline) { 14304f3549d7SRafael J. Wysocki ret = 1; 14314f3549d7SRafael J. Wysocki } else { 14324f3549d7SRafael J. Wysocki ret = dev->bus->offline(dev); 14334f3549d7SRafael J. Wysocki if (!ret) { 14344f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 14354f3549d7SRafael J. Wysocki dev->offline = true; 14364f3549d7SRafael J. Wysocki } 14374f3549d7SRafael J. Wysocki } 14384f3549d7SRafael J. Wysocki } 14394f3549d7SRafael J. Wysocki device_unlock(dev); 14404f3549d7SRafael J. Wysocki 14414f3549d7SRafael J. Wysocki return ret; 14424f3549d7SRafael J. Wysocki } 14434f3549d7SRafael J. Wysocki 14444f3549d7SRafael J. Wysocki /** 14454f3549d7SRafael J. Wysocki * device_online - Put the device back online after successful device_offline(). 14464f3549d7SRafael J. Wysocki * @dev: Device to be put back online. 14474f3549d7SRafael J. Wysocki * 14484f3549d7SRafael J. Wysocki * If device_offline() has been successfully executed for @dev, but the device 14494f3549d7SRafael J. Wysocki * has not been removed subsequently, execute its bus type's .online() callback 14504f3549d7SRafael J. Wysocki * to indicate that the device can be used again. 14514f3549d7SRafael J. Wysocki * 14524f3549d7SRafael J. Wysocki * Call under device_hotplug_lock. 14534f3549d7SRafael J. Wysocki */ 14544f3549d7SRafael J. Wysocki int device_online(struct device *dev) 14554f3549d7SRafael J. Wysocki { 14564f3549d7SRafael J. Wysocki int ret = 0; 14574f3549d7SRafael J. Wysocki 14584f3549d7SRafael J. Wysocki device_lock(dev); 14594f3549d7SRafael J. Wysocki if (device_supports_offline(dev)) { 14604f3549d7SRafael J. Wysocki if (dev->offline) { 14614f3549d7SRafael J. Wysocki ret = dev->bus->online(dev); 14624f3549d7SRafael J. Wysocki if (!ret) { 14634f3549d7SRafael J. Wysocki kobject_uevent(&dev->kobj, KOBJ_ONLINE); 14644f3549d7SRafael J. Wysocki dev->offline = false; 14654f3549d7SRafael J. Wysocki } 14664f3549d7SRafael J. Wysocki } else { 14674f3549d7SRafael J. Wysocki ret = 1; 14684f3549d7SRafael J. Wysocki } 14694f3549d7SRafael J. Wysocki } 14704f3549d7SRafael J. Wysocki device_unlock(dev); 14714f3549d7SRafael J. Wysocki 14724f3549d7SRafael J. Wysocki return ret; 14734f3549d7SRafael J. Wysocki } 14744f3549d7SRafael J. Wysocki 14757f100d15SKarthigan Srinivasan struct root_device { 14760aa0dc41SMark McLoughlin struct device dev; 14770aa0dc41SMark McLoughlin struct module *owner; 14780aa0dc41SMark McLoughlin }; 14790aa0dc41SMark McLoughlin 148093058424SJosh Triplett static inline struct root_device *to_root_device(struct device *d) 1481481e2079SFerenc Wagner { 1482481e2079SFerenc Wagner return container_of(d, struct root_device, dev); 1483481e2079SFerenc Wagner } 14840aa0dc41SMark McLoughlin 14850aa0dc41SMark McLoughlin static void root_device_release(struct device *dev) 14860aa0dc41SMark McLoughlin { 14870aa0dc41SMark McLoughlin kfree(to_root_device(dev)); 14880aa0dc41SMark McLoughlin } 14890aa0dc41SMark McLoughlin 14900aa0dc41SMark McLoughlin /** 14910aa0dc41SMark McLoughlin * __root_device_register - allocate and register a root device 14920aa0dc41SMark McLoughlin * @name: root device name 14930aa0dc41SMark McLoughlin * @owner: owner module of the root device, usually THIS_MODULE 14940aa0dc41SMark McLoughlin * 14950aa0dc41SMark McLoughlin * This function allocates a root device and registers it 14960aa0dc41SMark McLoughlin * using device_register(). In order to free the returned 14970aa0dc41SMark McLoughlin * device, use root_device_unregister(). 14980aa0dc41SMark McLoughlin * 14990aa0dc41SMark McLoughlin * Root devices are dummy devices which allow other devices 15000aa0dc41SMark McLoughlin * to be grouped under /sys/devices. Use this function to 15010aa0dc41SMark McLoughlin * allocate a root device and then use it as the parent of 15020aa0dc41SMark McLoughlin * any device which should appear under /sys/devices/{name} 15030aa0dc41SMark McLoughlin * 15040aa0dc41SMark McLoughlin * The /sys/devices/{name} directory will also contain a 15050aa0dc41SMark McLoughlin * 'module' symlink which points to the @owner directory 15060aa0dc41SMark McLoughlin * in sysfs. 15070aa0dc41SMark McLoughlin * 1508f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1509f0eae0edSJani Nikula * 15100aa0dc41SMark McLoughlin * Note: You probably want to use root_device_register(). 15110aa0dc41SMark McLoughlin */ 15120aa0dc41SMark McLoughlin struct device *__root_device_register(const char *name, struct module *owner) 15130aa0dc41SMark McLoughlin { 15140aa0dc41SMark McLoughlin struct root_device *root; 15150aa0dc41SMark McLoughlin int err = -ENOMEM; 15160aa0dc41SMark McLoughlin 15170aa0dc41SMark McLoughlin root = kzalloc(sizeof(struct root_device), GFP_KERNEL); 15180aa0dc41SMark McLoughlin if (!root) 15190aa0dc41SMark McLoughlin return ERR_PTR(err); 15200aa0dc41SMark McLoughlin 1521acc0e90fSGreg Kroah-Hartman err = dev_set_name(&root->dev, "%s", name); 15220aa0dc41SMark McLoughlin if (err) { 15230aa0dc41SMark McLoughlin kfree(root); 15240aa0dc41SMark McLoughlin return ERR_PTR(err); 15250aa0dc41SMark McLoughlin } 15260aa0dc41SMark McLoughlin 15270aa0dc41SMark McLoughlin root->dev.release = root_device_release; 15280aa0dc41SMark McLoughlin 15290aa0dc41SMark McLoughlin err = device_register(&root->dev); 15300aa0dc41SMark McLoughlin if (err) { 15310aa0dc41SMark McLoughlin put_device(&root->dev); 15320aa0dc41SMark McLoughlin return ERR_PTR(err); 15330aa0dc41SMark McLoughlin } 15340aa0dc41SMark McLoughlin 15351d9e882bSChristoph Egger #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ 15360aa0dc41SMark McLoughlin if (owner) { 15370aa0dc41SMark McLoughlin struct module_kobject *mk = &owner->mkobj; 15380aa0dc41SMark McLoughlin 15390aa0dc41SMark McLoughlin err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); 15400aa0dc41SMark McLoughlin if (err) { 15410aa0dc41SMark McLoughlin device_unregister(&root->dev); 15420aa0dc41SMark McLoughlin return ERR_PTR(err); 15430aa0dc41SMark McLoughlin } 15440aa0dc41SMark McLoughlin root->owner = owner; 15450aa0dc41SMark McLoughlin } 15460aa0dc41SMark McLoughlin #endif 15470aa0dc41SMark McLoughlin 15480aa0dc41SMark McLoughlin return &root->dev; 15490aa0dc41SMark McLoughlin } 15500aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(__root_device_register); 15510aa0dc41SMark McLoughlin 15520aa0dc41SMark McLoughlin /** 15530aa0dc41SMark McLoughlin * root_device_unregister - unregister and free a root device 15547cbcf225SRandy Dunlap * @dev: device going away 15550aa0dc41SMark McLoughlin * 15560aa0dc41SMark McLoughlin * This function unregisters and cleans up a device that was created by 15570aa0dc41SMark McLoughlin * root_device_register(). 15580aa0dc41SMark McLoughlin */ 15590aa0dc41SMark McLoughlin void root_device_unregister(struct device *dev) 15600aa0dc41SMark McLoughlin { 15610aa0dc41SMark McLoughlin struct root_device *root = to_root_device(dev); 15620aa0dc41SMark McLoughlin 15630aa0dc41SMark McLoughlin if (root->owner) 15640aa0dc41SMark McLoughlin sysfs_remove_link(&root->dev.kobj, "module"); 15650aa0dc41SMark McLoughlin 15660aa0dc41SMark McLoughlin device_unregister(dev); 15670aa0dc41SMark McLoughlin } 15680aa0dc41SMark McLoughlin EXPORT_SYMBOL_GPL(root_device_unregister); 15690aa0dc41SMark McLoughlin 157023681e47SGreg Kroah-Hartman 157123681e47SGreg Kroah-Hartman static void device_create_release(struct device *dev) 157223681e47SGreg Kroah-Hartman { 15731e0b2cf9SKay Sievers pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 157423681e47SGreg Kroah-Hartman kfree(dev); 157523681e47SGreg Kroah-Hartman } 157623681e47SGreg Kroah-Hartman 157739ef3112SGuenter Roeck static struct device * 157839ef3112SGuenter Roeck device_create_groups_vargs(struct class *class, struct device *parent, 157939ef3112SGuenter Roeck dev_t devt, void *drvdata, 158039ef3112SGuenter Roeck const struct attribute_group **groups, 158139ef3112SGuenter Roeck const char *fmt, va_list args) 158239ef3112SGuenter Roeck { 158339ef3112SGuenter Roeck struct device *dev = NULL; 158439ef3112SGuenter Roeck int retval = -ENODEV; 158539ef3112SGuenter Roeck 158639ef3112SGuenter Roeck if (class == NULL || IS_ERR(class)) 158739ef3112SGuenter Roeck goto error; 158839ef3112SGuenter Roeck 158939ef3112SGuenter Roeck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 159039ef3112SGuenter Roeck if (!dev) { 159139ef3112SGuenter Roeck retval = -ENOMEM; 159239ef3112SGuenter Roeck goto error; 159339ef3112SGuenter Roeck } 159439ef3112SGuenter Roeck 1595bbc780f8SDavid Herrmann device_initialize(dev); 159639ef3112SGuenter Roeck dev->devt = devt; 159739ef3112SGuenter Roeck dev->class = class; 159839ef3112SGuenter Roeck dev->parent = parent; 159939ef3112SGuenter Roeck dev->groups = groups; 160039ef3112SGuenter Roeck dev->release = device_create_release; 160139ef3112SGuenter Roeck dev_set_drvdata(dev, drvdata); 160239ef3112SGuenter Roeck 160339ef3112SGuenter Roeck retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 160439ef3112SGuenter Roeck if (retval) 160539ef3112SGuenter Roeck goto error; 160639ef3112SGuenter Roeck 1607bbc780f8SDavid Herrmann retval = device_add(dev); 160839ef3112SGuenter Roeck if (retval) 160939ef3112SGuenter Roeck goto error; 161039ef3112SGuenter Roeck 161139ef3112SGuenter Roeck return dev; 161239ef3112SGuenter Roeck 161339ef3112SGuenter Roeck error: 161439ef3112SGuenter Roeck put_device(dev); 161539ef3112SGuenter Roeck return ERR_PTR(retval); 161639ef3112SGuenter Roeck } 161739ef3112SGuenter Roeck 161823681e47SGreg Kroah-Hartman /** 16198882b394SGreg Kroah-Hartman * device_create_vargs - creates a device and registers it with sysfs 16208882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 16218882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 16228882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 16238882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 16248882b394SGreg Kroah-Hartman * @fmt: string for the device's name 16258882b394SGreg Kroah-Hartman * @args: va_list for the device's name 16268882b394SGreg Kroah-Hartman * 16278882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 16288882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 16298882b394SGreg Kroah-Hartman * 16308882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 16318882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 16328882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 16338882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 16348882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 16358882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 16368882b394SGreg Kroah-Hartman * pointer. 16378882b394SGreg Kroah-Hartman * 1638f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1639f0eae0edSJani Nikula * 16408882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 16418882b394SGreg Kroah-Hartman * been created with a call to class_create(). 16428882b394SGreg Kroah-Hartman */ 16438882b394SGreg Kroah-Hartman struct device *device_create_vargs(struct class *class, struct device *parent, 16448882b394SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, 16458882b394SGreg Kroah-Hartman va_list args) 16468882b394SGreg Kroah-Hartman { 164739ef3112SGuenter Roeck return device_create_groups_vargs(class, parent, devt, drvdata, NULL, 164839ef3112SGuenter Roeck fmt, args); 16498882b394SGreg Kroah-Hartman } 16508882b394SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create_vargs); 16518882b394SGreg Kroah-Hartman 16528882b394SGreg Kroah-Hartman /** 16534e106739SGreg Kroah-Hartman * device_create - creates a device and registers it with sysfs 16548882b394SGreg Kroah-Hartman * @class: pointer to the struct class that this device should be registered to 16558882b394SGreg Kroah-Hartman * @parent: pointer to the parent struct device of this new device, if any 16568882b394SGreg Kroah-Hartman * @devt: the dev_t for the char device to be added 16578882b394SGreg Kroah-Hartman * @drvdata: the data to be added to the device for callbacks 16588882b394SGreg Kroah-Hartman * @fmt: string for the device's name 16598882b394SGreg Kroah-Hartman * 16608882b394SGreg Kroah-Hartman * This function can be used by char device classes. A struct device 16618882b394SGreg Kroah-Hartman * will be created in sysfs, registered to the specified class. 16628882b394SGreg Kroah-Hartman * 16638882b394SGreg Kroah-Hartman * A "dev" file will be created, showing the dev_t for the device, if 16648882b394SGreg Kroah-Hartman * the dev_t is not 0,0. 16658882b394SGreg Kroah-Hartman * If a pointer to a parent struct device is passed in, the newly created 16668882b394SGreg Kroah-Hartman * struct device will be a child of that device in sysfs. 16678882b394SGreg Kroah-Hartman * The pointer to the struct device will be returned from the call. 16688882b394SGreg Kroah-Hartman * Any further sysfs files that might be required can be created using this 16698882b394SGreg Kroah-Hartman * pointer. 16708882b394SGreg Kroah-Hartman * 1671f0eae0edSJani Nikula * Returns &struct device pointer on success, or ERR_PTR() on error. 1672f0eae0edSJani Nikula * 16738882b394SGreg Kroah-Hartman * Note: the struct class passed to this function must have previously 16748882b394SGreg Kroah-Hartman * been created with a call to class_create(). 16758882b394SGreg Kroah-Hartman */ 16764e106739SGreg Kroah-Hartman struct device *device_create(struct class *class, struct device *parent, 16774e106739SGreg Kroah-Hartman dev_t devt, void *drvdata, const char *fmt, ...) 16788882b394SGreg Kroah-Hartman { 16798882b394SGreg Kroah-Hartman va_list vargs; 16808882b394SGreg Kroah-Hartman struct device *dev; 16818882b394SGreg Kroah-Hartman 16828882b394SGreg Kroah-Hartman va_start(vargs, fmt); 16838882b394SGreg Kroah-Hartman dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); 16848882b394SGreg Kroah-Hartman va_end(vargs); 16858882b394SGreg Kroah-Hartman return dev; 16868882b394SGreg Kroah-Hartman } 16874e106739SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_create); 16888882b394SGreg Kroah-Hartman 168939ef3112SGuenter Roeck /** 169039ef3112SGuenter Roeck * device_create_with_groups - creates a device and registers it with sysfs 169139ef3112SGuenter Roeck * @class: pointer to the struct class that this device should be registered to 169239ef3112SGuenter Roeck * @parent: pointer to the parent struct device of this new device, if any 169339ef3112SGuenter Roeck * @devt: the dev_t for the char device to be added 169439ef3112SGuenter Roeck * @drvdata: the data to be added to the device for callbacks 169539ef3112SGuenter Roeck * @groups: NULL-terminated list of attribute groups to be created 169639ef3112SGuenter Roeck * @fmt: string for the device's name 169739ef3112SGuenter Roeck * 169839ef3112SGuenter Roeck * This function can be used by char device classes. A struct device 169939ef3112SGuenter Roeck * will be created in sysfs, registered to the specified class. 170039ef3112SGuenter Roeck * Additional attributes specified in the groups parameter will also 170139ef3112SGuenter Roeck * be created automatically. 170239ef3112SGuenter Roeck * 170339ef3112SGuenter Roeck * A "dev" file will be created, showing the dev_t for the device, if 170439ef3112SGuenter Roeck * the dev_t is not 0,0. 170539ef3112SGuenter Roeck * If a pointer to a parent struct device is passed in, the newly created 170639ef3112SGuenter Roeck * struct device will be a child of that device in sysfs. 170739ef3112SGuenter Roeck * The pointer to the struct device will be returned from the call. 170839ef3112SGuenter Roeck * Any further sysfs files that might be required can be created using this 170939ef3112SGuenter Roeck * pointer. 171039ef3112SGuenter Roeck * 171139ef3112SGuenter Roeck * Returns &struct device pointer on success, or ERR_PTR() on error. 171239ef3112SGuenter Roeck * 171339ef3112SGuenter Roeck * Note: the struct class passed to this function must have previously 171439ef3112SGuenter Roeck * been created with a call to class_create(). 171539ef3112SGuenter Roeck */ 171639ef3112SGuenter Roeck struct device *device_create_with_groups(struct class *class, 171739ef3112SGuenter Roeck struct device *parent, dev_t devt, 171839ef3112SGuenter Roeck void *drvdata, 171939ef3112SGuenter Roeck const struct attribute_group **groups, 172039ef3112SGuenter Roeck const char *fmt, ...) 172139ef3112SGuenter Roeck { 172239ef3112SGuenter Roeck va_list vargs; 172339ef3112SGuenter Roeck struct device *dev; 172439ef3112SGuenter Roeck 172539ef3112SGuenter Roeck va_start(vargs, fmt); 172639ef3112SGuenter Roeck dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, 172739ef3112SGuenter Roeck fmt, vargs); 172839ef3112SGuenter Roeck va_end(vargs); 172939ef3112SGuenter Roeck return dev; 173039ef3112SGuenter Roeck } 173139ef3112SGuenter Roeck EXPORT_SYMBOL_GPL(device_create_with_groups); 173239ef3112SGuenter Roeck 17339f3b795aSMichał Mirosław static int __match_devt(struct device *dev, const void *data) 173423681e47SGreg Kroah-Hartman { 17359f3b795aSMichał Mirosław const dev_t *devt = data; 173623681e47SGreg Kroah-Hartman 1737cd35449bSDave Young return dev->devt == *devt; 1738775b64d2SRafael J. Wysocki } 173923681e47SGreg Kroah-Hartman 1740775b64d2SRafael J. Wysocki /** 1741775b64d2SRafael J. Wysocki * device_destroy - removes a device that was created with device_create() 1742775b64d2SRafael J. Wysocki * @class: pointer to the struct class that this device was registered with 1743775b64d2SRafael J. Wysocki * @devt: the dev_t of the device that was previously registered 1744775b64d2SRafael J. Wysocki * 1745775b64d2SRafael J. Wysocki * This call unregisters and cleans up a device that was created with a 1746775b64d2SRafael J. Wysocki * call to device_create(). 1747775b64d2SRafael J. Wysocki */ 1748775b64d2SRafael J. Wysocki void device_destroy(struct class *class, dev_t devt) 1749775b64d2SRafael J. Wysocki { 1750775b64d2SRafael J. Wysocki struct device *dev; 1751775b64d2SRafael J. Wysocki 1752695794aeSGreg Kroah-Hartman dev = class_find_device(class, NULL, &devt, __match_devt); 1753cd35449bSDave Young if (dev) { 1754cd35449bSDave Young put_device(dev); 175523681e47SGreg Kroah-Hartman device_unregister(dev); 175623681e47SGreg Kroah-Hartman } 1757cd35449bSDave Young } 175823681e47SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(device_destroy); 1759a2de48caSGreg Kroah-Hartman 1760a2de48caSGreg Kroah-Hartman /** 1761a2de48caSGreg Kroah-Hartman * device_rename - renames a device 1762a2de48caSGreg Kroah-Hartman * @dev: the pointer to the struct device to be renamed 1763a2de48caSGreg Kroah-Hartman * @new_name: the new name of the device 1764030c1d2bSEric W. Biederman * 1765030c1d2bSEric W. Biederman * It is the responsibility of the caller to provide mutual 1766030c1d2bSEric W. Biederman * exclusion between two different calls of device_rename 1767030c1d2bSEric W. Biederman * on the same device to ensure that new_name is valid and 1768030c1d2bSEric W. Biederman * won't conflict with other devices. 1769c6c0ac66SMichael Ellerman * 1770a5462516STimur Tabi * Note: Don't call this function. Currently, the networking layer calls this 1771a5462516STimur Tabi * function, but that will change. The following text from Kay Sievers offers 1772a5462516STimur Tabi * some insight: 1773a5462516STimur Tabi * 1774a5462516STimur Tabi * Renaming devices is racy at many levels, symlinks and other stuff are not 1775a5462516STimur Tabi * replaced atomically, and you get a "move" uevent, but it's not easy to 1776a5462516STimur Tabi * connect the event to the old and new device. Device nodes are not renamed at 1777a5462516STimur Tabi * all, there isn't even support for that in the kernel now. 1778a5462516STimur Tabi * 1779a5462516STimur Tabi * In the meantime, during renaming, your target name might be taken by another 1780a5462516STimur Tabi * driver, creating conflicts. Or the old name is taken directly after you 1781a5462516STimur Tabi * renamed it -- then you get events for the same DEVPATH, before you even see 1782a5462516STimur Tabi * the "move" event. It's just a mess, and nothing new should ever rely on 1783a5462516STimur Tabi * kernel device renaming. Besides that, it's not even implemented now for 1784a5462516STimur Tabi * other things than (driver-core wise very simple) network devices. 1785a5462516STimur Tabi * 1786a5462516STimur Tabi * We are currently about to change network renaming in udev to completely 1787a5462516STimur Tabi * disallow renaming of devices in the same namespace as the kernel uses, 1788a5462516STimur Tabi * because we can't solve the problems properly, that arise with swapping names 1789a5462516STimur Tabi * of multiple interfaces without races. Means, renaming of eth[0-9]* will only 1790a5462516STimur Tabi * be allowed to some other name than eth[0-9]*, for the aforementioned 1791a5462516STimur Tabi * reasons. 1792a5462516STimur Tabi * 1793a5462516STimur Tabi * Make up a "real" name in the driver before you register anything, or add 1794a5462516STimur Tabi * some other attributes for userspace to find the device, or use udev to add 1795a5462516STimur Tabi * symlinks -- but never rename kernel devices later, it's a complete mess. We 1796a5462516STimur Tabi * don't even want to get into that and try to implement the missing pieces in 1797a5462516STimur Tabi * the core. We really have other pieces to fix in the driver core mess. :) 1798a2de48caSGreg Kroah-Hartman */ 17996937e8f8SJohannes Berg int device_rename(struct device *dev, const char *new_name) 1800a2de48caSGreg Kroah-Hartman { 18014b30ee58STejun Heo struct kobject *kobj = &dev->kobj; 18022ee97cafSCornelia Huck char *old_device_name = NULL; 1803a2de48caSGreg Kroah-Hartman int error; 1804a2de48caSGreg Kroah-Hartman 1805a2de48caSGreg Kroah-Hartman dev = get_device(dev); 1806a2de48caSGreg Kroah-Hartman if (!dev) 1807a2de48caSGreg Kroah-Hartman return -EINVAL; 1808a2de48caSGreg Kroah-Hartman 180969df7533Sethan.zhao dev_dbg(dev, "renaming to %s\n", new_name); 1810a2de48caSGreg Kroah-Hartman 18111fa5ae85SKay Sievers old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); 18122ee97cafSCornelia Huck if (!old_device_name) { 1813952ab431SJesper Juhl error = -ENOMEM; 18142ee97cafSCornelia Huck goto out; 1815952ab431SJesper Juhl } 1816a2de48caSGreg Kroah-Hartman 1817f349cf34SEric W. Biederman if (dev->class) { 18184b30ee58STejun Heo error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, 18194b30ee58STejun Heo kobj, old_device_name, 18204b30ee58STejun Heo new_name, kobject_namespace(kobj)); 1821f349cf34SEric W. Biederman if (error) 1822f349cf34SEric W. Biederman goto out; 1823f349cf34SEric W. Biederman } 182439aba963SKay Sievers 18254b30ee58STejun Heo error = kobject_rename(kobj, new_name); 18261fa5ae85SKay Sievers if (error) 18272ee97cafSCornelia Huck goto out; 1828a2de48caSGreg Kroah-Hartman 18292ee97cafSCornelia Huck out: 1830a2de48caSGreg Kroah-Hartman put_device(dev); 1831a2de48caSGreg Kroah-Hartman 18322ee97cafSCornelia Huck kfree(old_device_name); 1833a2de48caSGreg Kroah-Hartman 1834a2de48caSGreg Kroah-Hartman return error; 1835a2de48caSGreg Kroah-Hartman } 1836a2807dbcSJohannes Berg EXPORT_SYMBOL_GPL(device_rename); 18378a82472fSCornelia Huck 18388a82472fSCornelia Huck static int device_move_class_links(struct device *dev, 18398a82472fSCornelia Huck struct device *old_parent, 18408a82472fSCornelia Huck struct device *new_parent) 18418a82472fSCornelia Huck { 1842f7f3461dSGreg Kroah-Hartman int error = 0; 18438a82472fSCornelia Huck 1844f7f3461dSGreg Kroah-Hartman if (old_parent) 1845f7f3461dSGreg Kroah-Hartman sysfs_remove_link(&dev->kobj, "device"); 1846f7f3461dSGreg Kroah-Hartman if (new_parent) 1847f7f3461dSGreg Kroah-Hartman error = sysfs_create_link(&dev->kobj, &new_parent->kobj, 1848f7f3461dSGreg Kroah-Hartman "device"); 1849f7f3461dSGreg Kroah-Hartman return error; 18508a82472fSCornelia Huck } 18518a82472fSCornelia Huck 18528a82472fSCornelia Huck /** 18538a82472fSCornelia Huck * device_move - moves a device to a new parent 18548a82472fSCornelia Huck * @dev: the pointer to the struct device to be moved 1855c744aeaeSCornelia Huck * @new_parent: the new parent of the device (can by NULL) 1856ffa6a705SCornelia Huck * @dpm_order: how to reorder the dpm_list 18578a82472fSCornelia Huck */ 1858ffa6a705SCornelia Huck int device_move(struct device *dev, struct device *new_parent, 1859ffa6a705SCornelia Huck enum dpm_order dpm_order) 18608a82472fSCornelia Huck { 18618a82472fSCornelia Huck int error; 18628a82472fSCornelia Huck struct device *old_parent; 1863c744aeaeSCornelia Huck struct kobject *new_parent_kobj; 18648a82472fSCornelia Huck 18658a82472fSCornelia Huck dev = get_device(dev); 18668a82472fSCornelia Huck if (!dev) 18678a82472fSCornelia Huck return -EINVAL; 18688a82472fSCornelia Huck 1869ffa6a705SCornelia Huck device_pm_lock(); 18708a82472fSCornelia Huck new_parent = get_device(new_parent); 1871c744aeaeSCornelia Huck new_parent_kobj = get_device_parent(dev, new_parent); 187263b6971aSCornelia Huck 18731e0b2cf9SKay Sievers pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), 18741e0b2cf9SKay Sievers __func__, new_parent ? dev_name(new_parent) : "<NULL>"); 1875c744aeaeSCornelia Huck error = kobject_move(&dev->kobj, new_parent_kobj); 18768a82472fSCornelia Huck if (error) { 187763b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 18788a82472fSCornelia Huck put_device(new_parent); 18798a82472fSCornelia Huck goto out; 18808a82472fSCornelia Huck } 18818a82472fSCornelia Huck old_parent = dev->parent; 18828a82472fSCornelia Huck dev->parent = new_parent; 18838a82472fSCornelia Huck if (old_parent) 1884f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 18850d358f22SYinghai Lu if (new_parent) { 1886f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1887f791b8c8SGreg Kroah-Hartman &new_parent->p->klist_children); 18880d358f22SYinghai Lu set_dev_node(dev, dev_to_node(new_parent)); 18890d358f22SYinghai Lu } 18900d358f22SYinghai Lu 1891bdd4034dSRabin Vincent if (dev->class) { 18928a82472fSCornelia Huck error = device_move_class_links(dev, old_parent, new_parent); 18938a82472fSCornelia Huck if (error) { 18948a82472fSCornelia Huck /* We ignore errors on cleanup since we're hosed anyway... */ 18958a82472fSCornelia Huck device_move_class_links(dev, new_parent, old_parent); 18968a82472fSCornelia Huck if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 1897c744aeaeSCornelia Huck if (new_parent) 1898f791b8c8SGreg Kroah-Hartman klist_remove(&dev->p->knode_parent); 18990d358f22SYinghai Lu dev->parent = old_parent; 19000d358f22SYinghai Lu if (old_parent) { 1901f791b8c8SGreg Kroah-Hartman klist_add_tail(&dev->p->knode_parent, 1902f791b8c8SGreg Kroah-Hartman &old_parent->p->klist_children); 19030d358f22SYinghai Lu set_dev_node(dev, dev_to_node(old_parent)); 19040d358f22SYinghai Lu } 19058a82472fSCornelia Huck } 190663b6971aSCornelia Huck cleanup_glue_dir(dev, new_parent_kobj); 19078a82472fSCornelia Huck put_device(new_parent); 19088a82472fSCornelia Huck goto out; 19098a82472fSCornelia Huck } 1910bdd4034dSRabin Vincent } 1911ffa6a705SCornelia Huck switch (dpm_order) { 1912ffa6a705SCornelia Huck case DPM_ORDER_NONE: 1913ffa6a705SCornelia Huck break; 1914ffa6a705SCornelia Huck case DPM_ORDER_DEV_AFTER_PARENT: 1915ffa6a705SCornelia Huck device_pm_move_after(dev, new_parent); 1916ffa6a705SCornelia Huck break; 1917ffa6a705SCornelia Huck case DPM_ORDER_PARENT_BEFORE_DEV: 1918ffa6a705SCornelia Huck device_pm_move_before(new_parent, dev); 1919ffa6a705SCornelia Huck break; 1920ffa6a705SCornelia Huck case DPM_ORDER_DEV_LAST: 1921ffa6a705SCornelia Huck device_pm_move_last(dev); 1922ffa6a705SCornelia Huck break; 1923ffa6a705SCornelia Huck } 1924bdd4034dSRabin Vincent 19258a82472fSCornelia Huck put_device(old_parent); 19268a82472fSCornelia Huck out: 1927ffa6a705SCornelia Huck device_pm_unlock(); 19288a82472fSCornelia Huck put_device(dev); 19298a82472fSCornelia Huck return error; 19308a82472fSCornelia Huck } 19318a82472fSCornelia Huck EXPORT_SYMBOL_GPL(device_move); 193237b0c020SGreg Kroah-Hartman 193337b0c020SGreg Kroah-Hartman /** 193437b0c020SGreg Kroah-Hartman * device_shutdown - call ->shutdown() on each device to shutdown. 193537b0c020SGreg Kroah-Hartman */ 193637b0c020SGreg Kroah-Hartman void device_shutdown(void) 193737b0c020SGreg Kroah-Hartman { 1938f123db8eSBenson Leung struct device *dev, *parent; 193937b0c020SGreg Kroah-Hartman 19406245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 19416245838fSHugh Daschbach /* 19426245838fSHugh Daschbach * Walk the devices list backward, shutting down each in turn. 19436245838fSHugh Daschbach * Beware that device unplug events may also start pulling 19446245838fSHugh Daschbach * devices offline, even as the system is shutting down. 19456245838fSHugh Daschbach */ 19466245838fSHugh Daschbach while (!list_empty(&devices_kset->list)) { 19476245838fSHugh Daschbach dev = list_entry(devices_kset->list.prev, struct device, 19486245838fSHugh Daschbach kobj.entry); 1949d1c6c030SMing Lei 1950d1c6c030SMing Lei /* 1951d1c6c030SMing Lei * hold reference count of device's parent to 1952d1c6c030SMing Lei * prevent it from being freed because parent's 1953d1c6c030SMing Lei * lock is to be held 1954d1c6c030SMing Lei */ 1955f123db8eSBenson Leung parent = get_device(dev->parent); 19566245838fSHugh Daschbach get_device(dev); 19576245838fSHugh Daschbach /* 19586245838fSHugh Daschbach * Make sure the device is off the kset list, in the 19596245838fSHugh Daschbach * event that dev->*->shutdown() doesn't remove it. 19606245838fSHugh Daschbach */ 19616245838fSHugh Daschbach list_del_init(&dev->kobj.entry); 19626245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 1963fe6b91f4SAlan Stern 1964d1c6c030SMing Lei /* hold lock to avoid race with probe/release */ 1965f123db8eSBenson Leung if (parent) 1966f123db8eSBenson Leung device_lock(parent); 1967d1c6c030SMing Lei device_lock(dev); 1968d1c6c030SMing Lei 1969fe6b91f4SAlan Stern /* Don't allow any more runtime suspends */ 1970fe6b91f4SAlan Stern pm_runtime_get_noresume(dev); 1971fe6b91f4SAlan Stern pm_runtime_barrier(dev); 19726245838fSHugh Daschbach 197337b0c020SGreg Kroah-Hartman if (dev->bus && dev->bus->shutdown) { 19740246c4faSShuoX Liu if (initcall_debug) 19750246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 197637b0c020SGreg Kroah-Hartman dev->bus->shutdown(dev); 197737b0c020SGreg Kroah-Hartman } else if (dev->driver && dev->driver->shutdown) { 19780246c4faSShuoX Liu if (initcall_debug) 19790246c4faSShuoX Liu dev_info(dev, "shutdown\n"); 198037b0c020SGreg Kroah-Hartman dev->driver->shutdown(dev); 198137b0c020SGreg Kroah-Hartman } 1982d1c6c030SMing Lei 1983d1c6c030SMing Lei device_unlock(dev); 1984f123db8eSBenson Leung if (parent) 1985f123db8eSBenson Leung device_unlock(parent); 1986d1c6c030SMing Lei 19876245838fSHugh Daschbach put_device(dev); 1988f123db8eSBenson Leung put_device(parent); 19896245838fSHugh Daschbach 19906245838fSHugh Daschbach spin_lock(&devices_kset->list_lock); 199137b0c020SGreg Kroah-Hartman } 19926245838fSHugh Daschbach spin_unlock(&devices_kset->list_lock); 199337b0c020SGreg Kroah-Hartman } 199499bcf217SJoe Perches 199599bcf217SJoe Perches /* 199699bcf217SJoe Perches * Device logging functions 199799bcf217SJoe Perches */ 199899bcf217SJoe Perches 199999bcf217SJoe Perches #ifdef CONFIG_PRINTK 2000666f355fSJoe Perches static int 2001666f355fSJoe Perches create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) 200299bcf217SJoe Perches { 2003c4e00daaSKay Sievers const char *subsys; 2004798efc60SJoe Perches size_t pos = 0; 200599bcf217SJoe Perches 2006c4e00daaSKay Sievers if (dev->class) 2007c4e00daaSKay Sievers subsys = dev->class->name; 2008c4e00daaSKay Sievers else if (dev->bus) 2009c4e00daaSKay Sievers subsys = dev->bus->name; 2010c4e00daaSKay Sievers else 2011798efc60SJoe Perches return 0; 2012c4e00daaSKay Sievers 2013798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); 2014655e5b7cSBen Hutchings if (pos >= hdrlen) 2015655e5b7cSBen Hutchings goto overflow; 2016c4e00daaSKay Sievers 2017c4e00daaSKay Sievers /* 2018c4e00daaSKay Sievers * Add device identifier DEVICE=: 2019c4e00daaSKay Sievers * b12:8 block dev_t 2020c4e00daaSKay Sievers * c127:3 char dev_t 2021c4e00daaSKay Sievers * n8 netdev ifindex 2022c4e00daaSKay Sievers * +sound:card0 subsystem:devname 2023c4e00daaSKay Sievers */ 2024c4e00daaSKay Sievers if (MAJOR(dev->devt)) { 2025c4e00daaSKay Sievers char c; 2026c4e00daaSKay Sievers 2027c4e00daaSKay Sievers if (strcmp(subsys, "block") == 0) 2028c4e00daaSKay Sievers c = 'b'; 2029c4e00daaSKay Sievers else 2030c4e00daaSKay Sievers c = 'c'; 2031798efc60SJoe Perches pos++; 2032798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2033c4e00daaSKay Sievers "DEVICE=%c%u:%u", 2034c4e00daaSKay Sievers c, MAJOR(dev->devt), MINOR(dev->devt)); 2035c4e00daaSKay Sievers } else if (strcmp(subsys, "net") == 0) { 2036c4e00daaSKay Sievers struct net_device *net = to_net_dev(dev); 2037c4e00daaSKay Sievers 2038798efc60SJoe Perches pos++; 2039798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2040c4e00daaSKay Sievers "DEVICE=n%u", net->ifindex); 2041c4e00daaSKay Sievers } else { 2042798efc60SJoe Perches pos++; 2043798efc60SJoe Perches pos += snprintf(hdr + pos, hdrlen - pos, 2044c4e00daaSKay Sievers "DEVICE=+%s:%s", subsys, dev_name(dev)); 2045c4e00daaSKay Sievers } 2046af7f2158SJim Cromie 2047655e5b7cSBen Hutchings if (pos >= hdrlen) 2048655e5b7cSBen Hutchings goto overflow; 2049655e5b7cSBen Hutchings 2050798efc60SJoe Perches return pos; 2051655e5b7cSBen Hutchings 2052655e5b7cSBen Hutchings overflow: 2053655e5b7cSBen Hutchings dev_WARN(dev, "device/subsystem name too long"); 2054655e5b7cSBen Hutchings return 0; 205599bcf217SJoe Perches } 2056798efc60SJoe Perches 205705e4e5b8SJoe Perches int dev_vprintk_emit(int level, const struct device *dev, 205805e4e5b8SJoe Perches const char *fmt, va_list args) 205905e4e5b8SJoe Perches { 206005e4e5b8SJoe Perches char hdr[128]; 206105e4e5b8SJoe Perches size_t hdrlen; 206205e4e5b8SJoe Perches 206305e4e5b8SJoe Perches hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); 206405e4e5b8SJoe Perches 206505e4e5b8SJoe Perches return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); 206605e4e5b8SJoe Perches } 206705e4e5b8SJoe Perches EXPORT_SYMBOL(dev_vprintk_emit); 206805e4e5b8SJoe Perches 206905e4e5b8SJoe Perches int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) 207005e4e5b8SJoe Perches { 207105e4e5b8SJoe Perches va_list args; 207205e4e5b8SJoe Perches int r; 207305e4e5b8SJoe Perches 207405e4e5b8SJoe Perches va_start(args, fmt); 207505e4e5b8SJoe Perches 207605e4e5b8SJoe Perches r = dev_vprintk_emit(level, dev, fmt, args); 207705e4e5b8SJoe Perches 207805e4e5b8SJoe Perches va_end(args); 207905e4e5b8SJoe Perches 208005e4e5b8SJoe Perches return r; 208105e4e5b8SJoe Perches } 208205e4e5b8SJoe Perches EXPORT_SYMBOL(dev_printk_emit); 208305e4e5b8SJoe Perches 2084d1f1052cSJoe Perches static void __dev_printk(const char *level, const struct device *dev, 2085798efc60SJoe Perches struct va_format *vaf) 2086798efc60SJoe Perches { 2087d1f1052cSJoe Perches if (dev) 2088d1f1052cSJoe Perches dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", 2089798efc60SJoe Perches dev_driver_string(dev), dev_name(dev), vaf); 2090d1f1052cSJoe Perches else 2091d1f1052cSJoe Perches printk("%s(NULL device *): %pV", level, vaf); 2092798efc60SJoe Perches } 209399bcf217SJoe Perches 2094d1f1052cSJoe Perches void dev_printk(const char *level, const struct device *dev, 209599bcf217SJoe Perches const char *fmt, ...) 209699bcf217SJoe Perches { 209799bcf217SJoe Perches struct va_format vaf; 209899bcf217SJoe Perches va_list args; 209999bcf217SJoe Perches 210099bcf217SJoe Perches va_start(args, fmt); 210199bcf217SJoe Perches 210299bcf217SJoe Perches vaf.fmt = fmt; 210399bcf217SJoe Perches vaf.va = &args; 210499bcf217SJoe Perches 2105d1f1052cSJoe Perches __dev_printk(level, dev, &vaf); 2106798efc60SJoe Perches 210799bcf217SJoe Perches va_end(args); 210899bcf217SJoe Perches } 210999bcf217SJoe Perches EXPORT_SYMBOL(dev_printk); 211099bcf217SJoe Perches 211199bcf217SJoe Perches #define define_dev_printk_level(func, kern_level) \ 2112d1f1052cSJoe Perches void func(const struct device *dev, const char *fmt, ...) \ 211399bcf217SJoe Perches { \ 211499bcf217SJoe Perches struct va_format vaf; \ 211599bcf217SJoe Perches va_list args; \ 211699bcf217SJoe Perches \ 211799bcf217SJoe Perches va_start(args, fmt); \ 211899bcf217SJoe Perches \ 211999bcf217SJoe Perches vaf.fmt = fmt; \ 212099bcf217SJoe Perches vaf.va = &args; \ 212199bcf217SJoe Perches \ 2122d1f1052cSJoe Perches __dev_printk(kern_level, dev, &vaf); \ 2123798efc60SJoe Perches \ 212499bcf217SJoe Perches va_end(args); \ 212599bcf217SJoe Perches } \ 212699bcf217SJoe Perches EXPORT_SYMBOL(func); 212799bcf217SJoe Perches 212899bcf217SJoe Perches define_dev_printk_level(dev_emerg, KERN_EMERG); 212999bcf217SJoe Perches define_dev_printk_level(dev_alert, KERN_ALERT); 213099bcf217SJoe Perches define_dev_printk_level(dev_crit, KERN_CRIT); 213199bcf217SJoe Perches define_dev_printk_level(dev_err, KERN_ERR); 213299bcf217SJoe Perches define_dev_printk_level(dev_warn, KERN_WARNING); 213399bcf217SJoe Perches define_dev_printk_level(dev_notice, KERN_NOTICE); 213499bcf217SJoe Perches define_dev_printk_level(_dev_info, KERN_INFO); 213599bcf217SJoe Perches 213699bcf217SJoe Perches #endif 213797badf87SRafael J. Wysocki 213897badf87SRafael J. Wysocki static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 213997badf87SRafael J. Wysocki { 214097badf87SRafael J. Wysocki return fwnode && !IS_ERR(fwnode->secondary); 214197badf87SRafael J. Wysocki } 214297badf87SRafael J. Wysocki 214397badf87SRafael J. Wysocki /** 214497badf87SRafael J. Wysocki * set_primary_fwnode - Change the primary firmware node of a given device. 214597badf87SRafael J. Wysocki * @dev: Device to handle. 214697badf87SRafael J. Wysocki * @fwnode: New primary firmware node of the device. 214797badf87SRafael J. Wysocki * 214897badf87SRafael J. Wysocki * Set the device's firmware node pointer to @fwnode, but if a secondary 214997badf87SRafael J. Wysocki * firmware node of the device is present, preserve it. 215097badf87SRafael J. Wysocki */ 215197badf87SRafael J. Wysocki void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 215297badf87SRafael J. Wysocki { 215397badf87SRafael J. Wysocki if (fwnode) { 215497badf87SRafael J. Wysocki struct fwnode_handle *fn = dev->fwnode; 215597badf87SRafael J. Wysocki 215697badf87SRafael J. Wysocki if (fwnode_is_primary(fn)) 215797badf87SRafael J. Wysocki fn = fn->secondary; 215897badf87SRafael J. Wysocki 215997badf87SRafael J. Wysocki fwnode->secondary = fn; 216097badf87SRafael J. Wysocki dev->fwnode = fwnode; 216197badf87SRafael J. Wysocki } else { 216297badf87SRafael J. Wysocki dev->fwnode = fwnode_is_primary(dev->fwnode) ? 216397badf87SRafael J. Wysocki dev->fwnode->secondary : NULL; 216497badf87SRafael J. Wysocki } 216597badf87SRafael J. Wysocki } 216697badf87SRafael J. Wysocki EXPORT_SYMBOL_GPL(set_primary_fwnode); 216797badf87SRafael J. Wysocki 216897badf87SRafael J. Wysocki /** 216997badf87SRafael J. Wysocki * set_secondary_fwnode - Change the secondary firmware node of a given device. 217097badf87SRafael J. Wysocki * @dev: Device to handle. 217197badf87SRafael J. Wysocki * @fwnode: New secondary firmware node of the device. 217297badf87SRafael J. Wysocki * 217397badf87SRafael J. Wysocki * If a primary firmware node of the device is present, set its secondary 217497badf87SRafael J. Wysocki * pointer to @fwnode. Otherwise, set the device's firmware node pointer to 217597badf87SRafael J. Wysocki * @fwnode. 217697badf87SRafael J. Wysocki */ 217797badf87SRafael J. Wysocki void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) 217897badf87SRafael J. Wysocki { 217997badf87SRafael J. Wysocki if (fwnode) 218097badf87SRafael J. Wysocki fwnode->secondary = ERR_PTR(-ENODEV); 218197badf87SRafael J. Wysocki 218297badf87SRafael J. Wysocki if (fwnode_is_primary(dev->fwnode)) 218397badf87SRafael J. Wysocki dev->fwnode->secondary = fwnode; 218497badf87SRafael J. Wysocki else 218597badf87SRafael J. Wysocki dev->fwnode = fwnode; 218697badf87SRafael J. Wysocki } 2187