From 075899682416938171ad47cba21de5dceebcdb43 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 4 Aug 2012 19:46:25 +0000 Subject: [PATCH] brcm47xx: use libgpio instaed of implementing the gpio interface ourself. SVN-Revision: 32992 --- package/broadcom-diag/src/diag.c | 108 ++-- package/broadcom-diag/src/gpio.h | 153 ------ package/switch/src/gpio-bcm947xx.h | 55 -- package/switch/src/gpio.h | 14 +- package/switch/src/switch-adm.c | 34 +- target/linux/brcm47xx/config-3.3 | 4 + ...50-bcma-export-needed-gpio-functions.patch | 47 -- .../140-bcm47xx-add-gpio_set_debounce.patch | 12 - .../220-add_gpio_request_one.patch | 51 -- ...ction-to-return-number-of-gpio-lines.patch | 40 ++ .../501-bcma-add-gpio-driver.patch | 170 ++++++ .../502-bcm47xx-rewrite-gpio-handling.patch | 490 ++++++++++++++++++ .../812-disable_wgt634u_crap.patch | 9 +- 13 files changed, 810 insertions(+), 377 deletions(-) delete mode 100644 package/switch/src/gpio-bcm947xx.h delete mode 100644 target/linux/brcm47xx/patches-3.3/050-bcma-export-needed-gpio-functions.patch delete mode 100644 target/linux/brcm47xx/patches-3.3/140-bcm47xx-add-gpio_set_debounce.patch delete mode 100644 target/linux/brcm47xx/patches-3.3/220-add_gpio_request_one.patch create mode 100644 target/linux/brcm47xx/patches-3.3/500-ssb-add-function-to-return-number-of-gpio-lines.patch create mode 100644 target/linux/brcm47xx/patches-3.3/501-bcma-add-gpio-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/502-bcm47xx-rewrite-gpio-handling.patch diff --git a/package/broadcom-diag/src/diag.c b/package/broadcom-diag/src/diag.c index 090fc5e3d5..cf6d789c29 100644 --- a/package/broadcom-diag/src/diag.c +++ b/package/broadcom-diag/src/diag.c @@ -156,9 +156,9 @@ static void __init bcm4780_init(void) { /* Enables GPIO 3 that controls HDD and led power on ASUS WL-700gE */ printk(MODULE_NAME ": Spinning up HDD and enabling leds\n"); - gpio_outen(pin, pin); - gpio_control(pin, 0); - gpio_out(pin, pin); + bcm47xx_gpio_outen(pin, pin); + bcm47xx_gpio_control(pin, 0); + bcm47xx_gpio_out(pin, pin); /* Wait 5s, so the HDD can spin up */ set_current_state(TASK_INTERRUPTIBLE); @@ -168,14 +168,14 @@ static void __init bcm4780_init(void) { static void __init NetCenter_init(void) { /* unset pin 6 (+12V) */ int pin = 1 << 6; - gpio_outen(pin, pin); - gpio_control(pin, 0); - gpio_out(pin, pin); + bcm47xx_gpio_outen(pin, pin); + bcm47xx_gpio_control(pin, 0); + bcm47xx_gpio_out(pin, pin); /* unset pin 1 (turn off red led, blue will light alone if +5V comes up) */ pin = 1 << 1; - gpio_outen(pin, pin); - gpio_control(pin, 0); - gpio_out(pin, pin); + bcm47xx_gpio_outen(pin, pin); + bcm47xx_gpio_control(pin, 0); + bcm47xx_gpio_out(pin, pin); /* unset pin 3 (+5V) and wait 5 seconds (harddisk spin up) */ bcm4780_init(); } @@ -184,9 +184,9 @@ static void __init bcm57xx_init(void) { int pin = 1 << 2; /* FIXME: switch comes up, but port mappings/vlans not right */ - gpio_outen(pin, pin); - gpio_control(pin, 0); - gpio_out(pin, pin); + bcm47xx_gpio_outen(pin, pin); + bcm47xx_gpio_control(pin, 0); + bcm47xx_gpio_out(pin, pin); } static struct platform_t __initdata platforms[] = { @@ -1283,6 +1283,42 @@ static struct platform_t __init *platform_detect(void) return NULL; } +static inline void ssb_maskset32(struct ssb_device *dev, + u16 offset, u32 mask, u32 set) +{ + ssb_write32(dev, offset, (ssb_read32(dev, offset) & mask) | set); +} + +static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *)) +{ + int irq; + + irq = gpio_to_irq(0); + if (irq == -EINVAL) return; + + if (enabled) { + if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler)) + return; + } else { + free_irq(irq, handler); + } + + switch (bcm47xx_bus_type) { +#ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: + if (bcm47xx_bus.ssb.chipco.dev) + ssb_maskset32(bcm47xx_bus.ssb.chipco.dev, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0)); + break; +#endif +#ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: + if (bcm47xx_bus.bcma.bus.drv_cc.core) + bcma_maskset32(bcm47xx_bus.bcma.bus.drv_cc.core, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO, (enabled ? BCMA_CC_IRQ_GPIO : 0)); + break; +#endif + } +} + static void register_buttons(struct button_t *b) { for (; b->name; b++) @@ -1290,18 +1326,18 @@ static void register_buttons(struct button_t *b) platform.button_mask &= ~gpiomask; - gpio_outen(platform.button_mask, 0); - gpio_control(platform.button_mask, 0); - platform.button_polarity = gpio_in() & platform.button_mask; - gpio_intpolarity(platform.button_mask, platform.button_polarity); - gpio_setintmask(platform.button_mask, platform.button_mask); + bcm47xx_gpio_outen(platform.button_mask, 0); + bcm47xx_gpio_control(platform.button_mask, 0); + platform.button_polarity = bcm47xx_gpio_in(~0) & platform.button_mask; + bcm47xx_gpio_polarity(platform.button_mask, platform.button_polarity); + bcm47xx_gpio_intmask(platform.button_mask, platform.button_mask); gpio_set_irqenable(1, button_handler); } static void unregister_buttons(struct button_t *b) { - gpio_setintmask(platform.button_mask, 0); + bcm47xx_gpio_intmask(platform.button_mask, 0); gpio_set_irqenable(0, button_handler); } @@ -1361,12 +1397,12 @@ static irqreturn_t button_handler(int irq, void *dev_id) struct button_t *b; u32 in, changed; - in = gpio_in() & platform.button_mask; - gpio_intpolarity(platform.button_mask, in); + in = bcm47xx_gpio_in(~0) & platform.button_mask; + bcm47xx_gpio_polarity(platform.button_mask, in); changed = platform.button_polarity ^ in; platform.button_polarity = in; - changed &= ~gpio_outen(0, 0); + changed &= ~bcm47xx_gpio_outen(0, 0); for (b = platform.buttons; b->name; b++) { struct event_t *event; @@ -1422,10 +1458,10 @@ static void register_leds(struct led_t *l) } } - gpio_outen(mask, oe_mask); - gpio_control(mask, 0); - gpio_out(mask, val); - gpio_setintmask(mask, 0); + bcm47xx_gpio_outen(mask, oe_mask); + bcm47xx_gpio_control(mask, 0); + bcm47xx_gpio_out(mask, val); + bcm47xx_gpio_intmask(mask, 0); } static void unregister_leds(struct led_t *l) @@ -1438,7 +1474,11 @@ static void unregister_leds(struct led_t *l) static void set_led_extif(struct led_t *led) { - gpio_set_extif(led->gpio, led->state); + volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (led->gpio & ~GPIO_TYPE_MASK); + if (led->state) + *addr = 0xFF; + else + *addr; } static void led_flash(unsigned long dummy) { @@ -1460,11 +1500,11 @@ static void led_flash(unsigned long dummy) { mask &= ~gpiomask; if (mask) { - u32 val = ~gpio_in(); + u32 val = ~bcm47xx_gpio_in(~0); - gpio_outen(mask, mask); - gpio_control(mask, 0); - gpio_out(mask, val); + bcm47xx_gpio_outen(mask, mask); + bcm47xx_gpio_control(mask, 0); + bcm47xx_gpio_out(mask, val); } if (mask || extif_blink) { mod_timer(&led_timer, jiffies + FLASH_TIME); @@ -1491,7 +1531,7 @@ static ssize_t diag_proc_read(struct file *file, char *buf, size_t count, loff_t if (led->gpio & GPIO_TYPE_EXTIF) { len = sprintf(page, "%d\n", led->state); } else { - u32 in = (gpio_in() & led->gpio ? 1 : 0); + u32 in = (bcm47xx_gpio_in(~0) & led->gpio ? 1 : 0); u8 p = (led->polarity == NORMAL ? 0 : 1); len = sprintf(page, "%d\n", ((in ^ p) ? 1 : 0)); } @@ -1555,9 +1595,9 @@ static ssize_t diag_proc_write(struct file *file, const char *buf, size_t count, led->state = p ^ ((page[0] == '1') ? 1 : 0); set_led_extif(led); } else { - gpio_outen(led->gpio, led->gpio); - gpio_control(led->gpio, 0); - gpio_out(led->gpio, ((p ^ (page[0] == '1')) ? led->gpio : 0)); + bcm47xx_gpio_outen(led->gpio, led->gpio); + bcm47xx_gpio_control(led->gpio, 0); + bcm47xx_gpio_out(led->gpio, ((p ^ (page[0] == '1')) ? led->gpio : 0)); } } break; diff --git a/package/broadcom-diag/src/gpio.h b/package/broadcom-diag/src/gpio.h index 4e382edeeb..d0e3e06c8a 100644 --- a/package/broadcom-diag/src/gpio.h +++ b/package/broadcom-diag/src/gpio.h @@ -6,150 +6,6 @@ #include #include -static inline u32 gpio_in(void) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_in(&bcm47xx_bus.ssb, ~0); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, ~0); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_out(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_outen(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); - return 0; -#endif - } - return -EINVAL; -} - -static inline u32 gpio_control(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_control(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_setintmask(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_intpolarity(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); -#endif - } - return -EINVAL; -} - -#ifdef CONFIG_BCM47XX_SSB -static inline u32 __ssb_write32_masked(struct ssb_device *dev, u16 offset, - u32 mask, u32 value) -{ - value &= mask; - value |= ssb_read32(dev, offset) & ~mask; - ssb_write32(dev, offset, value); - return value; -} -#endif - -#ifdef CONFIG_BCM47XX_BCMA -static inline u32 __bcma_write32_masked(struct bcma_device *dev, u16 offset, - u32 mask, u32 value) -{ - value &= mask; - value |= bcma_read32(dev, offset) & ~mask; - bcma_write32(dev, offset, value); - return value; -} -#endif - -static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *)) -{ - int irq; - - irq = gpio_to_irq(0); - if (irq == -EINVAL) return; - - if (enabled) { - if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler)) - return; - } else { - free_irq(irq, handler); - } - - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - if (bcm47xx_bus.ssb.chipco.dev) - __ssb_write32_masked(bcm47xx_bus.ssb.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0)); - break; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - if (bcm47xx_bus.bcma.bus.drv_cc.core) - __bcma_write32_masked(bcm47xx_bus.bcma.bus.drv_cc.core, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO, (enabled ? BCMA_CC_IRQ_GPIO : 0)); - break; -#endif - } -} - #define EXTIF_ADDR 0x1f000000 #define EXTIF_UART (EXTIF_ADDR + 0x00800000) @@ -157,13 +13,4 @@ static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *)) #define GPIO_TYPE_EXTIF (0x1 << 24) #define GPIO_TYPE_MASK (0xf << 24) -static inline void gpio_set_extif(int gpio, int value) -{ - volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (gpio & ~GPIO_TYPE_MASK); - if (value) - *addr = 0xFF; - else - *addr; -} - #endif /* __DIAG_GPIO_H */ diff --git a/package/switch/src/gpio-bcm947xx.h b/package/switch/src/gpio-bcm947xx.h deleted file mode 100644 index 23c221da87..0000000000 --- a/package/switch/src/gpio-bcm947xx.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __SWITCH_GPIO_H -#define __SWITCH_GPIO_H - -#include -#include -#include - -static inline u32 gpio_in(void) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_in(&bcm47xx_bus.ssb, ~0); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, ~0); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_out(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); -#endif - } - return -EINVAL; -} - -static inline u32 gpio_outen(u32 mask, u32 value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, mask, value); - return 0; -#endif - } - return -EINVAL; -} - -#endif /* __SWITCH_GPIO_H */ diff --git a/package/switch/src/gpio.h b/package/switch/src/gpio.h index 90bafd39ed..cb734f7b1b 100644 --- a/package/switch/src/gpio.h +++ b/package/switch/src/gpio.h @@ -9,16 +9,16 @@ #define __GPIO_H #ifdef CONFIG_BCM47XX -#include "gpio-bcm947xx.h" +#include #else #warning "Unsupported configuration." -#define gpio_in() (-1U) -#define gpio_out(mask, value) (-1U) -#define gpio_outen(mask, value) (-1U) -#define gpio_control(mask, value) (-1U) -#define gpio_intmask(mask, value) (-1U) -#define gpio_intpolarity(mask, value) (-1U) +#define bcm47xx_gpio_in(mask) (-1U) +#define bcm47xx_gpio_out(mask, value) (-1U) +#define bcm47xx_gpio_outen(mask, value) (-1U) +#define bcm47xx_gpio_control(mask, value) (-1U) +#define bcm47xx_gpio_intmask(mask, value) (-1U) +#define bcm47xx_gpio_polarity(mask, value) (-1U) #endif diff --git a/package/switch/src/switch-adm.c b/package/switch/src/switch-adm.c index 3826ca57f8..9a6d32b1ef 100644 --- a/package/switch/src/switch-adm.c +++ b/package/switch/src/switch-adm.c @@ -104,7 +104,7 @@ static void adm_write(int cs, char *buf, unsigned int bits) int i, len = (bits + 7) / 8; __u8 mask; - gpio_out(eecs, (cs ? eecs : 0)); + bcm47xx_gpio_out(eecs, (cs ? eecs : 0)); udelay(EECK_EDGE_TIME); /* Byte assemble from MSB to LSB */ @@ -112,25 +112,25 @@ static void adm_write(int cs, char *buf, unsigned int bits) /* Bit bang from MSB to LSB */ for (mask = 0x80; mask && bits > 0; mask >>= 1, bits --) { /* Clock low */ - gpio_out(eesk, 0); + bcm47xx_gpio_out(eesk, 0); udelay(EECK_EDGE_TIME); /* Output on rising edge */ - gpio_out(eedi, ((mask & buf[i]) ? eedi : 0)); + bcm47xx_gpio_out(eedi, ((mask & buf[i]) ? eedi : 0)); udelay(EEDI_SETUP_TIME); /* Clock high */ - gpio_out(eesk, eesk); + bcm47xx_gpio_out(eesk, eesk); udelay(EECK_EDGE_TIME); } } /* Clock low */ - gpio_out(eesk, 0); + bcm47xx_gpio_out(eesk, 0); udelay(EECK_EDGE_TIME); if (cs) - gpio_out(eecs, 0); + bcm47xx_gpio_out(eecs, 0); } @@ -139,7 +139,7 @@ static void adm_read(int cs, char *buf, unsigned int bits) int i, len = (bits + 7) / 8; __u8 mask; - gpio_out(eecs, (cs ? eecs : 0)); + bcm47xx_gpio_out(eecs, (cs ? eecs : 0)); udelay(EECK_EDGE_TIME); /* Byte assemble from MSB to LSB */ @@ -151,16 +151,16 @@ static void adm_read(int cs, char *buf, unsigned int bits) __u8 gp; /* Clock low */ - gpio_out(eesk, 0); + bcm47xx_gpio_out(eesk, 0); udelay(EECK_EDGE_TIME); /* Input on rising edge */ - gp = gpio_in(); + gp = bcm47xx_gpio_in(~0); if (gp & eedi) byte |= mask; /* Clock high */ - gpio_out(eesk, eesk); + bcm47xx_gpio_out(eesk, eesk); udelay(EECK_EDGE_TIME); } @@ -168,11 +168,11 @@ static void adm_read(int cs, char *buf, unsigned int bits) } /* Clock low */ - gpio_out(eesk, 0); + bcm47xx_gpio_out(eesk, 0); udelay(EECK_EDGE_TIME); if (cs) - gpio_out(eecs, 0); + bcm47xx_gpio_out(eecs, 0); } @@ -180,10 +180,10 @@ static void adm_read(int cs, char *buf, unsigned int bits) static void adm_enout(__u8 pins, __u8 val) { /* Prepare GPIO output value */ - gpio_out(pins, val); + bcm47xx_gpio_out(pins, val); /* Enable GPIO outputs */ - gpio_outen(pins, pins); + bcm47xx_gpio_outen(pins, pins); udelay(EECK_EDGE_TIME); } @@ -192,7 +192,7 @@ static void adm_enout(__u8 pins, __u8 val) static void adm_disout(__u8 pins) { /* Disable GPIO outputs */ - gpio_outen(pins, 0); + bcm47xx_gpio_outen(pins, 0); udelay(EECK_EDGE_TIME); } @@ -203,11 +203,11 @@ static void adm_adclk(int clocks) int i; for (i = 0; i < clocks; i++) { /* Clock high */ - gpio_out(eesk, eesk); + bcm47xx_gpio_out(eesk, eesk); udelay(EECK_EDGE_TIME); /* Clock low */ - gpio_out(eesk, 0); + bcm47xx_gpio_out(eesk, 0); udelay(EECK_EDGE_TIME); } } diff --git a/target/linux/brcm47xx/config-3.3 b/target/linux/brcm47xx/config-3.3 index 4ee8142f37..e207cf1743 100644 --- a/target/linux/brcm47xx/config-3.3 +++ b/target/linux/brcm47xx/config-3.3 @@ -1,6 +1,7 @@ CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_ARPD is not set CONFIG_B44=y @@ -15,6 +16,7 @@ CONFIG_BCMA=y CONFIG_BCMA_BLOCKIO=y CONFIG_BCMA_DEBUG=y CONFIG_BCMA_DRIVER_GMAC_CMN=y +CONFIG_BCMA_DRIVER_GPIO=y CONFIG_BCMA_DRIVER_MIPS=y CONFIG_BCMA_DRIVER_PCI_HOSTMODE=y CONFIG_BCMA_HOST_PCI=y @@ -50,6 +52,8 @@ CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_PCI_IOMAP=y +# CONFIG_GENERIC_PWM is not set +CONFIG_GPIOLIB=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y diff --git a/target/linux/brcm47xx/patches-3.3/050-bcma-export-needed-gpio-functions.patch b/target/linux/brcm47xx/patches-3.3/050-bcma-export-needed-gpio-functions.patch deleted file mode 100644 index 7d172d4c93..0000000000 --- a/target/linux/brcm47xx/patches-3.3/050-bcma-export-needed-gpio-functions.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f6e41db3ee7ead99e1398def222c14893fc265de Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Thu, 4 Aug 2011 21:09:48 +0200 -Subject: [PATCH 26/26] bcma: export needed gpio functions - - -Signed-off-by: Hauke Mehrtens ---- - drivers/bcma/driver_chipcommon.c | 5 +++++ - 1 files changed, 5 insertions(+), 0 deletions(-) - ---- a/drivers/bcma/driver_chipcommon.c -+++ b/drivers/bcma/driver_chipcommon.c -@@ -81,16 +81,19 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_ - { - return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; - } -+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_in); - - u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) - { - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); - } -+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out); - - u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) - { - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); - } -+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen); - - u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) - { -@@ -102,11 +105,13 @@ u32 bcma_chipco_gpio_intmask(struct bcma - { - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); - } -+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_intmask); - - u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) - { - return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); - } -+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_polarity); - - #ifdef CONFIG_BCMA_DRIVER_MIPS - void bcma_chipco_serial_init(struct bcma_drv_cc *cc) diff --git a/target/linux/brcm47xx/patches-3.3/140-bcm47xx-add-gpio_set_debounce.patch b/target/linux/brcm47xx/patches-3.3/140-bcm47xx-add-gpio_set_debounce.patch deleted file mode 100644 index c37bb13d14..0000000000 --- a/target/linux/brcm47xx/patches-3.3/140-bcm47xx-add-gpio_set_debounce.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/arch/mips/include/asm/mach-bcm47xx/gpio.h -+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h -@@ -151,5 +151,9 @@ static inline int gpio_polarity(unsigned - return -EINVAL; - } - -+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) -+{ -+ return -ENOSYS; -+} - - #endif /* __BCM47XX_GPIO_H */ diff --git a/target/linux/brcm47xx/patches-3.3/220-add_gpio_request_one.patch b/target/linux/brcm47xx/patches-3.3/220-add_gpio_request_one.patch deleted file mode 100644 index 00005e2d5a..0000000000 --- a/target/linux/brcm47xx/patches-3.3/220-add_gpio_request_one.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/arch/mips/bcm47xx/gpio.c -+++ b/arch/mips/bcm47xx/gpio.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -100,3 +101,30 @@ int gpio_to_irq(unsigned gpio) - return -EINVAL; - } - EXPORT_SYMBOL_GPL(gpio_to_irq); -+ -+/** -+ * gpio_request_one - request a single GPIO with initial configuration -+ * @gpio: the GPIO number -+ * @flags: GPIO configuration as specified by GPIOF_* -+ * @label: a literal description string of this GPIO -+ */ -+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) -+{ -+ int err; -+ -+ err = gpio_request(gpio, label); -+ if (err) -+ return err; -+ -+ if (flags & GPIOF_DIR_IN) -+ err = gpio_direction_input(gpio); -+ else -+ err = gpio_direction_output(gpio, -+ (flags & GPIOF_INIT_HIGH) ? 1 : 0); -+ -+ if (err) -+ gpio_free(gpio); -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(gpio_request_one); ---- a/arch/mips/include/asm/mach-bcm47xx/gpio.h -+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h -@@ -19,6 +19,7 @@ - extern int gpio_request(unsigned gpio, const char *label); - extern void gpio_free(unsigned gpio); - extern int gpio_to_irq(unsigned gpio); -+extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); - - static inline int gpio_get_value(unsigned gpio) - { diff --git a/target/linux/brcm47xx/patches-3.3/500-ssb-add-function-to-return-number-of-gpio-lines.patch b/target/linux/brcm47xx/patches-3.3/500-ssb-add-function-to-return-number-of-gpio-lines.patch new file mode 100644 index 0000000000..f1b483e4a4 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.3/500-ssb-add-function-to-return-number-of-gpio-lines.patch @@ -0,0 +1,40 @@ +--- a/drivers/ssb/embedded.c ++++ b/drivers/ssb/embedded.c +@@ -136,6 +136,18 @@ u32 ssb_gpio_polarity(struct ssb_bus *bu + } + EXPORT_SYMBOL(ssb_gpio_polarity); + ++int ssb_gpio_count(struct ssb_bus *bus) ++{ ++ if (ssb_chipco_available(&bus->chipco)) ++ return SSB_GPIO_CHIPCO_LINES; ++ else if (ssb_extif_available(&bus->extif)) ++ return SSB_GPIO_EXTIF_LINES; ++ else ++ SSB_WARN_ON(1); ++ return 0; ++} ++EXPORT_SYMBOL(ssb_gpio_count); ++ + #ifdef CONFIG_SSB_DRIVER_GIGE + static int gige_pci_init_callback(struct ssb_bus *bus, unsigned long data) + { +--- a/include/linux/ssb/ssb_embedded.h ++++ b/include/linux/ssb/ssb_embedded.h +@@ -7,6 +7,9 @@ + + extern int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks); + ++#define SSB_GPIO_EXTIF_LINES 5 ++#define SSB_GPIO_CHIPCO_LINES 16 ++ + /* Generic GPIO API */ + u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask); + u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value); +@@ -14,5 +17,6 @@ u32 ssb_gpio_outen(struct ssb_bus *bus, + u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value); + u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value); + u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value); ++int ssb_gpio_count(struct ssb_bus *bus); + + #endif /* LINUX_SSB_EMBEDDED_H_ */ diff --git a/target/linux/brcm47xx/patches-3.3/501-bcma-add-gpio-driver.patch b/target/linux/brcm47xx/patches-3.3/501-bcma-add-gpio-driver.patch new file mode 100644 index 0000000000..1fd2cffffb --- /dev/null +++ b/target/linux/brcm47xx/patches-3.3/501-bcma-add-gpio-driver.patch @@ -0,0 +1,170 @@ +--- a/drivers/bcma/Kconfig ++++ b/drivers/bcma/Kconfig +@@ -39,6 +39,11 @@ config BCMA_HOST_SOC + depends on BCMA_DRIVER_MIPS + select USB_HCD_BCMA if USB_EHCI_HCD || USB_OHCI_HCD + ++config BCMA_DRIVER_GPIO ++ bool ++ depends on BCMA_DRIVER_MIPS ++ default y ++ + config BCMA_SFLASH + bool + depends on BCMA_DRIVER_MIPS +--- a/drivers/bcma/Makefile ++++ b/drivers/bcma/Makefile +@@ -6,6 +6,7 @@ bcma-y += driver_pci.o + bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o + bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o + bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o ++bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o + bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o + bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o + obj-$(CONFIG_BCMA) += bcma.o +--- /dev/null ++++ b/drivers/bcma/driver_gpio.c +@@ -0,0 +1,96 @@ ++/* ++ * Broadcom specific AMBA ++ * GPIO driver for SoCs ++ * ++ * Copyright 2012, Hauke Mehrtens ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#include ++#include ++#include ++ ++u32 bcma_gpio_in(struct bcma_bus *bus, u32 mask) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_in(&bus->drv_cc, mask); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_in); ++ ++u32 bcma_gpio_out(struct bcma_bus *bus, u32 mask, u32 value) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_out(&bus->drv_cc, mask, value); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_out); ++ ++u32 bcma_gpio_outen(struct bcma_bus *bus, u32 mask, u32 value) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_outen(&bus->drv_cc, mask, value); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_outen); ++ ++u32 bcma_gpio_control(struct bcma_bus *bus, u32 mask, u32 value) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_control(&bus->drv_cc, mask, value); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_control); ++ ++u32 bcma_gpio_intmask(struct bcma_bus *bus, u32 mask, u32 value) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_intmask(&bus->drv_cc, mask, value); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_intmask); ++ ++u32 bcma_gpio_polarity(struct bcma_bus *bus, u32 mask, u32 value) ++{ ++ unsigned long flags; ++ u32 res = 0; ++ ++ spin_lock_irqsave(&bus->gpio_lock, flags); ++ res = bcma_chipco_gpio_polarity(&bus->drv_cc, mask, value); ++ spin_unlock_irqrestore(&bus->gpio_lock, flags); ++ ++ return res; ++} ++EXPORT_SYMBOL(bcma_gpio_polarity); ++ ++int bcma_gpio_count(struct bcma_bus *bus) ++{ ++ return BCMA_GPIO_CC_LINES; ++} ++EXPORT_SYMBOL(bcma_gpio_count); +--- a/drivers/bcma/scan.c ++++ b/drivers/bcma/scan.c +@@ -422,6 +422,10 @@ void bcma_init_bus(struct bcma_bus *bus) + if (bus->init_done) + return; + ++#ifdef CONFIG_BCMA_DRIVER_GPIO ++ spin_lock_init(&bus->gpio_lock); ++#endif ++ + INIT_LIST_HEAD(&bus->cores); + bus->nr_cores = 0; + +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -255,6 +255,11 @@ struct bcma_bus { + struct bcma_drv_mips drv_mips; + struct bcma_drv_gmac_cmn drv_gmac_cmn; + ++#ifdef CONFIG_BCMA_DRIVER_GPIO ++ /* Lock for GPIO register access. */ ++ spinlock_t gpio_lock; ++#endif /* CONFIG_BCMA_DRIVER_GPIO */ ++ + /* We decided to share SPROM struct with SSB as long as we do not need + * any hacks for BCMA. This simplifies drivers code. */ + struct ssb_sprom sprom; +--- /dev/null ++++ b/include/linux/bcma/bcma_driver_gpio.h +@@ -0,0 +1,17 @@ ++#ifndef LINUX_BCMA_DRIVER_GPIO_H_ ++#define LINUX_BCMA_DRIVER_GPIO_H_ ++ ++#include ++#include ++ ++#define BCMA_GPIO_CC_LINES 16 ++ ++u32 bcma_gpio_in(struct bcma_bus *bus, u32 mask); ++u32 bcma_gpio_out(struct bcma_bus *bus, u32 mask, u32 value); ++u32 bcma_gpio_outen(struct bcma_bus *bus, u32 mask, u32 value); ++u32 bcma_gpio_control(struct bcma_bus *bus, u32 mask, u32 value); ++u32 bcma_gpio_intmask(struct bcma_bus *bus, u32 mask, u32 value); ++u32 bcma_gpio_polarity(struct bcma_bus *bus, u32 mask, u32 value); ++int bcma_gpio_count(struct bcma_bus *bus); ++ ++#endif /* LINUX_BCMA_DRIVER_GPIO_H_ */ diff --git a/target/linux/brcm47xx/patches-3.3/502-bcm47xx-rewrite-gpio-handling.patch b/target/linux/brcm47xx/patches-3.3/502-bcm47xx-rewrite-gpio-handling.patch new file mode 100644 index 0000000000..4aa2e46d77 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.3/502-bcm47xx-rewrite-gpio-handling.patch @@ -0,0 +1,490 @@ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -92,6 +92,7 @@ config ATH79 + + config BCM47XX + bool "Broadcom BCM47XX based boards" ++ select ARCH_REQUIRE_GPIOLIB + select BOOT_RAW + select CEVT_R4K + select CSRC_R4K +@@ -100,7 +101,6 @@ config BCM47XX + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN +- select GENERIC_GPIO + select CFE + help + Support for BCM47XX based boards +--- a/arch/mips/bcm47xx/gpio.c ++++ b/arch/mips/bcm47xx/gpio.c +@@ -4,81 +4,198 @@ + * for more details. + * + * Copyright (C) 2007 Aurelien Jarno ++ * Copyright (C) 2012 Hauke Mehrtens ++ * ++ * Parts of this file are based on Atheros AR71XX/AR724X/AR913X GPIO + */ + + #include ++#include + #include +-#include +-#include +-#include +-#include ++#include ++#include ++#include ++ ++#include + +-#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) +-static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); +-#else +-static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); +-#endif + +-int gpio_request(unsigned gpio, const char *tag) ++static unsigned long bcm47xx_gpio_count; ++ ++/* low level BCM47xx gpio api */ ++u32 bcm47xx_gpio_in(u32 mask) + { + switch (bcm47xx_bus_type) { + #ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: +- if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && +- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) +- return -EINVAL; +- +- if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && +- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) +- return -EINVAL; ++ return ssb_gpio_in(&bcm47xx_bus.ssb, mask); ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ return bcma_gpio_in(&bcm47xx_bus.bcma.bus, mask); ++#endif ++ } ++ return -EINVAL; ++} ++EXPORT_SYMBOL(bcm47xx_gpio_in); + +- if (test_and_set_bit(gpio, gpio_in_use)) +- return -EBUSY; ++u32 bcm47xx_gpio_out(u32 mask, u32 value) ++{ ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value); ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ return bcma_gpio_out(&bcm47xx_bus.bcma.bus, mask, value); ++#endif ++ } ++ return -EINVAL; ++} ++EXPORT_SYMBOL(bcm47xx_gpio_out); + +- return 0; ++u32 bcm47xx_gpio_outen(u32 mask, u32 value) ++{ ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ return ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value); + #endif + #ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: +- if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) +- return -EINVAL; ++ return bcma_gpio_outen(&bcm47xx_bus.bcma.bus, mask, value); ++#endif ++ } ++ return -EINVAL; ++} ++EXPORT_SYMBOL(bcm47xx_gpio_outen); + +- if (test_and_set_bit(gpio, gpio_in_use)) +- return -EBUSY; ++u32 bcm47xx_gpio_control(u32 mask, u32 value) ++{ ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value); ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ return bcma_gpio_control(&bcm47xx_bus.bcma.bus, mask, value); ++#endif ++ } ++ return -EINVAL; ++} ++EXPORT_SYMBOL(bcm47xx_gpio_control); + +- return 0; ++u32 bcm47xx_gpio_intmask(u32 mask, u32 value) ++{ ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value); ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ return bcma_gpio_intmask(&bcm47xx_bus.bcma.bus, mask, value); + #endif + } + return -EINVAL; + } +-EXPORT_SYMBOL(gpio_request); ++EXPORT_SYMBOL(bcm47xx_gpio_intmask); + +-void gpio_free(unsigned gpio) ++u32 bcm47xx_gpio_polarity(u32 mask, u32 value) + { + switch (bcm47xx_bus_type) { + #ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: +- if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && +- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) +- return; ++ return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value); ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ return bcma_gpio_polarity(&bcm47xx_bus.bcma.bus, mask, value); ++#endif ++ } ++ return -EINVAL; ++} ++EXPORT_SYMBOL(bcm47xx_gpio_polarity); ++ ++ ++ ++static int bcm47xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) ++{ ++ return bcm47xx_gpio_in(1 << gpio); ++} ++ ++static void bcm47xx_gpio_set_value(struct gpio_chip *chip, ++ unsigned gpio, int value) ++{ ++ bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0); ++} ++ ++static int bcm47xx_gpio_direction_input(struct gpio_chip *chip, ++ unsigned gpio) ++{ ++ bcm47xx_gpio_outen(1 << gpio, 0); ++ return 0; ++} ++ ++static int bcm47xx_gpio_direction_output(struct gpio_chip *chip, ++ unsigned gpio, int value) ++{ ++ /* first set the gpio out value */ ++ bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0); ++ /* then set the gpio mode */ ++ bcm47xx_gpio_outen(1 << gpio, 1 << gpio); ++ return 0; ++} ++ ++static struct gpio_chip bcm47xx_gpio_chip = { ++ .label = "bcm47xx", ++ .get = bcm47xx_gpio_get_value, ++ .set = bcm47xx_gpio_set_value, ++ .direction_input = bcm47xx_gpio_direction_input, ++ .direction_output = bcm47xx_gpio_direction_output, ++ .base = 0, ++}; + +- if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && +- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) +- return; ++void __init bcm47xx_gpio_init(void) ++{ ++ int err; + +- clear_bit(gpio, gpio_in_use); +- return; ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ bcm47xx_gpio_count = ssb_gpio_count(&bcm47xx_bus.ssb); + #endif + #ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: +- if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) +- return; +- +- clear_bit(gpio, gpio_in_use); +- return; ++ bcm47xx_gpio_count = bcma_gpio_count(&bcm47xx_bus.bcma.bus); + #endif + } ++ ++ bcm47xx_gpio_chip.ngpio = bcm47xx_gpio_count; ++ ++ err = gpiochip_add(&bcm47xx_gpio_chip); ++ if (err) ++ panic("cannot add BCM47xx GPIO chip, error=%d", err); + } +-EXPORT_SYMBOL(gpio_free); ++ ++int gpio_get_value(unsigned gpio) ++{ ++ if (gpio < bcm47xx_gpio_count) ++ return bcm47xx_gpio_in(1 << gpio); ++ ++ return __gpio_get_value(gpio); ++} ++EXPORT_SYMBOL(gpio_get_value); ++ ++void gpio_set_value(unsigned gpio, int value) ++{ ++ if (gpio < bcm47xx_gpio_count) ++ bcm47xx_gpio_out(1 << gpio, value ? 1 << gpio : 0); ++ else ++ __gpio_set_value(gpio, value); ++} ++EXPORT_SYMBOL(gpio_set_value); + + int gpio_to_irq(unsigned gpio) + { +@@ -99,4 +216,11 @@ int gpio_to_irq(unsigned gpio) + } + return -EINVAL; + } +-EXPORT_SYMBOL_GPL(gpio_to_irq); ++EXPORT_SYMBOL(gpio_to_irq); ++ ++int irq_to_gpio(unsigned irq) ++{ ++ /* FIXME */ ++ return -EINVAL; ++} ++EXPORT_SYMBOL(irq_to_gpio); +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -344,6 +344,8 @@ void __init plat_mem_setup(void) + _machine_restart = bcm47xx_machine_restart; + _machine_halt = bcm47xx_machine_halt; + pm_power_off = bcm47xx_machine_halt; ++ ++ bcm47xx_gpio_init(); + } + + static int __init bcm47xx_register_bus_complete(void) +--- a/arch/mips/bcm47xx/wgt634u.c ++++ b/arch/mips/bcm47xx/wgt634u.c +@@ -133,6 +133,7 @@ static int __init wgt634u_init(void) + * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. + */ + u8 *et0mac; ++ int err; + + if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB) + return -ENODEV; +@@ -146,6 +147,12 @@ static int __init wgt634u_init(void) + + printk(KERN_INFO "WGT634U machine detected.\n"); + ++ err = gpio_request(WGT634U_GPIO_RESET, "reset-buton"); ++ if (err) { ++ printk(KERN_INFO "Can not register gpio fir reset button\n"); ++ return 0; ++ } ++ + if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET), + gpio_interrupt, IRQF_SHARED, + "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) { +--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h ++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +@@ -56,4 +56,6 @@ void bcm47xx_fill_bcma_boardinfo(struct + const char *prefix); + #endif + ++void bcm47xx_gpio_init(void); ++ + #endif /* __ASM_BCM47XX_H */ +--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h ++++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h +@@ -4,152 +4,39 @@ + * for more details. + * + * Copyright (C) 2007 Aurelien Jarno ++ * Copyright (C) 2012 Hauke Mehrtens + */ + + #ifndef __BCM47XX_GPIO_H + #define __BCM47XX_GPIO_H + +-#include +-#include +-#include +- +-#define BCM47XX_EXTIF_GPIO_LINES 5 +-#define BCM47XX_CHIPCO_GPIO_LINES 16 +- +-extern int gpio_request(unsigned gpio, const char *label); +-extern void gpio_free(unsigned gpio); +-extern int gpio_to_irq(unsigned gpio); ++#define ARCH_NR_GPIOS 64 ++#include + +-static inline int gpio_get_value(unsigned gpio) +-{ +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio); +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, +- 1 << gpio); +-#endif +- } +- return -EINVAL; +-} +- +-#define gpio_get_value_cansleep gpio_get_value +- +-static inline void gpio_set_value(unsigned gpio, int value) +-{ +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, +- value ? 1 << gpio : 0); +- return; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, +- value ? 1 << gpio : 0); +- return; +-#endif +- } +-} +- +-#define gpio_set_value_cansleep gpio_set_value +- +-static inline int gpio_cansleep(unsigned gpio) +-{ +- return 0; +-} ++/* low level BCM47xx gpio api */ ++u32 bcm47xx_gpio_in(u32 mask); ++u32 bcm47xx_gpio_out(u32 mask, u32 value); ++u32 bcm47xx_gpio_outen(u32 mask, u32 value); ++u32 bcm47xx_gpio_control(u32 mask, u32 value); ++u32 bcm47xx_gpio_intmask(u32 mask, u32 value); ++u32 bcm47xx_gpio_polarity(u32 mask, u32 value); + +-static inline int gpio_is_valid(unsigned gpio) +-{ +- return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES); +-} ++int gpio_to_irq(unsigned gpio); ++int irq_to_gpio(unsigned irq); ++int gpio_get_value(unsigned gpio); ++void gpio_set_value(unsigned gpio, int value); + +- +-static inline int gpio_direction_input(unsigned gpio) ++static inline void gpio_intmask(unsigned gpio, int value) + { +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0); +- return 0; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, +- 0); +- return 0; +-#endif +- } +- return -EINVAL; ++ bcm47xx_gpio_intmask(1 << gpio, value ? 1 << gpio : 0); + } + +-static inline int gpio_direction_output(unsigned gpio, int value) ++static inline void gpio_polarity(unsigned gpio, int value) + { +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- /* first set the gpio out value */ +- ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, +- value ? 1 << gpio : 0); +- /* then set the gpio mode */ +- ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio); +- return 0; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- /* first set the gpio out value */ +- bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, +- value ? 1 << gpio : 0); +- /* then set the gpio mode */ +- bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, +- 1 << gpio); +- return 0; +-#endif +- } +- return -EINVAL; ++ bcm47xx_gpio_polarity(1 << gpio, value ? 1 << gpio : 0); + } + +-static inline int gpio_intmask(unsigned gpio, int value) +-{ +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio, +- value ? 1 << gpio : 0); +- return 0; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc, +- 1 << gpio, value ? 1 << gpio : 0); +- return 0; +-#endif +- } +- return -EINVAL; +-} +- +-static inline int gpio_polarity(unsigned gpio, int value) +-{ +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio, +- value ? 1 << gpio : 0); +- return 0; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc, +- 1 << gpio, value ? 1 << gpio : 0); +- return 0; +-#endif +- } +- return -EINVAL; +-} + ++#define gpio_cansleep __gpio_cansleep + + #endif /* __BCM47XX_GPIO_H */ diff --git a/target/linux/brcm47xx/patches-3.3/812-disable_wgt634u_crap.patch b/target/linux/brcm47xx/patches-3.3/812-disable_wgt634u_crap.patch index 76419e823c..6b44254017 100644 --- a/target/linux/brcm47xx/patches-3.3/812-disable_wgt634u_crap.patch +++ b/target/linux/brcm47xx/patches-3.3/812-disable_wgt634u_crap.patch @@ -7,7 +7,7 @@ -obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o --- a/arch/mips/bcm47xx/wgt634u.c +++ /dev/null -@@ -1,170 +0,0 @@ +@@ -1,177 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive @@ -143,6 +143,7 @@ - * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. - */ - u8 *et0mac; +- int err; - - if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB) - return -ENODEV; @@ -156,6 +157,12 @@ - - printk(KERN_INFO "WGT634U machine detected.\n"); - +- err = gpio_request(WGT634U_GPIO_RESET, "reset-buton"); +- if (err) { +- printk(KERN_INFO "Can not register gpio fir reset button\n"); +- return 0; +- } +- - if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET), - gpio_interrupt, IRQF_SHARED, - "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) { -- 2.25.1