From cbcd075ba578be1932d03eedb9b4656f86a27308 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sat, 4 Aug 2012 12:01:26 +0800 Subject: [PATCH] --- yaml --- r: 324375 b: refs/heads/master c: bddb1b9078505bb0e430c87c5015c0963f7a594f h: refs/heads/master i: 324373: 03c2dc0ec31661e03ea619d736ed2afae13e6965 324371: b1fb9fbc26e040218947c1ff0918e83eeab015b2 324367: ad30f796befacca603659e9f4fe3256893e8641a v: v3 --- [refs] | 2 +- trunk/drivers/base/devres.c | 42 ++++++++++++++++++++++++++++++++++++ trunk/include/linux/device.h | 4 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 4a4284e86b59..6276473204dd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f531f05ae9437df5ba1ebd90017e4dd5526048e9 +refs/heads/master: bddb1b9078505bb0e430c87c5015c0963f7a594f diff --git a/trunk/drivers/base/devres.c b/trunk/drivers/base/devres.c index 2360adb7a58f..8731979d668a 100644 --- a/trunk/drivers/base/devres.c +++ b/trunk/drivers/base/devres.c @@ -143,6 +143,48 @@ void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp) EXPORT_SYMBOL_GPL(devres_alloc); #endif +/** + * devres_for_each_res - Resource iterator + * @dev: Device to iterate resource from + * @release: Look for resources associated with this release function + * @match: Match function (optional) + * @match_data: Data for the match function + * @fn: Function to be called for each matched resource. + * @data: Data for @fn, the 3rd parameter of @fn + * + * Call @fn for each devres of @dev which is associated with @release + * and for which @match returns 1. + * + * RETURNS: + * void + */ +void devres_for_each_res(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data, + void (*fn)(struct device *, void *, void *), + void *data) +{ + struct devres_node *node; + struct devres_node *tmp; + unsigned long flags; + + if (!fn) + return; + + spin_lock_irqsave(&dev->devres_lock, flags); + list_for_each_entry_safe_reverse(node, tmp, + &dev->devres_head, entry) { + struct devres *dr = container_of(node, struct devres, node); + + if (node->release != release) + continue; + if (match && !match(dev, dr->data, match_data)) + continue; + fn(dev, dr->data, data); + } + spin_unlock_irqrestore(&dev->devres_lock, flags); +} +EXPORT_SYMBOL_GPL(devres_for_each_res); + /** * devres_free - Free device resource data * @res: Pointer to devres data to free diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 52a5f15a2223..ecd900663726 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -536,6 +536,10 @@ extern void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp, #else extern void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp); #endif +extern void devres_for_each_res(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data, + void (*fn)(struct device *, void *, void *), + void *data); extern void devres_free(void *res); extern void devres_add(struct device *dev, void *res); extern void *devres_find(struct device *dev, dr_release_t release,