diff options
-rw-r--r-- | drivers/base/core.c | 33 | ||||
-rw-r--r-- | include/linux/device.h | 2 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 5d11bbdfbd2f..a29e68545462 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -750,12 +750,45 @@ int device_for_each_child(struct device * parent, void * data, | |||
750 | return error; | 750 | return error; |
751 | } | 751 | } |
752 | 752 | ||
753 | /** | ||
754 | * device_find_child - device iterator for locating a particular device. | ||
755 | * @parent: parent struct device | ||
756 | * @data: Data to pass to match function | ||
757 | * @match: Callback function to check device | ||
758 | * | ||
759 | * This is similar to the device_for_each_child() function above, but it | ||
760 | * returns a reference to a device that is 'found' for later use, as | ||
761 | * determined by the @match callback. | ||
762 | * | ||
763 | * The callback should return 0 if the device doesn't match and non-zero | ||
764 | * if it does. If the callback returns non-zero and a reference to the | ||
765 | * current device can be obtained, this function will return to the caller | ||
766 | * and not iterate over any more devices. | ||
767 | */ | ||
768 | struct device * device_find_child(struct device *parent, void *data, | ||
769 | int (*match)(struct device *, void *)) | ||
770 | { | ||
771 | struct klist_iter i; | ||
772 | struct device *child; | ||
773 | |||
774 | if (!parent) | ||
775 | return NULL; | ||
776 | |||
777 | klist_iter_init(&parent->klist_children, &i); | ||
778 | while ((child = next_device(&i))) | ||
779 | if (match(child, data) && get_device(child)) | ||
780 | break; | ||
781 | klist_iter_exit(&i); | ||
782 | return child; | ||
783 | } | ||
784 | |||
753 | int __init devices_init(void) | 785 | int __init devices_init(void) |
754 | { | 786 | { |
755 | return subsystem_register(&devices_subsys); | 787 | return subsystem_register(&devices_subsys); |
756 | } | 788 | } |
757 | 789 | ||
758 | EXPORT_SYMBOL_GPL(device_for_each_child); | 790 | EXPORT_SYMBOL_GPL(device_for_each_child); |
791 | EXPORT_SYMBOL_GPL(device_find_child); | ||
759 | 792 | ||
760 | EXPORT_SYMBOL_GPL(device_initialize); | 793 | EXPORT_SYMBOL_GPL(device_initialize); |
761 | EXPORT_SYMBOL_GPL(device_add); | 794 | EXPORT_SYMBOL_GPL(device_add); |
diff --git a/include/linux/device.h b/include/linux/device.h index 2d9dc358c027..0a0370c74181 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -421,6 +421,8 @@ extern int __must_check device_add(struct device * dev); | |||
421 | extern void device_del(struct device * dev); | 421 | extern void device_del(struct device * dev); |
422 | extern int device_for_each_child(struct device *, void *, | 422 | extern int device_for_each_child(struct device *, void *, |
423 | int (*fn)(struct device *, void *)); | 423 | int (*fn)(struct device *, void *)); |
424 | extern struct device *device_find_child(struct device *, void *data, | ||
425 | int (*match)(struct device *, void *)); | ||
424 | extern int device_rename(struct device *dev, char *new_name); | 426 | extern int device_rename(struct device *dev, char *new_name); |
425 | 427 | ||
426 | /* | 428 | /* |