Skip to content

Commit

Permalink
Merge tag 'pinctrl-for-v3.10' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/linusw/linux-pinctrl

Pull pinctrl update from Linus Walleij:
 "These are the pinctrl changes for v3.10:

   - Patrice Chotard contributed a new configuration debugfs interface
     and reintroduced fine-grained locking into the core: instead of
     having a "big pinctrl lock" we have a per-controller lock and
     specialized locks for the global controller and pinctrl handle
     lists.

   - Haoijan Zhuang deleted all the PXA and MMP2 pinctrl drivers and
     replaced them with pinctrl-single (which is also used by other
     SoCs) so we are gaining consolidation.  The platform particulars
     now come in through the device tree.

   - Haoijan also added support for generic pin config into the
     pinctrl-single driver which is another big consolidation win.

   - Finally also GPIO ranges are now supported by the pinctrl-single
     driver.

   - Tomasz Figa contributed a new Samsung S3C pinctrl driver, bringing
     more of the older Samsung platforms under the pinctrl umbrella and
     out of arch/arm.

   - Maxime Ripard contributed new Allwinner A10/A13 drivers.

   - Sachin Kamat, Wei Yongjun and Axel Lin did a lot of cleanups."

* tag 'pinctrl-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (66 commits)
  pinctrl: move subsystem mutex to pinctrl_dev struct
  pinctrl/pinconfig: fix misplaced goto
  pinctrl: s3c64xx: Fix build error caused by undefined chained_irq_enter
  pinctrl/pinconfig: add debug interface
  pinctrl: abx500: fix issue when no pdata
  pinctrl: pinctrl-single: add missing double quote
  pinctrl: sunxi: Rename wemac functions to emac
  pinctrl: exynos5440: add gpio interrupt support
  pinctrl: exynos5440: fix probe failure due to missing pin-list in config nodes
  pinctrl: ab8505: Staticize some symbols
  pinctrl: ab8540: Staticize some symbols
  pinctrl: ab9540: Staticize some symbols
  pinctrl: ab8500: Staticize some symbols
  pinctrl: abx500: Staticize some symbols
  pinctrl: Add pinctrl-s3c64xx driver
  pinctrl: samsung: Handle banks with two configuration registers
  pinctrl: samsung: Remove hardcoded register offsets
  pinctrl: samsung: Split pin bank description into two structures
  pinctrl: samsung: Include pinctrl-exynos driver data conditionally
  pinctrl: samsung: Protect bank registers with a spinlock
  ...
  • Loading branch information
Linus Torvalds committed Apr 29, 2013
2 parents 8127b39 + 42fed7b commit 000a74f
Show file tree
Hide file tree
Showing 55 changed files with 3,228 additions and 3,696 deletions.
6 changes: 3 additions & 3 deletions Documentation/devicetree/bindings/gpio/gpio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ announce the pinrange to the pin ctrl subsystem. For example,
compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
reg = <0x1460 0x18>;
gpio-controller;
gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>;
gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>;

}

Expand All @@ -107,8 +107,8 @@ where,

Next values specify the base pin and number of pins for the range
handled by 'qe_pio_e' gpio. In the given example from base pin 20 to
pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled
by this gpio controller.
pin 29 under pinctrl1 with gpio offset 0 and pin 50 to pin 69 under
pinctrl2 with gpio offset 10 is handled by this gpio controller.

The pinctrl node must have "#gpio-range-cells" property to show number of
arguments to pass with phandle from gpio controllers node.
109 changes: 107 additions & 2 deletions Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
One-register-per-pin type device tree based pinctrl driver

Required properties:
- compatible : "pinctrl-single"
- compatible : "pinctrl-single" or "pinconf-single".
"pinctrl-single" means that pinconf isn't supported.
"pinconf-single" means that generic pinconf is supported.

- reg : offset and length of the register set for the mux registers

Expand All @@ -14,9 +16,61 @@ Optional properties:
- pinctrl-single,function-off : function off mode for disabled state if
available and same for all registers; if not specified, disabling of
pin functions is ignored

- pinctrl-single,bit-per-mux : boolean to indicate that one register controls
more than one pin

- pinctrl-single,drive-strength : array of value that are used to configure
drive strength in the pinmux register. They're value of drive strength
current and drive strength mask.

/* drive strength current, mask */
pinctrl-single,power-source = <0x30 0xf0>;

- pinctrl-single,bias-pullup : array of value that are used to configure the
input bias pullup in the pinmux register.

/* input, enabled pullup bits, disabled pullup bits, mask */
pinctrl-single,bias-pullup = <0 1 0 1>;

- pinctrl-single,bias-pulldown : array of value that are used to configure the
input bias pulldown in the pinmux register.

/* input, enabled pulldown bits, disabled pulldown bits, mask */
pinctrl-single,bias-pulldown = <2 2 0 2>;

* Two bits to control input bias pullup and pulldown: User should use
pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. One bit means
pullup, and the other one bit means pulldown.
* Three bits to control input bias enable, pullup and pulldown. User should
use pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. Input bias
enable bit should be included in pullup or pulldown bits.
* Although driver could set PIN_CONFIG_BIAS_DISABLE, there's no property as
pinctrl-single,bias-disable. Because pinctrl single driver could implement
it by calling pulldown, pullup disabled.

- pinctrl-single,input-schmitt : array of value that are used to configure
input schmitt in the pinmux register. In some silicons, there're two input
schmitt value (rising-edge & falling-edge) in the pinmux register.

/* input schmitt value, mask */
pinctrl-single,input-schmitt = <0x30 0x70>;

- pinctrl-single,input-schmitt-enable : array of value that are used to
configure input schmitt enable or disable in the pinmux register.

/* input, enable bits, disable bits, mask */
pinctrl-single,input-schmitt-enable = <0x30 0x40 0 0x70>;

- pinctrl-single,gpio-range : list of value that are used to configure a GPIO
range. They're value of subnode phandle, pin base in pinctrl device, pin
number in this range, GPIO function value of this GPIO range.
The number of parameters is depend on #pinctrl-single,gpio-range-cells
property.

/* pin base, nr pins & gpio function */
pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>;

This driver assumes that there is only one register for each pin (unless the
pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as
specified in the pinctrl-bindings.txt document in this directory.
Expand All @@ -42,6 +96,20 @@ Where 0xdc is the offset from the pinctrl register base address for the
device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
be used when applying this change to the register.


Optional sub-node: In case some pins could be configured as GPIO in the pinmux
register, those pins could be defined as a GPIO range. This sub-node is required
by pinctrl-single,gpio-range property.

Required properties in sub-node:
- #pinctrl-single,gpio-range-cells : the number of parameters after phandle in
pinctrl-single,gpio-range property.

range: gpio-range {
#pinctrl-single,gpio-range-cells = <3>;
};


Example:

/* SoC common file */
Expand All @@ -58,7 +126,7 @@ pmx_core: pinmux@4a100040 {

/* second controller instance for pins in wkup domain */
pmx_wkup: pinmux@4a31e040 {
compatible = "pinctrl-single;
compatible = "pinctrl-single";
reg = <0x4a31e040 0x0038>;
#address-cells = <1>;
#size-cells = <0>;
Expand All @@ -76,6 +144,29 @@ control_devconf0: pinmux@48002274 {
pinctrl-single,function-mask = <0x5F>;
};

/* third controller instance for pins in gpio domain */
pmx_gpio: pinmux@d401e000 {
compatible = "pinconf-single";
reg = <0xd401e000 0x0330>;
#address-cells = <1>;
#size-cells = <1>;
ranges;

pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <7>;

/* sparse GPIO range could be supported */
pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
&range 12 1 0 &range 13 29 1
&range 43 1 0 &range 44 49 1
&range 94 1 1 &range 96 2 1>;

range: gpio-range {
#pinctrl-single,gpio-range-cells = <3>;
};
};


/* board specific .dts file */

&pmx_core {
Expand All @@ -96,6 +187,15 @@ control_devconf0: pinmux@48002274 {
>;
};

uart0_pins: pinmux_uart0_pins {
pinctrl-single,pins = <
0x208 0 /* UART0_RXD (IOCFG138) */
0x20c 0 /* UART0_TXD (IOCFG139) */
>;
pinctrl-single,bias-pulldown = <0 2 2>;
pinctrl-single,bias-pullup = <0 1 1>;
};

/* map uart2 pins */
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
Expand All @@ -122,6 +222,11 @@ control_devconf0: pinmux@48002274 {

};

&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
};

&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
Expand Down
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on-chip controllers onto these pads.

Required Properties:
- compatible: should be one of the following.
- "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
- "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
- "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
- "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
Expand Down Expand Up @@ -105,6 +106,8 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a

- compatible: identifies the type of the external wakeup interrupt controller
The possible values are:
- samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
found on Samsung S3C64xx SoCs,
- samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
found on Samsung Exynos4210 SoC.
- interrupt-parent: phandle of the interrupt parent to which the external
Expand Down
112 changes: 112 additions & 0 deletions Documentation/pinctrl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,13 @@ All the above functions are mandatory to implement for a pinmux driver.
Pin control interaction with the GPIO subsystem
===============================================

Note that the following implies that the use case is to use a certain pin
from the Linux kernel using the API in <linux/gpio.h> with gpio_request()
and similar functions. There are cases where you may be using something
that your datasheet calls "GPIO mode" but actually is just an electrical
configuration for a certain device. See the section below named
"GPIO mode pitfalls" for more details on this scenario.

The public pinmux API contains two functions named pinctrl_request_gpio()
and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and
Expand Down Expand Up @@ -774,6 +781,111 @@ obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered.


GPIO mode pitfalls
==================

Sometime the developer may be confused by a datasheet talking about a pin
being possible to set into "GPIO mode". It appears that what hardware
engineers mean with "GPIO mode" is not necessarily the use case that is
implied in the kernel interface <linux/gpio.h>: a pin that you grab from
kernel code and then either listen for input or drive high/low to
assert/deassert some external line.

Rather hardware engineers think that "GPIO mode" means that you can
software-control a few electrical properties of the pin that you would
not be able to control if the pin was in some other mode, such as muxed in
for a device.

Example: a pin is usually muxed in to be used as a UART TX line. But during
system sleep, we need to put this pin into "GPIO mode" and ground it.

If you make a 1-to-1 map to the GPIO subsystem for this pin, you may start
to think that you need to come up with something real complex, that the
pin shall be used for UART TX and GPIO at the same time, that you will grab
a pin control handle and set it to a certain state to enable UART TX to be
muxed in, then twist it over to GPIO mode and use gpio_direction_output()
to drive it low during sleep, then mux it over to UART TX again when you
wake up and maybe even gpio_request/gpio_free as part of this cycle. This
all gets very complicated.

The solution is to not think that what the datasheet calls "GPIO mode"
has to be handled by the <linux/gpio.h> interface. Instead view this as
a certain pin config setting. Look in e.g. <linux/pinctrl/pinconf-generic.h>
and you find this in the documentation:

PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
1 to indicate high level, argument 0 to indicate low level.

So it is perfectly possible to push a pin into "GPIO mode" and drive the
line low as part of the usual pin control map. So for example your UART
driver may look like this:

#include <linux/pinctrl/consumer.h>

struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_sleep;

pins_default = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_DEFAULT);
pins_sleep = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_SLEEP);

/* Normal mode */
retval = pinctrl_select_state(pinctrl, pins_default);
/* Sleep mode */
retval = pinctrl_select_state(pinctrl, pins_sleep);

And your machine configuration may look like this:
--------------------------------------------------

static unsigned long uart_default_mode[] = {
PIN_CONF_PACKED(PIN_CONFIG_DRIVE_PUSH_PULL, 0),
};

static unsigned long uart_sleep_mode[] = {
PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0),
};

static struct pinctrl_map __initdata pinmap[] = {
PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo",
"u0_group", "u0"),
PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo",
"UART_TX_PIN", uart_default_mode),
PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo",
"u0_group", "gpio-mode"),
PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo",
"UART_TX_PIN", uart_sleep_mode),
};

foo_init(void) {
pinctrl_register_mappings(pinmap, ARRAY_SIZE(pinmap));
}

Here the pins we want to control are in the "u0_group" and there is some
function called "u0" that can be enabled on this group of pins, and then
everything is UART business as usual. But there is also some function
named "gpio-mode" that can be mapped onto the same pins to move them into
GPIO mode.

This will give the desired effect without any bogus interaction with the
GPIO subsystem. It is just an electrical configuration used by that device
when going to sleep, it might imply that the pin is set into something the
datasheet calls "GPIO mode" but that is not the point: it is still used
by that UART device to control the pins that pertain to that very UART
driver, putting them into modes needed by the UART. GPIO in the Linux
kernel sense are just some 1-bit line, and is a different use case.

How the registers are poked to attain the push/pull and output low
configuration and the muxing of the "u0" or "gpio-mode" group onto these
pins is a question for the driver.

Some datasheets will be more helpful and refer to the "GPIO mode" as
"low power mode" rather than anything to do with GPIO. This often means
the same thing electrically speaking, but in this latter case the
software engineers will usually quickly identify that this is some
specific muxing/configuration rather than anything related to the GPIO
API.


Board/machine configuration
==================================

Expand Down
4 changes: 2 additions & 2 deletions arch/arm/boot/dts/spear1310.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
pinmux: pinmux@e0700000 {
compatible = "st,spear1310-pinmux";
reg = <0xe0700000 0x1000>;
#gpio-range-cells = <2>;
#gpio-range-cells = <3>;
};

apb {
Expand Down Expand Up @@ -212,7 +212,7 @@
interrupt-controller;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinmux 0 246>;
gpio-ranges = <&pinmux 0 0 246>;
status = "disabled";

st-plgpio,ngpio = <246>;
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/boot/dts/spear1340.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
pinmux: pinmux@e0700000 {
compatible = "st,spear1340-pinmux";
reg = <0xe0700000 0x1000>;
#gpio-range-cells = <2>;
#gpio-range-cells = <3>;
};

pwm: pwm@e0180000 {
Expand Down Expand Up @@ -127,7 +127,7 @@
interrupt-controller;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinmux 0 252>;
gpio-ranges = <&pinmux 0 0 252>;
status = "disabled";

st-plgpio,ngpio = <250>;
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/boot/dts/spear310.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
pinmux: pinmux@b4000000 {
compatible = "st,spear310-pinmux";
reg = <0xb4000000 0x1000>;
#gpio-range-cells = <2>;
#gpio-range-cells = <3>;
};

fsmc: flash@44000000 {
Expand Down Expand Up @@ -102,7 +102,7 @@
interrupt-controller;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinmux 0 102>;
gpio-ranges = <&pinmux 0 0 102>;
status = "disabled";

st-plgpio,ngpio = <102>;
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/boot/dts/spear320.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
pinmux: pinmux@b3000000 {
compatible = "st,spear320-pinmux";
reg = <0xb3000000 0x1000>;
#gpio-range-cells = <2>;
#gpio-range-cells = <3>;
};

clcd@90000000 {
Expand Down Expand Up @@ -130,7 +130,7 @@
interrupt-controller;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinmux 0 102>;
gpio-ranges = <&pinmux 0 0 102>;
status = "disabled";

st-plgpio,ngpio = <102>;
Expand Down
Loading

0 comments on commit 000a74f

Please sign in to comment.