]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/watchdog/aspeed_wdt.c
Merge tag 'iio-fixes-for-4.17a' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / watchdog / aspeed_wdt.c
index ca5b91e2eb9257c1be5da003fec6282dff64ca5a..1abe4d021fd27171bae9fb7a289c72916f041486 100644 (file)
@@ -46,6 +46,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define WDT_RELOAD_VALUE       0x04
 #define WDT_RESTART            0x08
 #define WDT_CTRL               0x0C
+#define   WDT_CTRL_BOOT_SECONDARY      BIT(7)
 #define   WDT_CTRL_RESET_MODE_SOC      (0x00 << 5)
 #define   WDT_CTRL_RESET_MODE_FULL_CHIP        (0x01 << 5)
 #define   WDT_CTRL_RESET_MODE_ARM_CPU  (0x10 << 5)
@@ -54,6 +55,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define   WDT_CTRL_WDT_INTR            BIT(2)
 #define   WDT_CTRL_RESET_SYSTEM                BIT(1)
 #define   WDT_CTRL_ENABLE              BIT(0)
+#define WDT_TIMEOUT_STATUS     0x10
+#define   WDT_TIMEOUT_STATUS_BOOT_SECONDARY    BIT(1)
 
 /*
  * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
@@ -158,6 +161,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
 {
        struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
 
+       wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
        aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
 
        mdelay(1000);
@@ -190,6 +194,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
        struct device_node *np;
        const char *reset_type;
        u32 duration;
+       u32 status;
        int ret;
 
        wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -232,16 +237,21 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
                wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
        } else {
                if (!strcmp(reset_type, "cpu"))
-                       wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (!strcmp(reset_type, "soc"))
-                       wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (!strcmp(reset_type, "system"))
-                       wdt->ctrl |= WDT_CTRL_RESET_SYSTEM;
+                       wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP |
+                                    WDT_CTRL_RESET_SYSTEM;
                else if (strcmp(reset_type, "none"))
                        return -EINVAL;
        }
        if (of_property_read_bool(np, "aspeed,external-signal"))
                wdt->ctrl |= WDT_CTRL_WDT_EXT;
+       if (of_property_read_bool(np, "aspeed,alt-boot"))
+               wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY;
 
        if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
                /*
@@ -300,6 +310,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
                writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
        }
 
+       status = readl(wdt->base + WDT_TIMEOUT_STATUS);
+       if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
+               wdt->wdd.bootstatus = WDIOF_CARDRESET;
+
        ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
        if (ret) {
                dev_err(&pdev->dev, "failed to register\n");