summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2003-04-28 09:05:37 -0700
committerGreg Kroah-Hartman <greg@kroah.com>2003-04-28 09:05:37 -0700
commit28926b3d45f4850f1d2d246a2c01b6d24fbd227c (patch)
treed35c1fab223537ebc0a22096d83ed2949405b595 /drivers/base
parent5d4d8070c3d10a9a18894c671b247c6790e3355a (diff)
driver core: rework driver class structures and logic
Removes the device_class, devclass_attribute, and device_interface structures and replaces them with class, class_device, and class_interface structures. This allows us to have multiple class_device structures per device structures which mirrors the ways things really are within the kernel. It also allows class_device structures to be created later than struct devices as they are naturally created much later in the initialization process of a device.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Makefile4
-rw-r--r--drivers/base/base.h20
-rw-r--r--drivers/base/bus.c11
-rw-r--r--drivers/base/class.c472
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/driver.c1
6 files changed, 307 insertions, 203 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index e9c753888d48..354a9789d29d 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,8 +1,6 @@
# Makefile for the Linux device tree
obj-y := core.o sys.o interface.o power.o bus.o \
- driver.o class.o intf.o platform.o \
+ driver.o class.o platform.o \
cpu.o firmware.o init.o
obj-$(CONFIG_NUMA) += node.o memblk.o
-obj-y += fs/
-obj-$(CONFIG_HOTPLUG) += hotplug.o
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 9180934e6c99..121bb0c84418 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -1,5 +1,4 @@
extern struct semaphore device_sem;
-extern struct semaphore devclass_sem;
extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev);
@@ -7,22 +6,3 @@ extern void bus_remove_device(struct device * dev);
extern int bus_add_driver(struct device_driver *);
extern void bus_remove_driver(struct device_driver *);
-extern int devclass_add_device(struct device *);
-extern void devclass_remove_device(struct device *);
-
-extern int devclass_add_driver(struct device_driver *);
-extern void devclass_remove_driver(struct device_driver *);
-
-extern int interface_add_dev(struct device *);
-extern void interface_remove_dev(struct device *);
-
-
-#ifdef CONFIG_HOTPLUG
-extern int class_hotplug(struct device *dev, const char *action);
-#else
-static inline int class_hotplug(struct device *dev, const char *action)
-{
- return 0;
-}
-#endif
-
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index e918f4db4840..3a8e54592af7 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -311,8 +311,7 @@ static int device_attach(struct device * dev)
* Walk the list of devices that the bus has on it and try to match
* the driver with each one.
* If bus_match() returns 0 and the @dev->driver is set, we've found
- * a compatible pair, so we call devclass_add_device() to add the
- * device to the class.
+ * a compatible pair.
*
* Note that we ignore the error from bus_match(), since it's perfectly
* valid for a driver not to bind to any devices.
@@ -328,8 +327,7 @@ static void driver_attach(struct device_driver * drv)
list_for_each(entry,&bus->devices.list) {
struct device * dev = container_of(entry,struct device,bus_list);
if (!dev->driver) {
- if (!bus_match(dev,drv))
- devclass_add_device(dev);
+ bus_match(dev,drv);
}
}
}
@@ -351,7 +349,6 @@ void device_release_driver(struct device * dev)
if (drv) {
sysfs_remove_link(&drv->kobj,dev->kobj.name);
list_del_init(&dev->driver_list);
- devclass_remove_device(dev);
if (drv->remove)
drv->remove(dev);
dev->driver = NULL;
@@ -443,8 +440,7 @@ int bus_add_driver(struct device_driver * drv)
}
down_write(&bus->subsys.rwsem);
- if (!(error = devclass_add_driver(drv)))
- driver_attach(drv);
+ driver_attach(drv);
up_write(&bus->subsys.rwsem);
if (error) {
@@ -471,7 +467,6 @@ void bus_remove_driver(struct device_driver * drv)
down_write(&drv->bus->subsys.rwsem);
pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name);
driver_detach(drv);
- devclass_remove_driver(drv);
up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj);
put_bus(drv->bus);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8e35b7884276..eda427f96134 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -1,5 +1,7 @@
/*
* class.c - basic device class management
+ *
+ * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
*/
#undef DEBUG
@@ -10,16 +12,14 @@
#include <linux/string.h>
#include "base.h"
-#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
-#define to_class(obj) container_of(obj,struct device_class,subsys.kset.kobj)
-
-DECLARE_MUTEX(devclass_sem);
+#define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
+#define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
static ssize_t
-devclass_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
+class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
- struct devclass_attribute * class_attr = to_class_attr(attr);
- struct device_class * dc = to_class(kobj);
+ struct class_attribute * class_attr = to_class_attr(attr);
+ struct class * dc = to_class(kobj);
ssize_t ret = 0;
if (class_attr->show)
@@ -28,11 +28,11 @@ devclass_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
}
static ssize_t
-devclass_attr_store(struct kobject * kobj, struct attribute * attr,
- const char * buf, size_t count)
+class_attr_store(struct kobject * kobj, struct attribute * attr,
+ const char * buf, size_t count)
{
- struct devclass_attribute * class_attr = to_class_attr(attr);
- struct device_class * dc = to_class(kobj);
+ struct class_attribute * class_attr = to_class_attr(attr);
+ struct class * dc = to_class(kobj);
ssize_t ret = 0;
if (class_attr->store)
@@ -41,242 +41,376 @@ devclass_attr_store(struct kobject * kobj, struct attribute * attr,
}
static struct sysfs_ops class_sysfs_ops = {
- .show = devclass_attr_show,
- .store = devclass_attr_store,
+ .show = class_attr_show,
+ .store = class_attr_store,
};
-static struct kobj_type ktype_devclass = {
+static struct kobj_type ktype_class = {
.sysfs_ops = &class_sysfs_ops,
};
-/* Classes can't use the kobject hotplug logic, as
- * they do not add new kobjects to the system */
-static decl_subsys(class,&ktype_devclass,NULL);
+/* Hotplug events for classes go to the class_obj subsys */
+static decl_subsys(class,&ktype_class,NULL);
-static int devclass_dev_link(struct device_class * cls, struct device * dev)
+int class_create_file(struct class * cls, struct class_attribute * attr)
{
- char linkname[16];
- snprintf(linkname,16,"%u",dev->class_num);
- return sysfs_create_link(&cls->devices.kobj,&dev->kobj,linkname);
+ int error;
+ if (cls) {
+ error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
+ } else
+ error = -EINVAL;
+ return error;
}
-static void devclass_dev_unlink(struct device_class * cls, struct device * dev)
+void class_remove_file(struct class * cls, struct class_attribute * attr)
{
- char linkname[16];
- snprintf(linkname,16,"%u",dev->class_num);
- sysfs_remove_link(&cls->devices.kobj,linkname);
+ if (cls)
+ sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
}
-static int devclass_drv_link(struct device_driver * drv)
+struct class * class_get(struct class * cls)
{
- char name[KOBJ_NAME_LEN * 3];
- snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
- return sysfs_create_link(&drv->devclass->drivers.kobj,&drv->kobj,name);
+ if (cls)
+ return container_of(subsys_get(&cls->subsys),struct class,subsys);
+ return NULL;
}
-static void devclass_drv_unlink(struct device_driver * drv)
+void class_put(struct class * cls)
{
- char name[KOBJ_NAME_LEN * 3];
- snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
- return sysfs_remove_link(&drv->devclass->drivers.kobj,name);
+ subsys_put(&cls->subsys);
}
+int class_register(struct class * cls)
+{
+ pr_debug("device class '%s': registering\n",cls->name);
+
+ INIT_LIST_HEAD(&cls->children);
+ INIT_LIST_HEAD(&cls->interfaces);
+
+ strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
+ subsys_set_kset(cls,class_subsys);
+ subsystem_register(&cls->subsys);
+
+ return 0;
+}
-int devclass_create_file(struct device_class * cls, struct devclass_attribute * attr)
+void class_unregister(struct class * cls)
{
- int error;
- if (cls) {
- error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
- } else
- error = -EINVAL;
+ pr_debug("device class '%s': unregistering\n",cls->name);
+ subsystem_unregister(&cls->subsys);
+}
+
+/* Class Device Stuff */
+
+int class_device_create_file(struct class_device * class_dev,
+ struct class_device_attribute * attr)
+{
+ int error = -EINVAL;
+ if (class_dev)
+ error = sysfs_create_file(&class_dev->kobj, &attr->attr);
return error;
}
-void devclass_remove_file(struct device_class * cls, struct devclass_attribute * attr)
+void class_device_remove_file(struct class_device * class_dev,
+ struct class_device_attribute * attr)
{
- if (cls)
- sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
+ if (class_dev)
+ sysfs_remove_file(&class_dev->kobj, &attr->attr);
}
+static int class_device_dev_link(struct class_device * class_dev)
+{
+ if (class_dev->dev)
+ return sysfs_create_link(&class_dev->kobj,
+ &class_dev->dev->kobj, "device");
+ return 0;
+}
-int devclass_add_driver(struct device_driver * drv)
+static void class_device_dev_unlink(struct class_device * class_dev)
{
- struct device_class * cls = get_devclass(drv->devclass);
- int error = 0;
+ if (class_dev->dev)
+ sysfs_remove_link(&class_dev->kobj, "device");
+}
- if (cls) {
- down_write(&cls->subsys.rwsem);
- pr_debug("device class %s: adding driver %s:%s\n",
- cls->name,drv->bus->name,drv->name);
- error = devclass_drv_link(drv);
-
- if (!error)
- list_add_tail(&drv->class_list,&cls->drivers.list);
- up_write(&cls->subsys.rwsem);
- }
- return error;
+#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
+#define to_class_dev_attr(_attr) container_of(_attr,struct class_device_attribute,attr)
+
+static ssize_t
+class_device_attr_show(struct kobject * kobj, struct attribute * attr,
+ char * buf)
+{
+ struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
+ struct class_device * cd = to_class_dev(kobj);
+ ssize_t ret = 0;
+
+ if (class_dev_attr->show)
+ ret = class_dev_attr->show(cd,buf);
+ return ret;
}
-void devclass_remove_driver(struct device_driver * drv)
+static ssize_t
+class_device_attr_store(struct kobject * kobj, struct attribute * attr,
+ const char * buf, size_t count)
{
- struct device_class * cls = drv->devclass;
- if (cls) {
- down_write(&cls->subsys.rwsem);
- pr_debug("device class %s: removing driver %s:%s\n",
- cls->name,drv->bus->name,drv->name);
- list_del_init(&drv->class_list);
- devclass_drv_unlink(drv);
- up_write(&cls->subsys.rwsem);
- put_devclass(cls);
- }
+ struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
+ struct class_device * cd = to_class_dev(kobj);
+ ssize_t ret = 0;
+
+ if (class_dev_attr->store)
+ ret = class_dev_attr->store(cd,buf,count);
+ return ret;
}
+static struct sysfs_ops class_dev_sysfs_ops = {
+ .show = class_device_attr_show,
+ .store = class_device_attr_store,
+};
+
+static struct kobj_type ktype_class_device = {
+ .sysfs_ops = &class_dev_sysfs_ops,
+};
-static void enum_device(struct device_class * cls, struct device * dev)
+static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
- u32 val;
- val = cls->devnum++;
- dev->class_num = val;
- devclass_dev_link(cls,dev);
+ struct kobj_type *ktype = get_ktype(kobj);
+
+ if (ktype == &ktype_class_device) {
+ struct class_device *class_dev = to_class_dev(kobj);
+ if (class_dev->class)
+ return 1;
+ }
+ return 0;
}
-static void unenum_device(struct device_class * cls, struct device * dev)
+static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
{
- devclass_dev_unlink(cls,dev);
- dev->class_num = 0;
+ struct class_device *class_dev = to_class_dev(kobj);
+
+ return class_dev->class->name;
}
-/**
- * devclass_add_device - register device with device class
- * @dev: device to be registered
- *
- * This is called when a device is either registered with the
- * core, or after the a driver module is loaded and bound to
- * the device.
- * The class is determined by looking at @dev's driver, so one
- * way or another, it must be bound to something. Once the
- * class is determined, it's set to prevent against concurrent
- * calls for the same device stomping on each other.
- *
- * /sbin/hotplug should be called once the device is added to
- * class and all the interfaces.
- */
-int devclass_add_device(struct device * dev)
+static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+ int num_envp, char *buffer, int buffer_size)
{
- struct device_class * cls;
- int error = 0;
-
- down(&devclass_sem);
- if (dev->driver) {
- cls = get_devclass(dev->driver->devclass);
-
- if (!cls)
- goto Done;
-
- pr_debug("device class %s: adding device %s\n",
- cls->name,dev->name);
- if (cls->add_device)
- error = cls->add_device(dev);
- if (error) {
- put_devclass(cls);
- goto Done;
+ struct class_device *class_dev = to_class_dev(kobj);
+ int retval = 0;
+
+ pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
+ if (class_dev->class->hotplug) {
+ /* have the bus specific function add its stuff */
+ retval = class_dev->class->hotplug (class_dev, envp, num_envp,
+ buffer, buffer_size);
+ if (retval) {
+ pr_debug ("%s - hotplug() returned %d\n",
+ __FUNCTION__, retval);
}
+ }
- down_write(&cls->subsys.rwsem);
- enum_device(cls,dev);
- list_add_tail(&dev->class_list,&cls->devices.list);
- /* notify userspace (call /sbin/hotplug) */
- class_hotplug (dev, "add");
+ return retval;
+}
- up_write(&cls->subsys.rwsem);
+static struct kset_hotplug_ops class_hotplug_ops = {
+ .filter = class_hotplug_filter,
+ .name = class_hotplug_name,
+ .hotplug = class_hotplug,
+};
- interface_add_dev(dev);
- }
- Done:
- up(&devclass_sem);
- return error;
+static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
+
+void class_device_initialize(struct class_device *class_dev)
+{
+ kobject_init(&class_dev->kobj);
+ INIT_LIST_HEAD(&class_dev->node);
}
-void devclass_remove_device(struct device * dev)
+int class_device_add(struct class_device *class_dev)
{
- struct device_class * cls;
+ struct class * parent;
+ struct class_interface * class_intf;
+ struct list_head * entry;
+ int error;
- down(&devclass_sem);
- if (dev->driver) {
- cls = dev->driver->devclass;
- if (!cls)
- goto Done;
+ class_dev = class_device_get(class_dev);
+ if (!class_dev || !strlen(class_dev->class_id))
+ return -EINVAL;
+
+ parent = class_get(class_dev->class);
+ if (class_dev->dev)
+ get_device(class_dev->dev);
+
+ pr_debug("CLASS: registering class device: ID = '%s'\n",
+ class_dev->class_id);
+
+ /* first, register with generic layer. */
+ strncpy(class_dev->kobj.name, class_dev->class_id, KOBJ_NAME_LEN);
+ kobj_set_kset_s(class_dev, class_subsys);
+ kobj_set_kset_s(class_dev, class_obj_subsys);
+ if (parent)
+ class_dev->kobj.parent = &parent->subsys.kset.kobj;
+
+ if ((error = kobject_add(&class_dev->kobj)))
+ goto register_done;
+
+ /* now take care of our own registration */
+ if (parent) {
+ down_write(&parent->subsys.rwsem);
+ list_add_tail(&class_dev->node, &parent->children);
+ list_for_each(entry, &parent->interfaces) {
+ class_intf = container_of(entry, struct class_interface, node);
+ if (class_intf->add)
+ class_intf->add(class_dev);
+ }
+ up_write(&parent->subsys.rwsem);
+ }
- interface_remove_dev(dev);
+ class_device_dev_link(class_dev);
- down_write(&cls->subsys.rwsem);
- pr_debug("device class %s: removing device %s\n",
- cls->name,dev->name);
+ register_done:
+ if (error && parent)
+ class_put(parent);
+ class_device_put(class_dev);
+ return error;
+}
- unenum_device(cls,dev);
+int class_device_register(struct class_device *class_dev)
+{
+ class_device_initialize(class_dev);
+ return class_device_add(class_dev);
+}
- list_del(&dev->class_list);
+void class_device_del(struct class_device *class_dev)
+{
+ struct class * parent = class_dev->class;
+ struct class_interface * class_intf;
+ struct list_head * entry;
+
+ if (parent) {
+ down_write(&parent->subsys.rwsem);
+ list_del_init(&class_dev->node);
+ list_for_each(entry, &parent->interfaces) {
+ class_intf = container_of(entry, struct class_interface, node);
+ if (class_intf->remove)
+ class_intf->remove(class_dev);
+ }
+ up_write(&parent->subsys.rwsem);
+ }
- /* notify userspace (call /sbin/hotplug) */
- class_hotplug (dev, "remove");
+ if (class_dev->dev) {
+ class_device_dev_unlink(class_dev);
+ put_device(class_dev->dev);
+ }
+
+ kobject_del(&class_dev->kobj);
- up_write(&cls->subsys.rwsem);
+ if (parent)
+ class_put(parent);
+}
- if (cls->remove_device)
- cls->remove_device(dev);
- put_devclass(cls);
- }
- Done:
- up(&devclass_sem);
+void class_device_unregister(struct class_device *class_dev)
+{
+ pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
+ class_dev->class_id);
+ class_device_del(class_dev);
+ class_device_put(class_dev);
}
-struct device_class * get_devclass(struct device_class * cls)
+struct class_device * class_device_get(struct class_device *class_dev)
{
- return cls ? container_of(subsys_get(&cls->subsys),struct device_class,subsys) : NULL;
+ if (class_dev)
+ return to_class_dev(kobject_get(&class_dev->kobj));
+ return NULL;
}
-void put_devclass(struct device_class * cls)
+void class_device_put(struct class_device *class_dev)
{
- subsys_put(&cls->subsys);
+ kobject_put(&class_dev->kobj);
}
-int devclass_register(struct device_class * cls)
+int class_interface_register(struct class_interface *class_intf)
{
- pr_debug("device class '%s': registering\n",cls->name);
- strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
- subsys_set_kset(cls,class_subsys);
- subsystem_register(&cls->subsys);
+ struct class * parent;
+ struct class_device * class_dev;
+ struct list_head * entry;
+
+ if (!class_intf || !class_intf->class)
+ return -ENODEV;
+
+ parent = class_get(class_intf->class);
+ if (!parent)
+ return -EINVAL;
- snprintf(cls->devices.kobj.name,KOBJ_NAME_LEN,"devices");
- cls->devices.subsys = &cls->subsys;
- kset_register(&cls->devices);
+ down_write(&parent->subsys.rwsem);
+ list_add_tail(&class_intf->node, &parent->interfaces);
- snprintf(cls->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
- cls->drivers.subsys = &cls->subsys;
- kset_register(&cls->drivers);
+ if (class_intf->add) {
+ list_for_each(entry, &parent->children) {
+ class_dev = container_of(entry, struct class_device, node);
+ class_intf->add(class_dev);
+ }
+ }
+ up_write(&parent->subsys.rwsem);
return 0;
}
-void devclass_unregister(struct device_class * cls)
+void class_interface_unregister(struct class_interface *class_intf)
{
- pr_debug("device class '%s': unregistering\n",cls->name);
- kset_unregister(&cls->drivers);
- kset_unregister(&cls->devices);
- subsystem_unregister(&cls->subsys);
+ struct class * parent = class_intf->class;
+ struct list_head * entry;
+
+ if (!parent)
+ return;
+
+ down_write(&parent->subsys.rwsem);
+ list_del_init(&class_intf->node);
+
+ if (class_intf->remove) {
+ list_for_each(entry, &parent->children) {
+ struct class_device *class_dev = container_of(entry, struct class_device, node);
+ class_intf->remove(class_dev);
+ }
+ }
+ up_write(&parent->subsys.rwsem);
+
+ class_put(parent);
}
+
+
int __init classes_init(void)
{
- return subsystem_register(&class_subsys);
-}
+ int retval;
-EXPORT_SYMBOL(devclass_create_file);
-EXPORT_SYMBOL(devclass_remove_file);
-EXPORT_SYMBOL(devclass_register);
-EXPORT_SYMBOL(devclass_unregister);
-EXPORT_SYMBOL(get_devclass);
-EXPORT_SYMBOL(put_devclass);
+ retval = subsystem_register(&class_subsys);
+ if (retval)
+ return retval;
+
+ /* ick, this is ugly, the things we go through to keep from showing up
+ * in sysfs... */
+ subsystem_init(&class_obj_subsys);
+ if (!class_obj_subsys.kset.subsys)
+ class_obj_subsys.kset.subsys = &class_obj_subsys;
+ return 0;
+}
+EXPORT_SYMBOL(class_create_file);
+EXPORT_SYMBOL(class_remove_file);
+EXPORT_SYMBOL(class_register);
+EXPORT_SYMBOL(class_unregister);
+EXPORT_SYMBOL(class_get);
+EXPORT_SYMBOL(class_put);
+
+EXPORT_SYMBOL(class_device_register);
+EXPORT_SYMBOL(class_device_unregister);
+EXPORT_SYMBOL(class_device_initialize);
+EXPORT_SYMBOL(class_device_add);
+EXPORT_SYMBOL(class_device_del);
+EXPORT_SYMBOL(class_device_get);
+EXPORT_SYMBOL(class_device_put);
+EXPORT_SYMBOL(class_device_create_file);
+EXPORT_SYMBOL(class_device_remove_file);
+
+EXPORT_SYMBOL(class_interface_register);
+EXPORT_SYMBOL(class_interface_unregister);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0374b33562cd..8c34057ea3c3 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -185,7 +185,6 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->children);
INIT_LIST_HEAD(&dev->driver_list);
INIT_LIST_HEAD(&dev->bus_list);
- INIT_LIST_HEAD(&dev->class_list);
}
/**
@@ -235,7 +234,6 @@ int device_add(struct device *dev)
if (platform_notify)
platform_notify(dev);
- devclass_add_device(dev);
register_done:
if (error && parent)
put_device(parent);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index c843b73c66da..a7b123878ce4 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -82,7 +82,6 @@ void put_driver(struct device_driver * drv)
int driver_register(struct device_driver * drv)
{
INIT_LIST_HEAD(&drv->devices);
- INIT_LIST_HEAD(&drv->class_list);
init_MUTEX_LOCKED(&drv->unload_sem);
return bus_add_driver(drv);
}