summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-10-15 07:41:35 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-10-15 07:41:35 -0700
commit8fbfe7cd5594010a23cb4e81786d1fb8015ffdee (patch)
treeb5be190f22984395209823ec3cac1c76fc93f67f /drivers/base
parente22f7f5fd43205bfd20ea3a7bb4e689cb3f3d278 (diff)
parent5a7728c6d3eb83df9d120944cca4cf476dd326a1 (diff)
Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c92
1 files changed, 57 insertions, 35 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4fc859d3ab57..83c31723d844 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -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);
}