7a37be85cfd52f008572b6da6f9de3c33bb0a60a
[openembedded.git] /
1 From 49da9bd487e54164a75503e0037a054cce697ed5 Mon Sep 17 00:00:00 2001
2 From: Philipp Zabel <philipp.zabel@gmail.com>
3 Date: Tue, 12 Feb 2008 04:38:12 +0300
4 Subject: [PATCH 23/64] This adds gpiolib support for the PXA architecture:
5    - move all GPIO API functions from generic.c into gpio.c
6    - convert the gpio_get/set_value macros into inline functions
7
8 This makes it easier to hook up GPIOs provided by external chips like
9 ASICs and CPLDs.
10
11 Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
12 Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
13 Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
14 Cc: Jean Delvare <khali@linux-fr.org>
15 Cc: Eric Miao <eric.miao@marvell.com>
16 Cc: Sam Ravnborg <sam@ravnborg.org>
17 Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
18 Cc: Ben Gardner <bgardner@wabtec.com>
19 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
20 ---
21  arch/arm/Kconfig                    |    1 +
22  arch/arm/mach-pxa/Makefile          |    3 +-
23  arch/arm/mach-pxa/generic.c         |   93 ----------------
24  arch/arm/mach-pxa/generic.h         |    1 +
25  arch/arm/mach-pxa/gpio.c            |  197 +++++++++++++++++++++++++++++++++++
26  arch/arm/mach-pxa/irq.c             |    2 +
27  include/asm-arm/arch-pxa/gpio.h     |   48 ++++-----
28  include/asm-arm/arch-pxa/pxa-regs.h |   13 +++
29  8 files changed, 236 insertions(+), 122 deletions(-)
30  create mode 100644 arch/arm/mach-pxa/gpio.c
31
32 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
33 index 06ca241..423e953 100644
34 --- a/arch/arm/Kconfig
35 +++ b/arch/arm/Kconfig
36 @@ -346,6 +346,7 @@ config ARCH_PXA
37         select GENERIC_TIME
38         select GENERIC_CLOCKEVENTS
39         select TICK_ONESHOT
40 +       select HAVE_GPIO_LIB
41         help
42           Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
43  
44 diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
45 index 4263527..5cb0216 100644
46 --- a/arch/arm/mach-pxa/Makefile
47 +++ b/arch/arm/mach-pxa/Makefile
48 @@ -3,7 +3,8 @@
49  #
50  
51  # Common support (must be linked before board specific support)
52 -obj-y                          += clock.o generic.o irq.o dma.o time.o
53 +obj-y                          += clock.o generic.o irq.o dma.o \
54 +                                  time.o gpio.o
55  obj-$(CONFIG_PXA25x)           += pxa25x.o
56  obj-$(CONFIG_PXA27x)           += pxa27x.o
57  obj-$(CONFIG_PXA3xx)           += pxa3xx.o mfp.o
58 diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
59 index 1c34946..6c07292 100644
60 --- a/arch/arm/mach-pxa/generic.c
61 +++ b/arch/arm/mach-pxa/generic.c
62 @@ -32,7 +32,6 @@
63  #include <asm/mach/map.h>
64  
65  #include <asm/arch/pxa-regs.h>
66 -#include <asm/arch/gpio.h>
67  #include <asm/arch/udc.h>
68  #include <asm/arch/pxafb.h>
69  #include <asm/arch/mmc.h>
70 @@ -73,97 +72,6 @@ unsigned int get_memclk_frequency_10khz(void)
71  EXPORT_SYMBOL(get_memclk_frequency_10khz);
72  
73  /*
74 - * Handy function to set GPIO alternate functions
75 - */
76 -int pxa_last_gpio;
77 -
78 -int pxa_gpio_mode(int gpio_mode)
79 -{
80 -       unsigned long flags;
81 -       int gpio = gpio_mode & GPIO_MD_MASK_NR;
82 -       int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
83 -       int gafr;
84 -
85 -       if (gpio > pxa_last_gpio)
86 -               return -EINVAL;
87 -
88 -       local_irq_save(flags);
89 -       if (gpio_mode & GPIO_DFLT_LOW)
90 -               GPCR(gpio) = GPIO_bit(gpio);
91 -       else if (gpio_mode & GPIO_DFLT_HIGH)
92 -               GPSR(gpio) = GPIO_bit(gpio);
93 -       if (gpio_mode & GPIO_MD_MASK_DIR)
94 -               GPDR(gpio) |= GPIO_bit(gpio);
95 -       else
96 -               GPDR(gpio) &= ~GPIO_bit(gpio);
97 -       gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
98 -       GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
99 -       local_irq_restore(flags);
100 -
101 -       return 0;
102 -}
103 -
104 -EXPORT_SYMBOL(pxa_gpio_mode);
105 -
106 -int gpio_direction_input(unsigned gpio)
107 -{
108 -       unsigned long flags;
109 -       u32 mask;
110 -
111 -       if (gpio > pxa_last_gpio)
112 -               return -EINVAL;
113 -
114 -       mask = GPIO_bit(gpio);
115 -       local_irq_save(flags);
116 -       GPDR(gpio) &= ~mask;
117 -       local_irq_restore(flags);
118 -
119 -       return 0;
120 -}
121 -EXPORT_SYMBOL(gpio_direction_input);
122 -
123 -int gpio_direction_output(unsigned gpio, int value)
124 -{
125 -       unsigned long flags;
126 -       u32 mask;
127 -
128 -       if (gpio > pxa_last_gpio)
129 -               return -EINVAL;
130 -
131 -       mask = GPIO_bit(gpio);
132 -       local_irq_save(flags);
133 -       if (value)
134 -               GPSR(gpio) = mask;
135 -       else
136 -               GPCR(gpio) = mask;
137 -       GPDR(gpio) |= mask;
138 -       local_irq_restore(flags);
139 -
140 -       return 0;
141 -}
142 -EXPORT_SYMBOL(gpio_direction_output);
143 -
144 -/*
145 - * Return GPIO level
146 - */
147 -int pxa_gpio_get_value(unsigned gpio)
148 -{
149 -       return __gpio_get_value(gpio);
150 -}
151 -
152 -EXPORT_SYMBOL(pxa_gpio_get_value);
153 -
154 -/*
155 - * Set output GPIO level
156 - */
157 -void pxa_gpio_set_value(unsigned gpio, int value)
158 -{
159 -       __gpio_set_value(gpio, value);
160 -}
161 -
162 -EXPORT_SYMBOL(pxa_gpio_set_value);
163 -
164 -/*
165   * Routine to safely enable or disable a clock in the CKEN
166   */
167  void __pxa_set_cken(int clock, int enable)
168 @@ -178,7 +86,6 @@ void __pxa_set_cken(int clock, int enable)
169  
170         local_irq_restore(flags);
171  }
172 -
173  EXPORT_SYMBOL(__pxa_set_cken);
174  
175  /*
176 diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
177 index b30f240..727a9f5 100644
178 --- a/arch/arm/mach-pxa/generic.h
179 +++ b/arch/arm/mach-pxa/generic.h
180 @@ -16,6 +16,7 @@ extern void __init pxa_init_irq_low(void);
181  extern void __init pxa_init_irq_high(void);
182  extern void __init pxa_init_irq_gpio(int gpio_nr);
183  extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
184 +extern void __init pxa_init_gpio(int gpio_nr);
185  extern void __init pxa25x_init_irq(void);
186  extern void __init pxa27x_init_irq(void);
187  extern void __init pxa3xx_init_irq(void);
188 diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
189 new file mode 100644
190 index 0000000..8638dd7
191 --- /dev/null
192 +++ b/arch/arm/mach-pxa/gpio.c
193 @@ -0,0 +1,197 @@
194 +/*
195 + *  linux/arch/arm/mach-pxa/gpio.c
196 + *
197 + *  Generic PXA GPIO handling
198 + *
199 + *  Author:    Nicolas Pitre
200 + *  Created:   Jun 15, 2001
201 + *  Copyright: MontaVista Software Inc.
202 + *
203 + *  This program is free software; you can redistribute it and/or modify
204 + *  it under the terms of the GNU General Public License version 2 as
205 + *  published by the Free Software Foundation.
206 + */
207 +
208 +#include <linux/init.h>
209 +#include <linux/module.h>
210 +
211 +#include <asm/gpio.h>
212 +#include <asm/hardware.h>
213 +#include <asm/io.h>
214 +#include <asm/arch/pxa-regs.h>
215 +
216 +#include "generic.h"
217 +
218 +
219 +struct pxa_gpio_chip {
220 +       struct gpio_chip chip;
221 +       void __iomem     *regbase;
222 +};
223 +
224 +int pxa_last_gpio;
225 +
226 +/*
227 + * Configure pins for GPIO or other functions
228 + */
229 +int pxa_gpio_mode(int gpio_mode)
230 +{
231 +       unsigned long flags;
232 +       int gpio = gpio_mode & GPIO_MD_MASK_NR;
233 +       int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
234 +       int gafr;
235 +
236 +       if (gpio > pxa_last_gpio)
237 +               return -EINVAL;
238 +
239 +       local_irq_save(flags);
240 +       if (gpio_mode & GPIO_DFLT_LOW)
241 +               GPCR(gpio) = GPIO_bit(gpio);
242 +       else if (gpio_mode & GPIO_DFLT_HIGH)
243 +               GPSR(gpio) = GPIO_bit(gpio);
244 +       if (gpio_mode & GPIO_MD_MASK_DIR)
245 +               GPDR(gpio) |= GPIO_bit(gpio);
246 +       else
247 +               GPDR(gpio) &= ~GPIO_bit(gpio);
248 +       gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
249 +       GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
250 +       local_irq_restore(flags);
251 +
252 +       return 0;
253 +}
254 +EXPORT_SYMBOL(pxa_gpio_mode);
255 +
256 +static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
257 +{
258 +       unsigned long        flags;
259 +       u32                  mask = 1 << offset;
260 +       u32                  value;
261 +       struct pxa_gpio_chip *pxa;
262 +       void __iomem         *gpdr;
263 +
264 +       pxa = container_of(chip, struct pxa_gpio_chip, chip);
265 +       gpdr = pxa->regbase + GPDR_OFFSET;
266 +       local_irq_save(flags);
267 +       value = __raw_readl(gpdr);
268 +       value &= ~mask;
269 +       __raw_writel(value, gpdr);
270 +       local_irq_restore(flags);
271 +
272 +       return 0;
273 +}
274 +
275 +static int pxa_gpio_direction_output(struct gpio_chip *chip,
276 +                                       unsigned offset, int value)
277 +{
278 +       unsigned long        flags;
279 +       u32                  mask = 1 << offset;
280 +       u32                  tmp;
281 +       struct pxa_gpio_chip *pxa;
282 +       void __iomem         *gpdr;
283 +
284 +       pxa = container_of(chip, struct pxa_gpio_chip, chip);
285 +       __raw_writel(mask,
286 +                       pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
287 +       gpdr = pxa->regbase + GPDR_OFFSET;
288 +       local_irq_save(flags);
289 +       tmp = __raw_readl(gpdr);
290 +       tmp |= mask;
291 +       __raw_writel(tmp, gpdr);
292 +       local_irq_restore(flags);
293 +
294 +       return 0;
295 +}
296 +
297 +/*
298 + * Return GPIO level
299 + */
300 +static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
301 +{
302 +       u32                  mask = 1 << offset;
303 +       struct pxa_gpio_chip *pxa;
304 +
305 +       pxa = container_of(chip, struct pxa_gpio_chip, chip);
306 +       return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
307 +}
308 +
309 +/*
310 + * Set output GPIO level
311 + */
312 +static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
313 +{
314 +       u32                  mask = 1 << offset;
315 +       struct pxa_gpio_chip *pxa;
316 +
317 +       pxa = container_of(chip, struct pxa_gpio_chip, chip);
318 +
319 +       if (value)
320 +               __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
321 +       else
322 +               __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
323 +}
324 +
325 +static struct pxa_gpio_chip pxa_gpio_chip[] = {
326 +       [0] = {
327 +               .regbase = GPIO0_BASE,
328 +               .chip = {
329 +                       .label            = "gpio-0",
330 +                       .direction_input  = pxa_gpio_direction_input,
331 +                       .direction_output = pxa_gpio_direction_output,
332 +                       .get              = pxa_gpio_get,
333 +                       .set              = pxa_gpio_set,
334 +                       .base             = 0,
335 +                       .ngpio            = 32,
336 +               },
337 +       },
338 +       [1] = {
339 +               .regbase = GPIO1_BASE,
340 +               .chip = {
341 +                       .label            = "gpio-1",
342 +                       .direction_input  = pxa_gpio_direction_input,
343 +                       .direction_output = pxa_gpio_direction_output,
344 +                       .get              = pxa_gpio_get,
345 +                       .set              = pxa_gpio_set,
346 +                       .base             = 32,
347 +                       .ngpio            = 32,
348 +               },
349 +       },
350 +       [2] = {
351 +               .regbase = GPIO2_BASE,
352 +               .chip = {
353 +                       .label            = "gpio-2",
354 +                       .direction_input  = pxa_gpio_direction_input,
355 +                       .direction_output = pxa_gpio_direction_output,
356 +                       .get              = pxa_gpio_get,
357 +                       .set              = pxa_gpio_set,
358 +                       .base             = 64,
359 +                       .ngpio            = 32, /* 21 for PXA25x */
360 +               },
361 +       },
362 +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
363 +       [3] = {
364 +               .regbase = GPIO3_BASE,
365 +               .chip = {
366 +                       .label            = "gpio-3",
367 +                       .direction_input  = pxa_gpio_direction_input,
368 +                       .direction_output = pxa_gpio_direction_output,
369 +                       .get              = pxa_gpio_get,
370 +                       .set              = pxa_gpio_set,
371 +                       .base             = 96,
372 +                       .ngpio            = 32,
373 +               },
374 +       },
375 +#endif
376 +};
377 +
378 +void __init pxa_init_gpio(int gpio_nr)
379 +{
380 +       int i;
381 +
382 +       /* add a GPIO chip for each register bank.
383 +        * the last PXA25x register only contains 21 GPIOs
384 +        */
385 +       for (i = 0; i < gpio_nr; i += 32) {
386 +               if (i+32 > gpio_nr)
387 +                       pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
388 +               gpiochip_add(&pxa_gpio_chip[i/32].chip);
389 +       }
390 +}
391 diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
392 index 07acb45..d0965ef 100644
393 --- a/arch/arm/mach-pxa/irq.c
394 +++ b/arch/arm/mach-pxa/irq.c
395 @@ -310,6 +310,8 @@ void __init pxa_init_irq_gpio(int gpio_nr)
396         /* Install handler for GPIO>=2 edge detect interrupts */
397         set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
398         set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
399 +
400 +       pxa_init_gpio(gpio_nr);
401  }
402  
403  void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
404 diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h
405 index 9dbc2dc..bdbf5f9 100644
406 --- a/include/asm-arm/arch-pxa/gpio.h
407 +++ b/include/asm-arm/arch-pxa/gpio.h
408 @@ -28,43 +28,35 @@
409  #include <asm/irq.h>
410  #include <asm/hardware.h>
411  
412 -static inline int gpio_request(unsigned gpio, const char *label)
413 -{
414 -       return 0;
415 -}
416 +#include <asm-generic/gpio.h>
417  
418 -static inline void gpio_free(unsigned gpio)
419 -{
420 -       return;
421 -}
422  
423 -extern int gpio_direction_input(unsigned gpio);
424 -extern int gpio_direction_output(unsigned gpio, int value);
425 +/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
426 + * Those cases currently cause holes in the GPIO number space.
427 + */
428 +#define NR_BUILTIN_GPIO 128
429  
430 -static inline int __gpio_get_value(unsigned gpio)
431 +static inline int gpio_get_value(unsigned gpio)
432  {
433 -       return GPLR(gpio) & GPIO_bit(gpio);
434 +       if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
435 +               return GPLR(gpio) & GPIO_bit(gpio);
436 +       else
437 +               return __gpio_get_value(gpio);
438  }
439  
440 -#define gpio_get_value(gpio)                   \
441 -       (__builtin_constant_p(gpio) ?           \
442 -        __gpio_get_value(gpio) :               \
443 -        pxa_gpio_get_value(gpio))
444 -
445 -static inline void __gpio_set_value(unsigned gpio, int value)
446 +static inline void gpio_set_value(unsigned gpio, int value)
447  {
448 -       if (value)
449 -               GPSR(gpio) = GPIO_bit(gpio);
450 -       else
451 -               GPCR(gpio) = GPIO_bit(gpio);
452 +       if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
453 +               if (value)
454 +                       GPSR(gpio) = GPIO_bit(gpio);
455 +               else
456 +                       GPCR(gpio) = GPIO_bit(gpio);
457 +       } else {
458 +               __gpio_set_value(gpio, value);
459 +       }
460  }
461  
462 -#define gpio_set_value(gpio,value)             \
463 -       (__builtin_constant_p(gpio) ?           \
464 -        __gpio_set_value(gpio, value) :        \
465 -        pxa_gpio_set_value(gpio, value))
466 -
467 -#include <asm-generic/gpio.h>                  /* cansleep wrappers */
468 +#define gpio_cansleep __gpio_cansleep
469  
470  #define gpio_to_irq(gpio)      IRQ_GPIO(gpio)
471  #define irq_to_gpio(irq)       IRQ_TO_GPIO(irq)
472 diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
473 index 1bd398d..bd57417 100644
474 --- a/include/asm-arm/arch-pxa/pxa-regs.h
475 +++ b/include/asm-arm/arch-pxa/pxa-regs.h
476 @@ -1131,6 +1131,19 @@
477   * General Purpose I/O
478   */
479  
480 +#define GPIO0_BASE     ((void __iomem *)io_p2v(0x40E00000))
481 +#define GPIO1_BASE     ((void __iomem *)io_p2v(0x40E00004))
482 +#define GPIO2_BASE     ((void __iomem *)io_p2v(0x40E00008))
483 +#define GPIO3_BASE     ((void __iomem *)io_p2v(0x40E00100))
484 +
485 +#define GPLR_OFFSET    0x00
486 +#define GPDR_OFFSET    0x0C
487 +#define GPSR_OFFSET    0x18
488 +#define GPCR_OFFSET    0x24
489 +#define GRER_OFFSET    0x30
490 +#define GFER_OFFSET    0x3C
491 +#define GEDR_OFFSET    0x48
492 +
493  #define GPLR0          __REG(0x40E00000)  /* GPIO Pin-Level Register GPIO<31:0> */
494  #define GPLR1          __REG(0x40E00004)  /* GPIO Pin-Level Register GPIO<63:32> */
495  #define GPLR2          __REG(0x40E00008)  /* GPIO Pin-Level Register GPIO<80:64> */
496 -- 
497 1.5.3.8
498