diff options
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 2 | ||||
-rw-r--r-- | drivers/watchdog/dw_wdt.c | 3 | ||||
-rw-r--r-- | drivers/watchdog/imx2_wdt.c | 7 | ||||
-rw-r--r-- | drivers/watchdog/lantiq_wdt.c | 5 | ||||
-rw-r--r-- | drivers/watchdog/octeon-wdt-main.c | 62 | ||||
-rw-r--r-- | drivers/watchdog/shwdt.c | 5 | ||||
-rw-r--r-- | drivers/watchdog/sunxi_wdt.c | 29 |
7 files changed, 72 insertions, 41 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 76dd54122f76..f57312fced80 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1293,7 +1293,7 @@ config DIAG288_WATCHDOG both. To compile this driver as a module, choose M here. The module - will be called vmwatchdog. + will be called diag288_wdt. # SUPERH (sh + sh64) Architecture diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index ee4f86ba83ec..9f210299de24 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -296,9 +296,6 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) int ret; struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -EINVAL; - dw_wdt.regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(dw_wdt.regs)) return PTR_ERR(dw_wdt.regs); diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 9d4874f09948..68c3d379ffa8 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -28,6 +28,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/timer.h> @@ -190,10 +191,12 @@ static struct regmap_config imx2_wdt_regmap_config = { static int __init imx2_wdt_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct imx2_wdt_device *wdev; struct watchdog_device *wdog; struct resource *res; void __iomem *base; + bool big_endian; int ret; u32 val; @@ -201,6 +204,10 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) if (!wdev) return -ENOMEM; + big_endian = of_property_read_bool(np, "big-endian"); + if (big_endian) + imx2_wdt_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index 3b3148c764a3..021e84eb88eb 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -192,11 +192,6 @@ ltq_wdt_probe(struct platform_device *pdev) struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct clk *clk; - if (!res) { - dev_err(&pdev->dev, "cannot obtain I/O memory region"); - return -ENOENT; - } - ltq_wdt_membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ltq_wdt_membase)) return PTR_ERR(ltq_wdt_membase); diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 4baf2d788920..8453531545df 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -145,35 +145,39 @@ static void __init octeon_wdt_build_stage1(void) uasm_i_mfc0(&p, K0, C0_STATUS); #ifdef CONFIG_HOTPLUG_CPU - uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader); + if (octeon_bootloader_entry_addr) + uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), + label_enter_bootloader); #endif /* Force 64-bit addressing enabled */ uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); uasm_i_mtc0(&p, K0, C0_STATUS); #ifdef CONFIG_HOTPLUG_CPU - uasm_i_mfc0(&p, K0, C0_EBASE); - /* Coreid number in K0 */ - uasm_i_andi(&p, K0, K0, 0xf); - /* 8 * coreid in bits 16-31 */ - uasm_i_dsll_safe(&p, K0, K0, 3 + 16); - uasm_i_ori(&p, K0, K0, 0x8001); - uasm_i_dsll_safe(&p, K0, K0, 16); - uasm_i_ori(&p, K0, K0, 0x0700); - uasm_i_drotr_safe(&p, K0, K0, 32); - /* - * Should result in: 0x8001,0700,0000,8*coreid which is - * CVMX_CIU_WDOGX(coreid) - 0x0500 - * - * Now ld K0, CVMX_CIU_WDOGX(coreid) - */ - uasm_i_ld(&p, K0, 0x500, K0); - /* - * If bit one set handle the NMI as a watchdog event. - * otherwise transfer control to bootloader. - */ - uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); - uasm_i_nop(&p); + if (octeon_bootloader_entry_addr) { + uasm_i_mfc0(&p, K0, C0_EBASE); + /* Coreid number in K0 */ + uasm_i_andi(&p, K0, K0, 0xf); + /* 8 * coreid in bits 16-31 */ + uasm_i_dsll_safe(&p, K0, K0, 3 + 16); + uasm_i_ori(&p, K0, K0, 0x8001); + uasm_i_dsll_safe(&p, K0, K0, 16); + uasm_i_ori(&p, K0, K0, 0x0700); + uasm_i_drotr_safe(&p, K0, K0, 32); + /* + * Should result in: 0x8001,0700,0000,8*coreid which is + * CVMX_CIU_WDOGX(coreid) - 0x0500 + * + * Now ld K0, CVMX_CIU_WDOGX(coreid) + */ + uasm_i_ld(&p, K0, 0x500, K0); + /* + * If bit one set handle the NMI as a watchdog event. + * otherwise transfer control to bootloader. + */ + uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); + uasm_i_nop(&p); + } #endif /* Clear Dcache so cvmseg works right. */ @@ -194,11 +198,13 @@ static void __init octeon_wdt_build_stage1(void) uasm_i_dmfc0(&p, K0, C0_DESAVE); #ifdef CONFIG_HOTPLUG_CPU - uasm_build_label(&l, p, label_enter_bootloader); - /* Jump to the bootloader and restore K0 */ - UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); - uasm_i_jr(&p, K0); - uasm_i_dmfc0(&p, K0, C0_DESAVE); + if (octeon_bootloader_entry_addr) { + uasm_build_label(&l, p, label_enter_bootloader); + /* Jump to the bootloader and restore K0 */ + UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); + uasm_i_jr(&p, K0); + uasm_i_dmfc0(&p, K0, C0_DESAVE); + } #endif uasm_resolve_relocs(relocs, labels); diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 061756e36cf8..fa89bb30d004 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -230,10 +230,6 @@ static int sh_wdt_probe(struct platform_device *pdev) if (pdev->id != -1) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!res)) - return -EINVAL; - wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL); if (unlikely(!wdt)) return -ENOMEM; @@ -249,6 +245,7 @@ static int sh_wdt_probe(struct platform_device *pdev) wdt->clk = NULL; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_ioremap_resource(wdt->dev, res); if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 693b9d2c6e39..60deb9d304c0 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -14,6 +14,7 @@ */ #include <linux/clk.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> @@ -22,9 +23,12 @@ #include <linux/moduleparam.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/types.h> #include <linux/watchdog.h> +#include <asm/system_misc.h> + #define WDT_MAX_TIMEOUT 16 #define WDT_MIN_TIMEOUT 1 #define WDT_MODE_TIMEOUT(n) ((n) << 3) @@ -70,6 +74,26 @@ static const int wdt_timeout_map[] = { [16] = 0xB, /* 16s */ }; +static void __iomem *reboot_wdt_base; + +static void sun4i_wdt_restart(enum reboot_mode mode, const char *cmd) +{ + /* Enable timer and set reset bit in the watchdog */ + writel(WDT_MODE_EN | WDT_MODE_RST_EN, reboot_wdt_base + WDT_MODE); + + /* + * Restart the watchdog. The default (and lowest) interval + * value for the watchdog is 0.5s. + */ + writel(WDT_CTRL_RELOAD, reboot_wdt_base + WDT_CTRL); + + while (1) { + mdelay(5); + writel(WDT_MODE_EN | WDT_MODE_RST_EN, + reboot_wdt_base + WDT_MODE); + } +} + static int sunxi_wdt_ping(struct watchdog_device *wdt_dev) { struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev); @@ -181,6 +205,9 @@ static int sunxi_wdt_probe(struct platform_device *pdev) if (unlikely(err)) return err; + reboot_wdt_base = sunxi_wdt->wdt_base; + arm_pm_restart = sun4i_wdt_restart; + dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)", sunxi_wdt->wdt_dev.timeout, nowayout); @@ -191,6 +218,8 @@ static int sunxi_wdt_remove(struct platform_device *pdev) { struct sunxi_wdt_dev *sunxi_wdt = platform_get_drvdata(pdev); + arm_pm_restart = NULL; + watchdog_unregister_device(&sunxi_wdt->wdt_dev); watchdog_set_drvdata(&sunxi_wdt->wdt_dev, NULL); |