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 @@ -100,7 +101,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>
39 +#include <linux/bcma/bcma_driver_gpio.h>
43 -#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
44 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
46 -static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
49 -int gpio_request(unsigned gpio, const char *tag)
50 +static unsigned long bcm47xx_gpio_count;
52 +/* low level BCM47xx gpio api */
53 +u32 bcm47xx_gpio_in(u32 mask)
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))
62 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
63 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
66 - if (test_and_set_bit(gpio, gpio_in_use))
70 + return ssb_gpio_in(&bcm47xx_bus.ssb, mask);
72 #ifdef CONFIG_BCM47XX_BCMA
73 case BCM47XX_BUS_TYPE_BCMA:
74 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
77 - if (test_and_set_bit(gpio, gpio_in_use))
79 + return bcma_gpio_in(&bcm47xx_bus.bcma.bus, mask);
84 +EXPORT_SYMBOL(bcm47xx_gpio_in);
87 +u32 bcm47xx_gpio_out(u32 mask, u32 value)
89 + switch (bcm47xx_bus_type) {
90 +#ifdef CONFIG_BCM47XX_SSB
91 + case BCM47XX_BUS_TYPE_SSB:
92 + return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value);
94 +#ifdef CONFIG_BCM47XX_BCMA
95 + case BCM47XX_BUS_TYPE_BCMA:
96 + return bcma_gpio_out(&bcm47xx_bus.bcma.bus, mask, value);
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_gpio_outen(&bcm47xx_bus.bcma.bus, mask, value);
122 +EXPORT_SYMBOL(bcm47xx_gpio_outen);
124 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
125 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
127 +u32 bcm47xx_gpio_control(u32 mask, u32 value)
129 + switch (bcm47xx_bus_type) {
130 +#ifdef CONFIG_BCM47XX_SSB
131 + case BCM47XX_BUS_TYPE_SSB:
132 + return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value);
134 +#ifdef CONFIG_BCM47XX_BCMA
135 + case BCM47XX_BUS_TYPE_BCMA:
136 + return bcma_gpio_control(&bcm47xx_bus.bcma.bus, mask, value);
141 +EXPORT_SYMBOL(bcm47xx_gpio_control);
143 - clear_bit(gpio, gpio_in_use);
145 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value)
147 + switch (bcm47xx_bus_type) {
148 +#ifdef CONFIG_BCM47XX_SSB
149 + case BCM47XX_BUS_TYPE_SSB:
150 + return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value);
152 #ifdef CONFIG_BCM47XX_BCMA
153 case BCM47XX_BUS_TYPE_BCMA:
154 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
156 + return bcma_gpio_intmask(&bcm47xx_bus.bcma.bus, mask, value);
161 +EXPORT_SYMBOL(bcm47xx_gpio_intmask);
163 - clear_bit(gpio, gpio_in_use);
165 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value)
167 + switch (bcm47xx_bus_type) {
168 +#ifdef CONFIG_BCM47XX_SSB
169 + case BCM47XX_BUS_TYPE_SSB:
170 + return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value);
172 +#ifdef CONFIG_BCM47XX_BCMA
173 + case BCM47XX_BUS_TYPE_BCMA:
174 + return bcma_gpio_polarity(&bcm47xx_bus.bcma.bus, mask, value);
179 +EXPORT_SYMBOL(bcm47xx_gpio_polarity);
182 +static int bcm47xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
184 + return bcm47xx_gpio_in(1 << gpio);
187 +static void bcm47xx_gpio_set_value(struct gpio_chip *chip,
188 + unsigned gpio, int value)
190 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
193 +static int bcm47xx_gpio_direction_input(struct gpio_chip *chip,
196 + bcm47xx_gpio_outen(1 << gpio, 0);
200 +static int bcm47xx_gpio_direction_output(struct gpio_chip *chip,
201 + unsigned gpio, int value)
203 + /* first set the gpio out value */
204 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
205 + /* then set the gpio mode */
206 + bcm47xx_gpio_outen(1 << gpio, 1 << gpio);
209 -EXPORT_SYMBOL(gpio_free);
211 -int gpio_to_irq(unsigned gpio)
212 +static int bcm47xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
214 switch (bcm47xx_bus_type) {
215 #ifdef CONFIG_BCM47XX_SSB
216 @@ -99,4 +166,55 @@ int gpio_to_irq(unsigned gpio)
220 -EXPORT_SYMBOL_GPL(gpio_to_irq);
222 +static struct gpio_chip bcm47xx_gpio_chip = {
223 + .label = "bcm47xx",
224 + .get = bcm47xx_gpio_get_value,
225 + .set = bcm47xx_gpio_set_value,
226 + .direction_input = bcm47xx_gpio_direction_input,
227 + .direction_output = bcm47xx_gpio_direction_output,
228 + .to_irq = bcm47xx_gpio_to_irq,
232 +void __init bcm47xx_gpio_init(void)
236 + switch (bcm47xx_bus_type) {
237 +#ifdef CONFIG_BCM47XX_SSB
238 + case BCM47XX_BUS_TYPE_SSB:
239 + bcm47xx_gpio_count = ssb_gpio_count(&bcm47xx_bus.ssb);
242 +#ifdef CONFIG_BCM47XX_BCMA
243 + case BCM47XX_BUS_TYPE_BCMA:
244 + bcm47xx_gpio_count = bcma_gpio_count(&bcm47xx_bus.bcma.bus);
249 + bcm47xx_gpio_chip.ngpio = bcm47xx_gpio_count;
251 + err = gpiochip_add(&bcm47xx_gpio_chip);
253 + panic("cannot add BCM47xx GPIO chip, error=%d", err);
256 +int gpio_get_value(unsigned gpio)
258 + if (gpio < bcm47xx_gpio_count)
259 + return bcm47xx_gpio_in(1 << gpio);
261 + return __gpio_get_value(gpio);
263 +EXPORT_SYMBOL(gpio_get_value);
265 +void gpio_set_value(unsigned gpio, int value)
267 + if (gpio < bcm47xx_gpio_count)
268 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
270 + __gpio_set_value(gpio, value);
272 +EXPORT_SYMBOL(gpio_set_value);
273 --- a/arch/mips/bcm47xx/setup.c
274 +++ b/arch/mips/bcm47xx/setup.c
275 @@ -345,6 +345,8 @@ void __init plat_mem_setup(void)
276 _machine_restart = bcm47xx_machine_restart;
277 _machine_halt = bcm47xx_machine_halt;
278 pm_power_off = bcm47xx_machine_halt;
280 + bcm47xx_gpio_init();
283 static int __init bcm47xx_register_bus_complete(void)
284 --- a/arch/mips/bcm47xx/wgt634u.c
285 +++ b/arch/mips/bcm47xx/wgt634u.c
286 @@ -133,6 +133,7 @@ static int __init wgt634u_init(void)
287 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
292 if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
294 @@ -146,6 +147,12 @@ static int __init wgt634u_init(void)
296 printk(KERN_INFO "WGT634U machine detected.\n");
298 + err = gpio_request(WGT634U_GPIO_RESET, "reset-buton");
300 + printk(KERN_INFO "Can not register gpio for reset button\n");
304 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
305 gpio_interrupt, IRQF_SHARED,
306 "WGT634U GPIO", ccore)) {
307 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
308 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
309 @@ -56,4 +56,6 @@ void bcm47xx_fill_bcma_boardinfo(struct
313 +void bcm47xx_gpio_init(void);
315 #endif /* __ASM_BCM47XX_H */
316 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
317 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
321 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
322 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
325 #ifndef __BCM47XX_GPIO_H
326 #define __BCM47XX_GPIO_H
328 -#include <linux/ssb/ssb_embedded.h>
329 -#include <linux/bcma/bcma.h>
330 -#include <asm/mach-bcm47xx/bcm47xx.h>
332 -#define BCM47XX_EXTIF_GPIO_LINES 5
333 -#define BCM47XX_CHIPCO_GPIO_LINES 16
335 -extern int gpio_request(unsigned gpio, const char *label);
336 -extern void gpio_free(unsigned gpio);
337 -extern int gpio_to_irq(unsigned gpio);
339 -static inline int gpio_get_value(unsigned gpio)
341 - switch (bcm47xx_bus_type) {
342 -#ifdef CONFIG_BCM47XX_SSB
343 - case BCM47XX_BUS_TYPE_SSB:
344 - return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
346 -#ifdef CONFIG_BCM47XX_BCMA
347 - case BCM47XX_BUS_TYPE_BCMA:
348 - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
355 -#define gpio_get_value_cansleep gpio_get_value
357 -static inline void gpio_set_value(unsigned gpio, int value)
359 - switch (bcm47xx_bus_type) {
360 -#ifdef CONFIG_BCM47XX_SSB
361 - case BCM47XX_BUS_TYPE_SSB:
362 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
363 - value ? 1 << gpio : 0);
366 -#ifdef CONFIG_BCM47XX_BCMA
367 - case BCM47XX_BUS_TYPE_BCMA:
368 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
369 - value ? 1 << gpio : 0);
375 -#define gpio_set_value_cansleep gpio_set_value
377 -static inline int gpio_cansleep(unsigned gpio)
382 -static inline int gpio_is_valid(unsigned gpio)
384 - return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
386 +#define ARCH_NR_GPIOS 64
387 +#include <asm-generic/gpio.h>
389 +/* low level BCM47xx gpio api */
390 +u32 bcm47xx_gpio_in(u32 mask);
391 +u32 bcm47xx_gpio_out(u32 mask, u32 value);
392 +u32 bcm47xx_gpio_outen(u32 mask, u32 value);
393 +u32 bcm47xx_gpio_control(u32 mask, u32 value);
394 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value);
395 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value);
397 -static inline int gpio_direction_input(unsigned gpio)
399 - switch (bcm47xx_bus_type) {
400 -#ifdef CONFIG_BCM47XX_SSB
401 - case BCM47XX_BUS_TYPE_SSB:
402 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
405 -#ifdef CONFIG_BCM47XX_BCMA
406 - case BCM47XX_BUS_TYPE_BCMA:
407 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
414 +int gpio_get_value(unsigned gpio);
415 +void gpio_set_value(unsigned gpio, int value);
417 -static inline int gpio_direction_output(unsigned gpio, int value)
418 +static inline void gpio_intmask(unsigned gpio, int value)
420 - switch (bcm47xx_bus_type) {
421 -#ifdef CONFIG_BCM47XX_SSB
422 - case BCM47XX_BUS_TYPE_SSB:
423 - /* first set the gpio out value */
424 - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
425 - value ? 1 << gpio : 0);
426 - /* then set the gpio mode */
427 - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
430 -#ifdef CONFIG_BCM47XX_BCMA
431 - case BCM47XX_BUS_TYPE_BCMA:
432 - /* first set the gpio out value */
433 - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
434 - value ? 1 << gpio : 0);
435 - /* then set the gpio mode */
436 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
442 + bcm47xx_gpio_intmask(1 << gpio, value ? 1 << gpio : 0);
445 -static inline int gpio_intmask(unsigned gpio, int value)
446 +static inline void gpio_polarity(unsigned gpio, int value)
448 - switch (bcm47xx_bus_type) {
449 -#ifdef CONFIG_BCM47XX_SSB
450 - case BCM47XX_BUS_TYPE_SSB:
451 - ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
452 - value ? 1 << gpio : 0);
455 -#ifdef CONFIG_BCM47XX_BCMA
456 - case BCM47XX_BUS_TYPE_BCMA:
457 - bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
458 - 1 << gpio, value ? 1 << gpio : 0);
463 + bcm47xx_gpio_polarity(1 << gpio, value ? 1 << gpio : 0);
466 -static inline int gpio_polarity(unsigned gpio, int value)
467 +static inline int irq_to_gpio(int gpio)
469 - switch (bcm47xx_bus_type) {
470 -#ifdef CONFIG_BCM47XX_SSB
471 - case BCM47XX_BUS_TYPE_SSB:
472 - ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
473 - value ? 1 << gpio : 0);
476 -#ifdef CONFIG_BCM47XX_BCMA
477 - case BCM47XX_BUS_TYPE_BCMA:
478 - bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
479 - 1 << gpio, value ? 1 << gpio : 0);
486 +#define gpio_cansleep __gpio_cansleep
487 +#define gpio_to_irq __gpio_to_irq
489 #endif /* __BCM47XX_GPIO_H */