ar71xx: fix random wireless mac address on the TEW-632BRP/DIR-615 boards
[openwrt.git] / target / linux / au1000 / patches-2.6.28 / 007-gpiolib.patch
1 --- a/arch/mips/alchemy/Kconfig
2 +++ b/arch/mips/alchemy/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/alchemy/common/gpio.c
9 +++ b/arch/mips/alchemy/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/arch/mips/include/asm/mach-au1x00/gpio.h
314 +++ b/arch/mips/include/asm/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_ */