Commit 89983478bdc99996bbc26bd63fd00358d3082cbe
Committed by
Tom Rini
1 parent
f3b44e8b27
Exists in
v2017.01-smarct4x
and in
33 other branches
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, ®s->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, ®s->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(®s->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(®s->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(®s->p3_inp_state); |
| 115 | 134 | break; |
| 116 | 135 | default: |
| ... | ... | @@ -149,6 +168,8 @@ |
| 149 | 168 | case 3: |
| 150 | 169 | writel(mask, ®s->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, ®s->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, ®s->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, ®s->p2_p3_dir_set); | |
| 255 | + break; | |
| 256 | + case 4: | |
| 257 | + /* GPI_xx; invalid. */ | |
| 229 | 258 | default: |
| 230 | 259 | return -1; |
| 231 | 260 | } |