Commit 89983478bdc99996bbc26bd63fd00358d3082cbe

Authored by Sylvain Lemieux
Committed by Tom Rini
1 parent f3b44e8b27

gpio: lpc32xx: fix issues with port3 gpio

The current simplify lpc32xx gpio driver implementation assume a
maximum of 32 GPIO per port; there are a total of 22 GPI, 24 GPO
and 6 GPIO to managed on port 3.

Update the driver to fix the following:
1) When requesting GPI_xx and GPO_xx on port 3 (xx is the same number)
   the second call to "gpio_request" will return -EBUSY.

2) The status of GPO_xx pin report the status of the
   corresponding GPI_xx pin when using the "gpio status" command.

3) The gpio driver may setup the direction register for the wrong
   gpio when calling "gpio_direction_input" (GPI_xx) or
   "gpio_direction_output" (GPO_xx) on port 3; the call to the
   direction is require to use the "gpio status" command.

The following change were done in the driver:
1) port3 GPI are cache in a separate 32 bits in the array.
2) port3 direction register written only for GPIO pins.
3) port3 GPO & GPIO (as output) are read using "p3_outp_state".
4) LPC32XX_GPI_P3_GRP updated to match the change.

Signed-off-by: Sylvain Lemieux <slemieux@tycoint.com>

Showing 2 changed files with 37 additions and 8 deletions Side-by-side Diff

arch/arm/include/asm/arch-lpc32xx/gpio_grp.h
... ... @@ -12,7 +12,7 @@
12 12  
13 13 /*
14 14 * Macro to map the pin for the lpc32xx_gpio driver.
15   - * Note: - GPIOS are considered here as homogeneous and linear, from 0 to 127;
  15 + * Note: - GPIOS are considered here as homogeneous and linear from 0 to 159;
16 16 * mapping is done per register, as group of 32.
17 17 * (see drivers/gpio/lpc32xx_gpio.c for details).
18 18 * - macros can be use with the following pins:
19 19  
... ... @@ -26,9 +26,9 @@
26 26 #define LPC32XX_GPIO_P0_GRP 0
27 27 #define LPC32XX_GPIO_P1_GRP 32
28 28 #define LPC32XX_GPIO_P2_GRP 64
29   -#define LPC32XX_GPI_P3_GRP 96
30 29 #define LPC32XX_GPO_P3_GRP 96
31 30 #define LPC32XX_GPIO_P3_GRP (LPC32XX_GPO_P3_GRP + 25)
  31 +#define LPC32XX_GPI_P3_GRP 128
32 32  
33 33 /*
34 34 * A specific GPIO can be selected with this macro
drivers/gpio/lpc32xx_gpio.c
... ... @@ -22,7 +22,7 @@
22 22 * read on another one.
23 23 *
24 24 * In order to keep this code simple, GPIOS are considered here as
25   - * homogeneous and linear, from 0 to 127.
  25 + * homogeneous and linear, from 0 to 159.
26 26 *
27 27 * ** WARNING #1 **
28 28 *
... ... @@ -35,7 +35,7 @@
35 35 * Please read NOTE in description of lpc32xx_gpio_get_function().
36 36 */
37 37  
38   -#define LPC32XX_GPIOS 128
  38 +#define LPC32XX_GPIOS 160
39 39  
40 40 struct lpc32xx_gpio_priv {
41 41 struct gpio_regs *regs;
42 42  
43 43  
... ... @@ -45,11 +45,18 @@
45 45  
46 46 /**
47 47 * We have 4 GPIO ports of 32 bits each
  48 + *
  49 + * Port mapping offset (32 bits each):
  50 + * - Port 0: 0
  51 + * - Port 1: 32
  52 + * - Port 2: 64
  53 + * - Port 3: GPO / GPIO (output): 96
  54 + * - Port 3: GPI: 128
48 55 */
49 56  
50   -#define MAX_GPIO 128
  57 +#define MAX_GPIO 160
51 58  
52   -#define GPIO_TO_PORT(gpio) ((gpio / 32) & 3)
  59 +#define GPIO_TO_PORT(gpio) ((gpio / 32) & 7)
53 60 #define GPIO_TO_RANK(gpio) (gpio % 32)
54 61 #define GPIO_TO_MASK(gpio) (1 << (gpio % 32))
55 62  
56 63  
... ... @@ -75,9 +82,16 @@
75 82 break;
76 83 case 2:
77 84 /* ports 2 and 3 share a common direction */
78   - case 3:
79 85 writel(mask, &regs->p2_p3_dir_clr);
80 86 break;
  87 + case 3:
  88 + /* Setup direction only for GPIO_xx. */
  89 + if ((mask >= 25) && (mask <= 30))
  90 + writel(mask, &regs->p2_p3_dir_clr);
  91 + break;
  92 + case 4:
  93 + /* GPI_xx; nothing to do. */
  94 + break;
81 95 default:
82 96 return -1;
83 97 }
... ... @@ -111,6 +125,11 @@
111 125 value = readl(&regs->p2_inp_state);
112 126 break;
113 127 case 3:
  128 + /* Read GPO_xx and GPIO_xx (as output) using p3_outp_state. */
  129 + value = readl(&regs->p3_outp_state);
  130 + break;
  131 + case 4:
  132 + /* Read GPI_xx and GPIO_xx (as input) using p3_inp_state. */
114 133 value = readl(&regs->p3_inp_state);
115 134 break;
116 135 default:
... ... @@ -149,6 +168,8 @@
149 168 case 3:
150 169 writel(mask, &regs->p3_outp_set);
151 170 break;
  171 + case 4:
  172 + /* GPI_xx; invalid. */
152 173 default:
153 174 return -1;
154 175 }
... ... @@ -181,6 +202,8 @@
181 202 case 3:
182 203 writel(mask, &regs->p3_outp_clr);
183 204 break;
  205 + case 4:
  206 + /* GPI_xx; invalid. */
184 207 default:
185 208 return -1;
186 209 }
187 210  
... ... @@ -223,9 +246,15 @@
223 246 break;
224 247 case 2:
225 248 /* ports 2 and 3 share a common direction */
226   - case 3:
227 249 writel(mask, &regs->p2_p3_dir_set);
228 250 break;
  251 + case 3:
  252 + /* Setup direction only for GPIO_xx. */
  253 + if ((mask >= 25) && (mask <= 30))
  254 + writel(mask, &regs->p2_p3_dir_set);
  255 + break;
  256 + case 4:
  257 + /* GPI_xx; invalid. */
229 258 default:
230 259 return -1;
231 260 }