aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig34
-rw-r--r--drivers/watchdog/Makefile3
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c17
-rw-r--r--drivers/watchdog/bcm2835_wdt.c189
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c9
-rw-r--r--drivers/watchdog/cpwd.c4
-rw-r--r--drivers/watchdog/da9052_wdt.c4
-rw-r--r--drivers/watchdog/da9055_wdt.c4
-rw-r--r--drivers/watchdog/dw_wdt.c11
-rw-r--r--drivers/watchdog/hpwdt.c11
-rw-r--r--drivers/watchdog/imx2_wdt.c6
-rw-r--r--drivers/watchdog/jz4740_wdt.c2
-rw-r--r--drivers/watchdog/mena21_wdt.c270
-rw-r--r--drivers/watchdog/mpcore_wdt.c456
-rw-r--r--drivers/watchdog/mtx-1_wdt.c3
-rw-r--r--drivers/watchdog/mv64x60_wdt.c4
-rw-r--r--drivers/watchdog/nuc900_wdt.c50
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c31
-rw-r--r--drivers/watchdog/orion_wdt.c7
-rw-r--r--drivers/watchdog/pnx4008_wdt.c7
-rw-r--r--drivers/watchdog/rc32434_wdt.c10
-rw-r--r--drivers/watchdog/riowd.c12
-rw-r--r--drivers/watchdog/s3c2410_wdt.c20
-rw-r--r--drivers/watchdog/shwdt.c18
-rw-r--r--drivers/watchdog/softdog.c1
-rw-r--r--drivers/watchdog/sp805_wdt.c7
-rw-r--r--drivers/watchdog/ts72xx_wdt.c67
-rw-r--r--drivers/watchdog/twl4030_wdt.c5
-rw-r--r--drivers/watchdog/watchdog_dev.c6
-rw-r--r--drivers/watchdog/wdrtas.c29
-rw-r--r--drivers/watchdog/wm831x_wdt.c21
31 files changed, 592 insertions, 726 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7460d349df59..8519bc696a6f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -221,15 +221,6 @@ config DW_WATCHDOG
221 To compile this driver as a module, choose M here: the 221 To compile this driver as a module, choose M here: the
222 module will be called dw_wdt. 222 module will be called dw_wdt.
223 223
224config MPCORE_WATCHDOG
225 tristate "MPcore watchdog"
226 depends on HAVE_ARM_TWD
227 help
228 Watchdog timer embedded into the MPcore system.
229
230 To compile this driver as a module, choose M here: the
231 module will be called mpcore_wdt.
232
233config EP93XX_WATCHDOG 224config EP93XX_WATCHDOG
234 tristate "EP93xx Watchdog" 225 tristate "EP93xx Watchdog"
235 depends on ARCH_EP93XX 226 depends on ARCH_EP93XX
@@ -291,7 +282,7 @@ config DAVINCI_WATCHDOG
291 282
292config ORION_WATCHDOG 283config ORION_WATCHDOG
293 tristate "Orion watchdog" 284 tristate "Orion watchdog"
294 depends on ARCH_ORION5X || ARCH_KIRKWOOD 285 depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE
295 select WATCHDOG_CORE 286 select WATCHDOG_CORE
296 help 287 help
297 Say Y here if to include support for the watchdog timer 288 Say Y here if to include support for the watchdog timer
@@ -1109,6 +1100,17 @@ config BCM63XX_WDT
1109 To compile this driver as a loadable module, choose M here. 1100 To compile this driver as a loadable module, choose M here.
1110 The module will be called bcm63xx_wdt. 1101 The module will be called bcm63xx_wdt.
1111 1102
1103config BCM2835_WDT
1104 tristate "Broadcom BCM2835 hardware watchdog"
1105 depends on ARCH_BCM2835
1106 select WATCHDOG_CORE
1107 help
1108 Watchdog driver for the built in watchdog hardware in Broadcom
1109 BCM2835 SoC.
1110
1111 To compile this driver as a loadable module, choose M here.
1112 The module will be called bcm2835_wdt.
1113
1112config LANTIQ_WDT 1114config LANTIQ_WDT
1113 tristate "Lantiq SoC watchdog" 1115 tristate "Lantiq SoC watchdog"
1114 depends on LANTIQ 1116 depends on LANTIQ
@@ -1183,6 +1185,18 @@ config BOOKE_WDT_DEFAULT_TIMEOUT
1183 1185
1184 The value can be overridden by the wdt_period command-line parameter. 1186 The value can be overridden by the wdt_period command-line parameter.
1185 1187
1188config MEN_A21_WDT
1189 tristate "MEN A21 VME CPU Carrier Board Watchdog Timer"
1190 select WATCHDOG_CORE
1191 depends on GPIOLIB
1192 help
1193 Watchdog driver for MEN A21 VMEbus CPU Carrier Boards.
1194
1195 The driver can also be built as a module. If so, the module will be
1196 called mena21_wdt.
1197
1198 If unsure select N here.
1199
1186# PPC64 Architecture 1200# PPC64 Architecture
1187 1201
1188config WATCHDOG_RTAS 1202config WATCHDOG_RTAS
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ec268995b261..2f26a0b47ddc 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,7 +41,6 @@ obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
41obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o 41obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
42obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o 42obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
43obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o 43obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
44obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
45obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o 44obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
46obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o 45obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
47obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o 46obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
@@ -54,6 +53,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
54obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o 53obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
55obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o 54obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
56obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o 55obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
56obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
57 57
58# AVR32 Architecture 58# AVR32 Architecture
59obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 59obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -144,6 +144,7 @@ obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
144obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o 144obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
145obj-$(CONFIG_PIKA_WDT) += pika_wdt.o 145obj-$(CONFIG_PIKA_WDT) += pika_wdt.o
146obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o 146obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
147obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o
147 148
148# PPC64 Architecture 149# PPC64 Architecture
149obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o 150obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 7a715e3e6828..b178e717ef09 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -321,13 +321,14 @@ static int __init at32_wdt_probe(struct platform_device *pdev)
321 return -ENXIO; 321 return -ENXIO;
322 } 322 }
323 323
324 wdt = kzalloc(sizeof(struct wdt_at32ap700x), GFP_KERNEL); 324 wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x),
325 GFP_KERNEL);
325 if (!wdt) { 326 if (!wdt) {
326 dev_dbg(&pdev->dev, "no memory for wdt structure\n"); 327 dev_dbg(&pdev->dev, "no memory for wdt structure\n");
327 return -ENOMEM; 328 return -ENOMEM;
328 } 329 }
329 330
330 wdt->regs = ioremap(regs->start, resource_size(regs)); 331 wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
331 if (!wdt->regs) { 332 if (!wdt->regs) {
332 ret = -ENOMEM; 333 ret = -ENOMEM;
333 dev_dbg(&pdev->dev, "could not map I/O memory\n"); 334 dev_dbg(&pdev->dev, "could not map I/O memory\n");
@@ -342,7 +343,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev)
342 dev_info(&pdev->dev, "CPU must be reset with external " 343 dev_info(&pdev->dev, "CPU must be reset with external "
343 "reset or POR due to silicon errata.\n"); 344 "reset or POR due to silicon errata.\n");
344 ret = -EIO; 345 ret = -EIO;
345 goto err_iounmap; 346 goto err_free;
346 } else { 347 } else {
347 wdt->users = 0; 348 wdt->users = 0;
348 } 349 }
@@ -364,7 +365,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev)
364 ret = misc_register(&wdt->miscdev); 365 ret = misc_register(&wdt->miscdev);
365 if (ret) { 366 if (ret) {
366 dev_dbg(&pdev->dev, "failed to register wdt miscdev\n"); 367 dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
367 goto err_register; 368 goto err_free;
368 } 369 }
369 370
370 dev_info(&pdev->dev, 371 dev_info(&pdev->dev,
@@ -373,12 +374,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev)
373 374
374 return 0; 375 return 0;
375 376
376err_register:
377 platform_set_drvdata(pdev, NULL);
378err_iounmap:
379 iounmap(wdt->regs);
380err_free: 377err_free:
381 kfree(wdt);
382 wdt = NULL; 378 wdt = NULL;
383 return ret; 379 return ret;
384} 380}
@@ -391,10 +387,7 @@ static int __exit at32_wdt_remove(struct platform_device *pdev)
391 at32_wdt_stop(); 387 at32_wdt_stop();
392 388
393 misc_deregister(&wdt->miscdev); 389 misc_deregister(&wdt->miscdev);
394 iounmap(wdt->regs);
395 kfree(wdt);
396 wdt = NULL; 390 wdt = NULL;
397 platform_set_drvdata(pdev, NULL);
398 } 391 }
399 return 0; 392 return 0;
400} 393}
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
new file mode 100644
index 000000000000..61566fc47f84
--- /dev/null
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -0,0 +1,189 @@
1/*
2 * Watchdog driver for Broadcom BCM2835
3 *
4 * "bcm2708_wdog" driver written by Luke Diamand that was obtained from
5 * branch "rpi-3.6.y" of git://github.com/raspberrypi/linux.git was used
6 * as a hardware reference for the Broadcom BCM2835 watchdog timer.
7 *
8 * Copyright (C) 2013 Lubomir Rintel <lkundrak@v3.sk>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/types.h>
17#include <linux/module.h>
18#include <linux/io.h>
19#include <linux/watchdog.h>
20#include <linux/platform_device.h>
21#include <linux/of_address.h>
22#include <linux/miscdevice.h>
23
24#define PM_RSTC 0x1c
25#define PM_WDOG 0x24
26
27#define PM_PASSWORD 0x5a000000
28
29#define PM_WDOG_TIME_SET 0x000fffff
30#define PM_RSTC_WRCFG_CLR 0xffffffcf
31#define PM_RSTC_WRCFG_SET 0x00000030
32#define PM_RSTC_WRCFG_FULL_RESET 0x00000020
33#define PM_RSTC_RESET 0x00000102
34
35#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
36#define WDOG_TICKS_TO_SECS(x) ((x) >> 16)
37
38struct bcm2835_wdt {
39 void __iomem *base;
40 spinlock_t lock;
41};
42
43static unsigned int heartbeat;
44static bool nowayout = WATCHDOG_NOWAYOUT;
45
46static int bcm2835_wdt_start(struct watchdog_device *wdog)
47{
48 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
49 uint32_t cur;
50 unsigned long flags;
51
52 spin_lock_irqsave(&wdt->lock, flags);
53
54 writel_relaxed(PM_PASSWORD | (SECS_TO_WDOG_TICKS(wdog->timeout) &
55 PM_WDOG_TIME_SET), wdt->base + PM_WDOG);
56 cur = readl_relaxed(wdt->base + PM_RSTC);
57 writel_relaxed(PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) |
58 PM_RSTC_WRCFG_FULL_RESET, wdt->base + PM_RSTC);
59
60 spin_unlock_irqrestore(&wdt->lock, flags);
61
62 return 0;
63}
64
65static int bcm2835_wdt_stop(struct watchdog_device *wdog)
66{
67 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
68
69 writel_relaxed(PM_PASSWORD | PM_RSTC_RESET, wdt->base + PM_RSTC);
70 dev_info(wdog->dev, "Watchdog timer stopped");
71 return 0;
72}
73
74static int bcm2835_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t)
75{
76 wdog->timeout = t;
77 return 0;
78}
79
80static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
81{
82 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
83
84 uint32_t ret = readl_relaxed(wdt->base + PM_WDOG);
85 return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
86}
87
88static struct watchdog_ops bcm2835_wdt_ops = {
89 .owner = THIS_MODULE,
90 .start = bcm2835_wdt_start,
91 .stop = bcm2835_wdt_stop,
92 .set_timeout = bcm2835_wdt_set_timeout,
93 .get_timeleft = bcm2835_wdt_get_timeleft,
94};
95
96static struct watchdog_info bcm2835_wdt_info = {
97 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
98 WDIOF_KEEPALIVEPING,
99 .identity = "Broadcom BCM2835 Watchdog timer",
100};
101
102static struct watchdog_device bcm2835_wdt_wdd = {
103 .info = &bcm2835_wdt_info,
104 .ops = &bcm2835_wdt_ops,
105 .min_timeout = 1,
106 .max_timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
107 .timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
108};
109
110static int bcm2835_wdt_probe(struct platform_device *pdev)
111{
112 struct device *dev = &pdev->dev;
113 struct device_node *np = dev->of_node;
114 struct bcm2835_wdt *wdt;
115 int err;
116
117 wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL);
118 if (!wdt) {
119 dev_err(dev, "Failed to allocate memory for watchdog device");
120 return -ENOMEM;
121 }
122 platform_set_drvdata(pdev, wdt);
123
124 spin_lock_init(&wdt->lock);
125
126 wdt->base = of_iomap(np, 0);
127 if (!wdt->base) {
128 dev_err(dev, "Failed to remap watchdog regs");
129 return -ENODEV;
130 }
131
132 watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
133 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
134 watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
135 err = watchdog_register_device(&bcm2835_wdt_wdd);
136 if (err) {
137 dev_err(dev, "Failed to register watchdog device");
138 iounmap(wdt->base);
139 return err;
140 }
141
142 dev_info(dev, "Broadcom BCM2835 watchdog timer");
143 return 0;
144}
145
146static int bcm2835_wdt_remove(struct platform_device *pdev)
147{
148 struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
149
150 watchdog_unregister_device(&bcm2835_wdt_wdd);
151 iounmap(wdt->base);
152
153 return 0;
154}
155
156static void bcm2835_wdt_shutdown(struct platform_device *pdev)
157{
158 bcm2835_wdt_stop(&bcm2835_wdt_wdd);
159}
160
161static const struct of_device_id bcm2835_wdt_of_match[] = {
162 { .compatible = "brcm,bcm2835-pm-wdt", },
163 {},
164};
165MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match);
166
167static struct platform_driver bcm2835_wdt_driver = {
168 .probe = bcm2835_wdt_probe,
169 .remove = bcm2835_wdt_remove,
170 .shutdown = bcm2835_wdt_shutdown,
171 .driver = {
172 .name = "bcm2835-wdt",
173 .owner = THIS_MODULE,
174 .of_match_table = bcm2835_wdt_of_match,
175 },
176};
177module_platform_driver(bcm2835_wdt_driver);
178
179module_param(heartbeat, uint, 0);
180MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
181
182module_param(nowayout, bool, 0);
183MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
184 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
185
186MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
187MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer");
188MODULE_LICENSE("GPL");
189MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index b2b80d4ac818..a14a58d9d110 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -16,6 +16,7 @@
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/io.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
20#include <linux/miscdevice.h> 21#include <linux/miscdevice.h>
21#include <linux/module.h> 22#include <linux/module.h>
@@ -249,7 +250,8 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
249 return -ENODEV; 250 return -ENODEV;
250 } 251 }
251 252
252 bcm63xx_wdt_device.regs = ioremap_nocache(r->start, resource_size(r)); 253 bcm63xx_wdt_device.regs = devm_ioremap_nocache(&pdev->dev, r->start,
254 resource_size(r));
253 if (!bcm63xx_wdt_device.regs) { 255 if (!bcm63xx_wdt_device.regs) {
254 dev_err(&pdev->dev, "failed to remap I/O resources\n"); 256 dev_err(&pdev->dev, "failed to remap I/O resources\n");
255 return -ENXIO; 257 return -ENXIO;
@@ -258,7 +260,7 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
258 ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, NULL); 260 ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, NULL);
259 if (ret < 0) { 261 if (ret < 0) {
260 dev_err(&pdev->dev, "failed to register wdt timer isr\n"); 262 dev_err(&pdev->dev, "failed to register wdt timer isr\n");
261 goto unmap; 263 return ret;
262 } 264 }
263 265
264 if (bcm63xx_wdt_settimeout(wdt_time)) { 266 if (bcm63xx_wdt_settimeout(wdt_time)) {
@@ -281,8 +283,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
281 283
282unregister_timer: 284unregister_timer:
283 bcm63xx_timer_unregister(TIMER_WDT_ID); 285 bcm63xx_timer_unregister(TIMER_WDT_ID);
284unmap:
285 iounmap(bcm63xx_wdt_device.regs);
286 return ret; 286 return ret;
287} 287}
288 288
@@ -293,7 +293,6 @@ static int bcm63xx_wdt_remove(struct platform_device *pdev)
293 293
294 misc_deregister(&bcm63xx_wdt_miscdev); 294 misc_deregister(&bcm63xx_wdt_miscdev);
295 bcm63xx_timer_unregister(TIMER_WDT_ID); 295 bcm63xx_timer_unregister(TIMER_WDT_ID);
296 iounmap(bcm63xx_wdt_device.regs);
297 return 0; 296 return 0;
298} 297}
299 298
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 70387582843f..213225edd059 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -621,7 +621,7 @@ static int cpwd_probe(struct platform_device *op)
621 WD_BADMODEL); 621 WD_BADMODEL);
622 } 622 }
623 623
624 dev_set_drvdata(&op->dev, p); 624 platform_set_drvdata(op, p);
625 cpwd_device = p; 625 cpwd_device = p;
626 err = 0; 626 err = 0;
627 627
@@ -642,7 +642,7 @@ out_free:
642 642
643static int cpwd_remove(struct platform_device *op) 643static int cpwd_remove(struct platform_device *op)
644{ 644{
645 struct cpwd *p = dev_get_drvdata(&op->dev); 645 struct cpwd *p = platform_get_drvdata(op);
646 int i; 646 int i;
647 647
648 for (i = 0; i < WD_NUMDEVS; i++) { 648 for (i = 0; i < WD_NUMDEVS; i++) {
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 367445009c64..f09c54e9686f 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -215,14 +215,14 @@ static int da9052_wdt_probe(struct platform_device *pdev)
215 goto err; 215 goto err;
216 } 216 }
217 217
218 dev_set_drvdata(&pdev->dev, driver_data); 218 platform_set_drvdata(pdev, driver_data);
219err: 219err:
220 return ret; 220 return ret;
221} 221}
222 222
223static int da9052_wdt_remove(struct platform_device *pdev) 223static int da9052_wdt_remove(struct platform_device *pdev)
224{ 224{
225 struct da9052_wdt_data *driver_data = dev_get_drvdata(&pdev->dev); 225 struct da9052_wdt_data *driver_data = platform_get_drvdata(pdev);
226 226
227 watchdog_unregister_device(&driver_data->wdt); 227 watchdog_unregister_device(&driver_data->wdt);
228 kref_put(&driver_data->kref, da9052_wdt_release_resources); 228 kref_put(&driver_data->kref, da9052_wdt_release_resources);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index f5ad10546fc9..575f37a965a4 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -174,7 +174,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
174 goto err; 174 goto err;
175 } 175 }
176 176
177 dev_set_drvdata(&pdev->dev, driver_data); 177 platform_set_drvdata(pdev, driver_data);
178 178
179 ret = watchdog_register_device(&driver_data->wdt); 179 ret = watchdog_register_device(&driver_data->wdt);
180 if (ret != 0) 180 if (ret != 0)
@@ -187,7 +187,7 @@ err:
187 187
188static int da9055_wdt_remove(struct platform_device *pdev) 188static int da9055_wdt_remove(struct platform_device *pdev)
189{ 189{
190 struct da9055_wdt_data *driver_data = dev_get_drvdata(&pdev->dev); 190 struct da9055_wdt_data *driver_data = platform_get_drvdata(pdev);
191 191
192 watchdog_unregister_device(&driver_data->wdt); 192 watchdog_unregister_device(&driver_data->wdt);
193 kref_put(&driver_data->kref, da9055_wdt_release_resources); 193 kref_put(&driver_data->kref, da9055_wdt_release_resources);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 203766989382..e621098bf663 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -154,8 +154,8 @@ static int dw_wdt_open(struct inode *inode, struct file *filp)
154 return nonseekable_open(inode, filp); 154 return nonseekable_open(inode, filp);
155} 155}
156 156
157ssize_t dw_wdt_write(struct file *filp, const char __user *buf, size_t len, 157static ssize_t dw_wdt_write(struct file *filp, const char __user *buf,
158 loff_t *offset) 158 size_t len, loff_t *offset)
159{ 159{
160 if (!len) 160 if (!len)
161 return 0; 161 return 0;
@@ -305,13 +305,13 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
305 if (IS_ERR(dw_wdt.regs)) 305 if (IS_ERR(dw_wdt.regs))
306 return PTR_ERR(dw_wdt.regs); 306 return PTR_ERR(dw_wdt.regs);
307 307
308 dw_wdt.clk = clk_get(&pdev->dev, NULL); 308 dw_wdt.clk = devm_clk_get(&pdev->dev, NULL);
309 if (IS_ERR(dw_wdt.clk)) 309 if (IS_ERR(dw_wdt.clk))
310 return PTR_ERR(dw_wdt.clk); 310 return PTR_ERR(dw_wdt.clk);
311 311
312 ret = clk_enable(dw_wdt.clk); 312 ret = clk_enable(dw_wdt.clk);
313 if (ret) 313 if (ret)
314 goto out_put_clk; 314 return ret;
315 315
316 spin_lock_init(&dw_wdt.lock); 316 spin_lock_init(&dw_wdt.lock);
317 317
@@ -327,8 +327,6 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
327 327
328out_disable_clk: 328out_disable_clk:
329 clk_disable(dw_wdt.clk); 329 clk_disable(dw_wdt.clk);
330out_put_clk:
331 clk_put(dw_wdt.clk);
332 330
333 return ret; 331 return ret;
334} 332}
@@ -338,7 +336,6 @@ static int dw_wdt_drv_remove(struct platform_device *pdev)
338 misc_deregister(&dw_wdt_miscdev); 336 misc_deregister(&dw_wdt_miscdev);
339 337
340 clk_disable(dw_wdt.clk); 338 clk_disable(dw_wdt.clk);
341 clk_put(dw_wdt.clk);
342 339
343 return 0; 340 return 0;
344} 341}
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 11796b9b864e..de7e4f497222 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,7 +39,7 @@
39#endif /* CONFIG_HPWDT_NMI_DECODING */ 39#endif /* CONFIG_HPWDT_NMI_DECODING */
40#include <asm/nmi.h> 40#include <asm/nmi.h>
41 41
42#define HPWDT_VERSION "1.3.1" 42#define HPWDT_VERSION "1.3.2"
43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) 43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) 44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) 45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535)
@@ -148,6 +148,7 @@ struct cmn_registers {
148static unsigned int hpwdt_nmi_decoding; 148static unsigned int hpwdt_nmi_decoding;
149static unsigned int allow_kdump = 1; 149static unsigned int allow_kdump = 1;
150static unsigned int is_icru; 150static unsigned int is_icru;
151static unsigned int is_uefi;
151static DEFINE_SPINLOCK(rom_lock); 152static DEFINE_SPINLOCK(rom_lock);
152static void *cru_rom_addr; 153static void *cru_rom_addr;
153static struct cmn_registers cmn_regs; 154static struct cmn_registers cmn_regs;
@@ -484,7 +485,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
484 goto out; 485 goto out;
485 486
486 spin_lock_irqsave(&rom_lock, rom_pl); 487 spin_lock_irqsave(&rom_lock, rom_pl);
487 if (!die_nmi_called && !is_icru) 488 if (!die_nmi_called && !is_icru && !is_uefi)
488 asminline_call(&cmn_regs, cru_rom_addr); 489 asminline_call(&cmn_regs, cru_rom_addr);
489 die_nmi_called = 1; 490 die_nmi_called = 1;
490 spin_unlock_irqrestore(&rom_lock, rom_pl); 491 spin_unlock_irqrestore(&rom_lock, rom_pl);
@@ -492,7 +493,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
492 if (allow_kdump) 493 if (allow_kdump)
493 hpwdt_stop(); 494 hpwdt_stop();
494 495
495 if (!is_icru) { 496 if (!is_icru && !is_uefi) {
496 if (cmn_regs.u1.ral == 0) { 497 if (cmn_regs.u1.ral == 0) {
497 panic("An NMI occurred, " 498 panic("An NMI occurred, "
498 "but unable to determine source.\n"); 499 "but unable to determine source.\n");
@@ -679,6 +680,8 @@ static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
679 smbios_proliant_ptr = (struct smbios_proliant_info *) dm; 680 smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
680 if (smbios_proliant_ptr->misc_features & 0x01) 681 if (smbios_proliant_ptr->misc_features & 0x01)
681 is_icru = 1; 682 is_icru = 1;
683 if (smbios_proliant_ptr->misc_features & 0x408)
684 is_uefi = 1;
682 } 685 }
683} 686}
684 687
@@ -697,7 +700,7 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
697 * the old cru detect code. 700 * the old cru detect code.
698 */ 701 */
699 dmi_walk(dmi_find_icru, NULL); 702 dmi_walk(dmi_find_icru, NULL);
700 if (!is_icru) { 703 if (!is_icru && !is_uefi) {
701 704
702 /* 705 /*
703 * We need to map the ROM to get the CRU service. 706 * We need to map the ROM to get the CRU service.
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 62946c2cb4f8..693ac3f4de5a 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -261,7 +261,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
261 if (IS_ERR(imx2_wdt.base)) 261 if (IS_ERR(imx2_wdt.base))
262 return PTR_ERR(imx2_wdt.base); 262 return PTR_ERR(imx2_wdt.base);
263 263
264 imx2_wdt.clk = clk_get(&pdev->dev, NULL); 264 imx2_wdt.clk = devm_clk_get(&pdev->dev, NULL);
265 if (IS_ERR(imx2_wdt.clk)) { 265 if (IS_ERR(imx2_wdt.clk)) {
266 dev_err(&pdev->dev, "can't get Watchdog clock\n"); 266 dev_err(&pdev->dev, "can't get Watchdog clock\n");
267 return PTR_ERR(imx2_wdt.clk); 267 return PTR_ERR(imx2_wdt.clk);
@@ -286,7 +286,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
286 286
287fail: 287fail:
288 imx2_wdt_miscdev.parent = NULL; 288 imx2_wdt_miscdev.parent = NULL;
289 clk_put(imx2_wdt.clk);
290 return ret; 289 return ret;
291} 290}
292 291
@@ -299,8 +298,7 @@ static int __exit imx2_wdt_remove(struct platform_device *pdev)
299 298
300 dev_crit(imx2_wdt_miscdev.parent, 299 dev_crit(imx2_wdt_miscdev.parent,
301 "Device removed: Expect reboot!\n"); 300 "Device removed: Expect reboot!\n");
302 } else 301 }
303 clk_put(imx2_wdt.clk);
304 302
305 imx2_wdt_miscdev.parent = NULL; 303 imx2_wdt_miscdev.parent = NULL;
306 return 0; 304 return 0;
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 1cb25f69a96d..d1afdf684c18 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -177,7 +177,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
177 goto err_out; 177 goto err_out;
178 } 178 }
179 179
180 drvdata->rtc_clk = clk_get(NULL, "rtc"); 180 drvdata->rtc_clk = clk_get(&pdev->dev, "rtc");
181 if (IS_ERR(drvdata->rtc_clk)) { 181 if (IS_ERR(drvdata->rtc_clk)) {
182 dev_err(&pdev->dev, "cannot find RTC clock\n"); 182 dev_err(&pdev->dev, "cannot find RTC clock\n");
183 ret = PTR_ERR(drvdata->rtc_clk); 183 ret = PTR_ERR(drvdata->rtc_clk);
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
new file mode 100644
index 000000000000..96dbba980579
--- /dev/null
+++ b/drivers/watchdog/mena21_wdt.c
@@ -0,0 +1,270 @@
1/*
2 * Watchdog driver for the A21 VME CPU Boards
3 *
4 * Copyright (C) 2013 MEN Mikro Elektronik Nuernberg GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation
9 */
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/types.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <linux/watchdog.h>
17#include <linux/uaccess.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <linux/delay.h>
21#include <linux/bitops.h>
22
23#define NUM_GPIOS 6
24
25enum a21_wdt_gpios {
26 GPIO_WD_ENAB,
27 GPIO_WD_FAST,
28 GPIO_WD_TRIG,
29 GPIO_WD_RST0,
30 GPIO_WD_RST1,
31 GPIO_WD_RST2,
32};
33
34struct a21_wdt_drv {
35 struct watchdog_device wdt;
36 struct mutex lock;
37 unsigned gpios[NUM_GPIOS];
38};
39
40static bool nowayout = WATCHDOG_NOWAYOUT;
41module_param(nowayout, bool, 0);
42MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
43 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44
45static unsigned int a21_wdt_get_bootstatus(struct a21_wdt_drv *drv)
46{
47 int reset = 0;
48
49 reset |= gpio_get_value(drv->gpios[GPIO_WD_RST0]) ? (1 << 0) : 0;
50 reset |= gpio_get_value(drv->gpios[GPIO_WD_RST1]) ? (1 << 1) : 0;
51 reset |= gpio_get_value(drv->gpios[GPIO_WD_RST2]) ? (1 << 2) : 0;
52
53 return reset;
54}
55
56static int a21_wdt_start(struct watchdog_device *wdt)
57{
58 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt);
59
60 mutex_lock(&drv->lock);
61
62 gpio_set_value(drv->gpios[GPIO_WD_ENAB], 1);
63
64 mutex_unlock(&drv->lock);
65
66 return 0;
67}
68
69static int a21_wdt_stop(struct watchdog_device *wdt)
70{
71 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt);
72
73 mutex_lock(&drv->lock);
74
75 gpio_set_value(drv->gpios[GPIO_WD_ENAB], 0);
76
77 mutex_unlock(&drv->lock);
78
79 return 0;
80}
81
82static int a21_wdt_ping(struct watchdog_device *wdt)
83{
84 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt);
85
86 mutex_lock(&drv->lock);
87
88 gpio_set_value(drv->gpios[GPIO_WD_TRIG], 0);
89 ndelay(10);
90 gpio_set_value(drv->gpios[GPIO_WD_TRIG], 1);
91
92 mutex_unlock(&drv->lock);
93
94 return 0;
95}
96
97static int a21_wdt_set_timeout(struct watchdog_device *wdt,
98 unsigned int timeout)
99{
100 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt);
101
102 if (timeout != 1 && timeout != 30) {
103 dev_err(wdt->dev, "Only 1 and 30 allowed as timeout\n");
104 return -EINVAL;
105 }
106
107 if (timeout == 30 && wdt->timeout == 1) {
108 dev_err(wdt->dev,
109 "Transition from fast to slow mode not allowed\n");
110 return -EINVAL;
111 }
112
113 mutex_lock(&drv->lock);
114
115 if (timeout == 1)
116 gpio_set_value(drv->gpios[GPIO_WD_FAST], 1);
117 else
118 gpio_set_value(drv->gpios[GPIO_WD_FAST], 0);
119
120 wdt->timeout = timeout;
121
122 mutex_unlock(&drv->lock);
123
124 return 0;
125}
126
127static const struct watchdog_info a21_wdt_info = {
128 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
129 .identity = "MEN A21 Watchdog",
130};
131
132static const struct watchdog_ops a21_wdt_ops = {
133 .owner = THIS_MODULE,
134 .start = a21_wdt_start,
135 .stop = a21_wdt_stop,
136 .ping = a21_wdt_ping,
137 .set_timeout = a21_wdt_set_timeout,
138};
139
140static struct watchdog_device a21_wdt = {
141 .info = &a21_wdt_info,
142 .ops = &a21_wdt_ops,
143 .min_timeout = 1,
144 .max_timeout = 30,
145};
146
147static int a21_wdt_probe(struct platform_device *pdev)
148{
149 struct device_node *node;
150 struct a21_wdt_drv *drv;
151 unsigned int reset = 0;
152 int num_gpios;
153 int ret;
154 int i;
155
156 drv = devm_kzalloc(&pdev->dev, sizeof(struct a21_wdt_drv), GFP_KERNEL);
157 if (!drv)
158 return -ENOMEM;
159
160 /* Fill GPIO pin array */
161 node = pdev->dev.of_node;
162
163 num_gpios = of_gpio_count(node);
164 if (num_gpios != NUM_GPIOS) {
165 dev_err(&pdev->dev, "gpios DT property wrong, got %d want %d",
166 num_gpios, NUM_GPIOS);
167 return -ENODEV;
168 }
169
170 for (i = 0; i < num_gpios; i++) {
171 int val;
172
173 val = of_get_gpio(node, i);
174 if (val < 0)
175 return val;
176
177 drv->gpios[i] = val;
178 }
179
180 /* Request the used GPIOs */
181 for (i = 0; i < num_gpios; i++) {
182 ret = devm_gpio_request(&pdev->dev, drv->gpios[i],
183 "MEN A21 Watchdog");
184 if (ret)
185 return ret;
186
187 if (i < GPIO_WD_RST0)
188 ret = gpio_direction_output(drv->gpios[i],
189 gpio_get_value(drv->gpios[i]));
190 else /* GPIO_WD_RST[0..2] are inputs */
191 ret = gpio_direction_input(drv->gpios[i]);
192 if (ret)
193 return ret;
194 }
195
196 mutex_init(&drv->lock);
197 watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
198 watchdog_set_nowayout(&a21_wdt, nowayout);
199 watchdog_set_drvdata(&a21_wdt, drv);
200
201 reset = a21_wdt_get_bootstatus(drv);
202 if (reset == 2)
203 a21_wdt.bootstatus |= WDIOF_EXTERN1;
204 else if (reset == 4)
205 a21_wdt.bootstatus |= WDIOF_CARDRESET;
206 else if (reset == 5)
207 a21_wdt.bootstatus |= WDIOF_POWERUNDER;
208 else if (reset == 7)
209 a21_wdt.bootstatus |= WDIOF_EXTERN2;
210
211 ret = watchdog_register_device(&a21_wdt);
212 if (ret) {
213 dev_err(&pdev->dev, "Cannot register watchdog device\n");
214 goto err_register_wd;
215 }
216
217 dev_set_drvdata(&pdev->dev, drv);
218
219 dev_info(&pdev->dev, "MEN A21 watchdog timer driver enabled\n");
220
221 return 0;
222
223err_register_wd:
224 mutex_destroy(&drv->lock);
225
226 return ret;
227}
228
229static int a21_wdt_remove(struct platform_device *pdev)
230{
231 struct a21_wdt_drv *drv = dev_get_drvdata(&pdev->dev);
232
233 dev_warn(&pdev->dev,
234 "Unregistering A21 watchdog driver, board may reboot\n");
235
236 watchdog_unregister_device(&drv->wdt);
237
238 mutex_destroy(&drv->lock);
239
240 return 0;
241}
242
243static void a21_wdt_shutdown(struct platform_device *pdev)
244{
245 struct a21_wdt_drv *drv = dev_get_drvdata(&pdev->dev);
246
247 gpio_set_value(drv->gpios[GPIO_WD_ENAB], 0);
248}
249
250static const struct of_device_id a21_wdt_ids[] = {
251 { .compatible = "men,a021-wdt" },
252 { },
253};
254
255static struct platform_driver a21_wdt_driver = {
256 .probe = a21_wdt_probe,
257 .remove = a21_wdt_remove,
258 .shutdown = a21_wdt_shutdown,
259 .driver = {
260 .name = "a21-watchdog",
261 .of_match_table = a21_wdt_ids,
262 },
263};
264
265module_platform_driver(a21_wdt_driver);
266
267MODULE_AUTHOR("MEN Mikro Elektronik");
268MODULE_DESCRIPTION("MEN A21 Watchdog");
269MODULE_LICENSE("GPL");
270MODULE_ALIAS("platform:a21-watchdog");
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
deleted file mode 100644
index 233cfadcb21f..000000000000
--- a/drivers/watchdog/mpcore_wdt.c
+++ /dev/null
@@ -1,456 +0,0 @@
1/*
2 * Watchdog driver for the mpcore watchdog timer
3 *
4 * (c) Copyright 2004 ARM Limited
5 *
6 * Based on the SoftDog driver:
7 * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
8 * All Rights Reserved.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
16 * warranty for any of this software. This material is provided
17 * "AS-IS" and at no charge.
18 *
19 * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
20 *
21 */
22
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/types.h>
28#include <linux/miscdevice.h>
29#include <linux/watchdog.h>
30#include <linux/fs.h>
31#include <linux/reboot.h>
32#include <linux/init.h>
33#include <linux/interrupt.h>
34#include <linux/platform_device.h>
35#include <linux/uaccess.h>
36#include <linux/slab.h>
37#include <linux/io.h>
38
39#include <asm/smp_twd.h>
40
41struct mpcore_wdt {
42 unsigned long timer_alive;
43 struct device *dev;
44 void __iomem *base;
45 int irq;
46 unsigned int perturb;
47 char expect_close;
48};
49
50static struct platform_device *mpcore_wdt_pdev;
51static DEFINE_SPINLOCK(wdt_lock);
52
53#define TIMER_MARGIN 60
54static int mpcore_margin = TIMER_MARGIN;
55module_param(mpcore_margin, int, 0);
56MODULE_PARM_DESC(mpcore_margin,
57 "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default="
58 __MODULE_STRING(TIMER_MARGIN) ")");
59
60static bool nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, bool, 0);
62MODULE_PARM_DESC(nowayout,
63 "Watchdog cannot be stopped once started (default="
64 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65
66#define ONLY_TESTING 0
67static int mpcore_noboot = ONLY_TESTING;
68module_param(mpcore_noboot, int, 0);
69MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
70 "set to 1 to ignore reboots, 0 to reboot (default="
71 __MODULE_STRING(ONLY_TESTING) ")");
72
73/*
74 * This is the interrupt handler. Note that we only use this
75 * in testing mode, so don't actually do a reboot here.
76 */
77static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
78{
79 struct mpcore_wdt *wdt = arg;
80
81 /* Check it really was our interrupt */
82 if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
83 dev_crit(wdt->dev, "Triggered - Reboot ignored\n");
84 /* Clear the interrupt on the watchdog */
85 writel(1, wdt->base + TWD_WDOG_INTSTAT);
86 return IRQ_HANDLED;
87 }
88 return IRQ_NONE;
89}
90
91/*
92 * mpcore_wdt_keepalive - reload the timer
93 *
94 * Note that the spec says a DIFFERENT value must be written to the reload
95 * register each time. The "perturb" variable deals with this by adding 1
96 * to the count every other time the function is called.
97 */
98static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
99{
100 unsigned long count;
101
102 spin_lock(&wdt_lock);
103 /* Assume prescale is set to 256 */
104 count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
105 count = (0xFFFFFFFFU - count) * (HZ / 5);
106 count = (count / 256) * mpcore_margin;
107
108 /* Reload the counter */
109 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
110 wdt->perturb = wdt->perturb ? 0 : 1;
111 spin_unlock(&wdt_lock);
112}
113
114static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
115{
116 spin_lock(&wdt_lock);
117 writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
118 writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
119 writel(0x0, wdt->base + TWD_WDOG_CONTROL);
120 spin_unlock(&wdt_lock);
121}
122
123static void mpcore_wdt_start(struct mpcore_wdt *wdt)
124{
125 dev_info(wdt->dev, "enabling watchdog\n");
126
127 /* This loads the count register but does NOT start the count yet */
128 mpcore_wdt_keepalive(wdt);
129
130 if (mpcore_noboot) {
131 /* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
132 writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
133 } else {
134 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
135 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
136 }
137}
138
139static int mpcore_wdt_set_heartbeat(int t)
140{
141 if (t < 0x0001 || t > 0xFFFF)
142 return -EINVAL;
143
144 mpcore_margin = t;
145 return 0;
146}
147
148/*
149 * /dev/watchdog handling
150 */
151static int mpcore_wdt_open(struct inode *inode, struct file *file)
152{
153 struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_pdev);
154
155 if (test_and_set_bit(0, &wdt->timer_alive))
156 return -EBUSY;
157
158 if (nowayout)
159 __module_get(THIS_MODULE);
160
161 file->private_data = wdt;
162
163 /*
164 * Activate timer
165 */
166 mpcore_wdt_start(wdt);
167
168 return nonseekable_open(inode, file);
169}
170
171static int mpcore_wdt_release(struct inode *inode, struct file *file)
172{
173 struct mpcore_wdt *wdt = file->private_data;
174
175 /*
176 * Shut off the timer.
177 * Lock it in if it's a module and we set nowayout
178 */
179 if (wdt->expect_close == 42)
180 mpcore_wdt_stop(wdt);
181 else {
182 dev_crit(wdt->dev,
183 "unexpected close, not stopping watchdog!\n");
184 mpcore_wdt_keepalive(wdt);
185 }
186 clear_bit(0, &wdt->timer_alive);
187 wdt->expect_close = 0;
188 return 0;
189}
190
191static ssize_t mpcore_wdt_write(struct file *file, const char *data,
192 size_t len, loff_t *ppos)
193{
194 struct mpcore_wdt *wdt = file->private_data;
195
196 /*
197 * Refresh the timer.
198 */
199 if (len) {
200 if (!nowayout) {
201 size_t i;
202
203 /* In case it was set long ago */
204 wdt->expect_close = 0;
205
206 for (i = 0; i != len; i++) {
207 char c;
208
209 if (get_user(c, data + i))
210 return -EFAULT;
211 if (c == 'V')
212 wdt->expect_close = 42;
213 }
214 }
215 mpcore_wdt_keepalive(wdt);
216 }
217 return len;
218}
219
220static const struct watchdog_info ident = {
221 .options = WDIOF_SETTIMEOUT |
222 WDIOF_KEEPALIVEPING |
223 WDIOF_MAGICCLOSE,
224 .identity = "MPcore Watchdog",
225};
226
227static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
228 unsigned long arg)
229{
230 struct mpcore_wdt *wdt = file->private_data;
231 int ret;
232 union {
233 struct watchdog_info ident;
234 int i;
235 } uarg;
236
237 if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
238 return -ENOTTY;
239
240 if (_IOC_DIR(cmd) & _IOC_WRITE) {
241 ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
242 if (ret)
243 return -EFAULT;
244 }
245
246 switch (cmd) {
247 case WDIOC_GETSUPPORT:
248 uarg.ident = ident;
249 ret = 0;
250 break;
251
252 case WDIOC_GETSTATUS:
253 case WDIOC_GETBOOTSTATUS:
254 uarg.i = 0;
255 ret = 0;
256 break;
257
258 case WDIOC_SETOPTIONS:
259 ret = -EINVAL;
260 if (uarg.i & WDIOS_DISABLECARD) {
261 mpcore_wdt_stop(wdt);
262 ret = 0;
263 }
264 if (uarg.i & WDIOS_ENABLECARD) {
265 mpcore_wdt_start(wdt);
266 ret = 0;
267 }
268 break;
269
270 case WDIOC_KEEPALIVE:
271 mpcore_wdt_keepalive(wdt);
272 ret = 0;
273 break;
274
275 case WDIOC_SETTIMEOUT:
276 ret = mpcore_wdt_set_heartbeat(uarg.i);
277 if (ret)
278 break;
279
280 mpcore_wdt_keepalive(wdt);
281 /* Fall */
282 case WDIOC_GETTIMEOUT:
283 uarg.i = mpcore_margin;
284 ret = 0;
285 break;
286
287 default:
288 return -ENOTTY;
289 }
290
291 if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
292 ret = copy_to_user((void __user *)arg, &uarg, _IOC_SIZE(cmd));
293 if (ret)
294 ret = -EFAULT;
295 }
296 return ret;
297}
298
299/*
300 * System shutdown handler. Turn off the watchdog if we're
301 * restarting or halting the system.
302 */
303static void mpcore_wdt_shutdown(struct platform_device *pdev)
304{
305 struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
306
307 if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
308 mpcore_wdt_stop(wdt);
309}
310
311/*
312 * Kernel Interfaces
313 */
314static const struct file_operations mpcore_wdt_fops = {
315 .owner = THIS_MODULE,
316 .llseek = no_llseek,
317 .write = mpcore_wdt_write,
318 .unlocked_ioctl = mpcore_wdt_ioctl,
319 .open = mpcore_wdt_open,
320 .release = mpcore_wdt_release,
321};
322
323static struct miscdevice mpcore_wdt_miscdev = {
324 .minor = WATCHDOG_MINOR,
325 .name = "watchdog",
326 .fops = &mpcore_wdt_fops,
327};
328
329static int mpcore_wdt_probe(struct platform_device *pdev)
330{
331 struct mpcore_wdt *wdt;
332 struct resource *res;
333 int ret;
334
335 /* We only accept one device, and it must have an id of -1 */
336 if (pdev->id != -1)
337 return -ENODEV;
338
339 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
340 if (!res)
341 return -ENODEV;
342
343 wdt = devm_kzalloc(&pdev->dev, sizeof(struct mpcore_wdt), GFP_KERNEL);
344 if (!wdt)
345 return -ENOMEM;
346
347 wdt->dev = &pdev->dev;
348 wdt->irq = platform_get_irq(pdev, 0);
349 if (wdt->irq >= 0) {
350 ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
351 "mpcore_wdt", wdt);
352 if (ret) {
353 dev_err(wdt->dev,
354 "cannot register IRQ%d for watchdog\n",
355 wdt->irq);
356 return ret;
357 }
358 }
359
360 wdt->base = devm_ioremap(wdt->dev, res->start, resource_size(res));
361 if (!wdt->base)
362 return -ENOMEM;
363
364 mpcore_wdt_miscdev.parent = &pdev->dev;
365 ret = misc_register(&mpcore_wdt_miscdev);
366 if (ret) {
367 dev_err(wdt->dev,
368 "cannot register miscdev on minor=%d (err=%d)\n",
369 WATCHDOG_MINOR, ret);
370 return ret;
371 }
372
373 mpcore_wdt_stop(wdt);
374 platform_set_drvdata(pdev, wdt);
375 mpcore_wdt_pdev = pdev;
376
377 return 0;
378}
379
380static int mpcore_wdt_remove(struct platform_device *pdev)
381{
382 platform_set_drvdata(pdev, NULL);
383
384 misc_deregister(&mpcore_wdt_miscdev);
385
386 mpcore_wdt_pdev = NULL;
387
388 return 0;
389}
390
391#ifdef CONFIG_PM
392static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
393{
394 struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
395 mpcore_wdt_stop(wdt); /* Turn the WDT off */
396 return 0;
397}
398
399static int mpcore_wdt_resume(struct platform_device *pdev)
400{
401 struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
402 /* re-activate timer */
403 if (test_bit(0, &wdt->timer_alive))
404 mpcore_wdt_start(wdt);
405 return 0;
406}
407#else
408#define mpcore_wdt_suspend NULL
409#define mpcore_wdt_resume NULL
410#endif
411
412/* work with hotplug and coldplug */
413MODULE_ALIAS("platform:mpcore_wdt");
414
415static struct platform_driver mpcore_wdt_driver = {
416 .probe = mpcore_wdt_probe,
417 .remove = mpcore_wdt_remove,
418 .suspend = mpcore_wdt_suspend,
419 .resume = mpcore_wdt_resume,
420 .shutdown = mpcore_wdt_shutdown,
421 .driver = {
422 .owner = THIS_MODULE,
423 .name = "mpcore_wdt",
424 },
425};
426
427static int __init mpcore_wdt_init(void)
428{
429 /*
430 * Check that the margin value is within it's range;
431 * if not reset to the default
432 */
433 if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
434 mpcore_wdt_set_heartbeat(TIMER_MARGIN);
435 pr_info("mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
436 TIMER_MARGIN);
437 }
438
439 pr_info("MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n",
440 mpcore_noboot, mpcore_margin, nowayout);
441
442 return platform_driver_register(&mpcore_wdt_driver);
443}
444
445static void __exit mpcore_wdt_exit(void)
446{
447 platform_driver_unregister(&mpcore_wdt_driver);
448}
449
450module_init(mpcore_wdt_init);
451module_exit(mpcore_wdt_exit);
452
453MODULE_AUTHOR("ARM Limited");
454MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
455MODULE_LICENSE("GPL");
456MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 14dab6ff87aa..b4341110ad4f 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -209,7 +209,7 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
209 int ret; 209 int ret;
210 210
211 mtx1_wdt_device.gpio = pdev->resource[0].start; 211 mtx1_wdt_device.gpio = pdev->resource[0].start;
212 ret = gpio_request_one(mtx1_wdt_device.gpio, 212 ret = devm_gpio_request_one(&pdev->dev, mtx1_wdt_device.gpio,
213 GPIOF_OUT_INIT_HIGH, "mtx1-wdt"); 213 GPIOF_OUT_INIT_HIGH, "mtx1-wdt");
214 if (ret < 0) { 214 if (ret < 0) {
215 dev_err(&pdev->dev, "failed to request gpio"); 215 dev_err(&pdev->dev, "failed to request gpio");
@@ -241,7 +241,6 @@ static int mtx1_wdt_remove(struct platform_device *pdev)
241 wait_for_completion(&mtx1_wdt_device.stop); 241 wait_for_completion(&mtx1_wdt_device.stop);
242 } 242 }
243 243
244 gpio_free(mtx1_wdt_device.gpio);
245 misc_deregister(&mtx1_wdt_misc); 244 misc_deregister(&mtx1_wdt_misc);
246 return 0; 245 return 0;
247} 246}
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index c7fb878ca493..e4cf98019265 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -276,7 +276,7 @@ static int mv64x60_wdt_probe(struct platform_device *dev)
276 if (!r) 276 if (!r)
277 return -ENODEV; 277 return -ENODEV;
278 278
279 mv64x60_wdt_regs = ioremap(r->start, resource_size(r)); 279 mv64x60_wdt_regs = devm_ioremap(&dev->dev, r->start, resource_size(r));
280 if (mv64x60_wdt_regs == NULL) 280 if (mv64x60_wdt_regs == NULL)
281 return -ENOMEM; 281 return -ENOMEM;
282 282
@@ -293,8 +293,6 @@ static int mv64x60_wdt_remove(struct platform_device *dev)
293 293
294 mv64x60_wdt_handler_disable(); 294 mv64x60_wdt_handler_disable();
295 295
296 iounmap(mv64x60_wdt_regs);
297
298 return 0; 296 return 0;
299} 297}
300 298
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index 04c45a102992..e2b6d2cf5c9d 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -61,7 +61,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
61 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 61 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
62 62
63struct nuc900_wdt { 63struct nuc900_wdt {
64 struct resource *res;
65 struct clk *wdt_clock; 64 struct clk *wdt_clock;
66 struct platform_device *pdev; 65 struct platform_device *pdev;
67 void __iomem *wdt_base; 66 void __iomem *wdt_base;
@@ -244,9 +243,11 @@ static struct miscdevice nuc900wdt_miscdev = {
244 243
245static int nuc900wdt_probe(struct platform_device *pdev) 244static int nuc900wdt_probe(struct platform_device *pdev)
246{ 245{
246 struct resource *res;
247 int ret = 0; 247 int ret = 0;
248 248
249 nuc900_wdt = kzalloc(sizeof(struct nuc900_wdt), GFP_KERNEL); 249 nuc900_wdt = devm_kzalloc(&pdev->dev, sizeof(*nuc900_wdt),
250 GFP_KERNEL);
250 if (!nuc900_wdt) 251 if (!nuc900_wdt)
251 return -ENOMEM; 252 return -ENOMEM;
252 253
@@ -254,33 +255,20 @@ static int nuc900wdt_probe(struct platform_device *pdev)
254 255
255 spin_lock_init(&nuc900_wdt->wdt_lock); 256 spin_lock_init(&nuc900_wdt->wdt_lock);
256 257
257 nuc900_wdt->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 258 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258 if (nuc900_wdt->res == NULL) { 259 if (res == NULL) {
259 dev_err(&pdev->dev, "no memory resource specified\n"); 260 dev_err(&pdev->dev, "no memory resource specified\n");
260 ret = -ENOENT; 261 return -ENOENT;
261 goto err_get;
262 } 262 }
263 263
264 if (!request_mem_region(nuc900_wdt->res->start, 264 nuc900_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
265 resource_size(nuc900_wdt->res), pdev->name)) { 265 if (IS_ERR(nuc900_wdt->wdt_base))
266 dev_err(&pdev->dev, "failed to get memory region\n"); 266 return PTR_ERR(nuc900_wdt->wdt_base);
267 ret = -ENOENT;
268 goto err_get;
269 }
270
271 nuc900_wdt->wdt_base = ioremap(nuc900_wdt->res->start,
272 resource_size(nuc900_wdt->res));
273 if (nuc900_wdt->wdt_base == NULL) {
274 dev_err(&pdev->dev, "failed to ioremap() region\n");
275 ret = -EINVAL;
276 goto err_req;
277 }
278 267
279 nuc900_wdt->wdt_clock = clk_get(&pdev->dev, NULL); 268 nuc900_wdt->wdt_clock = devm_clk_get(&pdev->dev, NULL);
280 if (IS_ERR(nuc900_wdt->wdt_clock)) { 269 if (IS_ERR(nuc900_wdt->wdt_clock)) {
281 dev_err(&pdev->dev, "failed to find watchdog clock source\n"); 270 dev_err(&pdev->dev, "failed to find watchdog clock source\n");
282 ret = PTR_ERR(nuc900_wdt->wdt_clock); 271 return PTR_ERR(nuc900_wdt->wdt_clock);
283 goto err_map;
284 } 272 }
285 273
286 clk_enable(nuc900_wdt->wdt_clock); 274 clk_enable(nuc900_wdt->wdt_clock);
@@ -298,14 +286,6 @@ static int nuc900wdt_probe(struct platform_device *pdev)
298 286
299err_clk: 287err_clk:
300 clk_disable(nuc900_wdt->wdt_clock); 288 clk_disable(nuc900_wdt->wdt_clock);
301 clk_put(nuc900_wdt->wdt_clock);
302err_map:
303 iounmap(nuc900_wdt->wdt_base);
304err_req:
305 release_mem_region(nuc900_wdt->res->start,
306 resource_size(nuc900_wdt->res));
307err_get:
308 kfree(nuc900_wdt);
309 return ret; 289 return ret;
310} 290}
311 291
@@ -314,14 +294,6 @@ static int nuc900wdt_remove(struct platform_device *pdev)
314 misc_deregister(&nuc900wdt_miscdev); 294 misc_deregister(&nuc900wdt_miscdev);
315 295
316 clk_disable(nuc900_wdt->wdt_clock); 296 clk_disable(nuc900_wdt->wdt_clock);
317 clk_put(nuc900_wdt->wdt_clock);
318
319 iounmap(nuc900_wdt->wdt_base);
320
321 release_mem_region(nuc900_wdt->res->start,
322 resource_size(nuc900_wdt->res));
323
324 kfree(nuc900_wdt);
325 297
326 return 0; 298 return 0;
327} 299}
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index 2761ddb08501..4dd281f2c33f 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -1,23 +1,13 @@
1/* 1/*
2* of_xilinx_wdt.c 1.01 A Watchdog Device Driver for Xilinx xps_timebase_wdt 2 * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt
3* 3 *
4* (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>) 4 * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>)
5* 5 *
6* ----------------------- 6 * This program is free software; you can redistribute it and/or
7* 7 * modify it under the terms of the GNU General Public License
8* This program is free software; you can redistribute it and/or 8 * as published by the Free Software Foundation; either version
9* modify it under the terms of the GNU General Public License 9 * 2 of the License, or (at your option) any later version.
10* as published by the Free Software Foundation; either version 10 */
11* 2 of the License, or (at your option) any later version.
12*
13* -----------------------
14* 30-May-2011 Alejandro Cabrera <aldaya@gmail.com>
15* - If "xlnx,wdt-enable-once" wasn't found on device tree the
16* module will use CONFIG_WATCHDOG_NOWAYOUT
17* - If the device tree parameters ("clock-frequency" and
18* "xlnx,wdt-interval") wasn't found the driver won't
19* know the wdt reset interval
20*/
21 11
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 13
@@ -394,6 +384,7 @@ static int xwdt_remove(struct platform_device *dev)
394 384
395/* Match table for of_platform binding */ 385/* Match table for of_platform binding */
396static struct of_device_id xwdt_of_match[] = { 386static struct of_device_id xwdt_of_match[] = {
387 { .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
397 { .compatible = "xlnx,xps-timebase-wdt-1.01.a", }, 388 { .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
398 {}, 389 {},
399}; 390};
@@ -413,5 +404,5 @@ module_platform_driver(xwdt_driver);
413 404
414MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); 405MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
415MODULE_DESCRIPTION("Xilinx Watchdog driver"); 406MODULE_DESCRIPTION("Xilinx Watchdog driver");
416MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL v2");
417MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 408MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index da577980d390..4ea5fcccac02 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -38,6 +38,9 @@
38#define WDT_IN_USE 0 38#define WDT_IN_USE 0
39#define WDT_OK_TO_CLOSE 1 39#define WDT_OK_TO_CLOSE 1
40 40
41#define WDT_RESET_OUT_EN BIT(1)
42#define WDT_INT_REQ BIT(3)
43
41static bool nowayout = WATCHDOG_NOWAYOUT; 44static bool nowayout = WATCHDOG_NOWAYOUT;
42static int heartbeat = -1; /* module parameter (seconds) */ 45static int heartbeat = -1; /* module parameter (seconds) */
43static unsigned int wdt_max_duration; /* (seconds) */ 46static unsigned int wdt_max_duration; /* (seconds) */
@@ -67,9 +70,7 @@ static int orion_wdt_start(struct watchdog_device *wdt_dev)
67 writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL); 70 writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
68 71
69 /* Clear watchdog timer interrupt */ 72 /* Clear watchdog timer interrupt */
70 reg = readl(BRIDGE_CAUSE); 73 writel(~WDT_INT_REQ, BRIDGE_CAUSE);
71 reg &= ~WDT_INT_REQ;
72 writel(reg, BRIDGE_CAUSE);
73 74
74 /* Enable watchdog timer */ 75 /* Enable watchdog timer */
75 reg = readl(wdt_reg + TIMER_CTRL); 76 reg = readl(wdt_reg + TIMER_CTRL);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index a3684a30eb69..b30bd430f591 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -159,13 +159,13 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
159 if (IS_ERR(wdt_base)) 159 if (IS_ERR(wdt_base))
160 return PTR_ERR(wdt_base); 160 return PTR_ERR(wdt_base);
161 161
162 wdt_clk = clk_get(&pdev->dev, NULL); 162 wdt_clk = devm_clk_get(&pdev->dev, NULL);
163 if (IS_ERR(wdt_clk)) 163 if (IS_ERR(wdt_clk))
164 return PTR_ERR(wdt_clk); 164 return PTR_ERR(wdt_clk);
165 165
166 ret = clk_enable(wdt_clk); 166 ret = clk_enable(wdt_clk);
167 if (ret) 167 if (ret)
168 goto out; 168 return ret;
169 169
170 pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? 170 pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
171 WDIOF_CARDRESET : 0; 171 WDIOF_CARDRESET : 0;
@@ -186,8 +186,6 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
186 186
187disable_clk: 187disable_clk:
188 clk_disable(wdt_clk); 188 clk_disable(wdt_clk);
189out:
190 clk_put(wdt_clk);
191 return ret; 189 return ret;
192} 190}
193 191
@@ -196,7 +194,6 @@ static int pnx4008_wdt_remove(struct platform_device *pdev)
196 watchdog_unregister_device(&pnx4008_wdd); 194 watchdog_unregister_device(&pnx4008_wdd);
197 195
198 clk_disable(wdt_clk); 196 clk_disable(wdt_clk);
199 clk_put(wdt_clk);
200 197
201 return 0; 198 return 0;
202} 199}
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index f78bc008cbb7..9cf6bc7a234f 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> /* For platform_driver framework */ 32#include <linux/platform_device.h> /* For platform_driver framework */
33#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 33#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
34#include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 34#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
35#include <linux/io.h> /* For devm_ioremap_nocache */
35 36
36#include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */ 37#include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */
37 38
@@ -271,7 +272,7 @@ static int rc32434_wdt_probe(struct platform_device *pdev)
271 return -ENODEV; 272 return -ENODEV;
272 } 273 }
273 274
274 wdt_reg = ioremap_nocache(r->start, resource_size(r)); 275 wdt_reg = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
275 if (!wdt_reg) { 276 if (!wdt_reg) {
276 pr_err("failed to remap I/O resources\n"); 277 pr_err("failed to remap I/O resources\n");
277 return -ENXIO; 278 return -ENXIO;
@@ -293,23 +294,18 @@ static int rc32434_wdt_probe(struct platform_device *pdev)
293 ret = misc_register(&rc32434_wdt_miscdev); 294 ret = misc_register(&rc32434_wdt_miscdev);
294 if (ret < 0) { 295 if (ret < 0) {
295 pr_err("failed to register watchdog device\n"); 296 pr_err("failed to register watchdog device\n");
296 goto unmap; 297 return ret;
297 } 298 }
298 299
299 pr_info("Watchdog Timer version " VERSION ", timer margin: %d sec\n", 300 pr_info("Watchdog Timer version " VERSION ", timer margin: %d sec\n",
300 timeout); 301 timeout);
301 302
302 return 0; 303 return 0;
303
304unmap:
305 iounmap(wdt_reg);
306 return ret;
307} 304}
308 305
309static int rc32434_wdt_remove(struct platform_device *pdev) 306static int rc32434_wdt_remove(struct platform_device *pdev)
310{ 307{
311 misc_deregister(&rc32434_wdt_miscdev); 308 misc_deregister(&rc32434_wdt_miscdev);
312 iounmap(wdt_reg);
313 return 0; 309 return 0;
314} 310}
315 311
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 0040451aec1d..3dd8ed28adc8 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -183,7 +183,7 @@ static int riowd_probe(struct platform_device *op)
183 goto out; 183 goto out;
184 184
185 err = -ENOMEM; 185 err = -ENOMEM;
186 p = kzalloc(sizeof(*p), GFP_KERNEL); 186 p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
187 if (!p) 187 if (!p)
188 goto out; 188 goto out;
189 189
@@ -192,7 +192,7 @@ static int riowd_probe(struct platform_device *op)
192 p->regs = of_ioremap(&op->resource[0], 0, 2, DRIVER_NAME); 192 p->regs = of_ioremap(&op->resource[0], 0, 2, DRIVER_NAME);
193 if (!p->regs) { 193 if (!p->regs) {
194 pr_err("Cannot map registers\n"); 194 pr_err("Cannot map registers\n");
195 goto out_free; 195 goto out;
196 } 196 }
197 /* Make miscdev useable right away */ 197 /* Make miscdev useable right away */
198 riowd_device = p; 198 riowd_device = p;
@@ -206,27 +206,23 @@ static int riowd_probe(struct platform_device *op)
206 pr_info("Hardware watchdog [%i minutes], regs at %p\n", 206 pr_info("Hardware watchdog [%i minutes], regs at %p\n",
207 riowd_timeout, p->regs); 207 riowd_timeout, p->regs);
208 208
209 dev_set_drvdata(&op->dev, p); 209 platform_set_drvdata(op, p);
210 return 0; 210 return 0;
211 211
212out_iounmap: 212out_iounmap:
213 riowd_device = NULL; 213 riowd_device = NULL;
214 of_iounmap(&op->resource[0], p->regs, 2); 214 of_iounmap(&op->resource[0], p->regs, 2);
215 215
216out_free:
217 kfree(p);
218
219out: 216out:
220 return err; 217 return err;
221} 218}
222 219
223static int riowd_remove(struct platform_device *op) 220static int riowd_remove(struct platform_device *op)
224{ 221{
225 struct riowd *p = dev_get_drvdata(&op->dev); 222 struct riowd *p = platform_get_drvdata(op);
226 223
227 misc_deregister(&riowd_miscdev); 224 misc_deregister(&riowd_miscdev);
228 of_iounmap(&op->resource[0], p->regs, 2); 225 of_iounmap(&op->resource[0], p->regs, 2);
229 kfree(p);
230 226
231 return 0; 227 return 0;
232} 228}
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 3a9f6961db2d..6a22cf5d35bd 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -358,7 +358,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
358 358
359 ret = s3c2410wdt_cpufreq_register(); 359 ret = s3c2410wdt_cpufreq_register();
360 if (ret < 0) { 360 if (ret < 0) {
361 pr_err("failed to register cpufreq\n"); 361 dev_err(dev, "failed to register cpufreq\n");
362 goto err_clk; 362 goto err_clk;
363 } 363 }
364 364
@@ -448,12 +448,12 @@ static void s3c2410wdt_shutdown(struct platform_device *dev)
448 s3c2410wdt_stop(&s3c2410_wdd); 448 s3c2410wdt_stop(&s3c2410_wdd);
449} 449}
450 450
451#ifdef CONFIG_PM 451#ifdef CONFIG_PM_SLEEP
452 452
453static unsigned long wtcon_save; 453static unsigned long wtcon_save;
454static unsigned long wtdat_save; 454static unsigned long wtdat_save;
455 455
456static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state) 456static int s3c2410wdt_suspend(struct device *dev)
457{ 457{
458 /* Save watchdog state, and turn it off. */ 458 /* Save watchdog state, and turn it off. */
459 wtcon_save = readl(wdt_base + S3C2410_WTCON); 459 wtcon_save = readl(wdt_base + S3C2410_WTCON);
@@ -465,7 +465,7 @@ static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state)
465 return 0; 465 return 0;
466} 466}
467 467
468static int s3c2410wdt_resume(struct platform_device *dev) 468static int s3c2410wdt_resume(struct device *dev)
469{ 469{
470 /* Restore watchdog state. */ 470 /* Restore watchdog state. */
471 471
@@ -473,16 +473,15 @@ static int s3c2410wdt_resume(struct platform_device *dev)
473 writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */ 473 writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
474 writel(wtcon_save, wdt_base + S3C2410_WTCON); 474 writel(wtcon_save, wdt_base + S3C2410_WTCON);
475 475
476 pr_info("watchdog %sabled\n", 476 dev_info(dev, "watchdog %sabled\n",
477 (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); 477 (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
478 478
479 return 0; 479 return 0;
480} 480}
481#endif
481 482
482#else 483static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend,
483#define s3c2410wdt_suspend NULL 484 s3c2410wdt_resume);
484#define s3c2410wdt_resume NULL
485#endif /* CONFIG_PM */
486 485
487#ifdef CONFIG_OF 486#ifdef CONFIG_OF
488static const struct of_device_id s3c2410_wdt_match[] = { 487static const struct of_device_id s3c2410_wdt_match[] = {
@@ -496,11 +495,10 @@ static struct platform_driver s3c2410wdt_driver = {
496 .probe = s3c2410wdt_probe, 495 .probe = s3c2410wdt_probe,
497 .remove = s3c2410wdt_remove, 496 .remove = s3c2410wdt_remove,
498 .shutdown = s3c2410wdt_shutdown, 497 .shutdown = s3c2410wdt_shutdown,
499 .suspend = s3c2410wdt_suspend,
500 .resume = s3c2410wdt_resume,
501 .driver = { 498 .driver = {
502 .owner = THIS_MODULE, 499 .owner = THIS_MODULE,
503 .name = "s3c2410-wdt", 500 .name = "s3c2410-wdt",
501 .pm = &s3c2410wdt_pm_ops,
504 .of_match_table = of_match_ptr(s3c2410_wdt_match), 502 .of_match_table = of_match_ptr(s3c2410_wdt_match),
505 }, 503 },
506}; 504};
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 6185af2b3310..5bca79457768 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -241,7 +241,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
241 241
242 wdt->dev = &pdev->dev; 242 wdt->dev = &pdev->dev;
243 243
244 wdt->clk = clk_get(&pdev->dev, NULL); 244 wdt->clk = devm_clk_get(&pdev->dev, NULL);
245 if (IS_ERR(wdt->clk)) { 245 if (IS_ERR(wdt->clk)) {
246 /* 246 /*
247 * Clock framework support is optional, continue on 247 * Clock framework support is optional, continue on
@@ -251,10 +251,8 @@ static int sh_wdt_probe(struct platform_device *pdev)
251 } 251 }
252 252
253 wdt->base = devm_ioremap_resource(wdt->dev, res); 253 wdt->base = devm_ioremap_resource(wdt->dev, res);
254 if (IS_ERR(wdt->base)) { 254 if (IS_ERR(wdt->base))
255 rc = PTR_ERR(wdt->base); 255 return PTR_ERR(wdt->base);
256 goto err;
257 }
258 256
259 watchdog_set_nowayout(&sh_wdt_dev, nowayout); 257 watchdog_set_nowayout(&sh_wdt_dev, nowayout);
260 watchdog_set_drvdata(&sh_wdt_dev, wdt); 258 watchdog_set_drvdata(&sh_wdt_dev, wdt);
@@ -277,7 +275,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
277 rc = watchdog_register_device(&sh_wdt_dev); 275 rc = watchdog_register_device(&sh_wdt_dev);
278 if (unlikely(rc)) { 276 if (unlikely(rc)) {
279 dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); 277 dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc);
280 goto err; 278 return rc;
281 } 279 }
282 280
283 init_timer(&wdt->timer); 281 init_timer(&wdt->timer);
@@ -292,23 +290,15 @@ static int sh_wdt_probe(struct platform_device *pdev)
292 pm_runtime_enable(&pdev->dev); 290 pm_runtime_enable(&pdev->dev);
293 291
294 return 0; 292 return 0;
295
296err:
297 clk_put(wdt->clk);
298
299 return rc;
300} 293}
301 294
302static int sh_wdt_remove(struct platform_device *pdev) 295static int sh_wdt_remove(struct platform_device *pdev)
303{ 296{
304 struct sh_wdt *wdt = platform_get_drvdata(pdev); 297 struct sh_wdt *wdt = platform_get_drvdata(pdev);
305 298
306 platform_set_drvdata(pdev, NULL);
307
308 watchdog_unregister_device(&sh_wdt_dev); 299 watchdog_unregister_device(&sh_wdt_dev);
309 300
310 pm_runtime_disable(&pdev->dev); 301 pm_runtime_disable(&pdev->dev);
311 clk_put(wdt->clk);
312 302
313 return 0; 303 return 0;
314} 304}
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index fe83beb8f1b7..b68b1e519d53 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -152,7 +152,6 @@ static struct watchdog_ops softdog_ops = {
152 .owner = THIS_MODULE, 152 .owner = THIS_MODULE,
153 .start = softdog_ping, 153 .start = softdog_ping,
154 .stop = softdog_stop, 154 .stop = softdog_stop,
155 .ping = softdog_ping,
156 .set_timeout = softdog_set_timeout, 155 .set_timeout = softdog_set_timeout,
157}; 156};
158 157
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 8872642505c0..58df98aec122 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -231,7 +231,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
231 goto err; 231 goto err;
232 } 232 }
233 233
234 wdt->clk = clk_get(&adev->dev, NULL); 234 wdt->clk = devm_clk_get(&adev->dev, NULL);
235 if (IS_ERR(wdt->clk)) { 235 if (IS_ERR(wdt->clk)) {
236 dev_warn(&adev->dev, "Clock not found\n"); 236 dev_warn(&adev->dev, "Clock not found\n");
237 ret = PTR_ERR(wdt->clk); 237 ret = PTR_ERR(wdt->clk);
@@ -251,15 +251,13 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
251 if (ret) { 251 if (ret) {
252 dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", 252 dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
253 ret); 253 ret);
254 goto err_register; 254 goto err;
255 } 255 }
256 amba_set_drvdata(adev, wdt); 256 amba_set_drvdata(adev, wdt);
257 257
258 dev_info(&adev->dev, "registration successful\n"); 258 dev_info(&adev->dev, "registration successful\n");
259 return 0; 259 return 0;
260 260
261err_register:
262 clk_put(wdt->clk);
263err: 261err:
264 dev_err(&adev->dev, "Probe Failed!!!\n"); 262 dev_err(&adev->dev, "Probe Failed!!!\n");
265 return ret; 263 return ret;
@@ -272,7 +270,6 @@ static int sp805_wdt_remove(struct amba_device *adev)
272 watchdog_unregister_device(&wdt->wdd); 270 watchdog_unregister_device(&wdt->wdd);
273 amba_set_drvdata(adev, NULL); 271 amba_set_drvdata(adev, NULL);
274 watchdog_set_drvdata(&wdt->wdd, NULL); 272 watchdog_set_drvdata(&wdt->wdd, NULL);
275 clk_put(wdt->clk);
276 273
277 return 0; 274 return 0;
278} 275}
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index b8a92459f10f..4da59b4d73f0 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -396,7 +396,7 @@ static int ts72xx_wdt_probe(struct platform_device *pdev)
396 struct resource *r1, *r2; 396 struct resource *r1, *r2;
397 int error = 0; 397 int error = 0;
398 398
399 wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL); 399 wdt = devm_kzalloc(&pdev->dev, sizeof(struct ts72xx_wdt), GFP_KERNEL);
400 if (!wdt) { 400 if (!wdt) {
401 dev_err(&pdev->dev, "failed to allocate memory\n"); 401 dev_err(&pdev->dev, "failed to allocate memory\n");
402 return -ENOMEM; 402 return -ENOMEM;
@@ -405,44 +405,22 @@ static int ts72xx_wdt_probe(struct platform_device *pdev)
405 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 405 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
406 if (!r1) { 406 if (!r1) {
407 dev_err(&pdev->dev, "failed to get memory resource\n"); 407 dev_err(&pdev->dev, "failed to get memory resource\n");
408 error = -ENODEV; 408 return -ENODEV;
409 goto fail;
410 } 409 }
411 410
412 r1 = request_mem_region(r1->start, resource_size(r1), pdev->name); 411 wdt->control_reg = devm_ioremap_resource(&pdev->dev, r1);
413 if (!r1) { 412 if (IS_ERR(wdt->control_reg))
414 dev_err(&pdev->dev, "cannot request memory region\n"); 413 return PTR_ERR(wdt->control_reg);
415 error = -EBUSY;
416 goto fail;
417 }
418
419 wdt->control_reg = ioremap(r1->start, resource_size(r1));
420 if (!wdt->control_reg) {
421 dev_err(&pdev->dev, "failed to map memory\n");
422 error = -ENODEV;
423 goto fail_free_control;
424 }
425 414
426 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 415 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
427 if (!r2) { 416 if (!r2) {
428 dev_err(&pdev->dev, "failed to get memory resource\n"); 417 dev_err(&pdev->dev, "failed to get memory resource\n");
429 error = -ENODEV; 418 return -ENODEV;
430 goto fail_unmap_control;
431 }
432
433 r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
434 if (!r2) {
435 dev_err(&pdev->dev, "cannot request memory region\n");
436 error = -EBUSY;
437 goto fail_unmap_control;
438 } 419 }
439 420
440 wdt->feed_reg = ioremap(r2->start, resource_size(r2)); 421 wdt->feed_reg = devm_ioremap_resource(&pdev->dev, r2);
441 if (!wdt->feed_reg) { 422 if (IS_ERR(wdt->feed_reg))
442 dev_err(&pdev->dev, "failed to map memory\n"); 423 return PTR_ERR(wdt->feed_reg);
443 error = -ENODEV;
444 goto fail_free_feed;
445 }
446 424
447 platform_set_drvdata(pdev, wdt); 425 platform_set_drvdata(pdev, wdt);
448 ts72xx_wdt_pdev = pdev; 426 ts72xx_wdt_pdev = pdev;
@@ -455,45 +433,20 @@ static int ts72xx_wdt_probe(struct platform_device *pdev)
455 error = misc_register(&ts72xx_wdt_miscdev); 433 error = misc_register(&ts72xx_wdt_miscdev);
456 if (error) { 434 if (error) {
457 dev_err(&pdev->dev, "failed to register miscdev\n"); 435 dev_err(&pdev->dev, "failed to register miscdev\n");
458 goto fail_unmap_feed; 436 return error;
459 } 437 }
460 438
461 dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); 439 dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
462 440
463 return 0; 441 return 0;
464
465fail_unmap_feed:
466 platform_set_drvdata(pdev, NULL);
467 iounmap(wdt->feed_reg);
468fail_free_feed:
469 release_mem_region(r2->start, resource_size(r2));
470fail_unmap_control:
471 iounmap(wdt->control_reg);
472fail_free_control:
473 release_mem_region(r1->start, resource_size(r1));
474fail:
475 kfree(wdt);
476 return error;
477} 442}
478 443
479static int ts72xx_wdt_remove(struct platform_device *pdev) 444static int ts72xx_wdt_remove(struct platform_device *pdev)
480{ 445{
481 struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
482 struct resource *res;
483 int error; 446 int error;
484 447
485 error = misc_deregister(&ts72xx_wdt_miscdev); 448 error = misc_deregister(&ts72xx_wdt_miscdev);
486 platform_set_drvdata(pdev, NULL);
487
488 iounmap(wdt->feed_reg);
489 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
490 release_mem_region(res->start, resource_size(res));
491
492 iounmap(wdt->control_reg);
493 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
494 release_mem_region(res->start, resource_size(res));
495 449
496 kfree(wdt);
497 return error; 450 return error;
498} 451}
499 452
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 0f03106f7516..2d4535dc2676 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -90,10 +90,8 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
90 twl4030_wdt_stop(wdt); 90 twl4030_wdt_stop(wdt);
91 91
92 ret = watchdog_register_device(wdt); 92 ret = watchdog_register_device(wdt);
93 if (ret) { 93 if (ret)
94 platform_set_drvdata(pdev, NULL);
95 return ret; 94 return ret;
96 }
97 95
98 return 0; 96 return 0;
99} 97}
@@ -103,7 +101,6 @@ static int twl4030_wdt_remove(struct platform_device *pdev)
103 struct watchdog_device *wdt = platform_get_drvdata(pdev); 101 struct watchdog_device *wdt = platform_get_drvdata(pdev);
104 102
105 watchdog_unregister_device(wdt); 103 watchdog_unregister_device(wdt);
106 platform_set_drvdata(pdev, NULL);
107 104
108 return 0; 105 return 0;
109} 106}
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index faf4e189fe42..6aaefbad303e 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -469,8 +469,10 @@ static int watchdog_release(struct inode *inode, struct file *file)
469 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then 469 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
470 * watchdog_stop will fail. 470 * watchdog_stop will fail.
471 */ 471 */
472 if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || 472 if (!test_bit(WDOG_ACTIVE, &wdd->status))
473 !(wdd->info->options & WDIOF_MAGICCLOSE)) 473 err = 0;
474 else if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
475 !(wdd->info->options & WDIOF_MAGICCLOSE))
474 err = watchdog_stop(wdd); 476 err = watchdog_stop(wdd);
475 477
476 /* If the watchdog was not stopped, send a keepalive ping */ 478 /* If the watchdog was not stopped, send a keepalive ping */
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 0a77655cda60..3045debd5411 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -162,31 +162,6 @@ static void wdrtas_timer_stop(void)
162} 162}
163 163
164/** 164/**
165 * wdrtas_log_scanned_event - logs an event we received during keepalive
166 *
167 * wdrtas_log_scanned_event prints a message to the log buffer dumping
168 * the results of the last event-scan call
169 */
170static void wdrtas_log_scanned_event(void)
171{
172 int i;
173
174 for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
175 pr_info("dumping event (line %i/%i), data = "
176 "%02x %02x %02x %02x %02x %02x %02x %02x "
177 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
178 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
179 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
180 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
181 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
182 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
183 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
184 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
185 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
186 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
187}
188
189/**
190 * wdrtas_timer_keepalive - resets watchdog timer to keep system alive 165 * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
191 * 166 *
192 * wdrtas_timer_keepalive restarts the watchdog timer by calling the 167 * wdrtas_timer_keepalive restarts the watchdog timer by calling the
@@ -205,7 +180,9 @@ static void wdrtas_timer_keepalive(void)
205 if (result < 0) 180 if (result < 0)
206 pr_err("event-scan failed: %li\n", result); 181 pr_err("event-scan failed: %li\n", result);
207 if (result == 0) 182 if (result == 0)
208 wdrtas_log_scanned_event(); 183 print_hex_dump(KERN_INFO, "dumping event, data: ",
184 DUMP_PREFIX_OFFSET, 16, 1,
185 wdrtas_logbuffer, WDRTAS_LOGBUFFER_LEN, false);
209 } while (result == 0); 186 } while (result == 0);
210} 187}
211 188
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 9dcb6d082277..d4e47eda4182 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -247,9 +247,10 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
247 reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT; 247 reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
248 248
249 if (pdata->update_gpio) { 249 if (pdata->update_gpio) {
250 ret = gpio_request_one(pdata->update_gpio, 250 ret = devm_gpio_request_one(&pdev->dev,
251 GPIOF_DIR_OUT | GPIOF_INIT_LOW, 251 pdata->update_gpio,
252 "Watchdog update"); 252 GPIOF_OUT_INIT_LOW,
253 "Watchdog update");
253 if (ret < 0) { 254 if (ret < 0) {
254 dev_err(wm831x->dev, 255 dev_err(wm831x->dev,
255 "Failed to request update GPIO: %d\n", 256 "Failed to request update GPIO: %d\n",
@@ -270,7 +271,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
270 } else { 271 } else {
271 dev_err(wm831x->dev, 272 dev_err(wm831x->dev,
272 "Failed to unlock security key: %d\n", ret); 273 "Failed to unlock security key: %d\n", ret);
273 goto err_gpio; 274 goto err;
274 } 275 }
275 } 276 }
276 277
@@ -278,29 +279,23 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
278 if (ret != 0) { 279 if (ret != 0) {
279 dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n", 280 dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
280 ret); 281 ret);
281 goto err_gpio; 282 goto err;
282 } 283 }
283 284
284 dev_set_drvdata(&pdev->dev, driver_data); 285 platform_set_drvdata(pdev, driver_data);
285 286
286 return 0; 287 return 0;
287 288
288err_gpio:
289 if (driver_data->update_gpio)
290 gpio_free(driver_data->update_gpio);
291err: 289err:
292 return ret; 290 return ret;
293} 291}
294 292
295static int wm831x_wdt_remove(struct platform_device *pdev) 293static int wm831x_wdt_remove(struct platform_device *pdev)
296{ 294{
297 struct wm831x_wdt_drvdata *driver_data = dev_get_drvdata(&pdev->dev); 295 struct wm831x_wdt_drvdata *driver_data = platform_get_drvdata(pdev);
298 296
299 watchdog_unregister_device(&driver_data->wdt); 297 watchdog_unregister_device(&driver_data->wdt);
300 298
301 if (driver_data->update_gpio)
302 gpio_free(driver_data->update_gpio);
303
304 return 0; 299 return 0;
305} 300}
306 301