From patchwork Mon Mar 18 11:05:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2288281 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 6B5A73FCF6 for ; Mon, 18 Mar 2013 11:21:11 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UHY4P-00062X-0j; Mon, 18 Mar 2013 11:17:37 +0000 Received: from kirsty.vergenet.net ([202.4.237.240]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UHXuk-00027L-Qj for linux-arm-kernel@lists.infradead.org; Mon, 18 Mar 2013 11:07:59 +0000 Received: from ayumi.akashicho.tokyo.vergenet.net (p8120-ipbfp1001kobeminato.hyogo.ocn.ne.jp [118.10.137.120]) by kirsty.vergenet.net (Postfix) with ESMTP id 28CA2267161; Mon, 18 Mar 2013 22:07:25 +1100 (EST) Received: by ayumi.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 2EA6DEDE60B; Mon, 18 Mar 2013 20:07:23 +0900 (JST) From: Simon Horman To: Arnd Bergmann , Olof Johansson Subject: [PATCH 012/142] sh-pfc: Shrink the pinctrl GPIO range to include real GPIOs only Date: Mon, 18 Mar 2013 20:05:08 +0900 Message-Id: <1363604838-29359-13-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1363604838-29359-1-git-send-email-horms+renesas@verge.net.au> References: <1363604838-29359-1-git-send-email-horms+renesas@verge.net.au> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130318_070739_724868_A3904946 X-CRM114-Status: GOOD ( 18.54 ) X-Spam-Score: -5.1 (-----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-5.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [202.4.237.240 listed in list.dnswl.org] -2.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Laurent Pinchart , linux-sh@vger.kernel.org, Linus Walleij , Magnus Damm , arm@kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Laurent Pinchart As a step towards GPIO function removal, shorten the GPIO range registered with the pinctrl core. Function GPIOs are now handled in the GPIO handlers directly instead of going through the pinctrl API. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 2 +- drivers/pinctrl/sh-pfc/core.h | 1 + drivers/pinctrl/sh-pfc/gpio.c | 57 ++++++++++++++++++++++++++++++++++++-- drivers/pinctrl/sh-pfc/pinctrl.c | 27 ++---------------- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index e7ad0d9..bed2d23 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -95,7 +95,7 @@ static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) (pfc->info->gpios[gpio].enum_id != 0); } -static bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) +bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) { return (gpio >= pfc->info->nr_pins) && (gpio < pfc->info->nr_gpios) && (pfc->info->gpios[gpio].enum_id != 0); diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index ba7c33c..dceaec0 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -47,6 +47,7 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); +bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio); int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, pinmux_enum_t *enum_idp); int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index f46f069..80a50d8 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -38,12 +38,51 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) static int sh_gpio_request(struct gpio_chip *gc, unsigned offset) { - return pinctrl_request_gpio(offset); + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int ret = -EINVAL; + + if (offset < pfc->info->nr_pins) + return pinctrl_request_gpio(offset); + + pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); + + spin_lock_irqsave(&pfc->lock, flags); + + if (!sh_pfc_gpio_is_function(pfc, offset)) + goto done; + + if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, + GPIO_CFG_DRYRUN)) + goto done; + + if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, + GPIO_CFG_REQ)) + goto done; + + ret = 0; + +done: + spin_unlock_irqrestore(&pfc->lock, flags); + return ret; } static void sh_gpio_free(struct gpio_chip *gc, unsigned offset) { - pinctrl_free_gpio(offset); + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int pinmux_type; + + if (offset < pfc->info->nr_pins) + return pinctrl_free_gpio(offset); + + spin_lock_irqsave(&pfc->lock, flags); + + pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; + + sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + + spin_unlock_irqrestore(&pfc->lock, flags); } static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value) @@ -70,12 +109,26 @@ static int sh_gpio_get_value(struct sh_pfc *pfc, unsigned gpio) static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset) { + struct sh_pfc *pfc = gpio_to_pfc(gc); + + if (offset >= pfc->info->nr_pins) { + /* Function GPIOs can only be requested, never configured. */ + return -EINVAL; + } + return pinctrl_gpio_direction_input(offset); } static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { + struct sh_pfc *pfc = gpio_to_pfc(gc); + + if (offset >= pfc->info->nr_pins) { + /* Function GPIOs can only be requested, never configured. */ + return -EINVAL; + } + sh_gpio_set_value(gpio_to_pfc(gc), offset, value); return pinctrl_gpio_direction_output(offset); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 682b3a6..747ee64 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -116,21 +116,6 @@ static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func, { } -static int sh_pfc_config_function(struct sh_pfc *pfc, unsigned offset) -{ - if (sh_pfc_config_gpio(pfc, offset, - PINMUX_TYPE_FUNCTION, - GPIO_CFG_DRYRUN) != 0) - return -EINVAL; - - if (sh_pfc_config_gpio(pfc, offset, - PINMUX_TYPE_FUNCTION, - GPIO_CFG_REQ) != 0) - return -EINVAL; - - return 0; -} - static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, int new_type) { @@ -198,19 +183,11 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; switch (pinmux_type) { - case PINMUX_TYPE_FUNCTION: - pr_notice_once("Use of GPIO API for function requests is " - "deprecated, convert to pinctrl\n"); - /* handle for now */ - ret = sh_pfc_config_function(pfc, offset); - if (unlikely(ret < 0)) - goto err; - - break; case PINMUX_TYPE_GPIO: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_OUTPUT: break; + case PINMUX_TYPE_FUNCTION: default: pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); ret = -ENOTSUPP; @@ -400,7 +377,7 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->range.name = DRV_NAME, pmx->range.id = 0; - pmx->range.npins = pfc->info->nr_gpios; + pmx->range.npins = pfc->info->nr_pins; pmx->range.base = 0; pmx->range.pin_base = 0;