brcm47xx: use libgpio instaed of implementing the gpio interface ourself.
[openwrt.git] / target / linux / brcm47xx / patches-3.3 / 502-bcm47xx-rewrite-gpio-handling.patch
1 --- a/arch/mips/Kconfig
2 +++ b/arch/mips/Kconfig
3 @@ -92,6 +92,7 @@ config ATH79
4  
5  config BCM47XX
6         bool "Broadcom BCM47XX based boards"
7 +       select ARCH_REQUIRE_GPIOLIB
8         select BOOT_RAW
9         select CEVT_R4K
10         select CSRC_R4K
11 @@ -100,7 +101,6 @@ config BCM47XX
12         select IRQ_CPU
13         select SYS_SUPPORTS_32BIT_KERNEL
14         select SYS_SUPPORTS_LITTLE_ENDIAN
15 -       select GENERIC_GPIO
16         select CFE
17         help
18          Support for BCM47XX based boards
19 --- a/arch/mips/bcm47xx/gpio.c
20 +++ b/arch/mips/bcm47xx/gpio.c
21 @@ -4,81 +4,198 @@
22   * for more details.
23   *
24   * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
25 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
26 + *
27 + * Parts of this file are based on Atheros AR71XX/AR724X/AR913X GPIO
28   */
29  
30  #include <linux/export.h>
31 +#include <linux/gpio.h>
32  #include <linux/ssb/ssb.h>
33 -#include <linux/ssb/ssb_driver_chipcommon.h>
34 -#include <linux/ssb/ssb_driver_extif.h>
35 -#include <asm/mach-bcm47xx/bcm47xx.h>
36 -#include <asm/mach-bcm47xx/gpio.h>
37 +#include <linux/ssb/ssb_embedded.h>
38 +#include <linux/bcma/bcma.h>
39 +#include <linux/bcma/bcma_driver_gpio.h>
40 +
41 +#include <bcm47xx.h>
42  
43 -#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
44 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
45 -#else
46 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
47 -#endif
48  
49 -int gpio_request(unsigned gpio, const char *tag)
50 +static unsigned long bcm47xx_gpio_count;
51 +
52 +/* low level BCM47xx gpio api */
53 +u32 bcm47xx_gpio_in(u32 mask)
54  {
55         switch (bcm47xx_bus_type) {
56  #ifdef CONFIG_BCM47XX_SSB
57         case BCM47XX_BUS_TYPE_SSB:
58 -               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
59 -                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
60 -                       return -EINVAL;
61 -
62 -               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
63 -                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
64 -                       return -EINVAL;
65 +               return ssb_gpio_in(&bcm47xx_bus.ssb, mask);
66 +#endif
67 +#ifdef CONFIG_BCM47XX_BCMA
68 +       case BCM47XX_BUS_TYPE_BCMA:
69 +               return bcma_gpio_in(&bcm47xx_bus.bcma.bus, mask);
70 +#endif
71 +       }
72 +       return -EINVAL;
73 +}
74 +EXPORT_SYMBOL(bcm47xx_gpio_in);
75  
76 -               if (test_and_set_bit(gpio, gpio_in_use))
77 -                       return -EBUSY;
78 +u32 bcm47xx_gpio_out(u32 mask, u32 value)
79 +{
80 +       switch (bcm47xx_bus_type) {
81 +#ifdef CONFIG_BCM47XX_SSB
82 +       case BCM47XX_BUS_TYPE_SSB:
83 +               return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value);
84 +#endif
85 +#ifdef CONFIG_BCM47XX_BCMA
86 +       case BCM47XX_BUS_TYPE_BCMA:
87 +               return bcma_gpio_out(&bcm47xx_bus.bcma.bus, mask, value);
88 +#endif
89 +       }
90 +       return -EINVAL;
91 +}
92 +EXPORT_SYMBOL(bcm47xx_gpio_out);
93  
94 -               return 0;
95 +u32 bcm47xx_gpio_outen(u32 mask, u32 value)
96 +{
97 +       switch (bcm47xx_bus_type) {
98 +#ifdef CONFIG_BCM47XX_SSB
99 +       case BCM47XX_BUS_TYPE_SSB:
100 +               return ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value);
101  #endif
102  #ifdef CONFIG_BCM47XX_BCMA
103         case BCM47XX_BUS_TYPE_BCMA:
104 -               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
105 -                       return -EINVAL;
106 +               return bcma_gpio_outen(&bcm47xx_bus.bcma.bus, mask, value);
107 +#endif
108 +       }
109 +       return -EINVAL;
110 +}
111 +EXPORT_SYMBOL(bcm47xx_gpio_outen);
112  
113 -               if (test_and_set_bit(gpio, gpio_in_use))
114 -                       return -EBUSY;
115 +u32 bcm47xx_gpio_control(u32 mask, u32 value)
116 +{
117 +       switch (bcm47xx_bus_type) {
118 +#ifdef CONFIG_BCM47XX_SSB
119 +       case BCM47XX_BUS_TYPE_SSB:
120 +               return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value);
121 +#endif
122 +#ifdef CONFIG_BCM47XX_BCMA
123 +       case BCM47XX_BUS_TYPE_BCMA:
124 +               return bcma_gpio_control(&bcm47xx_bus.bcma.bus, mask, value);
125 +#endif
126 +       }
127 +       return -EINVAL;
128 +}
129 +EXPORT_SYMBOL(bcm47xx_gpio_control);
130  
131 -               return 0;
132 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value)
133 +{
134 +       switch (bcm47xx_bus_type) {
135 +#ifdef CONFIG_BCM47XX_SSB
136 +       case BCM47XX_BUS_TYPE_SSB:
137 +               return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value);
138 +#endif
139 +#ifdef CONFIG_BCM47XX_BCMA
140 +       case BCM47XX_BUS_TYPE_BCMA:
141 +               return bcma_gpio_intmask(&bcm47xx_bus.bcma.bus, mask, value);
142  #endif
143         }
144         return -EINVAL;
145  }
146 -EXPORT_SYMBOL(gpio_request);
147 +EXPORT_SYMBOL(bcm47xx_gpio_intmask);
148  
149 -void gpio_free(unsigned gpio)
150 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value)
151  {
152         switch (bcm47xx_bus_type) {
153  #ifdef CONFIG_BCM47XX_SSB
154         case BCM47XX_BUS_TYPE_SSB:
155 -               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
156 -                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
157 -                       return;
158 +               return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value);
159 +#endif
160 +#ifdef CONFIG_BCM47XX_BCMA
161 +       case BCM47XX_BUS_TYPE_BCMA:
162 +               return bcma_gpio_polarity(&bcm47xx_bus.bcma.bus, mask, value);
163 +#endif
164 +       }
165 +       return -EINVAL;
166 +}
167 +EXPORT_SYMBOL(bcm47xx_gpio_polarity);
168 +
169 +
170 +
171 +static int bcm47xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
172 +{
173 +       return bcm47xx_gpio_in(1 << gpio);
174 +}
175 +
176 +static void bcm47xx_gpio_set_value(struct gpio_chip *chip,
177 +                                  unsigned gpio, int value)
178 +{
179 +       bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
180 +}
181 +
182 +static int bcm47xx_gpio_direction_input(struct gpio_chip *chip,
183 +                                       unsigned gpio)
184 +{
185 +       bcm47xx_gpio_outen(1 << gpio, 0);
186 +       return 0;
187 +}
188 +
189 +static int bcm47xx_gpio_direction_output(struct gpio_chip *chip,
190 +                                        unsigned gpio, int value)
191 +{
192 +       /* first set the gpio out value */
193 +       bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
194 +       /* then set the gpio mode */
195 +       bcm47xx_gpio_outen(1 << gpio, 1 << gpio);
196 +       return 0;
197 +}
198 +
199 +static struct gpio_chip bcm47xx_gpio_chip = {
200 +       .label                  = "bcm47xx",
201 +       .get                    = bcm47xx_gpio_get_value,
202 +       .set                    = bcm47xx_gpio_set_value,
203 +       .direction_input        = bcm47xx_gpio_direction_input,
204 +       .direction_output       = bcm47xx_gpio_direction_output,
205 +       .base                   = 0,
206 +};
207  
208 -               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
209 -                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
210 -                       return;
211 +void __init bcm47xx_gpio_init(void)
212 +{
213 +       int err;
214  
215 -               clear_bit(gpio, gpio_in_use);
216 -               return;
217 +       switch (bcm47xx_bus_type) {
218 +#ifdef CONFIG_BCM47XX_SSB
219 +       case BCM47XX_BUS_TYPE_SSB:
220 +               bcm47xx_gpio_count = ssb_gpio_count(&bcm47xx_bus.ssb);
221  #endif
222  #ifdef CONFIG_BCM47XX_BCMA
223         case BCM47XX_BUS_TYPE_BCMA:
224 -               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
225 -                       return;
226 -
227 -               clear_bit(gpio, gpio_in_use);
228 -               return;
229 +               bcm47xx_gpio_count = bcma_gpio_count(&bcm47xx_bus.bcma.bus);
230  #endif
231         }
232 +
233 +       bcm47xx_gpio_chip.ngpio = bcm47xx_gpio_count;
234 +
235 +       err = gpiochip_add(&bcm47xx_gpio_chip);
236 +       if (err)
237 +               panic("cannot add BCM47xx GPIO chip, error=%d", err);
238  }
239 -EXPORT_SYMBOL(gpio_free);
240 +
241 +int gpio_get_value(unsigned gpio)
242 +{
243 +       if (gpio < bcm47xx_gpio_count)
244 +               return bcm47xx_gpio_in(1 << gpio);
245 +
246 +       return __gpio_get_value(gpio);
247 +}
248 +EXPORT_SYMBOL(gpio_get_value);
249 +
250 +void gpio_set_value(unsigned gpio, int value)
251 +{
252 +       if (gpio < bcm47xx_gpio_count)
253 +               bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
254 +       else
255 +               __gpio_set_value(gpio, value);
256 +}
257 +EXPORT_SYMBOL(gpio_set_value);
258  
259  int gpio_to_irq(unsigned gpio)
260  {
261 @@ -99,4 +216,11 @@ int gpio_to_irq(unsigned gpio)
262         }
263         return -EINVAL;
264  }
265 -EXPORT_SYMBOL_GPL(gpio_to_irq);
266 +EXPORT_SYMBOL(gpio_to_irq);
267 +
268 +int irq_to_gpio(unsigned irq)
269 +{
270 +       /* FIXME */
271 +       return -EINVAL;
272 +}
273 +EXPORT_SYMBOL(irq_to_gpio);
274 --- a/arch/mips/bcm47xx/setup.c
275 +++ b/arch/mips/bcm47xx/setup.c
276 @@ -344,6 +344,8 @@ void __init plat_mem_setup(void)
277         _machine_restart = bcm47xx_machine_restart;
278         _machine_halt = bcm47xx_machine_halt;
279         pm_power_off = bcm47xx_machine_halt;
280 +
281 +       bcm47xx_gpio_init();
282  }
283  
284  static int __init bcm47xx_register_bus_complete(void)
285 --- a/arch/mips/bcm47xx/wgt634u.c
286 +++ b/arch/mips/bcm47xx/wgt634u.c
287 @@ -133,6 +133,7 @@ static int __init wgt634u_init(void)
288          * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
289          */
290         u8 *et0mac;
291 +       int err;
292  
293         if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
294                 return -ENODEV;
295 @@ -146,6 +147,12 @@ static int __init wgt634u_init(void)
296  
297                 printk(KERN_INFO "WGT634U machine detected.\n");
298  
299 +               err = gpio_request(WGT634U_GPIO_RESET, "reset-buton");
300 +               if (err) {
301 +                       printk(KERN_INFO "Can not register gpio fir reset button\n");
302 +                       return 0;
303 +               }
304 +
305                 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
306                                  gpio_interrupt, IRQF_SHARED,
307                                  "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
308 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
309 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
310 @@ -56,4 +56,6 @@ void bcm47xx_fill_bcma_boardinfo(struct
311                                  const char *prefix);
312  #endif
313  
314 +void bcm47xx_gpio_init(void);
315 +
316  #endif /* __ASM_BCM47XX_H */
317 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
318 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
319 @@ -4,152 +4,39 @@
320   * for more details.
321   *
322   * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
323 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
324   */
325  
326  #ifndef __BCM47XX_GPIO_H
327  #define __BCM47XX_GPIO_H
328  
329 -#include <linux/ssb/ssb_embedded.h>
330 -#include <linux/bcma/bcma.h>
331 -#include <asm/mach-bcm47xx/bcm47xx.h>
332 -
333 -#define BCM47XX_EXTIF_GPIO_LINES       5
334 -#define BCM47XX_CHIPCO_GPIO_LINES      16
335 -
336 -extern int gpio_request(unsigned gpio, const char *label);
337 -extern void gpio_free(unsigned gpio);
338 -extern int gpio_to_irq(unsigned gpio);
339 +#define ARCH_NR_GPIOS  64
340 +#include <asm-generic/gpio.h>
341  
342 -static inline int gpio_get_value(unsigned gpio)
343 -{
344 -       switch (bcm47xx_bus_type) {
345 -#ifdef CONFIG_BCM47XX_SSB
346 -       case BCM47XX_BUS_TYPE_SSB:
347 -               return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
348 -#endif
349 -#ifdef CONFIG_BCM47XX_BCMA
350 -       case BCM47XX_BUS_TYPE_BCMA:
351 -               return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
352 -                                          1 << gpio);
353 -#endif
354 -       }
355 -       return -EINVAL;
356 -}
357 -
358 -#define gpio_get_value_cansleep        gpio_get_value
359 -
360 -static inline void gpio_set_value(unsigned gpio, int value)
361 -{
362 -       switch (bcm47xx_bus_type) {
363 -#ifdef CONFIG_BCM47XX_SSB
364 -       case BCM47XX_BUS_TYPE_SSB:
365 -               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
366 -                            value ? 1 << gpio : 0);
367 -               return;
368 -#endif
369 -#ifdef CONFIG_BCM47XX_BCMA
370 -       case BCM47XX_BUS_TYPE_BCMA:
371 -               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
372 -                                    value ? 1 << gpio : 0);
373 -               return;
374 -#endif
375 -       }
376 -}
377 -
378 -#define gpio_set_value_cansleep gpio_set_value
379 -
380 -static inline int gpio_cansleep(unsigned gpio)
381 -{
382 -       return 0;
383 -}
384 +/* low level BCM47xx gpio api */
385 +u32 bcm47xx_gpio_in(u32 mask);
386 +u32 bcm47xx_gpio_out(u32 mask, u32 value);
387 +u32 bcm47xx_gpio_outen(u32 mask, u32 value);
388 +u32 bcm47xx_gpio_control(u32 mask, u32 value);
389 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value);
390 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value);
391  
392 -static inline int gpio_is_valid(unsigned gpio)
393 -{
394 -       return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
395 -}
396 +int gpio_to_irq(unsigned gpio);
397 +int irq_to_gpio(unsigned irq);
398 +int gpio_get_value(unsigned gpio);
399 +void gpio_set_value(unsigned gpio, int value);
400  
401 -
402 -static inline int gpio_direction_input(unsigned gpio)
403 +static inline void gpio_intmask(unsigned gpio, int value)
404  {
405 -       switch (bcm47xx_bus_type) {
406 -#ifdef CONFIG_BCM47XX_SSB
407 -       case BCM47XX_BUS_TYPE_SSB:
408 -               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
409 -               return 0;
410 -#endif
411 -#ifdef CONFIG_BCM47XX_BCMA
412 -       case BCM47XX_BUS_TYPE_BCMA:
413 -               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
414 -                                      0);
415 -               return 0;
416 -#endif
417 -       }
418 -       return -EINVAL;
419 +       bcm47xx_gpio_intmask(1 << gpio, value ? 1 << gpio : 0);
420  }
421  
422 -static inline int gpio_direction_output(unsigned gpio, int value)
423 +static inline void gpio_polarity(unsigned gpio, int value)
424  {
425 -       switch (bcm47xx_bus_type) {
426 -#ifdef CONFIG_BCM47XX_SSB
427 -       case BCM47XX_BUS_TYPE_SSB:
428 -               /* first set the gpio out value */
429 -               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
430 -                            value ? 1 << gpio : 0);
431 -               /* then set the gpio mode */
432 -               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
433 -               return 0;
434 -#endif
435 -#ifdef CONFIG_BCM47XX_BCMA
436 -       case BCM47XX_BUS_TYPE_BCMA:
437 -               /* first set the gpio out value */
438 -               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
439 -                                    value ? 1 << gpio : 0);
440 -               /* then set the gpio mode */
441 -               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
442 -                                      1 << gpio);
443 -               return 0;
444 -#endif
445 -       }
446 -       return -EINVAL;
447 +       bcm47xx_gpio_polarity(1 << gpio, value ? 1 << gpio : 0);
448  }
449  
450 -static inline int gpio_intmask(unsigned gpio, int value)
451 -{
452 -       switch (bcm47xx_bus_type) {
453 -#ifdef CONFIG_BCM47XX_SSB
454 -       case BCM47XX_BUS_TYPE_SSB:
455 -               ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
456 -                                value ? 1 << gpio : 0);
457 -               return 0;
458 -#endif
459 -#ifdef CONFIG_BCM47XX_BCMA
460 -       case BCM47XX_BUS_TYPE_BCMA:
461 -               bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
462 -                                        1 << gpio, value ? 1 << gpio : 0);
463 -               return 0;
464 -#endif
465 -       }
466 -       return -EINVAL;
467 -}
468 -
469 -static inline int gpio_polarity(unsigned gpio, int value)
470 -{
471 -       switch (bcm47xx_bus_type) {
472 -#ifdef CONFIG_BCM47XX_SSB
473 -       case BCM47XX_BUS_TYPE_SSB:
474 -               ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
475 -                                 value ? 1 << gpio : 0);
476 -               return 0;
477 -#endif
478 -#ifdef CONFIG_BCM47XX_BCMA
479 -       case BCM47XX_BUS_TYPE_BCMA:
480 -               bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
481 -                                         1 << gpio, value ? 1 << gpio : 0);
482 -               return 0;
483 -#endif
484 -       }
485 -       return -EINVAL;
486 -}
487  
488 +#define gpio_cansleep  __gpio_cansleep
489  
490  #endif /* __BCM47XX_GPIO_H */