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: 13000 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 C1DFD23FC0 for ; Tue, 20 Nov 2012 14:04:54 +0000 (UTC) Received: from mail-ia0-f180.google.com (mail-ia0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 49CB8A182F9 for ; Tue, 20 Nov 2012 14:04:54 +0000 (UTC) Received: by mail-ia0-f180.google.com with SMTP id t4so1718480iag.11 for ; Tue, 20 Nov 2012 06:04:53 -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=wPctosCZEb3aDKcsp3o4GvNgkWf7lsmGmV+m8t46kmw=; b=EB5t5wofrY2cF72LyamZ28bsMbQCCLC/w4efcWiLCgjK1w3re9jE7+4zHV2MYtHIaP CWATPc+q7rED26ZNyRlatZK3C0dBOih5dLyXlsIRl8DW3HP0MnpX9o5AiClH+YrGgGKA xBCv+YJ4mjTKnCilT/Jp850iHxrqfTKOtdQfVgYTjTF/EfspNOEmfGcUFXaNdf4eTH38 cH8vbfm8cIuA4OFu8PUSxL9oS54sMQZ5lN1G9XgLsz4T4k/vs7QEKQUv0nvdeeU1k4FD 7wduB2qRMRetKvzwNu+vCFCFkL+yDznopYkSZ6YVffTJKdD+8mxoy9BtK9ROGWvxNFfe HlKg== Received: by 10.50.187.197 with SMTP id fu5mr9934128igc.70.1353420293644; Tue, 20 Nov 2012 06:04:53 -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 n20csp322299igt; Tue, 20 Nov 2012 06:04:52 -0800 (PST) Received: by 10.14.216.193 with SMTP id g41mr34650003eep.37.1353420292285; Tue, 20 Nov 2012 06:04:52 -0800 (PST) Received: from eu1sys200aog111.obsmtp.com (eu1sys200aog111.obsmtp.com [207.126.144.131]) by mx.google.com with SMTP id i42si14877772eem.136.2012.11.20.06.04.45 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 20 Nov 2012 06:04:52 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.131 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.131; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.131 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-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 Cc: Stephen Warren , Anmar Oueja , Grant Likely , Linus Walleij 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-Gm-Message-State: ALoCoQntRhYn5AZ7F9OI62KKqY9ciLYlmGe8nEXN4ElEUcoPYMe+RV4pVmVJr0texqPEKIfEz5zF 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 --- 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;