diff options
author | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-08-04 19:46:25 +0000 |
---|---|---|
committer | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-08-04 19:46:25 +0000 |
commit | 1d6c42df96154e859a0c02ec578780cb2948bb43 (patch) | |
tree | c9205034126c854e2e3791e91fec1fd6d6925bc3 /target/linux | |
parent | 039f1795516bfb35e637ab26168d5ae42c547bf0 (diff) |
brcm47xx: use libgpio instaed of implementing the gpio interface ourself.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32992 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
8 files changed, 712 insertions, 111 deletions
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 <hauke@hauke-m.de> -Date: Thu, 4 Aug 2011 21:09:48 +0200 -Subject: [PATCH 26/26] bcma: export needed gpio functions - - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - 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 <linux/export.h> -+#include <linux/gpio.h> - #include <linux/ssb/ssb.h> - #include <linux/ssb/ssb_driver_chipcommon.h> - #include <linux/ssb/ssb_driver_extif.h> -@@ -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 <hauke@hauke-m.de> ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#include <linux/export.h> ++#include <linux/bcma/bcma.h> ++#include <linux/bcma/bcma_driver_gpio.h> ++ ++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 <linux/types.h> ++#include <linux/bcma/bcma.h> ++ ++#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 <aurelien@aurel32.net> ++ * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de> ++ * ++ * Parts of this file are based on Atheros AR71XX/AR724X/AR913X GPIO + */ + + #include <linux/export.h> ++#include <linux/gpio.h> + #include <linux/ssb/ssb.h> +-#include <linux/ssb/ssb_driver_chipcommon.h> +-#include <linux/ssb/ssb_driver_extif.h> +-#include <asm/mach-bcm47xx/bcm47xx.h> +-#include <asm/mach-bcm47xx/gpio.h> ++#include <linux/ssb/ssb_embedded.h> ++#include <linux/bcma/bcma.h> ++#include <linux/bcma/bcma_driver_gpio.h> ++ ++#include <bcm47xx.h> + +-#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 <aurelien@aurel32.net> ++ * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de> + */ + + #ifndef __BCM47XX_GPIO_H + #define __BCM47XX_GPIO_H + +-#include <linux/ssb/ssb_embedded.h> +-#include <linux/bcma/bcma.h> +-#include <asm/mach-bcm47xx/bcm47xx.h> +- +-#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 <asm-generic/gpio.h> + +-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)) { |