]> git.neil.brown.name Git - history.git/commitdiff
driver model: make classes and interfaces use kobject infrastructure.
authorPatrick Mochel <mochel@osdl.org>
Wed, 20 Nov 2002 15:05:27 +0000 (09:05 -0600)
committerPatrick Mochel <mochel@osdl.org>
Wed, 20 Nov 2002 15:05:27 +0000 (09:05 -0600)
Like the other objects, this allows a decent bit of cleanup. Details include:

- use rwsem in subsytem, instead of one in struct device_class.

- use refcount in struct kobject, instead of one in struct device_class.

- kill class's present flag.

- kill class_list, since we can just use class_subsys's.

- make interfaces instances of their class's subsystem. This allows us to
kill struct device_class::intf_list, and struct device_interface::node.

drivers/base/class.c
drivers/base/intf.c
include/linux/device.h

index 4e7397905841a4c5d4ed21e08e782c0468311336..fbc6326312d85dec8a18c6da962d835430113ca8 100644 (file)
@@ -2,6 +2,8 @@
  * class.c - basic device class management
  */
 
+#undef DEBUG
+
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -101,12 +103,12 @@ int devclass_add_driver(struct device_driver * drv)
 {
        struct device_class * cls = get_devclass(drv->devclass);
        if (cls) {
-               down_write(&cls->rwsem);
+               down_write(&cls->subsys.rwsem);
                pr_debug("device class %s: adding driver %s:%s\n",
                         cls->name,drv->bus->name,drv->name);
                list_add_tail(&drv->class_list,&cls->drivers);
                devclass_drv_link(drv);
-               up_write(&cls->rwsem);
+               up_write(&cls->subsys.rwsem);
        }
        return 0;
 }
@@ -115,12 +117,12 @@ void devclass_remove_driver(struct device_driver * drv)
 {
        struct device_class * cls = drv->devclass;
        if (cls) {
-               down_write(&cls->rwsem);
+               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->rwsem);
+               up_write(&cls->subsys.rwsem);
                put_devclass(cls);
        }
 }
@@ -163,7 +165,7 @@ int devclass_add_device(struct device * dev)
        if (dev->driver) {
                cls = get_devclass(dev->driver->devclass);
                if (cls) {
-                       down_write(&cls->rwsem);
+                       down_write(&cls->subsys.rwsem);
                        pr_debug("device class %s: adding device %s\n",
                                 cls->name,dev->name);
                        if (cls->add_device) 
@@ -176,7 +178,7 @@ int devclass_add_device(struct device * dev)
                        /* notify userspace (call /sbin/hotplug) */
                        class_hotplug (dev, "add");
 
-                       up_write(&cls->rwsem);
+                       up_write(&cls->subsys.rwsem);
                        if (error)
                                put_devclass(cls);
                }
@@ -191,7 +193,7 @@ void devclass_remove_device(struct device * dev)
        if (dev->driver) {
                cls = dev->driver->devclass;
                if (cls) {
-                       down_write(&cls->rwsem);
+                       down_write(&cls->subsys.rwsem);
                        pr_debug("device class %s: removing device %s\n",
                                 cls->name,dev->name);
                        interface_remove(cls,dev);
@@ -202,7 +204,7 @@ void devclass_remove_device(struct device * dev)
 
                        if (cls->remove_device)
                                cls->remove_device(dev);
-                       up_write(&cls->rwsem);
+                       up_write(&cls->subsys.rwsem);
                        put_devclass(cls);
                }
        }
@@ -210,34 +212,20 @@ void devclass_remove_device(struct device * dev)
 
 struct device_class * get_devclass(struct device_class * cls)
 {
-       struct device_class * ret = cls;
-       spin_lock(&device_lock);
-       if (cls && cls->present && atomic_read(&cls->refcount) > 0)
-               atomic_inc(&cls->refcount);
-       else
-               ret = NULL;
-       spin_unlock(&device_lock);
-       return ret;
+       return cls ? container_of(subsys_get(&cls->subsys),struct device_class,subsys) : NULL;
 }
 
 void put_devclass(struct device_class * cls)
 {
-       if (atomic_dec_and_lock(&cls->refcount,&device_lock)) {
-               list_del_init(&cls->node);
-               spin_unlock(&device_lock);
-       }
+       subsys_put(&cls->subsys);
 }
 
 
 int devclass_register(struct device_class * cls)
 {
        INIT_LIST_HEAD(&cls->drivers);
-       INIT_LIST_HEAD(&cls->intf_list);
-       init_rwsem(&cls->rwsem);
-       atomic_set(&cls->refcount,2);
-       cls->present = 1;
-       pr_debug("device class '%s': registering\n",cls->name);
 
+       pr_debug("device class '%s': registering\n",cls->name);
        strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN);
        cls->subsys.parent = &class_subsys;
        subsystem_register(&cls->subsys);
@@ -250,23 +238,15 @@ int devclass_register(struct device_class * cls)
        cls->drvsubsys.parent = &cls->subsys;
        subsystem_register(&cls->drvsubsys);
 
-       spin_lock(&device_lock);
-       list_add_tail(&cls->node,&class_list);
-       spin_unlock(&device_lock);
-       put_devclass(cls);
        return 0;
 }
 
 void devclass_unregister(struct device_class * cls)
 {
-       spin_lock(&device_lock);
-       cls->present = 0;
-       spin_unlock(&device_lock);
        pr_debug("device class '%s': unregistering\n",cls->name);
        subsystem_unregister(&cls->drvsubsys);
        subsystem_unregister(&cls->devsubsys);
        subsystem_unregister(&cls->subsys);
-       put_devclass(cls);
 }
 
 static int __init class_subsys_init(void)
@@ -276,6 +256,8 @@ static int __init class_subsys_init(void)
 
 core_initcall(class_subsys_init);
 
+EXPORT_SYMBOL(devclass_create_file);
+EXPORT_SYMBOL(devclass_remove_file);
 EXPORT_SYMBOL(devclass_register);
 EXPORT_SYMBOL(devclass_unregister);
 EXPORT_SYMBOL(get_devclass);
index e9eb94a2bed5884a715df6708365b20b96e1600b..d31ad38bf3d2eeaea379d3eaff48ac9b820c1a1f 100644 (file)
@@ -10,7 +10,7 @@
 #include "base.h"
 
 
-#define to_intf(node) container_of(node,struct device_interface,node)
+#define to_intf(node) container_of(node,struct device_interface,kobj.entry)
 
 /**
  * intf_dev_link - symlink from interface's directory to device's directory
@@ -34,22 +34,18 @@ static void intf_dev_unlink(struct intf_data * data)
 
 int interface_register(struct device_interface * intf)
 {
-       struct device_class * cls = intf->devclass;
+       struct device_class * cls = get_devclass(intf->devclass);
+       int error = 0;
 
        if (cls) {
                pr_debug("register interface '%s' with class '%s'\n",
                         intf->name,cls->name);
-               kobject_init(&intf->kobj);
                strncpy(intf->kobj.name,intf->name,KOBJ_NAME_LEN);
                intf->kobj.subsys = &cls->subsys;
                kobject_register(&intf->kobj);
-
-               spin_lock(&device_lock);
-               list_add_tail(&intf->node,&cls->intf_list);
-               spin_unlock(&device_lock);
-               return 0;
-       }
-       return -EINVAL;
+       } else
+               error = -EINVAL;
+       return error;
 }
 
 void interface_unregister(struct device_interface * intf)
@@ -57,9 +53,6 @@ void interface_unregister(struct device_interface * intf)
        pr_debug("unregistering interface '%s' from class '%s'\n",
                 intf->name,intf->devclass->name);
        kobject_unregister(&intf->kobj);
-       spin_lock(&device_lock);
-       list_del_init(&intf->node);
-       spin_unlock(&device_lock);
 }
 
 int interface_add(struct device_class * cls, struct device * dev)
@@ -69,7 +62,7 @@ int interface_add(struct device_class * cls, struct device * dev)
 
        pr_debug("adding '%s' to %s class interfaces\n",dev->name,cls->name);
 
-       list_for_each(node,&cls->intf_list) {
+       list_for_each(node,&cls->subsys.list) {
                struct device_interface * intf = to_intf(node);
                if (intf->add_device) {
                        error = intf->add_device(dev);
@@ -89,30 +82,25 @@ void interface_remove(struct device_class * cls, struct device * dev)
 
        pr_debug("remove '%s' from %s class interfaces: ",dev->name,cls->name);
 
-       spin_lock(&device_lock);
        list_for_each_safe(node,next,&dev->intf_list) {
                struct intf_data * intf_data = container_of(node,struct intf_data,node);
                list_del_init(&intf_data->node);
-               spin_unlock(&device_lock);
 
                intf_dev_unlink(intf_data);
                pr_debug("%s ",intf_data->intf->name);
                if (intf_data->intf->remove_device)
                        intf_data->intf->remove_device(intf_data);
-
-               spin_lock(&device_lock);
        }
-       spin_unlock(&device_lock);
        pr_debug("\n");
 }
 
 int interface_add_data(struct intf_data * data)
 {
-       spin_lock(&device_lock);
+       down_write(&data->intf->devclass->subsys.rwsem);
        list_add_tail(&data->node,&data->dev->intf_list);
-       data->intf_num = ++data->intf->devnum;
-       spin_unlock(&device_lock);
+       data->intf_num = data->intf->devnum++;
        intf_dev_link(data);
+       up_write(&data->intf->devclass->subsys.rwsem);
        return 0;
 }
 
index f995ac22714082f3584be7610e724f91ddc7aaf5..a88c4c7a3433f34da8d1f954ec12156d1a4dbf1b 100644 (file)
@@ -153,19 +153,12 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
  */
 struct device_class {
        char                    * name;
-       struct rw_semaphore     rwsem;
-
-       atomic_t                refcount;
-       u32                     present;
-
        u32                     devnum;
 
        struct subsystem        subsys;
        struct subsystem        devsubsys;
        struct subsystem        drvsubsys;
-       struct list_head        node;
        struct list_head        drivers;
-       struct list_head        intf_list;
 
        int     (*add_device)(struct device *);
        void    (*remove_device)(struct device *);
@@ -215,7 +208,6 @@ struct device_interface {
        struct device_class     * devclass;
 
        struct kobject          kobj;
-       struct list_head        node;
        struct list_head        devices;
 
        u32                     devnum;