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> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@38011 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
565a027db3
commit
81cf14367f
|
@ -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)))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue