diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2008-05-22 17:21:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-22 00:54:47 -0400 |
commit | 93562b537659fc0f63920fd4d9d24f54e434f4c4 (patch) | |
tree | 6b7678f91af838f0c1fb85105b68b6c7f7e027e0 | |
parent | 4e10673944a5c386378ff9d692ae37e19993f9d5 (diff) |
Driver Core: add ability for class_for_each_device to start in middle of list
This mirrors the functionality that driver_for_each_device has as well.
We add a start variable, and all callers of the function are fixed up at
the same time.
The block layer will be using this new functionality in a follow-on
patch.
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/base/class.c | 21 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 6 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 14 | ||||
-rw-r--r-- | drivers/power/apm_power.c | 2 | ||||
-rw-r--r-- | drivers/power/power_supply_core.c | 4 | ||||
-rw-r--r-- | include/linux/device.h | 3 |
6 files changed, 31 insertions, 19 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 71ce3ff6bdf5..2eb7048003a8 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -256,11 +256,14 @@ char *make_class_name(const char *name, struct kobject *kobj) | |||
256 | /** | 256 | /** |
257 | * class_for_each_device - device iterator | 257 | * class_for_each_device - device iterator |
258 | * @class: the class we're iterating | 258 | * @class: the class we're iterating |
259 | * @start: the device to start with in the list, if any. | ||
259 | * @data: data for the callback | 260 | * @data: data for the callback |
260 | * @fn: function to be called for each device | 261 | * @fn: function to be called for each device |
261 | * | 262 | * |
262 | * Iterate over @class's list of devices, and call @fn for each, | 263 | * Iterate over @class's list of devices, and call @fn for each, |
263 | * passing it @data. | 264 | * passing it @data. If @start is set, the list iteration will start |
265 | * there, otherwise if it is NULL, the iteration starts at the | ||
266 | * beginning of the list. | ||
264 | * | 267 | * |
265 | * We check the return of @fn each time. If it returns anything | 268 | * We check the return of @fn each time. If it returns anything |
266 | * other than 0, we break out and return that value. | 269 | * other than 0, we break out and return that value. |
@@ -269,8 +272,8 @@ char *make_class_name(const char *name, struct kobject *kobj) | |||
269 | * re-acquired in @fn, otherwise it will self-deadlocking. For | 272 | * re-acquired in @fn, otherwise it will self-deadlocking. For |
270 | * example, calls to add or remove class members would be verboten. | 273 | * example, calls to add or remove class members would be verboten. |
271 | */ | 274 | */ |
272 | int class_for_each_device(struct class *class, void *data, | 275 | int class_for_each_device(struct class *class, struct device *start, |
273 | int (*fn)(struct device *, void *)) | 276 | void *data, int (*fn)(struct device *, void *)) |
274 | { | 277 | { |
275 | struct device *dev; | 278 | struct device *dev; |
276 | int error = 0; | 279 | int error = 0; |
@@ -279,12 +282,14 @@ int class_for_each_device(struct class *class, void *data, | |||
279 | return -EINVAL; | 282 | return -EINVAL; |
280 | down(&class->sem); | 283 | down(&class->sem); |
281 | list_for_each_entry(dev, &class->devices, node) { | 284 | list_for_each_entry(dev, &class->devices, node) { |
285 | if (start) { | ||
286 | if (start == dev) | ||
287 | start = NULL; | ||
288 | continue; | ||
289 | } | ||
282 | dev = get_device(dev); | 290 | dev = get_device(dev); |
283 | if (dev) { | 291 | error = fn(dev, data); |
284 | error = fn(dev, data); | 292 | put_device(dev); |
285 | put_device(dev); | ||
286 | } else | ||
287 | error = -ENODEV; | ||
288 | if (error) | 293 | if (error) |
289 | break; | 294 | break; |
290 | } | 295 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 7608df83d6d1..7bf38c418086 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -722,7 +722,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
722 | 722 | ||
723 | INIT_LIST_HEAD(&driver->clients); | 723 | INIT_LIST_HEAD(&driver->clients); |
724 | /* Walk the adapters that are already present */ | 724 | /* Walk the adapters that are already present */ |
725 | class_for_each_device(&i2c_adapter_class, driver, __attach_adapter); | 725 | class_for_each_device(&i2c_adapter_class, NULL, driver, |
726 | __attach_adapter); | ||
726 | 727 | ||
727 | mutex_unlock(&core_lock); | 728 | mutex_unlock(&core_lock); |
728 | return 0; | 729 | return 0; |
@@ -782,7 +783,8 @@ void i2c_del_driver(struct i2c_driver *driver) | |||
782 | { | 783 | { |
783 | mutex_lock(&core_lock); | 784 | mutex_lock(&core_lock); |
784 | 785 | ||
785 | class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); | 786 | class_for_each_device(&i2c_adapter_class, NULL, driver, |
787 | __detach_adapter); | ||
786 | 788 | ||
787 | driver_unregister(&driver->driver); | 789 | driver_unregister(&driver->driver); |
788 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | 790 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 05710c7c1220..47c0d85e0f32 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -1453,7 +1453,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1453 | ne->in_limbo = 1; | 1453 | ne->in_limbo = 1; |
1454 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); | 1454 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1455 | 1455 | ||
1456 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend); | 1456 | class_for_each_device(&nodemgr_ud_class, NULL, ne, |
1457 | __nodemgr_driver_suspend); | ||
1457 | } | 1458 | } |
1458 | 1459 | ||
1459 | 1460 | ||
@@ -1462,7 +1463,8 @@ static void nodemgr_resume_ne(struct node_entry *ne) | |||
1462 | ne->in_limbo = 0; | 1463 | ne->in_limbo = 0; |
1463 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | 1464 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); |
1464 | 1465 | ||
1465 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume); | 1466 | class_for_each_device(&nodemgr_ud_class, NULL, ne, |
1467 | __nodemgr_driver_resume); | ||
1466 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1468 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1467 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1469 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
1468 | } | 1470 | } |
@@ -1498,7 +1500,8 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data) | |||
1498 | 1500 | ||
1499 | static void nodemgr_update_pdrv(struct node_entry *ne) | 1501 | static void nodemgr_update_pdrv(struct node_entry *ne) |
1500 | { | 1502 | { |
1501 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv); | 1503 | class_for_each_device(&nodemgr_ud_class, NULL, ne, |
1504 | __nodemgr_update_pdrv); | ||
1502 | } | 1505 | } |
1503 | 1506 | ||
1504 | 1507 | ||
@@ -1591,7 +1594,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1591 | * while probes are time-consuming. (Well, those probes need some | 1594 | * while probes are time-consuming. (Well, those probes need some |
1592 | * improvement...) */ | 1595 | * improvement...) */ |
1593 | 1596 | ||
1594 | class_for_each_device(&nodemgr_ne_class, ¶m, __nodemgr_node_probe); | 1597 | class_for_each_device(&nodemgr_ne_class, NULL, ¶m, |
1598 | __nodemgr_node_probe); | ||
1595 | 1599 | ||
1596 | /* If we had a bus reset while we were scanning the bus, it is | 1600 | /* If we had a bus reset while we were scanning the bus, it is |
1597 | * possible that we did not probe all nodes. In that case, we | 1601 | * possible that we did not probe all nodes. In that case, we |
@@ -1826,7 +1830,7 @@ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) | |||
1826 | 1830 | ||
1827 | hip.cb = cb; | 1831 | hip.cb = cb; |
1828 | hip.data = data; | 1832 | hip.data = data; |
1829 | error = class_for_each_device(&hpsb_host_class, &hip, | 1833 | error = class_for_each_device(&hpsb_host_class, NULL, &hip, |
1830 | __nodemgr_for_each_host); | 1834 | __nodemgr_for_each_host); |
1831 | 1835 | ||
1832 | return error; | 1836 | return error; |
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index a4892275659d..936bae560fa1 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c | |||
@@ -78,7 +78,7 @@ static void find_main_battery(void) | |||
78 | main_battery = NULL; | 78 | main_battery = NULL; |
79 | bp.main = main_battery; | 79 | bp.main = main_battery; |
80 | 80 | ||
81 | error = class_for_each_device(power_supply_class, &bp, | 81 | error = class_for_each_device(power_supply_class, NULL, &bp, |
82 | __find_main_battery); | 82 | __find_main_battery); |
83 | if (error) { | 83 | if (error) { |
84 | main_battery = bp.main; | 84 | main_battery = bp.main; |
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index af1633eb3b70..cb1ccb472921 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -41,7 +41,7 @@ static void power_supply_changed_work(struct work_struct *work) | |||
41 | 41 | ||
42 | dev_dbg(psy->dev, "%s\n", __func__); | 42 | dev_dbg(psy->dev, "%s\n", __func__); |
43 | 43 | ||
44 | class_for_each_device(power_supply_class, psy, | 44 | class_for_each_device(power_supply_class, NULL, psy, |
45 | __power_supply_changed_work); | 45 | __power_supply_changed_work); |
46 | 46 | ||
47 | power_supply_update_leds(psy); | 47 | power_supply_update_leds(psy); |
@@ -79,7 +79,7 @@ int power_supply_am_i_supplied(struct power_supply *psy) | |||
79 | { | 79 | { |
80 | int error; | 80 | int error; |
81 | 81 | ||
82 | error = class_for_each_device(power_supply_class, psy, | 82 | error = class_for_each_device(power_supply_class, NULL, psy, |
83 | __power_supply_am_i_supplied); | 83 | __power_supply_am_i_supplied); |
84 | 84 | ||
85 | dev_dbg(psy->dev, "%s %d\n", __func__, error); | 85 | dev_dbg(psy->dev, "%s %d\n", __func__, error); |
diff --git a/include/linux/device.h b/include/linux/device.h index de178712e02c..6d5b351b29c9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -210,7 +210,8 @@ extern struct kobject *sysfs_dev_block_kobj; | |||
210 | extern struct kobject *sysfs_dev_char_kobj; | 210 | extern struct kobject *sysfs_dev_char_kobj; |
211 | extern int __must_check class_register(struct class *class); | 211 | extern int __must_check class_register(struct class *class); |
212 | extern void class_unregister(struct class *class); | 212 | extern void class_unregister(struct class *class); |
213 | extern int class_for_each_device(struct class *class, void *data, | 213 | extern int class_for_each_device(struct class *class, struct device *start, |
214 | void *data, | ||
214 | int (*fn)(struct device *dev, void *data)); | 215 | int (*fn)(struct device *dev, void *data)); |
215 | extern struct device *class_find_device(struct class *class, void *data, | 216 | extern struct device *class_find_device(struct class *class, void *data, |
216 | int (*match)(struct device *, void *)); | 217 | int (*match)(struct device *, void *)); |