aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2015-03-18 13:21:17 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-03-25 11:37:03 -0400
commit1e702ec2aa3bfed17d1266d31f94923322afbc60 (patch)
treed8f19c9482ca5971ab1c24d0c9ad6c5216c94a29
parentf89e68fc3b5a5d53d73a0df71b94d3c0a009d0ba (diff)
pinctrl: st: Supply a GPIO get_direction() call-back
ST's hardware differentiates between GPIO mode and Pinctrl alternate functions. When a pin is in GPIO mode, there are dedicated registers to set and obtain direction status. However, If a pin's alternate function is in use then the direction is set and status is derived from a bunch of syscon registers. The issue is; until now there was a lack of parity between the two. For example: Catting the two following information sources could result in conflicting information (output has been snipped for simplicity): $ cat /sys/kernel/debug/gpio GPIOs 32-39, platform/961f080.pin-controller-sbc, PIO4: gpio-33 (? ) out hi $ cat /sys/kernel/debug/pinctrl/<pin-controller>/pinconf-pins pin 33 (PIO4[1]):[OE:0,PU:0,OD:0] [retime:0,invclk:0,clknotdat:0,de:0,rt-clk:0,rt-delay:0] In this example GPIO-33 is a GPIO controlled LED, which is set for output, as you'd expect. However, when the same information is drafted from Pinctrl, it clearly states that OE (Output Enable) is not set i.e. the pin is set for input. This is because OE normally only represents alternate functions and has no bearing on how the pin operates when in Alt-0 (GPIO mode). This patch changes the current semantics and provides a parity link between the two subsystems. The get_direction() call-back firstly determines which function a pin is operating in, then uses the appropriate helpers for that mode. Reported-by: Olivier Clergeaud <olivier.clergeaud@st.com> Acked-by: Maxime Coquelin <maxime.coquelin@st.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinctrl-st.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index 10ad19c73900..52a437738cc2 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -206,7 +206,6 @@
206#define gpio_chip_to_bank(chip) \ 206#define gpio_chip_to_bank(chip) \
207 container_of(chip, struct st_gpio_bank, gpio_chip) 207 container_of(chip, struct st_gpio_bank, gpio_chip)
208 208
209
210enum st_retime_style { 209enum st_retime_style {
211 st_retime_style_none, 210 st_retime_style_none,
212 st_retime_style_packed, 211 st_retime_style_packed,
@@ -781,6 +780,35 @@ static int st_gpio_direction_output(struct gpio_chip *chip,
781 return 0; 780 return 0;
782} 781}
783 782
783static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
784{
785 struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
786 struct st_pio_control pc = bank->pc;
787 unsigned long config;
788 unsigned int direction = 0;
789 unsigned int function;
790 unsigned int value;
791 int i = 0;
792
793 /* Alternate function direction is handled by Pinctrl */
794 function = st_pctl_get_pin_function(&pc, offset);
795 if (function) {
796 st_pinconf_get_direction(&pc, offset, &config);
797 return !ST_PINCONF_UNPACK_OE(config);
798 }
799
800 /*
801 * GPIO direction is handled differently
802 * - See st_gpio_direction() above for an explanation
803 */
804 for (i = 0; i <= 2; i++) {
805 value = readl(bank->base + REG_PIO_PC(i));
806 direction |= ((value >> offset) & 0x1) << i;
807 }
808
809 return (direction == ST_GPIO_DIRECTION_IN);
810}
811
784static int st_gpio_xlate(struct gpio_chip *gc, 812static int st_gpio_xlate(struct gpio_chip *gc,
785 const struct of_phandle_args *gpiospec, u32 *flags) 813 const struct of_phandle_args *gpiospec, u32 *flags)
786{ 814{
@@ -1452,6 +1480,7 @@ static struct gpio_chip st_gpio_template = {
1452 .set = st_gpio_set, 1480 .set = st_gpio_set,
1453 .direction_input = st_gpio_direction_input, 1481 .direction_input = st_gpio_direction_input,
1454 .direction_output = st_gpio_direction_output, 1482 .direction_output = st_gpio_direction_output,
1483 .get_direction = st_gpio_get_direction,
1455 .ngpio = ST_GPIO_PINS_PER_BANK, 1484 .ngpio = ST_GPIO_PINS_PER_BANK,
1456 .of_gpio_n_cells = 1, 1485 .of_gpio_n_cells = 1,
1457 .of_xlate = st_gpio_xlate, 1486 .of_xlate = st_gpio_xlate,