提交 3d060aeb 编写于 作者: A Andy Shevchenko 提交者: Lee Jones

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: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLee Jones <lee.jones@linaro.org>
上级 2e0fed7f
...@@ -1252,6 +1252,19 @@ void device_unregister(struct device *dev) ...@@ -1252,6 +1252,19 @@ void device_unregister(struct device *dev)
} }
EXPORT_SYMBOL_GPL(device_unregister); EXPORT_SYMBOL_GPL(device_unregister);
static struct device *prev_device(struct klist_iter *i)
{
struct klist_node *n = klist_prev(i);
struct device *dev = NULL;
struct device_private *p;
if (n) {
p = to_device_private_parent(n);
dev = p->device;
}
return dev;
}
static struct device *next_device(struct klist_iter *i) static struct device *next_device(struct klist_iter *i)
{ {
struct klist_node *n = klist_next(i); struct klist_node *n = klist_next(i);
...@@ -1340,6 +1353,36 @@ int device_for_each_child(struct device *parent, void *data, ...@@ -1340,6 +1353,36 @@ int device_for_each_child(struct device *parent, void *data,
} }
EXPORT_SYMBOL_GPL(device_for_each_child); EXPORT_SYMBOL_GPL(device_for_each_child);
/**
* device_for_each_child_reverse - device child iterator in reversed order.
* @parent: parent struct device.
* @fn: function to be called for each device.
* @data: data for the callback.
*
* Iterate over @parent's child devices, and call @fn for each,
* passing it @data.
*
* We check the return of @fn each time. If it returns anything
* other than 0, we break out and return that value.
*/
int device_for_each_child_reverse(struct device *parent, void *data,
int (*fn)(struct device *dev, void *data))
{
struct klist_iter i;
struct device *child;
int error = 0;
if (!parent->p)
return 0;
klist_iter_init(&parent->p->klist_children, &i);
while ((child = prev_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
return error;
}
EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
/** /**
* device_find_child - device iterator for locating a particular device. * device_find_child - device iterator for locating a particular device.
* @parent: parent struct device * @parent: parent struct device
......
...@@ -958,6 +958,8 @@ extern int __must_check device_add(struct device *dev); ...@@ -958,6 +958,8 @@ extern int __must_check device_add(struct device *dev);
extern void device_del(struct device *dev); extern void device_del(struct device *dev);
extern int device_for_each_child(struct device *dev, void *data, extern int device_for_each_child(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data)); int (*fn)(struct device *dev, void *data));
extern int device_for_each_child_reverse(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
extern struct device *device_find_child(struct device *dev, void *data, extern struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data)); int (*match)(struct device *dev, void *data));
extern int device_rename(struct device *dev, const char *new_name); extern int device_rename(struct device *dev, const char *new_name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册