brcm47xx: add new led and button support
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 12 Jan 2014 18:55:25 +0000 (18:55 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 12 Jan 2014 18:55:25 +0000 (18:55 +0000)
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
SVN-Revision: 39252

21 files changed:
target/linux/brcm47xx/config-3.10
target/linux/brcm47xx/patches-3.10/100-bcma-gpio-add-own-IRQ-domain.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/101-bcma-gpio-fix-irq-handling.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/102-ssb-gpio-add-own-IRQ-domain.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/120-MIPS-BCM47XX-Prepare-support-for-LEDs.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/121-MIPS-BCM47XX-Prepare-support-for-GPIO-buttons.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/122-MIPS-BCM47XX-Import-buttons-database-from-OpenWrt.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/123-MIPS-BCM47XX-Import-LEDs-database-from-OpenWrt.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/124-MIPS-BCM47XX-Enable-buttons-support-on-SSB.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/125-MIPS-BCM47XX-Convert-WNDR4500-to-new-syntax.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/126-MIPS-BCM47XX-Use-timer-trigger-for-status-LEDs.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/127-MIPS-BCM47XX-add-button-and-led-configuration-for-so.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/128-MIPS-BCM47XX-add-detection-and-GPIO-config-for-Sieme.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/129-MIPS-BCM47XX-add-Belkin-F7Dxxxx-board-detection.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.10/170-fix-74k-cpu.patch
target/linux/brcm47xx/patches-3.10/208-b44-use-fixed-PHY-device-if-we-do-not-find-any.patch
target/linux/brcm47xx/patches-3.10/400-arch-bcm47xx.patch
target/linux/brcm47xx/patches-3.10/812-disable_wgt634u_crap.patch
target/linux/brcm47xx/patches-3.10/820-wgt634u-nvram-fix.patch
target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch
target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch

index c35f872ede5aeddb19467ae485ff4d86ebef859c..4272dfaee6fcb2fc53e995536ee26f8970ebdac1 100644 (file)
@@ -95,6 +95,7 @@ CONFIG_HZ_PERIODIC=y
 CONFIG_IMAGE_CMDLINE_HACK=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IRQ_CPU=y
+CONFIG_IRQ_DOMAIN=y
 CONFIG_IRQ_FORCED_THREADING=y
 CONFIG_IRQ_WORK=y
 CONFIG_MDIO_BOARDINFO=y
diff --git a/target/linux/brcm47xx/patches-3.10/100-bcma-gpio-add-own-IRQ-domain.patch b/target/linux/brcm47xx/patches-3.10/100-bcma-gpio-add-own-IRQ-domain.patch
new file mode 100644 (file)
index 0000000..b6b370d
--- /dev/null
@@ -0,0 +1,222 @@
+From 37dc57c2400b2998868a5c103756f36b8dc53a17 Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Thu, 12 Dec 2013 13:46:03 +0100
+Subject: [PATCH 088/110] bcma: gpio: add own IRQ domain
+
+Input GPIO changes can generate interrupts, but we need kind of ACK for
+them by changing IRQ polarity. This is required to stop hardware from
+keep generating interrupts and generate another one on the next GPIO
+state change.
+This code allows using GPIOs with standard interrupts and add for
+example GPIO buttons support.
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Acked-by: John Crispin <blogic@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/6216/
+---
+ drivers/bcma/Kconfig                        |    1 +
+ drivers/bcma/driver_gpio.c                  |  135 ++++++++++++++++++++++++++-
+ include/linux/bcma/bcma_driver_chipcommon.h |    1 +
+ 3 files changed, 134 insertions(+), 3 deletions(-)
+
+--- a/drivers/bcma/Kconfig
++++ b/drivers/bcma/Kconfig
+@@ -76,6 +76,7 @@ config BCMA_DRIVER_GMAC_CMN
+ config BCMA_DRIVER_GPIO
+       bool "BCMA GPIO driver"
+       depends on BCMA && GPIOLIB
++      select IRQ_DOMAIN if BCMA_HOST_SOC
+       help
+         Driver to provide access to the GPIO pins of the bcma bus.
+--- a/drivers/bcma/driver_gpio.c
++++ b/drivers/bcma/driver_gpio.c
+@@ -9,6 +9,9 @@
+  */
+ #include <linux/gpio.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/irqdomain.h>
+ #include <linux/export.h>
+ #include <linux/bcma/bcma.h>
+@@ -73,19 +76,133 @@ static void bcma_gpio_free(struct gpio_c
+       bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
+ }
++#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
+ static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+ {
+       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+       if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
+-              return bcma_core_irq(cc->core);
++              return irq_find_mapping(cc->irq_domain, gpio);
+       else
+               return -EINVAL;
+ }
++static void bcma_gpio_irq_unmask(struct irq_data *d)
++{
++      struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
++
++      bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
++}
++
++static void bcma_gpio_irq_mask(struct irq_data *d)
++{
++      struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
++
++      bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
++}
++
++static struct irq_chip bcma_gpio_irq_chip = {
++      .name           = "BCMA-GPIO",
++      .irq_mask       = bcma_gpio_irq_mask,
++      .irq_unmask     = bcma_gpio_irq_unmask,
++};
++
++static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
++{
++      struct bcma_drv_cc *cc = dev_id;
++      u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
++      u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
++      u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
++      u32 irqs = (val ^ pol) & mask;
++      int gpio;
++
++      if (!irqs)
++              return IRQ_NONE;
++
++      for_each_set_bit(gpio, (unsigned long *)&irqs, cc->gpio.ngpio)
++              generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
++      bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
++
++      return IRQ_HANDLED;
++}
++
++static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
++{
++      struct gpio_chip *chip = &cc->gpio;
++      int gpio, hwirq, err;
++
++      if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
++              return 0;
++
++      cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
++                                             &irq_domain_simple_ops, cc);
++      if (!cc->irq_domain) {
++              err = -ENODEV;
++              goto err_irq_domain;
++      }
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_create_mapping(cc->irq_domain, gpio);
++
++              irq_set_chip_data(irq, cc);
++              irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
++                                       handle_simple_irq);
++      }
++
++      hwirq = bcma_core_irq(cc->core);
++      err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
++                        cc);
++      if (err)
++              goto err_req_irq;
++
++      bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
++
++      return 0;
++
++err_req_irq:
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(cc->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(cc->irq_domain);
++err_irq_domain:
++      return err;
++}
++
++static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
++{
++      struct gpio_chip *chip = &cc->gpio;
++      int gpio;
++
++      if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
++              return;
++
++      bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
++      free_irq(bcma_core_irq(cc->core), cc);
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(cc->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(cc->irq_domain);
++}
++#else
++static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
++{
++      return 0;
++}
++
++static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
++{
++}
++#endif
++
+ int bcma_gpio_init(struct bcma_drv_cc *cc)
+ {
+       struct gpio_chip *chip = &cc->gpio;
++      int err;
+       chip->label             = "bcma_gpio";
+       chip->owner             = THIS_MODULE;
+@@ -95,7 +212,8 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+       chip->set               = bcma_gpio_set_value;
+       chip->direction_input   = bcma_gpio_direction_input;
+       chip->direction_output  = bcma_gpio_direction_output;
+-      chip->to_irq            = bcma_gpio_to_irq;
++      if (IS_BUILTIN(CONFIG_BCMA_HOST_SOC))
++              chip->to_irq            = bcma_gpio_to_irq;
+       chip->ngpio             = 16;
+       /* There is just one SoC in one device and its GPIO addresses should be
+        * deterministic to address them more easily. The other buses could get
+@@ -105,10 +223,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+       else
+               chip->base              = -1;
+-      return gpiochip_add(chip);
++      err = bcma_gpio_irq_domain_init(cc);
++      if (err)
++              return err;
++
++      err = gpiochip_add(chip);
++      if (err) {
++              bcma_gpio_irq_domain_exit(cc);
++              return err;
++      }
++
++      return 0;
+ }
+ int bcma_gpio_unregister(struct bcma_drv_cc *cc)
+ {
++      bcma_gpio_irq_domain_exit(cc);
+       return gpiochip_remove(&cc->gpio);
+ }
+--- a/include/linux/bcma/bcma_driver_chipcommon.h
++++ b/include/linux/bcma/bcma_driver_chipcommon.h
+@@ -640,6 +640,7 @@ struct bcma_drv_cc {
+       spinlock_t gpio_lock;
+ #ifdef CONFIG_BCMA_DRIVER_GPIO
+       struct gpio_chip gpio;
++      struct irq_domain *irq_domain;
+ #endif
+ };
diff --git a/target/linux/brcm47xx/patches-3.10/101-bcma-gpio-fix-irq-handling.patch b/target/linux/brcm47xx/patches-3.10/101-bcma-gpio-fix-irq-handling.patch
new file mode 100644 (file)
index 0000000..388eefa
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/drivers/bcma/driver_gpio.c
++++ b/drivers/bcma/driver_gpio.c
+@@ -91,7 +91,9 @@ static void bcma_gpio_irq_unmask(struct
+ {
+       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
++      u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
++      bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
+       bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
+ }
+@@ -156,6 +158,7 @@ static int bcma_gpio_irq_domain_init(str
+       if (err)
+               goto err_req_irq;
++      bcma_chipco_gpio_intmask(cc, ~0, 0);
+       bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
+       return 0;
diff --git a/target/linux/brcm47xx/patches-3.10/102-ssb-gpio-add-own-IRQ-domain.patch b/target/linux/brcm47xx/patches-3.10/102-ssb-gpio-add-own-IRQ-domain.patch
new file mode 100644 (file)
index 0000000..9d3fe78
--- /dev/null
@@ -0,0 +1,450 @@
+From 5668cb19fea423cb6681f1efa8b130a26be2562e Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Fri, 3 Jan 2014 09:55:29 +0100
+Subject: [PATCH] ssb: gpio: add own IRQ domain
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ drivers/ssb/Kconfig       |    1 +
+ drivers/ssb/driver_gpio.c |  304 ++++++++++++++++++++++++++++++++++++++++++---
+ drivers/ssb/main.c        |   12 +-
+ include/linux/ssb/ssb.h   |    1 +
+ 4 files changed, 297 insertions(+), 21 deletions(-)
+
+--- a/drivers/ssb/Kconfig
++++ b/drivers/ssb/Kconfig
+@@ -169,6 +169,7 @@ config SSB_DRIVER_GIGE
+ config SSB_DRIVER_GPIO
+       bool "SSB GPIO driver"
+       depends on SSB && GPIOLIB
++      select IRQ_DOMAIN if SSB_EMBEDDED
+       help
+         Driver to provide access to the GPIO pins on the bus.
+--- a/drivers/ssb/driver_gpio.c
++++ b/drivers/ssb/driver_gpio.c
+@@ -9,16 +9,40 @@
+  */
+ #include <linux/gpio.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/irqdomain.h>
+ #include <linux/export.h>
+ #include <linux/ssb/ssb.h>
+ #include "ssb_private.h"
++
++/**************************************************
++ * Shared
++ **************************************************/
++
+ static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
+ {
+       return container_of(chip, struct ssb_bus, gpio);
+ }
++#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
++static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++      struct ssb_bus *bus = ssb_gpio_get_bus(chip);
++
++      if (bus->bustype == SSB_BUSTYPE_SSB)
++              return irq_find_mapping(bus->irq_domain, gpio);
++      else
++              return -EINVAL;
++}
++#endif
++
++/**************************************************
++ * ChipCommon
++ **************************************************/
++
+ static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
+ {
+       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+@@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct
+       ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
+ }
+-static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
++#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
++static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
+ {
+-      struct ssb_bus *bus = ssb_gpio_get_bus(chip);
++      struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
+-      if (bus->bustype == SSB_BUSTYPE_SSB)
+-              return ssb_mips_irq(bus->chipco.dev) + 2;
+-      else
+-              return -EINVAL;
++      ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
++}
++
++static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
++{
++      struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
++      u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
++
++      ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
++      ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
++}
++
++static struct irq_chip ssb_gpio_irq_chipco_chip = {
++      .name           = "SSB-GPIO-CC",
++      .irq_mask       = ssb_gpio_irq_chipco_mask,
++      .irq_unmask     = ssb_gpio_irq_chipco_unmask,
++};
++
++static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
++{
++      struct ssb_bus *bus = dev_id;
++      struct ssb_chipcommon *chipco = &bus->chipco;
++      u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
++      u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
++      u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
++      u32 irqs = (val ^ pol) & mask;
++      int gpio;
++
++      if (!irqs)
++              return IRQ_NONE;
++
++      for_each_set_bit(gpio, (unsigned long *)&irqs, bus->gpio.ngpio)
++              generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
++      ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
++
++      return IRQ_HANDLED;
++}
++
++static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
++{
++      struct ssb_chipcommon *chipco = &bus->chipco;
++      struct gpio_chip *chip = &bus->gpio;
++      int gpio, hwirq, err;
++
++      if (bus->bustype != SSB_BUSTYPE_SSB)
++              return 0;
++
++      bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
++                                              &irq_domain_simple_ops, chipco);
++      if (!bus->irq_domain) {
++              err = -ENODEV;
++              goto err_irq_domain;
++      }
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_create_mapping(bus->irq_domain, gpio);
++
++              irq_set_chip_data(irq, bus);
++              irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
++                                       handle_simple_irq);
++      }
++
++      hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
++      err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
++                        "gpio", bus);
++      if (err)
++              goto err_req_irq;
++
++      ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
++      chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
++
++      return 0;
++
++err_req_irq:
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(bus->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(bus->irq_domain);
++err_irq_domain:
++      return err;
++}
++
++static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
++{
++      struct ssb_chipcommon *chipco = &bus->chipco;
++      struct gpio_chip *chip = &bus->gpio;
++      int gpio;
++
++      if (bus->bustype != SSB_BUSTYPE_SSB)
++              return;
++
++      chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
++      free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(bus->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(bus->irq_domain);
++}
++#else
++static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
++{
++      return 0;
++}
++
++static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
++{
+ }
++#endif
+ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
+ {
+       struct gpio_chip *chip = &bus->gpio;
++      int err;
+       chip->label             = "ssb_chipco_gpio";
+       chip->owner             = THIS_MODULE;
+@@ -96,7 +230,8 @@ static int ssb_gpio_chipco_init(struct s
+       chip->set               = ssb_gpio_chipco_set_value;
+       chip->direction_input   = ssb_gpio_chipco_direction_input;
+       chip->direction_output  = ssb_gpio_chipco_direction_output;
+-      chip->to_irq            = ssb_gpio_chipco_to_irq;
++      if (IS_BUILTIN(CONFIG_SSB_EMBEDDED))
++              chip->to_irq    = ssb_gpio_to_irq;
+       chip->ngpio             = 16;
+       /* There is just one SoC in one device and its GPIO addresses should be
+        * deterministic to address them more easily. The other buses could get
+@@ -106,9 +241,23 @@ static int ssb_gpio_chipco_init(struct s
+       else
+               chip->base              = -1;
+-      return gpiochip_add(chip);
++      err = ssb_gpio_irq_chipco_domain_init(bus);
++      if (err)
++              return err;
++
++      err = gpiochip_add(chip);
++      if (err) {
++              ssb_gpio_irq_chipco_domain_exit(bus);
++              return err;
++      }
++
++      return 0;
+ }
++/**************************************************
++ * EXTIF
++ **************************************************/
++
+ #ifdef CONFIG_SSB_DRIVER_EXTIF
+ static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
+@@ -145,19 +294,127 @@ static int ssb_gpio_extif_direction_outp
+       return 0;
+ }
+-static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
++#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
++static void ssb_gpio_irq_extif_mask(struct irq_data *d)
+ {
+-      struct ssb_bus *bus = ssb_gpio_get_bus(chip);
++      struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
+-      if (bus->bustype == SSB_BUSTYPE_SSB)
+-              return ssb_mips_irq(bus->extif.dev) + 2;
+-      else
+-              return -EINVAL;
++      ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
+ }
++static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
++{
++      struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
++      int gpio = irqd_to_hwirq(d);
++      u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
++
++      ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
++      ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
++}
++
++static struct irq_chip ssb_gpio_irq_extif_chip = {
++      .name           = "SSB-GPIO-EXTIF",
++      .irq_mask       = ssb_gpio_irq_extif_mask,
++      .irq_unmask     = ssb_gpio_irq_extif_unmask,
++};
++
++static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
++{
++      struct ssb_bus *bus = dev_id;
++      struct ssb_extif *extif = &bus->extif;
++      u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
++      u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
++      u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
++      u32 irqs = (val ^ pol) & mask;
++      int gpio;
++
++      if (!irqs)
++              return IRQ_NONE;
++
++      for_each_set_bit(gpio, (unsigned long *)&irqs, bus->gpio.ngpio)
++              generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
++      ssb_extif_gpio_polarity(extif, irqs, val & irqs);
++
++      return IRQ_HANDLED;
++}
++
++static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
++{
++      struct ssb_extif *extif = &bus->extif;
++      struct gpio_chip *chip = &bus->gpio;
++      int gpio, hwirq, err;
++
++      if (bus->bustype != SSB_BUSTYPE_SSB)
++              return 0;
++
++      bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
++                                              &irq_domain_simple_ops, extif);
++      if (!bus->irq_domain) {
++              err = -ENODEV;
++              goto err_irq_domain;
++      }
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_create_mapping(bus->irq_domain, gpio);
++
++              irq_set_chip_data(irq, bus);
++              irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
++                                       handle_simple_irq);
++      }
++
++      hwirq = ssb_mips_irq(bus->extif.dev) + 2;
++      err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
++                        "gpio", bus);
++      if (err)
++              goto err_req_irq;
++
++      ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
++
++      return 0;
++
++err_req_irq:
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(bus->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(bus->irq_domain);
++err_irq_domain:
++      return err;
++}
++
++static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
++{
++      struct ssb_extif *extif = &bus->extif;
++      struct gpio_chip *chip = &bus->gpio;
++      int gpio;
++
++      if (bus->bustype != SSB_BUSTYPE_SSB)
++              return;
++
++      free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
++      for (gpio = 0; gpio < chip->ngpio; gpio++) {
++              int irq = irq_find_mapping(bus->irq_domain, gpio);
++
++              irq_dispose_mapping(irq);
++      }
++      irq_domain_remove(bus->irq_domain);
++}
++#else
++static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
++{
++      return 0;
++}
++
++static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
++{
++}
++#endif
++
+ static int ssb_gpio_extif_init(struct ssb_bus *bus)
+ {
+       struct gpio_chip *chip = &bus->gpio;
++      int err;
+       chip->label             = "ssb_extif_gpio";
+       chip->owner             = THIS_MODULE;
+@@ -165,7 +422,8 @@ static int ssb_gpio_extif_init(struct ss
+       chip->set               = ssb_gpio_extif_set_value;
+       chip->direction_input   = ssb_gpio_extif_direction_input;
+       chip->direction_output  = ssb_gpio_extif_direction_output;
+-      chip->to_irq            = ssb_gpio_extif_to_irq;
++      if (IS_BUILTIN(CONFIG_SSB_EMBEDDED))
++              chip->to_irq    = ssb_gpio_to_irq;
+       chip->ngpio             = 5;
+       /* There is just one SoC in one device and its GPIO addresses should be
+        * deterministic to address them more easily. The other buses could get
+@@ -175,7 +433,17 @@ static int ssb_gpio_extif_init(struct ss
+       else
+               chip->base              = -1;
+-      return gpiochip_add(chip);
++      err = ssb_gpio_irq_extif_domain_init(bus);
++      if (err)
++              return err;
++
++      err = gpiochip_add(chip);
++      if (err) {
++              ssb_gpio_irq_extif_domain_exit(bus);
++              return err;
++      }
++
++      return 0;
+ }
+ #else
+@@ -185,6 +453,10 @@ static int ssb_gpio_extif_init(struct ss
+ }
+ #endif
++/**************************************************
++ * Init
++ **************************************************/
++
+ int ssb_gpio_init(struct ssb_bus *bus)
+ {
+       if (ssb_chipco_available(&bus->chipco))
+--- a/drivers/ssb/main.c
++++ b/drivers/ssb/main.c
+@@ -590,6 +590,13 @@ static int ssb_attach_queued_buses(void)
+               ssb_pcicore_init(&bus->pcicore);
+               if (bus->bustype == SSB_BUSTYPE_SSB)
+                       ssb_watchdog_register(bus);
++
++              err = ssb_gpio_init(bus);
++              if (err == -ENOTSUPP)
++                      ssb_dbg("GPIO driver not activated\n");
++              else if (err)
++                      ssb_dbg("Error registering GPIO driver: %i\n", err);
++
+               ssb_bus_may_powerdown(bus);
+               err = ssb_devices_register(bus);
+@@ -827,11 +834,6 @@ static int ssb_bus_register(struct ssb_b
+       ssb_chipcommon_init(&bus->chipco);
+       ssb_extif_init(&bus->extif);
+       ssb_mipscore_init(&bus->mipscore);
+-      err = ssb_gpio_init(bus);
+-      if (err == -ENOTSUPP)
+-              ssb_dbg("GPIO driver not activated\n");
+-      else if (err)
+-              ssb_dbg("Error registering GPIO driver: %i\n", err);
+       err = ssb_fetch_invariants(bus, get_invariants);
+       if (err) {
+               ssb_bus_may_powerdown(bus);
+--- a/include/linux/ssb/ssb.h
++++ b/include/linux/ssb/ssb.h
+@@ -486,6 +486,7 @@ struct ssb_bus {
+ #endif /* EMBEDDED */
+ #ifdef CONFIG_SSB_DRIVER_GPIO
+       struct gpio_chip gpio;
++      struct irq_domain *irq_domain;
+ #endif /* DRIVER_GPIO */
+       /* Internal-only stuff follows. Do not touch. */
diff --git a/target/linux/brcm47xx/patches-3.10/120-MIPS-BCM47XX-Prepare-support-for-LEDs.patch b/target/linux/brcm47xx/patches-3.10/120-MIPS-BCM47XX-Prepare-support-for-LEDs.patch
new file mode 100644 (file)
index 0000000..424d1f0
--- /dev/null
@@ -0,0 +1,160 @@
+From 98e54a60a7346ef31cb851b670a238ad428b58fe Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Thu, 2 Jan 2014 13:27:15 +0100
+Subject: [PATCH 029/110] MIPS: BCM47XX: Prepare support for LEDs
+
+So far this is mostly just a proof of concept, database consists of a
+single device. Creating a nice iterateable array wasn't an option
+because devices have different amount of LEDs. And we don't want to
+waste memory just because of support for a device with dozens on LEDs.
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Acked-by: John Crispin <blogic@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/6299/
+---
+ arch/mips/bcm47xx/Kconfig           |    2 +
+ arch/mips/bcm47xx/Makefile          |    2 +-
+ arch/mips/bcm47xx/bcm47xx_private.h |    9 +++++
+ arch/mips/bcm47xx/leds.c            |   73 +++++++++++++++++++++++++++++++++++
+ arch/mips/bcm47xx/setup.c           |    6 +++
+ 5 files changed, 91 insertions(+), 1 deletion(-)
+ create mode 100644 arch/mips/bcm47xx/bcm47xx_private.h
+ create mode 100644 arch/mips/bcm47xx/leds.c
+
+--- a/arch/mips/bcm47xx/Kconfig
++++ b/arch/mips/bcm47xx/Kconfig
+@@ -12,6 +12,7 @@ config BCM47XX_SSB
+       select SSB_PCICORE_HOSTMODE if PCI
+       select SSB_DRIVER_GPIO
+       select GPIOLIB
++      select LEDS_GPIO_REGISTER
+       default y
+       help
+        Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
+@@ -29,6 +30,7 @@ config BCM47XX_BCMA
+       select BCMA_DRIVER_PCI_HOSTMODE if PCI
+       select BCMA_DRIVER_GPIO
+       select GPIOLIB
++      select LEDS_GPIO_REGISTER
+       default y
+       help
+        Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+--- a/arch/mips/bcm47xx/Makefile
++++ b/arch/mips/bcm47xx/Makefile
+@@ -4,5 +4,5 @@
+ #
+ obj-y                         += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
+-obj-y                         += board.o
++obj-y                         += board.o leds.o
+ obj-$(CONFIG_BCM47XX_SSB)     += wgt634u.o
+--- /dev/null
++++ b/arch/mips/bcm47xx/bcm47xx_private.h
+@@ -0,0 +1,9 @@
++#ifndef LINUX_BCM47XX_PRIVATE_H_
++#define LINUX_BCM47XX_PRIVATE_H_
++
++#include <linux/kernel.h>
++
++/* leds.c */
++void __init bcm47xx_leds_register(void);
++
++#endif
+--- /dev/null
++++ b/arch/mips/bcm47xx/leds.c
+@@ -0,0 +1,73 @@
++#include "bcm47xx_private.h"
++
++#include <linux/leds.h>
++#include <bcm47xx_board.h>
++
++static const struct gpio_led
++bcm47xx_leds_netgear_wndr4500_v1_leds[] __initconst = {
++      {
++              .name           = "bcm47xx:green:wps",
++              .gpio           = 1,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:green:power",
++              .gpio           = 2,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:orange:power",
++              .gpio           = 3,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:green:usb1",
++              .gpio           = 8,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:green:2ghz",
++              .gpio           = 9,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:blue:5ghz",
++              .gpio           = 11,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++      {
++              .name           = "bcm47xx:green:usb2",
++              .gpio           = 14,
++              .active_low     = 1,
++              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
++      },
++};
++
++static struct gpio_led_platform_data bcm47xx_leds_pdata;
++
++#define bcm47xx_set_pdata(dev_leds) do {                              \
++      bcm47xx_leds_pdata.leds = dev_leds;                             \
++      bcm47xx_leds_pdata.num_leds = ARRAY_SIZE(dev_leds);             \
++} while (0)
++
++void __init bcm47xx_leds_register(void)
++{
++      enum bcm47xx_board board = bcm47xx_board_get();
++
++      switch (board) {
++      case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
++              bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500_v1_leds);
++              break;
++      default:
++              pr_debug("No LEDs configuration found for this device\n");
++              return;
++      }
++
++      gpio_led_register_device(-1, &bcm47xx_leds_pdata);
++}
+--- a/arch/mips/bcm47xx/setup.c
++++ b/arch/mips/bcm47xx/setup.c
+@@ -26,6 +26,8 @@
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
++#include "bcm47xx_private.h"
++
+ #include <linux/export.h>
+ #include <linux/types.h>
+ #include <linux/ssb/ssb.h>
+@@ -243,6 +245,9 @@ static int __init bcm47xx_register_bus_c
+               break;
+ #endif
+       }
++
++      bcm47xx_leds_register();
++
+       return 0;
+ }
+ device_initcall(bcm47xx_register_bus_complete);
diff --git a/target/linux/brcm47xx/patches-3.10/121-MIPS-BCM47XX-Prepare-support-for-GPIO-buttons.patch b/target/linux/brcm47xx/patches-3.10/121-MIPS-BCM47XX-Prepare-support-for-GPIO-buttons.patch
new file mode 100644 (file)
index 0000000..627ea70
--- /dev/null
@@ -0,0 +1,152 @@
+From e352ec3c581df40f159771b30c262c2bc7fb802e Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Thu, 2 Jan 2014 13:31:32 +0100
+Subject: [PATCH 030/110] MIPS: BCM47XX: Prepare support for GPIO buttons
+
+So far this adds support for one Netgear model only, but it's designed
+and ready to add many more device. We could hopefully import database
+from OpenWrt.
+Support for SSB is currently disabled, because SSB doesn't implement IRQ
+domain yet.
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Acked-by: John Crispin <blogic@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/6300/
+---
+ arch/mips/bcm47xx/Makefile          |    2 +-
+ arch/mips/bcm47xx/bcm47xx_private.h |    3 ++
+ arch/mips/bcm47xx/buttons.c         |   95 +++++++++++++++++++++++++++++++++++
+ arch/mips/bcm47xx/setup.c           |    1 +
+ 4 files changed, 100 insertions(+), 1 deletion(-)
+ create mode 100644 arch/mips/bcm47xx/buttons.c
+
+--- a/arch/mips/bcm47xx/Makefile
++++ b/arch/mips/bcm47xx/Makefile
+@@ -4,5 +4,5 @@
+ #
+ obj-y                         += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
+-obj-y                         += board.o leds.o
++obj-y                         += board.o buttons.o leds.o
+ obj-$(CONFIG_BCM47XX_SSB)     += wgt634u.o
+--- a/arch/mips/bcm47xx/bcm47xx_private.h
++++ b/arch/mips/bcm47xx/bcm47xx_private.h
+@@ -3,6 +3,9 @@
+ #include <linux/kernel.h>
++/* buttons.c */
++int __init bcm47xx_buttons_register(void);
++
+ /* leds.c */
+ void __init bcm47xx_leds_register(void);
+--- /dev/null
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -0,0 +1,95 @@
++#include "bcm47xx_private.h"
++
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++#include <linux/interrupt.h>
++#include <linux/ssb/ssb_embedded.h>
++#include <bcm47xx_board.h>
++#include <bcm47xx.h>
++
++/**************************************************
++ * Database
++ **************************************************/
++
++static const struct gpio_keys_button
++bcm47xx_buttons_netgear_wndr4500_v1[] __initconst = {
++      {
++              .code           = KEY_WPS_BUTTON,
++              .gpio           = 4,
++              .active_low     = 1,
++      },
++      {
++              .code           = KEY_RFKILL,
++              .gpio           = 5,
++              .active_low     = 1,
++      },
++      {
++              .code           = KEY_RESTART,
++              .gpio           = 6,
++              .active_low     = 1,
++      },
++};
++
++/**************************************************
++ * Init
++ **************************************************/
++
++static struct gpio_keys_platform_data bcm47xx_button_pdata;
++
++static struct platform_device bcm47xx_buttons_gpio_keys = {
++      .name = "gpio-keys",
++      .dev = {
++              .platform_data = &bcm47xx_button_pdata,
++      }
++};
++
++/* Copy data from __initconst */
++static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons,
++                                     size_t nbuttons)
++{
++      size_t size = nbuttons * sizeof(*buttons);
++
++      bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
++      if (!bcm47xx_button_pdata.buttons)
++              return -ENOMEM;
++      memcpy(bcm47xx_button_pdata.buttons, buttons, size);
++      bcm47xx_button_pdata.nbuttons = nbuttons;
++
++      return 0;
++}
++
++#define bcm47xx_copy_bdata(dev_buttons)                                       \
++      bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons));
++
++int __init bcm47xx_buttons_register(void)
++{
++      enum bcm47xx_board board = bcm47xx_board_get();
++      int err;
++
++#ifdef CONFIG_BCM47XX_SSB
++      if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_SSB) {
++              pr_debug("Buttons on SSB are not supported yet.\n");
++              return -ENOTSUPP;
++      }
++#endif
++
++      switch (board) {
++      case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500_v1);
++              break;
++      default:
++              pr_debug("No buttons configuration found for this device\n");
++              return -ENOTSUPP;
++      }
++
++      if (err)
++              return -ENOMEM;
++
++      err = platform_device_register(&bcm47xx_buttons_gpio_keys);
++      if (err) {
++              pr_err("Failed to register platform device: %d\n", err);
++              return err;
++      }
++
++      return 0;
++}
+--- a/arch/mips/bcm47xx/setup.c
++++ b/arch/mips/bcm47xx/setup.c
+@@ -246,6 +246,7 @@ static int __init bcm47xx_register_bus_c
+ #endif
+       }
++      bcm47xx_buttons_register();
+       bcm47xx_leds_register();
+       return 0;
diff --git a/target/linux/brcm47xx/patches-3.10/122-MIPS-BCM47XX-Import-buttons-database-from-OpenWrt.patch b/target/linux/brcm47xx/patches-3.10/122-MIPS-BCM47XX-Import-buttons-database-from-OpenWrt.patch
new file mode 100644 (file)
index 0000000..e445a0c
--- /dev/null
@@ -0,0 +1,497 @@
+From 12dacbcfa86048cc0810fc6b91b3d7329722e59b Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Thu, 2 Jan 2014 13:37:56 +0100
+Subject: [PATCH 031/110] MIPS: BCM47XX: Import buttons database from OpenWrt
+
+This includes all devices from OpenWrt's "diag" that we support in arch
+code (we have entries for in enum bcm47xx_board).
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: John Crispin <blogic@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/6301/
+---
+ arch/mips/bcm47xx/buttons.c |  456 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 456 insertions(+)
+
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -11,6 +11,299 @@
+  * Database
+  **************************************************/
++#define BCM47XX_GPIO_KEY(_gpio, _code)                                        \
++      {                                                               \
++              .code           = _code,                                \
++              .gpio           = _gpio,                                \
++              .active_low     = 1,                                    \
++      }
++
++/* Asus */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_rtn12[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(1, KEY_RESTART),
++      BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */
++      BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */
++      BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_rtn16[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(8, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_rtn66u[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(9, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl300g[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl320ge[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl330ge[] __initconst = {
++      BCM47XX_GPIO_KEY(2, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl500gd[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl500gpv1[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_RESTART),
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
++      BCM47XX_GPIO_KEY(2, KEY_RESTART),
++      BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl500w[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++      BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl520gc[] __initconst = {
++      BCM47XX_GPIO_KEY(2, KEY_RESTART),
++      BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl520gu[] __initconst = {
++      BCM47XX_GPIO_KEY(2, KEY_RESTART),
++      BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wl700ge[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */
++      BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */
++      BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_asus_wlhdd[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++/* Huawei */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_huawei_e970[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++/* Belkin */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_belkin_f7d4301[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++      BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
++};
++
++/* Buffalo */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_whr_g125[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++      BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++      BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++      BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++};
++
++/* Dell */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_dell_tm2300[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_RESTART),
++};
++
++/* D-Link */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_dlink_dir130[] __initconst = {
++      BCM47XX_GPIO_KEY(3, KEY_RESTART),
++      BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_dlink_dir330[] __initconst = {
++      BCM47XX_GPIO_KEY(3, KEY_RESTART),
++      BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
++};
++
++/* Linksys */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e1000v1[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e1000v21[] __initconst = {
++      BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(10, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e2000v1[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(8, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e3000v1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e3200v1[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_RESTART),
++      BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_e4200v1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt150nv1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt150nv11[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt160nv1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt160nv3[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt300nv11[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_UNKNOWN),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt310nv1[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++      BCM47XX_GPIO_KEY(8, KEY_UNKNOWN),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++      BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt610nv2[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++/* Motorola */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_motorola_we800g[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_motorola_wr850gp[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_RESTART),
++};
++
++/* Netgear */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_RESTART),
++      BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(8, KEY_RFKILL),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_netgear_wndr3700v3[] __initconst = {
++      BCM47XX_GPIO_KEY(2, KEY_RFKILL),
++      BCM47XX_GPIO_KEY(3, KEY_RESTART),
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++};
++
+ static const struct gpio_keys_button
+ bcm47xx_buttons_netgear_wndr4500_v1[] __initconst = {
+       {
+@@ -30,6 +323,18 @@ bcm47xx_buttons_netgear_wndr4500_v1[] __
+       },
+ };
++static const struct gpio_keys_button
++bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++/* SimpleTech */
++
++static const struct gpio_keys_button
++bcm47xx_buttons_simpletech_simpleshare[] __initconst = {
++      BCM47XX_GPIO_KEY(0, KEY_RESTART),
++};
++
+ /**************************************************
+  * Init
+  **************************************************/
+@@ -74,9 +379,160 @@ int __init bcm47xx_buttons_register(void
+ #endif
+       switch (board) {
++      case BCM47XX_BOARD_ASUS_RTN12:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
++              break;
++      case BCM47XX_BOARD_ASUS_RTN16:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn16);
++              break;
++      case BCM47XX_BOARD_ASUS_RTN66U:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn66u);
++              break;
++      case BCM47XX_BOARD_ASUS_WL300G:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl300g);
++              break;
++      case BCM47XX_BOARD_ASUS_WL320GE:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl320ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WL330GE:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GD:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GPV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv1);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GPV2:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv2);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500W:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500w);
++              break;
++      case BCM47XX_BOARD_ASUS_WL520GC:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gc);
++              break;
++      case BCM47XX_BOARD_ASUS_WL520GU:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gu);
++              break;
++      case BCM47XX_BOARD_ASUS_WL700GE:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl700ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WLHDD:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd);
++              break;
++
++      case BCM47XX_BOARD_BELKIN_F7D4301:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301);
++              break;
++
++      case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr2_a54g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_G125:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g125);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_G54S:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g54s);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_hp_g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_G300N:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_g300n);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp);
++              break;
++
++      case BCM47XX_BOARD_DELL_TM2300:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_dell_tm2300);
++              break;
++
++      case BCM47XX_BOARD_DLINK_DIR130:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir130);
++              break;
++      case BCM47XX_BOARD_DLINK_DIR330:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir330);
++              break;
++
++      case BCM47XX_BOARD_HUAWEI_E970:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_huawei_e970);
++              break;
++
++      case BCM47XX_BOARD_LINKSYS_E1000V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E1000V21:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v21);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E2000V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E3000V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E3200V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3200v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E4200V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e4200v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT150NV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT150NV11:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv11);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT160NV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT160NV3:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT300NV11:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT310NV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT610NV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT610NV2:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2);
++              break;
++
++      case BCM47XX_BOARD_MOTOROLA_WE800G:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
++              break;
++      case BCM47XX_BOARD_MOTOROLA_WR850GP:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gp);
++              break;
++      case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3);
++              break;
++
++      case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
++              break;
++      case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
++              break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500_v1);
+               break;
++      case BCM47XX_BOARD_NETGEAR_WNR834BV2:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
++              break;
++
++      case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_simpletech_simpleshare);
++              break;
++
+       default:
+               pr_debug("No buttons configuration found for this device\n");
+               return -ENOTSUPP;
diff --git a/target/linux/brcm47xx/patches-3.10/123-MIPS-BCM47XX-Import-LEDs-database-from-OpenWrt.patch b/target/linux/brcm47xx/patches-3.10/123-MIPS-BCM47XX-Import-LEDs-database-from-OpenWrt.patch
new file mode 100644 (file)
index 0000000..2c7b5b7
--- /dev/null
@@ -0,0 +1,532 @@
+From 6d4b22bc843c9de0f6acdbdcfb9b91b897a39e9c Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Thu, 2 Jan 2014 12:32:57 +0100
+Subject: [PATCH 032/110] MIPS: BCM47XX: Import LEDs database from OpenWrt
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+Acked-by: John Crispin <blogic@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/6298/
+---
+ arch/mips/bcm47xx/leds.c |  494 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 494 insertions(+)
+
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -3,6 +3,334 @@
+ #include <linux/leds.h>
+ #include <bcm47xx_board.h>
++/**************************************************
++ * Database
++ **************************************************/
++
++#define BCM47XX_GPIO_LED(_gpio, _color, _function, _active_low,               \
++                       _default_state)                                \
++      {                                                               \
++              .name           = "bcm47xx:" _color ":" _function,      \
++              .gpio           = _gpio,                                \
++              .active_low     = _active_low,                          \
++              .default_state  = _default_state,                       \
++      }
++
++/* Asus */
++
++static const struct gpio_led
++bcm47xx_leds_asus_rtn12[] __initconst = {
++      BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_rtn16[] __initconst = {
++      BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_rtn66u[] __initconst = {
++      BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl300g[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl320ge[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(11, "unk", "link", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl330ge[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl500gd[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl500gpv1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl500gpv2[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl500w[] __initconst = {
++      BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl520gc[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl520gu[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wl700ge[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), /* Labeled "READY" (there is no "power" LED). Originally ON, flashing on USB activity. */
++};
++
++static const struct gpio_led
++bcm47xx_leds_asus_wlhdd[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(2, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Belkin */
++
++static const struct gpio_led
++bcm47xx_leds_belkin_f7d4301[] __initconst = {
++      BCM47XX_GPIO_LED(10, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(11, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(12, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(13, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(14, "unk", "usb0", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(15, "unk", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Buffalo */
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = {
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_whr_g125[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_whr_hp_g54[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_wzr_g300n[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_wzr_rs_g54[] __initconst = {
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_buffalo_wzr_rs_g54hp[] __initconst = {
++      BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Dell */
++
++static const struct gpio_led
++bcm47xx_leds_dell_tm2300[] __initconst = {
++      BCM47XX_GPIO_LED(6, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++/* D-Link */
++
++static const struct gpio_led
++bcm47xx_leds_dlink_dir130[] __initconst = {
++      BCM47XX_GPIO_LED(0, "green", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* Originally blinking when device is ready, separated from "power" LED */
++      BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_dlink_dir330[] __initconst = {
++      BCM47XX_GPIO_LED(0, "green", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* Originally blinking when device is ready, separated from "power" LED */
++      BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Huawei */
++
++static const struct gpio_led
++bcm47xx_leds_huawei_e970[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Linksys */
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e1000v1[] __initconst = {
++      BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e1000v21[] __initconst = {
++      BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e2000v1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e3000v1[] __initconst = {
++      BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e3200v1[] __initconst = {
++      BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_e4200v1[] __initconst = {
++      BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt150nv1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt150nv11[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt160nv1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt160nv3[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt300nv11[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "usb",  1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "power",  0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "amber", "wps",  1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(9, "blue", "wps",  1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
++      BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Motorola */
++
++static const struct gpio_led
++bcm47xx_leds_motorola_we800g[] __initconst = {
++      BCM47XX_GPIO_LED(1, "amber", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "unk", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), /* There are only 3 LEDs: Power, Wireless and Device (ethernet) */
++      BCM47XX_GPIO_LED(4, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++};
++
++static const struct gpio_led
++bcm47xx_leds_motorola_wr850gp[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(6, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_motorola_wr850gv2v3[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* Netgear */
++
++static const struct gpio_led
++bcm47xx_leds_netgear_wndr3400v1[] __initconst = {
++      BCM47XX_GPIO_LED(2, "green", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
+ static const struct gpio_led
+ bcm47xx_leds_netgear_wndr4500_v1_leds[] __initconst = {
+       {
+@@ -49,6 +377,24 @@ bcm47xx_leds_netgear_wndr4500_v1_leds[]
+       },
+ };
++static const struct gpio_led
++bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
++      BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++/* SimpleTech */
++
++static const struct gpio_led
++bcm47xx_leds_simpletech_simpleshare[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* "Ready" LED */
++};
++
++/**************************************************
++ * Init
++ **************************************************/
++
+ static struct gpio_led_platform_data bcm47xx_leds_pdata;
+ #define bcm47xx_set_pdata(dev_leds) do {                              \
+@@ -61,9 +407,157 @@ void __init bcm47xx_leds_register(void)
+       enum bcm47xx_board board = bcm47xx_board_get();
+       switch (board) {
++      case BCM47XX_BOARD_ASUS_RTN12:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
++              break;
++      case BCM47XX_BOARD_ASUS_RTN16:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
++              break;
++      case BCM47XX_BOARD_ASUS_RTN66U:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_rtn66u);
++              break;
++      case BCM47XX_BOARD_ASUS_WL300G:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl300g);
++              break;
++      case BCM47XX_BOARD_ASUS_WL320GE:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl320ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WL330GE:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GD:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GPV1:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv1);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500GPV2:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv2);
++              break;
++      case BCM47XX_BOARD_ASUS_WL500W:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl500w);
++              break;
++      case BCM47XX_BOARD_ASUS_WL520GC:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gc);
++              break;
++      case BCM47XX_BOARD_ASUS_WL520GU:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gu);
++              break;
++      case BCM47XX_BOARD_ASUS_WL700GE:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wl700ge);
++              break;
++      case BCM47XX_BOARD_ASUS_WLHDD:
++              bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd);
++              break;
++
++      case BCM47XX_BOARD_BELKIN_F7D4301:
++              bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301);
++              break;
++
++      case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr2_a54g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_G125:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g125);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_G54S:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g54s);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_hp_g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_G300N:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_g300n);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54);
++              break;
++      case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
++              bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54hp);
++              break;
++
++      case BCM47XX_BOARD_DELL_TM2300:
++              bcm47xx_set_pdata(bcm47xx_leds_dell_tm2300);
++              break;
++
++      case BCM47XX_BOARD_DLINK_DIR130:
++              bcm47xx_set_pdata(bcm47xx_leds_dlink_dir130);
++              break;
++      case BCM47XX_BOARD_DLINK_DIR330:
++              bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330);
++              break;
++
++      case BCM47XX_BOARD_HUAWEI_E970:
++              bcm47xx_set_pdata(bcm47xx_leds_huawei_e970);
++              break;
++
++      case BCM47XX_BOARD_LINKSYS_E1000V1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E1000V21:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v21);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E2000V1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e2000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E3000V1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e3000v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E3200V1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e3200v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_E4200V1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_e4200v1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT150NV1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT150NV11:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv11);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT160NV1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT160NV3:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT300NV11:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT310NV1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT610NV1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT610NV2:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2);
++              break;
++
++      case BCM47XX_BOARD_MOTOROLA_WE800G:
++              bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
++              break;
++      case BCM47XX_BOARD_MOTOROLA_WR850GP:
++              bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gp);
++              break;
++      case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
++              bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gv2v3);
++              break;
++
++      case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
++              bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1);
++              break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500_v1_leds);
+               break;
++      case BCM47XX_BOARD_NETGEAR_WNR834BV2:
++              bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
++              break;
++
++      case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
++              bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare);
++              break;
++
+       default:
+               pr_debug("No LEDs configuration found for this device\n");
+               return;
diff --git a/target/linux/brcm47xx/patches-3.10/124-MIPS-BCM47XX-Enable-buttons-support-on-SSB.patch b/target/linux/brcm47xx/patches-3.10/124-MIPS-BCM47XX-Enable-buttons-support-on-SSB.patch
new file mode 100644 (file)
index 0000000..7d59955
--- /dev/null
@@ -0,0 +1,36 @@
+From 6dac092b12755ccbc00412871cd9535b687d16d7 Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Fri, 3 Jan 2014 09:55:30 +0100
+Subject: [PATCH] MIPS: BCM47XX: Enable buttons support on SSB
+
+This is supported since implementing IRQ domain in ssb.
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+---
+ arch/mips/bcm47xx/buttons.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -3,7 +3,6 @@
+ #include <linux/input.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/interrupt.h>
+-#include <linux/ssb/ssb_embedded.h>
+ #include <bcm47xx_board.h>
+ #include <bcm47xx.h>
+@@ -371,13 +370,6 @@ int __init bcm47xx_buttons_register(void
+       enum bcm47xx_board board = bcm47xx_board_get();
+       int err;
+-#ifdef CONFIG_BCM47XX_SSB
+-      if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_SSB) {
+-              pr_debug("Buttons on SSB are not supported yet.\n");
+-              return -ENOTSUPP;
+-      }
+-#endif
+-
+       switch (board) {
+       case BCM47XX_BOARD_ASUS_RTN12:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
diff --git a/target/linux/brcm47xx/patches-3.10/125-MIPS-BCM47XX-Convert-WNDR4500-to-new-syntax.patch b/target/linux/brcm47xx/patches-3.10/125-MIPS-BCM47XX-Convert-WNDR4500-to-new-syntax.patch
new file mode 100644 (file)
index 0000000..00f962a
--- /dev/null
@@ -0,0 +1,118 @@
+From 2d842783d4aaa25803e92f663869ea64a4eddd00 Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Fri, 3 Jan 2014 09:37:42 +0100
+Subject: [PATCH] MIPS: BCM47XX: Convert WNDR4500 to new syntax
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+---
+ arch/mips/bcm47xx/buttons.c |   22 ++++--------------
+ arch/mips/bcm47xx/leds.c    |   53 ++++++++-----------------------------------
+ 2 files changed, 14 insertions(+), 61 deletions(-)
+
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -304,22 +304,10 @@ bcm47xx_buttons_netgear_wndr3700v3[] __i
+ };
+ static const struct gpio_keys_button
+-bcm47xx_buttons_netgear_wndr4500_v1[] __initconst = {
+-      {
+-              .code           = KEY_WPS_BUTTON,
+-              .gpio           = 4,
+-              .active_low     = 1,
+-      },
+-      {
+-              .code           = KEY_RFKILL,
+-              .gpio           = 5,
+-              .active_low     = 1,
+-      },
+-      {
+-              .code           = KEY_RESTART,
+-              .gpio           = 6,
+-              .active_low     = 1,
+-      },
++bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(5, KEY_RFKILL),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
+ };
+ static const struct gpio_keys_button
+@@ -515,7 +503,7 @@ int __init bcm47xx_buttons_register(void
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+-              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500_v1);
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNR834BV2:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -332,49 +332,14 @@ bcm47xx_leds_netgear_wndr3400v1[] __init
+ };
+ static const struct gpio_led
+-bcm47xx_leds_netgear_wndr4500_v1_leds[] __initconst = {
+-      {
+-              .name           = "bcm47xx:green:wps",
+-              .gpio           = 1,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:green:power",
+-              .gpio           = 2,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:orange:power",
+-              .gpio           = 3,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:green:usb1",
+-              .gpio           = 8,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:green:2ghz",
+-              .gpio           = 9,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:blue:5ghz",
+-              .gpio           = 11,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
+-      {
+-              .name           = "bcm47xx:green:usb2",
+-              .gpio           = 14,
+-              .active_low     = 1,
+-              .default_state  = LEDS_GPIO_DEFSTATE_KEEP,
+-      },
++bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
++      BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(2, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(3, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(8, "green", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(9, "green", "2ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(11, "blue", "5ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF),
+ };
+ static const struct gpio_led
+@@ -548,7 +513,7 @@ void __init bcm47xx_leds_register(void)
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+-              bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500_v1_leds);
++              bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNR834BV2:
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
diff --git a/target/linux/brcm47xx/patches-3.10/126-MIPS-BCM47XX-Use-timer-trigger-for-status-LEDs.patch b/target/linux/brcm47xx/patches-3.10/126-MIPS-BCM47XX-Use-timer-trigger-for-status-LEDs.patch
new file mode 100644 (file)
index 0000000..e14bea9
--- /dev/null
@@ -0,0 +1,49 @@
+From 5c985c2a17ae0bdbc95fd8246631e00a35746396 Mon Sep 17 00:00:00 2001
+From: Rafa? Mi?ecki <zajec5@gmail.com>
+Date: Fri, 3 Jan 2014 09:04:39 +0100
+Subject: [PATCH] MIPS: BCM47XX: Use "timer" trigger for status LEDs
+
+Some devices have power LED as well as status LED. The second one is
+used to show the firmware is up and running. Set "timer" trigger for
+such LEDs.
+
+Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
+---
+ arch/mips/bcm47xx/leds.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -16,6 +16,16 @@
+               .default_state  = _default_state,                       \
+       }
++#define BCM47XX_GPIO_LED_TRIGGER(_gpio, _color, _function, _active_low,       \
++                               _default_trigger)                      \
++      {                                                               \
++              .name           = "bcm47xx:" _color ":" _function,      \
++              .gpio           = _gpio,                                \
++              .active_low     = _active_low,                          \
++              .default_state  = LEDS_GPIO_DEFSTATE_OFF,               \
++              .default_trigger        = _default_trigger,             \
++      }
++
+ /* Asus */
+ static const struct gpio_led
+@@ -176,13 +186,13 @@ bcm47xx_leds_dell_tm2300[] __initconst =
+ static const struct gpio_led
+ bcm47xx_leds_dlink_dir130[] __initconst = {
+-      BCM47XX_GPIO_LED(0, "green", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* Originally blinking when device is ready, separated from "power" LED */
++      BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
+       BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
+ };
+ static const struct gpio_led
+ bcm47xx_leds_dlink_dir330[] __initconst = {
+-      BCM47XX_GPIO_LED(0, "green", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* Originally blinking when device is ready, separated from "power" LED */
++      BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
+       BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
+ };
diff --git a/target/linux/brcm47xx/patches-3.10/127-MIPS-BCM47XX-add-button-and-led-configuration-for-so.patch b/target/linux/brcm47xx/patches-3.10/127-MIPS-BCM47XX-add-button-and-led-configuration-for-so.patch
new file mode 100644 (file)
index 0000000..845d071
--- /dev/null
@@ -0,0 +1,133 @@
+From 9894af92816e729162812f2554c9d97578138834 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Fri, 10 Jan 2014 23:55:28 +0100
+Subject: [PATCH 1/2] MIPS: BCM47XX: add button and led configuration for some
+ Linksys devices
+
+This adds led and button GPIO configuration for Linksys wrt54g3gv2,
+wrt54gsv1 and wrtsl54gs. This is based on OpenWrt broadcom-diag code.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/mips/bcm47xx/buttons.c |   27 +++++++++++++++++++++++++++
+ arch/mips/bcm47xx/leds.c    |   33 +++++++++++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -259,6 +259,18 @@ bcm47xx_buttons_linksys_wrt310nv1[] __in
+ };
+ static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
++      BCM47XX_GPIO_KEY(5, KEY_WIMAX),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrt54gsv1[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
++static const struct gpio_keys_button
+ bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+       BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
+@@ -270,6 +282,12 @@ bcm47xx_buttons_linksys_wrt610nv2[] __in
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+ };
++static const struct gpio_keys_button
++bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
++      BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
++      BCM47XX_GPIO_KEY(6, KEY_RESTART),
++};
++
+ /* Motorola */
+ static const struct gpio_keys_button
+@@ -479,12 +497,21 @@ int __init bcm47xx_buttons_register(void
+       case BCM47XX_BOARD_LINKSYS_WRT310NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
+               break;
++      case BCM47XX_BOARD_LINKSYS_WRT54GSV1:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54gsv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
++              break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV2:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2);
+               break;
++      case BCM47XX_BOARD_LINKSYS_WRTSL54GS:
++              err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs);
++              break;
+       case BCM47XX_BOARD_MOTOROLA_WE800G:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -292,6 +292,21 @@ bcm47xx_leds_linksys_wrt310nv1[] __initc
+ };
+ static const struct gpio_led
++bcm47xx_leds_linksys_wrt54gsv1[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
++bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = {
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(2, "green", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
++};
++
++static const struct gpio_led
+ bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "usb",  1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "power",  0, LEDS_GPIO_DEFSTATE_OFF),
+@@ -308,6 +323,15 @@ bcm47xx_leds_linksys_wrt610nv2[] __initc
+       BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+ };
++static const struct gpio_led
++bcm47xx_leds_linksys_wrtsl54gs[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
++      BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(7, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
++};
++
+ /* Motorola */
+ static const struct gpio_led
+@@ -502,12 +526,21 @@ void __init bcm47xx_leds_register(void)
+       case BCM47XX_BOARD_LINKSYS_WRT310NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
+               break;
++      case BCM47XX_BOARD_LINKSYS_WRT54GSV1:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54gsv1);
++              break;
++      case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2);
++              break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV2:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2);
+               break;
++      case BCM47XX_BOARD_LINKSYS_WRTSL54GS:
++              bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs);
++              break;
+       case BCM47XX_BOARD_MOTOROLA_WE800G:
+               bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
diff --git a/target/linux/brcm47xx/patches-3.10/128-MIPS-BCM47XX-add-detection-and-GPIO-config-for-Sieme.patch b/target/linux/brcm47xx/patches-3.10/128-MIPS-BCM47XX-add-detection-and-GPIO-config-for-Sieme.patch
new file mode 100644 (file)
index 0000000..2c2cfda
--- /dev/null
@@ -0,0 +1,89 @@
+From c546fa49901252cbc1e4046d7188858b2f9e130f Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Fri, 10 Jan 2014 23:55:43 +0100
+Subject: [PATCH 2/2] MIPS: BCM47XX: add detection and GPIO config for Siemens
+ SE505v2
+
+This adds board detection for the Siemens SE505v2 and the led gpio
+configuration. This board does not have any buttons.
+This is based on OpenWrt broadcom-diag and Manuel Munz's nvram dump.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/mips/bcm47xx/board.c                          |   17 +++++++++++++++++
+ arch/mips/bcm47xx/leds.c                           |   12 ++++++++++++
+ arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h |    2 ++
+ 3 files changed, 31 insertions(+)
+
+--- a/arch/mips/bcm47xx/board.c
++++ b/arch/mips/bcm47xx/board.c
+@@ -179,6 +179,13 @@ struct bcm47xx_board_type_list3 bcm47xx_
+       { {0}, NULL},
+ };
++/* boardtype, boardrev */
++static const
++struct bcm47xx_board_type_list2 bcm47xx_board_list_board_type_rev[] __initconst = {
++      {{BCM47XX_BOARD_SIEMENS_SE505V2, "Siemens SE505 V2"}, "0x0101", "0x10"},
++      { {0}, NULL},
++};
++
+ static const
+ struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = {
+       {BCM47XX_BOARD_UNKNOWN, "Unknown Board"},
+@@ -272,6 +279,16 @@ static __init const struct bcm47xx_board
+                               return &e3->board;
+               }
+       }
++
++      if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
++          bcm47xx_nvram_getenv("boardrev", buf2, sizeof(buf2)) >= 0 &&
++          bcm47xx_nvram_getenv("boardnum", buf3, sizeof(buf3)) ==  -ENOENT) {
++              for (e2 = bcm47xx_board_list_board_type_rev; e2->value1; e2++) {
++                      if (!strcmp(buf1, e2->value1) &&
++                          !strcmp(buf2, e2->value2))
++                              return &e2->board;
++              }
++      }
+       return bcm47xx_board_unknown;
+ }
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -383,6 +383,14 @@ bcm47xx_leds_netgear_wnr834bv2[] __initc
+       BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF),
+ };
++/* Siemens */
++static const struct gpio_led
++bcm47xx_leds_siemens_se505v2[] __initconst = {
++      BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(3, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
++      BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
++};
++
+ /* SimpleTech */
+ static const struct gpio_led
+@@ -562,6 +570,10 @@ void __init bcm47xx_leds_register(void)
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
+               break;
++      case BCM47XX_BOARD_SIEMENS_SE505V2:
++              bcm47xx_set_pdata(bcm47xx_leds_siemens_se505v2);
++              break;
++
+       case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
+               bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare);
+               break;
+--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+@@ -94,6 +94,8 @@ enum bcm47xx_board {
+       BCM47XX_BOARD_PHICOMM_M1,
++      BCM47XX_BOARD_SIEMENS_SE505V2,
++
+       BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE,
+       BCM47XX_BOARD_ZTE_H218N,
diff --git a/target/linux/brcm47xx/patches-3.10/129-MIPS-BCM47XX-add-Belkin-F7Dxxxx-board-detection.patch b/target/linux/brcm47xx/patches-3.10/129-MIPS-BCM47XX-add-Belkin-F7Dxxxx-board-detection.patch
new file mode 100644 (file)
index 0000000..ff6c388
--- /dev/null
@@ -0,0 +1,77 @@
+From 44927df87162ae9beb6e7b934b0e75818b88e350 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Thu, 2 Jan 2014 19:10:05 +0100
+Subject: [PATCH] MIPS: BCM47XX: add Belkin F7Dxxxx board detection
+
+From: Cody P Schafer <devel@codyps.com>
+
+Add a few Belkin F7Dxxxx entries, with F7D4401 sourced from online
+documentation and the "F7D7302" being observed. F7D3301, F7D3302, and
+F7D4302 are reasonable guesses which are unlikely to cause
+mis-detection.
+
+Signed-off-by: Cody P Schafer <devel@codyps.com>
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/mips/bcm47xx/board.c                          |    4 ++++
+ arch/mips/bcm47xx/buttons.c                        |    4 ++++
+ arch/mips/bcm47xx/leds.c                           |    4 ++++
+ arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h |    4 ++++
+ 4 files changed, 16 insertions(+)
+
+--- a/arch/mips/bcm47xx/board.c
++++ b/arch/mips/bcm47xx/board.c
+@@ -71,7 +71,11 @@ struct bcm47xx_board_type_list1 bcm47xx_
+       {{BCM47XX_BOARD_ASUS_WL500W, "Asus WL500W"}, "WL500gW-"},
+       {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"},
+       {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"},
++      {{BCM47XX_BOARD_BELKIN_F7D3301, "Belkin F7D3301"}, "F7D3301"},
++      {{BCM47XX_BOARD_BELKIN_F7D3302, "Belkin F7D3302"}, "F7D3302"},
+       {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"},
++      {{BCM47XX_BOARD_BELKIN_F7D4302, "Belkin F7D4302"}, "F7D4302"},
++      {{BCM47XX_BOARD_BELKIN_F7D4401, "Belkin F7D4401"}, "F7D4401"},
+       { {0}, NULL},
+ };
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -420,7 +420,11 @@ int __init bcm47xx_buttons_register(void
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd);
+               break;
++      case BCM47XX_BOARD_BELKIN_F7D3301:
++      case BCM47XX_BOARD_BELKIN_F7D3302:
+       case BCM47XX_BOARD_BELKIN_F7D4301:
++      case BCM47XX_BOARD_BELKIN_F7D4302:
++      case BCM47XX_BOARD_BELKIN_F7D4401:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301);
+               break;
+--- a/arch/mips/bcm47xx/leds.c
++++ b/arch/mips/bcm47xx/leds.c
+@@ -457,7 +457,11 @@ void __init bcm47xx_leds_register(void)
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd);
+               break;
++      case BCM47XX_BOARD_BELKIN_F7D3301:
++      case BCM47XX_BOARD_BELKIN_F7D3302:
+       case BCM47XX_BOARD_BELKIN_F7D4301:
++      case BCM47XX_BOARD_BELKIN_F7D4302:
++      case BCM47XX_BOARD_BELKIN_F7D4401:
+               bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301);
+               break;
+--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+@@ -27,7 +27,11 @@ enum bcm47xx_board {
+       BCM47XX_BOARD_ASUS_WL700GE,
+       BCM47XX_BOARD_ASUS_WLHDD,
++      BCM47XX_BOARD_BELKIN_F7D3301,
++      BCM47XX_BOARD_BELKIN_F7D3302,
+       BCM47XX_BOARD_BELKIN_F7D4301,
++      BCM47XX_BOARD_BELKIN_F7D4302,
++      BCM47XX_BOARD_BELKIN_F7D4401,
+       BCM47XX_BOARD_BUFFALO_WBR2_G54,
+       BCM47XX_BOARD_BUFFALO_WHR2_A54G54,
index 6247933a8609b8813725df02492e6e6248dd5456..3e1543b7f5ad934c9eb2576b8b6cfd61b4bf0809 100644 (file)
@@ -14,7 +14,7 @@ Acked-by: Rafa? Mi?ecki <zajec5@gmail.com>
 
 --- a/arch/mips/bcm47xx/setup.c
 +++ b/arch/mips/bcm47xx/setup.c
-@@ -35,6 +35,7 @@
+@@ -37,6 +37,7 @@
  #include <asm/prom.h>
  #include <asm/reboot.h>
  #include <asm/time.h>
@@ -22,7 +22,7 @@ Acked-by: Rafa? Mi?ecki <zajec5@gmail.com>
  #include <bcm47xx.h>
  #include <bcm47xx_nvram.h>
  #include <bcm47xx_board.h>
-@@ -229,6 +230,31 @@ void __init plat_mem_setup(void)
+@@ -231,6 +232,31 @@ void __init plat_mem_setup(void)
        mips_set_machine_name(bcm47xx_board_get_name());
  }
  
index e30c454398bda2f1dfd85609da4234a7442fe25d..89744666e04c865a54412801eba5354c323b9010 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/arch/mips/bcm47xx/setup.c
 +++ b/arch/mips/bcm47xx/setup.c
-@@ -28,6 +28,9 @@
+@@ -30,6 +30,9 @@
  
  #include <linux/export.h>
  #include <linux/types.h>
@@ -30,7 +30,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  #include <linux/ssb/ssb.h>
  #include <linux/ssb/ssb_embedded.h>
  #include <linux/bcma/bcma_soc.h>
-@@ -255,6 +258,12 @@ static int __init bcm47xx_cpu_fixes(void
+@@ -257,6 +260,12 @@ static int __init bcm47xx_cpu_fixes(void
  }
  arch_initcall(bcm47xx_cpu_fixes);
  
@@ -43,14 +43,14 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static int __init bcm47xx_register_bus_complete(void)
  {
        switch (bcm47xx_bus_type) {
-@@ -269,6 +278,7 @@ static int __init bcm47xx_register_bus_c
-               break;
- #endif
-       }
+@@ -274,6 +283,7 @@ static int __init bcm47xx_register_bus_c
+       bcm47xx_buttons_register();
+       bcm47xx_leds_register();
 +      fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
        return 0;
  }
- device_initcall(bcm47xx_register_bus_complete);
 --- a/drivers/net/ethernet/broadcom/b44.c
 +++ b/drivers/net/ethernet/broadcom/b44.c
 @@ -2233,6 +2233,7 @@ static int b44_register_phy_one(struct b
index ed3e81600ab19841a5e11fee6e6d4617f3579fe3..7ea3f87c64a7118eb12af166803eb39ad65c1f52 100644 (file)
@@ -36,7 +36,7 @@
 @@ -5,4 +5,5 @@
  
  obj-y                         += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
- obj-y                         += board.o
+ obj-y                         += board.o buttons.o leds.o
 +obj-y                         += gpio.o
  obj-$(CONFIG_BCM47XX_SSB)     += wgt634u.o
 --- /dev/null
index f2950c93bfb551d76ea2178f480b78d8b421f489..e29fa627749edec3f8885373806d2246fdfbc5b2 100644 (file)
@@ -2,7 +2,7 @@
 +++ b/arch/mips/bcm47xx/Makefile
 @@ -6,4 +6,3 @@
  obj-y                         += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
- obj-y                         += board.o
+ obj-y                         += board.o buttons.o leds.o
  obj-y                         += gpio.o
 -obj-$(CONFIG_BCM47XX_SSB)     += wgt634u.o
 --- a/arch/mips/bcm47xx/wgt634u.c
index 96b6ed84c158052ee07234fbc0f706c5d9ecbe2d..7c90835e437fb8b0829c5c2530b8be019cc4236c 100644 (file)
@@ -7,7 +7,7 @@ out the configuration than the in kernel cfe config reader.
 +++ b/arch/mips/bcm47xx/Makefile
 @@ -6,3 +6,4 @@
  obj-y                         += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
- obj-y                         += board.o
+ obj-y                         += board.o buttons.o leds.o
  obj-y                         += gpio.o
 +obj-y                         += cfe_env.o
 --- /dev/null
index 6534af97e6cd08889334bf618f422d5792e630bc..92a565f65e441dd4ce362d404daba2d768ce602b 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/bcm47xx/setup.c
 +++ b/arch/mips/bcm47xx/setup.c
-@@ -34,6 +34,7 @@
+@@ -36,6 +36,7 @@
  #include <linux/ssb/ssb.h>
  #include <linux/ssb/ssb_embedded.h>
  #include <linux/bcma/bcma_soc.h>
@@ -8,7 +8,7 @@
  #include <asm/bootinfo.h>
  #include <asm/prom.h>
  #include <asm/reboot.h>
-@@ -264,6 +265,33 @@ static struct fixed_phy_status bcm47xx_f
+@@ -266,6 +267,33 @@ static struct fixed_phy_status bcm47xx_f
        .duplex = DUPLEX_FULL,
  };
  
  static int __init bcm47xx_register_bus_complete(void)
  {
        switch (bcm47xx_bus_type) {
-@@ -279,6 +307,8 @@ static int __init bcm47xx_register_bus_c
- #endif
-       }
+@@ -284,6 +312,7 @@ static int __init bcm47xx_register_bus_c
+       bcm47xx_buttons_register();
+       bcm47xx_leds_register();
        fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
 +      bcm47xx_register_gpio_watchdog();
-+
        return 0;
  }
- device_initcall(bcm47xx_register_bus_complete);
 --- a/arch/mips/configs/bcm47xx_defconfig
 +++ b/arch/mips/configs/bcm47xx_defconfig
 @@ -379,6 +379,7 @@ CONFIG_THERMAL=y
index 84be5121d5cbf3dc84c970fbb83d76629b4943ec..650f02f2a13ae0597a67b9d5689ffec25e68370d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/bcm47xx/setup.c
 +++ b/arch/mips/bcm47xx/setup.c
-@@ -125,6 +125,10 @@ static int bcm47xx_get_invariants(struct
+@@ -127,6 +127,10 @@ static int bcm47xx_get_invariants(struct
        if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
                iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);