From patchwork Fri Mar 29 02:41:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2361961 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by patchwork2.kernel.org (Postfix) with ESMTP id 618C4DF2A1 for ; Fri, 29 Mar 2013 02:51:46 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id BB088D00; Fri, 29 Mar 2013 02:46:25 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTP id 46553CDB for ; Fri, 29 Mar 2013 02:46:14 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 8161620177 for ; Fri, 29 Mar 2013 02:46:11 +0000 (UTC) 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 D904325BFB8; Fri, 29 Mar 2013 13:45:45 +1100 (EST) Received: by ayumi.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 7C74BEDEA2F; Fri, 29 Mar 2013 11:45:44 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Fri, 29 Mar 2013 11:41:53 +0900 Message-Id: <1364525119-31791-185-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> References: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Magnus Damm Subject: [LTSI-dev] [PATCH/RFC 184/390] sh: pfc: pin config get/set support. X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org From: Paul Mundt This implements simple support for adjusting the pin config value via the pinctrl API. The pinconf-generic code is abandoned for now until we've got a chance to revamp the pinmux_type state tracking that's needed by legacy code. Signed-off-by: Paul Mundt (cherry picked from commit fdd85ec3eb8cc1b663678a3efa16ee59a32e0277) Signed-off-by: Simon Horman --- drivers/sh/pfc/Kconfig | 1 - drivers/sh/pfc/pinctrl.c | 147 ++++++++++++++++++++++++++++++---------------- 2 files changed, 97 insertions(+), 51 deletions(-) diff --git a/drivers/sh/pfc/Kconfig b/drivers/sh/pfc/Kconfig index b743aaa..804f9ad 100644 --- a/drivers/sh/pfc/Kconfig +++ b/drivers/sh/pfc/Kconfig @@ -17,7 +17,6 @@ config PINCTRL_SH_PFC select PINCTRL select PINMUX select PINCONF - select GENERIC_PINCONF config GPIO_SH_PFC tristate "SuperH PFC GPIO support" diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c index 900afa5..0802b6c 100644 --- a/drivers/sh/pfc/pinctrl.c +++ b/drivers/sh/pfc/pinctrl.c @@ -65,10 +65,17 @@ static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, return 0; } +static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned offset) +{ + seq_printf(s, "%s", DRV_NAME); +} + static struct pinctrl_ops sh_pfc_pinctrl_ops = { .get_groups_count = sh_pfc_get_groups_count, .get_group_name = sh_pfc_get_group_name, .get_group_pins = sh_pfc_get_group_pins, + .pin_dbg_show = sh_pfc_pin_dbg_show, }; static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev) @@ -124,6 +131,59 @@ static inline int sh_pfc_config_function(struct sh_pfc *pfc, unsigned offset) return 0; } +static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, + int new_type) +{ + unsigned long flags; + int pinmux_type; + int ret = -EINVAL; + + spin_lock_irqsave(&pfc->lock, flags); + + pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE; + + /* + * See if the present config needs to first be de-configured. + */ + switch (pinmux_type) { + case PINMUX_TYPE_GPIO: + break; + case PINMUX_TYPE_OUTPUT: + case PINMUX_TYPE_INPUT: + case PINMUX_TYPE_INPUT_PULLUP: + case PINMUX_TYPE_INPUT_PULLDOWN: + sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + break; + default: + goto err; + } + + /* + * Dry run + */ + if (sh_pfc_config_gpio(pfc, offset, new_type, + GPIO_CFG_DRYRUN) != 0) + goto err; + + /* + * Request + */ + if (sh_pfc_config_gpio(pfc, offset, new_type, + GPIO_CFG_REQ) != 0) + goto err; + + pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + pfc->gpios[offset].flags |= new_type; + + ret = 0; + +err: + spin_unlock_irqrestore(&pfc->lock, flags); + + return ret; +} + + static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -185,49 +245,9 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned offset, bool input) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - struct sh_pfc *pfc = pmx->pfc; - unsigned long flags; - int pinmux_type, new_pinmux_type; - int ret = -EINVAL; + int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; - new_pinmux_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; - - spin_lock_irqsave(&pfc->lock, flags); - - pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE; - - switch (pinmux_type) { - case PINMUX_TYPE_GPIO: - break; - case PINMUX_TYPE_OUTPUT: - case PINMUX_TYPE_INPUT: - case PINMUX_TYPE_INPUT_PULLUP: - case PINMUX_TYPE_INPUT_PULLDOWN: - sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); - break; - default: - goto err; - } - - if (sh_pfc_config_gpio(pfc, offset, - new_pinmux_type, - GPIO_CFG_DRYRUN) != 0) - goto err; - - if (sh_pfc_config_gpio(pfc, offset, - new_pinmux_type, - GPIO_CFG_REQ) != 0) - BUG(); - - pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; - pfc->gpios[offset].flags |= new_pinmux_type; - - ret = 0; - -err: - spin_unlock_irqrestore(&pfc->lock, flags); - - return ret; + return sh_pfc_reconfig_pin(pmx->pfc, offset, type); } static struct pinmux_ops sh_pfc_pinmux_ops = { @@ -244,26 +264,53 @@ static struct pinmux_ops sh_pfc_pinmux_ops = { static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { - enum pin_config_param param = (enum pin_config_param)(*config); + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; - switch (param) { - default: - break; - } + *config = pfc->gpios[pin].flags & PINMUX_FLAG_TYPE; - return -ENOTSUPP; + return 0; } static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { - return -EINVAL; + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + + /* Validate the new type */ + if (config >= PINMUX_FLAG_TYPE) + return -EINVAL; + + return sh_pfc_reconfig_pin(pmx->pfc, pin, config); +} + +static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned pin) +{ + const char *pinmux_type_str[] = { + [PINMUX_TYPE_NONE] = "none", + [PINMUX_TYPE_FUNCTION] = "function", + [PINMUX_TYPE_GPIO] = "gpio", + [PINMUX_TYPE_OUTPUT] = "output", + [PINMUX_TYPE_INPUT] = "input", + [PINMUX_TYPE_INPUT_PULLUP] = "input bias pull up", + [PINMUX_TYPE_INPUT_PULLDOWN] = "input bias pull down", + }; + unsigned long config; + int rc; + + rc = sh_pfc_pinconf_get(pctldev, pin, &config); + if (unlikely(rc != 0)) + return; + + seq_printf(s, " %s", pinmux_type_str[config]); } static struct pinconf_ops sh_pfc_pinconf_ops = { - .is_generic = true, .pin_config_get = sh_pfc_pinconf_get, .pin_config_set = sh_pfc_pinconf_set, + .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, }; static struct pinctrl_gpio_range sh_pfc_gpio_range = {