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