diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 17:39:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 17:39:22 -0500 |
commit | 2ac9d7aaccbd598b5bd19ac40761b723bb675442 (patch) | |
tree | 09132a44e33798aaa5e80f10bf025b510015cab3 /drivers/gpio | |
parent | 5ede3ceb7b2c2843e153a1803edbdc8c56655950 (diff) | |
parent | dcf7ec5ee62a78123057a1e286c88ca739717409 (diff) |
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Driver specific changes
Again, a lot of platforms have changes in here: pxa, samsung, omap,
at91, imx, ...
* tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
ARM: sa1100: clean up of the clock support
ARM: pxa: add dummy clock for sa1100-rtc
RTC: sa1100: support sa1100, pxa and mmp soc families
RTC: sa1100: remove redundant code of setting alarm
RTC: sa1100: Clean out ost register
Input: zylonite-wm97xx - replace IRQ_GPIO() with gpio_to_irq()
pcmcia: pxa: replace IRQ_GPIO() with gpio_to_irq()
ARM: EXYNOS: Modified files for SPI consolidation work
ARM: S5P64X0: Enable SDHCI support
ARM: S5P64X0: Add lookup of sdhci-s3c clocks using generic names
ARM: S5P64X0: Add HSMMC setup for host Controller
ARM: EXYNOS: Add USB OHCI support to ORIGEN board
USB: Add Samsung Exynos OHCI diver
ARM: EXYNOS: Add USB OHCI support to SMDKV310 board
ARM: EXYNOS: Add USB OHCI device
net: macb: fix build break with !CONFIG_OF
i2c: tegra: Support DVC controller in device tree
i2c: tegra: Add __devinit/exit to probe/remove
net/at91_ether: use gpio_is_valid for phy IRQ line
ARM: at91/net: add macb ethernet controller in 9g45/9g20 DT
...
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 6 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-pxa.c | 377 |
3 files changed, 334 insertions, 51 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5099681cf503..e3380137b05b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -141,6 +141,12 @@ config GPIO_PL061 | |||
141 | help | 141 | help |
142 | Say yes here to support the PrimeCell PL061 GPIO device | 142 | Say yes here to support the PrimeCell PL061 GPIO device |
143 | 143 | ||
144 | config GPIO_PXA | ||
145 | bool "PXA GPIO support" | ||
146 | depends on ARCH_PXA || ARCH_MMP | ||
147 | help | ||
148 | Say yes here to support the PXA GPIO device | ||
149 | |||
144 | config GPIO_XILINX | 150 | config GPIO_XILINX |
145 | bool "Xilinx GPIO support" | 151 | bool "Xilinx GPIO support" |
146 | depends on PPC_OF || MICROBLAZE | 152 | depends on PPC_OF || MICROBLAZE |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4e018d6a7639..8ef9e9abe970 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -40,7 +40,7 @@ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | |||
40 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | 40 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o |
41 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | 41 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o |
42 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | 42 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o |
43 | obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o | 43 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o |
44 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | 44 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
45 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | 45 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o |
46 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 46 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index ee137712f9db..b2d3ee1d183a 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -11,14 +11,46 @@ | |||
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | ||
14 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/gpio-pxa.h> | ||
15 | #include <linux/init.h> | 18 | #include <linux/init.h> |
16 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
17 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/platform_device.h> | ||
18 | #include <linux/syscore_ops.h> | 22 | #include <linux/syscore_ops.h> |
19 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
20 | 24 | ||
21 | #include <mach/gpio-pxa.h> | 25 | /* |
26 | * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with | ||
27 | * one set of registers. The register offsets are organized below: | ||
28 | * | ||
29 | * GPLR GPDR GPSR GPCR GRER GFER GEDR | ||
30 | * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 | ||
31 | * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C | ||
32 | * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 | ||
33 | * | ||
34 | * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 | ||
35 | * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C | ||
36 | * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 | ||
37 | * | ||
38 | * NOTE: | ||
39 | * BANK 3 is only available on PXA27x and later processors. | ||
40 | * BANK 4 and 5 are only available on PXA935 | ||
41 | */ | ||
42 | |||
43 | #define GPLR_OFFSET 0x00 | ||
44 | #define GPDR_OFFSET 0x0C | ||
45 | #define GPSR_OFFSET 0x18 | ||
46 | #define GPCR_OFFSET 0x24 | ||
47 | #define GRER_OFFSET 0x30 | ||
48 | #define GFER_OFFSET 0x3C | ||
49 | #define GEDR_OFFSET 0x48 | ||
50 | #define GAFR_OFFSET 0x54 | ||
51 | #define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ | ||
52 | |||
53 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) | ||
22 | 54 | ||
23 | int pxa_last_gpio; | 55 | int pxa_last_gpio; |
24 | 56 | ||
@@ -39,8 +71,20 @@ struct pxa_gpio_chip { | |||
39 | #endif | 71 | #endif |
40 | }; | 72 | }; |
41 | 73 | ||
74 | enum { | ||
75 | PXA25X_GPIO = 0, | ||
76 | PXA26X_GPIO, | ||
77 | PXA27X_GPIO, | ||
78 | PXA3XX_GPIO, | ||
79 | PXA93X_GPIO, | ||
80 | MMP_GPIO = 0x10, | ||
81 | MMP2_GPIO, | ||
82 | }; | ||
83 | |||
42 | static DEFINE_SPINLOCK(gpio_lock); | 84 | static DEFINE_SPINLOCK(gpio_lock); |
43 | static struct pxa_gpio_chip *pxa_gpio_chips; | 85 | static struct pxa_gpio_chip *pxa_gpio_chips; |
86 | static int gpio_type; | ||
87 | static void __iomem *gpio_reg_base; | ||
44 | 88 | ||
45 | #define for_each_gpio_chip(i, c) \ | 89 | #define for_each_gpio_chip(i, c) \ |
46 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) | 90 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) |
@@ -55,6 +99,122 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) | |||
55 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; | 99 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; |
56 | } | 100 | } |
57 | 101 | ||
102 | static inline int gpio_is_pxa_type(int type) | ||
103 | { | ||
104 | return (type & MMP_GPIO) == 0; | ||
105 | } | ||
106 | |||
107 | static inline int gpio_is_mmp_type(int type) | ||
108 | { | ||
109 | return (type & MMP_GPIO) != 0; | ||
110 | } | ||
111 | |||
112 | /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, | ||
113 | * as well as their Alternate Function value being '1' for GPIO in GAFRx. | ||
114 | */ | ||
115 | static inline int __gpio_is_inverted(int gpio) | ||
116 | { | ||
117 | if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) | ||
118 | return 1; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate | ||
124 | * function of a GPIO, and GPDRx cannot be altered once configured. It | ||
125 | * is attributed as "occupied" here (I know this terminology isn't | ||
126 | * accurate, you are welcome to propose a better one :-) | ||
127 | */ | ||
128 | static inline int __gpio_is_occupied(unsigned gpio) | ||
129 | { | ||
130 | struct pxa_gpio_chip *pxachip; | ||
131 | void __iomem *base; | ||
132 | unsigned long gafr = 0, gpdr = 0; | ||
133 | int ret, af = 0, dir = 0; | ||
134 | |||
135 | pxachip = gpio_to_pxachip(gpio); | ||
136 | base = gpio_chip_base(&pxachip->chip); | ||
137 | gpdr = readl_relaxed(base + GPDR_OFFSET); | ||
138 | |||
139 | switch (gpio_type) { | ||
140 | case PXA25X_GPIO: | ||
141 | case PXA26X_GPIO: | ||
142 | case PXA27X_GPIO: | ||
143 | gafr = readl_relaxed(base + GAFR_OFFSET); | ||
144 | af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; | ||
145 | dir = gpdr & GPIO_bit(gpio); | ||
146 | |||
147 | if (__gpio_is_inverted(gpio)) | ||
148 | ret = (af != 1) || (dir == 0); | ||
149 | else | ||
150 | ret = (af != 0) || (dir != 0); | ||
151 | break; | ||
152 | default: | ||
153 | ret = gpdr & GPIO_bit(gpio); | ||
154 | break; | ||
155 | } | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | #ifdef CONFIG_ARCH_PXA | ||
160 | static inline int __pxa_gpio_to_irq(int gpio) | ||
161 | { | ||
162 | if (gpio_is_pxa_type(gpio_type)) | ||
163 | return PXA_GPIO_TO_IRQ(gpio); | ||
164 | return -1; | ||
165 | } | ||
166 | |||
167 | static inline int __pxa_irq_to_gpio(int irq) | ||
168 | { | ||
169 | if (gpio_is_pxa_type(gpio_type)) | ||
170 | return irq - PXA_GPIO_TO_IRQ(0); | ||
171 | return -1; | ||
172 | } | ||
173 | #else | ||
174 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } | ||
175 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } | ||
176 | #endif | ||
177 | |||
178 | #ifdef CONFIG_ARCH_MMP | ||
179 | static inline int __mmp_gpio_to_irq(int gpio) | ||
180 | { | ||
181 | if (gpio_is_mmp_type(gpio_type)) | ||
182 | return MMP_GPIO_TO_IRQ(gpio); | ||
183 | return -1; | ||
184 | } | ||
185 | |||
186 | static inline int __mmp_irq_to_gpio(int irq) | ||
187 | { | ||
188 | if (gpio_is_mmp_type(gpio_type)) | ||
189 | return irq - MMP_GPIO_TO_IRQ(0); | ||
190 | return -1; | ||
191 | } | ||
192 | #else | ||
193 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } | ||
194 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } | ||
195 | #endif | ||
196 | |||
197 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
198 | { | ||
199 | int gpio, ret; | ||
200 | |||
201 | gpio = chip->base + offset; | ||
202 | ret = __pxa_gpio_to_irq(gpio); | ||
203 | if (ret >= 0) | ||
204 | return ret; | ||
205 | return __mmp_gpio_to_irq(gpio); | ||
206 | } | ||
207 | |||
208 | int pxa_irq_to_gpio(int irq) | ||
209 | { | ||
210 | int ret; | ||
211 | |||
212 | ret = __pxa_irq_to_gpio(irq); | ||
213 | if (ret >= 0) | ||
214 | return ret; | ||
215 | return __mmp_irq_to_gpio(irq); | ||
216 | } | ||
217 | |||
58 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 218 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
59 | { | 219 | { |
60 | void __iomem *base = gpio_chip_base(chip); | 220 | void __iomem *base = gpio_chip_base(chip); |
@@ -63,12 +223,12 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
63 | 223 | ||
64 | spin_lock_irqsave(&gpio_lock, flags); | 224 | spin_lock_irqsave(&gpio_lock, flags); |
65 | 225 | ||
66 | value = __raw_readl(base + GPDR_OFFSET); | 226 | value = readl_relaxed(base + GPDR_OFFSET); |
67 | if (__gpio_is_inverted(chip->base + offset)) | 227 | if (__gpio_is_inverted(chip->base + offset)) |
68 | value |= mask; | 228 | value |= mask; |
69 | else | 229 | else |
70 | value &= ~mask; | 230 | value &= ~mask; |
71 | __raw_writel(value, base + GPDR_OFFSET); | 231 | writel_relaxed(value, base + GPDR_OFFSET); |
72 | 232 | ||
73 | spin_unlock_irqrestore(&gpio_lock, flags); | 233 | spin_unlock_irqrestore(&gpio_lock, flags); |
74 | return 0; | 234 | return 0; |
@@ -81,16 +241,16 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, | |||
81 | uint32_t tmp, mask = 1 << offset; | 241 | uint32_t tmp, mask = 1 << offset; |
82 | unsigned long flags; | 242 | unsigned long flags; |
83 | 243 | ||
84 | __raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); | 244 | writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); |
85 | 245 | ||
86 | spin_lock_irqsave(&gpio_lock, flags); | 246 | spin_lock_irqsave(&gpio_lock, flags); |
87 | 247 | ||
88 | tmp = __raw_readl(base + GPDR_OFFSET); | 248 | tmp = readl_relaxed(base + GPDR_OFFSET); |
89 | if (__gpio_is_inverted(chip->base + offset)) | 249 | if (__gpio_is_inverted(chip->base + offset)) |
90 | tmp &= ~mask; | 250 | tmp &= ~mask; |
91 | else | 251 | else |
92 | tmp |= mask; | 252 | tmp |= mask; |
93 | __raw_writel(tmp, base + GPDR_OFFSET); | 253 | writel_relaxed(tmp, base + GPDR_OFFSET); |
94 | 254 | ||
95 | spin_unlock_irqrestore(&gpio_lock, flags); | 255 | spin_unlock_irqrestore(&gpio_lock, flags); |
96 | return 0; | 256 | return 0; |
@@ -98,16 +258,16 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, | |||
98 | 258 | ||
99 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) | 259 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) |
100 | { | 260 | { |
101 | return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); | 261 | return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); |
102 | } | 262 | } |
103 | 263 | ||
104 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 264 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
105 | { | 265 | { |
106 | __raw_writel(1 << offset, gpio_chip_base(chip) + | 266 | writel_relaxed(1 << offset, gpio_chip_base(chip) + |
107 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 267 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
108 | } | 268 | } |
109 | 269 | ||
110 | static int __init pxa_init_gpio_chip(int gpio_end) | 270 | static int __devinit pxa_init_gpio_chip(int gpio_end) |
111 | { | 271 | { |
112 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 272 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
113 | struct pxa_gpio_chip *chips; | 273 | struct pxa_gpio_chip *chips; |
@@ -122,7 +282,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) | |||
122 | struct gpio_chip *c = &chips[i].chip; | 282 | struct gpio_chip *c = &chips[i].chip; |
123 | 283 | ||
124 | sprintf(chips[i].label, "gpio-%d", i); | 284 | sprintf(chips[i].label, "gpio-%d", i); |
125 | chips[i].regbase = GPIO_BANK(i); | 285 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); |
126 | 286 | ||
127 | c->base = gpio; | 287 | c->base = gpio; |
128 | c->label = chips[i].label; | 288 | c->label = chips[i].label; |
@@ -131,6 +291,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) | |||
131 | c->direction_output = pxa_gpio_direction_output; | 291 | c->direction_output = pxa_gpio_direction_output; |
132 | c->get = pxa_gpio_get; | 292 | c->get = pxa_gpio_get; |
133 | c->set = pxa_gpio_set; | 293 | c->set = pxa_gpio_set; |
294 | c->to_irq = pxa_gpio_to_irq; | ||
134 | 295 | ||
135 | /* number of GPIOs on last bank may be less than 32 */ | 296 | /* number of GPIOs on last bank may be less than 32 */ |
136 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 297 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
@@ -147,18 +308,18 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c) | |||
147 | { | 308 | { |
148 | uint32_t grer, gfer; | 309 | uint32_t grer, gfer; |
149 | 310 | ||
150 | grer = __raw_readl(c->regbase + GRER_OFFSET) & ~c->irq_mask; | 311 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask; |
151 | gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~c->irq_mask; | 312 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask; |
152 | grer |= c->irq_edge_rise & c->irq_mask; | 313 | grer |= c->irq_edge_rise & c->irq_mask; |
153 | gfer |= c->irq_edge_fall & c->irq_mask; | 314 | gfer |= c->irq_edge_fall & c->irq_mask; |
154 | __raw_writel(grer, c->regbase + GRER_OFFSET); | 315 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
155 | __raw_writel(gfer, c->regbase + GFER_OFFSET); | 316 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
156 | } | 317 | } |
157 | 318 | ||
158 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | 319 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) |
159 | { | 320 | { |
160 | struct pxa_gpio_chip *c; | 321 | struct pxa_gpio_chip *c; |
161 | int gpio = irq_to_gpio(d->irq); | 322 | int gpio = pxa_irq_to_gpio(d->irq); |
162 | unsigned long gpdr, mask = GPIO_bit(gpio); | 323 | unsigned long gpdr, mask = GPIO_bit(gpio); |
163 | 324 | ||
164 | c = gpio_to_pxachip(gpio); | 325 | c = gpio_to_pxachip(gpio); |
@@ -176,12 +337,12 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
176 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 337 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
177 | } | 338 | } |
178 | 339 | ||
179 | gpdr = __raw_readl(c->regbase + GPDR_OFFSET); | 340 | gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
180 | 341 | ||
181 | if (__gpio_is_inverted(gpio)) | 342 | if (__gpio_is_inverted(gpio)) |
182 | __raw_writel(gpdr | mask, c->regbase + GPDR_OFFSET); | 343 | writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET); |
183 | else | 344 | else |
184 | __raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET); | 345 | writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET); |
185 | 346 | ||
186 | if (type & IRQ_TYPE_EDGE_RISING) | 347 | if (type & IRQ_TYPE_EDGE_RISING) |
187 | c->irq_edge_rise |= mask; | 348 | c->irq_edge_rise |= mask; |
@@ -212,9 +373,9 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
212 | for_each_gpio_chip(gpio, c) { | 373 | for_each_gpio_chip(gpio, c) { |
213 | gpio_base = c->chip.base; | 374 | gpio_base = c->chip.base; |
214 | 375 | ||
215 | gedr = __raw_readl(c->regbase + GEDR_OFFSET); | 376 | gedr = readl_relaxed(c->regbase + GEDR_OFFSET); |
216 | gedr = gedr & c->irq_mask; | 377 | gedr = gedr & c->irq_mask; |
217 | __raw_writel(gedr, c->regbase + GEDR_OFFSET); | 378 | writel_relaxed(gedr, c->regbase + GEDR_OFFSET); |
218 | 379 | ||
219 | n = find_first_bit(&gedr, BITS_PER_LONG); | 380 | n = find_first_bit(&gedr, BITS_PER_LONG); |
220 | while (n < BITS_PER_LONG) { | 381 | while (n < BITS_PER_LONG) { |
@@ -229,29 +390,29 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
229 | 390 | ||
230 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 391 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
231 | { | 392 | { |
232 | int gpio = irq_to_gpio(d->irq); | 393 | int gpio = pxa_irq_to_gpio(d->irq); |
233 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 394 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
234 | 395 | ||
235 | __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); | 396 | writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); |
236 | } | 397 | } |
237 | 398 | ||
238 | static void pxa_mask_muxed_gpio(struct irq_data *d) | 399 | static void pxa_mask_muxed_gpio(struct irq_data *d) |
239 | { | 400 | { |
240 | int gpio = irq_to_gpio(d->irq); | 401 | int gpio = pxa_irq_to_gpio(d->irq); |
241 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 402 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
242 | uint32_t grer, gfer; | 403 | uint32_t grer, gfer; |
243 | 404 | ||
244 | c->irq_mask &= ~GPIO_bit(gpio); | 405 | c->irq_mask &= ~GPIO_bit(gpio); |
245 | 406 | ||
246 | grer = __raw_readl(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); | 407 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); |
247 | gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); | 408 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); |
248 | __raw_writel(grer, c->regbase + GRER_OFFSET); | 409 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
249 | __raw_writel(gfer, c->regbase + GFER_OFFSET); | 410 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
250 | } | 411 | } |
251 | 412 | ||
252 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | 413 | static void pxa_unmask_muxed_gpio(struct irq_data *d) |
253 | { | 414 | { |
254 | int gpio = irq_to_gpio(d->irq); | 415 | int gpio = pxa_irq_to_gpio(d->irq); |
255 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 416 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
256 | 417 | ||
257 | c->irq_mask |= GPIO_bit(gpio); | 418 | c->irq_mask |= GPIO_bit(gpio); |
@@ -266,34 +427,143 @@ static struct irq_chip pxa_muxed_gpio_chip = { | |||
266 | .irq_set_type = pxa_gpio_irq_type, | 427 | .irq_set_type = pxa_gpio_irq_type, |
267 | }; | 428 | }; |
268 | 429 | ||
269 | void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) | 430 | static int pxa_gpio_nums(void) |
270 | { | 431 | { |
271 | struct pxa_gpio_chip *c; | 432 | int count = 0; |
272 | int gpio, irq; | 433 | |
434 | #ifdef CONFIG_ARCH_PXA | ||
435 | if (cpu_is_pxa25x()) { | ||
436 | #ifdef CONFIG_CPU_PXA26x | ||
437 | count = 89; | ||
438 | gpio_type = PXA26X_GPIO; | ||
439 | #elif defined(CONFIG_PXA25x) | ||
440 | count = 84; | ||
441 | gpio_type = PXA26X_GPIO; | ||
442 | #endif /* CONFIG_CPU_PXA26x */ | ||
443 | } else if (cpu_is_pxa27x()) { | ||
444 | count = 120; | ||
445 | gpio_type = PXA27X_GPIO; | ||
446 | } else if (cpu_is_pxa93x() || cpu_is_pxa95x()) { | ||
447 | count = 191; | ||
448 | gpio_type = PXA93X_GPIO; | ||
449 | } else if (cpu_is_pxa3xx()) { | ||
450 | count = 127; | ||
451 | gpio_type = PXA3XX_GPIO; | ||
452 | } | ||
453 | #endif /* CONFIG_ARCH_PXA */ | ||
454 | |||
455 | #ifdef CONFIG_ARCH_MMP | ||
456 | if (cpu_is_pxa168() || cpu_is_pxa910()) { | ||
457 | count = 127; | ||
458 | gpio_type = MMP_GPIO; | ||
459 | } else if (cpu_is_mmp2()) { | ||
460 | count = 191; | ||
461 | gpio_type = MMP2_GPIO; | ||
462 | } | ||
463 | #endif /* CONFIG_ARCH_MMP */ | ||
464 | return count; | ||
465 | } | ||
273 | 466 | ||
274 | pxa_last_gpio = end; | 467 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) |
468 | { | ||
469 | struct pxa_gpio_chip *c; | ||
470 | struct resource *res; | ||
471 | struct clk *clk; | ||
472 | int gpio, irq, ret; | ||
473 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | ||
474 | |||
475 | pxa_last_gpio = pxa_gpio_nums(); | ||
476 | if (!pxa_last_gpio) | ||
477 | return -EINVAL; | ||
478 | |||
479 | irq0 = platform_get_irq_byname(pdev, "gpio0"); | ||
480 | irq1 = platform_get_irq_byname(pdev, "gpio1"); | ||
481 | irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); | ||
482 | if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) | ||
483 | || (irq_mux <= 0)) | ||
484 | return -EINVAL; | ||
485 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
486 | if (!res) | ||
487 | return -EINVAL; | ||
488 | gpio_reg_base = ioremap(res->start, resource_size(res)); | ||
489 | if (!gpio_reg_base) | ||
490 | return -EINVAL; | ||
491 | |||
492 | if (irq0 > 0) | ||
493 | gpio_offset = 2; | ||
494 | |||
495 | clk = clk_get(&pdev->dev, NULL); | ||
496 | if (IS_ERR(clk)) { | ||
497 | dev_err(&pdev->dev, "Error %ld to get gpio clock\n", | ||
498 | PTR_ERR(clk)); | ||
499 | iounmap(gpio_reg_base); | ||
500 | return PTR_ERR(clk); | ||
501 | } | ||
502 | ret = clk_prepare(clk); | ||
503 | if (ret) { | ||
504 | clk_put(clk); | ||
505 | iounmap(gpio_reg_base); | ||
506 | return ret; | ||
507 | } | ||
508 | ret = clk_enable(clk); | ||
509 | if (ret) { | ||
510 | clk_unprepare(clk); | ||
511 | clk_put(clk); | ||
512 | iounmap(gpio_reg_base); | ||
513 | return ret; | ||
514 | } | ||
275 | 515 | ||
276 | /* Initialize GPIO chips */ | 516 | /* Initialize GPIO chips */ |
277 | pxa_init_gpio_chip(end); | 517 | pxa_init_gpio_chip(pxa_last_gpio); |
278 | 518 | ||
279 | /* clear all GPIO edge detects */ | 519 | /* clear all GPIO edge detects */ |
280 | for_each_gpio_chip(gpio, c) { | 520 | for_each_gpio_chip(gpio, c) { |
281 | __raw_writel(0, c->regbase + GFER_OFFSET); | 521 | writel_relaxed(0, c->regbase + GFER_OFFSET); |
282 | __raw_writel(0, c->regbase + GRER_OFFSET); | 522 | writel_relaxed(0, c->regbase + GRER_OFFSET); |
283 | __raw_writel(~0,c->regbase + GEDR_OFFSET); | 523 | writel_relaxed(~0,c->regbase + GEDR_OFFSET); |
524 | /* unmask GPIO edge detect for AP side */ | ||
525 | if (gpio_is_mmp_type(gpio_type)) | ||
526 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); | ||
284 | } | 527 | } |
285 | 528 | ||
286 | for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { | 529 | #ifdef CONFIG_ARCH_PXA |
530 | irq = gpio_to_irq(0); | ||
531 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
532 | handle_edge_irq); | ||
533 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
534 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); | ||
535 | |||
536 | irq = gpio_to_irq(1); | ||
537 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
538 | handle_edge_irq); | ||
539 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
540 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); | ||
541 | #endif | ||
542 | |||
543 | for (irq = gpio_to_irq(gpio_offset); | ||
544 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { | ||
287 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 545 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
288 | handle_edge_irq); | 546 | handle_edge_irq); |
289 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 547 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
290 | } | 548 | } |
291 | 549 | ||
292 | /* Install handler for GPIO>=2 edge detect interrupts */ | 550 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); |
293 | irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); | 551 | return 0; |
294 | pxa_muxed_gpio_chip.irq_set_wake = fn; | ||
295 | } | 552 | } |
296 | 553 | ||
554 | static struct platform_driver pxa_gpio_driver = { | ||
555 | .probe = pxa_gpio_probe, | ||
556 | .driver = { | ||
557 | .name = "pxa-gpio", | ||
558 | }, | ||
559 | }; | ||
560 | |||
561 | static int __init pxa_gpio_init(void) | ||
562 | { | ||
563 | return platform_driver_register(&pxa_gpio_driver); | ||
564 | } | ||
565 | postcore_initcall(pxa_gpio_init); | ||
566 | |||
297 | #ifdef CONFIG_PM | 567 | #ifdef CONFIG_PM |
298 | static int pxa_gpio_suspend(void) | 568 | static int pxa_gpio_suspend(void) |
299 | { | 569 | { |
@@ -301,13 +571,13 @@ static int pxa_gpio_suspend(void) | |||
301 | int gpio; | 571 | int gpio; |
302 | 572 | ||
303 | for_each_gpio_chip(gpio, c) { | 573 | for_each_gpio_chip(gpio, c) { |
304 | c->saved_gplr = __raw_readl(c->regbase + GPLR_OFFSET); | 574 | c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); |
305 | c->saved_gpdr = __raw_readl(c->regbase + GPDR_OFFSET); | 575 | c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
306 | c->saved_grer = __raw_readl(c->regbase + GRER_OFFSET); | 576 | c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); |
307 | c->saved_gfer = __raw_readl(c->regbase + GFER_OFFSET); | 577 | c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET); |
308 | 578 | ||
309 | /* Clear GPIO transition detect bits */ | 579 | /* Clear GPIO transition detect bits */ |
310 | __raw_writel(0xffffffff, c->regbase + GEDR_OFFSET); | 580 | writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET); |
311 | } | 581 | } |
312 | return 0; | 582 | return 0; |
313 | } | 583 | } |
@@ -319,12 +589,12 @@ static void pxa_gpio_resume(void) | |||
319 | 589 | ||
320 | for_each_gpio_chip(gpio, c) { | 590 | for_each_gpio_chip(gpio, c) { |
321 | /* restore level with set/clear */ | 591 | /* restore level with set/clear */ |
322 | __raw_writel( c->saved_gplr, c->regbase + GPSR_OFFSET); | 592 | writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET); |
323 | __raw_writel(~c->saved_gplr, c->regbase + GPCR_OFFSET); | 593 | writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); |
324 | 594 | ||
325 | __raw_writel(c->saved_grer, c->regbase + GRER_OFFSET); | 595 | writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET); |
326 | __raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET); | 596 | writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET); |
327 | __raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET); | 597 | writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET); |
328 | } | 598 | } |
329 | } | 599 | } |
330 | #else | 600 | #else |
@@ -336,3 +606,10 @@ struct syscore_ops pxa_gpio_syscore_ops = { | |||
336 | .suspend = pxa_gpio_suspend, | 606 | .suspend = pxa_gpio_suspend, |
337 | .resume = pxa_gpio_resume, | 607 | .resume = pxa_gpio_resume, |
338 | }; | 608 | }; |
609 | |||
610 | static int __init pxa_gpio_sysinit(void) | ||
611 | { | ||
612 | register_syscore_ops(&pxa_gpio_syscore_ops); | ||
613 | return 0; | ||
614 | } | ||
615 | postcore_initcall(pxa_gpio_sysinit); | ||