diff options
Diffstat (limited to 'drivers/watchdog')
53 files changed, 552 insertions, 476 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index f1ff408c4b17..74ec8fc5cc03 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -111,6 +111,15 @@ config WM8350_WATCHDOG | |||
111 | Support for the watchdog in the WM8350 AudioPlus PMIC. When | 111 | Support for the watchdog in the WM8350 AudioPlus PMIC. When |
112 | the watchdog triggers the system will be reset. | 112 | the watchdog triggers the system will be reset. |
113 | 113 | ||
114 | config XILINX_WATCHDOG | ||
115 | tristate "Xilinx Watchdog timer" | ||
116 | select WATCHDOG_CORE | ||
117 | help | ||
118 | Watchdog driver for the xps_timebase_wdt ip core. | ||
119 | |||
120 | To compile this driver as a module, choose M here: the | ||
121 | module will be called of_xilinx_wdt. | ||
122 | |||
114 | # ALPHA Architecture | 123 | # ALPHA Architecture |
115 | 124 | ||
116 | # ARM Architecture | 125 | # ARM Architecture |
@@ -292,7 +301,7 @@ config DAVINCI_WATCHDOG | |||
292 | 301 | ||
293 | config ORION_WATCHDOG | 302 | config ORION_WATCHDOG |
294 | tristate "Orion watchdog" | 303 | tristate "Orion watchdog" |
295 | depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU | 304 | depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU |
296 | select WATCHDOG_CORE | 305 | select WATCHDOG_CORE |
297 | help | 306 | help |
298 | Say Y here if to include support for the watchdog timer | 307 | Say Y here if to include support for the watchdog timer |
@@ -421,6 +430,17 @@ config SIRFSOC_WATCHDOG | |||
421 | Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When | 430 | Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When |
422 | the watchdog triggers the system will be reset. | 431 | the watchdog triggers the system will be reset. |
423 | 432 | ||
433 | config TEGRA_WATCHDOG | ||
434 | tristate "Tegra watchdog" | ||
435 | depends on ARCH_TEGRA || COMPILE_TEST | ||
436 | select WATCHDOG_CORE | ||
437 | help | ||
438 | Say Y here to include support for the watchdog timer | ||
439 | embedded in NVIDIA Tegra SoCs. | ||
440 | |||
441 | To compile this driver as a module, choose M here: the | ||
442 | module will be called tegra_wdt. | ||
443 | |||
424 | # AVR32 Architecture | 444 | # AVR32 Architecture |
425 | 445 | ||
426 | config AT32AP700X_WDT | 446 | config AT32AP700X_WDT |
@@ -533,7 +553,7 @@ config GEODE_WDT | |||
533 | 553 | ||
534 | config SC520_WDT | 554 | config SC520_WDT |
535 | tristate "AMD Elan SC520 processor Watchdog" | 555 | tristate "AMD Elan SC520 processor Watchdog" |
536 | depends on X86 | 556 | depends on MELAN |
537 | help | 557 | help |
538 | This is the driver for the hardware watchdog built in to the | 558 | This is the driver for the hardware watchdog built in to the |
539 | AMD "Elan" SC520 microcomputer commonly used in embedded systems. | 559 | AMD "Elan" SC520 microcomputer commonly used in embedded systems. |
@@ -1023,18 +1043,6 @@ config M54xx_WATCHDOG | |||
1023 | 1043 | ||
1024 | # MicroBlaze Architecture | 1044 | # MicroBlaze Architecture |
1025 | 1045 | ||
1026 | config XILINX_WATCHDOG | ||
1027 | tristate "Xilinx Watchdog timer" | ||
1028 | depends on MICROBLAZE | ||
1029 | ---help--- | ||
1030 | Watchdog driver for the xps_timebase_wdt ip core. | ||
1031 | |||
1032 | IMPORTANT: The xps_timebase_wdt parent must have the property | ||
1033 | "clock-frequency" at device tree. | ||
1034 | |||
1035 | To compile this driver as a module, choose M here: the | ||
1036 | module will be called of_xilinx_wdt. | ||
1037 | |||
1038 | # MIPS Architecture | 1046 | # MIPS Architecture |
1039 | 1047 | ||
1040 | config ATH79_WDT | 1048 | config ATH79_WDT |
@@ -1160,7 +1168,7 @@ config BCM2835_WDT | |||
1160 | 1168 | ||
1161 | config BCM_KONA_WDT | 1169 | config BCM_KONA_WDT |
1162 | tristate "BCM Kona Watchdog" | 1170 | tristate "BCM Kona Watchdog" |
1163 | depends on ARCH_BCM | 1171 | depends on ARCH_BCM_MOBILE |
1164 | select WATCHDOG_CORE | 1172 | select WATCHDOG_CORE |
1165 | help | 1173 | help |
1166 | Support for the watchdog timer on the following Broadcom BCM281xx | 1174 | Support for the watchdog timer on the following Broadcom BCM281xx |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 985a66cda76f..1b5f3d5efad5 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o | |||
58 | obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o | 58 | obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o |
59 | obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o | 59 | obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o |
60 | obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o | 60 | obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o |
61 | obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o | ||
61 | 62 | ||
62 | # AVR32 Architecture | 63 | # AVR32 Architecture |
63 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 64 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 5cf1621def9c..5614416f1032 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c | |||
@@ -239,7 +239,7 @@ static struct miscdevice acq_miscdev = { | |||
239 | * Init & exit routines | 239 | * Init & exit routines |
240 | */ | 240 | */ |
241 | 241 | ||
242 | static int acq_probe(struct platform_device *dev) | 242 | static int __init acq_probe(struct platform_device *dev) |
243 | { | 243 | { |
244 | int ret; | 244 | int ret; |
245 | 245 | ||
@@ -291,7 +291,6 @@ static void acq_shutdown(struct platform_device *dev) | |||
291 | } | 291 | } |
292 | 292 | ||
293 | static struct platform_driver acquirewdt_driver = { | 293 | static struct platform_driver acquirewdt_driver = { |
294 | .probe = acq_probe, | ||
295 | .remove = acq_remove, | 294 | .remove = acq_remove, |
296 | .shutdown = acq_shutdown, | 295 | .shutdown = acq_shutdown, |
297 | .driver = { | 296 | .driver = { |
@@ -306,20 +305,18 @@ static int __init acq_init(void) | |||
306 | 305 | ||
307 | pr_info("WDT driver for Acquire single board computer initialising\n"); | 306 | pr_info("WDT driver for Acquire single board computer initialising\n"); |
308 | 307 | ||
309 | err = platform_driver_register(&acquirewdt_driver); | ||
310 | if (err) | ||
311 | return err; | ||
312 | |||
313 | acq_platform_device = platform_device_register_simple(DRV_NAME, | 308 | acq_platform_device = platform_device_register_simple(DRV_NAME, |
314 | -1, NULL, 0); | 309 | -1, NULL, 0); |
315 | if (IS_ERR(acq_platform_device)) { | 310 | if (IS_ERR(acq_platform_device)) |
316 | err = PTR_ERR(acq_platform_device); | 311 | return PTR_ERR(acq_platform_device); |
317 | goto unreg_platform_driver; | 312 | |
318 | } | 313 | err = platform_driver_probe(&acquirewdt_driver, acq_probe); |
314 | if (err) | ||
315 | goto unreg_platform_device; | ||
319 | return 0; | 316 | return 0; |
320 | 317 | ||
321 | unreg_platform_driver: | 318 | unreg_platform_device: |
322 | platform_driver_unregister(&acquirewdt_driver); | 319 | platform_device_unregister(acq_platform_device); |
323 | return err; | 320 | return err; |
324 | } | 321 | } |
325 | 322 | ||
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index a8961addc59c..7796db7fa6e1 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c | |||
@@ -238,7 +238,7 @@ static struct miscdevice advwdt_miscdev = { | |||
238 | * Init & exit routines | 238 | * Init & exit routines |
239 | */ | 239 | */ |
240 | 240 | ||
241 | static int advwdt_probe(struct platform_device *dev) | 241 | static int __init advwdt_probe(struct platform_device *dev) |
242 | { | 242 | { |
243 | int ret; | 243 | int ret; |
244 | 244 | ||
@@ -299,7 +299,6 @@ static void advwdt_shutdown(struct platform_device *dev) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | static struct platform_driver advwdt_driver = { | 301 | static struct platform_driver advwdt_driver = { |
302 | .probe = advwdt_probe, | ||
303 | .remove = advwdt_remove, | 302 | .remove = advwdt_remove, |
304 | .shutdown = advwdt_shutdown, | 303 | .shutdown = advwdt_shutdown, |
305 | .driver = { | 304 | .driver = { |
@@ -314,21 +313,19 @@ static int __init advwdt_init(void) | |||
314 | 313 | ||
315 | pr_info("WDT driver for Advantech single board computer initialising\n"); | 314 | pr_info("WDT driver for Advantech single board computer initialising\n"); |
316 | 315 | ||
317 | err = platform_driver_register(&advwdt_driver); | ||
318 | if (err) | ||
319 | return err; | ||
320 | |||
321 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, | 316 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, |
322 | -1, NULL, 0); | 317 | -1, NULL, 0); |
323 | if (IS_ERR(advwdt_platform_device)) { | 318 | if (IS_ERR(advwdt_platform_device)) |
324 | err = PTR_ERR(advwdt_platform_device); | 319 | return PTR_ERR(advwdt_platform_device); |
325 | goto unreg_platform_driver; | 320 | |
326 | } | 321 | err = platform_driver_probe(&advwdt_driver, advwdt_probe); |
322 | if (err) | ||
323 | goto unreg_platform_device; | ||
327 | 324 | ||
328 | return 0; | 325 | return 0; |
329 | 326 | ||
330 | unreg_platform_driver: | 327 | unreg_platform_device: |
331 | platform_driver_unregister(&advwdt_driver); | 328 | platform_device_unregister(advwdt_platform_device); |
332 | return err; | 329 | return err; |
333 | } | 330 | } |
334 | 331 | ||
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 3a996576343a..ae6c287a49cb 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/init.h> | ||
32 | #include <linux/miscdevice.h> | 31 | #include <linux/miscdevice.h> |
33 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
34 | #include <linux/watchdog.h> | 33 | #include <linux/watchdog.h> |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index afe7d17e6776..25b5c67d3af9 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -323,10 +323,8 @@ static int __init at32_wdt_probe(struct platform_device *pdev) | |||
323 | 323 | ||
324 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x), | 324 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x), |
325 | GFP_KERNEL); | 325 | GFP_KERNEL); |
326 | if (!wdt) { | 326 | if (!wdt) |
327 | dev_dbg(&pdev->dev, "no memory for wdt structure\n"); | ||
328 | return -ENOMEM; | 327 | return -ENOMEM; |
329 | } | ||
330 | 328 | ||
331 | wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); | 329 | wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); |
332 | if (!wdt->regs) { | 330 | if (!wdt->regs) { |
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index 9fa1f69dac13..399c3fddecf6 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/init.h> | ||
26 | #include <linux/io.h> | 25 | #include <linux/io.h> |
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index cafa973c43be..8df450c090a9 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c | |||
@@ -114,10 +114,8 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) | |||
114 | int err; | 114 | int err; |
115 | 115 | ||
116 | wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL); | 116 | wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL); |
117 | if (!wdt) { | 117 | if (!wdt) |
118 | dev_err(dev, "Failed to allocate memory for watchdog device"); | ||
119 | return -ENOMEM; | 118 | return -ENOMEM; |
120 | } | ||
121 | platform_set_drvdata(pdev, wdt); | 119 | platform_set_drvdata(pdev, wdt); |
122 | 120 | ||
123 | spin_lock_init(&wdt->lock); | 121 | spin_lock_init(&wdt->lock); |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index b4021a2b459b..b61fcc535979 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/bcm47xx_wdt.h> | 16 | #include <linux/bcm47xx_wdt.h> |
17 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
22 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 4eb188b87f8e..5a8e879a430a 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
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> | ||
19 | #include <linux/io.h> | 18 | #include <linux/io.h> |
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/miscdevice.h> | 20 | #include <linux/miscdevice.h> |
@@ -45,7 +44,6 @@ | |||
45 | static struct { | 44 | static struct { |
46 | void __iomem *regs; | 45 | void __iomem *regs; |
47 | struct timer_list timer; | 46 | struct timer_list timer; |
48 | int default_ticks; | ||
49 | unsigned long inuse; | 47 | unsigned long inuse; |
50 | atomic_t ticks; | 48 | atomic_t ticks; |
51 | } bcm63xx_wdt_device; | 49 | } bcm63xx_wdt_device; |
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index f1b8d555080e..a8dbceb32914 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -138,14 +138,6 @@ static void __booke_wdt_enable(void *data) | |||
138 | val &= ~WDTP_MASK; | 138 | val &= ~WDTP_MASK; |
139 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); | 139 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); |
140 | 140 | ||
141 | #ifdef CONFIG_PPC_BOOK3E_64 | ||
142 | /* | ||
143 | * Crit ints are currently broken on PPC64 Book-E, so | ||
144 | * just disable them for now. | ||
145 | */ | ||
146 | val &= ~TCR_WIE; | ||
147 | #endif | ||
148 | |||
149 | mtspr(SPRN_TCR, val); | 141 | mtspr(SPRN_TCR, val); |
150 | } | 142 | } |
151 | 143 | ||
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index f7ae49edb518..6d03e8e30f8b 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
32 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
33 | #include <linux/completion.h> | 32 | #include <linux/completion.h> |
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 213225edd059..e55ed702209f 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/major.h> | 23 | #include <linux/major.h> |
24 | #include <linux/init.h> | ||
25 | #include <linux/miscdevice.h> | 24 | #include <linux/miscdevice.h> |
26 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
27 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index f09c54e9686f..2e9589652e1e 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c | |||
@@ -185,7 +185,6 @@ static int da9052_wdt_probe(struct platform_device *pdev) | |||
185 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), | 185 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), |
186 | GFP_KERNEL); | 186 | GFP_KERNEL); |
187 | if (!driver_data) { | 187 | if (!driver_data) { |
188 | dev_err(da9052->dev, "Unable to alloacate watchdog device\n"); | ||
189 | ret = -ENOMEM; | 188 | ret = -ENOMEM; |
190 | goto err; | 189 | goto err; |
191 | } | 190 | } |
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 575f37a965a4..495089d8dbfe 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c | |||
@@ -151,10 +151,8 @@ static int da9055_wdt_probe(struct platform_device *pdev) | |||
151 | 151 | ||
152 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), | 152 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), |
153 | GFP_KERNEL); | 153 | GFP_KERNEL); |
154 | if (!driver_data) { | 154 | if (!driver_data) |
155 | dev_err(da9055->dev, "Failed to allocate watchdog device\n"); | ||
156 | return -ENOMEM; | 155 | return -ENOMEM; |
157 | } | ||
158 | 156 | ||
159 | driver_data->da9055 = da9055; | 157 | driver_data->da9055 = da9055; |
160 | 158 | ||
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index b1bae03742a9..d09ad2254b57 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/watchdog.h> | 18 | #include <linux/watchdog.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
21 | #include <linux/io.h> | 20 | #include <linux/io.h> |
22 | #include <linux/device.h> | 21 | #include <linux/device.h> |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index d1d07f2f69df..5f54e1e5819a 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -118,16 +118,9 @@ static int ep93xx_wdt_probe(struct platform_device *pdev) | |||
118 | int err; | 118 | int err; |
119 | 119 | ||
120 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 120 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
121 | if (!res) | 121 | mmio_base = devm_ioremap_resource(&pdev->dev, res); |
122 | return -ENXIO; | 122 | if (IS_ERR(mmio_base)) |
123 | 123 | return PTR_ERR(mmio_base); | |
124 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
125 | resource_size(res), pdev->name)) | ||
126 | return -EBUSY; | ||
127 | |||
128 | mmio_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
129 | if (!mmio_base) | ||
130 | return -ENXIO; | ||
131 | 124 | ||
132 | if (timeout < 1 || timeout > 3600) { | 125 | if (timeout < 1 || timeout > 3600) { |
133 | timeout = WDT_TIMEOUT; | 126 | timeout = WDT_TIMEOUT; |
@@ -172,9 +165,9 @@ static struct platform_driver ep93xx_wdt_driver = { | |||
172 | 165 | ||
173 | module_platform_driver(ep93xx_wdt_driver); | 166 | module_platform_driver(ep93xx_wdt_driver); |
174 | 167 | ||
175 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," | 168 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>"); |
176 | "Alessandro Zummo <a.zummo@towertech.it>," | 169 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
177 | "H Hartley Sweeten <hsweeten@visionengravers.com>"); | 170 | MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); |
178 | MODULE_DESCRIPTION("EP93xx Watchdog"); | 171 | MODULE_DESCRIPTION("EP93xx Watchdog"); |
179 | MODULE_LICENSE("GPL"); | 172 | MODULE_LICENSE("GPL"); |
180 | MODULE_VERSION(WDT_VERSION); | 173 | MODULE_VERSION(WDT_VERSION); |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 4a6ae84b42bc..4c43e3fa8bd2 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c | |||
@@ -215,7 +215,7 @@ static struct miscdevice geodewdt_miscdev = { | |||
215 | .fops = &geodewdt_fops, | 215 | .fops = &geodewdt_fops, |
216 | }; | 216 | }; |
217 | 217 | ||
218 | static int geodewdt_probe(struct platform_device *dev) | 218 | static int __init geodewdt_probe(struct platform_device *dev) |
219 | { | 219 | { |
220 | int ret; | 220 | int ret; |
221 | 221 | ||
@@ -255,7 +255,6 @@ static void geodewdt_shutdown(struct platform_device *dev) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | static struct platform_driver geodewdt_driver = { | 257 | static struct platform_driver geodewdt_driver = { |
258 | .probe = geodewdt_probe, | ||
259 | .remove = geodewdt_remove, | 258 | .remove = geodewdt_remove, |
260 | .shutdown = geodewdt_shutdown, | 259 | .shutdown = geodewdt_shutdown, |
261 | .driver = { | 260 | .driver = { |
@@ -268,20 +267,18 @@ static int __init geodewdt_init(void) | |||
268 | { | 267 | { |
269 | int ret; | 268 | int ret; |
270 | 269 | ||
271 | ret = platform_driver_register(&geodewdt_driver); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | |||
275 | geodewdt_platform_device = platform_device_register_simple(DRV_NAME, | 270 | geodewdt_platform_device = platform_device_register_simple(DRV_NAME, |
276 | -1, NULL, 0); | 271 | -1, NULL, 0); |
277 | if (IS_ERR(geodewdt_platform_device)) { | 272 | if (IS_ERR(geodewdt_platform_device)) |
278 | ret = PTR_ERR(geodewdt_platform_device); | 273 | return PTR_ERR(geodewdt_platform_device); |
274 | |||
275 | ret = platform_driver_probe(&geodewdt_driver, geodewdt_probe); | ||
276 | if (ret) | ||
279 | goto err; | 277 | goto err; |
280 | } | ||
281 | 278 | ||
282 | return 0; | 279 | return 0; |
283 | err: | 280 | err: |
284 | platform_driver_unregister(&geodewdt_driver); | 281 | platform_device_unregister(geodewdt_platform_device); |
285 | return ret; | 282 | return ret; |
286 | } | 283 | } |
287 | 284 | ||
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 2b75e8b47279..75d2243b94f5 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | 20 | #include <linux/io.h> |
22 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
23 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 25a2bfdb4e9d..d7befd58b391 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/miscdevice.h> | 37 | #include <linux/miscdevice.h> |
38 | #include <linux/watchdog.h> | 38 | #include <linux/watchdog.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
41 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
42 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 04f8af65acfd..0e6c0333f775 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -347,15 +347,15 @@ static const struct watchdog_info ident = { | |||
347 | static const struct watchdog_ops iTCO_wdt_ops = { | 347 | static const struct watchdog_ops iTCO_wdt_ops = { |
348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
349 | .start = iTCO_wdt_start, | 349 | .start = iTCO_wdt_start, |
350 | .stop = iTCO_wdt_stop, | 350 | .stop = iTCO_wdt_stop, |
351 | .ping = iTCO_wdt_ping, | 351 | .ping = iTCO_wdt_ping, |
352 | .set_timeout = iTCO_wdt_set_timeout, | 352 | .set_timeout = iTCO_wdt_set_timeout, |
353 | .get_timeleft = iTCO_wdt_get_timeleft, | 353 | .get_timeleft = iTCO_wdt_get_timeleft, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | static struct watchdog_device iTCO_wdt_watchdog_dev = { | 356 | static struct watchdog_device iTCO_wdt_watchdog_dev = { |
357 | .info = &ident, | 357 | .info = &ident, |
358 | .ops = &iTCO_wdt_ops, | 358 | .ops = &iTCO_wdt_ops, |
359 | }; | 359 | }; |
360 | 360 | ||
361 | /* | 361 | /* |
@@ -485,7 +485,7 @@ static int iTCO_wdt_probe(struct platform_device *dev) | |||
485 | iTCO_wdt_watchdog_dev.bootstatus = 0; | 485 | iTCO_wdt_watchdog_dev.bootstatus = 0; |
486 | iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT; | 486 | iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT; |
487 | watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout); | 487 | watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout); |
488 | iTCO_wdt_watchdog_dev.parent = dev->dev.parent; | 488 | iTCO_wdt_watchdog_dev.parent = &dev->dev; |
489 | 489 | ||
490 | /* Make sure the watchdog is not running */ | 490 | /* Make sure the watchdog is not running */ |
491 | iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); | 491 | iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 7ae36690c449..4247c498ee78 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -277,7 +277,7 @@ static struct miscdevice ibwdt_miscdev = { | |||
277 | * Init & exit routines | 277 | * Init & exit routines |
278 | */ | 278 | */ |
279 | 279 | ||
280 | static int ibwdt_probe(struct platform_device *dev) | 280 | static int __init ibwdt_probe(struct platform_device *dev) |
281 | { | 281 | { |
282 | int res; | 282 | int res; |
283 | 283 | ||
@@ -336,7 +336,6 @@ static void ibwdt_shutdown(struct platform_device *dev) | |||
336 | } | 336 | } |
337 | 337 | ||
338 | static struct platform_driver ibwdt_driver = { | 338 | static struct platform_driver ibwdt_driver = { |
339 | .probe = ibwdt_probe, | ||
340 | .remove = ibwdt_remove, | 339 | .remove = ibwdt_remove, |
341 | .shutdown = ibwdt_shutdown, | 340 | .shutdown = ibwdt_shutdown, |
342 | .driver = { | 341 | .driver = { |
@@ -351,21 +350,19 @@ static int __init ibwdt_init(void) | |||
351 | 350 | ||
352 | pr_info("WDT driver for IB700 single board computer initialising\n"); | 351 | pr_info("WDT driver for IB700 single board computer initialising\n"); |
353 | 352 | ||
354 | err = platform_driver_register(&ibwdt_driver); | ||
355 | if (err) | ||
356 | return err; | ||
357 | |||
358 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, | 353 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, |
359 | -1, NULL, 0); | 354 | -1, NULL, 0); |
360 | if (IS_ERR(ibwdt_platform_device)) { | 355 | if (IS_ERR(ibwdt_platform_device)) |
361 | err = PTR_ERR(ibwdt_platform_device); | 356 | return PTR_ERR(ibwdt_platform_device); |
362 | goto unreg_platform_driver; | 357 | |
363 | } | 358 | err = platform_driver_probe(&ibwdt_driver, ibwdt_probe); |
359 | if (err) | ||
360 | goto unreg_platform_device; | ||
364 | 361 | ||
365 | return 0; | 362 | return 0; |
366 | 363 | ||
367 | unreg_platform_driver: | 364 | unreg_platform_device: |
368 | platform_driver_unregister(&ibwdt_driver); | 365 | platform_device_unregister(ibwdt_platform_device); |
369 | return err; | 366 | return err; |
370 | } | 367 | } |
371 | 368 | ||
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index db0a34460e57..366b0474f278 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c | |||
@@ -360,7 +360,7 @@ struct ibmasr_id { | |||
360 | int type; | 360 | int type; |
361 | }; | 361 | }; |
362 | 362 | ||
363 | static struct ibmasr_id __initdata ibmasr_id_table[] = { | 363 | static struct ibmasr_id ibmasr_id_table[] __initdata = { |
364 | { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ }, | 364 | { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ }, |
365 | { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL }, | 365 | { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL }, |
366 | { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER }, | 366 | { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER }, |
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index 1b5c25a47b87..5d20cdd30efe 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c | |||
@@ -41,24 +41,15 @@ MODULE_PARM_DESC(nowayout, | |||
41 | 41 | ||
42 | static void indydog_start(void) | 42 | static void indydog_start(void) |
43 | { | 43 | { |
44 | u32 mc_ctrl0; | ||
45 | |||
46 | spin_lock(&indydog_lock); | 44 | spin_lock(&indydog_lock); |
47 | mc_ctrl0 = sgimc->cpuctrl0; | 45 | sgimc->cpuctrl0 |= SGIMC_CCTRL0_WDOG; |
48 | mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; | ||
49 | sgimc->cpuctrl0 = mc_ctrl0; | ||
50 | spin_unlock(&indydog_lock); | 46 | spin_unlock(&indydog_lock); |
51 | } | 47 | } |
52 | 48 | ||
53 | static void indydog_stop(void) | 49 | static void indydog_stop(void) |
54 | { | 50 | { |
55 | u32 mc_ctrl0; | ||
56 | |||
57 | spin_lock(&indydog_lock); | 51 | spin_lock(&indydog_lock); |
58 | 52 | sgimc->cpuctrl0 &= ~SGIMC_CCTRL0_WDOG; | |
59 | mc_ctrl0 = sgimc->cpuctrl0; | ||
60 | mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; | ||
61 | sgimc->cpuctrl0 = mc_ctrl0; | ||
62 | spin_unlock(&indydog_lock); | 53 | spin_unlock(&indydog_lock); |
63 | 54 | ||
64 | pr_info("Stopped watchdog timer\n"); | 55 | pr_info("Stopped watchdog timer\n"); |
diff --git a/drivers/watchdog/intel_scu_watchdog.c b/drivers/watchdog/intel_scu_watchdog.c index e13e65e996aa..0caab6241eb7 100644 --- a/drivers/watchdog/intel_scu_watchdog.c +++ b/drivers/watchdog/intel_scu_watchdog.c | |||
@@ -211,7 +211,6 @@ static int intel_scu_set_heartbeat(u32 t) | |||
211 | int ipc_ret; | 211 | int ipc_ret; |
212 | int retry_count; | 212 | int retry_count; |
213 | u32 soft_value; | 213 | u32 soft_value; |
214 | u32 hw_pre_value; | ||
215 | u32 hw_value; | 214 | u32 hw_value; |
216 | 215 | ||
217 | watchdog_device.timer_set = t; | 216 | watchdog_device.timer_set = t; |
@@ -273,8 +272,7 @@ static int intel_scu_set_heartbeat(u32 t) | |||
273 | watchdog_device.timer_load_count_addr); | 272 | watchdog_device.timer_load_count_addr); |
274 | 273 | ||
275 | /* read count value before starting timer */ | 274 | /* read count value before starting timer */ |
276 | hw_pre_value = ioread32(watchdog_device.timer_load_count_addr); | 275 | ioread32(watchdog_device.timer_load_count_addr); |
277 | hw_pre_value = hw_pre_value & 0xFFFF0000; | ||
278 | 276 | ||
279 | /* Start the timer */ | 277 | /* Start the timer */ |
280 | iowrite32(0x00000003, watchdog_device.timer_control_addr); | 278 | iowrite32(0x00000003, watchdog_device.timer_control_addr); |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index e2bba68ae71e..0b93739c0106 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | /* Defaults for Module Parameter */ | 55 | /* Defaults for Module Parameter */ |
56 | #define DEFAULT_NOGAMEPORT 0 | 56 | #define DEFAULT_NOGAMEPORT 0 |
57 | #define DEFAULT_NOCIR 0 | ||
57 | #define DEFAULT_EXCLUSIVE 1 | 58 | #define DEFAULT_EXCLUSIVE 1 |
58 | #define DEFAULT_TIMEOUT 60 | 59 | #define DEFAULT_TIMEOUT 60 |
59 | #define DEFAULT_TESTMODE 0 | 60 | #define DEFAULT_TESTMODE 0 |
@@ -136,11 +137,13 @@ | |||
136 | #define WDTS_LOCKED 3 | 137 | #define WDTS_LOCKED 3 |
137 | #define WDTS_USE_GP 4 | 138 | #define WDTS_USE_GP 4 |
138 | #define WDTS_EXPECTED 5 | 139 | #define WDTS_EXPECTED 5 |
140 | #define WDTS_USE_CIR 6 | ||
139 | 141 | ||
140 | static unsigned int base, gpact, ciract, max_units, chip_type; | 142 | static unsigned int base, gpact, ciract, max_units, chip_type; |
141 | static unsigned long wdt_status; | 143 | static unsigned long wdt_status; |
142 | 144 | ||
143 | static int nogameport = DEFAULT_NOGAMEPORT; | 145 | static int nogameport = DEFAULT_NOGAMEPORT; |
146 | static int nocir = DEFAULT_NOCIR; | ||
144 | static int exclusive = DEFAULT_EXCLUSIVE; | 147 | static int exclusive = DEFAULT_EXCLUSIVE; |
145 | static int timeout = DEFAULT_TIMEOUT; | 148 | static int timeout = DEFAULT_TIMEOUT; |
146 | static int testmode = DEFAULT_TESTMODE; | 149 | static int testmode = DEFAULT_TESTMODE; |
@@ -149,6 +152,9 @@ static bool nowayout = DEFAULT_NOWAYOUT; | |||
149 | module_param(nogameport, int, 0); | 152 | module_param(nogameport, int, 0); |
150 | MODULE_PARM_DESC(nogameport, "Forbid the activation of game port, default=" | 153 | MODULE_PARM_DESC(nogameport, "Forbid the activation of game port, default=" |
151 | __MODULE_STRING(DEFAULT_NOGAMEPORT)); | 154 | __MODULE_STRING(DEFAULT_NOGAMEPORT)); |
155 | module_param(nocir, int, 0); | ||
156 | MODULE_PARM_DESC(nocir, "Forbid the use of Consumer IR interrupts to reset timer, default=" | ||
157 | __MODULE_STRING(DEFAULT_NOCIR)); | ||
152 | module_param(exclusive, int, 0); | 158 | module_param(exclusive, int, 0); |
153 | MODULE_PARM_DESC(exclusive, "Watchdog exclusive device open, default=" | 159 | MODULE_PARM_DESC(exclusive, "Watchdog exclusive device open, default=" |
154 | __MODULE_STRING(DEFAULT_EXCLUSIVE)); | 160 | __MODULE_STRING(DEFAULT_EXCLUSIVE)); |
@@ -258,9 +264,17 @@ static void wdt_keepalive(void) | |||
258 | { | 264 | { |
259 | if (test_bit(WDTS_USE_GP, &wdt_status)) | 265 | if (test_bit(WDTS_USE_GP, &wdt_status)) |
260 | inb(base); | 266 | inb(base); |
261 | else | 267 | else if (test_bit(WDTS_USE_CIR, &wdt_status)) |
262 | /* The timer reloads with around 5 msec delay */ | 268 | /* The timer reloads with around 5 msec delay */ |
263 | outb(0x55, CIR_DR(base)); | 269 | outb(0x55, CIR_DR(base)); |
270 | else { | ||
271 | if (superio_enter()) | ||
272 | return; | ||
273 | |||
274 | superio_select(GPIO); | ||
275 | wdt_update_timeout(); | ||
276 | superio_exit(); | ||
277 | } | ||
264 | set_bit(WDTS_KEEPALIVE, &wdt_status); | 278 | set_bit(WDTS_KEEPALIVE, &wdt_status); |
265 | } | 279 | } |
266 | 280 | ||
@@ -273,7 +287,7 @@ static int wdt_start(void) | |||
273 | superio_select(GPIO); | 287 | superio_select(GPIO); |
274 | if (test_bit(WDTS_USE_GP, &wdt_status)) | 288 | if (test_bit(WDTS_USE_GP, &wdt_status)) |
275 | superio_outb(WDT_GAMEPORT, WDTCTRL); | 289 | superio_outb(WDT_GAMEPORT, WDTCTRL); |
276 | else | 290 | else if (test_bit(WDTS_USE_CIR, &wdt_status)) |
277 | superio_outb(WDT_CIRINT, WDTCTRL); | 291 | superio_outb(WDT_CIRINT, WDTCTRL); |
278 | wdt_update_timeout(); | 292 | wdt_update_timeout(); |
279 | 293 | ||
@@ -660,7 +674,7 @@ static int __init it87_wdt_init(void) | |||
660 | } | 674 | } |
661 | 675 | ||
662 | /* If we haven't Gameport support, try to get CIR support */ | 676 | /* If we haven't Gameport support, try to get CIR support */ |
663 | if (!test_bit(WDTS_USE_GP, &wdt_status)) { | 677 | if (!nocir && !test_bit(WDTS_USE_GP, &wdt_status)) { |
664 | if (!request_region(CIR_BASE, 8, WATCHDOG_NAME)) { | 678 | if (!request_region(CIR_BASE, 8, WATCHDOG_NAME)) { |
665 | if (gp_rreq_fail) | 679 | if (gp_rreq_fail) |
666 | pr_err("I/O Address 0x%04x and 0x%04x already in use\n", | 680 | pr_err("I/O Address 0x%04x and 0x%04x already in use\n", |
@@ -682,6 +696,7 @@ static int __init it87_wdt_init(void) | |||
682 | superio_select(GAMEPORT); | 696 | superio_select(GAMEPORT); |
683 | superio_outb(gpact, ACTREG); | 697 | superio_outb(gpact, ACTREG); |
684 | } | 698 | } |
699 | set_bit(WDTS_USE_CIR, &wdt_status); | ||
685 | } | 700 | } |
686 | 701 | ||
687 | if (timeout < 1 || timeout > max_units * 60) { | 702 | if (timeout < 1 || timeout > max_units * 60) { |
@@ -707,7 +722,7 @@ static int __init it87_wdt_init(void) | |||
707 | } | 722 | } |
708 | 723 | ||
709 | /* Initialize CIR to use it as keepalive source */ | 724 | /* Initialize CIR to use it as keepalive source */ |
710 | if (!test_bit(WDTS_USE_GP, &wdt_status)) { | 725 | if (test_bit(WDTS_USE_CIR, &wdt_status)) { |
711 | outb(0x00, CIR_RCR(base)); | 726 | outb(0x00, CIR_RCR(base)); |
712 | outb(0xc0, CIR_TCR1(base)); | 727 | outb(0xc0, CIR_TCR1(base)); |
713 | outb(0x5c, CIR_TCR2(base)); | 728 | outb(0x5c, CIR_TCR2(base)); |
@@ -717,9 +732,9 @@ static int __init it87_wdt_init(void) | |||
717 | outb(0x09, CIR_IER(base)); | 732 | outb(0x09, CIR_IER(base)); |
718 | } | 733 | } |
719 | 734 | ||
720 | pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d exclusive=%d nogameport=%d)\n", | 735 | pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d exclusive=%d nogameport=%d nocir=%d)\n", |
721 | chip_type, chip_rev, timeout, | 736 | chip_type, chip_rev, timeout, |
722 | nowayout, testmode, exclusive, nogameport); | 737 | nowayout, testmode, exclusive, nogameport, nocir); |
723 | 738 | ||
724 | superio_exit(); | 739 | superio_exit(); |
725 | return 0; | 740 | return 0; |
@@ -727,8 +742,10 @@ static int __init it87_wdt_init(void) | |||
727 | err_out_reboot: | 742 | err_out_reboot: |
728 | unregister_reboot_notifier(&wdt_notifier); | 743 | unregister_reboot_notifier(&wdt_notifier); |
729 | err_out_region: | 744 | err_out_region: |
730 | release_region(base, test_bit(WDTS_USE_GP, &wdt_status) ? 1 : 8); | 745 | if (test_bit(WDTS_USE_GP, &wdt_status)) |
731 | if (!test_bit(WDTS_USE_GP, &wdt_status)) { | 746 | release_region(base, 1); |
747 | else if (test_bit(WDTS_USE_CIR, &wdt_status)) { | ||
748 | release_region(base, 8); | ||
732 | superio_select(CIR); | 749 | superio_select(CIR); |
733 | superio_outb(ciract, ACTREG); | 750 | superio_outb(ciract, ACTREG); |
734 | } | 751 | } |
@@ -754,7 +771,7 @@ static void __exit it87_wdt_exit(void) | |||
754 | if (test_bit(WDTS_USE_GP, &wdt_status)) { | 771 | if (test_bit(WDTS_USE_GP, &wdt_status)) { |
755 | superio_select(GAMEPORT); | 772 | superio_select(GAMEPORT); |
756 | superio_outb(gpact, ACTREG); | 773 | superio_outb(gpact, ACTREG); |
757 | } else { | 774 | } else if (test_bit(WDTS_USE_CIR, &wdt_status)) { |
758 | superio_select(CIR); | 775 | superio_select(CIR); |
759 | superio_outb(ciract, ACTREG); | 776 | superio_outb(ciract, ACTREG); |
760 | } | 777 | } |
@@ -763,7 +780,11 @@ static void __exit it87_wdt_exit(void) | |||
763 | 780 | ||
764 | misc_deregister(&wdt_miscdev); | 781 | misc_deregister(&wdt_miscdev); |
765 | unregister_reboot_notifier(&wdt_notifier); | 782 | unregister_reboot_notifier(&wdt_notifier); |
766 | release_region(base, test_bit(WDTS_USE_GP, &wdt_status) ? 1 : 8); | 783 | |
784 | if (test_bit(WDTS_USE_GP, &wdt_status)) | ||
785 | release_region(base, 1); | ||
786 | else if (test_bit(WDTS_USE_CIR, &wdt_status)) | ||
787 | release_region(base, 8); | ||
767 | } | 788 | } |
768 | 789 | ||
769 | module_init(it87_wdt_init); | 790 | module_init(it87_wdt_init); |
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 3aa50cfa335f..91e45ca589e6 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/init.h> | ||
22 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
23 | #include <linux/io.h> | 22 | #include <linux/io.h> |
24 | #include <linux/device.h> | 23 | #include <linux/device.h> |
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index bdb3f4a5b27c..0e9cc6f5a919 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
25 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
26 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index c1f65b4c0aa4..7831955cd9e1 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c | |||
@@ -237,6 +237,7 @@ static const struct of_device_id mpc8xxx_wdt_match[] = { | |||
237 | .compatible = "fsl,mpc823-wdt", | 237 | .compatible = "fsl,mpc823-wdt", |
238 | .data = &(struct mpc8xxx_wdt_type) { | 238 | .data = &(struct mpc8xxx_wdt_type) { |
239 | .prescaler = 0x800, | 239 | .prescaler = 0x800, |
240 | .hw_enabled = true, | ||
240 | }, | 241 | }, |
241 | }, | 242 | }, |
242 | {}, | 243 | {}, |
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index edb31ffd7927..ff27c4ac96e4 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
42 | #include <linux/fs.h> | 42 | #include <linux/fs.h> |
43 | #include <linux/init.h> | ||
44 | #include <linux/ioport.h> | 43 | #include <linux/ioport.h> |
45 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
46 | #include <linux/completion.h> | 45 | #include <linux/completion.h> |
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c index a0d893b0930e..7135803ca1a3 100644 --- a/drivers/watchdog/nuc900_wdt.c +++ b/drivers/watchdog/nuc900_wdt.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | 15 | #include <linux/io.h> |
17 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index fb57103c8ebc..57ccae8327ff 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt | 2 | * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt |
3 | * | 3 | * |
4 | * (C) Copyright 2013 - 2014 Xilinx, Inc. | ||
4 | * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>) | 5 | * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>) |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
@@ -9,18 +10,13 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
10 | */ | 11 | */ |
11 | 12 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #include <linux/err.h> |
13 | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/fs.h> | ||
18 | #include <linux/miscdevice.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
21 | #include <linux/watchdog.h> | 18 | #include <linux/watchdog.h> |
22 | #include <linux/io.h> | 19 | #include <linux/io.h> |
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/of.h> | 20 | #include <linux/of.h> |
25 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
26 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
@@ -43,102 +39,103 @@ | |||
43 | #define XWT_TIMER_FAILED 0xFFFFFFFF | 39 | #define XWT_TIMER_FAILED 0xFFFFFFFF |
44 | 40 | ||
45 | #define WATCHDOG_NAME "Xilinx Watchdog" | 41 | #define WATCHDOG_NAME "Xilinx Watchdog" |
46 | #define PFX WATCHDOG_NAME ": " | ||
47 | 42 | ||
48 | struct xwdt_device { | 43 | struct xwdt_device { |
49 | struct resource res; | ||
50 | void __iomem *base; | 44 | void __iomem *base; |
51 | u32 nowayout; | ||
52 | u32 wdt_interval; | 45 | u32 wdt_interval; |
53 | u32 boot_status; | 46 | spinlock_t spinlock; |
47 | struct watchdog_device xilinx_wdt_wdd; | ||
54 | }; | 48 | }; |
55 | 49 | ||
56 | static struct xwdt_device xdev; | 50 | static int xilinx_wdt_start(struct watchdog_device *wdd) |
57 | |||
58 | static u32 timeout; | ||
59 | static u32 control_status_reg; | ||
60 | static u8 expect_close; | ||
61 | static u8 no_timeout; | ||
62 | static unsigned long driver_open; | ||
63 | |||
64 | static DEFINE_SPINLOCK(spinlock); | ||
65 | |||
66 | static void xwdt_start(void) | ||
67 | { | 51 | { |
68 | spin_lock(&spinlock); | 52 | u32 control_status_reg; |
53 | struct xwdt_device *xdev = watchdog_get_drvdata(wdd); | ||
54 | |||
55 | spin_lock(&xdev->spinlock); | ||
69 | 56 | ||
70 | /* Clean previous status and enable the watchdog timer */ | 57 | /* Clean previous status and enable the watchdog timer */ |
71 | control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); | 58 | control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); |
72 | control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); | 59 | control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); |
73 | 60 | ||
74 | iowrite32((control_status_reg | XWT_CSR0_EWDT1_MASK), | 61 | iowrite32((control_status_reg | XWT_CSR0_EWDT1_MASK), |
75 | xdev.base + XWT_TWCSR0_OFFSET); | 62 | xdev->base + XWT_TWCSR0_OFFSET); |
63 | |||
64 | iowrite32(XWT_CSRX_EWDT2_MASK, xdev->base + XWT_TWCSR1_OFFSET); | ||
76 | 65 | ||
77 | iowrite32(XWT_CSRX_EWDT2_MASK, xdev.base + XWT_TWCSR1_OFFSET); | 66 | spin_unlock(&xdev->spinlock); |
78 | 67 | ||
79 | spin_unlock(&spinlock); | 68 | return 0; |
80 | } | 69 | } |
81 | 70 | ||
82 | static void xwdt_stop(void) | 71 | static int xilinx_wdt_stop(struct watchdog_device *wdd) |
83 | { | 72 | { |
84 | spin_lock(&spinlock); | 73 | u32 control_status_reg; |
74 | struct xwdt_device *xdev = watchdog_get_drvdata(wdd); | ||
75 | |||
76 | spin_lock(&xdev->spinlock); | ||
85 | 77 | ||
86 | control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); | 78 | control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); |
87 | 79 | ||
88 | iowrite32((control_status_reg & ~XWT_CSR0_EWDT1_MASK), | 80 | iowrite32((control_status_reg & ~XWT_CSR0_EWDT1_MASK), |
89 | xdev.base + XWT_TWCSR0_OFFSET); | 81 | xdev->base + XWT_TWCSR0_OFFSET); |
90 | 82 | ||
91 | iowrite32(0, xdev.base + XWT_TWCSR1_OFFSET); | 83 | iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET); |
92 | 84 | ||
93 | spin_unlock(&spinlock); | 85 | spin_unlock(&xdev->spinlock); |
94 | pr_info("Stopped!\n"); | 86 | pr_info("Stopped!\n"); |
87 | |||
88 | return 0; | ||
95 | } | 89 | } |
96 | 90 | ||
97 | static void xwdt_keepalive(void) | 91 | static int xilinx_wdt_keepalive(struct watchdog_device *wdd) |
98 | { | 92 | { |
99 | spin_lock(&spinlock); | 93 | u32 control_status_reg; |
94 | struct xwdt_device *xdev = watchdog_get_drvdata(wdd); | ||
100 | 95 | ||
101 | control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); | 96 | spin_lock(&xdev->spinlock); |
102 | control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); | ||
103 | iowrite32(control_status_reg, xdev.base + XWT_TWCSR0_OFFSET); | ||
104 | 97 | ||
105 | spin_unlock(&spinlock); | 98 | control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); |
106 | } | 99 | control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); |
100 | iowrite32(control_status_reg, xdev->base + XWT_TWCSR0_OFFSET); | ||
107 | 101 | ||
108 | static void xwdt_get_status(int *status) | 102 | spin_unlock(&xdev->spinlock); |
109 | { | ||
110 | int new_status; | ||
111 | 103 | ||
112 | spin_lock(&spinlock); | 104 | return 0; |
105 | } | ||
113 | 106 | ||
114 | control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); | 107 | static const struct watchdog_info xilinx_wdt_ident = { |
115 | new_status = ((control_status_reg & | 108 | .options = WDIOF_MAGICCLOSE | |
116 | (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK)) != 0); | 109 | WDIOF_KEEPALIVEPING, |
117 | spin_unlock(&spinlock); | 110 | .firmware_version = 1, |
111 | .identity = WATCHDOG_NAME, | ||
112 | }; | ||
118 | 113 | ||
119 | *status = 0; | 114 | static const struct watchdog_ops xilinx_wdt_ops = { |
120 | if (new_status & 1) | 115 | .owner = THIS_MODULE, |
121 | *status |= WDIOF_CARDRESET; | 116 | .start = xilinx_wdt_start, |
122 | } | 117 | .stop = xilinx_wdt_stop, |
118 | .ping = xilinx_wdt_keepalive, | ||
119 | }; | ||
123 | 120 | ||
124 | static u32 xwdt_selftest(void) | 121 | static u32 xwdt_selftest(struct xwdt_device *xdev) |
125 | { | 122 | { |
126 | int i; | 123 | int i; |
127 | u32 timer_value1; | 124 | u32 timer_value1; |
128 | u32 timer_value2; | 125 | u32 timer_value2; |
129 | 126 | ||
130 | spin_lock(&spinlock); | 127 | spin_lock(&xdev->spinlock); |
131 | 128 | ||
132 | timer_value1 = ioread32(xdev.base + XWT_TBR_OFFSET); | 129 | timer_value1 = ioread32(xdev->base + XWT_TBR_OFFSET); |
133 | timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET); | 130 | timer_value2 = ioread32(xdev->base + XWT_TBR_OFFSET); |
134 | 131 | ||
135 | for (i = 0; | 132 | for (i = 0; |
136 | ((i <= XWT_MAX_SELFTEST_LOOP_COUNT) && | 133 | ((i <= XWT_MAX_SELFTEST_LOOP_COUNT) && |
137 | (timer_value2 == timer_value1)); i++) { | 134 | (timer_value2 == timer_value1)); i++) { |
138 | timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET); | 135 | timer_value2 = ioread32(xdev->base + XWT_TBR_OFFSET); |
139 | } | 136 | } |
140 | 137 | ||
141 | spin_unlock(&spinlock); | 138 | spin_unlock(&xdev->spinlock); |
142 | 139 | ||
143 | if (timer_value2 != timer_value1) | 140 | if (timer_value2 != timer_value1) |
144 | return ~XWT_TIMER_FAILED; | 141 | return ~XWT_TIMER_FAILED; |
@@ -146,238 +143,83 @@ static u32 xwdt_selftest(void) | |||
146 | return XWT_TIMER_FAILED; | 143 | return XWT_TIMER_FAILED; |
147 | } | 144 | } |
148 | 145 | ||
149 | static int xwdt_open(struct inode *inode, struct file *file) | ||
150 | { | ||
151 | /* Only one process can handle the wdt at a time */ | ||
152 | if (test_and_set_bit(0, &driver_open)) | ||
153 | return -EBUSY; | ||
154 | |||
155 | /* Make sure that the module are always loaded...*/ | ||
156 | if (xdev.nowayout) | ||
157 | __module_get(THIS_MODULE); | ||
158 | |||
159 | xwdt_start(); | ||
160 | pr_info("Started...\n"); | ||
161 | |||
162 | return nonseekable_open(inode, file); | ||
163 | } | ||
164 | |||
165 | static int xwdt_release(struct inode *inode, struct file *file) | ||
166 | { | ||
167 | if (expect_close == 42) { | ||
168 | xwdt_stop(); | ||
169 | } else { | ||
170 | pr_crit("Unexpected close, not stopping watchdog!\n"); | ||
171 | xwdt_keepalive(); | ||
172 | } | ||
173 | |||
174 | clear_bit(0, &driver_open); | ||
175 | expect_close = 0; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * xwdt_write: | ||
181 | * @file: file handle to the watchdog | ||
182 | * @buf: buffer to write (unused as data does not matter here | ||
183 | * @count: count of bytes | ||
184 | * @ppos: pointer to the position to write. No seeks allowed | ||
185 | * | ||
186 | * A write to a watchdog device is defined as a keepalive signal. Any | ||
187 | * write of data will do, as we don't define content meaning. | ||
188 | */ | ||
189 | static ssize_t xwdt_write(struct file *file, const char __user *buf, | ||
190 | size_t len, loff_t *ppos) | ||
191 | { | ||
192 | if (len) { | ||
193 | if (!xdev.nowayout) { | ||
194 | size_t i; | ||
195 | |||
196 | /* In case it was set long ago */ | ||
197 | expect_close = 0; | ||
198 | |||
199 | for (i = 0; i != len; i++) { | ||
200 | char c; | ||
201 | |||
202 | if (get_user(c, buf + i)) | ||
203 | return -EFAULT; | ||
204 | if (c == 'V') | ||
205 | expect_close = 42; | ||
206 | } | ||
207 | } | ||
208 | xwdt_keepalive(); | ||
209 | } | ||
210 | return len; | ||
211 | } | ||
212 | |||
213 | static const struct watchdog_info ident = { | ||
214 | .options = WDIOF_MAGICCLOSE | | ||
215 | WDIOF_KEEPALIVEPING, | ||
216 | .firmware_version = 1, | ||
217 | .identity = WATCHDOG_NAME, | ||
218 | }; | ||
219 | |||
220 | /* | ||
221 | * xwdt_ioctl: | ||
222 | * @file: file handle to the device | ||
223 | * @cmd: watchdog command | ||
224 | * @arg: argument pointer | ||
225 | * | ||
226 | * The watchdog API defines a common set of functions for all watchdogs | ||
227 | * according to their available features. | ||
228 | */ | ||
229 | static long xwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
230 | { | ||
231 | int status; | ||
232 | |||
233 | union { | ||
234 | struct watchdog_info __user *ident; | ||
235 | int __user *i; | ||
236 | } uarg; | ||
237 | |||
238 | uarg.i = (int __user *)arg; | ||
239 | |||
240 | switch (cmd) { | ||
241 | case WDIOC_GETSUPPORT: | ||
242 | return copy_to_user(uarg.ident, &ident, | ||
243 | sizeof(ident)) ? -EFAULT : 0; | ||
244 | |||
245 | case WDIOC_GETBOOTSTATUS: | ||
246 | return put_user(xdev.boot_status, uarg.i); | ||
247 | |||
248 | case WDIOC_GETSTATUS: | ||
249 | xwdt_get_status(&status); | ||
250 | return put_user(status, uarg.i); | ||
251 | |||
252 | case WDIOC_KEEPALIVE: | ||
253 | xwdt_keepalive(); | ||
254 | return 0; | ||
255 | |||
256 | case WDIOC_GETTIMEOUT: | ||
257 | if (no_timeout) | ||
258 | return -ENOTTY; | ||
259 | else | ||
260 | return put_user(timeout, uarg.i); | ||
261 | |||
262 | default: | ||
263 | return -ENOTTY; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static const struct file_operations xwdt_fops = { | ||
268 | .owner = THIS_MODULE, | ||
269 | .llseek = no_llseek, | ||
270 | .write = xwdt_write, | ||
271 | .open = xwdt_open, | ||
272 | .release = xwdt_release, | ||
273 | .unlocked_ioctl = xwdt_ioctl, | ||
274 | }; | ||
275 | |||
276 | static struct miscdevice xwdt_miscdev = { | ||
277 | .minor = WATCHDOG_MINOR, | ||
278 | .name = "watchdog", | ||
279 | .fops = &xwdt_fops, | ||
280 | }; | ||
281 | |||
282 | static int xwdt_probe(struct platform_device *pdev) | 146 | static int xwdt_probe(struct platform_device *pdev) |
283 | { | 147 | { |
284 | int rc; | 148 | int rc; |
285 | u32 *tmptr; | 149 | u32 pfreq = 0, enable_once = 0; |
286 | u32 *pfreq; | 150 | struct resource *res; |
287 | 151 | struct xwdt_device *xdev; | |
288 | no_timeout = 0; | 152 | struct watchdog_device *xilinx_wdt_wdd; |
289 | 153 | ||
290 | pfreq = (u32 *)of_get_property(pdev->dev.of_node, | 154 | xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); |
291 | "clock-frequency", NULL); | 155 | if (!xdev) |
292 | 156 | return -ENOMEM; | |
293 | if (pfreq == NULL) { | 157 | |
294 | pr_warn("The watchdog clock frequency cannot be obtained!\n"); | 158 | xilinx_wdt_wdd = &xdev->xilinx_wdt_wdd; |
295 | no_timeout = 1; | 159 | xilinx_wdt_wdd->info = &xilinx_wdt_ident; |
296 | } | 160 | xilinx_wdt_wdd->ops = &xilinx_wdt_ops; |
297 | 161 | xilinx_wdt_wdd->parent = &pdev->dev; | |
298 | rc = of_address_to_resource(pdev->dev.of_node, 0, &xdev.res); | 162 | |
299 | if (rc) { | 163 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
300 | pr_warn("invalid address!\n"); | 164 | xdev->base = devm_ioremap_resource(&pdev->dev, res); |
301 | return rc; | 165 | if (IS_ERR(xdev->base)) |
302 | } | 166 | return PTR_ERR(xdev->base); |
303 | 167 | ||
304 | tmptr = (u32 *)of_get_property(pdev->dev.of_node, | 168 | rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &pfreq); |
305 | "xlnx,wdt-interval", NULL); | 169 | if (rc) |
306 | if (tmptr == NULL) { | 170 | dev_warn(&pdev->dev, |
307 | pr_warn("Parameter \"xlnx,wdt-interval\" not found in device tree!\n"); | 171 | "The watchdog clock frequency cannot be obtained\n"); |
308 | no_timeout = 1; | 172 | |
309 | } else { | 173 | rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval", |
310 | xdev.wdt_interval = *tmptr; | 174 | &xdev->wdt_interval); |
311 | } | 175 | if (rc) |
312 | 176 | dev_warn(&pdev->dev, | |
313 | tmptr = (u32 *)of_get_property(pdev->dev.of_node, | 177 | "Parameter \"xlnx,wdt-interval\" not found\n"); |
314 | "xlnx,wdt-enable-once", NULL); | 178 | |
315 | if (tmptr == NULL) { | 179 | rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-enable-once", |
316 | pr_warn("Parameter \"xlnx,wdt-enable-once\" not found in device tree!\n"); | 180 | &enable_once); |
317 | xdev.nowayout = WATCHDOG_NOWAYOUT; | 181 | if (rc) |
318 | } | 182 | dev_warn(&pdev->dev, |
319 | 183 | "Parameter \"xlnx,wdt-enable-once\" not found\n"); | |
320 | /* | 184 | |
321 | * Twice of the 2^wdt_interval / freq because the first wdt overflow is | 185 | watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); |
322 | * ignored (interrupt), reset is only generated at second wdt overflow | 186 | |
323 | */ | 187 | /* |
324 | if (!no_timeout) | 188 | * Twice of the 2^wdt_interval / freq because the first wdt overflow is |
325 | timeout = 2 * ((1<<xdev.wdt_interval) / *pfreq); | 189 | * ignored (interrupt), reset is only generated at second wdt overflow |
326 | 190 | */ | |
327 | if (!request_mem_region(xdev.res.start, | 191 | if (pfreq && xdev->wdt_interval) |
328 | xdev.res.end - xdev.res.start + 1, WATCHDOG_NAME)) { | 192 | xilinx_wdt_wdd->timeout = 2 * ((1 << xdev->wdt_interval) / |
329 | rc = -ENXIO; | 193 | pfreq); |
330 | pr_err("memory request failure!\n"); | 194 | |
331 | goto err_out; | 195 | spin_lock_init(&xdev->spinlock); |
332 | } | 196 | watchdog_set_drvdata(xilinx_wdt_wdd, xdev); |
333 | 197 | ||
334 | xdev.base = ioremap(xdev.res.start, xdev.res.end - xdev.res.start + 1); | 198 | rc = xwdt_selftest(xdev); |
335 | if (xdev.base == NULL) { | ||
336 | rc = -ENOMEM; | ||
337 | pr_err("ioremap failure!\n"); | ||
338 | goto release_mem; | ||
339 | } | ||
340 | |||
341 | rc = xwdt_selftest(); | ||
342 | if (rc == XWT_TIMER_FAILED) { | 199 | if (rc == XWT_TIMER_FAILED) { |
343 | pr_err("SelfTest routine error!\n"); | 200 | dev_err(&pdev->dev, "SelfTest routine error\n"); |
344 | goto unmap_io; | 201 | return rc; |
345 | } | 202 | } |
346 | 203 | ||
347 | xwdt_get_status(&xdev.boot_status); | 204 | rc = watchdog_register_device(xilinx_wdt_wdd); |
348 | |||
349 | rc = misc_register(&xwdt_miscdev); | ||
350 | if (rc) { | 205 | if (rc) { |
351 | pr_err("cannot register miscdev on minor=%d (err=%d)\n", | 206 | dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc); |
352 | xwdt_miscdev.minor, rc); | 207 | return rc; |
353 | goto unmap_io; | ||
354 | } | 208 | } |
355 | 209 | ||
356 | if (no_timeout) | 210 | dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", |
357 | pr_info("driver loaded (timeout=? sec, nowayout=%d)\n", | 211 | xdev->base, xilinx_wdt_wdd->timeout); |
358 | xdev.nowayout); | ||
359 | else | ||
360 | pr_info("driver loaded (timeout=%d sec, nowayout=%d)\n", | ||
361 | timeout, xdev.nowayout); | ||
362 | 212 | ||
363 | expect_close = 0; | 213 | platform_set_drvdata(pdev, xdev); |
364 | clear_bit(0, &driver_open); | ||
365 | 214 | ||
366 | return 0; | 215 | return 0; |
367 | |||
368 | unmap_io: | ||
369 | iounmap(xdev.base); | ||
370 | release_mem: | ||
371 | release_mem_region(xdev.res.start, resource_size(&xdev.res)); | ||
372 | err_out: | ||
373 | return rc; | ||
374 | } | 216 | } |
375 | 217 | ||
376 | static int xwdt_remove(struct platform_device *dev) | 218 | static int xwdt_remove(struct platform_device *pdev) |
377 | { | 219 | { |
378 | misc_deregister(&xwdt_miscdev); | 220 | struct xwdt_device *xdev = platform_get_drvdata(pdev); |
379 | iounmap(xdev.base); | 221 | |
380 | release_mem_region(xdev.res.start, resource_size(&xdev.res)); | 222 | watchdog_unregister_device(&xdev->xilinx_wdt_wdd); |
381 | 223 | ||
382 | return 0; | 224 | return 0; |
383 | } | 225 | } |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 09cf0135e8ac..3691b157516a 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/watchdog.h> | 35 | #include <linux/watchdog.h> |
36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/init.h> | ||
38 | #include <linux/err.h> | 37 | #include <linux/err.h> |
39 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
40 | #include <linux/moduleparam.h> | 39 | #include <linux/moduleparam.h> |
@@ -58,7 +57,6 @@ struct omap_wdt_dev { | |||
58 | void __iomem *base; /* physical */ | 57 | void __iomem *base; /* physical */ |
59 | struct device *dev; | 58 | struct device *dev; |
60 | bool omap_wdt_users; | 59 | bool omap_wdt_users; |
61 | struct resource *mem; | ||
62 | int wdt_trgr_pattern; | 60 | int wdt_trgr_pattern; |
63 | struct mutex lock; /* to avoid races with PM */ | 61 | struct mutex lock; /* to avoid races with PM */ |
64 | }; | 62 | }; |
@@ -207,7 +205,7 @@ static int omap_wdt_probe(struct platform_device *pdev) | |||
207 | { | 205 | { |
208 | struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev); | 206 | struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev); |
209 | struct watchdog_device *omap_wdt; | 207 | struct watchdog_device *omap_wdt; |
210 | struct resource *res, *mem; | 208 | struct resource *res; |
211 | struct omap_wdt_dev *wdev; | 209 | struct omap_wdt_dev *wdev; |
212 | u32 rs; | 210 | u32 rs; |
213 | int ret; | 211 | int ret; |
@@ -216,29 +214,20 @@ static int omap_wdt_probe(struct platform_device *pdev) | |||
216 | if (!omap_wdt) | 214 | if (!omap_wdt) |
217 | return -ENOMEM; | 215 | return -ENOMEM; |
218 | 216 | ||
219 | /* reserve static register mappings */ | ||
220 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
221 | if (!res) | ||
222 | return -ENOENT; | ||
223 | |||
224 | mem = devm_request_mem_region(&pdev->dev, res->start, | ||
225 | resource_size(res), pdev->name); | ||
226 | if (!mem) | ||
227 | return -EBUSY; | ||
228 | |||
229 | wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); | 217 | wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); |
230 | if (!wdev) | 218 | if (!wdev) |
231 | return -ENOMEM; | 219 | return -ENOMEM; |
232 | 220 | ||
233 | wdev->omap_wdt_users = false; | 221 | wdev->omap_wdt_users = false; |
234 | wdev->mem = mem; | ||
235 | wdev->dev = &pdev->dev; | 222 | wdev->dev = &pdev->dev; |
236 | wdev->wdt_trgr_pattern = 0x1234; | 223 | wdev->wdt_trgr_pattern = 0x1234; |
237 | mutex_init(&wdev->lock); | 224 | mutex_init(&wdev->lock); |
238 | 225 | ||
239 | wdev->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 226 | /* reserve static register mappings */ |
240 | if (!wdev->base) | 227 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
241 | return -ENOMEM; | 228 | wdev->base = devm_ioremap_resource(&pdev->dev, res); |
229 | if (IS_ERR(wdev->base)) | ||
230 | return PTR_ERR(wdev->base); | ||
242 | 231 | ||
243 | omap_wdt->info = &omap_wdt_info; | 232 | omap_wdt->info = &omap_wdt_info; |
244 | omap_wdt->ops = &omap_wdt_ops; | 233 | omap_wdt->ops = &omap_wdt_ops; |
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 6f9b4c6e9bca..9b3c41d18703 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
23 | #include <linux/io.h> | 22 | #include <linux/io.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 5211d56b3681..9f15dd9435d1 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c | |||
@@ -512,9 +512,8 @@ static int __init pc87413_init(void) | |||
512 | return -EBUSY; | 512 | return -EBUSY; |
513 | 513 | ||
514 | ret = register_reboot_notifier(&pc87413_notifier); | 514 | ret = register_reboot_notifier(&pc87413_notifier); |
515 | if (ret != 0) { | 515 | if (ret != 0) |
516 | pr_err("cannot register reboot notifier (err=%d)\n", ret); | 516 | pr_err("cannot register reboot notifier (err=%d)\n", ret); |
517 | } | ||
518 | 517 | ||
519 | ret = misc_register(&pc87413_miscdev); | 518 | ret = misc_register(&pc87413_miscdev); |
520 | if (ret != 0) { | 519 | if (ret != 0) { |
@@ -575,8 +574,8 @@ static void __exit pc87413_exit(void) | |||
575 | module_init(pc87413_init); | 574 | module_init(pc87413_init); |
576 | module_exit(pc87413_exit); | 575 | module_exit(pc87413_exit); |
577 | 576 | ||
578 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>, " | 577 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); |
579 | "Marcus Junker <junker@anduras.de>,"); | 578 | MODULE_AUTHOR("Marcus Junker <junker@anduras.de>"); |
580 | MODULE_DESCRIPTION("PC87413 WDT driver"); | 579 | MODULE_DESCRIPTION("PC87413 WDT driver"); |
581 | MODULE_LICENSE("GPL"); | 580 | MODULE_LICENSE("GPL"); |
582 | 581 | ||
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index e562e0476016..1a11aedc4fe8 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
@@ -645,10 +645,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, | |||
645 | 645 | ||
646 | /* allocate memory for our device and initialize it */ | 646 | /* allocate memory for our device and initialize it */ |
647 | usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL); | 647 | usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL); |
648 | if (usb_pcwd == NULL) { | 648 | if (usb_pcwd == NULL) |
649 | pr_err("Out of memory\n"); | ||
650 | goto error; | 649 | goto error; |
651 | } | ||
652 | 650 | ||
653 | usb_pcwd_device = usb_pcwd; | 651 | usb_pcwd_device = usb_pcwd; |
654 | 652 | ||
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 5bec20f5dc2d..15fb316e9437 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
29 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
30 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 082d06262959..29cf4dcbc59c 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
32 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
33 | #include <linux/completion.h> | 32 | #include <linux/completion.h> |
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c index f53615dc633d..a7a0695971e4 100644 --- a/drivers/watchdog/retu_wdt.c +++ b/drivers/watchdog/retu_wdt.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
22 | #include <linux/device.h> | 21 | #include <linux/device.h> |
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 3dd8ed28adc8..cfed0fe264dc 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/init.h> | ||
14 | #include <linux/miscdevice.h> | 13 | #include <linux/miscdevice.h> |
15 | #include <linux/watchdog.h> | 14 | #include <linux/watchdog.h> |
16 | #include <linux/of.h> | 15 | #include <linux/of.h> |
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index aec946df6ed9..7c6ccd071baf 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
32 | #include <linux/watchdog.h> | 32 | #include <linux/watchdog.h> |
33 | #include <linux/init.h> | ||
34 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
35 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
36 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
@@ -526,7 +525,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
526 | goto err; | 525 | goto err; |
527 | } | 526 | } |
528 | 527 | ||
529 | clk_prepare_enable(wdt->clock); | 528 | ret = clk_prepare_enable(wdt->clock); |
529 | if (ret < 0) { | ||
530 | dev_err(dev, "failed to enable clock\n"); | ||
531 | return ret; | ||
532 | } | ||
530 | 533 | ||
531 | ret = s3c2410wdt_cpufreq_register(wdt); | 534 | ret = s3c2410wdt_cpufreq_register(wdt); |
532 | if (ret < 0) { | 535 | if (ret < 0) { |
@@ -608,7 +611,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
608 | 611 | ||
609 | err_clk: | 612 | err_clk: |
610 | clk_disable_unprepare(wdt->clock); | 613 | clk_disable_unprepare(wdt->clock); |
611 | wdt->clock = NULL; | ||
612 | 614 | ||
613 | err: | 615 | err: |
614 | return ret; | 616 | return ret; |
@@ -628,7 +630,6 @@ static int s3c2410wdt_remove(struct platform_device *dev) | |||
628 | s3c2410wdt_cpufreq_deregister(wdt); | 630 | s3c2410wdt_cpufreq_deregister(wdt); |
629 | 631 | ||
630 | clk_disable_unprepare(wdt->clock); | 632 | clk_disable_unprepare(wdt->clock); |
631 | wdt->clock = NULL; | ||
632 | 633 | ||
633 | return 0; | 634 | return 0; |
634 | } | 635 | } |
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c index f353e18b1a82..1cfd3f6a13d5 100644 --- a/drivers/watchdog/sc520_wdt.c +++ b/drivers/watchdog/sc520_wdt.c | |||
@@ -158,12 +158,11 @@ static void wdt_timer_ping(unsigned long data) | |||
158 | 158 | ||
159 | static void wdt_config(int writeval) | 159 | static void wdt_config(int writeval) |
160 | { | 160 | { |
161 | __u16 dummy; | ||
162 | unsigned long flags; | 161 | unsigned long flags; |
163 | 162 | ||
164 | /* buy some time (ping) */ | 163 | /* buy some time (ping) */ |
165 | spin_lock_irqsave(&wdt_spinlock, flags); | 164 | spin_lock_irqsave(&wdt_spinlock, flags); |
166 | dummy = readw(wdtmrctl); /* ensure write synchronization */ | 165 | readw(wdtmrctl); /* ensure write synchronization */ |
167 | writew(0xAAAA, wdtmrctl); | 166 | writew(0xAAAA, wdtmrctl); |
168 | writew(0x5555, wdtmrctl); | 167 | writew(0x5555, wdtmrctl); |
169 | /* unlock WDT = make WDT configuration register writable one time */ | 168 | /* unlock WDT = make WDT configuration register writable one time */ |
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index af3528f84d65..d04d02b41c32 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c | |||
@@ -293,8 +293,6 @@ static int sh_wdt_probe(struct platform_device *pdev) | |||
293 | 293 | ||
294 | static int sh_wdt_remove(struct platform_device *pdev) | 294 | static int sh_wdt_remove(struct platform_device *pdev) |
295 | { | 295 | { |
296 | struct sh_wdt *wdt = platform_get_drvdata(pdev); | ||
297 | |||
298 | watchdog_unregister_device(&sh_wdt_dev); | 296 | watchdog_unregister_device(&sh_wdt_dev); |
299 | 297 | ||
300 | pm_runtime_disable(&pdev->dev); | 298 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c index c04a1aa158e2..0dc5e323d59d 100644 --- a/drivers/watchdog/softdog.c +++ b/drivers/watchdog/softdog.c | |||
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(nowayout, | |||
62 | "Watchdog cannot be stopped once started (default=" | 62 | "Watchdog cannot be stopped once started (default=" |
63 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 63 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
64 | 64 | ||
65 | static int soft_noboot = 0; | 65 | static int soft_noboot; |
66 | module_param(soft_noboot, int, 0); | 66 | module_param(soft_noboot, int, 0); |
67 | MODULE_PARM_DESC(soft_noboot, | 67 | MODULE_PARM_DESC(soft_noboot, |
68 | "Softdog action, set to 1 to ignore reboots, 0 to reboot (default=0)"); | 68 | "Softdog action, set to 1 to ignore reboots, 0 to reboot (default=0)"); |
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index 3f786ce0a6f2..47629d268e0a 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/amba/bus.h> | 16 | #include <linux/amba/bus.h> |
17 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/io.h> | 19 | #include <linux/io.h> |
21 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
22 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -209,27 +208,15 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) | |||
209 | struct sp805_wdt *wdt; | 208 | struct sp805_wdt *wdt; |
210 | int ret = 0; | 209 | int ret = 0; |
211 | 210 | ||
212 | if (!devm_request_mem_region(&adev->dev, adev->res.start, | ||
213 | resource_size(&adev->res), "sp805_wdt")) { | ||
214 | dev_warn(&adev->dev, "Failed to get memory region resource\n"); | ||
215 | ret = -ENOENT; | ||
216 | goto err; | ||
217 | } | ||
218 | |||
219 | wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); | 211 | wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); |
220 | if (!wdt) { | 212 | if (!wdt) { |
221 | dev_warn(&adev->dev, "Kzalloc failed\n"); | ||
222 | ret = -ENOMEM; | 213 | ret = -ENOMEM; |
223 | goto err; | 214 | goto err; |
224 | } | 215 | } |
225 | 216 | ||
226 | wdt->base = devm_ioremap(&adev->dev, adev->res.start, | 217 | wdt->base = devm_ioremap_resource(&adev->dev, &adev->res); |
227 | resource_size(&adev->res)); | 218 | if (IS_ERR(wdt->base)) |
228 | if (!wdt->base) { | 219 | return PTR_ERR(wdt->base); |
229 | ret = -ENOMEM; | ||
230 | dev_warn(&adev->dev, "ioremap fail\n"); | ||
231 | goto err; | ||
232 | } | ||
233 | 220 | ||
234 | wdt->clk = devm_clk_get(&adev->dev, NULL); | 221 | wdt->clk = devm_clk_get(&adev->dev, NULL); |
235 | if (IS_ERR(wdt->clk)) { | 222 | if (IS_ERR(wdt->clk)) { |
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c index bb64ae3f47da..3804d5e9baea 100644 --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c | |||
@@ -9,7 +9,6 @@ | |||
9 | * under the terms of the GNU General Public License version 2 as published by | 9 | * under the terms of the GNU General Public License version 2 as published by |
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | #include <linux/init.h> | ||
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
15 | #include <linux/watchdog.h> | 14 | #include <linux/watchdog.h> |
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 76332d893e12..cd00a7836cdc 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c | |||
@@ -205,7 +205,7 @@ static void sunxi_wdt_shutdown(struct platform_device *pdev) | |||
205 | } | 205 | } |
206 | 206 | ||
207 | static const struct of_device_id sunxi_wdt_dt_ids[] = { | 207 | static const struct of_device_id sunxi_wdt_dt_ids[] = { |
208 | { .compatible = "allwinner,sun4i-wdt" }, | 208 | { .compatible = "allwinner,sun4i-a10-wdt" }, |
209 | { /* sentinel */ } | 209 | { /* sentinel */ } |
210 | }; | 210 | }; |
211 | MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); | 211 | MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); |
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c new file mode 100644 index 000000000000..750e2a26cb12 --- /dev/null +++ b/drivers/watchdog/tegra_wdt.c | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/watchdog.h> | ||
21 | |||
22 | /* minimum and maximum watchdog trigger timeout, in seconds */ | ||
23 | #define MIN_WDT_TIMEOUT 1 | ||
24 | #define MAX_WDT_TIMEOUT 255 | ||
25 | |||
26 | /* | ||
27 | * Base of the WDT registers, from the timer base address. There are | ||
28 | * actually 5 watchdogs that can be configured (by pairing with an available | ||
29 | * timer), at bases 0x100 + (WDT ID) * 0x20, where WDT ID is 0 through 4. | ||
30 | * This driver only configures the first watchdog (WDT ID 0). | ||
31 | */ | ||
32 | #define WDT_BASE 0x100 | ||
33 | #define WDT_ID 0 | ||
34 | |||
35 | /* | ||
36 | * Register base of the timer that's selected for pairing with the watchdog. | ||
37 | * This driver arbitrarily uses timer 5, which is currently unused by | ||
38 | * other drivers (in particular, the Tegra clocksource driver). If this | ||
39 | * needs to change, take care that the new timer is not used by the | ||
40 | * clocksource driver. | ||
41 | */ | ||
42 | #define WDT_TIMER_BASE 0x60 | ||
43 | #define WDT_TIMER_ID 5 | ||
44 | |||
45 | /* WDT registers */ | ||
46 | #define WDT_CFG 0x0 | ||
47 | #define WDT_CFG_PERIOD_SHIFT 4 | ||
48 | #define WDT_CFG_PERIOD_MASK 0xff | ||
49 | #define WDT_CFG_INT_EN (1 << 12) | ||
50 | #define WDT_CFG_PMC2CAR_RST_EN (1 << 15) | ||
51 | #define WDT_STS 0x4 | ||
52 | #define WDT_STS_COUNT_SHIFT 4 | ||
53 | #define WDT_STS_COUNT_MASK 0xff | ||
54 | #define WDT_STS_EXP_SHIFT 12 | ||
55 | #define WDT_STS_EXP_MASK 0x3 | ||
56 | #define WDT_CMD 0x8 | ||
57 | #define WDT_CMD_START_COUNTER (1 << 0) | ||
58 | #define WDT_CMD_DISABLE_COUNTER (1 << 1) | ||
59 | #define WDT_UNLOCK (0xc) | ||
60 | #define WDT_UNLOCK_PATTERN (0xc45a << 0) | ||
61 | |||
62 | /* Timer registers */ | ||
63 | #define TIMER_PTV 0x0 | ||
64 | #define TIMER_EN (1 << 31) | ||
65 | #define TIMER_PERIODIC (1 << 30) | ||
66 | |||
67 | struct tegra_wdt { | ||
68 | struct watchdog_device wdd; | ||
69 | void __iomem *wdt_regs; | ||
70 | void __iomem *tmr_regs; | ||
71 | }; | ||
72 | |||
73 | #define WDT_HEARTBEAT 120 | ||
74 | static int heartbeat = WDT_HEARTBEAT; | ||
75 | module_param(heartbeat, int, 0); | ||
76 | MODULE_PARM_DESC(heartbeat, | ||
77 | "Watchdog heartbeats in seconds. (default = " | ||
78 | __MODULE_STRING(WDT_HEARTBEAT) ")"); | ||
79 | |||
80 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
81 | module_param(nowayout, bool, 0); | ||
82 | MODULE_PARM_DESC(nowayout, | ||
83 | "Watchdog cannot be stopped once started (default=" | ||
84 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
85 | |||
86 | static int tegra_wdt_start(struct watchdog_device *wdd) | ||
87 | { | ||
88 | struct tegra_wdt *wdt = watchdog_get_drvdata(wdd); | ||
89 | u32 val; | ||
90 | |||
91 | /* | ||
92 | * This thing has a fixed 1MHz clock. Normally, we would set the | ||
93 | * period to 1 second by writing 1000000ul, but the watchdog system | ||
94 | * reset actually occurs on the 4th expiration of this counter, | ||
95 | * so we set the period to 1/4 of this amount. | ||
96 | */ | ||
97 | val = 1000000ul / 4; | ||
98 | val |= (TIMER_EN | TIMER_PERIODIC); | ||
99 | writel(val, wdt->tmr_regs + TIMER_PTV); | ||
100 | |||
101 | /* | ||
102 | * Set number of periods and start counter. | ||
103 | * | ||
104 | * Interrupt handler is not required for user space | ||
105 | * WDT accesses, since the caller is responsible to ping the | ||
106 | * WDT to reset the counter before expiration, through ioctls. | ||
107 | */ | ||
108 | val = WDT_TIMER_ID | | ||
109 | (wdd->timeout << WDT_CFG_PERIOD_SHIFT) | | ||
110 | WDT_CFG_PMC2CAR_RST_EN; | ||
111 | writel(val, wdt->wdt_regs + WDT_CFG); | ||
112 | |||
113 | writel(WDT_CMD_START_COUNTER, wdt->wdt_regs + WDT_CMD); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int tegra_wdt_stop(struct watchdog_device *wdd) | ||
119 | { | ||
120 | struct tegra_wdt *wdt = watchdog_get_drvdata(wdd); | ||
121 | |||
122 | writel(WDT_UNLOCK_PATTERN, wdt->wdt_regs + WDT_UNLOCK); | ||
123 | writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_regs + WDT_CMD); | ||
124 | writel(0, wdt->tmr_regs + TIMER_PTV); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int tegra_wdt_ping(struct watchdog_device *wdd) | ||
130 | { | ||
131 | struct tegra_wdt *wdt = watchdog_get_drvdata(wdd); | ||
132 | |||
133 | writel(WDT_CMD_START_COUNTER, wdt->wdt_regs + WDT_CMD); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int tegra_wdt_set_timeout(struct watchdog_device *wdd, | ||
139 | unsigned int timeout) | ||
140 | { | ||
141 | wdd->timeout = timeout; | ||
142 | |||
143 | if (watchdog_active(wdd)) | ||
144 | return tegra_wdt_start(wdd); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static unsigned int tegra_wdt_get_timeleft(struct watchdog_device *wdd) | ||
150 | { | ||
151 | struct tegra_wdt *wdt = watchdog_get_drvdata(wdd); | ||
152 | u32 val; | ||
153 | int count; | ||
154 | int exp; | ||
155 | |||
156 | val = readl(wdt->wdt_regs + WDT_STS); | ||
157 | |||
158 | /* Current countdown (from timeout) */ | ||
159 | count = (val >> WDT_STS_COUNT_SHIFT) & WDT_STS_COUNT_MASK; | ||
160 | |||
161 | /* Number of expirations (we are waiting for the 4th expiration) */ | ||
162 | exp = (val >> WDT_STS_EXP_SHIFT) & WDT_STS_EXP_MASK; | ||
163 | |||
164 | /* | ||
165 | * The entire thing is divided by 4 because we are ticking down 4 times | ||
166 | * faster due to needing to wait for the 4th expiration. | ||
167 | */ | ||
168 | return (((3 - exp) * wdd->timeout) + count) / 4; | ||
169 | } | ||
170 | |||
171 | static const struct watchdog_info tegra_wdt_info = { | ||
172 | .options = WDIOF_SETTIMEOUT | | ||
173 | WDIOF_MAGICCLOSE | | ||
174 | WDIOF_KEEPALIVEPING, | ||
175 | .firmware_version = 0, | ||
176 | .identity = "Tegra Watchdog", | ||
177 | }; | ||
178 | |||
179 | static struct watchdog_ops tegra_wdt_ops = { | ||
180 | .owner = THIS_MODULE, | ||
181 | .start = tegra_wdt_start, | ||
182 | .stop = tegra_wdt_stop, | ||
183 | .ping = tegra_wdt_ping, | ||
184 | .set_timeout = tegra_wdt_set_timeout, | ||
185 | .get_timeleft = tegra_wdt_get_timeleft, | ||
186 | }; | ||
187 | |||
188 | static int tegra_wdt_probe(struct platform_device *pdev) | ||
189 | { | ||
190 | struct watchdog_device *wdd; | ||
191 | struct tegra_wdt *wdt; | ||
192 | struct resource *res; | ||
193 | void __iomem *regs; | ||
194 | int ret; | ||
195 | |||
196 | /* This is the timer base. */ | ||
197 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
198 | regs = devm_ioremap_resource(&pdev->dev, res); | ||
199 | if (IS_ERR(regs)) | ||
200 | return PTR_ERR(regs); | ||
201 | |||
202 | /* | ||
203 | * Allocate our watchdog driver data, which has the | ||
204 | * struct watchdog_device nested within it. | ||
205 | */ | ||
206 | wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); | ||
207 | if (!wdt) | ||
208 | return -ENOMEM; | ||
209 | |||
210 | /* Initialize struct tegra_wdt. */ | ||
211 | wdt->wdt_regs = regs + WDT_BASE; | ||
212 | wdt->tmr_regs = regs + WDT_TIMER_BASE; | ||
213 | |||
214 | /* Initialize struct watchdog_device. */ | ||
215 | wdd = &wdt->wdd; | ||
216 | wdd->timeout = heartbeat; | ||
217 | wdd->info = &tegra_wdt_info; | ||
218 | wdd->ops = &tegra_wdt_ops; | ||
219 | wdd->min_timeout = MIN_WDT_TIMEOUT; | ||
220 | wdd->max_timeout = MAX_WDT_TIMEOUT; | ||
221 | |||
222 | watchdog_set_drvdata(wdd, wdt); | ||
223 | |||
224 | watchdog_set_nowayout(wdd, nowayout); | ||
225 | |||
226 | ret = watchdog_register_device(wdd); | ||
227 | if (ret) { | ||
228 | dev_err(&pdev->dev, | ||
229 | "failed to register watchdog device\n"); | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | platform_set_drvdata(pdev, wdt); | ||
234 | |||
235 | dev_info(&pdev->dev, | ||
236 | "initialized (heartbeat = %d sec, nowayout = %d)\n", | ||
237 | heartbeat, nowayout); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int tegra_wdt_remove(struct platform_device *pdev) | ||
243 | { | ||
244 | struct tegra_wdt *wdt = platform_get_drvdata(pdev); | ||
245 | |||
246 | tegra_wdt_stop(&wdt->wdd); | ||
247 | |||
248 | watchdog_unregister_device(&wdt->wdd); | ||
249 | |||
250 | dev_info(&pdev->dev, "removed wdt\n"); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | #ifdef CONFIG_PM_SLEEP | ||
256 | static int tegra_wdt_runtime_suspend(struct device *dev) | ||
257 | { | ||
258 | struct tegra_wdt *wdt = dev_get_drvdata(dev); | ||
259 | |||
260 | if (watchdog_active(&wdt->wdd)) | ||
261 | tegra_wdt_stop(&wdt->wdd); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int tegra_wdt_runtime_resume(struct device *dev) | ||
267 | { | ||
268 | struct tegra_wdt *wdt = dev_get_drvdata(dev); | ||
269 | |||
270 | if (watchdog_active(&wdt->wdd)) | ||
271 | tegra_wdt_start(&wdt->wdd); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | #endif | ||
276 | |||
277 | static const struct of_device_id tegra_wdt_of_match[] = { | ||
278 | { .compatible = "nvidia,tegra30-timer", }, | ||
279 | { }, | ||
280 | }; | ||
281 | MODULE_DEVICE_TABLE(of, tegra_wdt_of_match); | ||
282 | |||
283 | static const struct dev_pm_ops tegra_wdt_pm_ops = { | ||
284 | SET_SYSTEM_SLEEP_PM_OPS(tegra_wdt_runtime_suspend, | ||
285 | tegra_wdt_runtime_resume) | ||
286 | }; | ||
287 | |||
288 | static struct platform_driver tegra_wdt_driver = { | ||
289 | .probe = tegra_wdt_probe, | ||
290 | .remove = tegra_wdt_remove, | ||
291 | .driver = { | ||
292 | .owner = THIS_MODULE, | ||
293 | .name = "tegra-wdt", | ||
294 | .pm = &tegra_wdt_pm_ops, | ||
295 | .of_match_table = tegra_wdt_of_match, | ||
296 | }, | ||
297 | }; | ||
298 | module_platform_driver(tegra_wdt_driver); | ||
299 | |||
300 | MODULE_AUTHOR("NVIDIA Corporation"); | ||
301 | MODULE_DESCRIPTION("Tegra Watchdog Driver"); | ||
302 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 09d4831aa61f..afa9d6ef353a 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c | |||
@@ -61,7 +61,7 @@ struct ts72xx_wdt { | |||
61 | struct platform_device *pdev; | 61 | struct platform_device *pdev; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct platform_device *ts72xx_wdt_pdev; | 64 | static struct platform_device *ts72xx_wdt_pdev; |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * TS-72xx Watchdog supports following timeouts (value written | 67 | * TS-72xx Watchdog supports following timeouts (value written |
@@ -394,10 +394,8 @@ static int ts72xx_wdt_probe(struct platform_device *pdev) | |||
394 | int error = 0; | 394 | int error = 0; |
395 | 395 | ||
396 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct ts72xx_wdt), GFP_KERNEL); | 396 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct ts72xx_wdt), GFP_KERNEL); |
397 | if (!wdt) { | 397 | if (!wdt) |
398 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
399 | return -ENOMEM; | 398 | return -ENOMEM; |
400 | } | ||
401 | 399 | ||
402 | r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 400 | r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
403 | wdt->control_reg = devm_ioremap_resource(&pdev->dev, r1); | 401 | wdt->control_reg = devm_ioremap_resource(&pdev->dev, r1); |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index aaf2995d37f4..e9ea856b8ff2 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
@@ -402,7 +402,7 @@ static int __init wdt_init(void) | |||
402 | 402 | ||
403 | if (!found) { | 403 | if (!found) { |
404 | pr_err("No W83697HF/HG could be found\n"); | 404 | pr_err("No W83697HF/HG could be found\n"); |
405 | ret = -EIO; | 405 | ret = -ENODEV; |
406 | goto out; | 406 | goto out; |
407 | } | 407 | } |
408 | 408 | ||
@@ -455,6 +455,6 @@ module_init(wdt_init); | |||
455 | module_exit(wdt_exit); | 455 | module_exit(wdt_exit); |
456 | 456 | ||
457 | MODULE_LICENSE("GPL"); | 457 | MODULE_LICENSE("GPL"); |
458 | MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, " | 458 | MODULE_AUTHOR("Marcus Junker <junker@anduras.de>"); |
459 | "Samuel Tardieu <sam@rfc1149.net>"); | 459 | MODULE_AUTHOR("Samuel Tardieu <sam@rfc1149.net>"); |
460 | MODULE_DESCRIPTION("w83697hf/hg WDT driver"); | 460 | MODULE_DESCRIPTION("w83697hf/hg WDT driver"); |
diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index 7355ddd0b207..ebbb183be618 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c | |||
@@ -139,9 +139,8 @@ static const struct watchdog_info ident = { | |||
139 | static long watchdog_ioctl(struct file *file, unsigned int cmd, | 139 | static long watchdog_ioctl(struct file *file, unsigned int cmd, |
140 | unsigned long arg) | 140 | unsigned long arg) |
141 | { | 141 | { |
142 | unsigned int new_margin; | ||
143 | int __user *int_arg = (int __user *)arg; | 142 | int __user *int_arg = (int __user *)arg; |
144 | int ret = -ENOTTY; | 143 | int new_margin, ret = -ENOTTY; |
145 | 144 | ||
146 | switch (cmd) { | 145 | switch (cmd) { |
147 | case WDIOC_GETSUPPORT: | 146 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index 3dc578e71211..48b2c058b009 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
50 | #include <linux/notifier.h> | 50 | #include <linux/notifier.h> |
51 | #include <linux/reboot.h> | 51 | #include <linux/reboot.h> |
52 | #include <linux/init.h> | ||
53 | #include <linux/fs.h> | 52 | #include <linux/fs.h> |
54 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
55 | #include <linux/io.h> | 54 | #include <linux/io.h> |
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index e243bd01c774..2fa17e746ff6 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c | |||
@@ -204,7 +204,6 @@ static int wm831x_wdt_probe(struct platform_device *pdev) | |||
204 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), | 204 | driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), |
205 | GFP_KERNEL); | 205 | GFP_KERNEL); |
206 | if (!driver_data) { | 206 | if (!driver_data) { |
207 | dev_err(wm831x->dev, "Unable to alloacate watchdog device\n"); | ||
208 | ret = -ENOMEM; | 207 | ret = -ENOMEM; |
209 | goto err; | 208 | goto err; |
210 | } | 209 | } |