[au1000] prepare to support more au1x00 targets
[openwrt/svn-archive/archive.git] / target / linux / au1000 / patches-2.6.27 / 007-gpiolib.patch
1 --- a/arch/mips/au1000/Kconfig
2 +++ b/arch/mips/au1000/Kconfig
3 @@ -134,3 +134,4 @@ config SOC_AU1X00
4 select SYS_HAS_CPU_MIPS32_R1
5 select SYS_SUPPORTS_32BIT_KERNEL
6 select SYS_SUPPORTS_APM_EMULATION
7 + select ARCH_REQUIRE_GPIOLIB
8 --- a/arch/mips/au1000/common/gpio.c
9 +++ b/arch/mips/au1000/common/gpio.c
10 @@ -1,5 +1,5 @@
11 /*
12 - * Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
13 + * Copyright (C) 2007-2008, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
14 * Architecture specific GPIO support
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 @@ -27,122 +27,222 @@
18 * others have a second one : GPIO2
19 */
20
21 +#include <linux/kernel.h>
22 #include <linux/module.h>
23 +#include <linux/types.h>
24 +#include <linux/platform_device.h>
25 +#include <linux/gpio.h>
26
27 #include <asm/mach-au1x00/au1000.h>
28 -#include <asm/gpio.h>
29 +#include <asm/mach-au1x00/gpio.h>
30
31 -#define gpio1 sys
32 -#if !defined(CONFIG_SOC_AU1000)
33 +struct au1000_gpio_chip {
34 + struct gpio_chip chip;
35 + void __iomem *regbase;
36 +};
37
38 -static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE;
39 +#if !defined(CONFIG_SOC_AU1000)
40 #define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
41
42 -static int au1xxx_gpio2_read(unsigned gpio)
43 +/*
44 + * Return GPIO bank 2 level
45 + */
46 +static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
47 {
48 - gpio -= AU1XXX_GPIO_BASE;
49 - return ((gpio2->pinstate >> gpio) & 0x01);
50 + u32 mask = 1 << offset;
51 + struct au1000_gpio_chip *gpch;
52 +
53 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
54 + return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
55 }
56
57 -static void au1xxx_gpio2_write(unsigned gpio, int value)
58 +/*
59 + * Set output GPIO bank 2 level
60 + */
61 +static void au1000_gpio2_set(struct gpio_chip *chip,
62 + unsigned offset, int value)
63 {
64 - gpio -= AU1XXX_GPIO_BASE;
65 -
66 - gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
67 + u32 mask = (!!value) << offset;
68 + struct au1000_gpio_chip *gpch;
69 + unsigned long flags;
70 +
71 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
72 +
73 + local_irq_save(flags);
74 + writel((GPIO2_OUTPUT_ENABLE_MASK << offset) | mask,
75 + gpch->regbase + AU1000_GPIO2_OUT);
76 + local_irq_restore(flags);
77 }
78
79 -static int au1xxx_gpio2_direction_input(unsigned gpio)
80 +/*
81 + * Set GPIO bank 2 direction to input
82 + */
83 +static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
84 {
85 - gpio -= AU1XXX_GPIO_BASE;
86 - gpio2->dir &= ~(0x01 << gpio);
87 + unsigned long flags;
88 + u32 mask = 1 << offset;
89 + u32 value;
90 + struct au1000_gpio_chip *gpch;
91 + void __iomem *gpdr;
92 +
93 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
94 + gpdr = gpch->regbase + AU1000_GPIO2_DIR;
95 +
96 + local_irq_save(flags);
97 + value = readl(gpdr);
98 + value &= ~mask;
99 + writel(value, gpdr);
100 + local_irq_restore(flags);
101 +
102 return 0;
103 }
104
105 -static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
106 +/*
107 + * Set GPIO bank2 direction to output
108 + */
109 +static int au1000_gpio2_direction_output(struct gpio_chip *chip,
110 + unsigned offset, int value)
111 {
112 - gpio -= AU1XXX_GPIO_BASE;
113 - gpio2->dir |= 0x01 << gpio;
114 - gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
115 + unsigned long flags;
116 + u32 mask = 1 << offset;
117 + u32 tmp;
118 + struct au1000_gpio_chip *gpch;
119 + void __iomem *gpdr;
120 +
121 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
122 + gpdr = gpch->regbase + AU1000_GPIO2_DIR;
123 +
124 + local_irq_save(flags);
125 + tmp = readl(gpdr);
126 + tmp |= mask;
127 + writel(tmp, gpdr);
128 + mask = (!!value) << offset;
129 + writel((GPIO2_OUTPUT_ENABLE_MASK << offset) | mask,
130 + gpch->regbase + AU1000_GPIO2_OUT);
131 + local_irq_restore(flags);
132 +
133 return 0;
134 }
135 -
136 #endif /* !defined(CONFIG_SOC_AU1000) */
137
138 -static int au1xxx_gpio1_read(unsigned gpio)
139 +/*
140 + * Return GPIO bank 2 level
141 + */
142 +static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
143 {
144 - return (gpio1->pinstaterd >> gpio) & 0x01;
145 + u32 mask = 1 << offset;
146 + struct au1000_gpio_chip *gpch;
147 +
148 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
149 + return readl(gpch->regbase + 0x0110) & mask;
150 }
151
152 -static void au1xxx_gpio1_write(unsigned gpio, int value)
153 +/*
154 + * Set GPIO bank 1 level
155 + */
156 +static void au1000_gpio1_set(struct gpio_chip *chip,
157 + unsigned offset, int value)
158 {
159 + unsigned long flags;
160 + u32 mask = 1 << offset;
161 + struct au1000_gpio_chip *gpch;
162 +
163 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
164 +
165 + local_irq_save(flags);
166 if (value)
167 - gpio1->outputset = (0x01 << gpio);
168 + writel(mask, gpch->regbase + 0x0108);
169 else
170 - /* Output a zero */
171 - gpio1->outputclr = (0x01 << gpio);
172 + writel(mask, gpch->regbase + 0x010C);
173 + local_irq_restore(flags);
174 }
175
176 -static int au1xxx_gpio1_direction_input(unsigned gpio)
177 +/*
178 + * Set GPIO bank 1 direction to input
179 + */
180 +static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
181 {
182 - gpio1->pininputen = (0x01 << gpio);
183 - return 0;
184 -}
185 + unsigned long flags;
186 + u32 mask = 1 << offset;
187 + u32 value;
188 + struct au1000_gpio_chip *gpch;
189 + void __iomem *gpdr;
190 +
191 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
192 + gpdr = gpch->regbase + 0x0110;
193 +
194 + local_irq_save(flags);
195 + value = readl(gpdr);
196 + value |= mask;
197 + writel(mask, gpdr);
198 + local_irq_restore(flags);
199
200 -static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
201 -{
202 - gpio1->trioutclr = (0x01 & gpio);
203 - au1xxx_gpio1_write(gpio, value);
204 return 0;
205 }
206
207 -int au1xxx_gpio_get_value(unsigned gpio)
208 +/*
209 + * Set GPIO bank 1 direction to output
210 + */
211 +static int au1000_gpio1_direction_output(struct gpio_chip *chip,
212 + unsigned offset, int value)
213 {
214 - if (gpio >= AU1XXX_GPIO_BASE)
215 -#if defined(CONFIG_SOC_AU1000)
216 - return 0;
217 -#else
218 - return au1xxx_gpio2_read(gpio);
219 -#endif
220 + unsigned long flags;
221 + u32 mask = 1 << offset;
222 + u32 tmp;
223 + struct au1000_gpio_chip *gpch;
224 + void __iomem *gpdr;
225 +
226 + gpch = container_of(chip, struct au1000_gpio_chip, chip);
227 + gpdr = gpch->regbase + 0x0100;
228 +
229 + local_irq_save(flags);
230 + tmp = readl(gpdr);
231 + writel(tmp, gpdr);
232 + if (value)
233 + writel(mask, gpch->regbase + 0x0108);
234 else
235 - return au1xxx_gpio1_read(gpio);
236 -}
237 -EXPORT_SYMBOL(au1xxx_gpio_get_value);
238 + writel(mask, gpch->regbase + 0x0108);
239 + local_irq_restore(flags);
240
241 -void au1xxx_gpio_set_value(unsigned gpio, int value)
242 -{
243 - if (gpio >= AU1XXX_GPIO_BASE)
244 -#if defined(CONFIG_SOC_AU1000)
245 - ;
246 -#else
247 - au1xxx_gpio2_write(gpio, value);
248 -#endif
249 - else
250 - au1xxx_gpio1_write(gpio, value);
251 + return 0;
252 }
253 -EXPORT_SYMBOL(au1xxx_gpio_set_value);
254
255 -int au1xxx_gpio_direction_input(unsigned gpio)
256 -{
257 - if (gpio >= AU1XXX_GPIO_BASE)
258 -#if defined(CONFIG_SOC_AU1000)
259 - return -ENODEV;
260 -#else
261 - return au1xxx_gpio2_direction_input(gpio);
262 +struct au1000_gpio_chip au1000_gpio_chip[] = {
263 + [0] = {
264 + .regbase = (void __iomem *)SYS_BASE,
265 + .chip = {
266 + .label = "au1000-gpio1",
267 + .direction_input = au1000_gpio1_direction_input,
268 + .direction_output = au1000_gpio1_direction_output,
269 + .get = au1000_gpio1_get,
270 + .set = au1000_gpio1_set,
271 + .base = 0,
272 + .ngpio = 32,
273 + },
274 + },
275 +#if !defined(CONFIG_SOC_AU1000)
276 + [1] = {
277 + .regbase = (void __iomem *)GPIO2_BASE,
278 + .chip = {
279 + .label = "au1000-gpio2",
280 + .direction_input = au1000_gpio2_direction_input,
281 + .direction_output = au1000_gpio2_direction_output,
282 + .get = au1000_gpio2_get,
283 + .set = au1000_gpio2_set,
284 + .base = AU1XXX_GPIO_BASE,
285 + .ngpio = 32,
286 + },
287 + },
288 #endif
289 +};
290
291 - return au1xxx_gpio1_direction_input(gpio);
292 -}
293 -EXPORT_SYMBOL(au1xxx_gpio_direction_input);
294 -
295 -int au1xxx_gpio_direction_output(unsigned gpio, int value)
296 +int __init au1000_gpio_init(void)
297 {
298 - if (gpio >= AU1XXX_GPIO_BASE)
299 -#if defined(CONFIG_SOC_AU1000)
300 - return -ENODEV;
301 -#else
302 - return au1xxx_gpio2_direction_output(gpio, value);
303 + gpiochip_add(&au1000_gpio_chip[0].chip);
304 +#if !defined(CONFIG_SOC_AU1000)
305 + gpiochip_add(&au1000_gpio_chip[1].chip);
306 #endif
307
308 - return au1xxx_gpio1_direction_output(gpio, value);
309 + return 0;
310 }
311 -EXPORT_SYMBOL(au1xxx_gpio_direction_output);
312 +arch_initcall(au1000_gpio_init);
313 --- a/include/asm-mips/mach-au1x00/gpio.h
314 +++ b/include/asm-mips/mach-au1x00/gpio.h
315 @@ -1,69 +1,21 @@
316 #ifndef _AU1XXX_GPIO_H_
317 #define _AU1XXX_GPIO_H_
318
319 -#include <linux/types.h>
320 -
321 #define AU1XXX_GPIO_BASE 200
322
323 -struct au1x00_gpio2 {
324 - u32 dir;
325 - u32 reserved;
326 - u32 output;
327 - u32 pinstate;
328 - u32 inten;
329 - u32 enable;
330 -};
331 -
332 -extern int au1xxx_gpio_get_value(unsigned gpio);
333 -extern void au1xxx_gpio_set_value(unsigned gpio, int value);
334 -extern int au1xxx_gpio_direction_input(unsigned gpio);
335 -extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
336 -
337 -
338 -/* Wrappers for the arch-neutral GPIO API */
339 -
340 -static inline int gpio_request(unsigned gpio, const char *label)
341 -{
342 - /* Not yet implemented */
343 - return 0;
344 -}
345 -
346 -static inline void gpio_free(unsigned gpio)
347 -{
348 - /* Not yet implemented */
349 -}
350 -
351 -static inline int gpio_direction_input(unsigned gpio)
352 -{
353 - return au1xxx_gpio_direction_input(gpio);
354 -}
355 -
356 -static inline int gpio_direction_output(unsigned gpio, int value)
357 -{
358 - return au1xxx_gpio_direction_output(gpio, value);
359 -}
360 -
361 -static inline int gpio_get_value(unsigned gpio)
362 -{
363 - return au1xxx_gpio_get_value(gpio);
364 -}
365 -
366 -static inline void gpio_set_value(unsigned gpio, int value)
367 -{
368 - au1xxx_gpio_set_value(gpio, value);
369 -}
370 -
371 -static inline int gpio_to_irq(unsigned gpio)
372 -{
373 - return gpio;
374 -}
375 -
376 -static inline int irq_to_gpio(unsigned irq)
377 -{
378 - return irq;
379 -}
380 +#define AU1000_GPIO2_DIR 0x00
381 +#define AU1000_GPIO2_RSVD 0x04
382 +#define AU1000_GPIO2_OUT 0x08
383 +#define AU1000_GPIO2_ST 0x0C
384 +#define AU1000_GPIO2_INT 0x10
385 +#define AU1000_GPIO2_EN 0x14
386 +
387 +#define gpio_get_value __gpio_get_value
388 +#define gpio_set_value __gpio_set_value
389 +
390 +#define gpio_to_irq(gpio) NULL
391 +#define irq_to_gpio(irq) NULL
392
393 -/* For cansleep */
394 #include <asm-generic/gpio.h>
395
396 #endif /* _AU1XXX_GPIO_H_ */