Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

driver core: implement device_for_each_child_reverse()

The new function device_for_each_child_reverse() is helpful to traverse the
registered devices in a reversed order, e.g. in the case when an operation on
each device should be done first on the last added device, then on one before
last and so on.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Andy Shevchenko and committed by
Lee Jones
3d060aeb 2e0fed7f

+45
+43
drivers/base/core.c
··· 1252 1252 } 1253 1253 EXPORT_SYMBOL_GPL(device_unregister); 1254 1254 1255 + static struct device *prev_device(struct klist_iter *i) 1256 + { 1257 + struct klist_node *n = klist_prev(i); 1258 + struct device *dev = NULL; 1259 + struct device_private *p; 1260 + 1261 + if (n) { 1262 + p = to_device_private_parent(n); 1263 + dev = p->device; 1264 + } 1265 + return dev; 1266 + } 1267 + 1255 1268 static struct device *next_device(struct klist_iter *i) 1256 1269 { 1257 1270 struct klist_node *n = klist_next(i); ··· 1352 1339 return error; 1353 1340 } 1354 1341 EXPORT_SYMBOL_GPL(device_for_each_child); 1342 + 1343 + /** 1344 + * device_for_each_child_reverse - device child iterator in reversed order. 1345 + * @parent: parent struct device. 1346 + * @fn: function to be called for each device. 1347 + * @data: data for the callback. 1348 + * 1349 + * Iterate over @parent's child devices, and call @fn for each, 1350 + * passing it @data. 1351 + * 1352 + * We check the return of @fn each time. If it returns anything 1353 + * other than 0, we break out and return that value. 1354 + */ 1355 + int device_for_each_child_reverse(struct device *parent, void *data, 1356 + int (*fn)(struct device *dev, void *data)) 1357 + { 1358 + struct klist_iter i; 1359 + struct device *child; 1360 + int error = 0; 1361 + 1362 + if (!parent->p) 1363 + return 0; 1364 + 1365 + klist_iter_init(&parent->p->klist_children, &i); 1366 + while ((child = prev_device(&i)) && !error) 1367 + error = fn(child, data); 1368 + klist_iter_exit(&i); 1369 + return error; 1370 + } 1371 + EXPORT_SYMBOL_GPL(device_for_each_child_reverse); 1355 1372 1356 1373 /** 1357 1374 * device_find_child - device iterator for locating a particular device.
+2
include/linux/device.h
··· 958 958 extern void device_del(struct device *dev); 959 959 extern int device_for_each_child(struct device *dev, void *data, 960 960 int (*fn)(struct device *dev, void *data)); 961 + extern int device_for_each_child_reverse(struct device *dev, void *data, 962 + int (*fn)(struct device *dev, void *data)); 961 963 extern struct device *device_find_child(struct device *dev, void *data, 962 964 int (*match)(struct device *dev, void *data)); 963 965 extern int device_rename(struct device *dev, const char *new_name);