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))
65 + return ssb_gpio_in(&bcm47xx_bus.ssb, mask);
67 +#ifdef CONFIG_BCM47XX_BCMA
68 + case BCM47XX_BUS_TYPE_BCMA:
69 + return bcma_gpio_in(&bcm47xx_bus.bcma.bus, mask);
74 +EXPORT_SYMBOL(bcm47xx_gpio_in);
76 - if (test_and_set_bit(gpio, gpio_in_use))
78 +u32 bcm47xx_gpio_out(u32 mask, u32 value)
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);
85 +#ifdef CONFIG_BCM47XX_BCMA
86 + case BCM47XX_BUS_TYPE_BCMA:
87 + return bcma_gpio_out(&bcm47xx_bus.bcma.bus, mask, value);
92 +EXPORT_SYMBOL(bcm47xx_gpio_out);
95 +u32 bcm47xx_gpio_outen(u32 mask, u32 value)
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);
102 #ifdef CONFIG_BCM47XX_BCMA
103 case BCM47XX_BUS_TYPE_BCMA:
104 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
106 + return bcma_gpio_outen(&bcm47xx_bus.bcma.bus, mask, value);
111 +EXPORT_SYMBOL(bcm47xx_gpio_outen);
113 - if (test_and_set_bit(gpio, gpio_in_use))
115 +u32 bcm47xx_gpio_control(u32 mask, u32 value)
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);
122 +#ifdef CONFIG_BCM47XX_BCMA
123 + case BCM47XX_BUS_TYPE_BCMA:
124 + return bcma_gpio_control(&bcm47xx_bus.bcma.bus, mask, value);
129 +EXPORT_SYMBOL(bcm47xx_gpio_control);
132 +u32 bcm47xx_gpio_intmask(u32 mask, u32 value)
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);
139 +#ifdef CONFIG_BCM47XX_BCMA
140 + case BCM47XX_BUS_TYPE_BCMA:
141 + return bcma_gpio_intmask(&bcm47xx_bus.bcma.bus, mask, value);
146 -EXPORT_SYMBOL(gpio_request);
147 +EXPORT_SYMBOL(bcm47xx_gpio_intmask);
149 -void gpio_free(unsigned gpio)
150 +u32 bcm47xx_gpio_polarity(u32 mask, u32 value)
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))
158 + return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value);
160 +#ifdef CONFIG_BCM47XX_BCMA
161 + case BCM47XX_BUS_TYPE_BCMA:
162 + return bcma_gpio_polarity(&bcm47xx_bus.bcma.bus, mask, value);
167 +EXPORT_SYMBOL(bcm47xx_gpio_polarity);
171 +static int bcm47xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
173 + return bcm47xx_gpio_in(1 << gpio);
176 +static void bcm47xx_gpio_set_value(struct gpio_chip *chip,
177 + unsigned gpio, int value)
179 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
182 +static int bcm47xx_gpio_direction_input(struct gpio_chip *chip,
185 + bcm47xx_gpio_outen(1 << gpio, 0);
189 +static int bcm47xx_gpio_direction_output(struct gpio_chip *chip,
190 + unsigned gpio, int value)
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);
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,
208 - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
209 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
211 +void __init bcm47xx_gpio_init(void)
215 - clear_bit(gpio, gpio_in_use);
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);
222 #ifdef CONFIG_BCM47XX_BCMA
223 case BCM47XX_BUS_TYPE_BCMA:
224 - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
227 - clear_bit(gpio, gpio_in_use);
229 + bcm47xx_gpio_count = bcma_gpio_count(&bcm47xx_bus.bcma.bus);
233 + bcm47xx_gpio_chip.ngpio = bcm47xx_gpio_count;
235 + err = gpiochip_add(&bcm47xx_gpio_chip);
237 + panic("cannot add BCM47xx GPIO chip, error=%d", err);
239 -EXPORT_SYMBOL(gpio_free);
241 +int gpio_get_value(unsigned gpio)
243 + if (gpio < bcm47xx_gpio_count)
244 + return bcm47xx_gpio_in(1 << gpio);
246 + return __gpio_get_value(gpio);
248 +EXPORT_SYMBOL(gpio_get_value);
250 +void gpio_set_value(unsigned gpio, int value)
252 + if (gpio < bcm47xx_gpio_count)
253 + bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0);
255 + __gpio_set_value(gpio, value);
257 +EXPORT_SYMBOL(gpio_set_value);
259 int gpio_to_irq(unsigned gpio)
261 @@ -99,4 +216,11 @@ int gpio_to_irq(unsigned gpio)
265 -EXPORT_SYMBOL_GPL(gpio_to_irq);
266 +EXPORT_SYMBOL(gpio_to_irq);
268 +int irq_to_gpio(unsigned irq)
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;
281 + bcm47xx_gpio_init();
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.
293 if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
295 @@ -146,6 +147,12 @@ static int __init wgt634u_init(void)
297 printk(KERN_INFO "WGT634U machine detected.\n");
299 + err = gpio_request(WGT634U_GPIO_RESET, "reset-buton");
301 + printk(KERN_INFO "Can not register gpio fir reset button\n");
305 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
306 gpio_interrupt, IRQF_SHARED,
307 "WGT634U GPIO", ccore)) {
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
314 +void bcm47xx_gpio_init(void);
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
322 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
323 + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
326 #ifndef __BCM47XX_GPIO_H
327 #define __BCM47XX_GPIO_H
329 -#include <linux/ssb/ssb_embedded.h>
330 -#include <linux/bcma/bcma.h>
331 -#include <asm/mach-bcm47xx/bcm47xx.h>
333 -#define BCM47XX_EXTIF_GPIO_LINES 5
334 -#define BCM47XX_CHIPCO_GPIO_LINES 16
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>
342 -static inline int gpio_get_value(unsigned gpio)
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);
349 -#ifdef CONFIG_BCM47XX_BCMA
350 - case BCM47XX_BUS_TYPE_BCMA:
351 - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
358 -#define gpio_get_value_cansleep gpio_get_value
360 -static inline void gpio_set_value(unsigned gpio, int value)
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);
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);
378 -#define gpio_set_value_cansleep gpio_set_value
380 -static inline int gpio_cansleep(unsigned gpio)
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);
392 -static inline int gpio_is_valid(unsigned gpio)
394 - return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
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);
402 -static inline int gpio_direction_input(unsigned gpio)
403 +static inline void gpio_intmask(unsigned gpio, int value)
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);
411 -#ifdef CONFIG_BCM47XX_BCMA
412 - case BCM47XX_BUS_TYPE_BCMA:
413 - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
419 + bcm47xx_gpio_intmask(1 << gpio, value ? 1 << gpio : 0);
422 -static inline int gpio_direction_output(unsigned gpio, int value)
423 +static inline void gpio_polarity(unsigned gpio, int value)
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);
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,
447 + bcm47xx_gpio_polarity(1 << gpio, value ? 1 << gpio : 0);
450 -static inline int gpio_intmask(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);
469 -static inline int gpio_polarity(unsigned gpio, int value)
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);
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);
488 +#define gpio_cansleep __gpio_cansleep
490 #endif /* __BCM47XX_GPIO_H */