diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-03 13:15:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-04 19:33:16 -0400 |
commit | d926d0e4c74cfcb42a05e91d1cdf698b41e1e118 (patch) | |
tree | 9d7cdc794f6c56ef728c751759d8ef639ee6f38f /drivers/base/devres.c | |
parent | 698cd2ddd851b34e7200b4f846ae68306e11bae4 (diff) |
devres: Add devres_release()
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>
Diffstat (limited to 'drivers/base/devres.c')
-rw-r--r-- | drivers/base/devres.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 1741a60de117..2360adb7a58f 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -330,6 +330,37 @@ int devres_destroy(struct device *dev, dr_release_t release, | |||
330 | } | 330 | } |
331 | EXPORT_SYMBOL_GPL(devres_destroy); | 331 | EXPORT_SYMBOL_GPL(devres_destroy); |
332 | 332 | ||
333 | |||
334 | /** | ||
335 | * devres_release - Find a device resource and destroy it, calling release | ||
336 | * @dev: Device to find resource from | ||
337 | * @release: Look for resources associated with this release function | ||
338 | * @match: Match function (optional) | ||
339 | * @match_data: Data for the match function | ||
340 | * | ||
341 | * Find the latest devres of @dev associated with @release and for | ||
342 | * which @match returns 1. If @match is NULL, it's considered to | ||
343 | * match all. If found, the resource is removed atomically, the | ||
344 | * release function called and the resource freed. | ||
345 | * | ||
346 | * RETURNS: | ||
347 | * 0 if devres is found and freed, -ENOENT if not found. | ||
348 | */ | ||
349 | int devres_release(struct device *dev, dr_release_t release, | ||
350 | dr_match_t match, void *match_data) | ||
351 | { | ||
352 | void *res; | ||
353 | |||
354 | res = devres_remove(dev, release, match, match_data); | ||
355 | if (unlikely(!res)) | ||
356 | return -ENOENT; | ||
357 | |||
358 | (*release)(dev, res); | ||
359 | devres_free(res); | ||
360 | return 0; | ||
361 | } | ||
362 | EXPORT_SYMBOL_GPL(devres_release); | ||
363 | |||
333 | static int remove_nodes(struct device *dev, | 364 | static int remove_nodes(struct device *dev, |
334 | struct list_head *first, struct list_head *end, | 365 | struct list_head *first, struct list_head *end, |
335 | struct list_head *todo) | 366 | struct list_head *todo) |