From patchwork Tue Nov 6 15:17:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12695 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id BE0DE23F56 for ; Tue, 6 Nov 2012 15:17:37 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id 6DEFBA18132 for ; Tue, 6 Nov 2012 15:17:37 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so689619iej.11 for ; Tue, 06 Nov 2012 07:17:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=M0aT0a/SIG1J37997y/TZ8p6h1wFF1B7OHQxTloDYP0=; b=VSxeHFv1TkXJ4xiOchDaORvYO5DIBqcG7RPzQ0ArrkUCsiAhpMCc0L8blSSQIMCGlG 9G/sm+x7HNQXaRyYzWSeSPG7ya8gKs9M1Usgc3SwIagE6ANc2gCw0yyoMT6gVmtWFL/K TXkRfj8fJUWQpXAw5ckUCw4csyqBJW+5W96zXmbe/c0F7lsaiJ9OlAU3hc3W7NtzDccd kI80Kz2mFPb5JsspdACYfTdFy+L2BUou0HneOeFF2jK4ZOMpYBCdvCk0rNZfBJqZi6p4 grlGNtOporc+NDkb20NugC4So9KW+8j0bGESHQ5eqKwfaePXQTfxDo5aCfnLZn1gte+r fEOg== Received: by 10.50.40.166 with SMTP id y6mr1291000igk.57.1352215057218; Tue, 06 Nov 2012 07:17:37 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.67.148 with SMTP id n20csp58028igt; Tue, 6 Nov 2012 07:17:36 -0800 (PST) Received: by 10.14.203.132 with SMTP id f4mr4618290eeo.11.1352215055776; Tue, 06 Nov 2012 07:17:35 -0800 (PST) Received: from eu1sys200aog110.obsmtp.com (eu1sys200aog110.obsmtp.com [207.126.144.129]) by mx.google.com with SMTP id l45si429427eep.39.2012.11.06.07.17.20 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Nov 2012 07:17:35 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.129; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKUJkp/1gCKho6T6eGo6Fcf3mnzkcGTUY9@postini.com; Tue, 06 Nov 2012 15:17:33 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 4755AE6; Tue, 6 Nov 2012 15:08:58 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id E89EAA8B; Tue, 6 Nov 2012 15:17:11 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 9D70024C2F0; Tue, 6 Nov 2012 16:17:03 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 6 Nov 2012 16:17:10 +0100 From: Linus Walleij To: , , Shiraz Hashim , Viresh Kumar Cc: Stephen Warren , Anmar Oueja , Grant Likely , Linus Walleij Subject: [PATCH 5/5] gpiolib: separation of pin concerns Date: Tue, 6 Nov 2012 16:17:08 +0100 Message-ID: <1352215028-30381-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkaY//HDwir0DLcGHIA280YxOg1zkxkIdF7v/SsAXtyCq1CN+uI/tpPMXfO0mfz4F3WsQCE From: Linus Walleij The fact that of_gpiochip_add_pin_range() and gpiochip_add_pin_range() share too much code is fragile and will invariably mean that bugs need to be fixed in two places instead of one. So separate the concerns of gpiolib.c and gpiolib-of.c and have the latter call the former as back-end. This is necessary also when going forward with other device descriptions such as ACPI. This is done by: - Adding a return code to gpiochip_add_pin_range() so we can reliably check whether this succeeds. - Get rid of the custom of_pinctrl_add_gpio_range() from pinctrl. Instead create of_pinctrl_get() to just retrive the pin controller per se from an OF node. This composite function was just begging to be deleted, it was way to purpose-specific. - Use pinctrl_dev_get_name() to get the name of the retrieved pin controller and use that to call back into the generic gpiochip_add_pin_range(). Now the pin range is only allocated and tied to a pin controller from the core implementation in gpiolib.c. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 23 +++++++++-------------- drivers/gpio/gpiolib.c | 8 +++++--- drivers/pinctrl/devicetree.c | 4 +--- include/asm-generic/gpio.h | 4 ++-- include/linux/gpio.h | 2 +- include/linux/pinctrl/pinctrl.h | 7 ++----- 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 67403e4..a40cd84 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add); static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; - struct gpio_pin_range *pin_range; struct of_phandle_args pinspec; + struct pinctrl_dev *pctldev; int index = 0, ret; if (!np) @@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (ret) break; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), - GFP_KERNEL); - if (!pin_range) { - pr_err("%s: GPIO chip: failed to allocate pin ranges\n", - chip->label); + pctldev = of_pinctrl_get(pinspec.np); + if (!pctldev) break; - } - pin_range->range.name = chip->label; - pin_range->range.base = chip->base; - pin_range->range.pin_base = pinspec.args[0]; - pin_range->range.npins = pinspec.args[1]; - pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np, - &pin_range->range); + ret = gpiochip_add_pin_range(chip, + pinctrl_dev_get_name(pctldev), + pinspec.args[0], + pinspec.args[1]); - list_add_tail(&pin_range->node, &chip->pin_ranges); + if (ret) + break; } while (index++); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fd7280f..addbabb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1185,8 +1185,8 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) { struct gpio_pin_range *pin_range; @@ -1194,7 +1194,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); - return; + return -ENOMEM; } pin_range->range.name = chip->label; @@ -1205,6 +1205,8 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, &pin_range->range); list_add_tail(&pin_range->node, &chip->pin_ranges); + + return 0; } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 6728ec7..fe2d1af 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -106,8 +106,7 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) return NULL; } -struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range) +struct pinctrl_dev *of_pinctrl_get(struct device_node *np) { struct pinctrl_dev *pctldev; @@ -115,7 +114,6 @@ struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, if (!pctldev) return NULL; - pinctrl_add_gpio_range(pctldev, range); return pctldev; } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2e60de4..50d995e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -63,8 +63,8 @@ struct gpio_pin_range { struct pinctrl_gpio_range range; }; -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins); void gpiochip_remove_pin_ranges(struct gpio_chip *chip); #endif diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 21d28b9..81bbfe5 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -233,7 +233,7 @@ static inline int irq_to_gpio(unsigned irq) #ifdef CONFIG_PINCTRL -static inline void +static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int pin_base, unsigned int npins) { diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 434e5a9..4a58428 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -141,16 +141,13 @@ extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range); #ifdef CONFIG_OF -extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range); +extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); #else static inline -struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range) +struct pinctrl_dev *of_pinctrl_get(struct device_node *np) { return NULL; } - #endif /* CONFIG_OF */ extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);