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>
This commit is contained in:
parent
2e0fed7f7c
commit
3d060aeb72
|
@ -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,
|
||||||
}
|
}
|
||||||
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);
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue