brcm47xx: Add support for Huawei E970
This patch adds support for Huawei E970 wireless gateway devices. It has been tested on an E970 labelled as T-Mobile web'n'walk Box IV. E960/B970 should work too, from what I know it's basically the same hardware. The device has a Broadcom BCM5354 SoC and a built-in 3G USB modem. It uses a hardware watchdog which needs GPIO-7 to be toggled at least every 1-2 seconds. This patch uses gpio_wdt module (see my previous patch today) to take care of this. Tested and works: 3G wan, wlan+LED, VLAN config, failsafe using reset button, image to be used for upgrade from OEM firmware's web interface Link to the wiki page I've created: <http://wiki.openwrt.org/toh/huawei/e970> Issue: * lzma-loader crashes, so gzipped kernel is used. Presumably due to watchdog reset during kernel decompress. Signed-off-by: Mathias Adam <m.adam--openwrt@adamis.de> SVN-Revision: 38011
This commit is contained in:
parent
0294358e11
commit
c78e4fb220
4 changed files with 121 additions and 1 deletions
|
@ -59,6 +59,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||||
CONFIG_GPIOLIB=y
|
CONFIG_GPIOLIB=y
|
||||||
CONFIG_GPIO_DEVRES=y
|
CONFIG_GPIO_DEVRES=y
|
||||||
CONFIG_GPIO_SYSFS=y
|
CONFIG_GPIO_SYSFS=y
|
||||||
|
CONFIG_GPIO_WDT=y
|
||||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||||
CONFIG_HAS_DMA=y
|
CONFIG_HAS_DMA=y
|
||||||
CONFIG_HAS_IOMEM=y
|
CONFIG_HAS_IOMEM=y
|
||||||
|
|
|
@ -13,6 +13,7 @@ endef
|
||||||
|
|
||||||
define Image/Prepare
|
define Image/Prepare
|
||||||
cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
|
cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
|
||||||
|
gzip -nc9 $(KDIR)/vmlinux > $(KDIR)/vmlinux.gz
|
||||||
ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
|
ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
|
||||||
cat $(KDIR)/vmlinux-initramfs | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux-initramfs.lzma
|
cat $(KDIR)/vmlinux-initramfs | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux-initramfs.lzma
|
||||||
endif
|
endif
|
||||||
|
@ -59,6 +60,12 @@ define Image/Build/Edi
|
||||||
$(STAGING_DIR_HOST)/bin/trx2edips $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(3).bin
|
$(STAGING_DIR_HOST)/bin/trx2edips $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(3).bin
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Image/Build/Huawei
|
||||||
|
dd if=/dev/zero of=$(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin bs=92 count=1
|
||||||
|
echo -ne 'HDR0\x08\x00\x00\x00' >> $(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin
|
||||||
|
cat $(BIN_DIR)/$(IMG_PREFIX)-$(1)-gz.trx >> $(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin
|
||||||
|
endef
|
||||||
|
|
||||||
define trxalign/jffs2-128k
|
define trxalign/jffs2-128k
|
||||||
-a 0x20000 -f $(KDIR)/root.$(1)
|
-a 0x20000 -f $(KDIR)/root.$(1)
|
||||||
endef
|
endef
|
||||||
|
@ -134,9 +141,13 @@ define Image/Build
|
||||||
$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx \
|
$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx \
|
||||||
-f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \
|
-f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \
|
||||||
$(call trxalign/$(1),$(1))
|
$(call trxalign/$(1),$(1))
|
||||||
|
$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1)-gz.trx \
|
||||||
|
-f $(KDIR)/vmlinux.gz \
|
||||||
|
$(call trxalign/$(1),$(1))
|
||||||
$(call Image/Build/$(1),$(1))
|
$(call Image/Build/$(1),$(1))
|
||||||
$(call Image/Build/Motorola,$(1),wr850g,1,$(1))
|
$(call Image/Build/Motorola,$(1),wr850g,1,$(1))
|
||||||
$(call Image/Build/USR,$(1),usr5461,$(1))
|
$(call Image/Build/USR,$(1),usr5461,$(1))
|
||||||
|
$(call Image/Build/Huawei,$(1),e970,$(1))
|
||||||
$(call Image/Build/Chk,$(1),wgr614_v8,U12H072T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
$(call Image/Build/Chk,$(1),wgr614_v8,U12H072T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
||||||
# $(call Image/Build/Chk,$(1),wgr614_v9,U12H094T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
# $(call Image/Build/Chk,$(1),wgr614_v9,U12H094T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
||||||
$(call Image/Build/Chk,$(1),wndr3300_v1,U12H093T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
$(call Image/Build/Chk,$(1),wndr3300_v1,U12H093T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))
|
||||||
|
|
108
target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch
Normal file
108
target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
|
@@ -33,11 +33,13 @@
|
||||||
|
#include <linux/bcma/bcma_soc.h>
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
+#include <linux/gpio_wdt.h>
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/reboot.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <bcm47xx.h>
|
||||||
|
#include <bcm47xx_nvram.h>
|
||||||
|
+#include <bcm47xx_board.h>
|
||||||
|
|
||||||
|
union bcm47xx_bus bcm47xx_bus;
|
||||||
|
EXPORT_SYMBOL(bcm47xx_bus);
|
||||||
|
@@ -254,6 +256,33 @@ void __init plat_mem_setup(void)
|
||||||
|
pm_power_off = bcm47xx_machine_halt;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static struct gpio_wdt_platform_data gpio_wdt_data;
|
||||||
|
+
|
||||||
|
+static struct platform_device gpio_wdt_device = {
|
||||||
|
+ .name = "gpio-wdt",
|
||||||
|
+ .id = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &gpio_wdt_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init bcm47xx_register_gpio_watchdog(void)
|
||||||
|
+{
|
||||||
|
+ enum bcm47xx_board board = bcm47xx_board_get();
|
||||||
|
+
|
||||||
|
+ switch (board) {
|
||||||
|
+ case BCM47XX_BOARD_HUAWEI_E970:
|
||||||
|
+ pr_info("bcm47xx: detected Huawei E970 or similar, starting early gpio_wdt timer\n");
|
||||||
|
+ gpio_wdt_data.gpio = 7;
|
||||||
|
+ gpio_wdt_data.interval = HZ;
|
||||||
|
+ gpio_wdt_data.first_interval = HZ / 5;
|
||||||
|
+ return platform_device_register(&gpio_wdt_device);
|
||||||
|
+ default:
|
||||||
|
+ /* Nothing to do */
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int __init bcm47xx_register_bus_complete(void)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_bus_type) {
|
||||||
|
@@ -268,6 +297,8 @@ static int __init bcm47xx_register_bus_c
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
+ 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
|
||||||
|
CONFIG_WATCHDOG=y
|
||||||
|
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||||
|
CONFIG_BCM47XX_WDT=y
|
||||||
|
+CONFIG_GPIO_WDT=y
|
||||||
|
CONFIG_SSB_DRIVER_GIGE=y
|
||||||
|
CONFIG_DISPLAY_SUPPORT=m
|
||||||
|
CONFIG_SOUND=m
|
||||||
|
--- a/drivers/ssb/embedded.c
|
||||||
|
+++ b/drivers/ssb/embedded.c
|
||||||
|
@@ -34,11 +34,36 @@ int ssb_watchdog_timer_set(struct ssb_bu
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ssb_watchdog_timer_set);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCM47XX
|
||||||
|
+#include <bcm47xx_board.h>
|
||||||
|
+
|
||||||
|
+static bool ssb_watchdog_supported(void)
|
||||||
|
+{
|
||||||
|
+ enum bcm47xx_board board = bcm47xx_board_get();
|
||||||
|
+
|
||||||
|
+ /* The Huawei E970 has a hardware watchdog using a GPIO */
|
||||||
|
+ switch (board) {
|
||||||
|
+ case BCM47XX_BOARD_HUAWEI_E970:
|
||||||
|
+ return false;
|
||||||
|
+ default:
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static bool ssb_watchdog_supported(void)
|
||||||
|
+{
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
int ssb_watchdog_register(struct ssb_bus *bus)
|
||||||
|
{
|
||||||
|
struct bcm47xx_wdt wdt = {};
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
+ if (!ssb_watchdog_supported())
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
if (ssb_chipco_available(&bus->chipco)) {
|
||||||
|
wdt.driver_data = &bus->chipco;
|
||||||
|
wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/arch/mips/bcm47xx/setup.c
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
+++ b/arch/mips/bcm47xx/setup.c
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
@@ -120,6 +120,10 @@ static int bcm47xx_get_invariants(struct
|
@@ -122,6 +122,10 @@ static int bcm47xx_get_invariants(struct
|
||||||
if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue