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:
		@@ -59,6 +59,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
 | 
			
		||||
CONFIG_GPIOLIB=y
 | 
			
		||||
CONFIG_GPIO_DEVRES=y
 | 
			
		||||
CONFIG_GPIO_SYSFS=y
 | 
			
		||||
CONFIG_GPIO_WDT=y
 | 
			
		||||
CONFIG_HARDWARE_WATCHPOINTS=y
 | 
			
		||||
CONFIG_HAS_DMA=y
 | 
			
		||||
CONFIG_HAS_IOMEM=y
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ endef
 | 
			
		||||
 | 
			
		||||
define Image/Prepare
 | 
			
		||||
	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),)
 | 
			
		||||
	cat $(KDIR)/vmlinux-initramfs | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux-initramfs.lzma
 | 
			
		||||
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
 | 
			
		||||
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
 | 
			
		||||
-a 0x20000 -f $(KDIR)/root.$(1)
 | 
			
		||||
endef
 | 
			
		||||
@@ -134,9 +141,13 @@ define Image/Build
 | 
			
		||||
	$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx \
 | 
			
		||||
		-f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \
 | 
			
		||||
		$(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/Motorola,$(1),wr850g,1,$(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_v9,U12H094T00_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
 | 
			
		||||
+++ 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)
 | 
			
		||||
 		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user