OpenWrt – Rev 4

Subversion Repositories:
Rev:
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -37,6 +37,7 @@
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
 #include <linux/bcma/bcma_soc.h>
+#include <linux/old_gpio_wdt.h>
 #include <asm/bootinfo.h>
 #include <asm/idle.h>
 #include <asm/prom.h>
@@ -225,6 +226,33 @@ static struct fixed_phy_status bcm47xx_f
        .duplex = DUPLEX_FULL,
 };
 
+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) {
@@ -244,6 +272,7 @@ static int __init bcm47xx_register_bus_c
        bcm47xx_workarounds();
 
        fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status, -1);
+       bcm47xx_register_gpio_watchdog();
        return 0;
 }
 device_initcall(bcm47xx_register_bus_complete);
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -66,6 +66,7 @@ CONFIG_HW_RANDOM=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_WATCHDOG=y
 CONFIG_BCM47XX_WDT=y
+CONFIG_GPIO_WDT=y
 CONFIG_SSB_DEBUG=y
 CONFIG_SSB_DRIVER_GIGE=y
 CONFIG_BCMA_DRIVER_GMAC_CMN=y
--- 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;