From patchwork Mon Feb 22 14:07:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laxman Dewangan X-Patchwork-Id: 586311 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id CFEDB140C9E for ; Tue, 23 Feb 2016 01:42:03 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755192AbcBVOVb (ORCPT ); Mon, 22 Feb 2016 09:21:31 -0500 Received: from hqemgate16.nvidia.com ([216.228.121.65]:13453 "EHLO hqemgate16.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753819AbcBVOV2 (ORCPT ); Mon, 22 Feb 2016 09:21:28 -0500 Received: from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by hqemgate16.nvidia.com id ; Mon, 22 Feb 2016 06:21:53 -0800 Received: from hqemhub03.nvidia.com ([172.20.150.15]) by hqnvupgp08.nvidia.com (PGP Universal service); Mon, 22 Feb 2016 06:21:24 -0800 X-PGP-Universal: processed; by hqnvupgp08.nvidia.com on Mon, 22 Feb 2016 06:21:24 -0800 Received: from ldewanganubuntu-System-Product-Name.nvidia.com (172.20.144.16) by hqemhub03.nvidia.com (172.20.150.15) with Microsoft SMTP Server (TLS) id 8.3.406.0; Mon, 22 Feb 2016 06:21:27 -0800 From: Laxman Dewangan To: , , , , , , , , , CC: , , , , , , , , , , , Subject: [PATCH 01/61] gpio: Add devm_ apis for gpiochip_add_data and gpiochip_remove Date: Mon, 22 Feb 2016 19:37:50 +0530 Message-ID: <1456150130-2668-2-git-send-email-ldewangan@nvidia.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1456150130-2668-1-git-send-email-ldewangan@nvidia.com> References: <1456150130-2668-1-git-send-email-ldewangan@nvidia.com> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add device managed APIs devm_gpiochip_add_data() and devm_gpiochip_remove() for the APIs gpiochip_add_data() and gpiochip_remove(). This helps in reducing code in error path and sometimes removal of .remove callback for driver unbind. Signed-off-by: Laxman Dewangan --- drivers/gpio/gpiolib.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/gpio/driver.h | 4 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5c1ba87..d9a40bc 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -462,6 +462,80 @@ void gpiochip_remove(struct gpio_chip *chip) } EXPORT_SYMBOL_GPL(gpiochip_remove); +static void devm_gpio_chip_release(struct device *dev, void *res) +{ + struct gpio_chip *chip = *(struct gpio_chip **)res; + + gpiochip_remove(chip); +} + +static int devm_gpio_chip_match(struct device *dev, void *res, void *data) + +{ + struct gpio_chip **r = res; + + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + + return *r == data; +} + +/** + * devm_gpiochip_add_data() - Resource manager piochip_add_data() + * @dev: the device pointer on which irq_chip belongs to. + * @chip: the chip to register, with chip->base initialized + * Context: potentially before irqs will work + * + * Returns a negative errno if the chip can't be registered, such as + * because the chip->base is invalid or already associated with a + * different chip. Otherwise it returns zero as a success code. + * + * The gpio chip automatically be released when the device is unbound. + */ +int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip, + void *data) +{ + struct gpio_chip **ptr; + int ret; + + ptr = devres_alloc(devm_gpio_chip_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = gpiochip_add_data(chip, data); + if (ret < 0) { + devres_free(ptr); + return ret; + } + + *ptr = chip; + devres_add(dev, ptr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_gpiochip_add_data); + +/** + * devm_gpiochip_remove() - Resource manager of gpiochip_remove() + * @dev: device for which which resource was allocated + * @chip: the chip to remove + * + * A gpio_chip with any GPIOs still requested may not be removed. + */ +void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip) +{ + int ret; + + ret = devres_release(dev, devm_gpio_chip_release, + devm_gpio_chip_match, chip); + if (!ret) + WARN_ON(ret); +} +EXPORT_SYMBOL_GPL(devm_gpiochip_remove); + /** * gpiochip_find() - iterator for locating a specific gpio_chip * @data: data to pass to match function diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 82fda48..d5d19cc 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -205,6 +205,10 @@ static inline int gpiochip_add(struct gpio_chip *chip) return gpiochip_add_data(chip, NULL); } extern void gpiochip_remove(struct gpio_chip *chip); +extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip, + void *data); +extern void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip); + extern struct gpio_chip *gpiochip_find(void *data, int (*match)(struct gpio_chip *chip, void *data));