Commit 1c44f5f16fee880b294f8068354bfb9dddf1349b

Authored by Philipp Zabel
Committed by Linus Torvalds
1 parent 7c2db759ec

gpiolib support for the PXA architecture

This adds gpiolib support for the PXA architecture:
  - move all GPIO API functions from generic.c into gpio.c
  - convert the gpio_get/set_value macros into inline functions

This makes it easier to hook up GPIOs provided by external chips like
ASICs and CPLDs.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Eric Miao <eric.miao@marvell.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: Ben Gardner <bgardner@wabtec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Minor ARM fixup from David Brownell folded into this ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 8 changed files with 236 additions and 122 deletions Side-by-side Diff

... ... @@ -385,6 +385,7 @@
385 385 depends on MMU
386 386 select ARCH_MTD_XIP
387 387 select GENERIC_GPIO
  388 + select HAVE_GPIO_LIB
388 389 select GENERIC_TIME
389 390 select GENERIC_CLOCKEVENTS
390 391 select TICK_ONESHOT
arch/arm/mach-pxa/Makefile
... ... @@ -3,7 +3,8 @@
3 3 #
4 4  
5 5 # Common support (must be linked before board specific support)
6   -obj-y += clock.o devices.o generic.o irq.o dma.o time.o
  6 +obj-y += clock.o devices.o generic.o irq.o dma.o \
  7 + time.o gpio.o
7 8 obj-$(CONFIG_PXA25x) += pxa25x.o
8 9 obj-$(CONFIG_PXA27x) += pxa27x.o
9 10 obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o smemc.o
arch/arm/mach-pxa/generic.c
... ... @@ -32,7 +32,6 @@
32 32 #include <asm/mach/map.h>
33 33  
34 34 #include <asm/arch/pxa-regs.h>
35   -#include <asm/arch/gpio.h>
36 35  
37 36 #include "generic.h"
38 37  
... ... @@ -67,97 +66,6 @@
67 66 EXPORT_SYMBOL(get_memclk_frequency_10khz);
68 67  
69 68 /*
70   - * Handy function to set GPIO alternate functions
71   - */
72   -int pxa_last_gpio;
73   -
74   -int pxa_gpio_mode(int gpio_mode)
75   -{
76   - unsigned long flags;
77   - int gpio = gpio_mode & GPIO_MD_MASK_NR;
78   - int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
79   - int gafr;
80   -
81   - if (gpio > pxa_last_gpio)
82   - return -EINVAL;
83   -
84   - local_irq_save(flags);
85   - if (gpio_mode & GPIO_DFLT_LOW)
86   - GPCR(gpio) = GPIO_bit(gpio);
87   - else if (gpio_mode & GPIO_DFLT_HIGH)
88   - GPSR(gpio) = GPIO_bit(gpio);
89   - if (gpio_mode & GPIO_MD_MASK_DIR)
90   - GPDR(gpio) |= GPIO_bit(gpio);
91   - else
92   - GPDR(gpio) &= ~GPIO_bit(gpio);
93   - gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
94   - GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
95   - local_irq_restore(flags);
96   -
97   - return 0;
98   -}
99   -
100   -EXPORT_SYMBOL(pxa_gpio_mode);
101   -
102   -int gpio_direction_input(unsigned gpio)
103   -{
104   - unsigned long flags;
105   - u32 mask;
106   -
107   - if (gpio > pxa_last_gpio)
108   - return -EINVAL;
109   -
110   - mask = GPIO_bit(gpio);
111   - local_irq_save(flags);
112   - GPDR(gpio) &= ~mask;
113   - local_irq_restore(flags);
114   -
115   - return 0;
116   -}
117   -EXPORT_SYMBOL(gpio_direction_input);
118   -
119   -int gpio_direction_output(unsigned gpio, int value)
120   -{
121   - unsigned long flags;
122   - u32 mask;
123   -
124   - if (gpio > pxa_last_gpio)
125   - return -EINVAL;
126   -
127   - mask = GPIO_bit(gpio);
128   - local_irq_save(flags);
129   - if (value)
130   - GPSR(gpio) = mask;
131   - else
132   - GPCR(gpio) = mask;
133   - GPDR(gpio) |= mask;
134   - local_irq_restore(flags);
135   -
136   - return 0;
137   -}
138   -EXPORT_SYMBOL(gpio_direction_output);
139   -
140   -/*
141   - * Return GPIO level
142   - */
143   -int pxa_gpio_get_value(unsigned gpio)
144   -{
145   - return __gpio_get_value(gpio);
146   -}
147   -
148   -EXPORT_SYMBOL(pxa_gpio_get_value);
149   -
150   -/*
151   - * Set output GPIO level
152   - */
153   -void pxa_gpio_set_value(unsigned gpio, int value)
154   -{
155   - __gpio_set_value(gpio, value);
156   -}
157   -
158   -EXPORT_SYMBOL(pxa_gpio_set_value);
159   -
160   -/*
161 69 * Routine to safely enable or disable a clock in the CKEN
162 70 */
163 71 void __pxa_set_cken(int clock, int enable)
... ... @@ -172,7 +80,6 @@
172 80  
173 81 local_irq_restore(flags);
174 82 }
175   -
176 83 EXPORT_SYMBOL(__pxa_set_cken);
177 84  
178 85 /*
arch/arm/mach-pxa/generic.h
... ... @@ -16,6 +16,7 @@
16 16 extern void __init pxa_init_irq_high(void);
17 17 extern void __init pxa_init_irq_gpio(int gpio_nr);
18 18 extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
  19 +extern void __init pxa_init_gpio(int gpio_nr);
19 20 extern void __init pxa25x_init_irq(void);
20 21 extern void __init pxa27x_init_irq(void);
21 22 extern void __init pxa3xx_init_irq(void);
arch/arm/mach-pxa/gpio.c
  1 +/*
  2 + * linux/arch/arm/mach-pxa/gpio.c
  3 + *
  4 + * Generic PXA GPIO handling
  5 + *
  6 + * Author: Nicolas Pitre
  7 + * Created: Jun 15, 2001
  8 + * Copyright: MontaVista Software Inc.
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License version 2 as
  12 + * published by the Free Software Foundation.
  13 + */
  14 +
  15 +#include <linux/init.h>
  16 +#include <linux/module.h>
  17 +
  18 +#include <asm/gpio.h>
  19 +#include <asm/hardware.h>
  20 +#include <asm/io.h>
  21 +#include <asm/arch/pxa-regs.h>
  22 +
  23 +#include "generic.h"
  24 +
  25 +
  26 +struct pxa_gpio_chip {
  27 + struct gpio_chip chip;
  28 + void __iomem *regbase;
  29 +};
  30 +
  31 +int pxa_last_gpio;
  32 +
  33 +/*
  34 + * Configure pins for GPIO or other functions
  35 + */
  36 +int pxa_gpio_mode(int gpio_mode)
  37 +{
  38 + unsigned long flags;
  39 + int gpio = gpio_mode & GPIO_MD_MASK_NR;
  40 + int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
  41 + int gafr;
  42 +
  43 + if (gpio > pxa_last_gpio)
  44 + return -EINVAL;
  45 +
  46 + local_irq_save(flags);
  47 + if (gpio_mode & GPIO_DFLT_LOW)
  48 + GPCR(gpio) = GPIO_bit(gpio);
  49 + else if (gpio_mode & GPIO_DFLT_HIGH)
  50 + GPSR(gpio) = GPIO_bit(gpio);
  51 + if (gpio_mode & GPIO_MD_MASK_DIR)
  52 + GPDR(gpio) |= GPIO_bit(gpio);
  53 + else
  54 + GPDR(gpio) &= ~GPIO_bit(gpio);
  55 + gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
  56 + GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
  57 + local_irq_restore(flags);
  58 +
  59 + return 0;
  60 +}
  61 +EXPORT_SYMBOL(pxa_gpio_mode);
  62 +
  63 +static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  64 +{
  65 + unsigned long flags;
  66 + u32 mask = 1 << offset;
  67 + u32 value;
  68 + struct pxa_gpio_chip *pxa;
  69 + void __iomem *gpdr;
  70 +
  71 + pxa = container_of(chip, struct pxa_gpio_chip, chip);
  72 + gpdr = pxa->regbase + GPDR_OFFSET;
  73 + local_irq_save(flags);
  74 + value = __raw_readl(gpdr);
  75 + value &= ~mask;
  76 + __raw_writel(value, gpdr);
  77 + local_irq_restore(flags);
  78 +
  79 + return 0;
  80 +}
  81 +
  82 +static int pxa_gpio_direction_output(struct gpio_chip *chip,
  83 + unsigned offset, int value)
  84 +{
  85 + unsigned long flags;
  86 + u32 mask = 1 << offset;
  87 + u32 tmp;
  88 + struct pxa_gpio_chip *pxa;
  89 + void __iomem *gpdr;
  90 +
  91 + pxa = container_of(chip, struct pxa_gpio_chip, chip);
  92 + __raw_writel(mask,
  93 + pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
  94 + gpdr = pxa->regbase + GPDR_OFFSET;
  95 + local_irq_save(flags);
  96 + tmp = __raw_readl(gpdr);
  97 + tmp |= mask;
  98 + __raw_writel(tmp, gpdr);
  99 + local_irq_restore(flags);
  100 +
  101 + return 0;
  102 +}
  103 +
  104 +/*
  105 + * Return GPIO level
  106 + */
  107 +static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
  108 +{
  109 + u32 mask = 1 << offset;
  110 + struct pxa_gpio_chip *pxa;
  111 +
  112 + pxa = container_of(chip, struct pxa_gpio_chip, chip);
  113 + return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
  114 +}
  115 +
  116 +/*
  117 + * Set output GPIO level
  118 + */
  119 +static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  120 +{
  121 + u32 mask = 1 << offset;
  122 + struct pxa_gpio_chip *pxa;
  123 +
  124 + pxa = container_of(chip, struct pxa_gpio_chip, chip);
  125 +
  126 + if (value)
  127 + __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
  128 + else
  129 + __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
  130 +}
  131 +
  132 +static struct pxa_gpio_chip pxa_gpio_chip[] = {
  133 + [0] = {
  134 + .regbase = GPIO0_BASE,
  135 + .chip = {
  136 + .label = "gpio-0",
  137 + .direction_input = pxa_gpio_direction_input,
  138 + .direction_output = pxa_gpio_direction_output,
  139 + .get = pxa_gpio_get,
  140 + .set = pxa_gpio_set,
  141 + .base = 0,
  142 + .ngpio = 32,
  143 + },
  144 + },
  145 + [1] = {
  146 + .regbase = GPIO1_BASE,
  147 + .chip = {
  148 + .label = "gpio-1",
  149 + .direction_input = pxa_gpio_direction_input,
  150 + .direction_output = pxa_gpio_direction_output,
  151 + .get = pxa_gpio_get,
  152 + .set = pxa_gpio_set,
  153 + .base = 32,
  154 + .ngpio = 32,
  155 + },
  156 + },
  157 + [2] = {
  158 + .regbase = GPIO2_BASE,
  159 + .chip = {
  160 + .label = "gpio-2",
  161 + .direction_input = pxa_gpio_direction_input,
  162 + .direction_output = pxa_gpio_direction_output,
  163 + .get = pxa_gpio_get,
  164 + .set = pxa_gpio_set,
  165 + .base = 64,
  166 + .ngpio = 32, /* 21 for PXA25x */
  167 + },
  168 + },
  169 +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
  170 + [3] = {
  171 + .regbase = GPIO3_BASE,
  172 + .chip = {
  173 + .label = "gpio-3",
  174 + .direction_input = pxa_gpio_direction_input,
  175 + .direction_output = pxa_gpio_direction_output,
  176 + .get = pxa_gpio_get,
  177 + .set = pxa_gpio_set,
  178 + .base = 96,
  179 + .ngpio = 32,
  180 + },
  181 + },
  182 +#endif
  183 +};
  184 +
  185 +void __init pxa_init_gpio(int gpio_nr)
  186 +{
  187 + int i;
  188 +
  189 + /* add a GPIO chip for each register bank.
  190 + * the last PXA25x register only contains 21 GPIOs
  191 + */
  192 + for (i = 0; i < gpio_nr; i += 32) {
  193 + if (i+32 > gpio_nr)
  194 + pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
  195 + gpiochip_add(&pxa_gpio_chip[i/32].chip);
  196 + }
  197 +}
arch/arm/mach-pxa/irq.c
... ... @@ -311,6 +311,8 @@
311 311 /* Install handler for GPIO>=2 edge detect interrupts */
312 312 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
313 313 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
  314 +
  315 + pxa_init_gpio(gpio_nr);
314 316 }
315 317  
316 318 void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
include/asm-arm/arch-pxa/gpio.h
... ... @@ -28,43 +28,35 @@
28 28 #include <asm/irq.h>
29 29 #include <asm/hardware.h>
30 30  
31   -static inline int gpio_request(unsigned gpio, const char *label)
32   -{
33   - return 0;
34   -}
  31 +#include <asm-generic/gpio.h>
35 32  
36   -static inline void gpio_free(unsigned gpio)
37   -{
38   - return;
39   -}
40 33  
41   -extern int gpio_direction_input(unsigned gpio);
42   -extern int gpio_direction_output(unsigned gpio, int value);
  34 +/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
  35 + * Those cases currently cause holes in the GPIO number space.
  36 + */
  37 +#define NR_BUILTIN_GPIO 128
43 38  
44   -static inline int __gpio_get_value(unsigned gpio)
  39 +static inline int gpio_get_value(unsigned gpio)
45 40 {
46   - return GPLR(gpio) & GPIO_bit(gpio);
  41 + if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
  42 + return GPLR(gpio) & GPIO_bit(gpio);
  43 + else
  44 + return __gpio_get_value(gpio);
47 45 }
48 46  
49   -#define gpio_get_value(gpio) \
50   - (__builtin_constant_p(gpio) ? \
51   - __gpio_get_value(gpio) : \
52   - pxa_gpio_get_value(gpio))
53   -
54   -static inline void __gpio_set_value(unsigned gpio, int value)
  47 +static inline void gpio_set_value(unsigned gpio, int value)
55 48 {
56   - if (value)
57   - GPSR(gpio) = GPIO_bit(gpio);
58   - else
59   - GPCR(gpio) = GPIO_bit(gpio);
  49 + if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
  50 + if (value)
  51 + GPSR(gpio) = GPIO_bit(gpio);
  52 + else
  53 + GPCR(gpio) = GPIO_bit(gpio);
  54 + } else {
  55 + __gpio_set_value(gpio, value);
  56 + }
60 57 }
61 58  
62   -#define gpio_set_value(gpio,value) \
63   - (__builtin_constant_p(gpio) ? \
64   - __gpio_set_value(gpio, value) : \
65   - pxa_gpio_set_value(gpio, value))
66   -
67   -#include <asm-generic/gpio.h> /* cansleep wrappers */
  59 +#define gpio_cansleep __gpio_cansleep
68 60  
69 61 #define gpio_to_irq(gpio) IRQ_GPIO(gpio)
70 62 #define irq_to_gpio(irq) IRQ_TO_GPIO(irq)
include/asm-arm/arch-pxa/pxa-regs.h
... ... @@ -1131,6 +1131,19 @@
1131 1131 * General Purpose I/O
1132 1132 */
1133 1133  
  1134 +#define GPIO0_BASE ((void __iomem *)io_p2v(0x40E00000))
  1135 +#define GPIO1_BASE ((void __iomem *)io_p2v(0x40E00004))
  1136 +#define GPIO2_BASE ((void __iomem *)io_p2v(0x40E00008))
  1137 +#define GPIO3_BASE ((void __iomem *)io_p2v(0x40E00100))
  1138 +
  1139 +#define GPLR_OFFSET 0x00
  1140 +#define GPDR_OFFSET 0x0C
  1141 +#define GPSR_OFFSET 0x18
  1142 +#define GPCR_OFFSET 0x24
  1143 +#define GRER_OFFSET 0x30
  1144 +#define GFER_OFFSET 0x3C
  1145 +#define GEDR_OFFSET 0x48
  1146 +
1134 1147 #define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */
1135 1148 #define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */
1136 1149 #define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */