From patchwork Fri Mar 29 02:44:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2363691 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by patchwork1.kernel.org (Postfix) with ESMTP id AB6253FD40 for ; Fri, 29 Mar 2013 02:58:55 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4F76FE71; Fri, 29 Mar 2013 02:48:10 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTP id 29781DD8 for ; Fri, 29 Mar 2013 02:47:56 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 1816D1F9A4 for ; Fri, 29 Mar 2013 02:47:53 +0000 (UTC) Received: from ayumi.akashicho.tokyo.vergenet.net (p8120-ipbfp1001kobeminato.hyogo.ocn.ne.jp [118.10.137.120]) by kirsty.vergenet.net (Postfix) with ESMTP id C76EE2C6A17; Fri, 29 Mar 2013 13:46:04 +1100 (EST) Received: by ayumi.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 68596EDEA2A; Fri, 29 Mar 2013 11:46:03 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Fri, 29 Mar 2013 11:44:48 +0900 Message-Id: <1364525119-31791-360-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> References: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Magnus Damm Subject: [LTSI-dev] [PATCH/RFC 359/390] devres: Add devres_release() X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org From: Mark Brown 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 Signed-off-by: Greg Kroah-Hartman (cherry picked from commit d926d0e4c74cfcb42a05e91d1cdf698b41e1e118) Signed-off-by: Simon Horman --- drivers/base/devres.c | 31 +++++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 524bf96..d948b96 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -326,6 +326,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) diff --git a/include/linux/device.h b/include/linux/device.h index e339929..5c7fdbd 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -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,