From patchwork Tue Nov 20 14:04:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1773841 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id AE862DF230 for ; Tue, 20 Nov 2012 14:07:24 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TaoS1-0008Ai-4R; Tue, 20 Nov 2012 14:05:21 +0000 Received: from eu1sys200aog111.obsmtp.com ([207.126.144.131]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1TaoRY-00084V-Aa for linux-arm-kernel@lists.infradead.org; Tue, 20 Nov 2012 14:04:55 +0000 Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob111.postini.com ([207.126.147.11]) with SMTP ID DSNKUKuN/VqEv7HCmnmY1YhTkUhneGztyA7n@postini.com; Tue, 20 Nov 2012 14:04:52 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 8BB6E4E; Tue, 20 Nov 2012 14:03:40 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 9E2ED61; Tue, 20 Nov 2012 09:11:15 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id DFA6524C2F4; Tue, 20 Nov 2012 15:04:08 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 20 Nov 2012 15:04:15 +0100 From: Linus Walleij To: , , Shiraz Hashim , Viresh Kumar Subject: [PATCH 1/7 v2] gpiolib: let gpiochip_add_pin_range() specify offset Date: Tue, 20 Nov 2012 15:04:09 +0100 Message-ID: <1353420249-17957-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121120_090452_945238_F82CD36F X-CRM114-Status: GOOD ( 18.58 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.131 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Anmar Oueja , Grant Likely , Linus Walleij , Stephen Warren X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Linus Walleij Like with commit 3c739ad0df5eb41cd7adad879eda6aa09879eb76 it is not always enough to specify all the pins of a gpio_chip from offset zero to be added to a pin map range, since the mapping from GPIO to pin controller may not be linear at all, but need to be broken into a few consecutive sub-ranges or 1-pin entries for complicated cases. The ranges may also be sparse. This alters the signature of the function to accept offsets into both the GPIO-chip local pinspace and the pin controller local pinspace. Signed-off-by: Linus Walleij Reviewed-by: Viresh Kumar Reviewed-by: Stephen Warren --- drivers/gpio/gpiolib.c | 32 +++++++++++++++++++++++++++++--- include/asm-generic/gpio.h | 6 ++++-- include/linux/gpio.h | 3 ++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c5f6500..6d13bea 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1187,24 +1187,45 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL +/** + * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping + * @chip: the gpiochip to add the range for + * @pinctrl_name: the dev_name() of the pin controller to map to + * @offset: the start offset in the current gpio_chip number space + * @pin_base: the start offset in the pin controller number space + * @npins: the number of pins from the offset of each pin space (GPIO and + * pin controller) to accumulate in this range + */ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { struct gpio_pin_range *pin_range; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); + pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); return -ENOMEM; } + /* Use local offset as range ID */ + pin_range->range.id = offset; + pin_range->range.gc = chip; pin_range->range.name = chip->label; - pin_range->range.base = chip->base; + pin_range->range.base = chip->base + offset; pin_range->range.pin_base = pin_base; pin_range->range.npins = npins; pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, &pin_range->range); + if (!pin_range->pctldev) { + pr_err("%s: GPIO chip: could not create pin range\n", + chip->label); + kfree(pin_range); + } + pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", + chip->label, offset, offset + npins - 1, + pin_base, pin_base + npins - 1); list_add_tail(&pin_range->node, &chip->pin_ranges); @@ -1212,6 +1233,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); +/** + * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings + * @chip: the chip to remove all the mappings for + */ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { struct gpio_pin_range *pin_range, *tmp; @@ -1220,6 +1245,7 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) list_del(&pin_range->node); pinctrl_remove_gpio_range(pin_range->pctldev, &pin_range->range); + kfree(pin_range); } } EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2b84fc3..ec58fdb 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -283,14 +283,16 @@ struct gpio_pin_range { }; int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); + unsigned int offset, unsigned int pin_base, + unsigned int npins); void gpiochip_remove_pin_ranges(struct gpio_chip *chip); #else static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { return 0; } diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 7ba2762..99861c6 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -233,7 +233,8 @@ static inline int irq_to_gpio(unsigned irq) static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { WARN_ON(1); return -EINVAL;