aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 18:12:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 18:12:59 -0400
commit51a73ba5f409ef6f419c8ec3a0d1257633500aaa (patch)
tree7bd3d8c4b9b6de178342bd48636b85da79ddbd18
parente91eb6204fb826116453e43d4f5cf0f666bf46fe (diff)
parent6551881c86c791237a3bebf11eb3bd70b60ea782 (diff)
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: - new driver for NXP LPC18xx Watchdog Timer - new driver for SAMA5D4 watchdog timer - add support for MCP79 to nv_tco driver - clean-up and improvement of the mpc8xxx watchdog driver - improvements to gpio-wdt - at91sam9_wdt clock improvements ... and other small fixes and improvements * git://www.linux-watchdog.org/linux-watchdog: (25 commits) Watchdog: Fix parent of watchdog_devices watchdog: at91rm9200: Correct check for syscon_node_to_regmap() errors watchdog: at91sam9: get and use slow clock Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog driver watchdog: add a driver to support SAMA5D4 watchdog timer watchdog: mpc8xxx: allow to compile for MPC512x watchdog: mpc8xxx: use better error code when watchdog cannot be enabled watchdog: mpc8xxx: use dynamic memory for device specific data watchdog: mpc8xxx: use devm_ioremap_resource to map memory watchdog: mpc8xxx: make use of of_device_get_match_data watchdog: mpc8xxx: simplify registration watchdog: mpc8xxx: remove dead code watchdog: lpc18xx_wdt_get_timeleft() can be static DT: watchdog: Add NXP LPC18xx Watchdog Timer binding documentation watchdog: NXP LPC18xx Watchdog Timer Driver watchdog: gpio-wdt: ping already at startup for always running devices watchdog: gpio-wdt: be more strict about hw_algo matching Documentation: watchdog: at91sam9_wdt: add clocks property watchdog: booke_wdt: Use infrastructure to check timeout limits watchdog: (nv_tco) add support for MCP79 ...
-rw-r--r--Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt35
-rw-r--r--Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt19
-rw-r--r--Documentation/watchdog/src/watchdog-test.c22
-rw-r--r--drivers/misc/mei/wd.c1
-rw-r--r--drivers/watchdog/Kconfig22
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/at91sam9_wdt.c22
-rw-r--r--drivers/watchdog/at91sam9_wdt.h2
-rw-r--r--drivers/watchdog/bcm2835_wdt.c1
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c1
-rw-r--r--drivers/watchdog/bcm_kona_wdt.c1
-rw-r--r--drivers/watchdog/booke_wdt.c4
-rw-r--r--drivers/watchdog/coh901327_wdt.c1
-rw-r--r--drivers/watchdog/da9052_wdt.c1
-rw-r--r--drivers/watchdog/da9055_wdt.c1
-rw-r--r--drivers/watchdog/da9062_wdt.c1
-rw-r--r--drivers/watchdog/da9063_wdt.c1
-rw-r--r--drivers/watchdog/davinci_wdt.c1
-rw-r--r--drivers/watchdog/digicolor_wdt.c1
-rw-r--r--drivers/watchdog/ep93xx_wdt.c1
-rw-r--r--drivers/watchdog/gpio_wdt.c65
-rw-r--r--drivers/watchdog/ie6xx_wdt.c1
-rw-r--r--drivers/watchdog/imgpdc_wdt.c1
-rw-r--r--drivers/watchdog/intel-mid_wdt.c1
-rw-r--r--drivers/watchdog/jz4740_wdt.c1
-rw-r--r--drivers/watchdog/lpc18xx_wdt.c340
-rw-r--r--drivers/watchdog/mena21_wdt.c1
-rw-r--r--drivers/watchdog/menf21bmc_wdt.c1
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c156
-rw-r--r--drivers/watchdog/mtk_wdt.c39
-rw-r--r--drivers/watchdog/nv_tco.c2
-rw-r--r--drivers/watchdog/omap_wdt.c1
-rw-r--r--drivers/watchdog/orion_wdt.c1
-rw-r--r--drivers/watchdog/pnx4008_wdt.c1
-rw-r--r--drivers/watchdog/qcom-wdt.c1
-rw-r--r--drivers/watchdog/retu_wdt.c1
-rw-r--r--drivers/watchdog/rt2880_wdt.c1
-rw-r--r--drivers/watchdog/s3c2410_wdt.c1
-rw-r--r--drivers/watchdog/sama5d4_wdt.c280
-rw-r--r--drivers/watchdog/shwdt.c1
-rw-r--r--drivers/watchdog/sirfsoc_wdt.c1
-rw-r--r--drivers/watchdog/sp805_wdt.c1
-rw-r--r--drivers/watchdog/st_lpc_wdt.c1
-rw-r--r--drivers/watchdog/stmp3xxx_rtc_wdt.c1
-rw-r--r--drivers/watchdog/sunxi_wdt.c2
-rw-r--r--drivers/watchdog/tegra_wdt.c1
-rw-r--r--drivers/watchdog/twl4030_wdt.c1
-rw-r--r--drivers/watchdog/txx9wdt.c1
-rw-r--r--drivers/watchdog/ux500_wdt.c1
-rw-r--r--drivers/watchdog/via_wdt.c1
-rw-r--r--drivers/watchdog/wm831x_wdt.c1
-rw-r--r--drivers/watchdog/wm8350_wdt.c1
53 files changed, 916 insertions, 135 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 000000000000..f7cc7c060910
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
1* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
2
3Required properties:
4- compatible: "atmel,sama5d4-wdt"
5- reg: base physical address and length of memory mapped region.
6
7Optional properties:
8- timeout-sec: watchdog timeout value (in seconds).
9- interrupts: interrupt number to the CPU.
10- atmel,watchdog-type: should be "hardware" or "software".
11 "hardware": enable watchdog fault reset. A watchdog fault triggers
12 watchdog reset.
13 "software": enable watchdog fault interrupt. A watchdog fault asserts
14 watchdog interrupt.
15- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
16 in idle state.
17 CAUTION: This property should be used with care, it actually makes the
18 watchdog not counting when the CPU is in idle state, therefore the
19 watchdog reset time depends on mean CPU usage and will not reset at all
20 if the CPU stop working while it is in idle state, which is probably
21 not what you want.
22- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
23 in debug state.
24
25Example:
26 watchdog@fc068640 {
27 compatible = "atmel,sama5d4-wdt";
28 reg = <0xfc068640 0x10>;
29 interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
30 timeout-sec = <10>;
31 atmel,watchdog-type = "hardware";
32 atmel,dbg-halt;
33 atmel,idle-halt;
34 status = "okay";
35 };
diff --git a/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt b/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt
new file mode 100644
index 000000000000..09f6b24969e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt
@@ -0,0 +1,19 @@
1* NXP LPC18xx Watchdog Timer (WDT)
2
3Required properties:
4- compatible: Should be "nxp,lpc1850-wwdt"
5- reg: Should contain WDT registers location and length
6- clocks: Must contain an entry for each entry in clock-names.
7- clock-names: Should contain "wdtclk" and "reg"; the watchdog counter
8 clock and register interface clock respectively.
9- interrupts: Should contain WDT interrupt
10
11Examples:
12
13watchdog@40080000 {
14 compatible = "nxp,lpc1850-wwdt";
15 reg = <0x40080000 0x24>;
16 clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_WWDT>;
17 clock-names = "wdtclk", "reg";
18 interrupts = <49>;
19};
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
index 3da822967ee0..fcdde8fc98be 100644
--- a/Documentation/watchdog/src/watchdog-test.c
+++ b/Documentation/watchdog/src/watchdog-test.c
@@ -41,6 +41,7 @@ static void term(int sig)
41int main(int argc, char *argv[]) 41int main(int argc, char *argv[])
42{ 42{
43 int flags; 43 int flags;
44 unsigned int ping_rate = 1;
44 45
45 fd = open("/dev/watchdog", O_WRONLY); 46 fd = open("/dev/watchdog", O_WRONLY);
46 47
@@ -63,22 +64,33 @@ int main(int argc, char *argv[])
63 fprintf(stderr, "Watchdog card enabled.\n"); 64 fprintf(stderr, "Watchdog card enabled.\n");
64 fflush(stderr); 65 fflush(stderr);
65 goto end; 66 goto end;
67 } else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
68 flags = atoi(argv[2]);
69 ioctl(fd, WDIOC_SETTIMEOUT, &flags);
70 fprintf(stderr, "Watchdog timeout set to %u seconds.\n", flags);
71 fflush(stderr);
72 goto end;
73 } else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
74 ping_rate = strtoul(argv[2], NULL, 0);
75 fprintf(stderr, "Watchdog ping rate set to %u seconds.\n", ping_rate);
76 fflush(stderr);
66 } else { 77 } else {
67 fprintf(stderr, "-d to disable, -e to enable.\n"); 78 fprintf(stderr, "-d to disable, -e to enable, -t <n> to set " \
79 "the timeout,\n-p <n> to set the ping rate, and \n");
68 fprintf(stderr, "run by itself to tick the card.\n"); 80 fprintf(stderr, "run by itself to tick the card.\n");
69 fflush(stderr); 81 fflush(stderr);
70 goto end; 82 goto end;
71 } 83 }
72 } else {
73 fprintf(stderr, "Watchdog Ticking Away!\n");
74 fflush(stderr);
75 } 84 }
76 85
86 fprintf(stderr, "Watchdog Ticking Away!\n");
87 fflush(stderr);
88
77 signal(SIGINT, term); 89 signal(SIGINT, term);
78 90
79 while(1) { 91 while(1) {
80 keep_alive(); 92 keep_alive();
81 sleep(1); 93 sleep(ping_rate);
82 } 94 }
83end: 95end:
84 close(fd); 96 close(fd);
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 2bc0f5089f82..b346638833b0 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
364 364
365 int ret; 365 int ret;
366 366
367 amt_wd_dev.parent = dev->dev;
367 /* unlock to perserve correct locking order */ 368 /* unlock to perserve correct locking order */
368 mutex_unlock(&dev->device_lock); 369 mutex_unlock(&dev->device_lock);
369 ret = watchdog_register_device(&amt_wd_dev); 370 ret = watchdog_register_device(&amt_wd_dev);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 55c4b5b0a317..c68edc16aa54 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -188,6 +188,15 @@ config AT91SAM9X_WATCHDOG
188 Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will 188 Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
189 reboot your system when the timeout is reached. 189 reboot your system when the timeout is reached.
190 190
191config SAMA5D4_WATCHDOG
192 tristate "Atmel SAMA5D4 Watchdog Timer"
193 depends on ARCH_AT91
194 select WATCHDOG_CORE
195 help
196 Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
197 Its Watchdog Timer Mode Register can be written more than once.
198 This will reboot your system when the timeout is reached.
199
191config CADENCE_WATCHDOG 200config CADENCE_WATCHDOG
192 tristate "Cadence Watchdog Timer" 201 tristate "Cadence Watchdog Timer"
193 depends on HAS_IOMEM 202 depends on HAS_IOMEM
@@ -558,6 +567,17 @@ config DIGICOLOR_WATCHDOG
558 To compile this driver as a module, choose M here: the 567 To compile this driver as a module, choose M here: the
559 module will be called digicolor_wdt. 568 module will be called digicolor_wdt.
560 569
570config LPC18XX_WATCHDOG
571 tristate "LPC18xx/43xx Watchdog"
572 depends on ARCH_LPC18XX || COMPILE_TEST
573 select WATCHDOG_CORE
574 help
575 Say Y here if to include support for the watchdog timer
576 in NXP LPC SoCs family, which includes LPC18xx/LPC43xx
577 processors.
578 To compile this driver as a module, choose M here: the
579 module will be called lpc18xx_wdt.
580
561# AVR32 Architecture 581# AVR32 Architecture
562 582
563config AT32AP700X_WDT 583config AT32AP700X_WDT
@@ -1334,7 +1354,7 @@ config MPC5200_WDT
1334 1354
1335config 8xxx_WDT 1355config 8xxx_WDT
1336 tristate "MPC8xxx Platform Watchdog Timer" 1356 tristate "MPC8xxx Platform Watchdog Timer"
1337 depends on PPC_8xx || PPC_83xx || PPC_86xx 1357 depends on PPC_8xx || PPC_83xx || PPC_86xx || PPC_MPC512x
1338 select WATCHDOG_CORE 1358 select WATCHDOG_CORE
1339 help 1359 help
1340 This driver is for a SoC level watchdog that exists on some 1360 This driver is for a SoC level watchdog that exists on some
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 59ea9a1b8e76..0c616e3f67bb 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
41obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o 41obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
42obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o 42obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
43obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o 43obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
44obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
44obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o 45obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
45obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o 46obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
46obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o 47obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
@@ -66,6 +67,7 @@ obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
66obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o 67obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
67obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o 68obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
68obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o 69obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
70obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
69 71
70# AVR32 Architecture 72# AVR32 Architecture
71obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 73obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 9ba1153465ae..e12a797cb820 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -244,7 +244,7 @@ static int at91wdt_probe(struct platform_device *pdev)
244 } 244 }
245 245
246 regmap_st = syscon_node_to_regmap(parent->of_node); 246 regmap_st = syscon_node_to_regmap(parent->of_node);
247 if (!regmap_st) 247 if (IS_ERR(regmap_st))
248 return -ENODEV; 248 return -ENODEV;
249 249
250 res = misc_register(&at91wdt_miscdev); 250 res = misc_register(&at91wdt_miscdev);
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index e4698f7c5f93..7e6acaf3ece4 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -17,6 +17,7 @@
17 17
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 19
20#include <linux/clk.h>
20#include <linux/errno.h> 21#include <linux/errno.h>
21#include <linux/init.h> 22#include <linux/init.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
@@ -90,6 +91,7 @@ struct at91wdt {
90 unsigned long heartbeat; /* WDT heartbeat in jiffies */ 91 unsigned long heartbeat; /* WDT heartbeat in jiffies */
91 bool nowayout; 92 bool nowayout;
92 unsigned int irq; 93 unsigned int irq;
94 struct clk *sclk;
93}; 95};
94 96
95/* ......................................................................... */ 97/* ......................................................................... */
@@ -352,15 +354,25 @@ static int __init at91wdt_probe(struct platform_device *pdev)
352 if (IS_ERR(wdt->base)) 354 if (IS_ERR(wdt->base))
353 return PTR_ERR(wdt->base); 355 return PTR_ERR(wdt->base);
354 356
357 wdt->sclk = devm_clk_get(&pdev->dev, NULL);
358 if (IS_ERR(wdt->sclk))
359 return PTR_ERR(wdt->sclk);
360
361 err = clk_prepare_enable(wdt->sclk);
362 if (err) {
363 dev_err(&pdev->dev, "Could not enable slow clock\n");
364 return err;
365 }
366
355 if (pdev->dev.of_node) { 367 if (pdev->dev.of_node) {
356 err = of_at91wdt_init(pdev->dev.of_node, wdt); 368 err = of_at91wdt_init(pdev->dev.of_node, wdt);
357 if (err) 369 if (err)
358 return err; 370 goto err_clk;
359 } 371 }
360 372
361 err = at91_wdt_init(pdev, wdt); 373 err = at91_wdt_init(pdev, wdt);
362 if (err) 374 if (err)
363 return err; 375 goto err_clk;
364 376
365 platform_set_drvdata(pdev, wdt); 377 platform_set_drvdata(pdev, wdt);
366 378
@@ -368,6 +380,11 @@ static int __init at91wdt_probe(struct platform_device *pdev)
368 wdt->wdd.timeout, wdt->nowayout); 380 wdt->wdd.timeout, wdt->nowayout);
369 381
370 return 0; 382 return 0;
383
384err_clk:
385 clk_disable_unprepare(wdt->sclk);
386
387 return err;
371} 388}
372 389
373static int __exit at91wdt_remove(struct platform_device *pdev) 390static int __exit at91wdt_remove(struct platform_device *pdev)
@@ -377,6 +394,7 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
377 394
378 pr_warn("I quit now, hardware will probably reboot!\n"); 395 pr_warn("I quit now, hardware will probably reboot!\n");
379 del_timer(&wdt->timer); 396 del_timer(&wdt->timer);
397 clk_disable_unprepare(wdt->sclk);
380 398
381 return 0; 399 return 0;
382} 400}
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6c41b..b79a83b467ce 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,13 @@
22 22
23#define AT91_WDT_MR 0x04 /* Watchdog Mode Register */ 23#define AT91_WDT_MR 0x04 /* Watchdog Mode Register */
24#define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ 24#define AT91_WDT_WDV (0xfff << 0) /* Counter Value */
25#define AT91_WDT_SET_WDV(x) ((x) & AT91_WDT_WDV)
25#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ 26#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */
26#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ 27#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */
27#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */ 28#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */
28#define AT91_WDT_WDDIS (1 << 15) /* Watchdog Disable */ 29#define AT91_WDT_WDDIS (1 << 15) /* Watchdog Disable */
29#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */ 30#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */
31#define AT91_WDT_SET_WDD(x) (((x) << 16) & AT91_WDT_WDD)
30#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ 32#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */
31#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ 33#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */
32 34
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 7116968dee12..66c3e656a616 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -182,6 +182,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
182 watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); 182 watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
183 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); 183 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
184 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout); 184 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
185 bcm2835_wdt_wdd.parent = &pdev->dev;
185 err = watchdog_register_device(&bcm2835_wdt_wdd); 186 err = watchdog_register_device(&bcm2835_wdt_wdd);
186 if (err) { 187 if (err) {
187 dev_err(dev, "Failed to register watchdog device"); 188 dev_err(dev, "Failed to register watchdog device");
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index b28a072abf78..4064a43f1360 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -209,6 +209,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
209 209
210 wdt->wdd.info = &bcm47xx_wdt_info; 210 wdt->wdd.info = &bcm47xx_wdt_info;
211 wdt->wdd.timeout = WDT_DEFAULT_TIME; 211 wdt->wdd.timeout = WDT_DEFAULT_TIME;
212 wdt->wdd.parent = &pdev->dev;
212 ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout); 213 ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
213 if (ret) 214 if (ret)
214 goto err_timer; 215 goto err_timer;
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 22d8ae65772a..e0c98423f2c9 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -319,6 +319,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
319 spin_lock_init(&wdt->lock); 319 spin_lock_init(&wdt->lock);
320 platform_set_drvdata(pdev, wdt); 320 platform_set_drvdata(pdev, wdt);
321 watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt); 321 watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
322 bcm_kona_wdt_wdd.parent = &pdev->dev;
322 323
323 ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0); 324 ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
324 if (ret) { 325 if (ret) {
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index e96b09b135c8..04da4b66c75e 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -186,8 +186,6 @@ static int booke_wdt_stop(struct watchdog_device *wdog)
186static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev, 186static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev,
187 unsigned int timeout) 187 unsigned int timeout)
188{ 188{
189 if (timeout > MAX_WDT_TIMEOUT)
190 return -EINVAL;
191 wdt_dev->timeout = timeout; 189 wdt_dev->timeout = timeout;
192 booke_wdt_set(wdt_dev); 190 booke_wdt_set(wdt_dev);
193 191
@@ -211,7 +209,6 @@ static struct watchdog_device booke_wdt_dev = {
211 .info = &booke_wdt_info, 209 .info = &booke_wdt_info,
212 .ops = &booke_wdt_ops, 210 .ops = &booke_wdt_ops,
213 .min_timeout = 1, 211 .min_timeout = 1,
214 .max_timeout = 0xFFFF
215}; 212};
216 213
217static void __exit booke_wdt_exit(void) 214static void __exit booke_wdt_exit(void)
@@ -229,6 +226,7 @@ static int __init booke_wdt_init(void)
229 booke_wdt_set_timeout(&booke_wdt_dev, 226 booke_wdt_set_timeout(&booke_wdt_dev,
230 period_to_sec(booke_wdt_period)); 227 period_to_sec(booke_wdt_period));
231 watchdog_set_nowayout(&booke_wdt_dev, nowayout); 228 watchdog_set_nowayout(&booke_wdt_dev, nowayout);
229 booke_wdt_dev.max_timeout = MAX_WDT_TIMEOUT;
232 if (booke_wdt_enabled) 230 if (booke_wdt_enabled)
233 booke_wdt_start(&booke_wdt_dev); 231 booke_wdt_start(&booke_wdt_dev);
234 232
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index ce12f437f195..a099b77fc0b9 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -358,6 +358,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
358 if (ret < 0) 358 if (ret < 0)
359 coh901327_wdt.timeout = 60; 359 coh901327_wdt.timeout = 60;
360 360
361 coh901327_wdt.parent = &pdev->dev;
361 ret = watchdog_register_device(&coh901327_wdt); 362 ret = watchdog_register_device(&coh901327_wdt);
362 if (ret == 0) 363 if (ret == 0)
363 dev_info(&pdev->dev, 364 dev_info(&pdev->dev,
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 2e9589652e1e..67e67977bd29 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
195 da9052_wdt->timeout = DA9052_DEF_TIMEOUT; 195 da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
196 da9052_wdt->info = &da9052_wdt_info; 196 da9052_wdt->info = &da9052_wdt_info;
197 da9052_wdt->ops = &da9052_wdt_ops; 197 da9052_wdt->ops = &da9052_wdt_ops;
198 da9052_wdt->parent = &pdev->dev;
198 watchdog_set_drvdata(da9052_wdt, driver_data); 199 watchdog_set_drvdata(da9052_wdt, driver_data);
199 200
200 kref_init(&driver_data->kref); 201 kref_init(&driver_data->kref);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 495089d8dbfe..04d1430d93d2 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
161 da9055_wdt->timeout = DA9055_DEF_TIMEOUT; 161 da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
162 da9055_wdt->info = &da9055_wdt_info; 162 da9055_wdt->info = &da9055_wdt_info;
163 da9055_wdt->ops = &da9055_wdt_ops; 163 da9055_wdt->ops = &da9055_wdt_ops;
164 da9055_wdt->parent = &pdev->dev;
164 watchdog_set_nowayout(da9055_wdt, nowayout); 165 watchdog_set_nowayout(da9055_wdt, nowayout);
165 watchdog_set_drvdata(da9055_wdt, driver_data); 166 watchdog_set_drvdata(da9055_wdt, driver_data);
166 167
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index b3a870ce85be..7386111220d5 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
210 wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT; 210 wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
211 wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT; 211 wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
212 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 212 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
213 wdt->wdtdev.parent = &pdev->dev;
213 214
214 watchdog_set_drvdata(&wdt->wdtdev, wdt); 215 watchdog_set_drvdata(&wdt->wdtdev, wdt);
215 dev_set_drvdata(&pdev->dev, wdt); 216 dev_set_drvdata(&pdev->dev, wdt);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index e2fe2ebdebd4..6bf130bd863d 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
175 wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT; 175 wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
176 wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT; 176 wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
177 wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT; 177 wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
178 wdt->wdtdev.parent = &pdev->dev;
178 179
179 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 180 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
180 181
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index cfdf8a408aea..17454ca653f4 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -179,6 +179,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
179 wdd->min_timeout = 1; 179 wdd->min_timeout = 1;
180 wdd->max_timeout = MAX_HEARTBEAT; 180 wdd->max_timeout = MAX_HEARTBEAT;
181 wdd->timeout = DEFAULT_HEARTBEAT; 181 wdd->timeout = DEFAULT_HEARTBEAT;
182 wdd->parent = &pdev->dev;
182 183
183 watchdog_init_timeout(wdd, heartbeat, dev); 184 watchdog_init_timeout(wdd, heartbeat, dev);
184 185
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 31d8e4936611..50abe1bf62a5 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -143,6 +143,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
143 } 143 }
144 dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk); 144 dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
145 dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout; 145 dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
146 dc_wdt_wdd.parent = &pdev->dev;
146 147
147 spin_lock_init(&wdt->lock); 148 spin_lock_init(&wdt->lock);
148 149
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 7a2cc7191c58..0a4d7cc05d54 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
132 val = readl(mmio_base + EP93XX_WATCHDOG); 132 val = readl(mmio_base + EP93XX_WATCHDOG);
133 ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0; 133 ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
134 ep93xx_wdt_wdd.timeout = timeout; 134 ep93xx_wdt_wdd.timeout = timeout;
135 ep93xx_wdt_wdd.parent = &pdev->dev;
135 136
136 watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout); 137 watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);
137 138
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 1687cc2d7122..90d59d3f38a3 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -50,12 +50,41 @@ static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
50 gpio_direction_input(priv->gpio); 50 gpio_direction_input(priv->gpio);
51} 51}
52 52
53static void gpio_wdt_hwping(unsigned long data)
54{
55 struct watchdog_device *wdd = (struct watchdog_device *)data;
56 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
57
58 if (priv->armed && time_after(jiffies, priv->last_jiffies +
59 msecs_to_jiffies(wdd->timeout * 1000))) {
60 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
61 return;
62 }
63
64 /* Restart timer */
65 mod_timer(&priv->timer, jiffies + priv->hw_margin);
66
67 switch (priv->hw_algo) {
68 case HW_ALGO_TOGGLE:
69 /* Toggle output pin */
70 priv->state = !priv->state;
71 gpio_set_value_cansleep(priv->gpio, priv->state);
72 break;
73 case HW_ALGO_LEVEL:
74 /* Pulse */
75 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
76 udelay(1);
77 gpio_set_value_cansleep(priv->gpio, priv->active_low);
78 break;
79 }
80}
81
53static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv) 82static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv)
54{ 83{
55 priv->state = priv->active_low; 84 priv->state = priv->active_low;
56 gpio_direction_output(priv->gpio, priv->state); 85 gpio_direction_output(priv->gpio, priv->state);
57 priv->last_jiffies = jiffies; 86 priv->last_jiffies = jiffies;
58 mod_timer(&priv->timer, priv->last_jiffies + priv->hw_margin); 87 gpio_wdt_hwping((unsigned long)&priv->wdd);
59} 88}
60 89
61static int gpio_wdt_start(struct watchdog_device *wdd) 90static int gpio_wdt_start(struct watchdog_device *wdd)
@@ -97,35 +126,6 @@ static int gpio_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
97 return gpio_wdt_ping(wdd); 126 return gpio_wdt_ping(wdd);
98} 127}
99 128
100static void gpio_wdt_hwping(unsigned long data)
101{
102 struct watchdog_device *wdd = (struct watchdog_device *)data;
103 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
104
105 if (priv->armed && time_after(jiffies, priv->last_jiffies +
106 msecs_to_jiffies(wdd->timeout * 1000))) {
107 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
108 return;
109 }
110
111 /* Restart timer */
112 mod_timer(&priv->timer, jiffies + priv->hw_margin);
113
114 switch (priv->hw_algo) {
115 case HW_ALGO_TOGGLE:
116 /* Toggle output pin */
117 priv->state = !priv->state;
118 gpio_set_value_cansleep(priv->gpio, priv->state);
119 break;
120 case HW_ALGO_LEVEL:
121 /* Pulse */
122 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
123 udelay(1);
124 gpio_set_value_cansleep(priv->gpio, priv->active_low);
125 break;
126 }
127}
128
129static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code, 129static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code,
130 void *unused) 130 void *unused)
131{ 131{
@@ -182,10 +182,10 @@ static int gpio_wdt_probe(struct platform_device *pdev)
182 ret = of_property_read_string(pdev->dev.of_node, "hw_algo", &algo); 182 ret = of_property_read_string(pdev->dev.of_node, "hw_algo", &algo);
183 if (ret) 183 if (ret)
184 return ret; 184 return ret;
185 if (!strncmp(algo, "toggle", 6)) { 185 if (!strcmp(algo, "toggle")) {
186 priv->hw_algo = HW_ALGO_TOGGLE; 186 priv->hw_algo = HW_ALGO_TOGGLE;
187 f = GPIOF_IN; 187 f = GPIOF_IN;
188 } else if (!strncmp(algo, "level", 5)) { 188 } else if (!strcmp(algo, "level")) {
189 priv->hw_algo = HW_ALGO_LEVEL; 189 priv->hw_algo = HW_ALGO_LEVEL;
190 f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; 190 f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
191 } else { 191 } else {
@@ -217,6 +217,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
217 priv->wdd.ops = &gpio_wdt_ops; 217 priv->wdd.ops = &gpio_wdt_ops;
218 priv->wdd.min_timeout = SOFT_TIMEOUT_MIN; 218 priv->wdd.min_timeout = SOFT_TIMEOUT_MIN;
219 priv->wdd.max_timeout = SOFT_TIMEOUT_MAX; 219 priv->wdd.max_timeout = SOFT_TIMEOUT_MAX;
220 priv->wdd.parent = &pdev->dev;
220 221
221 if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0) 222 if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
222 priv->wdd.timeout = SOFT_TIMEOUT_DEF; 223 priv->wdd.timeout = SOFT_TIMEOUT_DEF;
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 9bc39ae51624..78c2541f5d52 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -267,6 +267,7 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
267 267
268 ie6xx_wdt_dev.timeout = timeout; 268 ie6xx_wdt_dev.timeout = timeout;
269 watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout); 269 watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
270 ie6xx_wdt_dev.parent = &pdev->dev;
270 271
271 spin_lock_init(&ie6xx_wdt_data.unlock_sequence); 272 spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
272 273
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c
index 0f73621827ab..15ab07230960 100644
--- a/drivers/watchdog/imgpdc_wdt.c
+++ b/drivers/watchdog/imgpdc_wdt.c
@@ -316,6 +316,7 @@ static int pdc_wdt_remove(struct platform_device *pdev)
316{ 316{
317 struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev); 317 struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
318 318
319 unregister_restart_handler(&pdc_wdt->restart_handler);
319 pdc_wdt_stop(&pdc_wdt->wdt_dev); 320 pdc_wdt_stop(&pdc_wdt->wdt_dev);
320 watchdog_unregister_device(&pdc_wdt->wdt_dev); 321 watchdog_unregister_device(&pdc_wdt->wdt_dev);
321 clk_disable_unprepare(pdc_wdt->wdt_clk); 322 clk_disable_unprepare(pdc_wdt->wdt_clk);
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 84f6701c391f..0a436b5d1e84 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -137,6 +137,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
137 wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN; 137 wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
138 wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX; 138 wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
139 wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT; 139 wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
140 wdt_dev->parent = &pdev->dev;
140 141
141 watchdog_set_drvdata(wdt_dev, &pdev->dev); 142 watchdog_set_drvdata(wdt_dev, &pdev->dev);
142 platform_set_drvdata(pdev, wdt_dev); 143 platform_set_drvdata(pdev, wdt_dev);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 4c2cc09c0c57..6a7d5c365438 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -174,6 +174,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
174 jz4740_wdt->timeout = heartbeat; 174 jz4740_wdt->timeout = heartbeat;
175 jz4740_wdt->min_timeout = 1; 175 jz4740_wdt->min_timeout = 1;
176 jz4740_wdt->max_timeout = MAX_HEARTBEAT; 176 jz4740_wdt->max_timeout = MAX_HEARTBEAT;
177 jz4740_wdt->parent = &pdev->dev;
177 watchdog_set_nowayout(jz4740_wdt, nowayout); 178 watchdog_set_nowayout(jz4740_wdt, nowayout);
178 watchdog_set_drvdata(jz4740_wdt, drvdata); 179 watchdog_set_drvdata(jz4740_wdt, drvdata);
179 180
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
new file mode 100644
index 000000000000..ab7b8b185d99
--- /dev/null
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -0,0 +1,340 @@
1/*
2 * NXP LPC18xx Watchdog Timer (WDT)
3 *
4 * Copyright (c) 2015 Ariel D'Alessandro <ariel@vanguardiasur.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * Notes
11 * -----
12 * The Watchdog consists of a fixed divide-by-4 clock pre-scaler and a 24-bit
13 * counter which decrements on every clock cycle.
14 */
15
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/platform_device.h>
21#include <linux/reboot.h>
22#include <linux/watchdog.h>
23
24/* Registers */
25#define LPC18XX_WDT_MOD 0x00
26#define LPC18XX_WDT_MOD_WDEN BIT(0)
27#define LPC18XX_WDT_MOD_WDRESET BIT(1)
28
29#define LPC18XX_WDT_TC 0x04
30#define LPC18XX_WDT_TC_MIN 0xff
31#define LPC18XX_WDT_TC_MAX 0xffffff
32
33#define LPC18XX_WDT_FEED 0x08
34#define LPC18XX_WDT_FEED_MAGIC1 0xaa
35#define LPC18XX_WDT_FEED_MAGIC2 0x55
36
37#define LPC18XX_WDT_TV 0x0c
38
39/* Clock pre-scaler */
40#define LPC18XX_WDT_CLK_DIV 4
41
42/* Timeout values in seconds */
43#define LPC18XX_WDT_DEF_TIMEOUT 30U
44
45static int heartbeat;
46module_param(heartbeat, int, 0);
47MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds (default="
48 __MODULE_STRING(LPC18XX_WDT_DEF_TIMEOUT) ")");
49
50static bool nowayout = WATCHDOG_NOWAYOUT;
51module_param(nowayout, bool, 0);
52MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
53 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
54
55struct lpc18xx_wdt_dev {
56 struct watchdog_device wdt_dev;
57 struct clk *reg_clk;
58 struct clk *wdt_clk;
59 unsigned long clk_rate;
60 void __iomem *base;
61 struct timer_list timer;
62 struct notifier_block restart_handler;
63 spinlock_t lock;
64};
65
66static int lpc18xx_wdt_feed(struct watchdog_device *wdt_dev)
67{
68 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
69 unsigned long flags;
70
71 /*
72 * An abort condition will occur if an interrupt happens during the feed
73 * sequence.
74 */
75 spin_lock_irqsave(&lpc18xx_wdt->lock, flags);
76 writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
77 writel(LPC18XX_WDT_FEED_MAGIC2, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
78 spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags);
79
80 return 0;
81}
82
83static void lpc18xx_wdt_timer_feed(unsigned long data)
84{
85 struct watchdog_device *wdt_dev = (struct watchdog_device *)data;
86 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
87
88 lpc18xx_wdt_feed(wdt_dev);
89
90 /* Use safe value (1/2 of real timeout) */
91 mod_timer(&lpc18xx_wdt->timer, jiffies +
92 msecs_to_jiffies((wdt_dev->timeout * MSEC_PER_SEC) / 2));
93}
94
95/*
96 * Since LPC18xx Watchdog cannot be disabled in hardware, we must keep feeding
97 * it with a timer until userspace watchdog software takes over.
98 */
99static int lpc18xx_wdt_stop(struct watchdog_device *wdt_dev)
100{
101 lpc18xx_wdt_timer_feed((unsigned long)wdt_dev);
102
103 return 0;
104}
105
106static void __lpc18xx_wdt_set_timeout(struct lpc18xx_wdt_dev *lpc18xx_wdt)
107{
108 unsigned int val;
109
110 val = DIV_ROUND_UP(lpc18xx_wdt->wdt_dev.timeout * lpc18xx_wdt->clk_rate,
111 LPC18XX_WDT_CLK_DIV);
112 writel(val, lpc18xx_wdt->base + LPC18XX_WDT_TC);
113}
114
115static int lpc18xx_wdt_set_timeout(struct watchdog_device *wdt_dev,
116 unsigned int new_timeout)
117{
118 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
119
120 lpc18xx_wdt->wdt_dev.timeout = new_timeout;
121 __lpc18xx_wdt_set_timeout(lpc18xx_wdt);
122
123 return 0;
124}
125
126static unsigned int lpc18xx_wdt_get_timeleft(struct watchdog_device *wdt_dev)
127{
128 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
129 unsigned int val;
130
131 val = readl(lpc18xx_wdt->base + LPC18XX_WDT_TV);
132 return (val * LPC18XX_WDT_CLK_DIV) / lpc18xx_wdt->clk_rate;
133}
134
135static int lpc18xx_wdt_start(struct watchdog_device *wdt_dev)
136{
137 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
138 unsigned int val;
139
140 if (timer_pending(&lpc18xx_wdt->timer))
141 del_timer(&lpc18xx_wdt->timer);
142
143 val = readl(lpc18xx_wdt->base + LPC18XX_WDT_MOD);
144 val |= LPC18XX_WDT_MOD_WDEN;
145 val |= LPC18XX_WDT_MOD_WDRESET;
146 writel(val, lpc18xx_wdt->base + LPC18XX_WDT_MOD);
147
148 /*
149 * Setting the WDEN bit in the WDMOD register is not sufficient to
150 * enable the Watchdog. A valid feed sequence must be completed after
151 * setting WDEN before the Watchdog is capable of generating a reset.
152 */
153 lpc18xx_wdt_feed(wdt_dev);
154
155 return 0;
156}
157
158static struct watchdog_info lpc18xx_wdt_info = {
159 .identity = "NXP LPC18xx Watchdog",
160 .options = WDIOF_SETTIMEOUT |
161 WDIOF_KEEPALIVEPING |
162 WDIOF_MAGICCLOSE,
163};
164
165static const struct watchdog_ops lpc18xx_wdt_ops = {
166 .owner = THIS_MODULE,
167 .start = lpc18xx_wdt_start,
168 .stop = lpc18xx_wdt_stop,
169 .ping = lpc18xx_wdt_feed,
170 .set_timeout = lpc18xx_wdt_set_timeout,
171 .get_timeleft = lpc18xx_wdt_get_timeleft,
172};
173
174static int lpc18xx_wdt_restart(struct notifier_block *this, unsigned long mode,
175 void *cmd)
176{
177 struct lpc18xx_wdt_dev *lpc18xx_wdt = container_of(this,
178 struct lpc18xx_wdt_dev, restart_handler);
179 unsigned long flags;
180 int val;
181
182 /*
183 * Incorrect feed sequence causes immediate watchdog reset if enabled.
184 */
185 spin_lock_irqsave(&lpc18xx_wdt->lock, flags);
186
187 val = readl(lpc18xx_wdt->base + LPC18XX_WDT_MOD);
188 val |= LPC18XX_WDT_MOD_WDEN;
189 val |= LPC18XX_WDT_MOD_WDRESET;
190 writel(val, lpc18xx_wdt->base + LPC18XX_WDT_MOD);
191
192 writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
193 writel(LPC18XX_WDT_FEED_MAGIC2, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
194
195 writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
196 writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
197
198 spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags);
199
200 return NOTIFY_OK;
201}
202
203static int lpc18xx_wdt_probe(struct platform_device *pdev)
204{
205 struct lpc18xx_wdt_dev *lpc18xx_wdt;
206 struct device *dev = &pdev->dev;
207 struct resource *res;
208 int ret;
209
210 lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL);
211 if (!lpc18xx_wdt)
212 return -ENOMEM;
213
214 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
215 lpc18xx_wdt->base = devm_ioremap_resource(dev, res);
216 if (IS_ERR(lpc18xx_wdt->base))
217 return PTR_ERR(lpc18xx_wdt->base);
218
219 lpc18xx_wdt->reg_clk = devm_clk_get(dev, "reg");
220 if (IS_ERR(lpc18xx_wdt->reg_clk)) {
221 dev_err(dev, "failed to get the reg clock\n");
222 return PTR_ERR(lpc18xx_wdt->reg_clk);
223 }
224
225 lpc18xx_wdt->wdt_clk = devm_clk_get(dev, "wdtclk");
226 if (IS_ERR(lpc18xx_wdt->wdt_clk)) {
227 dev_err(dev, "failed to get the wdt clock\n");
228 return PTR_ERR(lpc18xx_wdt->wdt_clk);
229 }
230
231 ret = clk_prepare_enable(lpc18xx_wdt->reg_clk);
232 if (ret) {
233 dev_err(dev, "could not prepare or enable sys clock\n");
234 return ret;
235 }
236
237 ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk);
238 if (ret) {
239 dev_err(dev, "could not prepare or enable wdt clock\n");
240 goto disable_reg_clk;
241 }
242
243 /* We use the clock rate to calculate timeouts */
244 lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
245 if (lpc18xx_wdt->clk_rate == 0) {
246 dev_err(dev, "failed to get clock rate\n");
247 ret = -EINVAL;
248 goto disable_wdt_clk;
249 }
250
251 lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info;
252 lpc18xx_wdt->wdt_dev.ops = &lpc18xx_wdt_ops;
253
254 lpc18xx_wdt->wdt_dev.min_timeout = DIV_ROUND_UP(LPC18XX_WDT_TC_MIN *
255 LPC18XX_WDT_CLK_DIV, lpc18xx_wdt->clk_rate);
256
257 lpc18xx_wdt->wdt_dev.max_timeout = (LPC18XX_WDT_TC_MAX *
258 LPC18XX_WDT_CLK_DIV) / lpc18xx_wdt->clk_rate;
259
260 lpc18xx_wdt->wdt_dev.timeout = min(lpc18xx_wdt->wdt_dev.max_timeout,
261 LPC18XX_WDT_DEF_TIMEOUT);
262
263 spin_lock_init(&lpc18xx_wdt->lock);
264
265 lpc18xx_wdt->wdt_dev.parent = dev;
266 watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt);
267
268 ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev);
269
270 __lpc18xx_wdt_set_timeout(lpc18xx_wdt);
271
272 setup_timer(&lpc18xx_wdt->timer, lpc18xx_wdt_timer_feed,
273 (unsigned long)&lpc18xx_wdt->wdt_dev);
274
275 watchdog_set_nowayout(&lpc18xx_wdt->wdt_dev, nowayout);
276
277 platform_set_drvdata(pdev, lpc18xx_wdt);
278
279 ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev);
280 if (ret)
281 goto disable_wdt_clk;
282
283 lpc18xx_wdt->restart_handler.notifier_call = lpc18xx_wdt_restart;
284 lpc18xx_wdt->restart_handler.priority = 128;
285 ret = register_restart_handler(&lpc18xx_wdt->restart_handler);
286 if (ret)
287 dev_warn(dev, "failed to register restart handler: %d\n", ret);
288
289 return 0;
290
291disable_wdt_clk:
292 clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
293disable_reg_clk:
294 clk_disable_unprepare(lpc18xx_wdt->reg_clk);
295 return ret;
296}
297
298static void lpc18xx_wdt_shutdown(struct platform_device *pdev)
299{
300 struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
301
302 lpc18xx_wdt_stop(&lpc18xx_wdt->wdt_dev);
303}
304
305static int lpc18xx_wdt_remove(struct platform_device *pdev)
306{
307 struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
308
309 unregister_restart_handler(&lpc18xx_wdt->restart_handler);
310
311 dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
312 del_timer(&lpc18xx_wdt->timer);
313
314 watchdog_unregister_device(&lpc18xx_wdt->wdt_dev);
315 clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
316 clk_disable_unprepare(lpc18xx_wdt->reg_clk);
317
318 return 0;
319}
320
321static const struct of_device_id lpc18xx_wdt_match[] = {
322 { .compatible = "nxp,lpc1850-wwdt" },
323 {}
324};
325MODULE_DEVICE_TABLE(of, lpc18xx_wdt_match);
326
327static struct platform_driver lpc18xx_wdt_driver = {
328 .driver = {
329 .name = "lpc18xx-wdt",
330 .of_match_table = lpc18xx_wdt_match,
331 },
332 .probe = lpc18xx_wdt_probe,
333 .remove = lpc18xx_wdt_remove,
334 .shutdown = lpc18xx_wdt_shutdown,
335};
336module_platform_driver(lpc18xx_wdt_driver);
337
338MODULE_AUTHOR("Ariel D'Alessandro <ariel@vanguardiasur.com.ar>");
339MODULE_DESCRIPTION("NXP LPC18xx Watchdog Timer Driver");
340MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index d193a5e79c38..69013007dc47 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -197,6 +197,7 @@ static int a21_wdt_probe(struct platform_device *pdev)
197 watchdog_init_timeout(&a21_wdt, 30, &pdev->dev); 197 watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
198 watchdog_set_nowayout(&a21_wdt, nowayout); 198 watchdog_set_nowayout(&a21_wdt, nowayout);
199 watchdog_set_drvdata(&a21_wdt, drv); 199 watchdog_set_drvdata(&a21_wdt, drv);
200 a21_wdt.parent = &pdev->dev;
200 201
201 reset = a21_wdt_get_bootstatus(drv); 202 reset = a21_wdt_get_bootstatus(drv);
202 if (reset == 2) 203 if (reset == 2)
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
index 59f0913c7341..3aefddebb386 100644
--- a/drivers/watchdog/menf21bmc_wdt.c
+++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -130,6 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
130 drv_data->wdt.info = &menf21bmc_wdt_info; 130 drv_data->wdt.info = &menf21bmc_wdt_info;
131 drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN; 131 drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
132 drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX; 132 drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
133 drv_data->wdt.parent = &pdev->dev;
133 drv_data->i2c_client = i2c_client; 134 drv_data->i2c_client = i2c_client;
134 135
135 /* 136 /*
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 689381a24887..5f2273aac37d 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -50,8 +50,12 @@ struct mpc8xxx_wdt_type {
50 bool hw_enabled; 50 bool hw_enabled;
51}; 51};
52 52
53static struct mpc8xxx_wdt __iomem *wd_base; 53struct mpc8xxx_wdt_ddata {
54static int mpc8xxx_wdt_init_late(void); 54 struct mpc8xxx_wdt __iomem *base;
55 struct watchdog_device wdd;
56 struct timer_list timer;
57 spinlock_t lock;
58};
55 59
56static u16 timeout = 0xffff; 60static u16 timeout = 0xffff;
57module_param(timeout, ushort, 0); 61module_param(timeout, ushort, 0);
@@ -68,65 +72,59 @@ module_param(nowayout, bool, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 72MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
69 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 73 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
70 74
71/* 75static void mpc8xxx_wdt_keepalive(struct mpc8xxx_wdt_ddata *ddata)
72 * We always prescale, but if someone really doesn't want to they can set this
73 * to 0
74 */
75static int prescale = 1;
76
77static DEFINE_SPINLOCK(wdt_spinlock);
78
79static void mpc8xxx_wdt_keepalive(void)
80{ 76{
81 /* Ping the WDT */ 77 /* Ping the WDT */
82 spin_lock(&wdt_spinlock); 78 spin_lock(&ddata->lock);
83 out_be16(&wd_base->swsrr, 0x556c); 79 out_be16(&ddata->base->swsrr, 0x556c);
84 out_be16(&wd_base->swsrr, 0xaa39); 80 out_be16(&ddata->base->swsrr, 0xaa39);
85 spin_unlock(&wdt_spinlock); 81 spin_unlock(&ddata->lock);
86} 82}
87 83
88static struct watchdog_device mpc8xxx_wdt_dev;
89static void mpc8xxx_wdt_timer_ping(unsigned long arg);
90static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0,
91 (unsigned long)&mpc8xxx_wdt_dev);
92
93static void mpc8xxx_wdt_timer_ping(unsigned long arg) 84static void mpc8xxx_wdt_timer_ping(unsigned long arg)
94{ 85{
95 struct watchdog_device *w = (struct watchdog_device *)arg; 86 struct mpc8xxx_wdt_ddata *ddata = (void *)arg;
96 87
97 mpc8xxx_wdt_keepalive(); 88 mpc8xxx_wdt_keepalive(ddata);
98 /* We're pinging it twice faster than needed, just to be sure. */ 89 /* We're pinging it twice faster than needed, just to be sure. */
99 mod_timer(&wdt_timer, jiffies + HZ * w->timeout / 2); 90 mod_timer(&ddata->timer, jiffies + HZ * ddata->wdd.timeout / 2);
100} 91}
101 92
102static int mpc8xxx_wdt_start(struct watchdog_device *w) 93static int mpc8xxx_wdt_start(struct watchdog_device *w)
103{ 94{
104 u32 tmp = SWCRR_SWEN; 95 struct mpc8xxx_wdt_ddata *ddata =
96 container_of(w, struct mpc8xxx_wdt_ddata, wdd);
97
98 u32 tmp = SWCRR_SWEN | SWCRR_SWPR;
105 99
106 /* Good, fire up the show */ 100 /* Good, fire up the show */
107 if (prescale)
108 tmp |= SWCRR_SWPR;
109 if (reset) 101 if (reset)
110 tmp |= SWCRR_SWRI; 102 tmp |= SWCRR_SWRI;
111 103
112 tmp |= timeout << 16; 104 tmp |= timeout << 16;
113 105
114 out_be32(&wd_base->swcrr, tmp); 106 out_be32(&ddata->base->swcrr, tmp);
115 107
116 del_timer_sync(&wdt_timer); 108 del_timer_sync(&ddata->timer);
117 109
118 return 0; 110 return 0;
119} 111}
120 112
121static int mpc8xxx_wdt_ping(struct watchdog_device *w) 113static int mpc8xxx_wdt_ping(struct watchdog_device *w)
122{ 114{
123 mpc8xxx_wdt_keepalive(); 115 struct mpc8xxx_wdt_ddata *ddata =
116 container_of(w, struct mpc8xxx_wdt_ddata, wdd);
117
118 mpc8xxx_wdt_keepalive(ddata);
124 return 0; 119 return 0;
125} 120}
126 121
127static int mpc8xxx_wdt_stop(struct watchdog_device *w) 122static int mpc8xxx_wdt_stop(struct watchdog_device *w)
128{ 123{
129 mod_timer(&wdt_timer, jiffies); 124 struct mpc8xxx_wdt_ddata *ddata =
125 container_of(w, struct mpc8xxx_wdt_ddata, wdd);
126
127 mod_timer(&ddata->timer, jiffies);
130 return 0; 128 return 0;
131} 129}
132 130
@@ -143,53 +141,57 @@ static struct watchdog_ops mpc8xxx_wdt_ops = {
143 .stop = mpc8xxx_wdt_stop, 141 .stop = mpc8xxx_wdt_stop,
144}; 142};
145 143
146static struct watchdog_device mpc8xxx_wdt_dev = {
147 .info = &mpc8xxx_wdt_info,
148 .ops = &mpc8xxx_wdt_ops,
149};
150
151static const struct of_device_id mpc8xxx_wdt_match[];
152static int mpc8xxx_wdt_probe(struct platform_device *ofdev) 144static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
153{ 145{
154 int ret; 146 int ret;
155 const struct of_device_id *match; 147 struct resource *res;
156 struct device_node *np = ofdev->dev.of_node;
157 const struct mpc8xxx_wdt_type *wdt_type; 148 const struct mpc8xxx_wdt_type *wdt_type;
149 struct mpc8xxx_wdt_ddata *ddata;
158 u32 freq = fsl_get_sys_freq(); 150 u32 freq = fsl_get_sys_freq();
159 bool enabled; 151 bool enabled;
160 unsigned int timeout_sec; 152 unsigned int timeout_sec;
161 153
162 match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); 154 wdt_type = of_device_get_match_data(&ofdev->dev);
163 if (!match) 155 if (!wdt_type)
164 return -EINVAL; 156 return -EINVAL;
165 wdt_type = match->data;
166 157
167 if (!freq || freq == -1) 158 if (!freq || freq == -1)
168 return -EINVAL; 159 return -EINVAL;
169 160
170 wd_base = of_iomap(np, 0); 161 ddata = devm_kzalloc(&ofdev->dev, sizeof(*ddata), GFP_KERNEL);
171 if (!wd_base) 162 if (!ddata)
172 return -ENOMEM; 163 return -ENOMEM;
173 164
174 enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN; 165 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
166 ddata->base = devm_ioremap_resource(&ofdev->dev, res);
167 if (IS_ERR(ddata->base))
168 return PTR_ERR(ddata->base);
169
170 enabled = in_be32(&ddata->base->swcrr) & SWCRR_SWEN;
175 if (!enabled && wdt_type->hw_enabled) { 171 if (!enabled && wdt_type->hw_enabled) {
176 pr_info("could not be enabled in software\n"); 172 pr_info("could not be enabled in software\n");
177 ret = -ENOSYS; 173 return -ENODEV;
178 goto err_unmap;
179 } 174 }
180 175
176 spin_lock_init(&ddata->lock);
177 setup_timer(&ddata->timer, mpc8xxx_wdt_timer_ping,
178 (unsigned long)ddata);
179
180 ddata->wdd.info = &mpc8xxx_wdt_info,
181 ddata->wdd.ops = &mpc8xxx_wdt_ops,
182
181 /* Calculate the timeout in seconds */ 183 /* Calculate the timeout in seconds */
182 if (prescale) 184 timeout_sec = (timeout * wdt_type->prescaler) / freq;
183 timeout_sec = (timeout * wdt_type->prescaler) / freq; 185
184 else 186 ddata->wdd.timeout = timeout_sec;
185 timeout_sec = timeout / freq; 187
186 188 watchdog_set_nowayout(&ddata->wdd, nowayout);
187 mpc8xxx_wdt_dev.timeout = timeout_sec; 189
188#ifdef MODULE 190 ret = watchdog_register_device(&ddata->wdd);
189 ret = mpc8xxx_wdt_init_late(); 191 if (ret) {
190 if (ret) 192 pr_err("cannot register watchdog device (err=%d)\n", ret);
191 goto err_unmap; 193 return ret;
192#endif 194 }
193 195
194 pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d seconds)\n", 196 pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d seconds)\n",
195 reset ? "reset" : "interrupt", timeout, timeout_sec); 197 reset ? "reset" : "interrupt", timeout, timeout_sec);
@@ -200,21 +202,20 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
200 * userspace handles it. 202 * userspace handles it.
201 */ 203 */
202 if (enabled) 204 if (enabled)
203 mod_timer(&wdt_timer, jiffies); 205 mod_timer(&ddata->timer, jiffies);
206
207 platform_set_drvdata(ofdev, ddata);
204 return 0; 208 return 0;
205err_unmap:
206 iounmap(wd_base);
207 wd_base = NULL;
208 return ret;
209} 209}
210 210
211static int mpc8xxx_wdt_remove(struct platform_device *ofdev) 211static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
212{ 212{
213 struct mpc8xxx_wdt_ddata *ddata = platform_get_drvdata(ofdev);
214
213 pr_crit("Watchdog removed, expect the %s soon!\n", 215 pr_crit("Watchdog removed, expect the %s soon!\n",
214 reset ? "reset" : "machine check exception"); 216 reset ? "reset" : "machine check exception");
215 del_timer_sync(&wdt_timer); 217 del_timer_sync(&ddata->timer);
216 watchdog_unregister_device(&mpc8xxx_wdt_dev); 218 watchdog_unregister_device(&ddata->wdd);
217 iounmap(wd_base);
218 219
219 return 0; 220 return 0;
220} 221}
@@ -253,31 +254,6 @@ static struct platform_driver mpc8xxx_wdt_driver = {
253 }, 254 },
254}; 255};
255 256
256/*
257 * We do wdt initialization in two steps: arch_initcall probes the wdt
258 * very early to start pinging the watchdog (misc devices are not yet
259 * available), and later module_init() just registers the misc device.
260 */
261static int mpc8xxx_wdt_init_late(void)
262{
263 int ret;
264
265 if (!wd_base)
266 return -ENODEV;
267
268 watchdog_set_nowayout(&mpc8xxx_wdt_dev, nowayout);
269
270 ret = watchdog_register_device(&mpc8xxx_wdt_dev);
271 if (ret) {
272 pr_err("cannot register watchdog device (err=%d)\n", ret);
273 return ret;
274 }
275 return 0;
276}
277#ifndef MODULE
278module_init(mpc8xxx_wdt_init_late);
279#endif
280
281static int __init mpc8xxx_wdt_init(void) 257static int __init mpc8xxx_wdt_init(void)
282{ 258{
283 return platform_driver_register(&mpc8xxx_wdt_driver); 259 return platform_driver_register(&mpc8xxx_wdt_driver);
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 938b987de551..6ad9df948711 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -210,6 +210,14 @@ static int mtk_wdt_probe(struct platform_device *pdev)
210 return 0; 210 return 0;
211} 211}
212 212
213static void mtk_wdt_shutdown(struct platform_device *pdev)
214{
215 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
216
217 if (watchdog_active(&mtk_wdt->wdt_dev))
218 mtk_wdt_stop(&mtk_wdt->wdt_dev);
219}
220
213static int mtk_wdt_remove(struct platform_device *pdev) 221static int mtk_wdt_remove(struct platform_device *pdev)
214{ 222{
215 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); 223 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
@@ -221,17 +229,48 @@ static int mtk_wdt_remove(struct platform_device *pdev)
221 return 0; 229 return 0;
222} 230}
223 231
232#ifdef CONFIG_PM_SLEEP
233static int mtk_wdt_suspend(struct device *dev)
234{
235 struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
236
237 if (watchdog_active(&mtk_wdt->wdt_dev))
238 mtk_wdt_stop(&mtk_wdt->wdt_dev);
239
240 return 0;
241}
242
243static int mtk_wdt_resume(struct device *dev)
244{
245 struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
246
247 if (watchdog_active(&mtk_wdt->wdt_dev)) {
248 mtk_wdt_start(&mtk_wdt->wdt_dev);
249 mtk_wdt_ping(&mtk_wdt->wdt_dev);
250 }
251
252 return 0;
253}
254#endif
255
224static const struct of_device_id mtk_wdt_dt_ids[] = { 256static const struct of_device_id mtk_wdt_dt_ids[] = {
225 { .compatible = "mediatek,mt6589-wdt" }, 257 { .compatible = "mediatek,mt6589-wdt" },
226 { /* sentinel */ } 258 { /* sentinel */ }
227}; 259};
228MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids); 260MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
229 261
262static const struct dev_pm_ops mtk_wdt_pm_ops = {
263 SET_SYSTEM_SLEEP_PM_OPS(mtk_wdt_suspend,
264 mtk_wdt_resume)
265};
266
230static struct platform_driver mtk_wdt_driver = { 267static struct platform_driver mtk_wdt_driver = {
231 .probe = mtk_wdt_probe, 268 .probe = mtk_wdt_probe,
232 .remove = mtk_wdt_remove, 269 .remove = mtk_wdt_remove,
270 .shutdown = mtk_wdt_shutdown,
233 .driver = { 271 .driver = {
234 .name = DRV_NAME, 272 .name = DRV_NAME,
273 .pm = &mtk_wdt_pm_ops,
235 .of_match_table = mtk_wdt_dt_ids, 274 .of_match_table = mtk_wdt_dt_ids,
236 }, 275 },
237}; 276};
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c
index c028454be66c..bd917bb757b8 100644
--- a/drivers/watchdog/nv_tco.c
+++ b/drivers/watchdog/nv_tco.c
@@ -294,6 +294,8 @@ static const struct pci_device_id tco_pci_tbl[] = {
294 PCI_ANY_ID, PCI_ANY_ID, }, 294 PCI_ANY_ID, PCI_ANY_ID, },
295 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS, 295 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS,
296 PCI_ANY_ID, PCI_ANY_ID, }, 296 PCI_ANY_ID, PCI_ANY_ID, },
297 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS,
298 PCI_ANY_ID, PCI_ANY_ID, },
297 { 0, }, /* End of list */ 299 { 0, }, /* End of list */
298}; 300};
299MODULE_DEVICE_TABLE(pci, tco_pci_tbl); 301MODULE_DEVICE_TABLE(pci, tco_pci_tbl);
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index de911c7e477c..d96bee017fd3 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -253,6 +253,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
253 wdev->wdog.ops = &omap_wdt_ops; 253 wdev->wdog.ops = &omap_wdt_ops;
254 wdev->wdog.min_timeout = TIMER_MARGIN_MIN; 254 wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
255 wdev->wdog.max_timeout = TIMER_MARGIN_MAX; 255 wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
256 wdev->wdog.parent = &pdev->dev;
256 257
257 if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0) 258 if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
258 wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; 259 wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index ef0c628d5037..c6b8f4a43bde 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -567,6 +567,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
567 567
568 dev->wdt.timeout = wdt_max_duration; 568 dev->wdt.timeout = wdt_max_duration;
569 dev->wdt.max_timeout = wdt_max_duration; 569 dev->wdt.max_timeout = wdt_max_duration;
570 dev->wdt.parent = &pdev->dev;
570 watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev); 571 watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
571 572
572 platform_set_drvdata(pdev, &dev->wdt); 573 platform_set_drvdata(pdev, &dev->wdt);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index b9c6049c3e78..4224b3ec83a5 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -167,6 +167,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
167 167
168 pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? 168 pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
169 WDIOF_CARDRESET : 0; 169 WDIOF_CARDRESET : 0;
170 pnx4008_wdd.parent = &pdev->dev;
170 watchdog_set_nowayout(&pnx4008_wdd, nowayout); 171 watchdog_set_nowayout(&pnx4008_wdd, nowayout);
171 172
172 pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */ 173 pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index aa03ca8f2d9b..773dcfaee7b2 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -171,6 +171,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
171 wdt->wdd.ops = &qcom_wdt_ops; 171 wdt->wdd.ops = &qcom_wdt_ops;
172 wdt->wdd.min_timeout = 1; 172 wdt->wdd.min_timeout = 1;
173 wdt->wdd.max_timeout = 0x10000000U / wdt->rate; 173 wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
174 wdt->wdd.parent = &pdev->dev;
174 175
175 /* 176 /*
176 * If 'timeout-sec' unspecified in devicetree, assume a 30 second 177 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index b7c68e275aeb..39cd51df2ffc 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -127,6 +127,7 @@ static int retu_wdt_probe(struct platform_device *pdev)
127 retu_wdt->timeout = RETU_WDT_MAX_TIMER; 127 retu_wdt->timeout = RETU_WDT_MAX_TIMER;
128 retu_wdt->min_timeout = 0; 128 retu_wdt->min_timeout = 0;
129 retu_wdt->max_timeout = RETU_WDT_MAX_TIMER; 129 retu_wdt->max_timeout = RETU_WDT_MAX_TIMER;
130 retu_wdt->parent = &pdev->dev;
130 131
131 watchdog_set_drvdata(retu_wdt, wdev); 132 watchdog_set_drvdata(retu_wdt, wdev);
132 watchdog_set_nowayout(retu_wdt, nowayout); 133 watchdog_set_nowayout(retu_wdt, nowayout);
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index a6f7e2e29beb..1967919ae743 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -161,6 +161,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
161 rt288x_wdt_dev.dev = &pdev->dev; 161 rt288x_wdt_dev.dev = &pdev->dev;
162 rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); 162 rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
163 rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); 163 rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
164 rt288x_wdt_dev.parent = &pdev->dev;
164 165
165 watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout, 166 watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
166 &pdev->dev); 167 &pdev->dev);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e89ae027c91d..d781000c7825 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -607,6 +607,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
607 watchdog_set_nowayout(&wdt->wdt_device, nowayout); 607 watchdog_set_nowayout(&wdt->wdt_device, nowayout);
608 608
609 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt); 609 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
610 wdt->wdt_device.parent = &pdev->dev;
610 611
611 ret = watchdog_register_device(&wdt->wdt_device); 612 ret = watchdog_register_device(&wdt->wdt_device);
612 if (ret) { 613 if (ret) {
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
new file mode 100644
index 000000000000..a49634cdc1cc
--- /dev/null
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -0,0 +1,280 @@
1/*
2 * Driver for Atmel SAMA5D4 Watchdog Timer
3 *
4 * Copyright (C) 2015 Atmel Corporation
5 *
6 * Licensed under GPLv2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/io.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_irq.h>
15#include <linux/platform_device.h>
16#include <linux/reboot.h>
17#include <linux/watchdog.h>
18
19#include "at91sam9_wdt.h"
20
21/* minimum and maximum watchdog timeout, in seconds */
22#define MIN_WDT_TIMEOUT 1
23#define MAX_WDT_TIMEOUT 16
24#define WDT_DEFAULT_TIMEOUT MAX_WDT_TIMEOUT
25
26#define WDT_SEC2TICKS(s) ((s) ? (((s) << 8) - 1) : 0)
27
28struct sama5d4_wdt {
29 struct watchdog_device wdd;
30 void __iomem *reg_base;
31 u32 config;
32};
33
34static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
35static bool nowayout = WATCHDOG_NOWAYOUT;
36
37module_param(wdt_timeout, int, 0);
38MODULE_PARM_DESC(wdt_timeout,
39 "Watchdog timeout in seconds. (default = "
40 __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
41
42module_param(nowayout, bool, 0);
43MODULE_PARM_DESC(nowayout,
44 "Watchdog cannot be stopped once started (default="
45 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
46
47#define wdt_read(wdt, field) \
48 readl_relaxed((wdt)->reg_base + (field))
49
50#define wdt_write(wtd, field, val) \
51 writel_relaxed((val), (wdt)->reg_base + (field))
52
53static int sama5d4_wdt_start(struct watchdog_device *wdd)
54{
55 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
56 u32 reg;
57
58 reg = wdt_read(wdt, AT91_WDT_MR);
59 reg &= ~AT91_WDT_WDDIS;
60 wdt_write(wdt, AT91_WDT_MR, reg);
61
62 return 0;
63}
64
65static int sama5d4_wdt_stop(struct watchdog_device *wdd)
66{
67 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
68 u32 reg;
69
70 reg = wdt_read(wdt, AT91_WDT_MR);
71 reg |= AT91_WDT_WDDIS;
72 wdt_write(wdt, AT91_WDT_MR, reg);
73
74 return 0;
75}
76
77static int sama5d4_wdt_ping(struct watchdog_device *wdd)
78{
79 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
80
81 wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
82
83 return 0;
84}
85
86static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
87 unsigned int timeout)
88{
89 struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
90 u32 value = WDT_SEC2TICKS(timeout);
91 u32 reg;
92
93 reg = wdt_read(wdt, AT91_WDT_MR);
94 reg &= ~AT91_WDT_WDV;
95 reg &= ~AT91_WDT_WDD;
96 reg |= AT91_WDT_SET_WDV(value);
97 reg |= AT91_WDT_SET_WDD(value);
98 wdt_write(wdt, AT91_WDT_MR, reg);
99
100 wdd->timeout = timeout;
101
102 return 0;
103}
104
105static const struct watchdog_info sama5d4_wdt_info = {
106 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
107 .identity = "Atmel SAMA5D4 Watchdog",
108};
109
110static struct watchdog_ops sama5d4_wdt_ops = {
111 .owner = THIS_MODULE,
112 .start = sama5d4_wdt_start,
113 .stop = sama5d4_wdt_stop,
114 .ping = sama5d4_wdt_ping,
115 .set_timeout = sama5d4_wdt_set_timeout,
116};
117
118static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id)
119{
120 struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id);
121
122 if (wdt_read(wdt, AT91_WDT_SR)) {
123 pr_crit("Atmel Watchdog Software Reset\n");
124 emergency_restart();
125 pr_crit("Reboot didn't succeed\n");
126 }
127
128 return IRQ_HANDLED;
129}
130
131static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
132{
133 const char *tmp;
134
135 wdt->config = AT91_WDT_WDDIS;
136
137 if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
138 !strcmp(tmp, "software"))
139 wdt->config |= AT91_WDT_WDFIEN;
140 else
141 wdt->config |= AT91_WDT_WDRSTEN;
142
143 if (of_property_read_bool(np, "atmel,idle-halt"))
144 wdt->config |= AT91_WDT_WDIDLEHLT;
145
146 if (of_property_read_bool(np, "atmel,dbg-halt"))
147 wdt->config |= AT91_WDT_WDDBGHLT;
148
149 return 0;
150}
151
152static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
153{
154 struct watchdog_device *wdd = &wdt->wdd;
155 u32 value = WDT_SEC2TICKS(wdd->timeout);
156 u32 reg;
157
158 /*
159 * Because the fields WDV and WDD must not be modified when the WDDIS
160 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
161 */
162 reg = wdt_read(wdt, AT91_WDT_MR);
163 reg &= ~AT91_WDT_WDDIS;
164 wdt_write(wdt, AT91_WDT_MR, reg);
165
166 reg = wdt->config;
167 reg |= AT91_WDT_SET_WDD(value);
168 reg |= AT91_WDT_SET_WDV(value);
169
170 wdt_write(wdt, AT91_WDT_MR, reg);
171
172 return 0;
173}
174
175static int sama5d4_wdt_probe(struct platform_device *pdev)
176{
177 struct watchdog_device *wdd;
178 struct sama5d4_wdt *wdt;
179 struct resource *res;
180 void __iomem *regs;
181 u32 irq = 0;
182 int ret;
183
184 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
185 if (!wdt)
186 return -ENOMEM;
187
188 wdd = &wdt->wdd;
189 wdd->timeout = wdt_timeout;
190 wdd->info = &sama5d4_wdt_info;
191 wdd->ops = &sama5d4_wdt_ops;
192 wdd->min_timeout = MIN_WDT_TIMEOUT;
193 wdd->max_timeout = MAX_WDT_TIMEOUT;
194
195 watchdog_set_drvdata(wdd, wdt);
196
197 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
198 regs = devm_ioremap_resource(&pdev->dev, res);
199 if (IS_ERR(regs))
200 return PTR_ERR(regs);
201
202 wdt->reg_base = regs;
203
204 if (pdev->dev.of_node) {
205 irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
206 if (!irq)
207 dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
208
209 ret = of_sama5d4_wdt_init(pdev->dev.of_node, wdt);
210 if (ret)
211 return ret;
212 }
213
214 if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
215 ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
216 IRQF_SHARED | IRQF_IRQPOLL |
217 IRQF_NO_SUSPEND, pdev->name, pdev);
218 if (ret) {
219 dev_err(&pdev->dev,
220 "cannot register interrupt handler\n");
221 return ret;
222 }
223 }
224
225 ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
226 if (ret) {
227 dev_err(&pdev->dev, "unable to set timeout value\n");
228 return ret;
229 }
230
231 ret = sama5d4_wdt_init(wdt);
232 if (ret)
233 return ret;
234
235 watchdog_set_nowayout(wdd, nowayout);
236
237 ret = watchdog_register_device(wdd);
238 if (ret) {
239 dev_err(&pdev->dev, "failed to register watchdog device\n");
240 return ret;
241 }
242
243 platform_set_drvdata(pdev, wdt);
244
245 dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
246 wdt_timeout, nowayout);
247
248 return 0;
249}
250
251static int sama5d4_wdt_remove(struct platform_device *pdev)
252{
253 struct sama5d4_wdt *wdt = platform_get_drvdata(pdev);
254
255 sama5d4_wdt_stop(&wdt->wdd);
256
257 watchdog_unregister_device(&wdt->wdd);
258
259 return 0;
260}
261
262static const struct of_device_id sama5d4_wdt_of_match[] = {
263 { .compatible = "atmel,sama5d4-wdt", },
264 { }
265};
266MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
267
268static struct platform_driver sama5d4_wdt_driver = {
269 .probe = sama5d4_wdt_probe,
270 .remove = sama5d4_wdt_remove,
271 .driver = {
272 .name = "sama5d4_wdt",
273 .of_match_table = sama5d4_wdt_of_match,
274 }
275};
276module_platform_driver(sama5d4_wdt_driver);
277
278MODULE_AUTHOR("Atmel Corporation");
279MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
280MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 567458b137a6..f90812170657 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -252,6 +252,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
252 252
253 watchdog_set_nowayout(&sh_wdt_dev, nowayout); 253 watchdog_set_nowayout(&sh_wdt_dev, nowayout);
254 watchdog_set_drvdata(&sh_wdt_dev, wdt); 254 watchdog_set_drvdata(&sh_wdt_dev, wdt);
255 sh_wdt_dev.parent = &pdev->dev;
255 256
256 spin_lock_init(&wdt->lock); 257 spin_lock_init(&wdt->lock);
257 258
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index 42fa5c0c518a..d0578ab2e636 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -154,6 +154,7 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
154 154
155 watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev); 155 watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
156 watchdog_set_nowayout(&sirfsoc_wdd, nowayout); 156 watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
157 sirfsoc_wdd.parent = &pdev->dev;
157 158
158 ret = watchdog_register_device(&sirfsoc_wdd); 159 ret = watchdog_register_device(&sirfsoc_wdd);
159 if (ret) 160 if (ret)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 4e7fec36f5c3..01d816251302 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -226,6 +226,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
226 wdt->adev = adev; 226 wdt->adev = adev;
227 wdt->wdd.info = &wdt_info; 227 wdt->wdd.info = &wdt_info;
228 wdt->wdd.ops = &wdt_ops; 228 wdt->wdd.ops = &wdt_ops;
229 wdt->wdd.parent = &adev->dev;
229 230
230 spin_lock_init(&wdt->lock); 231 spin_lock_init(&wdt->lock);
231 watchdog_set_nowayout(&wdt->wdd, nowayout); 232 watchdog_set_nowayout(&wdt->wdd, nowayout);
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 6785afdc0fca..14e9badf2bfa 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
241 return -EINVAL; 241 return -EINVAL;
242 } 242 }
243 st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate; 243 st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
244 st_wdog_dev.parent = &pdev->dev;
244 245
245 ret = clk_prepare_enable(clk); 246 ret = clk_prepare_enable(clk);
246 if (ret) { 247 if (ret) {
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index e7f0d5b60d3d..3ee6128a540e 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -76,6 +76,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
76 watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev); 76 watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
77 77
78 stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT); 78 stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
79 stmp3xxx_wdd.parent = &pdev->dev;
79 80
80 ret = watchdog_register_device(&stmp3xxx_wdd); 81 ret = watchdog_register_device(&stmp3xxx_wdd);
81 if (ret < 0) { 82 if (ret < 0) {
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index a29afb37c48c..47bd8a14d01f 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -184,7 +184,7 @@ static int sunxi_wdt_start(struct watchdog_device *wdt_dev)
184 /* Set system reset function */ 184 /* Set system reset function */
185 reg = readl(wdt_base + regs->wdt_cfg); 185 reg = readl(wdt_base + regs->wdt_cfg);
186 reg &= ~(regs->wdt_reset_mask); 186 reg &= ~(regs->wdt_reset_mask);
187 reg |= ~(regs->wdt_reset_val); 187 reg |= regs->wdt_reset_val;
188 writel(reg, wdt_base + regs->wdt_cfg); 188 writel(reg, wdt_base + regs->wdt_cfg);
189 189
190 /* Enable watchdog */ 190 /* Enable watchdog */
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 30451ea46902..7f97cdd53f29 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
218 wdd->ops = &tegra_wdt_ops; 218 wdd->ops = &tegra_wdt_ops;
219 wdd->min_timeout = MIN_WDT_TIMEOUT; 219 wdd->min_timeout = MIN_WDT_TIMEOUT;
220 wdd->max_timeout = MAX_WDT_TIMEOUT; 220 wdd->max_timeout = MAX_WDT_TIMEOUT;
221 wdd->parent = &pdev->dev;
221 222
222 watchdog_set_drvdata(wdd, wdt); 223 watchdog_set_drvdata(wdd, wdt);
223 224
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 2c1db6fa9a27..9bf3cc0f3961 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -83,6 +83,7 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
83 wdt->timeout = 30; 83 wdt->timeout = 30;
84 wdt->min_timeout = 1; 84 wdt->min_timeout = 1;
85 wdt->max_timeout = 30; 85 wdt->max_timeout = 30;
86 wdt->parent = &pdev->dev;
86 87
87 watchdog_set_nowayout(wdt, nowayout); 88 watchdog_set_nowayout(wdt, nowayout);
88 platform_set_drvdata(pdev, wdt); 89 platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 7f615933d31a..c2da880292bc 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -131,6 +131,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
131 txx9wdt.timeout = timeout; 131 txx9wdt.timeout = timeout;
132 txx9wdt.min_timeout = 1; 132 txx9wdt.min_timeout = 1;
133 txx9wdt.max_timeout = WD_MAX_TIMEOUT; 133 txx9wdt.max_timeout = WD_MAX_TIMEOUT;
134 txx9wdt.parent = &dev->dev;
134 watchdog_set_nowayout(&txx9wdt, nowayout); 135 watchdog_set_nowayout(&txx9wdt, nowayout);
135 136
136 ret = watchdog_register_device(&txx9wdt); 137 ret = watchdog_register_device(&txx9wdt);
diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
index 9de09ab00838..37c084353cce 100644
--- a/drivers/watchdog/ux500_wdt.c
+++ b/drivers/watchdog/ux500_wdt.c
@@ -96,6 +96,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
96 ux500_wdt.max_timeout = WATCHDOG_MAX28; 96 ux500_wdt.max_timeout = WATCHDOG_MAX28;
97 } 97 }
98 98
99 ux500_wdt.parent = &pdev->dev;
99 watchdog_set_nowayout(&ux500_wdt, nowayout); 100 watchdog_set_nowayout(&ux500_wdt, nowayout);
100 101
101 /* disable auto off on sleep */ 102 /* disable auto off on sleep */
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 56369c4f1961..5f9cbc37520d 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -206,6 +206,7 @@ static int wdt_probe(struct pci_dev *pdev,
206 timeout = WDT_TIMEOUT; 206 timeout = WDT_TIMEOUT;
207 207
208 wdt_dev.timeout = timeout; 208 wdt_dev.timeout = timeout;
209 wdt_dev.parent = &pdev->dev;
209 watchdog_set_nowayout(&wdt_dev, nowayout); 210 watchdog_set_nowayout(&wdt_dev, nowayout);
210 if (readl(wdt_mem) & VIA_WDT_FIRED) 211 if (readl(wdt_mem) & VIA_WDT_FIRED)
211 wdt_dev.bootstatus |= WDIOF_CARDRESET; 212 wdt_dev.bootstatus |= WDIOF_CARDRESET;
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 2fa17e746ff6..8d1184aee932 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -215,6 +215,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
215 215
216 wm831x_wdt->info = &wm831x_wdt_info; 216 wm831x_wdt->info = &wm831x_wdt_info;
217 wm831x_wdt->ops = &wm831x_wdt_ops; 217 wm831x_wdt->ops = &wm831x_wdt_ops;
218 wm831x_wdt->parent = &pdev->dev;
218 watchdog_set_nowayout(wm831x_wdt, nowayout); 219 watchdog_set_nowayout(wm831x_wdt, nowayout);
219 watchdog_set_drvdata(wm831x_wdt, driver_data); 220 watchdog_set_drvdata(wm831x_wdt, driver_data);
220 221
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 34d272ada23d..4ab4b8347d45 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -151,6 +151,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
151 151
152 watchdog_set_nowayout(&wm8350_wdt, nowayout); 152 watchdog_set_nowayout(&wm8350_wdt, nowayout);
153 watchdog_set_drvdata(&wm8350_wdt, wm8350); 153 watchdog_set_drvdata(&wm8350_wdt, wm8350);
154 wm8350_wdt.parent = &pdev->dev;
154 155
155 /* Default to 4s timeout */ 156 /* Default to 4s timeout */
156 wm8350_wdt_set_timeout(&wm8350_wdt, 4); 157 wm8350_wdt_set_timeout(&wm8350_wdt, 4);