From patchwork Tue Nov 22 12:00:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 5276 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 3E1DB24016 for ; Tue, 22 Nov 2011 12:00:33 +0000 (UTC) Received: from mail-yw0-f52.google.com (mail-yw0-f52.google.com [209.85.213.52]) by fiordland.canonical.com (Postfix) with ESMTP id E36F0A18621 for ; Tue, 22 Nov 2011 12:00:32 +0000 (UTC) Received: by ywb5 with SMTP id 5so84665ywb.11 for ; Tue, 22 Nov 2011 04:00:32 -0800 (PST) Received: by 10.152.104.1 with SMTP id ga1mr11520906lab.40.1321963231779; Tue, 22 Nov 2011 04:00:31 -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.152.41.198 with SMTP id h6cs174577lal; Tue, 22 Nov 2011 04:00:31 -0800 (PST) Received: by 10.14.3.138 with SMTP id 10mr1296299eeh.218.1321963229573; Tue, 22 Nov 2011 04:00:29 -0800 (PST) Received: from eu1sys200aog108.obsmtp.com (eu1sys200aog108.obsmtp.com. [207.126.144.125]) by mx.google.com with SMTP id g46si3111260eea.190.2011.11.22.04.00.24 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 22 Nov 2011 04:00:29 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.125 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.125; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.125 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-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob108.postini.com ([207.126.147.11]) with SMTP ID DSNKTsuO1VhZpTxKUmM7kVUtAqXW+ElAQPju@postini.com; Tue, 22 Nov 2011 12:00:29 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E5A6AD4; Tue, 22 Nov 2011 12:00:14 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 143432191; Tue, 22 Nov 2011 12:00:14 +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 BC07024C2F1; Tue, 22 Nov 2011 13:00:07 +0100 (CET) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 22 Nov 2011 13:00:13 +0100 From: Linus Walleij To: Cc: Stephen Warren , Grant Likely , Barry Song <21cnbao@gmail.com>, Shawn Guo , Thomas Abraham , Dong Aisheng , Rajendra Nayak , Linus Walleij , Igor Grinberg Subject: [PATCH] pinctrl: GPIO direction support for muxing Date: Tue, 22 Nov 2011 13:00:06 +0100 Message-ID: <1321963206-10502-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.3.2 MIME-Version: 1.0 From: Linus Walleij When requesting a single GPIO pin to be muxed in, some controllers will need to poke a different value into the control register depending on whether the pin will be used for GPIO output or GPIO input. So create pinmux counterparts to gpio_direction_[input|output] in the pinctrl framework. ChangeLog v1->v2: - This also amends the documentation to make it clear the this function and associated machinery is *ONLY* intended as a backend to gpiolib machinery, not for everyone and his dog to start playing around with pins. ChangeLog v2->v3: - Don't pass an argument to the common request function, instead provide pinmux_* counterparts to the gpio_direction_[input|output] calls, simpler and anyone can understand it. ChangeLog v3->v4: - Fix numerous spelling mistakes and dangling text in documentation. Add Ack and Rewewed-by. Cc: Igor Grinberg Acked-by: Stephen Warren Reviewed-by: Thomas Abraham Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 32 +++++++++++++++----- drivers/pinctrl/pinmux.c | 61 ++++++++++++++++++++++++++++++++++++++++ include/linux/pinctrl/pinmux.h | 24 +++++++++++++++- 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index b33c84c..25a2a12 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -645,6 +645,17 @@ All the above functions are mandatory to implement for a pinmux driver. Pinmux interaction with the GPIO subsystem ========================================== +The public pinmux API contains two functions named pinmux_request_gpio() +and pinmux_free_gpio(). These two functions shall *ONLY* be called from +gpiolib-based drivers as part of their gpio_request() and +gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output] +shall only be called from within respective gpio_direction_[input|output] +gpiolib implementation. + +NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be +muxed in. Instead, implement a proper gpiolib driver and have that driver +request proper muxing for its pins. + The function list could become long, especially if you can convert every individual pin into a GPIO pin independent of any other pins, and then try the approach to define every pin as a function. @@ -652,19 +663,24 @@ the approach to define every pin as a function. In this case, the function array would become 64 entries for each GPIO setting and then the device functions. -For this reason there is an additional function a pinmux driver can implement -to enable only GPIO on an individual pin: .gpio_request_enable(). The same -.free() function as for other functions is assumed to be usable also for -GPIO pins. +For this reason there are two functions a pinmux driver can implement +to enable only GPIO on an individual pin: .gpio_request_enable() and +.gpio_disable_free(). This function will pass in the affected GPIO range identified by the pin controller core, so you know which GPIO pins are being affected by the request operation. -Alternatively it is fully allowed to use named functions for each GPIO -pin, the pinmux_request_gpio() will attempt to obtain the function "gpioN" -where "N" is the global GPIO pin number if no special GPIO-handler is -registered. +If your driver needs to have an indication from the framework of whether the +GPIO pin shall be used for input or output you can implement the +.gpio_set_direction() function. As described this shall be called from the +gpiolib driver and the affected GPIO range, pin offset and desired direction +will be passed along to this function. + +Alternatively to using these special functions, it is fully allowed to use +named functions for each GPIO pin, the pinmux_request_gpio() will attempt to +obtain the function "gpioN" where "N" is the global GPIO pin number if no +special GPIO-handler is registered. Pinmux board/machine configuration diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index d27b77d..15ae972 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -218,6 +218,10 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, /** * pinmux_request_gpio() - request a single pin to be muxed in as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_request() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed in. */ int pinmux_request_gpio(unsigned gpio) { @@ -253,6 +257,10 @@ EXPORT_SYMBOL_GPL(pinmux_request_gpio); /** * pinmux_free_gpio() - free a single pin, currently used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_free() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed out. */ void pinmux_free_gpio(unsigned gpio) { @@ -274,6 +282,59 @@ void pinmux_free_gpio(unsigned gpio) } EXPORT_SYMBOL_GPL(pinmux_free_gpio); +static int pinmux_gpio_direction(unsigned gpio, bool input) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + const struct pinmux_ops *ops; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return ret; + + ops = pctldev->desc->pmxops; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + if (ops->gpio_set_direction) + ret = ops->gpio_set_direction(pctldev, range, pin, input); + else + ret = 0; + + return ret; +} + +/** + * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_input() semantics, platforms and individual + * drivers shall *NOT* touch pinmux GPIO calls. + */ +int pinmux_gpio_direction_input(unsigned gpio) +{ + return pinmux_gpio_direction(gpio, true); +} +EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input); + +/** + * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_output() semantics, platforms and individual + * drivers shall *NOT* touch pinmux GPIO calls. + */ +int pinmux_gpio_direction_output(unsigned gpio) +{ + return pinmux_gpio_direction(gpio, false); +} +EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); + /** * pinmux_register_mappings() - register a set of pinmux mappings * @maps: the pinmux mappings table to register diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index bb7a979..937b3e2 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -54,7 +54,13 @@ struct pinctrl_dev; * Implement this only if you can mux every pin individually as GPIO. The * affected GPIO range is passed along with an offset(pin number) into that * specific GPIO range - function selectors and pin groups are orthogonal - * to this, the core will however make sure the pins do not collide + * to this, the core will however make sure the pins do not collide. + * @gpio_disable_free: free up GPIO muxing on a certain pin, the reverse of + * @gpio_request_enable + * @gpio_set_direction: Since controllers may need different configurations + * depending on whether the GPIO is configured as input or output, + * a direction selector function may be implemented as a backing + * to the GPIO controllers that need pin muxing. */ struct pinmux_ops { int (*request) (struct pinctrl_dev *pctldev, unsigned offset); @@ -76,11 +82,17 @@ struct pinmux_ops { void (*gpio_disable_free) (struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset); + int (*gpio_set_direction) (struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, + bool input); }; /* External interface to pinmux */ extern int pinmux_request_gpio(unsigned gpio); extern void pinmux_free_gpio(unsigned gpio); +extern int pinmux_gpio_direction_input(unsigned gpio); +extern int pinmux_gpio_direction_output(unsigned gpio); extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); extern void pinmux_put(struct pinmux *pmx); extern int pinmux_enable(struct pinmux *pmx); @@ -97,6 +109,16 @@ static inline void pinmux_free_gpio(unsigned gpio) { } +static inline int pinmux_gpio_direction_input(unsigned gpio) +{ + return 0; +} + +static inline int pinmux_gpio_direction_output(unsigned gpio) +{ + return 0; +} + static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) { return NULL;