]> Pileus Git - ~andy/linux/commitdiff
devres: Add devres_release()
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 3 May 2012 17:15:13 +0000 (18:15 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 May 2012 23:33:16 +0000 (16:33 -0700)
APIs using devres frequently want to implement a "remove and free the
resource" operation so it seems sensible that they should be able to
just have devres do the freeing for them since that's a big part of what
devres is all about.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/devres.c
include/linux/device.h

index 1741a60de117f6e2ce4c5462b33a3ab58b33ec15..2360adb7a58f0b924402169edba8936e1257ee3f 100644 (file)
@@ -330,6 +330,37 @@ int devres_destroy(struct device *dev, dr_release_t release,
 }
 EXPORT_SYMBOL_GPL(devres_destroy);
 
+
+/**
+ * devres_release - Find a device resource and destroy it, calling release
+ * @dev: Device to find resource from
+ * @release: Look for resources associated with this release function
+ * @match: Match function (optional)
+ * @match_data: Data for the match function
+ *
+ * Find the latest devres of @dev associated with @release and for
+ * which @match returns 1.  If @match is NULL, it's considered to
+ * match all.  If found, the resource is removed atomically, the
+ * release function called and the resource freed.
+ *
+ * RETURNS:
+ * 0 if devres is found and freed, -ENOENT if not found.
+ */
+int devres_release(struct device *dev, dr_release_t release,
+                  dr_match_t match, void *match_data)
+{
+       void *res;
+
+       res = devres_remove(dev, release, match, match_data);
+       if (unlikely(!res))
+               return -ENOENT;
+
+       (*release)(dev, res);
+       devres_free(res);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devres_release);
+
 static int remove_nodes(struct device *dev,
                        struct list_head *first, struct list_head *end,
                        struct list_head *todo)
index 3ab4d63609b6573f5576947e4dd5c66630627860..863acf8a0dcefe1f2487b0a87146ccee8ba9971f 100644 (file)
@@ -541,6 +541,8 @@ extern void *devres_remove(struct device *dev, dr_release_t release,
                           dr_match_t match, void *match_data);
 extern int devres_destroy(struct device *dev, dr_release_t release,
                          dr_match_t match, void *match_data);
+extern int devres_release(struct device *dev, dr_release_t release,
+                         dr_match_t match, void *match_data);
 
 /* devres group */
 extern void * __must_check devres_open_group(struct device *dev, void *id,