]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/base/class.c
Driver Core: add ability for class_find_device to start in middle of list
[linux-2.6-omap-h63xx.git] / drivers / base / class.c
index e085af0ff94fb93007e7dce12f98443e4c5daa6d..3918d0e432d447565c6bfbfac09ab1d6db7e35c9 100644 (file)
@@ -148,6 +148,10 @@ int class_register(struct class *cls)
        if (error)
                return error;
 
+       /* set the default /sys/dev directory for devices of this class */
+       if (!cls->dev_kobj)
+               cls->dev_kobj = sysfs_dev_char_kobj;
+
 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
        /* let the block class directory show up in the root of sysfs */
        if (cls != &block_class)
@@ -252,11 +256,14 @@ char *make_class_name(const char *name, struct kobject *kobj)
 /**
  * class_for_each_device - device iterator
  * @class: the class we're iterating
+ * @start: the device to start with in the list, if any.
  * @data: data for the callback
  * @fn: function to be called for each device
  *
  * Iterate over @class's list of devices, and call @fn for each,
- * passing it @data.
+ * passing it @data.  If @start is set, the list iteration will start
+ * there, otherwise if it is NULL, the iteration starts at the
+ * beginning of the list.
  *
  * We check the return of @fn each time. If it returns anything
  * other than 0, we break out and return that value.
@@ -265,8 +272,8 @@ char *make_class_name(const char *name, struct kobject *kobj)
  * re-acquired in @fn, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-int class_for_each_device(struct class *class, void *data,
-                          int (*fn)(struct device *, void *))
+int class_for_each_device(struct class *class, struct device *start,
+                         void *data, int (*fn)(struct device *, void *))
 {
        struct device *dev;
        int error = 0;
@@ -275,12 +282,14 @@ int class_for_each_device(struct class *class, void *data,
                return -EINVAL;
        down(&class->sem);
        list_for_each_entry(dev, &class->devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       error = fn(dev, data);
-                       put_device(dev);
-               } else
-                       error = -ENODEV;
+               error = fn(dev, data);
+               put_device(dev);
                if (error)
                        break;
        }
@@ -293,6 +302,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
 /**
  * class_find_device - device iterator for locating a particular device
  * @class: the class we're iterating
+ * @start: Device to begin with
  * @data: data for the match function
  * @match: function to check device
  *
@@ -310,8 +320,9 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
  * re-acquired in @match, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-struct device *class_find_device(struct class *class, void *data,
-                                  int (*match)(struct device *, void *))
+struct device *class_find_device(struct class *class, struct device *start,
+                                void *data,
+                                int (*match)(struct device *, void *))
 {
        struct device *dev;
        int found = 0;
@@ -321,15 +332,17 @@ struct device *class_find_device(struct class *class, void *data,
 
        down(&class->sem);
        list_for_each_entry(dev, &class->devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       if (match(dev, data)) {
-                               found = 1;
-                               break;
-                       } else
-                               put_device(dev);
-               } else
+               if (match(dev, data)) {
+                       found = 1;
                        break;
+               } else
+                       put_device(dev);
        }
        up(&class->sem);