From patchwork Thu Mar 2 13:48:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 9600275 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DF6D160414 for ; Thu, 2 Mar 2017 13:49:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D25D2284FE for ; Thu, 2 Mar 2017 13:49:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C573E28565; Thu, 2 Mar 2017 13:49:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A5CD284FE for ; Thu, 2 Mar 2017 13:49:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752480AbdCBNsn (ORCPT ); Thu, 2 Mar 2017 08:48:43 -0500 Received: from mga01.intel.com ([192.55.52.88]:44265 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752452AbdCBNsl (ORCPT ); Thu, 2 Mar 2017 08:48:41 -0500 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Mar 2017 05:48:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,231,1484035200"; d="scan'208";a="939818785" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga003.jf.intel.com with ESMTP; 02 Mar 2017 05:48:37 -0800 Received: by black.fi.intel.com (Postfix, from userid 1003) id 217C818D; Thu, 2 Mar 2017 15:48:05 +0200 (EET) From: Andy Shevchenko To: Linus Walleij , linux-gpio@vger.kernel.org, "Rafael J. Wysocki" , linux-acpi@vger.kernel.org, Mika Westerberg , linux-kernel@vger.kernel.org Cc: Andy Shevchenko Subject: [PATCH v1] gpio: acpi: Add managed variant of acpi_dev_add_driver_gpios() Date: Thu, 2 Mar 2017 15:48:05 +0200 Message-Id: <20170302134805.81705-1-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.11.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce device managed variant of acpi_dev_add_driver_gpios() and its counterpart acpi_dev_remove_driver_gpios(). The functions in most cases are used in driver's ->probe() and ->remove() callbacks, that's why it's useful to have managed variant of them. Signed-off-by: Andy Shevchenko --- This is supposed to go through GPIO tree. Linus, can you create an immutable branch that other subsystems can use it if needed? (We currently have one possible leak and devm_*() would help there) drivers/gpio/gpiolib-acpi.c | 31 +++++++++++++++++++++++++++++++ include/linux/acpi.h | 11 +++++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 1459e6183194..3fe63d8ed426 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -362,6 +362,37 @@ int acpi_dev_add_driver_gpios(struct acpi_device *adev, } EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios); +static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res) +{ + acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev)); +} + +int devm_acpi_dev_add_driver_gpios(struct device *dev, + const struct acpi_gpio_mapping *gpios) +{ + void *res; + int ret; + + res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL); + if (!res) + return -ENOMEM; + + ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios); + if (ret) { + devres_free(res); + return ret; + } + devres_add(dev, res); + return 0; +} +EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios); + +void devm_acpi_dev_remove_driver_gpios(struct device *dev) +{ + WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL)); +} +EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); + static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, struct acpi_reference_args *args) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 673acda012af..c8eaaad4a9ed 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -952,6 +952,10 @@ static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) adev->driver_gpios = NULL; } +int devm_acpi_dev_add_driver_gpios(struct device *dev, + const struct acpi_gpio_mapping *gpios); +void devm_acpi_dev_remove_driver_gpios(struct device *dev); + int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index); #else static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev, @@ -961,6 +965,13 @@ static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev, } static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {} +static inline int devm_acpi_dev_add_driver_gpios(struct device *dev, + const struct acpi_gpio_mapping *gpios) +{ + return -ENXIO; +} +static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {} + static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) { return -ENXIO;