1 --- a/arch/mips/Kconfig
2 +++ b/arch/mips/Kconfig
3 @@ -92,6 +92,7 @@ config ATH79
6 bool "Broadcom BCM47XX based boards"
7 + select ARCH_REQUIRE_GPIOLIB
11 @@ -101,7 +102,6 @@ config BCM47XX
13 select SYS_SUPPORTS_32BIT_KERNEL
14 select SYS_SUPPORTS_LITTLE_ENDIAN
18 Support for BCM47XX based boards
19 --- a/arch/mips/bcm47xx/gpio.c
20 +++ b/arch/mips/bcm47xx/gpio.c
24 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
25 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
27 + * Parts of this file are based on Atheros AR71XX/AR724X/AR913X GPIO
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>
42 -#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
43 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
45 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
48 -int gpio_request(unsigned gpio, const char *tag)
49 +static unsigned long bcm47xx_gpio_count;
51 +/* low level BCM47xx gpio api */
52 +u32 bcm47xx_gpio_in(u32 mask)
54 switch (bcm47xx_bus_type) {
55 #ifdef CONFIG_BCM47XX_SSB
56 case BCM47XX_BUS_TYPE_SSB:
57 - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
58 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
61 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
62 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
65 - if (test_and_set_bit(gpio, gpio_in_use))
69 + return ssb_gpio_in(&bcm47xx_bus.ssb, mask);
71 #ifdef CONFIG_BCM47XX_BCMA
72 case BCM47XX_BUS_TYPE_BCMA:
73 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
76 - if (test_and_set_bit(gpio, gpio_in_use))
78 + return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, mask);
83 +EXPORT_SYMBOL(bcm47xx_gpio_in);
86 +u32 bcm47xx_gpio_out(u32 mask, u32 value)
88 + switch (bcm47xx_bus_type) {
89 +#ifdef CONFIG_BCM47XX_SSB
90 + case BCM47XX_BUS_TYPE_SSB:
91 + return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value);
93 +#ifdef CONFIG_BCM47XX_BCMA
94 + case BCM47XX_BUS_TYPE_BCMA:
95 + return bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, mask,
101 -EXPORT_SYMBOL(gpio_request);
102 +EXPORT_SYMBOL(bcm47xx_gpio_out);
104 -void gpio_free(unsigned gpio)
105 +u32 bcm47xx_gpio_outen(u32 mask, u32 value)
107 switch (bcm47xx_bus_type) {
108 #ifdef CONFIG_BCM47XX_SSB
109 case BCM47XX_BUS_TYPE_SSB:
110 - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
111 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
113 + return ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value);
115 +#ifdef CONFIG_BCM47XX_BCMA
116 + case BCM47XX_BUS_TYPE_BCMA:
117 + return bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc,
123 +EXPORT_SYMBOL(bcm47xx_gpio_outen);
125 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
126 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
128 +u32 bcm47xx_gpio_control(u32 mask, u32 value)
130 + switch (bcm47xx_bus_type) {
131 +#ifdef CONFIG_BCM47XX_SSB
132 + case BCM47XX_BUS_TYPE_SSB:
133 + return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value);
135 +#ifdef CONFIG_BCM47XX_BCMA
136 + case BCM47XX_BUS_TYPE_BCMA:
137 + return bcma_chipco_gpio_control(&bcm47xx_bus.bcma.bus.drv_cc,
143 +EXPORT_SYMBOL(bcm47xx_gpio_control);
145 - clear_bit(gpio, gpio_in_use);
147 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value)
149 + switch (bcm47xx_bus_type) {
150 +#ifdef CONFIG_BCM47XX_SSB
151 + case BCM47XX_BUS_TYPE_SSB:
152 + return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value);
154 #ifdef CONFIG_BCM47XX_BCMA
155 case BCM47XX_BUS_TYPE_BCMA:
156 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
158 + return bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
164 +EXPORT_SYMBOL(bcm47xx_gpio_intmask);
166 - clear_bit(gpio, gpio_in_use);
168 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value)
170 + switch (bcm47xx_bus_type) {
171 +#ifdef CONFIG_BCM47XX_SSB
172 + case BCM47XX_BUS_TYPE_SSB:
173 + return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value);
175 +#ifdef CONFIG_BCM47XX_BCMA
176 + case BCM47XX_BUS_TYPE_BCMA:
177 + return bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
183 +EXPORT_SYMBOL(bcm47xx_gpio_polarity);
186 +static int bcm47xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
188 + return bcm47xx_gpio_in(1 << gpio);
191 +static void bcm47xx_gpio_set_value(struct gpio_chip *chip,
192 + unsigned gpio, int value)
194 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
197 +static int bcm47xx_gpio_direction_input(struct gpio_chip *chip,
200 + bcm47xx_gpio_outen(1 << gpio, 0);
204 +static int bcm47xx_gpio_direction_output(struct gpio_chip *chip,
205 + unsigned gpio, int value)
207 + /* first set the gpio out value */
208 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
209 + /* then set the gpio mode */
210 + bcm47xx_gpio_outen(1 << gpio, 1 << gpio);
213 -EXPORT_SYMBOL(gpio_free);
215 -int gpio_to_irq(unsigned gpio)
216 +static int bcm47xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
218 switch (bcm47xx_bus_type) {
219 #ifdef CONFIG_BCM47XX_SSB
220 @@ -99,4 +170,55 @@ int gpio_to_irq(unsigned gpio)
224 -EXPORT_SYMBOL_GPL(gpio_to_irq);
226 +static struct gpio_chip bcm47xx_gpio_chip = {
227 + .label = "bcm47xx",
228 + .get = bcm47xx_gpio_get_value,
229 + .set = bcm47xx_gpio_set_value,
230 + .direction_input = bcm47xx_gpio_direction_input,
231 + .direction_output = bcm47xx_gpio_direction_output,
232 + .to_irq = bcm47xx_gpio_to_irq,
236 +void __init bcm47xx_gpio_init(void)
240 + switch (bcm47xx_bus_type) {
241 +#ifdef CONFIG_BCM47XX_SSB
242 + case BCM47XX_BUS_TYPE_SSB:
243 + bcm47xx_gpio_count = ssb_gpio_count(&bcm47xx_bus.ssb);
246 +#ifdef CONFIG_BCM47XX_BCMA
247 + case BCM47XX_BUS_TYPE_BCMA:
248 + bcm47xx_gpio_count = bcma_chipco_gpio_count();
253 + bcm47xx_gpio_chip.ngpio = bcm47xx_gpio_count;
255 + err = gpiochip_add(&bcm47xx_gpio_chip);
257 + panic("cannot add BCM47xx GPIO chip, error=%d", err);
260 +int gpio_get_value(unsigned gpio)
262 + if (gpio < bcm47xx_gpio_count)
263 + return bcm47xx_gpio_in(1 << gpio);
265 + return __gpio_get_value(gpio);
267 +EXPORT_SYMBOL(gpio_get_value);
269 +void gpio_set_value(unsigned gpio, int value)
271 + if (gpio < bcm47xx_gpio_count)
272 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
274 + __gpio_set_value(gpio, value);
276 +EXPORT_SYMBOL(gpio_set_value);
277 --- a/arch/mips/bcm47xx/setup.c
278 +++ b/arch/mips/bcm47xx/setup.c
279 @@ -252,6 +252,8 @@ void __init plat_mem_setup(void)
280 _machine_restart = bcm47xx_machine_restart;
281 _machine_halt = bcm47xx_machine_halt;
282 pm_power_off = bcm47xx_machine_halt;
284 + bcm47xx_gpio_init();
287 static int __init bcm47xx_register_bus_complete(void)
288 --- a/arch/mips/bcm47xx/wgt634u.c
289 +++ b/arch/mips/bcm47xx/wgt634u.c
290 @@ -133,6 +133,7 @@ static int __init wgt634u_init(void)
291 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
296 if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
298 @@ -146,6 +147,12 @@ static int __init wgt634u_init(void)
300 printk(KERN_INFO "WGT634U machine detected.\n");
302 + err = gpio_request(WGT634U_GPIO_RESET, "reset-buton");
304 + printk(KERN_INFO "Can not register gpio for reset button\n");
308 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
309 gpio_interrupt, IRQF_SHARED,
310 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
311 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
312 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
313 @@ -56,4 +56,6 @@ void bcm47xx_fill_bcma_boardinfo(struct
317 +void bcm47xx_gpio_init(void);
319 #endif /* __ASM_BCM47XX_H */
320 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
321 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
325 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
326 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
329 #ifndef __BCM47XX_GPIO_H
330 #define __BCM47XX_GPIO_H
332 -#include <linux/ssb/ssb_embedded.h>
333 -#include <linux/bcma/bcma.h>
334 -#include <asm/mach-bcm47xx/bcm47xx.h>
336 -#define BCM47XX_EXTIF_GPIO_LINES 5
337 -#define BCM47XX_CHIPCO_GPIO_LINES 16
339 -extern int gpio_request(unsigned gpio, const char *label);
340 -extern void gpio_free(unsigned gpio);
341 -extern int gpio_to_irq(unsigned gpio);
343 -static inline int gpio_get_value(unsigned gpio)
345 - switch (bcm47xx_bus_type) {
346 -#ifdef CONFIG_BCM47XX_SSB
347 - case BCM47XX_BUS_TYPE_SSB:
348 - return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
350 -#ifdef CONFIG_BCM47XX_BCMA
351 - case BCM47XX_BUS_TYPE_BCMA:
352 - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
359 -#define gpio_get_value_cansleep gpio_get_value
361 -static inline void gpio_set_value(unsigned gpio, int value)
363 - switch (bcm47xx_bus_type) {
364 -#ifdef CONFIG_BCM47XX_SSB
365 - case BCM47XX_BUS_TYPE_SSB:
366 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
367 - value ? 1 << gpio : 0);
370 -#ifdef CONFIG_BCM47XX_BCMA
371 - case BCM47XX_BUS_TYPE_BCMA:
372 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
373 - value ? 1 << gpio : 0);
379 -#define gpio_set_value_cansleep gpio_set_value
381 -static inline int gpio_cansleep(unsigned gpio)
386 -static inline int gpio_is_valid(unsigned gpio)
388 - return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
390 +#define ARCH_NR_GPIOS 64
391 +#include <asm-generic/gpio.h>
393 +/* low level BCM47xx gpio api */
394 +u32 bcm47xx_gpio_in(u32 mask);
395 +u32 bcm47xx_gpio_out(u32 mask, u32 value);
396 +u32 bcm47xx_gpio_outen(u32 mask, u32 value);
397 +u32 bcm47xx_gpio_control(u32 mask, u32 value);
398 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value);
399 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value);
401 -static inline int gpio_direction_input(unsigned gpio)
403 - switch (bcm47xx_bus_type) {
404 -#ifdef CONFIG_BCM47XX_SSB
405 - case BCM47XX_BUS_TYPE_SSB:
406 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
409 -#ifdef CONFIG_BCM47XX_BCMA
410 - case BCM47XX_BUS_TYPE_BCMA:
411 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
418 +int gpio_get_value(unsigned gpio);
419 +void gpio_set_value(unsigned gpio, int value);
421 -static inline int gpio_direction_output(unsigned gpio, int value)
422 +static inline void gpio_intmask(unsigned gpio, int value)
424 - switch (bcm47xx_bus_type) {
425 -#ifdef CONFIG_BCM47XX_SSB
426 - case BCM47XX_BUS_TYPE_SSB:
427 - /* first set the gpio out value */
428 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
429 - value ? 1 << gpio : 0);
430 - /* then set the gpio mode */
431 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
434 -#ifdef CONFIG_BCM47XX_BCMA
435 - case BCM47XX_BUS_TYPE_BCMA:
436 - /* first set the gpio out value */
437 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
438 - value ? 1 << gpio : 0);
439 - /* then set the gpio mode */
440 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
446 + bcm47xx_gpio_intmask(1 << gpio, value ? 1 << gpio : 0);
449 -static inline int gpio_intmask(unsigned gpio, int value)
450 +static inline void gpio_polarity(unsigned gpio, int value)
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);
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);
467 + bcm47xx_gpio_polarity(1 << gpio, value ? 1 << gpio : 0);
470 -static inline int gpio_polarity(unsigned gpio, int value)
471 +static inline int irq_to_gpio(int gpio)
473 - switch (bcm47xx_bus_type) {
474 -#ifdef CONFIG_BCM47XX_SSB
475 - case BCM47XX_BUS_TYPE_SSB:
476 - ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
477 - value ? 1 << gpio : 0);
480 -#ifdef CONFIG_BCM47XX_BCMA
481 - case BCM47XX_BUS_TYPE_BCMA:
482 - bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
483 - 1 << gpio, value ? 1 << gpio : 0);
490 +#define gpio_cansleep __gpio_cansleep
491 +#define gpio_to_irq __gpio_to_irq
493 #endif /* __BCM47XX_GPIO_H */