]> git.hungrycats.org Git - linux/commitdiff
[PATCH] device_register() splitup
authorAlexander Viro <viro@math.psu.edu>
Tue, 15 Oct 2002 11:23:37 +0000 (04:23 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 15 Oct 2002 11:23:37 +0000 (04:23 -0700)
new driverfs helpers - device_initialize/device_add and device_del.
The latter is device_unregister() sans the final put_device().  The former
is splitup of device_register() into initialization and insertion into tree.

drivers/base/core.c
include/linux/device.h

index 4fc859d3ab579d76f75886c75f797d6d292f81e3..83c31723d8447211514f1e84cce555f7214e8847 100644 (file)
@@ -149,36 +149,16 @@ void driver_detach(struct device_driver * drv)
        spin_unlock(&device_lock);
 }
 
-/**
- * device_register - register a device
- * @dev:       pointer to the device structure
- *
- * First, make sure that the device has a parent, create
- * a directory for it, then add it to the parent's list of
- * children.
- *
- * Maintains a global list of all devices, in depth-first ordering.
- * The head for that list is device_root.g_list.
- */
-int device_register(struct device *dev)
+int device_add(struct device *dev)
 {
        int error;
 
        if (!dev || !strlen(dev->bus_id))
                return -EINVAL;
 
-       INIT_LIST_HEAD(&dev->node);
-       INIT_LIST_HEAD(&dev->children);
-       INIT_LIST_HEAD(&dev->g_list);
-       INIT_LIST_HEAD(&dev->driver_list);
-       INIT_LIST_HEAD(&dev->bus_list);
-       INIT_LIST_HEAD(&dev->intf_list);
-       spin_lock_init(&dev->lock);
-       atomic_set(&dev->refcount,2);
-       dev->present = 1;
        spin_lock(&device_lock);
+       dev->present = 1;
        if (dev->parent) {
-               get_device_locked(dev->parent);
                list_add_tail(&dev->g_list,&dev->parent->g_list);
                list_add_tail(&dev->node,&dev->parent->children);
        } else
@@ -209,10 +189,48 @@ int device_register(struct device *dev)
                list_del_init(&dev->g_list);
                list_del_init(&dev->node);
                spin_unlock(&device_lock);
-               if (dev->parent)
-                       put_device(dev->parent);
        }
-       put_device(dev);
+       return error;
+}
+
+void device_initialize(struct device *dev)
+{
+       INIT_LIST_HEAD(&dev->node);
+       INIT_LIST_HEAD(&dev->children);
+       INIT_LIST_HEAD(&dev->g_list);
+       INIT_LIST_HEAD(&dev->driver_list);
+       INIT_LIST_HEAD(&dev->bus_list);
+       INIT_LIST_HEAD(&dev->intf_list);
+       spin_lock_init(&dev->lock);
+       atomic_set(&dev->refcount,1);
+       if (dev->parent)
+               get_device(dev->parent);
+}
+
+/**
+ * device_register - register a device
+ * @dev:       pointer to the device structure
+ *
+ * First, make sure that the device has a parent, create
+ * a directory for it, then add it to the parent's list of
+ * children.
+ *
+ * Maintains a global list of all devices, in depth-first ordering.
+ * The head for that list is device_root.g_list.
+ */
+int device_register(struct device *dev)
+{
+       int error;
+
+       if (!dev || !strlen(dev->bus_id))
+               return -EINVAL;
+
+       device_initialize(dev);
+       if (dev->parent)
+               get_device(dev->parent);
+       error = device_add(dev);
+       if (error && dev->parent)
+               put_device(dev->parent);
        return error;
 }
 
@@ -257,16 +275,7 @@ void put_device(struct device * dev)
                put_device(parent);
 }
 
-/**
- * device_unregister - unlink device
- * @dev:       device going away
- *
- * The device has been removed from the system, so we disavow knowledge
- * of it. It might not be the final reference to the device, so we mark
- * it as !present, so no more references to it can be acquired.
- * In the end, we decrement the final reference count for it.
- */
-void device_unregister(struct device * dev)
+void device_del(struct device * dev)
 {
        spin_lock(&device_lock);
        dev->present = 0;
@@ -293,7 +302,20 @@ void device_unregister(struct device * dev)
 
        /* remove the driverfs directory */
        device_remove_dir(dev);
+}
 
+/**
+ * device_unregister - unlink device
+ * @dev:       device going away
+ *
+ * The device has been removed from the system, so we disavow knowledge
+ * of it. It might not be the final reference to the device, so we mark
+ * it as !present, so no more references to it can be acquired.
+ * In the end, we decrement the final reference count for it.
+ */
+void device_unregister(struct device * dev)
+{
+       device_del(dev);
        put_device(dev);
 }
 
index 3290c5c4027650acf1884b8610c09fab857d4df0..80a63939f9245e617488e973cd128e5e0588288c 100644 (file)
@@ -329,6 +329,9 @@ dev_set_drvdata (struct device *dev, void *data)
  */
 extern int device_register(struct device * dev);
 extern void device_unregister(struct device * dev);
+extern void device_initialize(struct device * dev);
+extern int device_add(struct device * dev);
+extern void device_del(struct device * dev);
 
 /* driverfs interface for exporting device attributes */