diff options
Diffstat (limited to 'drivers/watchdog')
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 | ||
224 | config 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 | |||
233 | config EP93XX_WATCHDOG | 224 | config 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 | ||
292 | config ORION_WATCHDOG | 283 | config 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 | ||
1103 | config 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 | |||
1112 | config LANTIQ_WDT | 1114 | config 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 | ||
1188 | config 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 | ||
1188 | config WATCHDOG_RTAS | 1202 | config 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 | |||
41 | obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o | 41 | obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o |
42 | obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o | 42 | obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o |
43 | obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o | 43 | obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o |
44 | obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o | ||
45 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o | 44 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o |
46 | obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o | 45 | obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o |
47 | obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o | 46 | obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o |
@@ -54,6 +53,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o | |||
54 | obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o | 53 | obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o |
55 | obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o | 54 | obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o |
56 | obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o | 55 | obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o |
56 | obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o | ||
57 | 57 | ||
58 | # AVR32 Architecture | 58 | # AVR32 Architecture |
59 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 59 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
@@ -144,6 +144,7 @@ obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o | |||
144 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o | 144 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o |
145 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o | 145 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o |
146 | obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o | 146 | obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o |
147 | obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o | ||
147 | 148 | ||
148 | # PPC64 Architecture | 149 | # PPC64 Architecture |
149 | obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o | 150 | obj-$(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 | ||
376 | err_register: | ||
377 | platform_set_drvdata(pdev, NULL); | ||
378 | err_iounmap: | ||
379 | iounmap(wdt->regs); | ||
380 | err_free: | 377 | err_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 | |||
38 | struct bcm2835_wdt { | ||
39 | void __iomem *base; | ||
40 | spinlock_t lock; | ||
41 | }; | ||
42 | |||
43 | static unsigned int heartbeat; | ||
44 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
45 | |||
46 | static 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 | |||
65 | static 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 | |||
74 | static int bcm2835_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t) | ||
75 | { | ||
76 | wdog->timeout = t; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static 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 | |||
88 | static 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 | |||
96 | static struct watchdog_info bcm2835_wdt_info = { | ||
97 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | | ||
98 | WDIOF_KEEPALIVEPING, | ||
99 | .identity = "Broadcom BCM2835 Watchdog timer", | ||
100 | }; | ||
101 | |||
102 | static 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 | |||
110 | static 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 | |||
146 | static 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 | |||
156 | static void bcm2835_wdt_shutdown(struct platform_device *pdev) | ||
157 | { | ||
158 | bcm2835_wdt_stop(&bcm2835_wdt_wdd); | ||
159 | } | ||
160 | |||
161 | static const struct of_device_id bcm2835_wdt_of_match[] = { | ||
162 | { .compatible = "brcm,bcm2835-pm-wdt", }, | ||
163 | {}, | ||
164 | }; | ||
165 | MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match); | ||
166 | |||
167 | static 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 | }; | ||
177 | module_platform_driver(bcm2835_wdt_driver); | ||
178 | |||
179 | module_param(heartbeat, uint, 0); | ||
180 | MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds"); | ||
181 | |||
182 | module_param(nowayout, bool, 0); | ||
183 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
184 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
185 | |||
186 | MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>"); | ||
187 | MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer"); | ||
188 | MODULE_LICENSE("GPL"); | ||
189 | MODULE_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 | ||
282 | unregister_timer: | 284 | unregister_timer: |
283 | bcm63xx_timer_unregister(TIMER_WDT_ID); | 285 | bcm63xx_timer_unregister(TIMER_WDT_ID); |
284 | unmap: | ||
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 | ||
643 | static int cpwd_remove(struct platform_device *op) | 643 | static 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); |
219 | err: | 219 | err: |
220 | return ret; | 220 | return ret; |
221 | } | 221 | } |
222 | 222 | ||
223 | static int da9052_wdt_remove(struct platform_device *pdev) | 223 | static 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 | ||
188 | static int da9055_wdt_remove(struct platform_device *pdev) | 188 | static 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 | ||
157 | ssize_t dw_wdt_write(struct file *filp, const char __user *buf, size_t len, | 157 | static 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 | ||
328 | out_disable_clk: | 328 | out_disable_clk: |
329 | clk_disable(dw_wdt.clk); | 329 | clk_disable(dw_wdt.clk); |
330 | out_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 { | |||
148 | static unsigned int hpwdt_nmi_decoding; | 148 | static unsigned int hpwdt_nmi_decoding; |
149 | static unsigned int allow_kdump = 1; | 149 | static unsigned int allow_kdump = 1; |
150 | static unsigned int is_icru; | 150 | static unsigned int is_icru; |
151 | static unsigned int is_uefi; | ||
151 | static DEFINE_SPINLOCK(rom_lock); | 152 | static DEFINE_SPINLOCK(rom_lock); |
152 | static void *cru_rom_addr; | 153 | static void *cru_rom_addr; |
153 | static struct cmn_registers cmn_regs; | 154 | static 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 | ||
287 | fail: | 287 | fail: |
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 | |||
25 | enum 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 | |||
34 | struct a21_wdt_drv { | ||
35 | struct watchdog_device wdt; | ||
36 | struct mutex lock; | ||
37 | unsigned gpios[NUM_GPIOS]; | ||
38 | }; | ||
39 | |||
40 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
41 | module_param(nowayout, bool, 0); | ||
42 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
43 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
44 | |||
45 | static 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 | |||
56 | static 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 | |||
69 | static 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 | |||
82 | static 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 | |||
97 | static 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 | |||
127 | static const struct watchdog_info a21_wdt_info = { | ||
128 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | ||
129 | .identity = "MEN A21 Watchdog", | ||
130 | }; | ||
131 | |||
132 | static 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 | |||
140 | static 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 | |||
147 | static 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 | |||
223 | err_register_wd: | ||
224 | mutex_destroy(&drv->lock); | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static 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 | |||
243 | static 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 | |||
250 | static const struct of_device_id a21_wdt_ids[] = { | ||
251 | { .compatible = "men,a021-wdt" }, | ||
252 | { }, | ||
253 | }; | ||
254 | |||
255 | static 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 | |||
265 | module_platform_driver(a21_wdt_driver); | ||
266 | |||
267 | MODULE_AUTHOR("MEN Mikro Elektronik"); | ||
268 | MODULE_DESCRIPTION("MEN A21 Watchdog"); | ||
269 | MODULE_LICENSE("GPL"); | ||
270 | MODULE_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 | |||
41 | struct 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 | |||
50 | static struct platform_device *mpcore_wdt_pdev; | ||
51 | static DEFINE_SPINLOCK(wdt_lock); | ||
52 | |||
53 | #define TIMER_MARGIN 60 | ||
54 | static int mpcore_margin = TIMER_MARGIN; | ||
55 | module_param(mpcore_margin, int, 0); | ||
56 | MODULE_PARM_DESC(mpcore_margin, | ||
57 | "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default=" | ||
58 | __MODULE_STRING(TIMER_MARGIN) ")"); | ||
59 | |||
60 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
61 | module_param(nowayout, bool, 0); | ||
62 | MODULE_PARM_DESC(nowayout, | ||
63 | "Watchdog cannot be stopped once started (default=" | ||
64 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
65 | |||
66 | #define ONLY_TESTING 0 | ||
67 | static int mpcore_noboot = ONLY_TESTING; | ||
68 | module_param(mpcore_noboot, int, 0); | ||
69 | MODULE_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 | */ | ||
77 | static 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 | */ | ||
98 | static 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 | |||
114 | static 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 | |||
123 | static 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 | |||
139 | static 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 | */ | ||
151 | static 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 | |||
171 | static 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 | |||
191 | static 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 | |||
220 | static const struct watchdog_info ident = { | ||
221 | .options = WDIOF_SETTIMEOUT | | ||
222 | WDIOF_KEEPALIVEPING | | ||
223 | WDIOF_MAGICCLOSE, | ||
224 | .identity = "MPcore Watchdog", | ||
225 | }; | ||
226 | |||
227 | static 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 | */ | ||
303 | static 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 | */ | ||
314 | static 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 | |||
323 | static struct miscdevice mpcore_wdt_miscdev = { | ||
324 | .minor = WATCHDOG_MINOR, | ||
325 | .name = "watchdog", | ||
326 | .fops = &mpcore_wdt_fops, | ||
327 | }; | ||
328 | |||
329 | static 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 | |||
380 | static 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 | ||
392 | static 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 | |||
399 | static 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 */ | ||
413 | MODULE_ALIAS("platform:mpcore_wdt"); | ||
414 | |||
415 | static 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 | |||
427 | static 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 | |||
445 | static void __exit mpcore_wdt_exit(void) | ||
446 | { | ||
447 | platform_driver_unregister(&mpcore_wdt_driver); | ||
448 | } | ||
449 | |||
450 | module_init(mpcore_wdt_init); | ||
451 | module_exit(mpcore_wdt_exit); | ||
452 | |||
453 | MODULE_AUTHOR("ARM Limited"); | ||
454 | MODULE_DESCRIPTION("MPcore Watchdog Device Driver"); | ||
455 | MODULE_LICENSE("GPL"); | ||
456 | MODULE_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 | ||
63 | struct nuc900_wdt { | 63 | struct 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 | ||
245 | static int nuc900wdt_probe(struct platform_device *pdev) | 244 | static 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 | ||
299 | err_clk: | 287 | err_clk: |
300 | clk_disable(nuc900_wdt->wdt_clock); | 288 | clk_disable(nuc900_wdt->wdt_clock); |
301 | clk_put(nuc900_wdt->wdt_clock); | ||
302 | err_map: | ||
303 | iounmap(nuc900_wdt->wdt_base); | ||
304 | err_req: | ||
305 | release_mem_region(nuc900_wdt->res->start, | ||
306 | resource_size(nuc900_wdt->res)); | ||
307 | err_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 */ |
396 | static struct of_device_id xwdt_of_match[] = { | 386 | static 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 | ||
414 | MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); | 405 | MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); |
415 | MODULE_DESCRIPTION("Xilinx Watchdog driver"); | 406 | MODULE_DESCRIPTION("Xilinx Watchdog driver"); |
416 | MODULE_LICENSE("GPL"); | 407 | MODULE_LICENSE("GPL v2"); |
417 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 408 | MODULE_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 | |||
41 | static bool nowayout = WATCHDOG_NOWAYOUT; | 44 | static bool nowayout = WATCHDOG_NOWAYOUT; |
42 | static int heartbeat = -1; /* module parameter (seconds) */ | 45 | static int heartbeat = -1; /* module parameter (seconds) */ |
43 | static unsigned int wdt_max_duration; /* (seconds) */ | 46 | static 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 | ||
187 | disable_clk: | 187 | disable_clk: |
188 | clk_disable(wdt_clk); | 188 | clk_disable(wdt_clk); |
189 | out: | ||
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 | |||
304 | unmap: | ||
305 | iounmap(wdt_reg); | ||
306 | return ret; | ||
307 | } | 304 | } |
308 | 305 | ||
309 | static int rc32434_wdt_remove(struct platform_device *pdev) | 306 | static 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 | ||
212 | out_iounmap: | 212 | out_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 | ||
216 | out_free: | ||
217 | kfree(p); | ||
218 | |||
219 | out: | 216 | out: |
220 | return err; | 217 | return err; |
221 | } | 218 | } |
222 | 219 | ||
223 | static int riowd_remove(struct platform_device *op) | 220 | static 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 | ||
453 | static unsigned long wtcon_save; | 453 | static unsigned long wtcon_save; |
454 | static unsigned long wtdat_save; | 454 | static unsigned long wtdat_save; |
455 | 455 | ||
456 | static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state) | 456 | static 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 | ||
468 | static int s3c2410wdt_resume(struct platform_device *dev) | 468 | static 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 | 483 | static 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 |
488 | static const struct of_device_id s3c2410_wdt_match[] = { | 487 | static 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 | |||
296 | err: | ||
297 | clk_put(wdt->clk); | ||
298 | |||
299 | return rc; | ||
300 | } | 293 | } |
301 | 294 | ||
302 | static int sh_wdt_remove(struct platform_device *pdev) | 295 | static 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 | ||
261 | err_register: | ||
262 | clk_put(wdt->clk); | ||
263 | err: | 261 | err: |
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 | |||
465 | fail_unmap_feed: | ||
466 | platform_set_drvdata(pdev, NULL); | ||
467 | iounmap(wdt->feed_reg); | ||
468 | fail_free_feed: | ||
469 | release_mem_region(r2->start, resource_size(r2)); | ||
470 | fail_unmap_control: | ||
471 | iounmap(wdt->control_reg); | ||
472 | fail_free_control: | ||
473 | release_mem_region(r1->start, resource_size(r1)); | ||
474 | fail: | ||
475 | kfree(wdt); | ||
476 | return error; | ||
477 | } | 442 | } |
478 | 443 | ||
479 | static int ts72xx_wdt_remove(struct platform_device *pdev) | 444 | static 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 | */ | ||
170 | static 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 | ||
288 | err_gpio: | ||
289 | if (driver_data->update_gpio) | ||
290 | gpio_free(driver_data->update_gpio); | ||
291 | err: | 289 | err: |
292 | return ret; | 290 | return ret; |
293 | } | 291 | } |
294 | 292 | ||
295 | static int wm831x_wdt_remove(struct platform_device *pdev) | 293 | static 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 | ||