diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
commit | 6be325719b3e54624397e413efd4b33a997e55a3 (patch) | |
tree | 57f321a56794cab2222e179b16731e0d76a4a68a /drivers/watchdog | |
parent | 26d92f9276a56d55511a427fb70bd70886af647a (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 16 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 2 | ||||
-rw-r--r-- | drivers/watchdog/adx_wdt.c | 6 | ||||
-rw-r--r-- | drivers/watchdog/at32ap700x_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/davinci_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/geodewdt.c | 40 | ||||
-rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 49 | ||||
-rw-r--r-- | drivers/watchdog/mpc5200_wdt.c | 293 | ||||
-rw-r--r-- | drivers/watchdog/mpcore_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/mv64x60_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/omap_wdt.c | 9 | ||||
-rw-r--r-- | drivers/watchdog/pnx4008_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/rm9k_wdt.c | 419 | ||||
-rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/twl4030_wdt.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/txx9wdt.c | 6 |
16 files changed, 88 insertions, 768 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3711b888d482..088f32f29a6e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -368,7 +368,7 @@ config ALIM7101_WDT | |||
368 | 368 | ||
369 | config GEODE_WDT | 369 | config GEODE_WDT |
370 | tristate "AMD Geode CS5535/CS5536 Watchdog" | 370 | tristate "AMD Geode CS5535/CS5536 Watchdog" |
371 | depends on MGEODE_LX | 371 | depends on CS5535_MFGPT |
372 | help | 372 | help |
373 | This driver enables a watchdog capability built into the | 373 | This driver enables a watchdog capability built into the |
374 | CS5535/CS5536 companion chips for the AMD Geode GX and LX | 374 | CS5535/CS5536 companion chips for the AMD Geode GX and LX |
@@ -815,16 +815,6 @@ config PNX833X_WDT | |||
815 | timer has expired and no process has written to /dev/watchdog during | 815 | timer has expired and no process has written to /dev/watchdog during |
816 | that time. | 816 | that time. |
817 | 817 | ||
818 | config WDT_RM9K_GPI | ||
819 | tristate "RM9000/GPI hardware watchdog" | ||
820 | depends on CPU_RM9000 | ||
821 | help | ||
822 | Watchdog implementation using the GPI hardware found on | ||
823 | PMC-Sierra RM9xxx CPUs. | ||
824 | |||
825 | To compile this driver as a module, choose M here: the | ||
826 | module will be called rm9k_wdt. | ||
827 | |||
828 | config SIBYTE_WDOG | 818 | config SIBYTE_WDOG |
829 | tristate "Sibyte SoC hardware watchdog" | 819 | tristate "Sibyte SoC hardware watchdog" |
830 | depends on CPU_SB1 | 820 | depends on CPU_SB1 |
@@ -861,8 +851,10 @@ config GEF_WDT | |||
861 | Watchdog timer found in a number of GE Fanuc single board computers. | 851 | Watchdog timer found in a number of GE Fanuc single board computers. |
862 | 852 | ||
863 | config MPC5200_WDT | 853 | config MPC5200_WDT |
864 | tristate "MPC5200 Watchdog Timer" | 854 | bool "MPC52xx Watchdog Timer" |
865 | depends on PPC_MPC52xx | 855 | depends on PPC_MPC52xx |
856 | help | ||
857 | Use General Purpose Timer (GPT) 0 on the MPC5200 as Watchdog. | ||
866 | 858 | ||
867 | config 8xxx_WDT | 859 | config 8xxx_WDT |
868 | tristate "MPC8xxx Platform Watchdog Timer" | 860 | tristate "MPC8xxx Platform Watchdog Timer" |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 699199b1baa6..475c61100069 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -109,7 +109,6 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o | |||
109 | obj-$(CONFIG_INDYDOG) += indydog.o | 109 | obj-$(CONFIG_INDYDOG) += indydog.o |
110 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o | 110 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o |
111 | obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o | 111 | obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o |
112 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o | ||
113 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o | 112 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o |
114 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o | 113 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o |
115 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | 114 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o |
@@ -118,7 +117,6 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | |||
118 | 117 | ||
119 | # POWERPC Architecture | 118 | # POWERPC Architecture |
120 | obj-$(CONFIG_GEF_WDT) += gef_wdt.o | 119 | obj-$(CONFIG_GEF_WDT) += gef_wdt.o |
121 | obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o | ||
122 | obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o | 120 | obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o |
123 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o | 121 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o |
124 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o | 122 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o |
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 77afb0acc500..9d7d155364f8 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c | |||
@@ -242,14 +242,14 @@ static int __devinit adx_wdt_probe(struct platform_device *pdev) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | res = devm_request_mem_region(&pdev->dev, res->start, | 244 | res = devm_request_mem_region(&pdev->dev, res->start, |
245 | res->end - res->start + 1, res->name); | 245 | resource_size(res), res->name); |
246 | if (!res) { | 246 | if (!res) { |
247 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); | 247 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); |
248 | return -ENXIO; | 248 | return -ENXIO; |
249 | } | 249 | } |
250 | 250 | ||
251 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, | 251 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, |
252 | res->end - res->start + 1); | 252 | resource_size(res)); |
253 | if (!wdt->base) { | 253 | if (!wdt->base) { |
254 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | 254 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); |
255 | return -ENXIO; | 255 | return -ENXIO; |
@@ -314,7 +314,7 @@ static int adx_wdt_resume(struct device *dev) | |||
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | 316 | ||
317 | static struct dev_pm_ops adx_wdt_pm_ops = { | 317 | static const struct dev_pm_ops adx_wdt_pm_ops = { |
318 | .suspend = adx_wdt_suspend, | 318 | .suspend = adx_wdt_suspend, |
319 | .resume = adx_wdt_resume, | 319 | .resume = adx_wdt_resume, |
320 | }; | 320 | }; |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index e8ae638e5804..037847923dcb 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -326,7 +326,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev) | |||
326 | return -ENOMEM; | 326 | return -ENOMEM; |
327 | } | 327 | } |
328 | 328 | ||
329 | wdt->regs = ioremap(regs->start, regs->end - regs->start + 1); | 329 | wdt->regs = ioremap(regs->start, resource_size(regs)); |
330 | if (!wdt->regs) { | 330 | if (!wdt->regs) { |
331 | ret = -ENOMEM; | 331 | ret = -ENOMEM; |
332 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); | 332 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 9d7520fa9e9c..887136de1857 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -221,7 +221,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) | |||
221 | return -ENOENT; | 221 | return -ENOENT; |
222 | } | 222 | } |
223 | 223 | ||
224 | size = res->end - res->start + 1; | 224 | size = resource_size(res); |
225 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 225 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
226 | 226 | ||
227 | if (wdt_mem == NULL) { | 227 | if (wdt_mem == NULL) { |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 9acf0015a1e7..38252ff828ca 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip | 1 | /* Watchdog timer for machines with the CS5535/CS5536 companion chip |
2 | * | 2 | * |
3 | * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. | 3 | * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. |
4 | * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -19,7 +20,7 @@ | |||
19 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> |
20 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
21 | 22 | ||
22 | #include <asm/geode.h> | 23 | #include <linux/cs5535.h> |
23 | 24 | ||
24 | #define GEODEWDT_HZ 500 | 25 | #define GEODEWDT_HZ 500 |
25 | #define GEODEWDT_SCALE 6 | 26 | #define GEODEWDT_SCALE 6 |
@@ -46,25 +47,25 @@ MODULE_PARM_DESC(nowayout, | |||
46 | 47 | ||
47 | static struct platform_device *geodewdt_platform_device; | 48 | static struct platform_device *geodewdt_platform_device; |
48 | static unsigned long wdt_flags; | 49 | static unsigned long wdt_flags; |
49 | static int wdt_timer; | 50 | static struct cs5535_mfgpt_timer *wdt_timer; |
50 | static int safe_close; | 51 | static int safe_close; |
51 | 52 | ||
52 | static void geodewdt_ping(void) | 53 | static void geodewdt_ping(void) |
53 | { | 54 | { |
54 | /* Stop the counter */ | 55 | /* Stop the counter */ |
55 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 56 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
56 | 57 | ||
57 | /* Reset the counter */ | 58 | /* Reset the counter */ |
58 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 59 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
59 | 60 | ||
60 | /* Enable the counter */ | 61 | /* Enable the counter */ |
61 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | 62 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); |
62 | } | 63 | } |
63 | 64 | ||
64 | static void geodewdt_disable(void) | 65 | static void geodewdt_disable(void) |
65 | { | 66 | { |
66 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 67 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
67 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 68 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
68 | } | 69 | } |
69 | 70 | ||
70 | static int geodewdt_set_heartbeat(int val) | 71 | static int geodewdt_set_heartbeat(int val) |
@@ -72,10 +73,10 @@ static int geodewdt_set_heartbeat(int val) | |||
72 | if (val < 1 || val > GEODEWDT_MAX_SECONDS) | 73 | if (val < 1 || val > GEODEWDT_MAX_SECONDS) |
73 | return -EINVAL; | 74 | return -EINVAL; |
74 | 75 | ||
75 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 76 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
76 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); | 77 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); |
77 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 78 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
78 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | 79 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); |
79 | 80 | ||
80 | timeout = val; | 81 | timeout = val; |
81 | return 0; | 82 | return 0; |
@@ -215,28 +216,25 @@ static struct miscdevice geodewdt_miscdev = { | |||
215 | 216 | ||
216 | static int __devinit geodewdt_probe(struct platform_device *dev) | 217 | static int __devinit geodewdt_probe(struct platform_device *dev) |
217 | { | 218 | { |
218 | int ret, timer; | 219 | int ret; |
219 | |||
220 | timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); | ||
221 | 220 | ||
222 | if (timer == -1) { | 221 | wdt_timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); |
222 | if (!wdt_timer) { | ||
223 | printk(KERN_ERR "geodewdt: No timers were available\n"); | 223 | printk(KERN_ERR "geodewdt: No timers were available\n"); |
224 | return -ENODEV; | 224 | return -ENODEV; |
225 | } | 225 | } |
226 | 226 | ||
227 | wdt_timer = timer; | ||
228 | |||
229 | /* Set up the timer */ | 227 | /* Set up the timer */ |
230 | 228 | ||
231 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, | 229 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, |
232 | GEODEWDT_SCALE | (3 << 8)); | 230 | GEODEWDT_SCALE | (3 << 8)); |
233 | 231 | ||
234 | /* Set up comparator 2 to reset when the event fires */ | 232 | /* Set up comparator 2 to reset when the event fires */ |
235 | geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); | 233 | cs5535_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); |
236 | 234 | ||
237 | /* Set up the initial timeout */ | 235 | /* Set up the initial timeout */ |
238 | 236 | ||
239 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, | 237 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, |
240 | timeout * GEODEWDT_HZ); | 238 | timeout * GEODEWDT_HZ); |
241 | 239 | ||
242 | ret = misc_register(&geodewdt_miscdev); | 240 | ret = misc_register(&geodewdt_miscdev); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index e44fbb31bc6f..4bdb7f1a9077 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -29,7 +29,9 @@ | |||
29 | * document number 313056-003, 313057-017: 82801H (ICH8) | 29 | * document number 313056-003, 313057-017: 82801H (ICH8) |
30 | * document number 316972-004, 316973-012: 82801I (ICH9) | 30 | * document number 316972-004, 316973-012: 82801I (ICH9) |
31 | * document number 319973-002, 319974-002: 82801J (ICH10) | 31 | * document number 319973-002, 319974-002: 82801J (ICH10) |
32 | * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) | 32 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) |
33 | * document number 320066-003, 320257-008: EP80597 (IICH) | ||
34 | * document number TBD : Cougar Point (CPT) | ||
33 | */ | 35 | */ |
34 | 36 | ||
35 | /* | 37 | /* |
@@ -99,7 +101,22 @@ enum iTCO_chipsets { | |||
99 | TCO_ICH10DO, /* ICH10DO */ | 101 | TCO_ICH10DO, /* ICH10DO */ |
100 | TCO_PCH, /* PCH Desktop Full Featured */ | 102 | TCO_PCH, /* PCH Desktop Full Featured */ |
101 | TCO_PCHM, /* PCH Mobile Full Featured */ | 103 | TCO_PCHM, /* PCH Mobile Full Featured */ |
104 | TCO_P55, /* P55 */ | ||
105 | TCO_PM55, /* PM55 */ | ||
106 | TCO_H55, /* H55 */ | ||
107 | TCO_QM57, /* QM57 */ | ||
108 | TCO_H57, /* H57 */ | ||
109 | TCO_HM55, /* HM55 */ | ||
110 | TCO_Q57, /* Q57 */ | ||
111 | TCO_HM57, /* HM57 */ | ||
102 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ | 112 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ |
113 | TCO_QS57, /* QS57 */ | ||
114 | TCO_3400, /* 3400 */ | ||
115 | TCO_3420, /* 3420 */ | ||
116 | TCO_3450, /* 3450 */ | ||
117 | TCO_EP80579, /* EP80579 */ | ||
118 | TCO_CPTD, /* CPT Desktop */ | ||
119 | TCO_CPTM, /* CPT Mobile */ | ||
103 | }; | 120 | }; |
104 | 121 | ||
105 | static struct { | 122 | static struct { |
@@ -142,7 +159,22 @@ static struct { | |||
142 | {"ICH10DO", 2}, | 159 | {"ICH10DO", 2}, |
143 | {"PCH Desktop Full Featured", 2}, | 160 | {"PCH Desktop Full Featured", 2}, |
144 | {"PCH Mobile Full Featured", 2}, | 161 | {"PCH Mobile Full Featured", 2}, |
162 | {"P55", 2}, | ||
163 | {"PM55", 2}, | ||
164 | {"H55", 2}, | ||
165 | {"QM57", 2}, | ||
166 | {"H57", 2}, | ||
167 | {"HM55", 2}, | ||
168 | {"Q57", 2}, | ||
169 | {"HM57", 2}, | ||
145 | {"PCH Mobile SFF Full Featured", 2}, | 170 | {"PCH Mobile SFF Full Featured", 2}, |
171 | {"QS57", 2}, | ||
172 | {"3400", 2}, | ||
173 | {"3420", 2}, | ||
174 | {"3450", 2}, | ||
175 | {"EP80579", 2}, | ||
176 | {"CPT Desktop", 2}, | ||
177 | {"CPT Mobile", 2}, | ||
146 | {NULL, 0} | 178 | {NULL, 0} |
147 | }; | 179 | }; |
148 | 180 | ||
@@ -213,7 +245,22 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
213 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, | 245 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, |
214 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, | 246 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, |
215 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, | 247 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, |
248 | { ITCO_PCI_DEVICE(0x3b02, TCO_P55)}, | ||
249 | { ITCO_PCI_DEVICE(0x3b03, TCO_PM55)}, | ||
250 | { ITCO_PCI_DEVICE(0x3b06, TCO_H55)}, | ||
251 | { ITCO_PCI_DEVICE(0x3b07, TCO_QM57)}, | ||
252 | { ITCO_PCI_DEVICE(0x3b08, TCO_H57)}, | ||
253 | { ITCO_PCI_DEVICE(0x3b09, TCO_HM55)}, | ||
254 | { ITCO_PCI_DEVICE(0x3b0a, TCO_Q57)}, | ||
255 | { ITCO_PCI_DEVICE(0x3b0b, TCO_HM57)}, | ||
216 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, | 256 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, |
257 | { ITCO_PCI_DEVICE(0x3b0f, TCO_QS57)}, | ||
258 | { ITCO_PCI_DEVICE(0x3b12, TCO_3400)}, | ||
259 | { ITCO_PCI_DEVICE(0x3b14, TCO_3420)}, | ||
260 | { ITCO_PCI_DEVICE(0x3b16, TCO_3450)}, | ||
261 | { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, | ||
262 | { ITCO_PCI_DEVICE(0x1c42, TCO_CPTD)}, | ||
263 | { ITCO_PCI_DEVICE(0x1c43, TCO_CPTM)}, | ||
217 | { 0, }, /* End of list */ | 264 | { 0, }, /* End of list */ |
218 | }; | 265 | }; |
219 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 266 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c deleted file mode 100644 index fa9c47ce0ae7..000000000000 --- a/drivers/watchdog/mpc5200_wdt.c +++ /dev/null | |||
@@ -1,293 +0,0 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/miscdevice.h> | ||
4 | #include <linux/watchdog.h> | ||
5 | #include <linux/io.h> | ||
6 | #include <linux/spinlock.h> | ||
7 | #include <linux/of_platform.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <asm/mpc52xx.h> | ||
10 | |||
11 | |||
12 | #define GPT_MODE_WDT (1 << 15) | ||
13 | #define GPT_MODE_CE (1 << 12) | ||
14 | #define GPT_MODE_MS_TIMER (0x4) | ||
15 | |||
16 | |||
17 | struct mpc5200_wdt { | ||
18 | unsigned count; /* timer ticks before watchdog kicks in */ | ||
19 | long ipb_freq; | ||
20 | struct miscdevice miscdev; | ||
21 | struct resource mem; | ||
22 | struct mpc52xx_gpt __iomem *regs; | ||
23 | spinlock_t io_lock; | ||
24 | }; | ||
25 | |||
26 | /* is_active stores wether or not the /dev/watchdog device is opened */ | ||
27 | static unsigned long is_active; | ||
28 | |||
29 | /* misc devices don't provide a way, to get back to 'dev' or 'miscdev' from | ||
30 | * file operations, which sucks. But there can be max 1 watchdog anyway, so... | ||
31 | */ | ||
32 | static struct mpc5200_wdt *wdt_global; | ||
33 | |||
34 | |||
35 | /* helper to calculate timeout in timer counts */ | ||
36 | static void mpc5200_wdt_set_timeout(struct mpc5200_wdt *wdt, int timeout) | ||
37 | { | ||
38 | /* use biggest prescaler of 64k */ | ||
39 | wdt->count = (wdt->ipb_freq + 0xffff) / 0x10000 * timeout; | ||
40 | |||
41 | if (wdt->count > 0xffff) | ||
42 | wdt->count = 0xffff; | ||
43 | } | ||
44 | /* return timeout in seconds (calculated from timer count) */ | ||
45 | static int mpc5200_wdt_get_timeout(struct mpc5200_wdt *wdt) | ||
46 | { | ||
47 | return wdt->count * 0x10000 / wdt->ipb_freq; | ||
48 | } | ||
49 | |||
50 | |||
51 | /* watchdog operations */ | ||
52 | static int mpc5200_wdt_start(struct mpc5200_wdt *wdt) | ||
53 | { | ||
54 | spin_lock(&wdt->io_lock); | ||
55 | /* disable */ | ||
56 | out_be32(&wdt->regs->mode, 0); | ||
57 | /* set timeout, with maximum prescaler */ | ||
58 | out_be32(&wdt->regs->count, 0x0 | wdt->count); | ||
59 | /* enable watchdog */ | ||
60 | out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | | ||
61 | GPT_MODE_MS_TIMER); | ||
62 | spin_unlock(&wdt->io_lock); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt) | ||
67 | { | ||
68 | spin_lock(&wdt->io_lock); | ||
69 | /* writing A5 to OCPW resets the watchdog */ | ||
70 | out_be32(&wdt->regs->mode, 0xA5000000 | | ||
71 | (0xffffff & in_be32(&wdt->regs->mode))); | ||
72 | spin_unlock(&wdt->io_lock); | ||
73 | return 0; | ||
74 | } | ||
75 | static int mpc5200_wdt_stop(struct mpc5200_wdt *wdt) | ||
76 | { | ||
77 | spin_lock(&wdt->io_lock); | ||
78 | /* disable */ | ||
79 | out_be32(&wdt->regs->mode, 0); | ||
80 | spin_unlock(&wdt->io_lock); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | |||
85 | /* file operations */ | ||
86 | static ssize_t mpc5200_wdt_write(struct file *file, const char __user *data, | ||
87 | size_t len, loff_t *ppos) | ||
88 | { | ||
89 | struct mpc5200_wdt *wdt = file->private_data; | ||
90 | mpc5200_wdt_ping(wdt); | ||
91 | return 0; | ||
92 | } | ||
93 | static struct watchdog_info mpc5200_wdt_info = { | ||
94 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | ||
95 | .identity = "mpc5200 watchdog on GPT0", | ||
96 | }; | ||
97 | static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd, | ||
98 | unsigned long arg) | ||
99 | { | ||
100 | struct mpc5200_wdt *wdt = file->private_data; | ||
101 | int __user *data = (int __user *)arg; | ||
102 | int timeout; | ||
103 | int ret = 0; | ||
104 | |||
105 | switch (cmd) { | ||
106 | case WDIOC_GETSUPPORT: | ||
107 | ret = copy_to_user(data, &mpc5200_wdt_info, | ||
108 | sizeof(mpc5200_wdt_info)); | ||
109 | if (ret) | ||
110 | ret = -EFAULT; | ||
111 | break; | ||
112 | |||
113 | case WDIOC_GETSTATUS: | ||
114 | case WDIOC_GETBOOTSTATUS: | ||
115 | ret = put_user(0, data); | ||
116 | break; | ||
117 | |||
118 | case WDIOC_KEEPALIVE: | ||
119 | mpc5200_wdt_ping(wdt); | ||
120 | break; | ||
121 | |||
122 | case WDIOC_SETTIMEOUT: | ||
123 | ret = get_user(timeout, data); | ||
124 | if (ret) | ||
125 | break; | ||
126 | mpc5200_wdt_set_timeout(wdt, timeout); | ||
127 | mpc5200_wdt_start(wdt); | ||
128 | /* fall through and return the timeout */ | ||
129 | |||
130 | case WDIOC_GETTIMEOUT: | ||
131 | timeout = mpc5200_wdt_get_timeout(wdt); | ||
132 | ret = put_user(timeout, data); | ||
133 | break; | ||
134 | |||
135 | default: | ||
136 | ret = -ENOTTY; | ||
137 | } | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int mpc5200_wdt_open(struct inode *inode, struct file *file) | ||
142 | { | ||
143 | /* /dev/watchdog can only be opened once */ | ||
144 | if (test_and_set_bit(0, &is_active)) | ||
145 | return -EBUSY; | ||
146 | |||
147 | /* Set and activate the watchdog */ | ||
148 | mpc5200_wdt_set_timeout(wdt_global, 30); | ||
149 | mpc5200_wdt_start(wdt_global); | ||
150 | file->private_data = wdt_global; | ||
151 | return nonseekable_open(inode, file); | ||
152 | } | ||
153 | static int mpc5200_wdt_release(struct inode *inode, struct file *file) | ||
154 | { | ||
155 | #if WATCHDOG_NOWAYOUT == 0 | ||
156 | struct mpc5200_wdt *wdt = file->private_data; | ||
157 | mpc5200_wdt_stop(wdt); | ||
158 | wdt->count = 0; /* == disabled */ | ||
159 | #endif | ||
160 | clear_bit(0, &is_active); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static const struct file_operations mpc5200_wdt_fops = { | ||
165 | .owner = THIS_MODULE, | ||
166 | .write = mpc5200_wdt_write, | ||
167 | .unlocked_ioctl = mpc5200_wdt_ioctl, | ||
168 | .open = mpc5200_wdt_open, | ||
169 | .release = mpc5200_wdt_release, | ||
170 | }; | ||
171 | |||
172 | /* module operations */ | ||
173 | static int mpc5200_wdt_probe(struct of_device *op, | ||
174 | const struct of_device_id *match) | ||
175 | { | ||
176 | struct mpc5200_wdt *wdt; | ||
177 | int err; | ||
178 | const void *has_wdt; | ||
179 | int size; | ||
180 | |||
181 | has_wdt = of_get_property(op->node, "has-wdt", NULL); | ||
182 | if (!has_wdt) | ||
183 | has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL); | ||
184 | if (!has_wdt) | ||
185 | return -ENODEV; | ||
186 | |||
187 | wdt = kzalloc(sizeof(*wdt), GFP_KERNEL); | ||
188 | if (!wdt) | ||
189 | return -ENOMEM; | ||
190 | |||
191 | wdt->ipb_freq = mpc5xxx_get_bus_frequency(op->node); | ||
192 | |||
193 | err = of_address_to_resource(op->node, 0, &wdt->mem); | ||
194 | if (err) | ||
195 | goto out_free; | ||
196 | size = wdt->mem.end - wdt->mem.start + 1; | ||
197 | if (!request_mem_region(wdt->mem.start, size, "mpc5200_wdt")) { | ||
198 | err = -ENODEV; | ||
199 | goto out_free; | ||
200 | } | ||
201 | wdt->regs = ioremap(wdt->mem.start, size); | ||
202 | if (!wdt->regs) { | ||
203 | err = -ENODEV; | ||
204 | goto out_release; | ||
205 | } | ||
206 | |||
207 | dev_set_drvdata(&op->dev, wdt); | ||
208 | spin_lock_init(&wdt->io_lock); | ||
209 | |||
210 | wdt->miscdev = (struct miscdevice) { | ||
211 | .minor = WATCHDOG_MINOR, | ||
212 | .name = "watchdog", | ||
213 | .fops = &mpc5200_wdt_fops, | ||
214 | .parent = &op->dev, | ||
215 | }; | ||
216 | wdt_global = wdt; | ||
217 | err = misc_register(&wdt->miscdev); | ||
218 | if (!err) | ||
219 | return 0; | ||
220 | |||
221 | iounmap(wdt->regs); | ||
222 | out_release: | ||
223 | release_mem_region(wdt->mem.start, size); | ||
224 | out_free: | ||
225 | kfree(wdt); | ||
226 | return err; | ||
227 | } | ||
228 | |||
229 | static int mpc5200_wdt_remove(struct of_device *op) | ||
230 | { | ||
231 | struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev); | ||
232 | |||
233 | mpc5200_wdt_stop(wdt); | ||
234 | misc_deregister(&wdt->miscdev); | ||
235 | iounmap(wdt->regs); | ||
236 | release_mem_region(wdt->mem.start, wdt->mem.end - wdt->mem.start + 1); | ||
237 | kfree(wdt); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | static int mpc5200_wdt_suspend(struct of_device *op, pm_message_t state) | ||
242 | { | ||
243 | struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev); | ||
244 | mpc5200_wdt_stop(wdt); | ||
245 | return 0; | ||
246 | } | ||
247 | static int mpc5200_wdt_resume(struct of_device *op) | ||
248 | { | ||
249 | struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev); | ||
250 | if (wdt->count) | ||
251 | mpc5200_wdt_start(wdt); | ||
252 | return 0; | ||
253 | } | ||
254 | static int mpc5200_wdt_shutdown(struct of_device *op) | ||
255 | { | ||
256 | struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev); | ||
257 | mpc5200_wdt_stop(wdt); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static struct of_device_id mpc5200_wdt_match[] = { | ||
262 | { .compatible = "mpc5200-gpt", }, | ||
263 | { .compatible = "fsl,mpc5200-gpt", }, | ||
264 | {}, | ||
265 | }; | ||
266 | static struct of_platform_driver mpc5200_wdt_driver = { | ||
267 | .owner = THIS_MODULE, | ||
268 | .name = "mpc5200-gpt-wdt", | ||
269 | .match_table = mpc5200_wdt_match, | ||
270 | .probe = mpc5200_wdt_probe, | ||
271 | .remove = mpc5200_wdt_remove, | ||
272 | .suspend = mpc5200_wdt_suspend, | ||
273 | .resume = mpc5200_wdt_resume, | ||
274 | .shutdown = mpc5200_wdt_shutdown, | ||
275 | }; | ||
276 | |||
277 | |||
278 | static int __init mpc5200_wdt_init(void) | ||
279 | { | ||
280 | return of_register_platform_driver(&mpc5200_wdt_driver); | ||
281 | } | ||
282 | |||
283 | static void __exit mpc5200_wdt_exit(void) | ||
284 | { | ||
285 | of_unregister_platform_driver(&mpc5200_wdt_driver); | ||
286 | } | ||
287 | |||
288 | module_init(mpc5200_wdt_init); | ||
289 | module_exit(mpc5200_wdt_exit); | ||
290 | |||
291 | MODULE_AUTHOR("Domen Puncer <domen.puncer@telargo.com>"); | ||
292 | MODULE_LICENSE("Dual BSD/GPL"); | ||
293 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 83fa34b214b4..a2dc07c2ed49 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
@@ -350,7 +350,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
350 | ret = -ENXIO; | 350 | ret = -ENXIO; |
351 | goto err_free; | 351 | goto err_free; |
352 | } | 352 | } |
353 | wdt->base = ioremap(res->start, res->end - res->start + 1); | 353 | wdt->base = ioremap(res->start, resource_size(res)); |
354 | if (!wdt->base) { | 354 | if (!wdt->base) { |
355 | ret = -ENOMEM; | 355 | ret = -ENOMEM; |
356 | goto err_free; | 356 | goto err_free; |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index acf589dc057c..a51dbe4c43da 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
@@ -275,7 +275,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev) | |||
275 | if (!r) | 275 | if (!r) |
276 | return -ENODEV; | 276 | return -ENODEV; |
277 | 277 | ||
278 | mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1); | 278 | mv64x60_wdt_regs = ioremap(r->start, resource_size(r)); |
279 | if (mv64x60_wdt_regs == NULL) | 279 | if (mv64x60_wdt_regs == NULL) |
280 | return -ENOMEM; | 280 | return -ENOMEM; |
281 | 281 | ||
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 429ea99eaee5..c6aaf2845741 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -277,8 +277,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
277 | goto err_busy; | 277 | goto err_busy; |
278 | } | 278 | } |
279 | 279 | ||
280 | mem = request_mem_region(res->start, res->end - res->start + 1, | 280 | mem = request_mem_region(res->start, resource_size(res), pdev->name); |
281 | pdev->name); | ||
282 | if (!mem) { | 281 | if (!mem) { |
283 | ret = -EBUSY; | 282 | ret = -EBUSY; |
284 | goto err_busy; | 283 | goto err_busy; |
@@ -306,7 +305,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
306 | goto err_clk; | 305 | goto err_clk; |
307 | } | 306 | } |
308 | 307 | ||
309 | wdev->base = ioremap(res->start, res->end - res->start + 1); | 308 | wdev->base = ioremap(res->start, resource_size(res)); |
310 | if (!wdev->base) { | 309 | if (!wdev->base) { |
311 | ret = -ENOMEM; | 310 | ret = -ENOMEM; |
312 | goto err_ioremap; | 311 | goto err_ioremap; |
@@ -358,7 +357,7 @@ err_clk: | |||
358 | kfree(wdev); | 357 | kfree(wdev); |
359 | 358 | ||
360 | err_kzalloc: | 359 | err_kzalloc: |
361 | release_mem_region(res->start, res->end - res->start + 1); | 360 | release_mem_region(res->start, resource_size(res)); |
362 | 361 | ||
363 | err_busy: | 362 | err_busy: |
364 | err_get_resource: | 363 | err_get_resource: |
@@ -383,7 +382,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) | |||
383 | return -ENOENT; | 382 | return -ENOENT; |
384 | 383 | ||
385 | misc_deregister(&(wdev->omap_wdt_miscdev)); | 384 | misc_deregister(&(wdev->omap_wdt_miscdev)); |
386 | release_mem_region(res->start, res->end - res->start + 1); | 385 | release_mem_region(res->start, resource_size(res)); |
387 | platform_set_drvdata(pdev, NULL); | 386 | platform_set_drvdata(pdev, NULL); |
388 | 387 | ||
389 | clk_put(wdev->ick); | 388 | clk_put(wdev->ick); |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 4d227b152001..430a5848a9a5 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) | |||
264 | return -ENOENT; | 264 | return -ENOENT; |
265 | } | 265 | } |
266 | 266 | ||
267 | size = res->end - res->start + 1; | 267 | size = resource_size(res); |
268 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 268 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
269 | 269 | ||
270 | if (wdt_mem == NULL) { | 270 | if (wdt_mem == NULL) { |
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c deleted file mode 100644 index bb66958b9433..000000000000 --- a/drivers/watchdog/rm9k_wdt.c +++ /dev/null | |||
@@ -1,419 +0,0 @@ | |||
1 | /* | ||
2 | * Watchdog implementation for GPI h/w found on PMC-Sierra RM9xxx | ||
3 | * chips. | ||
4 | * | ||
5 | * Copyright (C) 2004 by Basler Vision Technologies AG | ||
6 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/reboot.h> | ||
29 | #include <linux/notifier.h> | ||
30 | #include <linux/miscdevice.h> | ||
31 | #include <linux/watchdog.h> | ||
32 | #include <linux/io.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | #include <asm/atomic.h> | ||
35 | #include <asm/processor.h> | ||
36 | #include <asm/system.h> | ||
37 | #include <asm/rm9k-ocd.h> | ||
38 | |||
39 | #include <rm9k_wdt.h> | ||
40 | |||
41 | |||
42 | #define CLOCK 125000000 | ||
43 | #define MAX_TIMEOUT_SECONDS 32 | ||
44 | #define CPCCR 0x0080 | ||
45 | #define CPGIG1SR 0x0044 | ||
46 | #define CPGIG1ER 0x0054 | ||
47 | |||
48 | |||
49 | /* Function prototypes */ | ||
50 | static irqreturn_t wdt_gpi_irqhdl(int, void *); | ||
51 | static void wdt_gpi_start(void); | ||
52 | static void wdt_gpi_stop(void); | ||
53 | static void wdt_gpi_set_timeout(unsigned int); | ||
54 | static int wdt_gpi_open(struct inode *, struct file *); | ||
55 | static int wdt_gpi_release(struct inode *, struct file *); | ||
56 | static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, | ||
57 | loff_t *); | ||
58 | static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); | ||
59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); | ||
60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, | ||
61 | const char *, unsigned int); | ||
62 | static int __init wdt_gpi_probe(struct platform_device *); | ||
63 | static int __exit wdt_gpi_remove(struct platform_device *); | ||
64 | |||
65 | |||
66 | static const char wdt_gpi_name[] = "wdt_gpi"; | ||
67 | static atomic_t opencnt; | ||
68 | static int expect_close; | ||
69 | static int locked; | ||
70 | |||
71 | |||
72 | /* These are set from device resources */ | ||
73 | static void __iomem *wd_regs; | ||
74 | static unsigned int wd_irq, wd_ctr; | ||
75 | |||
76 | |||
77 | /* Module arguments */ | ||
78 | static int timeout = MAX_TIMEOUT_SECONDS; | ||
79 | module_param(timeout, int, 0444); | ||
80 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); | ||
81 | |||
82 | static unsigned long resetaddr = 0xbffdc200; | ||
83 | module_param(resetaddr, ulong, 0444); | ||
84 | MODULE_PARM_DESC(resetaddr, "Address to write to to force a reset"); | ||
85 | |||
86 | static unsigned long flagaddr = 0xbffdc104; | ||
87 | module_param(flagaddr, ulong, 0444); | ||
88 | MODULE_PARM_DESC(flagaddr, "Address to write to boot flags to"); | ||
89 | |||
90 | static int powercycle; | ||
91 | module_param(powercycle, bool, 0444); | ||
92 | MODULE_PARM_DESC(powercycle, "Cycle power if watchdog expires"); | ||
93 | |||
94 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
95 | module_param(nowayout, bool, 0444); | ||
96 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started"); | ||
97 | |||
98 | |||
99 | /* Kernel interfaces */ | ||
100 | static const struct file_operations fops = { | ||
101 | .owner = THIS_MODULE, | ||
102 | .open = wdt_gpi_open, | ||
103 | .release = wdt_gpi_release, | ||
104 | .write = wdt_gpi_write, | ||
105 | .unlocked_ioctl = wdt_gpi_ioctl, | ||
106 | }; | ||
107 | |||
108 | static struct miscdevice miscdev = { | ||
109 | .minor = WATCHDOG_MINOR, | ||
110 | .name = wdt_gpi_name, | ||
111 | .fops = &fops, | ||
112 | }; | ||
113 | |||
114 | static struct notifier_block wdt_gpi_shutdown = { | ||
115 | .notifier_call = wdt_gpi_notify, | ||
116 | }; | ||
117 | |||
118 | |||
119 | /* Interrupt handler */ | ||
120 | static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt) | ||
121 | { | ||
122 | if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1)) | ||
123 | return IRQ_NONE; | ||
124 | __raw_writel(0x1, wd_regs + 0x0008); | ||
125 | |||
126 | |||
127 | printk(KERN_CRIT "%s: watchdog expired - resetting system\n", | ||
128 | wdt_gpi_name); | ||
129 | |||
130 | *(volatile char *) flagaddr |= 0x01; | ||
131 | *(volatile char *) resetaddr = powercycle ? 0x01 : 0x2; | ||
132 | iob(); | ||
133 | while (1) | ||
134 | cpu_relax(); | ||
135 | } | ||
136 | |||
137 | |||
138 | /* Watchdog functions */ | ||
139 | static void wdt_gpi_start(void) | ||
140 | { | ||
141 | u32 reg; | ||
142 | |||
143 | lock_titan_regs(); | ||
144 | reg = titan_readl(CPGIG1ER); | ||
145 | titan_writel(reg | (0x100 << wd_ctr), CPGIG1ER); | ||
146 | iob(); | ||
147 | unlock_titan_regs(); | ||
148 | } | ||
149 | |||
150 | static void wdt_gpi_stop(void) | ||
151 | { | ||
152 | u32 reg; | ||
153 | |||
154 | lock_titan_regs(); | ||
155 | reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4)); | ||
156 | titan_writel(reg, CPCCR); | ||
157 | reg = titan_readl(CPGIG1ER); | ||
158 | titan_writel(reg & ~(0x100 << wd_ctr), CPGIG1ER); | ||
159 | iob(); | ||
160 | unlock_titan_regs(); | ||
161 | } | ||
162 | |||
163 | static void wdt_gpi_set_timeout(unsigned int to) | ||
164 | { | ||
165 | u32 reg; | ||
166 | const u32 wdval = (to * CLOCK) & ~0x0000000f; | ||
167 | |||
168 | lock_titan_regs(); | ||
169 | reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4)); | ||
170 | titan_writel(reg, CPCCR); | ||
171 | wmb(); | ||
172 | __raw_writel(wdval, wd_regs + 0x0000); | ||
173 | wmb(); | ||
174 | titan_writel(reg | (0x2 << (wd_ctr * 4)), CPCCR); | ||
175 | wmb(); | ||
176 | titan_writel(reg | (0x5 << (wd_ctr * 4)), CPCCR); | ||
177 | iob(); | ||
178 | unlock_titan_regs(); | ||
179 | } | ||
180 | |||
181 | |||
182 | /* /dev/watchdog operations */ | ||
183 | static int wdt_gpi_open(struct inode *inode, struct file *file) | ||
184 | { | ||
185 | int res; | ||
186 | |||
187 | if (unlikely(atomic_dec_if_positive(&opencnt) < 0)) | ||
188 | return -EBUSY; | ||
189 | |||
190 | expect_close = 0; | ||
191 | if (locked) { | ||
192 | module_put(THIS_MODULE); | ||
193 | free_irq(wd_irq, &miscdev); | ||
194 | locked = 0; | ||
195 | } | ||
196 | |||
197 | res = request_irq(wd_irq, wdt_gpi_irqhdl, IRQF_SHARED | IRQF_DISABLED, | ||
198 | wdt_gpi_name, &miscdev); | ||
199 | if (unlikely(res)) | ||
200 | return res; | ||
201 | |||
202 | wdt_gpi_set_timeout(timeout); | ||
203 | wdt_gpi_start(); | ||
204 | |||
205 | printk(KERN_INFO "%s: watchdog started, timeout = %u seconds\n", | ||
206 | wdt_gpi_name, timeout); | ||
207 | return nonseekable_open(inode, file); | ||
208 | } | ||
209 | |||
210 | static int wdt_gpi_release(struct inode *inode, struct file *file) | ||
211 | { | ||
212 | if (nowayout) { | ||
213 | printk(KERN_INFO "%s: no way out - watchdog left running\n", | ||
214 | wdt_gpi_name); | ||
215 | __module_get(THIS_MODULE); | ||
216 | locked = 1; | ||
217 | } else { | ||
218 | if (expect_close) { | ||
219 | wdt_gpi_stop(); | ||
220 | free_irq(wd_irq, &miscdev); | ||
221 | printk(KERN_INFO "%s: watchdog stopped\n", | ||
222 | wdt_gpi_name); | ||
223 | } else { | ||
224 | printk(KERN_CRIT "%s: unexpected close() -" | ||
225 | " watchdog left running\n", | ||
226 | wdt_gpi_name); | ||
227 | wdt_gpi_set_timeout(timeout); | ||
228 | __module_get(THIS_MODULE); | ||
229 | locked = 1; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | atomic_inc(&opencnt); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s, | ||
238 | loff_t *o) | ||
239 | { | ||
240 | char val; | ||
241 | |||
242 | wdt_gpi_set_timeout(timeout); | ||
243 | expect_close = (s > 0) && !get_user(val, d) && (val == 'V'); | ||
244 | return s ? 1 : 0; | ||
245 | } | ||
246 | |||
247 | static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
248 | { | ||
249 | long res = -ENOTTY; | ||
250 | const long size = _IOC_SIZE(cmd); | ||
251 | int stat; | ||
252 | void __user *argp = (void __user *)arg; | ||
253 | static struct watchdog_info wdinfo = { | ||
254 | .identity = "RM9xxx/GPI watchdog", | ||
255 | .firmware_version = 0, | ||
256 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | ||
257 | }; | ||
258 | |||
259 | if (unlikely(_IOC_TYPE(cmd) != WATCHDOG_IOCTL_BASE)) | ||
260 | return -ENOTTY; | ||
261 | |||
262 | if ((_IOC_DIR(cmd) & _IOC_READ) | ||
263 | && !access_ok(VERIFY_WRITE, arg, size)) | ||
264 | return -EFAULT; | ||
265 | |||
266 | if ((_IOC_DIR(cmd) & _IOC_WRITE) | ||
267 | && !access_ok(VERIFY_READ, arg, size)) | ||
268 | return -EFAULT; | ||
269 | |||
270 | expect_close = 0; | ||
271 | |||
272 | switch (cmd) { | ||
273 | case WDIOC_GETSUPPORT: | ||
274 | wdinfo.options = nowayout ? | ||
275 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : | ||
276 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | ||
277 | WDIOF_MAGICCLOSE; | ||
278 | res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; | ||
279 | break; | ||
280 | |||
281 | case WDIOC_GETSTATUS: | ||
282 | break; | ||
283 | |||
284 | case WDIOC_GETBOOTSTATUS: | ||
285 | stat = (*(volatile char *) flagaddr & 0x01) | ||
286 | ? WDIOF_CARDRESET : 0; | ||
287 | res = __copy_to_user(argp, &stat, size) ? | ||
288 | -EFAULT : size; | ||
289 | break; | ||
290 | |||
291 | case WDIOC_SETOPTIONS: | ||
292 | break; | ||
293 | |||
294 | case WDIOC_KEEPALIVE: | ||
295 | wdt_gpi_set_timeout(timeout); | ||
296 | res = size; | ||
297 | break; | ||
298 | |||
299 | case WDIOC_SETTIMEOUT: | ||
300 | { | ||
301 | int val; | ||
302 | if (unlikely(__copy_from_user(&val, argp, size))) { | ||
303 | res = -EFAULT; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | if (val > MAX_TIMEOUT_SECONDS) | ||
308 | val = MAX_TIMEOUT_SECONDS; | ||
309 | timeout = val; | ||
310 | wdt_gpi_set_timeout(val); | ||
311 | res = size; | ||
312 | printk(KERN_INFO "%s: timeout set to %u seconds\n", | ||
313 | wdt_gpi_name, timeout); | ||
314 | } | ||
315 | break; | ||
316 | |||
317 | case WDIOC_GETTIMEOUT: | ||
318 | res = __copy_to_user(argp, &timeout, size) ? | ||
319 | -EFAULT : size; | ||
320 | break; | ||
321 | } | ||
322 | |||
323 | return res; | ||
324 | } | ||
325 | |||
326 | |||
327 | /* Shutdown notifier */ | ||
328 | static int wdt_gpi_notify(struct notifier_block *this, unsigned long code, | ||
329 | void *unused) | ||
330 | { | ||
331 | if (code == SYS_DOWN || code == SYS_HALT) | ||
332 | wdt_gpi_stop(); | ||
333 | |||
334 | return NOTIFY_DONE; | ||
335 | } | ||
336 | |||
337 | |||
338 | /* Init & exit procedures */ | ||
339 | static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, | ||
340 | const char *name, unsigned int type) | ||
341 | { | ||
342 | char buf[80]; | ||
343 | if (snprintf(buf, sizeof(buf), "%s_0", name) >= sizeof(buf)) | ||
344 | return NULL; | ||
345 | return platform_get_resource_byname(pdv, type, buf); | ||
346 | } | ||
347 | |||
348 | /* No hotplugging on the platform bus - use __devinit */ | ||
349 | static int __devinit wdt_gpi_probe(struct platform_device *pdv) | ||
350 | { | ||
351 | int res; | ||
352 | const struct resource | ||
353 | * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, | ||
354 | IORESOURCE_MEM), | ||
355 | * const ri = wdt_gpi_get_resource(pdv, WDT_RESOURCE_IRQ, | ||
356 | IORESOURCE_IRQ), | ||
357 | * const rc = wdt_gpi_get_resource(pdv, WDT_RESOURCE_COUNTER, | ||
358 | 0); | ||
359 | |||
360 | if (unlikely(!rr || !ri || !rc)) | ||
361 | return -ENXIO; | ||
362 | |||
363 | wd_regs = ioremap_nocache(rr->start, rr->end + 1 - rr->start); | ||
364 | if (unlikely(!wd_regs)) | ||
365 | return -ENOMEM; | ||
366 | wd_irq = ri->start; | ||
367 | wd_ctr = rc->start; | ||
368 | res = misc_register(&miscdev); | ||
369 | if (res) | ||
370 | iounmap(wd_regs); | ||
371 | else | ||
372 | register_reboot_notifier(&wdt_gpi_shutdown); | ||
373 | return res; | ||
374 | } | ||
375 | |||
376 | static int __devexit wdt_gpi_remove(struct platform_device *dev) | ||
377 | { | ||
378 | int res; | ||
379 | |||
380 | unregister_reboot_notifier(&wdt_gpi_shutdown); | ||
381 | res = misc_deregister(&miscdev); | ||
382 | iounmap(wd_regs); | ||
383 | wd_regs = NULL; | ||
384 | return res; | ||
385 | } | ||
386 | |||
387 | |||
388 | /* Device driver init & exit */ | ||
389 | static struct platform_driver wgt_gpi_driver = { | ||
390 | .driver = { | ||
391 | .name = wdt_gpi_name, | ||
392 | .owner = THIS_MODULE, | ||
393 | }, | ||
394 | .probe = wdt_gpi_probe, | ||
395 | .remove = __devexit_p(wdt_gpi_remove), | ||
396 | }; | ||
397 | |||
398 | static int __init wdt_gpi_init_module(void) | ||
399 | { | ||
400 | atomic_set(&opencnt, 1); | ||
401 | if (timeout > MAX_TIMEOUT_SECONDS) | ||
402 | timeout = MAX_TIMEOUT_SECONDS; | ||
403 | return platform_driver_register(&wdt_gpi_driver); | ||
404 | } | ||
405 | |||
406 | static void __exit wdt_gpi_cleanup_module(void) | ||
407 | { | ||
408 | platform_driver_unregister(&wdt_gpi_driver); | ||
409 | } | ||
410 | |||
411 | module_init(wdt_gpi_init_module); | ||
412 | module_exit(wdt_gpi_cleanup_module); | ||
413 | |||
414 | MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>"); | ||
415 | MODULE_DESCRIPTION("Basler eXcite watchdog driver for gpi devices"); | ||
416 | MODULE_VERSION("0.1"); | ||
417 | MODULE_LICENSE("GPL"); | ||
418 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
419 | |||
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 85b93e15d011..8760a26ab2a3 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -421,7 +421,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
421 | return -ENOENT; | 421 | return -ENOENT; |
422 | } | 422 | } |
423 | 423 | ||
424 | size = (res->end - res->start) + 1; | 424 | size = resource_size(res); |
425 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 425 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
426 | if (wdt_mem == NULL) { | 426 | if (wdt_mem == NULL) { |
427 | dev_err(dev, "failed to get memory region\n"); | 427 | dev_err(dev, "failed to get memory region\n"); |
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index cb46556f2973..8162a40d1522 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
28 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <linux/i2c/twl4030.h> | 29 | #include <linux/i2c/twl.h> |
30 | 30 | ||
31 | #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 | 31 | #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 |
32 | 32 | ||
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " | |||
48 | 48 | ||
49 | static int twl4030_wdt_write(unsigned char val) | 49 | static int twl4030_wdt_write(unsigned char val) |
50 | { | 50 | { |
51 | return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, | 51 | return twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, |
52 | TWL4030_WATCHDOG_CFG_REG_OFFS); | 52 | TWL4030_WATCHDOG_CFG_REG_OFFS); |
53 | } | 53 | } |
54 | 54 | ||
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 6adab77fbbb0..d635566e9307 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
@@ -214,12 +214,10 @@ static int __init txx9wdt_probe(struct platform_device *dev) | |||
214 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 214 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
215 | if (!res) | 215 | if (!res) |
216 | goto exit_busy; | 216 | goto exit_busy; |
217 | if (!devm_request_mem_region(&dev->dev, | 217 | if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), |
218 | res->start, res->end - res->start + 1, | ||
219 | "txx9wdt")) | 218 | "txx9wdt")) |
220 | goto exit_busy; | 219 | goto exit_busy; |
221 | txx9wdt_reg = devm_ioremap(&dev->dev, | 220 | txx9wdt_reg = devm_ioremap(&dev->dev, res->start, resource_size(res)); |
222 | res->start, res->end - res->start + 1); | ||
223 | if (!txx9wdt_reg) | 221 | if (!txx9wdt_reg) |
224 | goto exit_busy; | 222 | goto exit_busy; |
225 | 223 | ||