aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/devres.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2012-08-04 12:01:26 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-16 13:30:29 -0700
commitbddb1b9078505bb0e430c87c5015c0963f7a594f (patch)
treeef3d3a201dd23633d5c2dad8fb00be82a35f3023 /drivers/base/devres.c
parentfirmware loader: store firmware name into devres list (diff)
downloadlinux-dev-bddb1b9078505bb0e430c87c5015c0963f7a594f.tar.xz
linux-dev-bddb1b9078505bb0e430c87c5015c0963f7a594f.zip
driver core: devres: introduce devres_for_each_res
This patch introduces one devres API of devres_for_each_res so that the device's driver can iterate each resource it has interest in. The firmware loader will use the API to get each firmware name from the device instance. Signed-off-by: Ming Lei <ming.lei@canonical.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/devres.c')
-rw-r--r--drivers/base/devres.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 2360adb7a58f..8731979d668a 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -144,6 +144,48 @@ 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
*