aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2015-07-27 11:04:00 -0400
committerLee Jones <lee.jones@linaro.org>2015-07-28 03:50:42 -0400
commit3d060aeb72113cda0acf906bfe26914fc689506a (patch)
tree683028071415f9724d618e8a4f84124a10111a6d
parent2e0fed7f7cdc41679e209c5636ad7537dc6210a9 (diff)
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>
-rw-r--r--drivers/base/core.c43
-rw-r--r--include/linux/device.h2
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index dafae6d2f7ac..7d6279554afc 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1252,6 +1252,19 @@ void device_unregister(struct device *dev)
1252} 1252}
1253EXPORT_SYMBOL_GPL(device_unregister); 1253EXPORT_SYMBOL_GPL(device_unregister);
1254 1254
1255static 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
1255static struct device *next_device(struct klist_iter *i) 1268static struct device *next_device(struct klist_iter *i)
1256{ 1269{
1257 struct klist_node *n = klist_next(i); 1270 struct klist_node *n = klist_next(i);
@@ -1341,6 +1354,36 @@ int device_for_each_child(struct device *parent, void *data,
1341EXPORT_SYMBOL_GPL(device_for_each_child); 1354EXPORT_SYMBOL_GPL(device_for_each_child);
1342 1355
1343/** 1356/**
1357 * device_for_each_child_reverse - device child iterator in reversed order.
1358 * @parent: parent struct device.
1359 * @fn: function to be called for each device.
1360 * @data: data for the callback.
1361 *
1362 * Iterate over @parent's child devices, and call @fn for each,
1363 * passing it @data.
1364 *
1365 * We check the return of @fn each time. If it returns anything
1366 * other than 0, we break out and return that value.
1367 */
1368int device_for_each_child_reverse(struct device *parent, void *data,
1369 int (*fn)(struct device *dev, void *data))
1370{
1371 struct klist_iter i;
1372 struct device *child;
1373 int error = 0;
1374
1375 if (!parent->p)
1376 return 0;
1377
1378 klist_iter_init(&parent->p->klist_children, &i);
1379 while ((child = prev_device(&i)) && !error)
1380 error = fn(child, data);
1381 klist_iter_exit(&i);
1382 return error;
1383}
1384EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
1385
1386/**
1344 * device_find_child - device iterator for locating a particular device. 1387 * device_find_child - device iterator for locating a particular device.
1345 * @parent: parent struct device 1388 * @parent: parent struct device
1346 * @match: Callback function to check device 1389 * @match: Callback function to check device
diff --git a/include/linux/device.h b/include/linux/device.h
index 5a31bf3a4024..af6fbc35d8a6 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -958,6 +958,8 @@ extern int __must_check device_add(struct device *dev);
958extern void device_del(struct device *dev); 958extern void device_del(struct device *dev);
959extern int device_for_each_child(struct device *dev, void *data, 959extern int device_for_each_child(struct device *dev, void *data,
960 int (*fn)(struct device *dev, void *data)); 960 int (*fn)(struct device *dev, void *data));
961extern int device_for_each_child_reverse(struct device *dev, void *data,
962 int (*fn)(struct device *dev, void *data));
961extern struct device *device_find_child(struct device *dev, void *data, 963extern struct device *device_find_child(struct device *dev, void *data,
962 int (*match)(struct device *dev, void *data)); 964 int (*match)(struct device *dev, void *data));
963extern int device_rename(struct device *dev, const char *new_name); 965extern int device_rename(struct device *dev, const char *new_name);