diff options
Diffstat (limited to 'drivers/watchdog')
66 files changed, 1459 insertions, 1071 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3711b888d482..b87ba23442d2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -175,7 +175,7 @@ config SA1100_WATCHDOG | |||
175 | 175 | ||
176 | config MPCORE_WATCHDOG | 176 | config MPCORE_WATCHDOG |
177 | tristate "MPcore watchdog" | 177 | tristate "MPcore watchdog" |
178 | depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS | 178 | depends on HAVE_ARM_TWD |
179 | help | 179 | help |
180 | Watchdog timer embedded into the MPcore system. | 180 | Watchdog timer embedded into the MPcore system. |
181 | 181 | ||
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG | |||
194 | 194 | ||
195 | config OMAP_WATCHDOG | 195 | config OMAP_WATCHDOG |
196 | tristate "OMAP Watchdog" | 196 | tristate "OMAP Watchdog" |
197 | depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX | 197 | depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS |
198 | help | 198 | help |
199 | Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' | 199 | Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y' |
200 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. | 200 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. |
201 | 201 | ||
202 | config PNX4008_WATCHDOG | 202 | config PNX4008_WATCHDOG |
203 | tristate "PNX4008 Watchdog" | 203 | tristate "PNX4008 Watchdog" |
@@ -289,6 +289,23 @@ config ADX_WATCHDOG | |||
289 | Say Y here if you want support for the watchdog timer on Avionic | 289 | Say Y here if you want support for the watchdog timer on Avionic |
290 | Design Xanthos boards. | 290 | Design Xanthos boards. |
291 | 291 | ||
292 | config TS72XX_WATCHDOG | ||
293 | tristate "TS-72XX SBC Watchdog" | ||
294 | depends on MACH_TS72XX | ||
295 | help | ||
296 | Technologic Systems TS-7200, TS-7250 and TS-7260 boards have | ||
297 | watchdog timer implemented in a external CPLD chip. Say Y here | ||
298 | if you want to support for the watchdog timer on TS-72XX boards. | ||
299 | |||
300 | To compile this driver as a module, choose M here: the | ||
301 | module will be called ts72xx_wdt. | ||
302 | |||
303 | config MAX63XX_WATCHDOG | ||
304 | tristate "Max63xx watchdog" | ||
305 | depends on ARM && HAS_IOMEM | ||
306 | help | ||
307 | Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. | ||
308 | |||
292 | # AVR32 Architecture | 309 | # AVR32 Architecture |
293 | 310 | ||
294 | config AT32AP700X_WDT | 311 | config AT32AP700X_WDT |
@@ -368,7 +385,7 @@ config ALIM7101_WDT | |||
368 | 385 | ||
369 | config GEODE_WDT | 386 | config GEODE_WDT |
370 | tristate "AMD Geode CS5535/CS5536 Watchdog" | 387 | tristate "AMD Geode CS5535/CS5536 Watchdog" |
371 | depends on MGEODE_LX | 388 | depends on CS5535_MFGPT |
372 | help | 389 | help |
373 | This driver enables a watchdog capability built into the | 390 | This driver enables a watchdog capability built into the |
374 | CS5535/CS5536 companion chips for the AMD Geode GX and LX | 391 | CS5535/CS5536 companion chips for the AMD Geode GX and LX |
@@ -396,8 +413,8 @@ config SBC_FITPC2_WATCHDOG | |||
396 | tristate "Compulab SBC-FITPC2 watchdog" | 413 | tristate "Compulab SBC-FITPC2 watchdog" |
397 | depends on X86 | 414 | depends on X86 |
398 | ---help--- | 415 | ---help--- |
399 | This is the driver for the built-in watchdog timer on the fit-PC2 | 416 | This is the driver for the built-in watchdog timer on the fit-PC2, |
400 | Single-board computer made by Compulab. | 417 | fit-PC2i, CM-iAM single-board computers made by Compulab. |
401 | 418 | ||
402 | It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux. | 419 | It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux. |
403 | When "Watchdog Timer Value" enabled one can set 31-255 s operational range. | 420 | When "Watchdog Timer Value" enabled one can set 31-255 s operational range. |
@@ -815,16 +832,6 @@ config PNX833X_WDT | |||
815 | timer has expired and no process has written to /dev/watchdog during | 832 | timer has expired and no process has written to /dev/watchdog during |
816 | that time. | 833 | that time. |
817 | 834 | ||
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 | 835 | config SIBYTE_WDOG |
829 | tristate "Sibyte SoC hardware watchdog" | 836 | tristate "Sibyte SoC hardware watchdog" |
830 | depends on CPU_SB1 | 837 | depends on CPU_SB1 |
@@ -855,14 +862,16 @@ config TXX9_WDT | |||
855 | # POWERPC Architecture | 862 | # POWERPC Architecture |
856 | 863 | ||
857 | config GEF_WDT | 864 | config GEF_WDT |
858 | tristate "GE Fanuc Watchdog Timer" | 865 | tristate "GE Watchdog Timer" |
859 | depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A | 866 | depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A |
860 | ---help--- | 867 | ---help--- |
861 | Watchdog timer found in a number of GE Fanuc single board computers. | 868 | Watchdog timer found in a number of GE single board computers. |
862 | 869 | ||
863 | config MPC5200_WDT | 870 | config MPC5200_WDT |
864 | tristate "MPC5200 Watchdog Timer" | 871 | bool "MPC52xx Watchdog Timer" |
865 | depends on PPC_MPC52xx | 872 | depends on PPC_MPC52xx |
873 | help | ||
874 | Use General Purpose Timer (GPT) 0 on the MPC5200 as Watchdog. | ||
866 | 875 | ||
867 | config 8xxx_WDT | 876 | config 8xxx_WDT |
868 | tristate "MPC8xxx Platform Watchdog Timer" | 877 | tristate "MPC8xxx Platform Watchdog Timer" |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 699199b1baa6..5e3cb95bb0e9 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o | |||
46 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o | 46 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o |
47 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o | 47 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o |
48 | obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o | 48 | obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o |
49 | obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o | ||
49 | 50 | ||
50 | # AVR32 Architecture | 51 | # AVR32 Architecture |
51 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 52 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
@@ -109,7 +110,6 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o | |||
109 | obj-$(CONFIG_INDYDOG) += indydog.o | 110 | obj-$(CONFIG_INDYDOG) += indydog.o |
110 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o | 111 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o |
111 | obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o | 112 | obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o |
112 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o | ||
113 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o | 113 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o |
114 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o | 114 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o |
115 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | 115 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o |
@@ -118,7 +118,6 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | |||
118 | 118 | ||
119 | # POWERPC Architecture | 119 | # POWERPC Architecture |
120 | obj-$(CONFIG_GEF_WDT) += gef_wdt.o | 120 | obj-$(CONFIG_GEF_WDT) += gef_wdt.o |
121 | obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o | ||
122 | obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o | 121 | obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o |
123 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o | 122 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o |
124 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o | 123 | obj-$(CONFIG_PIKA_WDT) += pika_wdt.o |
@@ -144,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o | |||
144 | # Architecture Independant | 143 | # Architecture Independant |
145 | obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o | 144 | obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o |
146 | obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o | 145 | obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o |
146 | obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o | ||
147 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o | 147 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o |
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 4d18c874d963..2ffce4d75443 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c | |||
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
150 | int options, retval = -EINVAL; | 150 | int options, retval = -EINVAL; |
151 | void __user *argp = (void __user *)arg; | 151 | void __user *argp = (void __user *)arg; |
152 | int __user *p = argp; | 152 | int __user *p = argp; |
153 | static struct watchdog_info ident = { | 153 | static const struct watchdog_info ident = { |
154 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 154 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
155 | .firmware_version = 1, | 155 | .firmware_version = 1, |
156 | .identity = WATCHDOG_NAME, | 156 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 824d076a5cd6..4d40965d2c9f 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c | |||
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
137 | int new_timeout; | 137 | int new_timeout; |
138 | void __user *argp = (void __user *)arg; | 138 | void __user *argp = (void __user *)arg; |
139 | int __user *p = argp; | 139 | int __user *p = argp; |
140 | static struct watchdog_info ident = { | 140 | static const struct watchdog_info ident = { |
141 | .options = WDIOF_KEEPALIVEPING | | 141 | .options = WDIOF_KEEPALIVEPING | |
142 | WDIOF_SETTIMEOUT | | 142 | WDIOF_SETTIMEOUT | |
143 | WDIOF_MAGICCLOSE, | 143 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 77afb0acc500..af6e6b16475a 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
10 | #include <linux/gfp.h> | ||
10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
11 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -37,7 +38,7 @@ struct adx_wdt { | |||
37 | spinlock_t lock; | 38 | spinlock_t lock; |
38 | }; | 39 | }; |
39 | 40 | ||
40 | static struct watchdog_info adx_wdt_info = { | 41 | static const struct watchdog_info adx_wdt_info = { |
41 | .identity = "Avionic Design Xanthos Watchdog", | 42 | .identity = "Avionic Design Xanthos Watchdog", |
42 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 43 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
43 | }; | 44 | }; |
@@ -242,14 +243,14 @@ static int __devinit adx_wdt_probe(struct platform_device *pdev) | |||
242 | } | 243 | } |
243 | 244 | ||
244 | res = devm_request_mem_region(&pdev->dev, res->start, | 245 | res = devm_request_mem_region(&pdev->dev, res->start, |
245 | res->end - res->start + 1, res->name); | 246 | resource_size(res), res->name); |
246 | if (!res) { | 247 | if (!res) { |
247 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); | 248 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); |
248 | return -ENXIO; | 249 | return -ENXIO; |
249 | } | 250 | } |
250 | 251 | ||
251 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, | 252 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, |
252 | res->end - res->start + 1); | 253 | resource_size(res)); |
253 | if (!wdt->base) { | 254 | if (!wdt->base) { |
254 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | 255 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); |
255 | return -ENXIO; | 256 | return -ENXIO; |
@@ -314,7 +315,7 @@ static int adx_wdt_resume(struct device *dev) | |||
314 | return 0; | 315 | return 0; |
315 | } | 316 | } |
316 | 317 | ||
317 | static struct dev_pm_ops adx_wdt_pm_ops = { | 318 | static const struct dev_pm_ops adx_wdt_pm_ops = { |
318 | .suspend = adx_wdt_suspend, | 319 | .suspend = adx_wdt_suspend, |
319 | .resume = adx_wdt_resume, | 320 | .resume = adx_wdt_resume, |
320 | }; | 321 | }; |
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index 937a80fb61e1..1e9caea8ff8a 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c | |||
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
180 | { | 180 | { |
181 | void __user *argp = (void __user *)arg; | 181 | void __user *argp = (void __user *)arg; |
182 | int __user *p = argp; | 182 | int __user *p = argp; |
183 | static struct watchdog_info ident = { | 183 | static const struct watchdog_info ident = { |
184 | .options = WDIOF_KEEPALIVEPING | | 184 | .options = WDIOF_KEEPALIVEPING | |
185 | WDIOF_SETTIMEOUT | | 185 | WDIOF_SETTIMEOUT | |
186 | WDIOF_MAGICCLOSE, | 186 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index f90afdb1b255..d8d4da9a483d 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c | |||
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
238 | { | 238 | { |
239 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
240 | int __user *p = argp; | 240 | int __user *p = argp; |
241 | static struct watchdog_info ident = { | 241 | static const struct watchdog_info ident = { |
242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
243 | | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
244 | .firmware_version = 1, | 244 | .firmware_version = 1, |
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 2e94b71b20d9..c764c52412e4 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
36 | #include <linux/uaccess.h> | 36 | #include <linux/uaccess.h> |
37 | #include <linux/clk.h> | ||
37 | 38 | ||
38 | #include <asm/addrspace.h> | 39 | #include <asm/addrspace.h> |
39 | #include <asm/mach-ar7/ar7.h> | 40 | #include <asm/mach-ar7/ar7.h> |
@@ -80,6 +81,8 @@ static struct resource *ar7_regs_wdt; | |||
80 | /* Pointer to the remapped WDT IO space */ | 81 | /* Pointer to the remapped WDT IO space */ |
81 | static struct ar7_wdt *ar7_wdt; | 82 | static struct ar7_wdt *ar7_wdt; |
82 | 83 | ||
84 | static struct clk *vbus_clk; | ||
85 | |||
83 | static void ar7_wdt_kick(u32 value) | 86 | static void ar7_wdt_kick(u32 value) |
84 | { | 87 | { |
85 | WRITE_REG(ar7_wdt->kick_lock, 0x5555); | 88 | WRITE_REG(ar7_wdt->kick_lock, 0x5555); |
@@ -138,17 +141,19 @@ static void ar7_wdt_disable(u32 value) | |||
138 | static void ar7_wdt_update_margin(int new_margin) | 141 | static void ar7_wdt_update_margin(int new_margin) |
139 | { | 142 | { |
140 | u32 change; | 143 | u32 change; |
144 | u32 vbus_rate; | ||
141 | 145 | ||
142 | change = new_margin * (ar7_vbus_freq() / prescale_value); | 146 | vbus_rate = clk_get_rate(vbus_clk); |
147 | change = new_margin * (vbus_rate / prescale_value); | ||
143 | if (change < 1) | 148 | if (change < 1) |
144 | change = 1; | 149 | change = 1; |
145 | if (change > 0xffff) | 150 | if (change > 0xffff) |
146 | change = 0xffff; | 151 | change = 0xffff; |
147 | ar7_wdt_change(change); | 152 | ar7_wdt_change(change); |
148 | margin = change * prescale_value / ar7_vbus_freq(); | 153 | margin = change * prescale_value / vbus_rate; |
149 | printk(KERN_INFO DRVNAME | 154 | printk(KERN_INFO DRVNAME |
150 | ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", | 155 | ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", |
151 | margin, prescale_value, change, ar7_vbus_freq()); | 156 | margin, prescale_value, change, vbus_rate); |
152 | } | 157 | } |
153 | 158 | ||
154 | static void ar7_wdt_enable_wdt(void) | 159 | static void ar7_wdt_enable_wdt(void) |
@@ -214,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, | |||
214 | static long ar7_wdt_ioctl(struct file *file, | 219 | static long ar7_wdt_ioctl(struct file *file, |
215 | unsigned int cmd, unsigned long arg) | 220 | unsigned int cmd, unsigned long arg) |
216 | { | 221 | { |
217 | static struct watchdog_info ident = { | 222 | static const struct watchdog_info ident = { |
218 | .identity = LONGNAME, | 223 | .identity = LONGNAME, |
219 | .firmware_version = 1, | 224 | .firmware_version = 1, |
220 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | 225 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
@@ -298,6 +303,13 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev) | |||
298 | goto out_mem_region; | 303 | goto out_mem_region; |
299 | } | 304 | } |
300 | 305 | ||
306 | vbus_clk = clk_get(NULL, "vbus"); | ||
307 | if (IS_ERR(vbus_clk)) { | ||
308 | printk(KERN_ERR DRVNAME ": could not get vbus clock\n"); | ||
309 | rc = PTR_ERR(vbus_clk); | ||
310 | goto out_mem_region; | ||
311 | } | ||
312 | |||
301 | ar7_wdt_disable_wdt(); | 313 | ar7_wdt_disable_wdt(); |
302 | ar7_wdt_prescale(prescale_value); | 314 | ar7_wdt_prescale(prescale_value); |
303 | ar7_wdt_update_margin(margin); | 315 | ar7_wdt_update_margin(margin); |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index e8ae638e5804..1cddf92cb9a6 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | #define TIMEOUT_MIN 1 | 37 | #define TIMEOUT_MIN 1 |
37 | #define TIMEOUT_MAX 2 | 38 | #define TIMEOUT_MAX 2 |
@@ -202,7 +203,7 @@ static int at32_wdt_get_status(void) | |||
202 | return status; | 203 | return status; |
203 | } | 204 | } |
204 | 205 | ||
205 | static struct watchdog_info at32_wdt_info = { | 206 | static const struct watchdog_info at32_wdt_info = { |
206 | .identity = "at32ap700x watchdog", | 207 | .identity = "at32ap700x watchdog", |
207 | .options = WDIOF_SETTIMEOUT | | 208 | .options = WDIOF_SETTIMEOUT | |
208 | WDIOF_KEEPALIVEPING | | 209 | WDIOF_KEEPALIVEPING | |
@@ -326,7 +327,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev) | |||
326 | return -ENOMEM; | 327 | return -ENOMEM; |
327 | } | 328 | } |
328 | 329 | ||
329 | wdt->regs = ioremap(regs->start, regs->end - regs->start + 1); | 330 | wdt->regs = ioremap(regs->start, resource_size(regs)); |
330 | if (!wdt->regs) { | 331 | if (!wdt->regs) { |
331 | ret = -ENOMEM; | 332 | ret = -ENOMEM; |
332 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); | 333 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index b185dafe1494..b3046dc4b56c 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_time) | |||
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | static struct watchdog_info at91_wdt_info = { | 124 | static const struct watchdog_info at91_wdt_info = { |
125 | .identity = "at91 watchdog", | 125 | .identity = "at91 watchdog", |
126 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 126 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
127 | }; | 127 | }; |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index 751c003864ad..5f245522397b 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data, | |||
149 | return len; | 149 | return len; |
150 | } | 150 | } |
151 | 151 | ||
152 | static struct watchdog_info bcm47xx_wdt_info = { | 152 | static const struct watchdog_info bcm47xx_wdt_info = { |
153 | .identity = DRV_NAME, | 153 | .identity = DRV_NAME, |
154 | .options = WDIOF_SETTIMEOUT | | 154 | .options = WDIOF_SETTIMEOUT | |
155 | WDIOF_KEEPALIVEPING | | 155 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index c7b3f9df2317..9c7ccd1e9088 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Watchdog Driver | 2 | * Blackfin On-Chip Watchdog Driver |
3 | * Supports BF53[123]/BF53[467]/BF54[2489]/BF561 | ||
4 | * | 3 | * |
5 | * Originally based on softdog.c | 4 | * Originally based on softdog.c |
6 | * Copyright 2006-2007 Analog Devices Inc. | 5 | * Copyright 2006-2010 Analog Devices Inc. |
7 | * Copyright 2006-2007 Michele d'Amico | 6 | * Copyright 2006-2007 Michele d'Amico |
8 | * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> | 7 | * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> |
9 | * | 8 | * |
@@ -20,8 +19,6 @@ | |||
20 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
21 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
22 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
23 | #include <linux/notifier.h> | ||
24 | #include <linux/reboot.h> | ||
25 | #include <linux/init.h> | 22 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
27 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
@@ -75,7 +72,7 @@ | |||
75 | 72 | ||
76 | static unsigned int timeout = WATCHDOG_TIMEOUT; | 73 | static unsigned int timeout = WATCHDOG_TIMEOUT; |
77 | static int nowayout = WATCHDOG_NOWAYOUT; | 74 | static int nowayout = WATCHDOG_NOWAYOUT; |
78 | static struct watchdog_info bfin_wdt_info; | 75 | static const struct watchdog_info bfin_wdt_info; |
79 | static unsigned long open_check; | 76 | static unsigned long open_check; |
80 | static char expect_close; | 77 | static char expect_close; |
81 | static DEFINE_SPINLOCK(bfin_wdt_spinlock); | 78 | static DEFINE_SPINLOCK(bfin_wdt_spinlock); |
@@ -137,13 +134,15 @@ static int bfin_wdt_running(void) | |||
137 | */ | 134 | */ |
138 | static int bfin_wdt_set_timeout(unsigned long t) | 135 | static int bfin_wdt_set_timeout(unsigned long t) |
139 | { | 136 | { |
140 | u32 cnt; | 137 | u32 cnt, max_t, sclk; |
141 | unsigned long flags; | 138 | unsigned long flags; |
142 | 139 | ||
143 | stampit(); | 140 | sclk = get_sclk(); |
141 | max_t = -1 / sclk; | ||
142 | cnt = t * sclk; | ||
143 | stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt); | ||
144 | 144 | ||
145 | cnt = t * get_sclk(); | 145 | if (t > max_t) { |
146 | if (cnt < get_sclk()) { | ||
147 | printk(KERN_WARNING PFX "timeout value is too large\n"); | 146 | printk(KERN_WARNING PFX "timeout value is too large\n"); |
148 | return -EINVAL; | 147 | return -EINVAL; |
149 | } | 148 | } |
@@ -308,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file, | |||
308 | } | 307 | } |
309 | } | 308 | } |
310 | 309 | ||
311 | /** | ||
312 | * bfin_wdt_notify_sys - Notifier Handler | ||
313 | * @this: notifier block | ||
314 | * @code: notifier event | ||
315 | * @unused: unused | ||
316 | * | ||
317 | * Handles specific events, such as turning off the watchdog during a | ||
318 | * shutdown event. | ||
319 | */ | ||
320 | static int bfin_wdt_notify_sys(struct notifier_block *this, | ||
321 | unsigned long code, void *unused) | ||
322 | { | ||
323 | stampit(); | ||
324 | |||
325 | if (code == SYS_DOWN || code == SYS_HALT) | ||
326 | bfin_wdt_stop(); | ||
327 | |||
328 | return NOTIFY_DONE; | ||
329 | } | ||
330 | |||
331 | #ifdef CONFIG_PM | 310 | #ifdef CONFIG_PM |
332 | static int state_before_suspend; | 311 | static int state_before_suspend; |
333 | 312 | ||
@@ -387,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = { | |||
387 | .fops = &bfin_wdt_fops, | 366 | .fops = &bfin_wdt_fops, |
388 | }; | 367 | }; |
389 | 368 | ||
390 | static struct watchdog_info bfin_wdt_info = { | 369 | static const struct watchdog_info bfin_wdt_info = { |
391 | .identity = "Blackfin Watchdog", | 370 | .identity = "Blackfin Watchdog", |
392 | .options = WDIOF_SETTIMEOUT | | 371 | .options = WDIOF_SETTIMEOUT | |
393 | WDIOF_KEEPALIVEPING | | 372 | WDIOF_KEEPALIVEPING | |
394 | WDIOF_MAGICCLOSE, | 373 | WDIOF_MAGICCLOSE, |
395 | }; | 374 | }; |
396 | 375 | ||
397 | static struct notifier_block bfin_wdt_notifier = { | ||
398 | .notifier_call = bfin_wdt_notify_sys, | ||
399 | }; | ||
400 | |||
401 | /** | 376 | /** |
402 | * bfin_wdt_probe - Initialize module | 377 | * bfin_wdt_probe - Initialize module |
403 | * | 378 | * |
404 | * Registers the misc device and notifier handler. Actual device | 379 | * Registers the misc device. Actual device |
405 | * initialization is handled by bfin_wdt_open(). | 380 | * initialization is handled by bfin_wdt_open(). |
406 | */ | 381 | */ |
407 | static int __devinit bfin_wdt_probe(struct platform_device *pdev) | 382 | static int __devinit bfin_wdt_probe(struct platform_device *pdev) |
408 | { | 383 | { |
409 | int ret; | 384 | int ret; |
410 | 385 | ||
411 | ret = register_reboot_notifier(&bfin_wdt_notifier); | ||
412 | if (ret) { | ||
413 | pr_devinit(KERN_ERR PFX | ||
414 | "cannot register reboot notifier (err=%d)\n", ret); | ||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | ret = misc_register(&bfin_wdt_miscdev); | 386 | ret = misc_register(&bfin_wdt_miscdev); |
419 | if (ret) { | 387 | if (ret) { |
420 | pr_devinit(KERN_ERR PFX | 388 | pr_devinit(KERN_ERR PFX |
421 | "cannot register miscdev on minor=%d (err=%d)\n", | 389 | "cannot register miscdev on minor=%d (err=%d)\n", |
422 | WATCHDOG_MINOR, ret); | 390 | WATCHDOG_MINOR, ret); |
423 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
424 | return ret; | 391 | return ret; |
425 | } | 392 | } |
426 | 393 | ||
@@ -433,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev) | |||
433 | /** | 400 | /** |
434 | * bfin_wdt_remove - Initialize module | 401 | * bfin_wdt_remove - Initialize module |
435 | * | 402 | * |
436 | * Unregisters the misc device and notifier handler. Actual device | 403 | * Unregisters the misc device. Actual device |
437 | * deinitialization is handled by bfin_wdt_close(). | 404 | * deinitialization is handled by bfin_wdt_close(). |
438 | */ | 405 | */ |
439 | static int __devexit bfin_wdt_remove(struct platform_device *pdev) | 406 | static int __devexit bfin_wdt_remove(struct platform_device *pdev) |
440 | { | 407 | { |
441 | misc_deregister(&bfin_wdt_miscdev); | 408 | misc_deregister(&bfin_wdt_miscdev); |
442 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
443 | return 0; | 409 | return 0; |
444 | } | 410 | } |
445 | 411 | ||
412 | /** | ||
413 | * bfin_wdt_shutdown - Soft Shutdown Handler | ||
414 | * | ||
415 | * Handles the soft shutdown event. | ||
416 | */ | ||
417 | static void bfin_wdt_shutdown(struct platform_device *pdev) | ||
418 | { | ||
419 | stampit(); | ||
420 | |||
421 | bfin_wdt_stop(); | ||
422 | } | ||
423 | |||
446 | static struct platform_device *bfin_wdt_device; | 424 | static struct platform_device *bfin_wdt_device; |
447 | 425 | ||
448 | static struct platform_driver bfin_wdt_driver = { | 426 | static struct platform_driver bfin_wdt_driver = { |
449 | .probe = bfin_wdt_probe, | 427 | .probe = bfin_wdt_probe, |
450 | .remove = __devexit_p(bfin_wdt_remove), | 428 | .remove = __devexit_p(bfin_wdt_remove), |
429 | .shutdown = bfin_wdt_shutdown, | ||
451 | .suspend = bfin_wdt_suspend, | 430 | .suspend = bfin_wdt_suspend, |
452 | .resume = bfin_wdt_resume, | 431 | .resume = bfin_wdt_resume, |
453 | .driver = { | 432 | .driver = { |
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index e8380ef65c1c..801ead191499 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | |||
44 | 44 | ||
45 | #ifdef CONFIG_FSL_BOOKE | 45 | #ifdef CONFIG_FSL_BOOKE |
46 | #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) | 46 | #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) |
47 | #define WDTP_MASK (WDTP(0)) | 47 | #define WDTP_MASK (WDTP(0x3f)) |
48 | #else | 48 | #else |
49 | #define WDTP(x) (TCR_WP(x)) | 49 | #define WDTP(x) (TCR_WP(x)) |
50 | #define WDTP_MASK (TCR_WP_MASK) | 50 | #define WDTP_MASK (TCR_WP_MASK) |
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 381026c0bd7b..9291506b8b23 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c | |||
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file *file, unsigned int cmd, | |||
257 | struct watchdog_info __user *ident; | 257 | struct watchdog_info __user *ident; |
258 | int __user *i; | 258 | int __user *i; |
259 | } uarg; | 259 | } uarg; |
260 | static struct watchdog_info ident = { | 260 | static const struct watchdog_info ident = { |
261 | .options = WDIOF_CARDRESET | | 261 | .options = WDIOF_CARDRESET | |
262 | WDIOF_SETTIMEOUT | | 262 | WDIOF_SETTIMEOUT | |
263 | WDIOF_KEEPALIVEPING, | 263 | WDIOF_KEEPALIVEPING, |
@@ -508,7 +508,7 @@ void coh901327_watchdog_reset(void) | |||
508 | * deactivating the watchdog before it is shut down by it. | 508 | * deactivating the watchdog before it is shut down by it. |
509 | * | 509 | * |
510 | * NOTE: on future versions of the watchdog, this restriction is | 510 | * NOTE: on future versions of the watchdog, this restriction is |
511 | * gone: the watchdog will be reloaded with a defaul value (1 min) | 511 | * gone: the watchdog will be reloaded with a default value (1 min) |
512 | * instead of last value, and you can conveniently set the watchdog | 512 | * instead of last value, and you can conveniently set the watchdog |
513 | * timeout to 10ms (value = 1) without any problems. | 513 | * timeout to 10ms (value = 1) without any problems. |
514 | */ | 514 | */ |
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 71f6d7eec9a8..edd3475f41db 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, | |||
154 | void __user *argp = (void __user *)arg; | 154 | void __user *argp = (void __user *)arg; |
155 | int __user *p = argp; | 155 | int __user *p = argp; |
156 | unsigned int value; | 156 | unsigned int value; |
157 | static struct watchdog_info ident = { | 157 | static const struct watchdog_info ident = { |
158 | .options = WDIOF_CARDRESET, | 158 | .options = WDIOF_CARDRESET, |
159 | .identity = "CPU5 WDT", | 159 | .identity = "CPU5 WDT", |
160 | }; | 160 | }; |
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 081f2955419e..ba2efce4b40e 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/timer.h> | 26 | #include <linux/timer.h> |
27 | #include <linux/slab.h> | ||
27 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
28 | #include <linux/io.h> | 29 | #include <linux/io.h> |
29 | #include <linux/of.h> | 30 | #include <linux/of.h> |
@@ -403,7 +404,7 @@ static int cpwd_release(struct inode *inode, struct file *file) | |||
403 | 404 | ||
404 | static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 405 | static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
405 | { | 406 | { |
406 | static struct watchdog_info info = { | 407 | static const struct watchdog_info info = { |
407 | .options = WDIOF_SETTIMEOUT, | 408 | .options = WDIOF_SETTIMEOUT, |
408 | .firmware_version = 1, | 409 | .firmware_version = 1, |
409 | .identity = DRIVER_NAME, | 410 | .identity = DRIVER_NAME, |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 9d7520fa9e9c..596ba604e78d 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #define MODULE_NAME "DAVINCI-WDT: " | 31 | #define MODULE_NAME "DAVINCI-WDT: " |
31 | 32 | ||
@@ -142,7 +143,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len, | |||
142 | return len; | 143 | return len; |
143 | } | 144 | } |
144 | 145 | ||
145 | static struct watchdog_info ident = { | 146 | static const struct watchdog_info ident = { |
146 | .options = WDIOF_KEEPALIVEPING, | 147 | .options = WDIOF_KEEPALIVEPING, |
147 | .identity = "DaVinci Watchdog", | 148 | .identity = "DaVinci Watchdog", |
148 | }; | 149 | }; |
@@ -221,7 +222,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) | |||
221 | return -ENOENT; | 222 | return -ENOENT; |
222 | } | 223 | } |
223 | 224 | ||
224 | size = res->end - res->start + 1; | 225 | size = resource_size(res); |
225 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 226 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
226 | 227 | ||
227 | if (wdt_mem == NULL) { | 228 | if (wdt_mem == NULL) { |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index cdd55e0d09f8..59359c9a5e01 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, const char __user *data, size_t len, | |||
131 | return len; | 131 | return len; |
132 | } | 132 | } |
133 | 133 | ||
134 | static struct watchdog_info ident = { | 134 | static const struct watchdog_info ident = { |
135 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, | 135 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, |
136 | .identity = "EP93xx Watchdog", | 136 | .identity = "EP93xx Watchdog", |
137 | }; | 137 | }; |
@@ -244,7 +244,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | |||
244 | module_param(timeout, int, 0); | 244 | module_param(timeout, int, 0); |
245 | MODULE_PARM_DESC(timeout, | 245 | MODULE_PARM_DESC(timeout, |
246 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | 246 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" |
247 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 247 | __MODULE_STRING(WDT_TIMEOUT) ")"); |
248 | 248 | ||
249 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," | 249 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," |
250 | "Alessandro Zummo <a.zummo@towertech.it>"); | 250 | "Alessandro Zummo <a.zummo@towertech.it>"); |
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index 9add3541fb42..d1c4e55b1db0 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c | |||
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *file, | |||
238 | { | 238 | { |
239 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
240 | int __user *p = argp; | 240 | int __user *p = argp; |
241 | static struct watchdog_info ident = { | 241 | static const struct watchdog_info ident = { |
242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
243 | | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
244 | .firmware_version = 1, | 244 | .firmware_version = 1, |
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 734d9806a872..abdbad034a6c 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * GE Fanuc watchdog userspace interface | 2 | * GE watchdog userspace interface |
3 | * | 3 | * |
4 | * Author: Martyn Welch <martyn.welch@gefanuc.com> | 4 | * Author: Martyn Welch <martyn.welch@ge.com> |
5 | * | 5 | * |
6 | * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. | 6 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *file, unsigned int cmd, | |||
161 | int timeout; | 161 | int timeout; |
162 | int options; | 162 | int options; |
163 | void __user *argp = (void __user *)arg; | 163 | void __user *argp = (void __user *)arg; |
164 | static struct watchdog_info info = { | 164 | static const struct watchdog_info info = { |
165 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | | 165 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | |
166 | WDIOF_KEEPALIVEPING, | 166 | WDIOF_KEEPALIVEPING, |
167 | .firmware_version = 0, | 167 | .firmware_version = 0, |
168 | .identity = "GE Fanuc watchdog", | 168 | .identity = "GE watchdog", |
169 | }; | 169 | }; |
170 | 170 | ||
171 | switch (cmd) { | 171 | switch (cmd) { |
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt_driver = { | |||
311 | 311 | ||
312 | static int __init gef_wdt_init(void) | 312 | static int __init gef_wdt_init(void) |
313 | { | 313 | { |
314 | printk(KERN_INFO "GE Fanuc watchdog driver\n"); | 314 | printk(KERN_INFO "GE watchdog driver\n"); |
315 | return of_register_platform_driver(&gef_wdt_driver); | 315 | return of_register_platform_driver(&gef_wdt_driver); |
316 | } | 316 | } |
317 | 317 | ||
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void) | |||
323 | module_init(gef_wdt_init); | 323 | module_init(gef_wdt_init); |
324 | module_exit(gef_wdt_exit); | 324 | module_exit(gef_wdt_exit); |
325 | 325 | ||
326 | MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); | 326 | MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>"); |
327 | MODULE_DESCRIPTION("GE Fanuc watchdog driver"); | 327 | MODULE_DESCRIPTION("GE watchdog driver"); |
328 | MODULE_LICENSE("GPL"); | 328 | MODULE_LICENSE("GPL"); |
329 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 329 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
330 | MODULE_ALIAS("platform: gef_wdt"); | 330 | MODULE_ALIAS("platform: gef_wdt"); |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 9acf0015a1e7..9b49b125ad5a 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; |
@@ -141,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd, | |||
141 | int __user *p = argp; | 142 | int __user *p = argp; |
142 | int interval; | 143 | int interval; |
143 | 144 | ||
144 | static struct watchdog_info ident = { | 145 | static const struct watchdog_info ident = { |
145 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 146 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
146 | | WDIOF_MAGICCLOSE, | 147 | | WDIOF_MAGICCLOSE, |
147 | .firmware_version = 1, | 148 | .firmware_version = 1, |
@@ -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/hpwdt.c b/drivers/watchdog/hpwdt.c index a6c5674c78e6..809e7167a624 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/efi.h> | 39 | #include <linux/efi.h> |
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/bootmem.h> | 41 | #include <linux/bootmem.h> |
42 | #include <linux/slab.h> | ||
43 | #include <asm/desc.h> | 42 | #include <asm/desc.h> |
44 | #include <asm/cacheflush.h> | 43 | #include <asm/cacheflush.h> |
45 | 44 | ||
@@ -443,7 +442,7 @@ static void hpwdt_ping(void) | |||
443 | static int hpwdt_change_timer(int new_margin) | 442 | static int hpwdt_change_timer(int new_margin) |
444 | { | 443 | { |
445 | /* Arbitrary, can't find the card's limits */ | 444 | /* Arbitrary, can't find the card's limits */ |
446 | if (new_margin < 30 || new_margin > 600) { | 445 | if (new_margin < 5 || new_margin > 600) { |
447 | printk(KERN_WARNING | 446 | printk(KERN_WARNING |
448 | "hpwdt: New value passed in is invalid: %d seconds.\n", | 447 | "hpwdt: New value passed in is invalid: %d seconds.\n", |
449 | new_margin); | 448 | new_margin); |
@@ -554,7 +553,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data, | |||
554 | return len; | 553 | return len; |
555 | } | 554 | } |
556 | 555 | ||
557 | static struct watchdog_info ident = { | 556 | static const struct watchdog_info ident = { |
558 | .options = WDIOF_SETTIMEOUT | | 557 | .options = WDIOF_SETTIMEOUT | |
559 | WDIOF_KEEPALIVEPING | | 558 | WDIOF_KEEPALIVEPING | |
560 | WDIOF_MAGICCLOSE, | 559 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 7ba0b11ec525..bb9750a03942 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/miscdevice.h> | 35 | #include <linux/miscdevice.h> |
36 | #include <linux/watchdog.h> | 36 | #include <linux/watchdog.h> |
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
40 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
@@ -42,7 +41,7 @@ | |||
42 | #include <linux/io.h> | 41 | #include <linux/io.h> |
43 | 42 | ||
44 | /* Module and version information */ | 43 | /* Module and version information */ |
45 | #define ESB_VERSION "0.04" | 44 | #define ESB_VERSION "0.05" |
46 | #define ESB_MODULE_NAME "i6300ESB timer" | 45 | #define ESB_MODULE_NAME "i6300ESB timer" |
47 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION | 46 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION |
48 | #define PFX ESB_MODULE_NAME ": " | 47 | #define PFX ESB_MODULE_NAME ": " |
@@ -65,7 +64,7 @@ | |||
65 | /* Config register bits */ | 64 | /* Config register bits */ |
66 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ | 65 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ |
67 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ | 66 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ |
68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ | 67 | #define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */ |
69 | 68 | ||
70 | /* Reload register bits */ | 69 | /* Reload register bits */ |
71 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ | 70 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ |
@@ -82,7 +81,9 @@ static unsigned long timer_alive; | |||
82 | static struct pci_dev *esb_pci; | 81 | static struct pci_dev *esb_pci; |
83 | static unsigned short triggered; /* The status of the watchdog upon boot */ | 82 | static unsigned short triggered; /* The status of the watchdog upon boot */ |
84 | static char esb_expect_close; | 83 | static char esb_expect_close; |
85 | static struct platform_device *esb_platform_device; | 84 | |
85 | /* We can only use 1 card due to the /dev/watchdog restriction */ | ||
86 | static int cards_found; | ||
86 | 87 | ||
87 | /* module parameters */ | 88 | /* module parameters */ |
88 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ | 89 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout, | |||
111 | */ | 112 | */ |
112 | static inline void esb_unlock_registers(void) | 113 | static inline void esb_unlock_registers(void) |
113 | { | 114 | { |
114 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); | 115 | writew(ESB_UNLOCK1, ESB_RELOAD_REG); |
115 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | 116 | writew(ESB_UNLOCK2, ESB_RELOAD_REG); |
116 | } | 117 | } |
117 | 118 | ||
118 | static int esb_timer_start(void) | 119 | static int esb_timer_start(void) |
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
256 | int new_heartbeat; | 257 | int new_heartbeat; |
257 | void __user *argp = (void __user *)arg; | 258 | void __user *argp = (void __user *)arg; |
258 | int __user *p = argp; | 259 | int __user *p = argp; |
259 | static struct watchdog_info ident = { | 260 | static const struct watchdog_info ident = { |
260 | .options = WDIOF_SETTIMEOUT | | 261 | .options = WDIOF_SETTIMEOUT | |
261 | WDIOF_KEEPALIVEPING | | 262 | WDIOF_KEEPALIVEPING | |
262 | WDIOF_MAGICCLOSE, | 263 | WDIOF_MAGICCLOSE, |
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = { | |||
332 | 333 | ||
333 | /* | 334 | /* |
334 | * Data for PCI driver interface | 335 | * Data for PCI driver interface |
335 | * | ||
336 | * This data only exists for exporting the supported | ||
337 | * PCI ids via MODULE_DEVICE_TABLE. We do not actually | ||
338 | * register a pci_driver, because someone else might one day | ||
339 | * want to register another driver on the same PCI id. | ||
340 | */ | 336 | */ |
341 | static struct pci_device_id esb_pci_tbl[] = { | 337 | static struct pci_device_id esb_pci_tbl[] = { |
342 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, | 338 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, |
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); | |||
348 | * Init & exit routines | 344 | * Init & exit routines |
349 | */ | 345 | */ |
350 | 346 | ||
351 | static unsigned char __devinit esb_getdevice(void) | 347 | static unsigned char __devinit esb_getdevice(struct pci_dev *pdev) |
352 | { | 348 | { |
353 | /* | 349 | if (pci_enable_device(pdev)) { |
354 | * Find the PCI device | ||
355 | */ | ||
356 | |||
357 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
358 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); | ||
359 | |||
360 | if (!esb_pci) | ||
361 | return 0; | ||
362 | |||
363 | if (pci_enable_device(esb_pci)) { | ||
364 | printk(KERN_ERR PFX "failed to enable device\n"); | 350 | printk(KERN_ERR PFX "failed to enable device\n"); |
365 | goto err_devput; | 351 | goto err_devput; |
366 | } | 352 | } |
367 | 353 | ||
368 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 354 | if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) { |
369 | printk(KERN_ERR PFX "failed to request region\n"); | 355 | printk(KERN_ERR PFX "failed to request region\n"); |
370 | goto err_disable; | 356 | goto err_disable; |
371 | } | 357 | } |
372 | 358 | ||
373 | BASEADDR = pci_ioremap_bar(esb_pci, 0); | 359 | BASEADDR = pci_ioremap_bar(pdev, 0); |
374 | if (BASEADDR == NULL) { | 360 | if (BASEADDR == NULL) { |
375 | /* Something's wrong here, BASEADDR has to be set */ | 361 | /* Something's wrong here, BASEADDR has to be set */ |
376 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); | 362 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void) | |||
378 | } | 364 | } |
379 | 365 | ||
380 | /* Done */ | 366 | /* Done */ |
367 | esb_pci = pdev; | ||
381 | return 1; | 368 | return 1; |
382 | 369 | ||
383 | err_release: | 370 | err_release: |
384 | pci_release_region(esb_pci, 0); | 371 | pci_release_region(pdev, 0); |
385 | err_disable: | 372 | err_disable: |
386 | pci_disable_device(esb_pci); | 373 | pci_disable_device(pdev); |
387 | err_devput: | 374 | err_devput: |
388 | pci_dev_put(esb_pci); | ||
389 | return 0; | 375 | return 0; |
390 | } | 376 | } |
391 | 377 | ||
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void) | |||
430 | esb_timer_set_heartbeat(heartbeat); | 416 | esb_timer_set_heartbeat(heartbeat); |
431 | } | 417 | } |
432 | 418 | ||
433 | static int __devinit esb_probe(struct platform_device *dev) | 419 | static int __devinit esb_probe(struct pci_dev *pdev, |
420 | const struct pci_device_id *ent) | ||
434 | { | 421 | { |
435 | int ret; | 422 | int ret; |
436 | 423 | ||
424 | cards_found++; | ||
425 | if (cards_found == 1) | ||
426 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
427 | ESB_VERSION); | ||
428 | |||
429 | if (cards_found > 1) { | ||
430 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); | ||
431 | return -ENODEV; | ||
432 | } | ||
433 | |||
437 | /* Check whether or not the hardware watchdog is there */ | 434 | /* Check whether or not the hardware watchdog is there */ |
438 | if (!esb_getdevice() || esb_pci == NULL) | 435 | if (!esb_getdevice(pdev) || esb_pci == NULL) |
439 | return -ENODEV; | 436 | return -ENODEV; |
440 | 437 | ||
441 | /* Check that the heartbeat value is within it's range; | 438 | /* Check that the heartbeat value is within it's range; |
@@ -467,11 +464,11 @@ err_unmap: | |||
467 | iounmap(BASEADDR); | 464 | iounmap(BASEADDR); |
468 | pci_release_region(esb_pci, 0); | 465 | pci_release_region(esb_pci, 0); |
469 | pci_disable_device(esb_pci); | 466 | pci_disable_device(esb_pci); |
470 | pci_dev_put(esb_pci); | 467 | esb_pci = NULL; |
471 | return ret; | 468 | return ret; |
472 | } | 469 | } |
473 | 470 | ||
474 | static int __devexit esb_remove(struct platform_device *dev) | 471 | static void __devexit esb_remove(struct pci_dev *pdev) |
475 | { | 472 | { |
476 | /* Stop the timer before we leave */ | 473 | /* Stop the timer before we leave */ |
477 | if (!nowayout) | 474 | if (!nowayout) |
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev) | |||
482 | iounmap(BASEADDR); | 479 | iounmap(BASEADDR); |
483 | pci_release_region(esb_pci, 0); | 480 | pci_release_region(esb_pci, 0); |
484 | pci_disable_device(esb_pci); | 481 | pci_disable_device(esb_pci); |
485 | pci_dev_put(esb_pci); | 482 | esb_pci = NULL; |
486 | return 0; | ||
487 | } | 483 | } |
488 | 484 | ||
489 | static void esb_shutdown(struct platform_device *dev) | 485 | static void esb_shutdown(struct pci_dev *pdev) |
490 | { | 486 | { |
491 | esb_timer_stop(); | 487 | esb_timer_stop(); |
492 | } | 488 | } |
493 | 489 | ||
494 | static struct platform_driver esb_platform_driver = { | 490 | static struct pci_driver esb_driver = { |
491 | .name = ESB_MODULE_NAME, | ||
492 | .id_table = esb_pci_tbl, | ||
495 | .probe = esb_probe, | 493 | .probe = esb_probe, |
496 | .remove = __devexit_p(esb_remove), | 494 | .remove = __devexit_p(esb_remove), |
497 | .shutdown = esb_shutdown, | 495 | .shutdown = esb_shutdown, |
498 | .driver = { | ||
499 | .owner = THIS_MODULE, | ||
500 | .name = ESB_MODULE_NAME, | ||
501 | }, | ||
502 | }; | 496 | }; |
503 | 497 | ||
504 | static int __init watchdog_init(void) | 498 | static int __init watchdog_init(void) |
505 | { | 499 | { |
506 | int err; | 500 | return pci_register_driver(&esb_driver); |
507 | |||
508 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
509 | ESB_VERSION); | ||
510 | |||
511 | err = platform_driver_register(&esb_platform_driver); | ||
512 | if (err) | ||
513 | return err; | ||
514 | |||
515 | esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME, | ||
516 | -1, NULL, 0); | ||
517 | if (IS_ERR(esb_platform_device)) { | ||
518 | err = PTR_ERR(esb_platform_device); | ||
519 | goto unreg_platform_driver; | ||
520 | } | ||
521 | |||
522 | return 0; | ||
523 | |||
524 | unreg_platform_driver: | ||
525 | platform_driver_unregister(&esb_platform_driver); | ||
526 | return err; | ||
527 | } | 501 | } |
528 | 502 | ||
529 | static void __exit watchdog_cleanup(void) | 503 | static void __exit watchdog_cleanup(void) |
530 | { | 504 | { |
531 | platform_device_unregister(esb_platform_device); | 505 | pci_unregister_driver(&esb_driver); |
532 | platform_driver_unregister(&esb_platform_driver); | ||
533 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); | 506 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); |
534 | } | 507 | } |
535 | 508 | ||
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 6a51edde6ea7..8da886035374 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) | 2 | * intel TCO Watchdog Driver |
3 | * | 3 | * |
4 | * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. | 4 | * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. |
5 | * | 5 | * |
@@ -14,47 +14,24 @@ | |||
14 | * | 14 | * |
15 | * The TCO watchdog is implemented in the following I/O controller hubs: | 15 | * The TCO watchdog is implemented in the following I/O controller hubs: |
16 | * (See the intel documentation on http://developer.intel.com.) | 16 | * (See the intel documentation on http://developer.intel.com.) |
17 | * 82801AA (ICH) : document number 290655-003, 290677-014, | 17 | * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) |
18 | * 82801AB (ICHO) : document number 290655-003, 290677-014, | 18 | * document number 290687-002, 298242-027: 82801BA (ICH2) |
19 | * 82801BA (ICH2) : document number 290687-002, 298242-027, | 19 | * document number 290733-003, 290739-013: 82801CA (ICH3-S) |
20 | * 82801BAM (ICH2-M) : document number 290687-002, 298242-027, | 20 | * document number 290716-001, 290718-007: 82801CAM (ICH3-M) |
21 | * 82801CA (ICH3-S) : document number 290733-003, 290739-013, | 21 | * document number 290744-001, 290745-025: 82801DB (ICH4) |
22 | * 82801CAM (ICH3-M) : document number 290716-001, 290718-007, | 22 | * document number 252337-001, 252663-008: 82801DBM (ICH4-M) |
23 | * 82801DB (ICH4) : document number 290744-001, 290745-025, | 23 | * document number 273599-001, 273645-002: 82801E (C-ICH) |
24 | * 82801DBM (ICH4-M) : document number 252337-001, 252663-008, | 24 | * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) |
25 | * 82801E (C-ICH) : document number 273599-001, 273645-002, | 25 | * document number 300641-004, 300884-013: 6300ESB |
26 | * 82801EB (ICH5) : document number 252516-001, 252517-028, | 26 | * document number 301473-002, 301474-026: 82801F (ICH6) |
27 | * 82801ER (ICH5R) : document number 252516-001, 252517-028, | 27 | * document number 313082-001, 313075-006: 631xESB, 632xESB |
28 | * 6300ESB (6300ESB) : document number 300641-004, 300884-013, | 28 | * document number 307013-003, 307014-024: 82801G (ICH7) |
29 | * 82801FB (ICH6) : document number 301473-002, 301474-026, | 29 | * document number 313056-003, 313057-017: 82801H (ICH8) |
30 | * 82801FR (ICH6R) : document number 301473-002, 301474-026, | 30 | * document number 316972-004, 316973-012: 82801I (ICH9) |
31 | * 82801FBM (ICH6-M) : document number 301473-002, 301474-026, | 31 | * document number 319973-002, 319974-002: 82801J (ICH10) |
32 | * 82801FW (ICH6W) : document number 301473-001, 301474-026, | 32 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) |
33 | * 82801FRW (ICH6RW) : document number 301473-001, 301474-026, | 33 | * document number 320066-003, 320257-008: EP80597 (IICH) |
34 | * 631xESB (631xESB) : document number 313082-001, 313075-006, | 34 | * document number TBD : Cougar Point (CPT) |
35 | * 632xESB (632xESB) : document number 313082-001, 313075-006, | ||
36 | * 82801GB (ICH7) : document number 307013-003, 307014-024, | ||
37 | * 82801GR (ICH7R) : document number 307013-003, 307014-024, | ||
38 | * 82801GDH (ICH7DH) : document number 307013-003, 307014-024, | ||
39 | * 82801GBM (ICH7-M) : document number 307013-003, 307014-024, | ||
40 | * 82801GHM (ICH7-M DH) : document number 307013-003, 307014-024, | ||
41 | * 82801GU (ICH7-U) : document number 307013-003, 307014-024, | ||
42 | * 82801HB (ICH8) : document number 313056-003, 313057-017, | ||
43 | * 82801HR (ICH8R) : document number 313056-003, 313057-017, | ||
44 | * 82801HBM (ICH8M) : document number 313056-003, 313057-017, | ||
45 | * 82801HH (ICH8DH) : document number 313056-003, 313057-017, | ||
46 | * 82801HO (ICH8DO) : document number 313056-003, 313057-017, | ||
47 | * 82801HEM (ICH8M-E) : document number 313056-003, 313057-017, | ||
48 | * 82801IB (ICH9) : document number 316972-004, 316973-012, | ||
49 | * 82801IR (ICH9R) : document number 316972-004, 316973-012, | ||
50 | * 82801IH (ICH9DH) : document number 316972-004, 316973-012, | ||
51 | * 82801IO (ICH9DO) : document number 316972-004, 316973-012, | ||
52 | * 82801IBM (ICH9M) : document number 316972-004, 316973-012, | ||
53 | * 82801IEM (ICH9M-E) : document number 316972-004, 316973-012, | ||
54 | * 82801JIB (ICH10) : document number 319973-002, 319974-002, | ||
55 | * 82801JIR (ICH10R) : document number 319973-002, 319974-002, | ||
56 | * 82801JD (ICH10D) : document number 319973-002, 319974-002, | ||
57 | * 82801JDO (ICH10DO) : document number 319973-002, 319974-002 | ||
58 | */ | 35 | */ |
59 | 36 | ||
60 | /* | 37 | /* |
@@ -122,6 +99,53 @@ enum iTCO_chipsets { | |||
122 | TCO_ICH10R, /* ICH10R */ | 99 | TCO_ICH10R, /* ICH10R */ |
123 | TCO_ICH10D, /* ICH10D */ | 100 | TCO_ICH10D, /* ICH10D */ |
124 | TCO_ICH10DO, /* ICH10DO */ | 101 | TCO_ICH10DO, /* ICH10DO */ |
102 | TCO_PCH, /* PCH Desktop 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 */ | ||
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_CPT1, /* Cougar Point */ | ||
119 | TCO_CPT2, /* Cougar Point Desktop */ | ||
120 | TCO_CPT3, /* Cougar Point Mobile */ | ||
121 | TCO_CPT4, /* Cougar Point */ | ||
122 | TCO_CPT5, /* Cougar Point */ | ||
123 | TCO_CPT6, /* Cougar Point */ | ||
124 | TCO_CPT7, /* Cougar Point */ | ||
125 | TCO_CPT8, /* Cougar Point */ | ||
126 | TCO_CPT9, /* Cougar Point */ | ||
127 | TCO_CPT10, /* Cougar Point */ | ||
128 | TCO_CPT11, /* Cougar Point */ | ||
129 | TCO_CPT12, /* Cougar Point */ | ||
130 | TCO_CPT13, /* Cougar Point */ | ||
131 | TCO_CPT14, /* Cougar Point */ | ||
132 | TCO_CPT15, /* Cougar Point */ | ||
133 | TCO_CPT16, /* Cougar Point */ | ||
134 | TCO_CPT17, /* Cougar Point */ | ||
135 | TCO_CPT18, /* Cougar Point */ | ||
136 | TCO_CPT19, /* Cougar Point */ | ||
137 | TCO_CPT20, /* Cougar Point */ | ||
138 | TCO_CPT21, /* Cougar Point */ | ||
139 | TCO_CPT22, /* Cougar Point */ | ||
140 | TCO_CPT23, /* Cougar Point */ | ||
141 | TCO_CPT24, /* Cougar Point */ | ||
142 | TCO_CPT25, /* Cougar Point */ | ||
143 | TCO_CPT26, /* Cougar Point */ | ||
144 | TCO_CPT27, /* Cougar Point */ | ||
145 | TCO_CPT28, /* Cougar Point */ | ||
146 | TCO_CPT29, /* Cougar Point */ | ||
147 | TCO_CPT30, /* Cougar Point */ | ||
148 | TCO_CPT31, /* Cougar Point */ | ||
125 | }; | 149 | }; |
126 | 150 | ||
127 | static struct { | 151 | static struct { |
@@ -162,6 +186,53 @@ static struct { | |||
162 | {"ICH10R", 2}, | 186 | {"ICH10R", 2}, |
163 | {"ICH10D", 2}, | 187 | {"ICH10D", 2}, |
164 | {"ICH10DO", 2}, | 188 | {"ICH10DO", 2}, |
189 | {"PCH Desktop Full Featured", 2}, | ||
190 | {"PCH Mobile Full Featured", 2}, | ||
191 | {"P55", 2}, | ||
192 | {"PM55", 2}, | ||
193 | {"H55", 2}, | ||
194 | {"QM57", 2}, | ||
195 | {"H57", 2}, | ||
196 | {"HM55", 2}, | ||
197 | {"Q57", 2}, | ||
198 | {"HM57", 2}, | ||
199 | {"PCH Mobile SFF Full Featured", 2}, | ||
200 | {"QS57", 2}, | ||
201 | {"3400", 2}, | ||
202 | {"3420", 2}, | ||
203 | {"3450", 2}, | ||
204 | {"EP80579", 2}, | ||
205 | {"Cougar Point", 2}, | ||
206 | {"Cougar Point", 2}, | ||
207 | {"Cougar Point", 2}, | ||
208 | {"Cougar Point", 2}, | ||
209 | {"Cougar Point", 2}, | ||
210 | {"Cougar Point", 2}, | ||
211 | {"Cougar Point", 2}, | ||
212 | {"Cougar Point", 2}, | ||
213 | {"Cougar Point", 2}, | ||
214 | {"Cougar Point", 2}, | ||
215 | {"Cougar Point", 2}, | ||
216 | {"Cougar Point", 2}, | ||
217 | {"Cougar Point", 2}, | ||
218 | {"Cougar Point", 2}, | ||
219 | {"Cougar Point", 2}, | ||
220 | {"Cougar Point", 2}, | ||
221 | {"Cougar Point", 2}, | ||
222 | {"Cougar Point", 2}, | ||
223 | {"Cougar Point", 2}, | ||
224 | {"Cougar Point", 2}, | ||
225 | {"Cougar Point", 2}, | ||
226 | {"Cougar Point", 2}, | ||
227 | {"Cougar Point", 2}, | ||
228 | {"Cougar Point", 2}, | ||
229 | {"Cougar Point", 2}, | ||
230 | {"Cougar Point", 2}, | ||
231 | {"Cougar Point", 2}, | ||
232 | {"Cougar Point", 2}, | ||
233 | {"Cougar Point", 2}, | ||
234 | {"Cougar Point", 2}, | ||
235 | {"Cougar Point", 2}, | ||
165 | {NULL, 0} | 236 | {NULL, 0} |
166 | }; | 237 | }; |
167 | 238 | ||
@@ -230,6 +301,53 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
230 | { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)}, | 301 | { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)}, |
231 | { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)}, | 302 | { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)}, |
232 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, | 303 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, |
304 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, | ||
305 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, | ||
306 | { ITCO_PCI_DEVICE(0x3b02, TCO_P55)}, | ||
307 | { ITCO_PCI_DEVICE(0x3b03, TCO_PM55)}, | ||
308 | { ITCO_PCI_DEVICE(0x3b06, TCO_H55)}, | ||
309 | { ITCO_PCI_DEVICE(0x3b07, TCO_QM57)}, | ||
310 | { ITCO_PCI_DEVICE(0x3b08, TCO_H57)}, | ||
311 | { ITCO_PCI_DEVICE(0x3b09, TCO_HM55)}, | ||
312 | { ITCO_PCI_DEVICE(0x3b0a, TCO_Q57)}, | ||
313 | { ITCO_PCI_DEVICE(0x3b0b, TCO_HM57)}, | ||
314 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, | ||
315 | { ITCO_PCI_DEVICE(0x3b0f, TCO_QS57)}, | ||
316 | { ITCO_PCI_DEVICE(0x3b12, TCO_3400)}, | ||
317 | { ITCO_PCI_DEVICE(0x3b14, TCO_3420)}, | ||
318 | { ITCO_PCI_DEVICE(0x3b16, TCO_3450)}, | ||
319 | { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, | ||
320 | { ITCO_PCI_DEVICE(0x1c41, TCO_CPT1)}, | ||
321 | { ITCO_PCI_DEVICE(0x1c42, TCO_CPT2)}, | ||
322 | { ITCO_PCI_DEVICE(0x1c43, TCO_CPT3)}, | ||
323 | { ITCO_PCI_DEVICE(0x1c44, TCO_CPT4)}, | ||
324 | { ITCO_PCI_DEVICE(0x1c45, TCO_CPT5)}, | ||
325 | { ITCO_PCI_DEVICE(0x1c46, TCO_CPT6)}, | ||
326 | { ITCO_PCI_DEVICE(0x1c47, TCO_CPT7)}, | ||
327 | { ITCO_PCI_DEVICE(0x1c48, TCO_CPT8)}, | ||
328 | { ITCO_PCI_DEVICE(0x1c49, TCO_CPT9)}, | ||
329 | { ITCO_PCI_DEVICE(0x1c4a, TCO_CPT10)}, | ||
330 | { ITCO_PCI_DEVICE(0x1c4b, TCO_CPT11)}, | ||
331 | { ITCO_PCI_DEVICE(0x1c4c, TCO_CPT12)}, | ||
332 | { ITCO_PCI_DEVICE(0x1c4d, TCO_CPT13)}, | ||
333 | { ITCO_PCI_DEVICE(0x1c4e, TCO_CPT14)}, | ||
334 | { ITCO_PCI_DEVICE(0x1c4f, TCO_CPT15)}, | ||
335 | { ITCO_PCI_DEVICE(0x1c50, TCO_CPT16)}, | ||
336 | { ITCO_PCI_DEVICE(0x1c51, TCO_CPT17)}, | ||
337 | { ITCO_PCI_DEVICE(0x1c52, TCO_CPT18)}, | ||
338 | { ITCO_PCI_DEVICE(0x1c53, TCO_CPT19)}, | ||
339 | { ITCO_PCI_DEVICE(0x1c54, TCO_CPT20)}, | ||
340 | { ITCO_PCI_DEVICE(0x1c55, TCO_CPT21)}, | ||
341 | { ITCO_PCI_DEVICE(0x1c56, TCO_CPT22)}, | ||
342 | { ITCO_PCI_DEVICE(0x1c57, TCO_CPT23)}, | ||
343 | { ITCO_PCI_DEVICE(0x1c58, TCO_CPT24)}, | ||
344 | { ITCO_PCI_DEVICE(0x1c59, TCO_CPT25)}, | ||
345 | { ITCO_PCI_DEVICE(0x1c5a, TCO_CPT26)}, | ||
346 | { ITCO_PCI_DEVICE(0x1c5b, TCO_CPT27)}, | ||
347 | { ITCO_PCI_DEVICE(0x1c5c, TCO_CPT28)}, | ||
348 | { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)}, | ||
349 | { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)}, | ||
350 | { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)}, | ||
233 | { 0, }, /* End of list */ | 351 | { 0, }, /* End of list */ |
234 | }; | 352 | }; |
235 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 353 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
@@ -553,7 +671,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, | |||
553 | int new_heartbeat; | 671 | int new_heartbeat; |
554 | void __user *argp = (void __user *)arg; | 672 | void __user *argp = (void __user *)arg; |
555 | int __user *p = argp; | 673 | int __user *p = argp; |
556 | static struct watchdog_info ident = { | 674 | static const struct watchdog_info ident = { |
557 | .options = WDIOF_SETTIMEOUT | | 675 | .options = WDIOF_SETTIMEOUT | |
558 | WDIOF_KEEPALIVEPING | | 676 | WDIOF_KEEPALIVEPING | |
559 | WDIOF_MAGICCLOSE, | 677 | WDIOF_MAGICCLOSE, |
@@ -667,7 +785,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
667 | if (iTCO_wdt_private.iTCO_version == 2) { | 785 | if (iTCO_wdt_private.iTCO_version == 2) { |
668 | pci_read_config_dword(pdev, 0xf0, &base_address); | 786 | pci_read_config_dword(pdev, 0xf0, &base_address); |
669 | if ((base_address & 1) == 0) { | 787 | if ((base_address & 1) == 0) { |
670 | printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); | 788 | printk(KERN_ERR PFX "RCBA is disabled by hardware\n"); |
671 | ret = -ENODEV; | 789 | ret = -ENODEV; |
672 | goto out; | 790 | goto out; |
673 | } | 791 | } |
@@ -677,8 +795,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
677 | 795 | ||
678 | /* Check chipset's NO_REBOOT bit */ | 796 | /* Check chipset's NO_REBOOT bit */ |
679 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { | 797 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { |
680 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " | 798 | printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, " |
681 | "reboot disabled by hardware\n"); | 799 | "platform may have disabled it\n"); |
682 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 800 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
683 | goto out_unmap; | 801 | goto out_unmap; |
684 | } | 802 | } |
@@ -774,6 +892,7 @@ static void __devexit iTCO_wdt_cleanup(void) | |||
774 | 892 | ||
775 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) | 893 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) |
776 | { | 894 | { |
895 | int ret = -ENODEV; | ||
777 | int found = 0; | 896 | int found = 0; |
778 | struct pci_dev *pdev = NULL; | 897 | struct pci_dev *pdev = NULL; |
779 | const struct pci_device_id *ent; | 898 | const struct pci_device_id *ent; |
@@ -783,19 +902,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev) | |||
783 | for_each_pci_dev(pdev) { | 902 | for_each_pci_dev(pdev) { |
784 | ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); | 903 | ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); |
785 | if (ent) { | 904 | if (ent) { |
786 | if (!(iTCO_wdt_init(pdev, ent, dev))) { | 905 | found++; |
787 | found++; | 906 | ret = iTCO_wdt_init(pdev, ent, dev); |
907 | if (!ret) | ||
788 | break; | 908 | break; |
789 | } | ||
790 | } | 909 | } |
791 | } | 910 | } |
792 | 911 | ||
793 | if (!found) { | 912 | if (!found) |
794 | printk(KERN_INFO PFX "No card detected\n"); | 913 | printk(KERN_INFO PFX "No card detected\n"); |
795 | return -ENODEV; | ||
796 | } | ||
797 | 914 | ||
798 | return 0; | 915 | return ret; |
799 | } | 916 | } |
800 | 917 | ||
801 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) | 918 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 4bef3ddff4a5..0149d8dfc81d 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
174 | void __user *argp = (void __user *)arg; | 174 | void __user *argp = (void __user *)arg; |
175 | int __user *p = argp; | 175 | int __user *p = argp; |
176 | 176 | ||
177 | static struct watchdog_info ident = { | 177 | static const struct watchdog_info ident = { |
178 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 178 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
179 | | WDIOF_MAGICCLOSE, | 179 | | WDIOF_MAGICCLOSE, |
180 | .firmware_version = 1, | 180 | .firmware_version = 1, |
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index 89fcefcc8510..195e0f798e76 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | ||
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
18 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index bea8a124a559..1cc5609666d1 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c | |||
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd, | |||
111 | unsigned long arg) | 111 | unsigned long arg) |
112 | { | 112 | { |
113 | int options, retval = -EINVAL; | 113 | int options, retval = -EINVAL; |
114 | static struct watchdog_info ident = { | 114 | static const struct watchdog_info ident = { |
115 | .options = WDIOF_KEEPALIVEPING, | 115 | .options = WDIOF_KEEPALIVEPING, |
116 | .firmware_version = 0, | 116 | .firmware_version = 0, |
117 | .identity = "Hardware Watchdog for SGI IP22", | 117 | .identity = "Hardware Watchdog for SGI IP22", |
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index daed48ded7fe..f52c162b1bea 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c | |||
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, | |||
236 | { | 236 | { |
237 | void __user *argp = (void __user *)arg; | 237 | void __user *argp = (void __user *)arg; |
238 | int __user *p = argp; | 238 | int __user *p = argp; |
239 | static struct watchdog_info ident = { | 239 | static const struct watchdog_info ident = { |
240 | .identity = "IT8712F Watchdog", | 240 | .identity = "IT8712F Watchdog", |
241 | .firmware_version = 1, | 241 | .firmware_version = 1, |
242 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | 242 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index cc133c531d08..b709b3b2d1ef 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c | |||
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
421 | return count; | 421 | return count; |
422 | } | 422 | } |
423 | 423 | ||
424 | static struct watchdog_info ident = { | 424 | static const struct watchdog_info ident = { |
425 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 425 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
426 | .firmware_version = 1, | 426 | .firmware_version = 1, |
427 | .identity = WATCHDOG_NAME, | 427 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index 4f4b35a20d84..e86952a7168c 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/timer.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
24 | #include <linux/miscdevice.h> | 25 | #include <linux/miscdevice.h> |
@@ -99,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data, | |||
99 | } | 100 | } |
100 | 101 | ||
101 | 102 | ||
102 | static struct watchdog_info ident = { | 103 | static const struct watchdog_info ident = { |
103 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 104 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
104 | WDIOF_KEEPALIVEPING, | 105 | WDIOF_KEEPALIVEPING, |
105 | .identity = "IXP2000 Watchdog", | 106 | .identity = "IXP2000 Watchdog", |
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index 147b4d5c63b3..e02c0ecda26b 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c | |||
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
89 | return len; | 89 | return len; |
90 | } | 90 | } |
91 | 91 | ||
92 | static struct watchdog_info ident = { | 92 | static const struct watchdog_info ident = { |
93 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | 93 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | |
94 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 94 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
95 | .identity = "IXP4xx Watchdog", | 95 | .identity = "IXP4xx Watchdog", |
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index e1c82769b08e..2852bb2e3fd9 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode *inode, struct file *file) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static struct watchdog_info ks8695_wdt_info = { | 148 | static const struct watchdog_info ks8695_wdt_info = { |
149 | .identity = "ks8695 watchdog", | 149 | .identity = "ks8695 watchdog", |
150 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 150 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
151 | }; | 151 | }; |
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index b6b3f59ab446..2d118cf022fc 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * wd#1 - 2 seconds; | 21 | * wd#1 - 2 seconds; |
22 | * wd#2 - 7.2 ms; | 22 | * wd#2 - 7.2 ms; |
23 | * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or | 23 | * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or |
24 | * a system RESET and it starts wd#2 that unconditionaly will RESET | 24 | * a system RESET and it starts wd#2 that unconditionally will RESET |
25 | * the system when the counter reaches zero. | 25 | * the system when the counter reaches zero. |
26 | * | 26 | * |
27 | * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> | 27 | * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> |
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout, | |||
101 | 101 | ||
102 | #define PFX "machzwd" | 102 | #define PFX "machzwd" |
103 | 103 | ||
104 | static struct watchdog_info zf_info = { | 104 | static const struct watchdog_info zf_info = { |
105 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 105 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
106 | .firmware_version = 1, | 106 | .firmware_version = 1, |
107 | .identity = "ZF-Logic watchdog", | 107 | .identity = "ZF-Logic watchdog", |
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c new file mode 100644 index 000000000000..3053ff05ca41 --- /dev/null +++ b/drivers/watchdog/max63xx_wdt.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * drivers/char/watchdog/max63xx_wdt.c | ||
3 | * | ||
4 | * Driver for max63{69,70,71,72,73,74} watchdog timers | ||
5 | * | ||
6 | * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | * | ||
12 | * This driver assumes the watchdog pins are memory mapped (as it is | ||
13 | * the case for the Arcom Zeus). Should it be connected over GPIOs or | ||
14 | * another interface, some abstraction will have to be introduced. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/moduleparam.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/fs.h> | ||
22 | #include <linux/miscdevice.h> | ||
23 | #include <linux/watchdog.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/bitops.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | #define DEFAULT_HEARTBEAT 60 | ||
34 | #define MAX_HEARTBEAT 60 | ||
35 | |||
36 | static int heartbeat = DEFAULT_HEARTBEAT; | ||
37 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
38 | |||
39 | /* | ||
40 | * Memory mapping: a single byte, 3 first lower bits to select bit 3 | ||
41 | * to ping the watchdog. | ||
42 | */ | ||
43 | #define MAX6369_WDSET (7 << 0) | ||
44 | #define MAX6369_WDI (1 << 3) | ||
45 | |||
46 | static DEFINE_SPINLOCK(io_lock); | ||
47 | |||
48 | static unsigned long wdt_status; | ||
49 | #define WDT_IN_USE 0 | ||
50 | #define WDT_RUNNING 1 | ||
51 | #define WDT_OK_TO_CLOSE 2 | ||
52 | |||
53 | static int nodelay; | ||
54 | static struct resource *wdt_mem; | ||
55 | static void __iomem *wdt_base; | ||
56 | static struct platform_device *max63xx_pdev; | ||
57 | |||
58 | /* | ||
59 | * The timeout values used are actually the absolute minimum the chip | ||
60 | * offers. Typical values on my board are slightly over twice as long | ||
61 | * (10s setting ends up with a 25s timeout), and can be up to 3 times | ||
62 | * the nominal setting (according to the datasheet). So please take | ||
63 | * these values with a grain of salt. Same goes for the initial delay | ||
64 | * "feature". Only max6373/74 have a few settings without this initial | ||
65 | * delay (selected with the "nodelay" parameter). | ||
66 | * | ||
67 | * I also decided to remove from the tables any timeout smaller than a | ||
68 | * second, as it looked completly overkill... | ||
69 | */ | ||
70 | |||
71 | /* Timeouts in second */ | ||
72 | struct max63xx_timeout { | ||
73 | u8 wdset; | ||
74 | u8 tdelay; | ||
75 | u8 twd; | ||
76 | }; | ||
77 | |||
78 | static struct max63xx_timeout max6369_table[] = { | ||
79 | { 5, 1, 1 }, | ||
80 | { 6, 10, 10 }, | ||
81 | { 7, 60, 60 }, | ||
82 | { }, | ||
83 | }; | ||
84 | |||
85 | static struct max63xx_timeout max6371_table[] = { | ||
86 | { 6, 60, 3 }, | ||
87 | { 7, 60, 60 }, | ||
88 | { }, | ||
89 | }; | ||
90 | |||
91 | static struct max63xx_timeout max6373_table[] = { | ||
92 | { 2, 60, 1 }, | ||
93 | { 5, 0, 1 }, | ||
94 | { 1, 3, 3 }, | ||
95 | { 7, 60, 10 }, | ||
96 | { 6, 0, 10 }, | ||
97 | { }, | ||
98 | }; | ||
99 | |||
100 | static struct max63xx_timeout *current_timeout; | ||
101 | |||
102 | static struct max63xx_timeout * | ||
103 | max63xx_select_timeout(struct max63xx_timeout *table, int value) | ||
104 | { | ||
105 | while (table->twd) { | ||
106 | if (value <= table->twd) { | ||
107 | if (nodelay && table->tdelay == 0) | ||
108 | return table; | ||
109 | |||
110 | if (!nodelay) | ||
111 | return table; | ||
112 | } | ||
113 | |||
114 | table++; | ||
115 | } | ||
116 | |||
117 | return NULL; | ||
118 | } | ||
119 | |||
120 | static void max63xx_wdt_ping(void) | ||
121 | { | ||
122 | u8 val; | ||
123 | |||
124 | spin_lock(&io_lock); | ||
125 | |||
126 | val = __raw_readb(wdt_base); | ||
127 | |||
128 | __raw_writeb(val | MAX6369_WDI, wdt_base); | ||
129 | __raw_writeb(val & ~MAX6369_WDI, wdt_base); | ||
130 | |||
131 | spin_unlock(&io_lock); | ||
132 | } | ||
133 | |||
134 | static void max63xx_wdt_enable(struct max63xx_timeout *entry) | ||
135 | { | ||
136 | u8 val; | ||
137 | |||
138 | if (test_and_set_bit(WDT_RUNNING, &wdt_status)) | ||
139 | return; | ||
140 | |||
141 | spin_lock(&io_lock); | ||
142 | |||
143 | val = __raw_readb(wdt_base); | ||
144 | val &= ~MAX6369_WDSET; | ||
145 | val |= entry->wdset; | ||
146 | __raw_writeb(val, wdt_base); | ||
147 | |||
148 | spin_unlock(&io_lock); | ||
149 | |||
150 | /* check for a edge triggered startup */ | ||
151 | if (entry->tdelay == 0) | ||
152 | max63xx_wdt_ping(); | ||
153 | } | ||
154 | |||
155 | static void max63xx_wdt_disable(void) | ||
156 | { | ||
157 | u8 val; | ||
158 | |||
159 | spin_lock(&io_lock); | ||
160 | |||
161 | val = __raw_readb(wdt_base); | ||
162 | val &= ~MAX6369_WDSET; | ||
163 | val |= 3; | ||
164 | __raw_writeb(val, wdt_base); | ||
165 | |||
166 | spin_unlock(&io_lock); | ||
167 | |||
168 | clear_bit(WDT_RUNNING, &wdt_status); | ||
169 | } | ||
170 | |||
171 | static int max63xx_wdt_open(struct inode *inode, struct file *file) | ||
172 | { | ||
173 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | ||
174 | return -EBUSY; | ||
175 | |||
176 | max63xx_wdt_enable(current_timeout); | ||
177 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
178 | |||
179 | return nonseekable_open(inode, file); | ||
180 | } | ||
181 | |||
182 | static ssize_t max63xx_wdt_write(struct file *file, const char *data, | ||
183 | size_t len, loff_t *ppos) | ||
184 | { | ||
185 | if (len) { | ||
186 | if (!nowayout) { | ||
187 | size_t i; | ||
188 | |||
189 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
190 | for (i = 0; i != len; i++) { | ||
191 | char c; | ||
192 | |||
193 | if (get_user(c, data + i)) | ||
194 | return -EFAULT; | ||
195 | |||
196 | if (c == 'V') | ||
197 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | max63xx_wdt_ping(); | ||
202 | } | ||
203 | |||
204 | return len; | ||
205 | } | ||
206 | |||
207 | static const struct watchdog_info ident = { | ||
208 | .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | ||
209 | .identity = "max63xx Watchdog", | ||
210 | }; | ||
211 | |||
212 | static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd, | ||
213 | unsigned long arg) | ||
214 | { | ||
215 | int ret = -ENOTTY; | ||
216 | |||
217 | switch (cmd) { | ||
218 | case WDIOC_GETSUPPORT: | ||
219 | ret = copy_to_user((struct watchdog_info *)arg, &ident, | ||
220 | sizeof(ident)) ? -EFAULT : 0; | ||
221 | break; | ||
222 | |||
223 | case WDIOC_GETSTATUS: | ||
224 | case WDIOC_GETBOOTSTATUS: | ||
225 | ret = put_user(0, (int *)arg); | ||
226 | break; | ||
227 | |||
228 | case WDIOC_KEEPALIVE: | ||
229 | max63xx_wdt_ping(); | ||
230 | ret = 0; | ||
231 | break; | ||
232 | |||
233 | case WDIOC_GETTIMEOUT: | ||
234 | ret = put_user(heartbeat, (int *)arg); | ||
235 | break; | ||
236 | } | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | static int max63xx_wdt_release(struct inode *inode, struct file *file) | ||
241 | { | ||
242 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | ||
243 | max63xx_wdt_disable(); | ||
244 | else | ||
245 | dev_crit(&max63xx_pdev->dev, | ||
246 | "device closed unexpectedly - timer will not stop\n"); | ||
247 | |||
248 | clear_bit(WDT_IN_USE, &wdt_status); | ||
249 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static const struct file_operations max63xx_wdt_fops = { | ||
255 | .owner = THIS_MODULE, | ||
256 | .llseek = no_llseek, | ||
257 | .write = max63xx_wdt_write, | ||
258 | .unlocked_ioctl = max63xx_wdt_ioctl, | ||
259 | .open = max63xx_wdt_open, | ||
260 | .release = max63xx_wdt_release, | ||
261 | }; | ||
262 | |||
263 | static struct miscdevice max63xx_wdt_miscdev = { | ||
264 | .minor = WATCHDOG_MINOR, | ||
265 | .name = "watchdog", | ||
266 | .fops = &max63xx_wdt_fops, | ||
267 | }; | ||
268 | |||
269 | static int __devinit max63xx_wdt_probe(struct platform_device *pdev) | ||
270 | { | ||
271 | int ret = 0; | ||
272 | int size; | ||
273 | struct resource *res; | ||
274 | struct device *dev = &pdev->dev; | ||
275 | struct max63xx_timeout *table; | ||
276 | |||
277 | table = (struct max63xx_timeout *)pdev->id_entry->driver_data; | ||
278 | |||
279 | if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) | ||
280 | heartbeat = DEFAULT_HEARTBEAT; | ||
281 | |||
282 | dev_info(dev, "requesting %ds heartbeat\n", heartbeat); | ||
283 | current_timeout = max63xx_select_timeout(table, heartbeat); | ||
284 | |||
285 | if (!current_timeout) { | ||
286 | dev_err(dev, "unable to satisfy heartbeat request\n"); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | dev_info(dev, "using %ds heartbeat with %ds initial delay\n", | ||
291 | current_timeout->twd, current_timeout->tdelay); | ||
292 | |||
293 | heartbeat = current_timeout->twd; | ||
294 | |||
295 | max63xx_pdev = pdev; | ||
296 | |||
297 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
298 | if (res == NULL) { | ||
299 | dev_err(dev, "failed to get memory region resource\n"); | ||
300 | return -ENOENT; | ||
301 | } | ||
302 | |||
303 | size = resource_size(res); | ||
304 | wdt_mem = request_mem_region(res->start, size, pdev->name); | ||
305 | |||
306 | if (wdt_mem == NULL) { | ||
307 | dev_err(dev, "failed to get memory region\n"); | ||
308 | return -ENOENT; | ||
309 | } | ||
310 | |||
311 | wdt_base = ioremap(res->start, size); | ||
312 | if (!wdt_base) { | ||
313 | dev_err(dev, "failed to map memory region\n"); | ||
314 | ret = -ENOMEM; | ||
315 | goto out_request; | ||
316 | } | ||
317 | |||
318 | ret = misc_register(&max63xx_wdt_miscdev); | ||
319 | if (ret < 0) { | ||
320 | dev_err(dev, "cannot register misc device\n"); | ||
321 | goto out_unmap; | ||
322 | } | ||
323 | |||
324 | return 0; | ||
325 | |||
326 | out_unmap: | ||
327 | iounmap(wdt_base); | ||
328 | out_request: | ||
329 | release_resource(wdt_mem); | ||
330 | kfree(wdt_mem); | ||
331 | |||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static int __devexit max63xx_wdt_remove(struct platform_device *pdev) | ||
336 | { | ||
337 | misc_deregister(&max63xx_wdt_miscdev); | ||
338 | if (wdt_mem) { | ||
339 | release_resource(wdt_mem); | ||
340 | kfree(wdt_mem); | ||
341 | wdt_mem = NULL; | ||
342 | } | ||
343 | |||
344 | if (wdt_base) | ||
345 | iounmap(wdt_base); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static struct platform_device_id max63xx_id_table[] = { | ||
351 | { "max6369_wdt", (kernel_ulong_t)max6369_table, }, | ||
352 | { "max6370_wdt", (kernel_ulong_t)max6369_table, }, | ||
353 | { "max6371_wdt", (kernel_ulong_t)max6371_table, }, | ||
354 | { "max6372_wdt", (kernel_ulong_t)max6371_table, }, | ||
355 | { "max6373_wdt", (kernel_ulong_t)max6373_table, }, | ||
356 | { "max6374_wdt", (kernel_ulong_t)max6373_table, }, | ||
357 | { }, | ||
358 | }; | ||
359 | MODULE_DEVICE_TABLE(platform, max63xx_id_table); | ||
360 | |||
361 | static struct platform_driver max63xx_wdt_driver = { | ||
362 | .probe = max63xx_wdt_probe, | ||
363 | .remove = __devexit_p(max63xx_wdt_remove), | ||
364 | .id_table = max63xx_id_table, | ||
365 | .driver = { | ||
366 | .name = "max63xx_wdt", | ||
367 | .owner = THIS_MODULE, | ||
368 | }, | ||
369 | }; | ||
370 | |||
371 | static int __init max63xx_wdt_init(void) | ||
372 | { | ||
373 | return platform_driver_register(&max63xx_wdt_driver); | ||
374 | } | ||
375 | |||
376 | static void __exit max63xx_wdt_exit(void) | ||
377 | { | ||
378 | platform_driver_unregister(&max63xx_wdt_driver); | ||
379 | } | ||
380 | |||
381 | module_init(max63xx_wdt_init); | ||
382 | module_exit(max63xx_wdt_exit); | ||
383 | |||
384 | MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>"); | ||
385 | MODULE_DESCRIPTION("max63xx Watchdog Driver"); | ||
386 | |||
387 | module_param(heartbeat, int, 0); | ||
388 | MODULE_PARM_DESC(heartbeat, | ||
389 | "Watchdog heartbeat period in seconds from 1 to " | ||
390 | __MODULE_STRING(MAX_HEARTBEAT) ", default " | ||
391 | __MODULE_STRING(DEFAULT_HEARTBEAT)); | ||
392 | |||
393 | module_param(nowayout, int, 0); | ||
394 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
395 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
396 | |||
397 | module_param(nodelay, int, 0); | ||
398 | MODULE_PARM_DESC(nodelay, | ||
399 | "Force selection of a timeout setting without initial delay " | ||
400 | "(max6373/74 only, default=0)"); | ||
401 | |||
402 | MODULE_LICENSE("GPL"); | ||
403 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 407b025cb104..bc820d16699a 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c | |||
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *file, | |||
201 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
202 | int __user *p = argp; | 202 | int __user *p = argp; |
203 | int status; | 203 | int status; |
204 | static struct watchdog_info ident = { | 204 | static const struct watchdog_info ident = { |
205 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 205 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
206 | .firmware_version = 1, | 206 | .firmware_version = 1, |
207 | .identity = "MixCOM watchdog", | 207 | .identity = "MixCOM watchdog", |
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/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 38c588ee694f..4e3941c5e293 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c | |||
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd, | |||
148 | { | 148 | { |
149 | void __user *argp = (void __user *)arg; | 149 | void __user *argp = (void __user *)arg; |
150 | int __user *p = argp; | 150 | int __user *p = argp; |
151 | static struct watchdog_info ident = { | 151 | static const struct watchdog_info ident = { |
152 | .options = WDIOF_KEEPALIVEPING, | 152 | .options = WDIOF_KEEPALIVEPING, |
153 | .firmware_version = 1, | 153 | .firmware_version = 1, |
154 | .identity = "MPC8xxx", | 154 | .identity = "MPC8xxx", |
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 83fa34b214b4..b8ec7aca3c8e 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
@@ -30,8 +30,10 @@ | |||
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <linux/slab.h> | ||
34 | #include <linux/io.h> | ||
33 | 35 | ||
34 | #include <asm/hardware/arm_twd.h> | 36 | #include <asm/smp_twd.h> |
35 | 37 | ||
36 | struct mpcore_wdt { | 38 | struct mpcore_wdt { |
37 | unsigned long timer_alive; | 39 | unsigned long timer_alive; |
@@ -43,7 +45,7 @@ struct mpcore_wdt { | |||
43 | }; | 45 | }; |
44 | 46 | ||
45 | static struct platform_device *mpcore_wdt_dev; | 47 | static struct platform_device *mpcore_wdt_dev; |
46 | extern unsigned int mpcore_timer_rate; | 48 | static DEFINE_SPINLOCK(wdt_lock); |
47 | 49 | ||
48 | #define TIMER_MARGIN 60 | 50 | #define TIMER_MARGIN 60 |
49 | static int mpcore_margin = TIMER_MARGIN; | 51 | static int mpcore_margin = TIMER_MARGIN; |
@@ -93,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) | |||
93 | */ | 95 | */ |
94 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) | 96 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) |
95 | { | 97 | { |
96 | unsigned int count; | 98 | unsigned long count; |
97 | 99 | ||
100 | spin_lock(&wdt_lock); | ||
98 | /* Assume prescale is set to 256 */ | 101 | /* Assume prescale is set to 256 */ |
99 | count = (mpcore_timer_rate / 256) * mpcore_margin; | 102 | count = __raw_readl(wdt->base + TWD_WDOG_COUNTER); |
103 | count = (0xFFFFFFFFU - count) * (HZ / 5); | ||
104 | count = (count / 256) * mpcore_margin; | ||
100 | 105 | ||
101 | /* Reload the counter */ | 106 | /* Reload the counter */ |
102 | spin_lock(&wdt_lock); | ||
103 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); | 107 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); |
104 | wdt->perturb = wdt->perturb ? 0 : 1; | 108 | wdt->perturb = wdt->perturb ? 0 : 1; |
105 | spin_unlock(&wdt_lock); | 109 | spin_unlock(&wdt_lock); |
@@ -118,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
118 | { | 122 | { |
119 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); | 123 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); |
120 | 124 | ||
121 | spin_lock(&wdt_lock); | ||
122 | /* This loads the count register but does NOT start the count yet */ | 125 | /* This loads the count register but does NOT start the count yet */ |
123 | mpcore_wdt_keepalive(wdt); | 126 | mpcore_wdt_keepalive(wdt); |
124 | 127 | ||
@@ -129,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
129 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ | 132 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ |
130 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); | 133 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); |
131 | } | 134 | } |
132 | spin_unlock(&wdt_lock); | ||
133 | } | 135 | } |
134 | 136 | ||
135 | static int mpcore_wdt_set_heartbeat(int t) | 137 | static int mpcore_wdt_set_heartbeat(int t) |
@@ -213,7 +215,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data, | |||
213 | return len; | 215 | return len; |
214 | } | 216 | } |
215 | 217 | ||
216 | static struct watchdog_info ident = { | 218 | static const struct watchdog_info ident = { |
217 | .options = WDIOF_SETTIMEOUT | | 219 | .options = WDIOF_SETTIMEOUT | |
218 | WDIOF_KEEPALIVEPING | | 220 | WDIOF_KEEPALIVEPING | |
219 | WDIOF_MAGICCLOSE, | 221 | WDIOF_MAGICCLOSE, |
@@ -350,7 +352,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
350 | ret = -ENXIO; | 352 | ret = -ENXIO; |
351 | goto err_free; | 353 | goto err_free; |
352 | } | 354 | } |
353 | wdt->base = ioremap(res->start, res->end - res->start + 1); | 355 | wdt->base = ioremap(res->start, resource_size(res)); |
354 | if (!wdt->base) { | 356 | if (!wdt->base) { |
355 | ret = -ENOMEM; | 357 | ret = -ENOMEM; |
356 | goto err_free; | 358 | goto err_free; |
@@ -359,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
359 | mpcore_wdt_miscdev.parent = &dev->dev; | 361 | mpcore_wdt_miscdev.parent = &dev->dev; |
360 | ret = misc_register(&mpcore_wdt_miscdev); | 362 | ret = misc_register(&mpcore_wdt_miscdev); |
361 | if (ret) { | 363 | if (ret) { |
362 | dev_printk(KERN_ERR, _dev, | 364 | dev_printk(KERN_ERR, wdt->dev, |
363 | "cannot register miscdev on minor=%d (err=%d)\n", | 365 | "cannot register miscdev on minor=%d (err=%d)\n", |
364 | WATCHDOG_MINOR, ret); | 366 | WATCHDOG_MINOR, ret); |
365 | goto err_misc; | 367 | goto err_misc; |
@@ -368,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
368 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, | 370 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, |
369 | "mpcore_wdt", wdt); | 371 | "mpcore_wdt", wdt); |
370 | if (ret) { | 372 | if (ret) { |
371 | dev_printk(KERN_ERR, _dev, | 373 | dev_printk(KERN_ERR, wdt->dev, |
372 | "cannot register IRQ%d for watchdog\n", wdt->irq); | 374 | "cannot register IRQ%d for watchdog\n", wdt->irq); |
373 | goto err_irq; | 375 | goto err_irq; |
374 | } | 376 | } |
375 | 377 | ||
376 | mpcore_wdt_stop(wdt); | 378 | mpcore_wdt_stop(wdt); |
377 | platform_set_drvdata(&dev->dev, wdt); | 379 | platform_set_drvdata(dev, wdt); |
378 | mpcore_wdt_dev = dev; | 380 | mpcore_wdt_dev = dev; |
379 | 381 | ||
380 | return 0; | 382 | return 0; |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index acf589dc057c..97f8a48d8b78 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct file *file, | |||
179 | int timeout; | 179 | int timeout; |
180 | int options; | 180 | int options; |
181 | void __user *argp = (void __user *)arg; | 181 | void __user *argp = (void __user *)arg; |
182 | static struct watchdog_info info = { | 182 | static const struct watchdog_info info = { |
183 | .options = WDIOF_SETTIMEOUT | | 183 | .options = WDIOF_SETTIMEOUT | |
184 | WDIOF_MAGICCLOSE | | 184 | WDIOF_MAGICCLOSE | |
185 | WDIOF_KEEPALIVEPING, | 185 | WDIOF_KEEPALIVEPING, |
@@ -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/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c index adefe3a9d510..6cee33d4b161 100644 --- a/drivers/watchdog/nuc900_wdt.c +++ b/drivers/watchdog/nuc900_wdt.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
25 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 3ed571a2ab18..76b58abf4451 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -42,8 +42,9 @@ | |||
42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
43 | #include <linux/io.h> | 43 | #include <linux/io.h> |
44 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
45 | #include <linux/slab.h> | ||
45 | #include <mach/hardware.h> | 46 | #include <mach/hardware.h> |
46 | #include <mach/prcm.h> | 47 | #include <plat/prcm.h> |
47 | 48 | ||
48 | #include "omap_wdt.h" | 49 | #include "omap_wdt.h" |
49 | 50 | ||
@@ -277,8 +278,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
277 | goto err_busy; | 278 | goto err_busy; |
278 | } | 279 | } |
279 | 280 | ||
280 | mem = request_mem_region(res->start, res->end - res->start + 1, | 281 | mem = request_mem_region(res->start, resource_size(res), pdev->name); |
281 | pdev->name); | ||
282 | if (!mem) { | 282 | if (!mem) { |
283 | ret = -EBUSY; | 283 | ret = -EBUSY; |
284 | goto err_busy; | 284 | goto err_busy; |
@@ -306,7 +306,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
306 | goto err_clk; | 306 | goto err_clk; |
307 | } | 307 | } |
308 | 308 | ||
309 | wdev->base = ioremap(res->start, res->end - res->start + 1); | 309 | wdev->base = ioremap(res->start, resource_size(res)); |
310 | if (!wdev->base) { | 310 | if (!wdev->base) { |
311 | ret = -ENOMEM; | 311 | ret = -ENOMEM; |
312 | goto err_ioremap; | 312 | goto err_ioremap; |
@@ -358,7 +358,7 @@ err_clk: | |||
358 | kfree(wdev); | 358 | kfree(wdev); |
359 | 359 | ||
360 | err_kzalloc: | 360 | err_kzalloc: |
361 | release_mem_region(res->start, res->end - res->start + 1); | 361 | release_mem_region(res->start, resource_size(res)); |
362 | 362 | ||
363 | err_busy: | 363 | err_busy: |
364 | err_get_resource: | 364 | err_get_resource: |
@@ -383,7 +383,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) | |||
383 | return -ENOENT; | 383 | return -ENOENT; |
384 | 384 | ||
385 | misc_deregister(&(wdev->omap_wdt_miscdev)); | 385 | misc_deregister(&(wdev->omap_wdt_miscdev)); |
386 | release_mem_region(res->start, res->end - res->start + 1); | 386 | release_mem_region(res->start, resource_size(res)); |
387 | platform_set_drvdata(pdev, NULL); | 387 | platform_set_drvdata(pdev, NULL); |
388 | 388 | ||
389 | clk_put(wdev->ick); | 389 | clk_put(wdev->ick); |
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 1a2b916e3f8d..d3aa2f1fe61d 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c | |||
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd, | |||
407 | int __user *i; | 407 | int __user *i; |
408 | } uarg; | 408 | } uarg; |
409 | 409 | ||
410 | static struct watchdog_info ident = { | 410 | static const struct watchdog_info ident = { |
411 | .options = WDIOF_KEEPALIVEPING | | 411 | .options = WDIOF_KEEPALIVEPING | |
412 | WDIOF_SETTIMEOUT | | 412 | WDIOF_SETTIMEOUT | |
413 | WDIOF_MAGICCLOSE, | 413 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index aa9512321f3a..06f7922606c0 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c | |||
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
606 | int temperature; | 606 | int temperature; |
607 | int new_heartbeat; | 607 | int new_heartbeat; |
608 | int __user *argp = (int __user *)arg; | 608 | int __user *argp = (int __user *)arg; |
609 | static struct watchdog_info ident = { | 609 | static const struct watchdog_info ident = { |
610 | .options = WDIOF_OVERHEAT | | 610 | .options = WDIOF_OVERHEAT | |
611 | WDIOF_CARDRESET | | 611 | WDIOF_CARDRESET | |
612 | WDIOF_KEEPALIVEPING | | 612 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index 698f51bff1bc..64374d636f09 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c | |||
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd, | |||
481 | { | 481 | { |
482 | void __user *argp = (void __user *)arg; | 482 | void __user *argp = (void __user *)arg; |
483 | int __user *p = argp; | 483 | int __user *p = argp; |
484 | static struct watchdog_info ident = { | 484 | static const struct watchdog_info ident = { |
485 | .options = WDIOF_OVERHEAT | | 485 | .options = WDIOF_OVERHEAT | |
486 | WDIOF_CARDRESET | | 486 | WDIOF_CARDRESET | |
487 | WDIOF_KEEPALIVEPING | | 487 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 052fe451851f..8e4eacc5bb52 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd, | |||
404 | { | 404 | { |
405 | void __user *argp = (void __user *)arg; | 405 | void __user *argp = (void __user *)arg; |
406 | int __user *p = argp; | 406 | int __user *p = argp; |
407 | static struct watchdog_info ident = { | 407 | static const struct watchdog_info ident = { |
408 | .options = WDIOF_KEEPALIVEPING | | 408 | .options = WDIOF_KEEPALIVEPING | |
409 | WDIOF_SETTIMEOUT | | 409 | WDIOF_SETTIMEOUT | |
410 | WDIOF_MAGICCLOSE, | 410 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 4d227b152001..bf5b97c546eb 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/slab.h> | ||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
34 | 35 | ||
35 | #define MODULE_NAME "PNX4008-WDT: " | 36 | #define MODULE_NAME "PNX4008-WDT: " |
@@ -96,9 +97,6 @@ static void wdt_enable(void) | |||
96 | { | 97 | { |
97 | spin_lock(&io_lock); | 98 | spin_lock(&io_lock); |
98 | 99 | ||
99 | if (wdt_clk) | ||
100 | clk_set_rate(wdt_clk, 1); | ||
101 | |||
102 | /* stop counter, initiate counter reset */ | 100 | /* stop counter, initiate counter reset */ |
103 | __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); | 101 | __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); |
104 | /*wait for reset to complete. 100% guarantee event */ | 102 | /*wait for reset to complete. 100% guarantee event */ |
@@ -125,19 +123,25 @@ static void wdt_disable(void) | |||
125 | spin_lock(&io_lock); | 123 | spin_lock(&io_lock); |
126 | 124 | ||
127 | __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ | 125 | __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ |
128 | if (wdt_clk) | ||
129 | clk_set_rate(wdt_clk, 0); | ||
130 | 126 | ||
131 | spin_unlock(&io_lock); | 127 | spin_unlock(&io_lock); |
132 | } | 128 | } |
133 | 129 | ||
134 | static int pnx4008_wdt_open(struct inode *inode, struct file *file) | 130 | static int pnx4008_wdt_open(struct inode *inode, struct file *file) |
135 | { | 131 | { |
132 | int ret; | ||
133 | |||
136 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 134 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
137 | return -EBUSY; | 135 | return -EBUSY; |
138 | 136 | ||
139 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 137 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
140 | 138 | ||
139 | ret = clk_enable(wdt_clk); | ||
140 | if (ret) { | ||
141 | clear_bit(WDT_IN_USE, &wdt_status); | ||
142 | return ret; | ||
143 | } | ||
144 | |||
141 | wdt_enable(); | 145 | wdt_enable(); |
142 | 146 | ||
143 | return nonseekable_open(inode, file); | 147 | return nonseekable_open(inode, file); |
@@ -225,6 +229,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file) | |||
225 | printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); | 229 | printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); |
226 | 230 | ||
227 | wdt_disable(); | 231 | wdt_disable(); |
232 | clk_disable(wdt_clk); | ||
228 | clear_bit(WDT_IN_USE, &wdt_status); | 233 | clear_bit(WDT_IN_USE, &wdt_status); |
229 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 234 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
230 | 235 | ||
@@ -264,7 +269,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) | |||
264 | return -ENOENT; | 269 | return -ENOENT; |
265 | } | 270 | } |
266 | 271 | ||
267 | size = res->end - res->start + 1; | 272 | size = resource_size(res); |
268 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 273 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
269 | 274 | ||
270 | if (wdt_mem == NULL) { | 275 | if (wdt_mem == NULL) { |
@@ -273,25 +278,33 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) | |||
273 | } | 278 | } |
274 | wdt_base = (void __iomem *)IO_ADDRESS(res->start); | 279 | wdt_base = (void __iomem *)IO_ADDRESS(res->start); |
275 | 280 | ||
276 | wdt_clk = clk_get(&pdev->dev, "wdt_ck"); | 281 | wdt_clk = clk_get(&pdev->dev, NULL); |
277 | if (IS_ERR(wdt_clk)) { | 282 | if (IS_ERR(wdt_clk)) { |
278 | ret = PTR_ERR(wdt_clk); | 283 | ret = PTR_ERR(wdt_clk); |
279 | release_resource(wdt_mem); | 284 | release_resource(wdt_mem); |
280 | kfree(wdt_mem); | 285 | kfree(wdt_mem); |
281 | goto out; | 286 | goto out; |
282 | } else | 287 | } |
283 | clk_set_rate(wdt_clk, 1); | 288 | |
289 | ret = clk_enable(wdt_clk); | ||
290 | if (ret) { | ||
291 | release_resource(wdt_mem); | ||
292 | kfree(wdt_mem); | ||
293 | goto out; | ||
294 | } | ||
284 | 295 | ||
285 | ret = misc_register(&pnx4008_wdt_miscdev); | 296 | ret = misc_register(&pnx4008_wdt_miscdev); |
286 | if (ret < 0) { | 297 | if (ret < 0) { |
287 | printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); | 298 | printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); |
288 | release_resource(wdt_mem); | 299 | release_resource(wdt_mem); |
289 | kfree(wdt_mem); | 300 | kfree(wdt_mem); |
290 | clk_set_rate(wdt_clk, 0); | 301 | clk_disable(wdt_clk); |
302 | clk_put(wdt_clk); | ||
291 | } else { | 303 | } else { |
292 | boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? | 304 | boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? |
293 | WDIOF_CARDRESET : 0; | 305 | WDIOF_CARDRESET : 0; |
294 | wdt_disable(); /*disable for now */ | 306 | wdt_disable(); /*disable for now */ |
307 | clk_disable(wdt_clk); | ||
295 | set_bit(WDT_DEVICE_INITED, &wdt_status); | 308 | set_bit(WDT_DEVICE_INITED, &wdt_status); |
296 | } | 309 | } |
297 | 310 | ||
@@ -302,11 +315,10 @@ out: | |||
302 | static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) | 315 | static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) |
303 | { | 316 | { |
304 | misc_deregister(&pnx4008_wdt_miscdev); | 317 | misc_deregister(&pnx4008_wdt_miscdev); |
305 | if (wdt_clk) { | 318 | |
306 | clk_set_rate(wdt_clk, 0); | 319 | clk_disable(wdt_clk); |
307 | clk_put(wdt_clk); | 320 | clk_put(wdt_clk); |
308 | wdt_clk = NULL; | 321 | |
309 | } | ||
310 | if (wdt_mem) { | 322 | if (wdt_mem) { |
311 | release_resource(wdt_mem); | 323 | release_resource(wdt_mem); |
312 | kfree(wdt_mem); | 324 | kfree(wdt_mem); |
diff --git a/drivers/watchdog/pnx833x_wdt.c b/drivers/watchdog/pnx833x_wdt.c index 538ec2c05197..09102f09e681 100644 --- a/drivers/watchdog/pnx833x_wdt.c +++ b/drivers/watchdog/pnx833x_wdt.c | |||
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
141 | int options, new_timeout = 0; | 141 | int options, new_timeout = 0; |
142 | uint32_t timeout, timeout_left = 0; | 142 | uint32_t timeout, timeout_left = 0; |
143 | 143 | ||
144 | static struct watchdog_info ident = { | 144 | static const struct watchdog_info ident = { |
145 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, | 145 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, |
146 | .firmware_version = 0, | 146 | .firmware_version = 0, |
147 | .identity = "Hardware Watchdog for PNX833x", | 147 | .identity = "Hardware Watchdog for PNX833x", |
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index bf12d06b5877..d4c29b5311a4 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c | |||
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, | |||
198 | void __user *argp = (void __user *)arg; | 198 | void __user *argp = (void __user *)arg; |
199 | int new_timeout; | 199 | int new_timeout; |
200 | unsigned int value; | 200 | unsigned int value; |
201 | static struct watchdog_info ident = { | 201 | static const struct watchdog_info ident = { |
202 | .options = WDIOF_SETTIMEOUT | | 202 | .options = WDIOF_SETTIMEOUT | |
203 | WDIOF_KEEPALIVEPING | | 203 | WDIOF_KEEPALIVEPING | |
204 | WDIOF_MAGICCLOSE, | 204 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 4976bfd1fce6..69c6adbd8205 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c | |||
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
149 | { | 149 | { |
150 | void __user *argp = (void __user *)arg; | 150 | void __user *argp = (void __user *)arg; |
151 | unsigned int value; | 151 | unsigned int value; |
152 | static struct watchdog_info ident = { | 152 | static const struct watchdog_info ident = { |
153 | .options = WDIOF_CARDRESET, | 153 | .options = WDIOF_CARDRESET, |
154 | .identity = "RDC321x WDT", | 154 | .identity = "RDC321x WDT", |
155 | }; | 155 | }; |
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index d3c824dc2358..ea7f803f6248 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c | |||
@@ -10,12 +10,12 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/watchdog.h> | 13 | #include <linux/watchdog.h> |
15 | #include <linux/of.h> | 14 | #include <linux/of.h> |
16 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
17 | #include <linux/io.h> | 16 | #include <linux/io.h> |
18 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
18 | #include <linux/slab.h> | ||
19 | 19 | ||
20 | 20 | ||
21 | /* RIO uses the NatSemi Super I/O power management logical device | 21 | /* RIO uses the NatSemi Super I/O power management logical device |
@@ -75,7 +75,6 @@ static void riowd_writereg(struct riowd *p, u8 val, int index) | |||
75 | 75 | ||
76 | static int riowd_open(struct inode *inode, struct file *filp) | 76 | static int riowd_open(struct inode *inode, struct file *filp) |
77 | { | 77 | { |
78 | cycle_kernel_lock(); | ||
79 | nonseekable_open(inode, filp); | 78 | nonseekable_open(inode, filp); |
80 | return 0; | 79 | return 0; |
81 | } | 80 | } |
@@ -87,7 +86,7 @@ static int riowd_release(struct inode *inode, struct file *filp) | |||
87 | 86 | ||
88 | static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 87 | static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
89 | { | 88 | { |
90 | static struct watchdog_info info = { | 89 | static const struct watchdog_info info = { |
91 | .options = WDIOF_SETTIMEOUT, | 90 | .options = WDIOF_SETTIMEOUT, |
92 | .firmware_version = 1, | 91 | .firmware_version = 1, |
93 | .identity = DRIVER_NAME, | 92 | .identity = DRIVER_NAME, |
@@ -194,6 +193,8 @@ static int __devinit riowd_probe(struct of_device *op, | |||
194 | printk(KERN_ERR PFX "Cannot map registers.\n"); | 193 | printk(KERN_ERR PFX "Cannot map registers.\n"); |
195 | goto out_free; | 194 | goto out_free; |
196 | } | 195 | } |
196 | /* Make miscdev useable right away */ | ||
197 | riowd_device = p; | ||
197 | 198 | ||
198 | err = misc_register(&riowd_miscdev); | 199 | err = misc_register(&riowd_miscdev); |
199 | if (err) { | 200 | if (err) { |
@@ -205,10 +206,10 @@ static int __devinit riowd_probe(struct of_device *op, | |||
205 | "regs at %p\n", riowd_timeout, p->regs); | 206 | "regs at %p\n", riowd_timeout, p->regs); |
206 | 207 | ||
207 | dev_set_drvdata(&op->dev, p); | 208 | dev_set_drvdata(&op->dev, p); |
208 | riowd_device = p; | ||
209 | return 0; | 209 | return 0; |
210 | 210 | ||
211 | out_iounmap: | 211 | out_iounmap: |
212 | riowd_device = NULL; | ||
212 | of_iounmap(&op->resource[0], p->regs, 2); | 213 | of_iounmap(&op->resource[0], p->regs, 2); |
213 | 214 | ||
214 | out_free: | 215 | out_free: |
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 b57ac6b49147..e4cebef55177 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <linux/clk.h> | 36 | #include <linux/clk.h> |
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <linux/io.h> | 38 | #include <linux/io.h> |
39 | #include <linux/cpufreq.h> | ||
40 | #include <linux/slab.h> | ||
39 | 41 | ||
40 | #include <mach/map.h> | 42 | #include <mach/map.h> |
41 | 43 | ||
@@ -142,9 +144,14 @@ static void s3c2410wdt_start(void) | |||
142 | spin_unlock(&wdt_lock); | 144 | spin_unlock(&wdt_lock); |
143 | } | 145 | } |
144 | 146 | ||
147 | static inline int s3c2410wdt_is_running(void) | ||
148 | { | ||
149 | return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE; | ||
150 | } | ||
151 | |||
145 | static int s3c2410wdt_set_heartbeat(int timeout) | 152 | static int s3c2410wdt_set_heartbeat(int timeout) |
146 | { | 153 | { |
147 | unsigned int freq = clk_get_rate(wdt_clock); | 154 | unsigned long freq = clk_get_rate(wdt_clock); |
148 | unsigned int count; | 155 | unsigned int count; |
149 | unsigned int divisor = 1; | 156 | unsigned int divisor = 1; |
150 | unsigned long wtcon; | 157 | unsigned long wtcon; |
@@ -155,7 +162,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) | |||
155 | freq /= 128; | 162 | freq /= 128; |
156 | count = timeout * freq; | 163 | count = timeout * freq; |
157 | 164 | ||
158 | DBG("%s: count=%d, timeout=%d, freq=%d\n", | 165 | DBG("%s: count=%d, timeout=%d, freq=%lu\n", |
159 | __func__, count, timeout, freq); | 166 | __func__, count, timeout, freq); |
160 | 167 | ||
161 | /* if the count is bigger than the watchdog register, | 168 | /* if the count is bigger than the watchdog register, |
@@ -324,6 +331,73 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) | |||
324 | s3c2410wdt_keepalive(); | 331 | s3c2410wdt_keepalive(); |
325 | return IRQ_HANDLED; | 332 | return IRQ_HANDLED; |
326 | } | 333 | } |
334 | |||
335 | |||
336 | #ifdef CONFIG_CPU_FREQ | ||
337 | |||
338 | static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, | ||
339 | unsigned long val, void *data) | ||
340 | { | ||
341 | int ret; | ||
342 | |||
343 | if (!s3c2410wdt_is_running()) | ||
344 | goto done; | ||
345 | |||
346 | if (val == CPUFREQ_PRECHANGE) { | ||
347 | /* To ensure that over the change we don't cause the | ||
348 | * watchdog to trigger, we perform an keep-alive if | ||
349 | * the watchdog is running. | ||
350 | */ | ||
351 | |||
352 | s3c2410wdt_keepalive(); | ||
353 | } else if (val == CPUFREQ_POSTCHANGE) { | ||
354 | s3c2410wdt_stop(); | ||
355 | |||
356 | ret = s3c2410wdt_set_heartbeat(tmr_margin); | ||
357 | |||
358 | if (ret >= 0) | ||
359 | s3c2410wdt_start(); | ||
360 | else | ||
361 | goto err; | ||
362 | } | ||
363 | |||
364 | done: | ||
365 | return 0; | ||
366 | |||
367 | err: | ||
368 | dev_err(wdt_dev, "cannot set new value for timeout %d\n", tmr_margin); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static struct notifier_block s3c2410wdt_cpufreq_transition_nb = { | ||
373 | .notifier_call = s3c2410wdt_cpufreq_transition, | ||
374 | }; | ||
375 | |||
376 | static inline int s3c2410wdt_cpufreq_register(void) | ||
377 | { | ||
378 | return cpufreq_register_notifier(&s3c2410wdt_cpufreq_transition_nb, | ||
379 | CPUFREQ_TRANSITION_NOTIFIER); | ||
380 | } | ||
381 | |||
382 | static inline void s3c2410wdt_cpufreq_deregister(void) | ||
383 | { | ||
384 | cpufreq_unregister_notifier(&s3c2410wdt_cpufreq_transition_nb, | ||
385 | CPUFREQ_TRANSITION_NOTIFIER); | ||
386 | } | ||
387 | |||
388 | #else | ||
389 | static inline int s3c2410wdt_cpufreq_register(void) | ||
390 | { | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static inline void s3c2410wdt_cpufreq_deregister(void) | ||
395 | { | ||
396 | } | ||
397 | #endif | ||
398 | |||
399 | |||
400 | |||
327 | /* device interface */ | 401 | /* device interface */ |
328 | 402 | ||
329 | static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | 403 | static int __devinit s3c2410wdt_probe(struct platform_device *pdev) |
@@ -348,7 +422,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
348 | return -ENOENT; | 422 | return -ENOENT; |
349 | } | 423 | } |
350 | 424 | ||
351 | size = (res->end - res->start) + 1; | 425 | size = resource_size(res); |
352 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 426 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
353 | if (wdt_mem == NULL) { | 427 | if (wdt_mem == NULL) { |
354 | dev_err(dev, "failed to get memory region\n"); | 428 | dev_err(dev, "failed to get memory region\n"); |
@@ -387,6 +461,11 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
387 | 461 | ||
388 | clk_enable(wdt_clock); | 462 | clk_enable(wdt_clock); |
389 | 463 | ||
464 | if (s3c2410wdt_cpufreq_register() < 0) { | ||
465 | printk(KERN_ERR PFX "failed to register cpufreq\n"); | ||
466 | goto err_clk; | ||
467 | } | ||
468 | |||
390 | /* see if we can actually set the requested timer margin, and if | 469 | /* see if we can actually set the requested timer margin, and if |
391 | * not, try the default value */ | 470 | * not, try the default value */ |
392 | 471 | ||
@@ -407,7 +486,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
407 | if (ret) { | 486 | if (ret) { |
408 | dev_err(dev, "cannot register miscdev on minor=%d (%d)\n", | 487 | dev_err(dev, "cannot register miscdev on minor=%d (%d)\n", |
409 | WATCHDOG_MINOR, ret); | 488 | WATCHDOG_MINOR, ret); |
410 | goto err_clk; | 489 | goto err_cpufreq; |
411 | } | 490 | } |
412 | 491 | ||
413 | if (tmr_atboot && started == 0) { | 492 | if (tmr_atboot && started == 0) { |
@@ -432,6 +511,9 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
432 | 511 | ||
433 | return 0; | 512 | return 0; |
434 | 513 | ||
514 | err_cpufreq: | ||
515 | s3c2410wdt_cpufreq_deregister(); | ||
516 | |||
435 | err_clk: | 517 | err_clk: |
436 | clk_disable(wdt_clock); | 518 | clk_disable(wdt_clock); |
437 | clk_put(wdt_clock); | 519 | clk_put(wdt_clock); |
@@ -451,6 +533,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
451 | 533 | ||
452 | static int __devexit s3c2410wdt_remove(struct platform_device *dev) | 534 | static int __devexit s3c2410wdt_remove(struct platform_device *dev) |
453 | { | 535 | { |
536 | s3c2410wdt_cpufreq_deregister(); | ||
537 | |||
454 | release_resource(wdt_mem); | 538 | release_resource(wdt_mem); |
455 | kfree(wdt_mem); | 539 | kfree(wdt_mem); |
456 | wdt_mem = NULL; | 540 | wdt_mem = NULL; |
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c index 9748eed73196..88c83aa57303 100644 --- a/drivers/watchdog/sb_wdog.c +++ b/drivers/watchdog/sb_wdog.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Watchdog driver for SiByte SB1 SoCs | 2 | * Watchdog driver for SiByte SB1 SoCs |
3 | * | 3 | * |
4 | * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@onstor.com> | 4 | * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@lsi.com> |
5 | * | 5 | * |
6 | * This driver is intended to make the second of two hardware watchdogs | 6 | * This driver is intended to make the second of two hardware watchdogs |
7 | * on the Sibyte 12XX and 11XX SoCs available to the user. There are two | 7 | * on the Sibyte 12XX and 11XX SoCs available to the user. There are two |
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock); | |||
67 | void sbwdog_set(char __iomem *wdog, unsigned long t) | 67 | void sbwdog_set(char __iomem *wdog, unsigned long t) |
68 | { | 68 | { |
69 | spin_lock(&sbwd_lock); | 69 | spin_lock(&sbwd_lock); |
70 | __raw_writeb(0, wdog - 0x10); | 70 | __raw_writeb(0, wdog); |
71 | __raw_writeq(t & 0x7fffffUL, wdog); | 71 | __raw_writeq(t & 0x7fffffUL, wdog - 0x10); |
72 | spin_unlock(&sbwd_lock); | 72 | spin_unlock(&sbwd_lock); |
73 | } | 73 | } |
74 | 74 | ||
@@ -326,7 +326,7 @@ static void __exit sbwdog_exit(void) | |||
326 | module_init(sbwdog_init); | 326 | module_init(sbwdog_init); |
327 | module_exit(sbwdog_exit); | 327 | module_exit(sbwdog_exit); |
328 | 328 | ||
329 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>"); | 329 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>"); |
330 | MODULE_DESCRIPTION("SiByte Watchdog"); | 330 | MODULE_DESCRIPTION("SiByte Watchdog"); |
331 | 331 | ||
332 | module_param(timeout, ulong, 0); | 332 | module_param(timeout, ulong, 0); |
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c index 91430a89107c..c7d67e9a7465 100644 --- a/drivers/watchdog/sbc_fitpc2_wdt.c +++ b/drivers/watchdog/sbc_fitpc2_wdt.c | |||
@@ -30,7 +30,7 @@ | |||
30 | static int nowayout = WATCHDOG_NOWAYOUT; | 30 | static int nowayout = WATCHDOG_NOWAYOUT; |
31 | static unsigned int margin = 60; /* (secs) Default is 1 minute */ | 31 | static unsigned int margin = 60; /* (secs) Default is 1 minute */ |
32 | static unsigned long wdt_status; | 32 | static unsigned long wdt_status; |
33 | static DEFINE_SPINLOCK(wdt_lock); | 33 | static DEFINE_MUTEX(wdt_lock); |
34 | 34 | ||
35 | #define WDT_IN_USE 0 | 35 | #define WDT_IN_USE 0 |
36 | #define WDT_OK_TO_CLOSE 1 | 36 | #define WDT_OK_TO_CLOSE 1 |
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock); | |||
45 | 45 | ||
46 | static void wdt_send_data(unsigned char command, unsigned char data) | 46 | static void wdt_send_data(unsigned char command, unsigned char data) |
47 | { | 47 | { |
48 | outb(command, COMMAND_PORT); | ||
49 | mdelay(100); | ||
50 | outb(data, DATA_PORT); | 48 | outb(data, DATA_PORT); |
51 | mdelay(200); | 49 | msleep(200); |
50 | outb(command, COMMAND_PORT); | ||
51 | msleep(100); | ||
52 | } | 52 | } |
53 | 53 | ||
54 | static void wdt_enable(void) | 54 | static void wdt_enable(void) |
55 | { | 55 | { |
56 | spin_lock(&wdt_lock); | 56 | mutex_lock(&wdt_lock); |
57 | wdt_send_data(IFACE_ON_COMMAND, 1); | 57 | wdt_send_data(IFACE_ON_COMMAND, 1); |
58 | wdt_send_data(REBOOT_COMMAND, margin); | 58 | wdt_send_data(REBOOT_COMMAND, margin); |
59 | spin_unlock(&wdt_lock); | 59 | mutex_unlock(&wdt_lock); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void wdt_disable(void) | 62 | static void wdt_disable(void) |
63 | { | 63 | { |
64 | spin_lock(&wdt_lock); | 64 | mutex_lock(&wdt_lock); |
65 | wdt_send_data(IFACE_ON_COMMAND, 0); | 65 | wdt_send_data(IFACE_ON_COMMAND, 0); |
66 | wdt_send_data(REBOOT_COMMAND, 0); | 66 | wdt_send_data(REBOOT_COMMAND, 0); |
67 | spin_unlock(&wdt_lock); | 67 | mutex_unlock(&wdt_lock); |
68 | } | 68 | } |
69 | 69 | ||
70 | static int fitpc2_wdt_open(struct inode *inode, struct file *file) | 70 | static int fitpc2_wdt_open(struct inode *inode, struct file *file) |
@@ -111,7 +111,7 @@ out: | |||
111 | } | 111 | } |
112 | 112 | ||
113 | 113 | ||
114 | static struct watchdog_info ident = { | 114 | static const struct watchdog_info ident = { |
115 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 115 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
116 | WDIOF_KEEPALIVEPING, | 116 | WDIOF_KEEPALIVEPING, |
117 | .identity = WATCHDOG_NAME, | 117 | .identity = WATCHDOG_NAME, |
@@ -202,11 +202,10 @@ static int __init fitpc2_wdt_init(void) | |||
202 | { | 202 | { |
203 | int err; | 203 | int err; |
204 | 204 | ||
205 | if (strcmp("SBC-FITPC2", dmi_get_system_info(DMI_BOARD_NAME))) { | 205 | if (!strstr(dmi_get_system_info(DMI_BOARD_NAME), "SBC-FITPC2")) |
206 | pr_info("board name is: %s. Should be SBC-FITPC2\n", | ||
207 | dmi_get_system_info(DMI_BOARD_NAME)); | ||
208 | return -ENODEV; | 206 | return -ENODEV; |
209 | } | 207 | |
208 | pr_info("%s found\n", dmi_get_system_info(DMI_BOARD_NAME)); | ||
210 | 209 | ||
211 | if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) { | 210 | if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) { |
212 | pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT); | 211 | pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT); |
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 569eb295a7a8..9c40f48804f5 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c | |||
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
250 | int new_timeout; | 250 | int new_timeout; |
251 | void __user *argp = (void __user *)arg; | 251 | void __user *argp = (void __user *)arg; |
252 | int __user *p = argp; | 252 | int __user *p = argp; |
253 | static struct watchdog_info ident = { | 253 | static const struct watchdog_info ident = { |
254 | .options = WDIOF_KEEPALIVEPING | | 254 | .options = WDIOF_KEEPALIVEPING | |
255 | WDIOF_SETTIMEOUT | | 255 | WDIOF_SETTIMEOUT | |
256 | WDIOF_MAGICCLOSE, | 256 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c index 5dd952681f32..b3421fd2cda8 100644 --- a/drivers/watchdog/stmp3xxx_wdt.c +++ b/drivers/watchdog/stmp3xxx_wdt.c | |||
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct file *file, const char __user *data, | |||
94 | return len; | 94 | return len; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct watchdog_info ident = { | 97 | static const struct watchdog_info ident = { |
98 | .options = WDIOF_CARDRESET | | 98 | .options = WDIOF_CARDRESET | |
99 | WDIOF_MAGICCLOSE | | 99 | WDIOF_MAGICCLOSE | |
100 | WDIOF_SETTIMEOUT | | 100 | WDIOF_SETTIMEOUT | |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c new file mode 100644 index 000000000000..458c499c1223 --- /dev/null +++ b/drivers/watchdog/ts72xx_wdt.c | |||
@@ -0,0 +1,521 @@ | |||
1 | /* | ||
2 | * Watchdog driver for Technologic Systems TS-72xx based SBCs | ||
3 | * (TS-7200, TS-7250 and TS-7260). These boards have external | ||
4 | * glue logic CPLD chip, which includes programmable watchdog | ||
5 | * timer. | ||
6 | * | ||
7 | * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi> | ||
8 | * | ||
9 | * This driver is based on ep93xx_wdt and wm831x_wdt drivers. | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/fs.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/miscdevice.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/watchdog.h> | ||
25 | #include <linux/uaccess.h> | ||
26 | |||
27 | #define TS72XX_WDT_FEED_VAL 0x05 | ||
28 | #define TS72XX_WDT_DEFAULT_TIMEOUT 8 | ||
29 | |||
30 | static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT; | ||
31 | module_param(timeout, int, 0); | ||
32 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. " | ||
33 | "(1 <= timeout <= 8, default=" | ||
34 | __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT) | ||
35 | ")"); | ||
36 | |||
37 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
38 | module_param(nowayout, int, 0); | ||
39 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | ||
40 | |||
41 | /** | ||
42 | * struct ts72xx_wdt - watchdog control structure | ||
43 | * @lock: lock that protects this structure | ||
44 | * @regval: watchdog timeout value suitable for control register | ||
45 | * @flags: flags controlling watchdog device state | ||
46 | * @control_reg: watchdog control register | ||
47 | * @feed_reg: watchdog feed register | ||
48 | * @pdev: back pointer to platform dev | ||
49 | */ | ||
50 | struct ts72xx_wdt { | ||
51 | struct mutex lock; | ||
52 | int regval; | ||
53 | |||
54 | #define TS72XX_WDT_BUSY_FLAG 1 | ||
55 | #define TS72XX_WDT_EXPECT_CLOSE_FLAG 2 | ||
56 | int flags; | ||
57 | |||
58 | void __iomem *control_reg; | ||
59 | void __iomem *feed_reg; | ||
60 | |||
61 | struct platform_device *pdev; | ||
62 | }; | ||
63 | |||
64 | struct platform_device *ts72xx_wdt_pdev; | ||
65 | |||
66 | /* | ||
67 | * TS-72xx Watchdog supports following timeouts (value written | ||
68 | * to control register): | ||
69 | * value description | ||
70 | * ------------------------- | ||
71 | * 0x00 watchdog disabled | ||
72 | * 0x01 250ms | ||
73 | * 0x02 500ms | ||
74 | * 0x03 1s | ||
75 | * 0x04 reserved | ||
76 | * 0x05 2s | ||
77 | * 0x06 4s | ||
78 | * 0x07 8s | ||
79 | * | ||
80 | * Timeouts below 1s are not very usable so we don't | ||
81 | * allow them at all. | ||
82 | * | ||
83 | * We provide two functions that convert between these: | ||
84 | * timeout_to_regval() and regval_to_timeout(). | ||
85 | */ | ||
86 | static const struct { | ||
87 | int timeout; | ||
88 | int regval; | ||
89 | } ts72xx_wdt_map[] = { | ||
90 | { 1, 3 }, | ||
91 | { 2, 5 }, | ||
92 | { 4, 6 }, | ||
93 | { 8, 7 }, | ||
94 | }; | ||
95 | |||
96 | /** | ||
97 | * timeout_to_regval() - converts given timeout to control register value | ||
98 | * @new_timeout: timeout in seconds to be converted | ||
99 | * | ||
100 | * Function converts given @new_timeout into valid value that can | ||
101 | * be programmed into watchdog control register. When conversion is | ||
102 | * not possible, function returns %-EINVAL. | ||
103 | */ | ||
104 | static int timeout_to_regval(int new_timeout) | ||
105 | { | ||
106 | int i; | ||
107 | |||
108 | /* first limit it to 1 - 8 seconds */ | ||
109 | new_timeout = clamp_val(new_timeout, 1, 8); | ||
110 | |||
111 | for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) { | ||
112 | if (ts72xx_wdt_map[i].timeout >= new_timeout) | ||
113 | return ts72xx_wdt_map[i].regval; | ||
114 | } | ||
115 | |||
116 | return -EINVAL; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * regval_to_timeout() - converts control register value to timeout | ||
121 | * @regval: control register value to be converted | ||
122 | * | ||
123 | * Function converts given @regval to timeout in seconds (1, 2, 4 or 8). | ||
124 | * If @regval cannot be converted, function returns %-EINVAL. | ||
125 | */ | ||
126 | static int regval_to_timeout(int regval) | ||
127 | { | ||
128 | int i; | ||
129 | |||
130 | for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) { | ||
131 | if (ts72xx_wdt_map[i].regval == regval) | ||
132 | return ts72xx_wdt_map[i].timeout; | ||
133 | } | ||
134 | |||
135 | return -EINVAL; | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * ts72xx_wdt_kick() - kick the watchdog | ||
140 | * @wdt: watchdog to be kicked | ||
141 | * | ||
142 | * Called with @wdt->lock held. | ||
143 | */ | ||
144 | static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt) | ||
145 | { | ||
146 | __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * ts72xx_wdt_start() - starts the watchdog timer | ||
151 | * @wdt: watchdog to be started | ||
152 | * | ||
153 | * This function programs timeout to watchdog timer | ||
154 | * and starts it. | ||
155 | * | ||
156 | * Called with @wdt->lock held. | ||
157 | */ | ||
158 | static void ts72xx_wdt_start(struct ts72xx_wdt *wdt) | ||
159 | { | ||
160 | /* | ||
161 | * To program the wdt, it first must be "fed" and | ||
162 | * only after that (within 30 usecs) the configuration | ||
163 | * can be changed. | ||
164 | */ | ||
165 | ts72xx_wdt_kick(wdt); | ||
166 | __raw_writeb((u8)wdt->regval, wdt->control_reg); | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * ts72xx_wdt_stop() - stops the watchdog timer | ||
171 | * @wdt: watchdog to be stopped | ||
172 | * | ||
173 | * Called with @wdt->lock held. | ||
174 | */ | ||
175 | static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt) | ||
176 | { | ||
177 | ts72xx_wdt_kick(wdt); | ||
178 | __raw_writeb(0, wdt->control_reg); | ||
179 | } | ||
180 | |||
181 | static int ts72xx_wdt_open(struct inode *inode, struct file *file) | ||
182 | { | ||
183 | struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev); | ||
184 | int regval; | ||
185 | |||
186 | /* | ||
187 | * Try to convert default timeout to valid register | ||
188 | * value first. | ||
189 | */ | ||
190 | regval = timeout_to_regval(timeout); | ||
191 | if (regval < 0) { | ||
192 | dev_err(&wdt->pdev->dev, | ||
193 | "failed to convert timeout (%d) to register value\n", | ||
194 | timeout); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | |||
198 | if (mutex_lock_interruptible(&wdt->lock)) | ||
199 | return -ERESTARTSYS; | ||
200 | |||
201 | if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) { | ||
202 | mutex_unlock(&wdt->lock); | ||
203 | return -EBUSY; | ||
204 | } | ||
205 | |||
206 | wdt->flags = TS72XX_WDT_BUSY_FLAG; | ||
207 | wdt->regval = regval; | ||
208 | file->private_data = wdt; | ||
209 | |||
210 | ts72xx_wdt_start(wdt); | ||
211 | |||
212 | mutex_unlock(&wdt->lock); | ||
213 | return nonseekable_open(inode, file); | ||
214 | } | ||
215 | |||
216 | static int ts72xx_wdt_release(struct inode *inode, struct file *file) | ||
217 | { | ||
218 | struct ts72xx_wdt *wdt = file->private_data; | ||
219 | |||
220 | if (mutex_lock_interruptible(&wdt->lock)) | ||
221 | return -ERESTARTSYS; | ||
222 | |||
223 | if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) { | ||
224 | ts72xx_wdt_stop(wdt); | ||
225 | } else { | ||
226 | dev_warn(&wdt->pdev->dev, | ||
227 | "TS-72XX WDT device closed unexpectly. " | ||
228 | "Watchdog timer will not stop!\n"); | ||
229 | /* | ||
230 | * Kick it one more time, to give userland some time | ||
231 | * to recover (for example, respawning the kicker | ||
232 | * daemon). | ||
233 | */ | ||
234 | ts72xx_wdt_kick(wdt); | ||
235 | } | ||
236 | |||
237 | wdt->flags = 0; | ||
238 | |||
239 | mutex_unlock(&wdt->lock); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static ssize_t ts72xx_wdt_write(struct file *file, | ||
244 | const char __user *data, | ||
245 | size_t len, | ||
246 | loff_t *ppos) | ||
247 | { | ||
248 | struct ts72xx_wdt *wdt = file->private_data; | ||
249 | |||
250 | if (!len) | ||
251 | return 0; | ||
252 | |||
253 | if (mutex_lock_interruptible(&wdt->lock)) | ||
254 | return -ERESTARTSYS; | ||
255 | |||
256 | ts72xx_wdt_kick(wdt); | ||
257 | |||
258 | /* | ||
259 | * Support for magic character closing. User process | ||
260 | * writes 'V' into the device, just before it is closed. | ||
261 | * This means that we know that the wdt timer can be | ||
262 | * stopped after user closes the device. | ||
263 | */ | ||
264 | if (!nowayout) { | ||
265 | int i; | ||
266 | |||
267 | for (i = 0; i < len; i++) { | ||
268 | char c; | ||
269 | |||
270 | /* In case it was set long ago */ | ||
271 | wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG; | ||
272 | |||
273 | if (get_user(c, data + i)) { | ||
274 | mutex_unlock(&wdt->lock); | ||
275 | return -EFAULT; | ||
276 | } | ||
277 | if (c == 'V') { | ||
278 | wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG; | ||
279 | break; | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | mutex_unlock(&wdt->lock); | ||
285 | return len; | ||
286 | } | ||
287 | |||
288 | static const struct watchdog_info winfo = { | ||
289 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | ||
290 | WDIOF_MAGICCLOSE, | ||
291 | .firmware_version = 1, | ||
292 | .identity = "TS-72XX WDT", | ||
293 | }; | ||
294 | |||
295 | static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, | ||
296 | unsigned long arg) | ||
297 | { | ||
298 | struct ts72xx_wdt *wdt = file->private_data; | ||
299 | void __user *argp = (void __user *)arg; | ||
300 | int __user *p = (int __user *)argp; | ||
301 | int error = 0; | ||
302 | |||
303 | if (mutex_lock_interruptible(&wdt->lock)) | ||
304 | return -ERESTARTSYS; | ||
305 | |||
306 | switch (cmd) { | ||
307 | case WDIOC_GETSUPPORT: | ||
308 | error = copy_to_user(argp, &winfo, sizeof(winfo)); | ||
309 | break; | ||
310 | |||
311 | case WDIOC_GETSTATUS: | ||
312 | case WDIOC_GETBOOTSTATUS: | ||
313 | return put_user(0, p); | ||
314 | |||
315 | case WDIOC_KEEPALIVE: | ||
316 | ts72xx_wdt_kick(wdt); | ||
317 | break; | ||
318 | |||
319 | case WDIOC_SETOPTIONS: { | ||
320 | int options; | ||
321 | |||
322 | if (get_user(options, p)) { | ||
323 | error = -EFAULT; | ||
324 | break; | ||
325 | } | ||
326 | |||
327 | error = -EINVAL; | ||
328 | |||
329 | if ((options & WDIOS_DISABLECARD) != 0) { | ||
330 | ts72xx_wdt_stop(wdt); | ||
331 | error = 0; | ||
332 | } | ||
333 | if ((options & WDIOS_ENABLECARD) != 0) { | ||
334 | ts72xx_wdt_start(wdt); | ||
335 | error = 0; | ||
336 | } | ||
337 | |||
338 | break; | ||
339 | } | ||
340 | |||
341 | case WDIOC_SETTIMEOUT: { | ||
342 | int new_timeout; | ||
343 | |||
344 | if (get_user(new_timeout, p)) { | ||
345 | error = -EFAULT; | ||
346 | } else { | ||
347 | int regval; | ||
348 | |||
349 | regval = timeout_to_regval(new_timeout); | ||
350 | if (regval < 0) { | ||
351 | error = -EINVAL; | ||
352 | } else { | ||
353 | ts72xx_wdt_stop(wdt); | ||
354 | wdt->regval = regval; | ||
355 | ts72xx_wdt_start(wdt); | ||
356 | } | ||
357 | } | ||
358 | if (error) | ||
359 | break; | ||
360 | |||
361 | /*FALLTHROUGH*/ | ||
362 | } | ||
363 | |||
364 | case WDIOC_GETTIMEOUT: | ||
365 | if (put_user(regval_to_timeout(wdt->regval), p)) | ||
366 | error = -EFAULT; | ||
367 | break; | ||
368 | |||
369 | default: | ||
370 | error = -ENOTTY; | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | mutex_unlock(&wdt->lock); | ||
375 | return error; | ||
376 | } | ||
377 | |||
378 | static const struct file_operations ts72xx_wdt_fops = { | ||
379 | .owner = THIS_MODULE, | ||
380 | .llseek = no_llseek, | ||
381 | .open = ts72xx_wdt_open, | ||
382 | .release = ts72xx_wdt_release, | ||
383 | .write = ts72xx_wdt_write, | ||
384 | .unlocked_ioctl = ts72xx_wdt_ioctl, | ||
385 | }; | ||
386 | |||
387 | static struct miscdevice ts72xx_wdt_miscdev = { | ||
388 | .minor = WATCHDOG_MINOR, | ||
389 | .name = "watchdog", | ||
390 | .fops = &ts72xx_wdt_fops, | ||
391 | }; | ||
392 | |||
393 | static __devinit int ts72xx_wdt_probe(struct platform_device *pdev) | ||
394 | { | ||
395 | struct ts72xx_wdt *wdt; | ||
396 | struct resource *r1, *r2; | ||
397 | int error = 0; | ||
398 | |||
399 | wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL); | ||
400 | if (!wdt) { | ||
401 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
402 | return -ENOMEM; | ||
403 | } | ||
404 | |||
405 | r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
406 | if (!r1) { | ||
407 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
408 | error = -ENODEV; | ||
409 | goto fail; | ||
410 | } | ||
411 | |||
412 | r1 = request_mem_region(r1->start, resource_size(r1), pdev->name); | ||
413 | if (!r1) { | ||
414 | dev_err(&pdev->dev, "cannot request memory region\n"); | ||
415 | error = -EBUSY; | ||
416 | goto fail; | ||
417 | } | ||
418 | |||
419 | wdt->control_reg = ioremap(r1->start, resource_size(r1)); | ||
420 | if (!wdt->control_reg) { | ||
421 | dev_err(&pdev->dev, "failed to map memory\n"); | ||
422 | error = -ENODEV; | ||
423 | goto fail_free_control; | ||
424 | } | ||
425 | |||
426 | r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
427 | if (!r2) { | ||
428 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
429 | error = -ENODEV; | ||
430 | goto fail_unmap_control; | ||
431 | } | ||
432 | |||
433 | r2 = request_mem_region(r2->start, resource_size(r2), pdev->name); | ||
434 | if (!r2) { | ||
435 | dev_err(&pdev->dev, "cannot request memory region\n"); | ||
436 | error = -EBUSY; | ||
437 | goto fail_unmap_control; | ||
438 | } | ||
439 | |||
440 | wdt->feed_reg = ioremap(r2->start, resource_size(r2)); | ||
441 | if (!wdt->feed_reg) { | ||
442 | dev_err(&pdev->dev, "failed to map memory\n"); | ||
443 | error = -ENODEV; | ||
444 | goto fail_free_feed; | ||
445 | } | ||
446 | |||
447 | platform_set_drvdata(pdev, wdt); | ||
448 | ts72xx_wdt_pdev = pdev; | ||
449 | wdt->pdev = pdev; | ||
450 | mutex_init(&wdt->lock); | ||
451 | |||
452 | error = misc_register(&ts72xx_wdt_miscdev); | ||
453 | if (error) { | ||
454 | dev_err(&pdev->dev, "failed to register miscdev\n"); | ||
455 | goto fail_unmap_feed; | ||
456 | } | ||
457 | |||
458 | dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); | ||
459 | |||
460 | return 0; | ||
461 | |||
462 | fail_unmap_feed: | ||
463 | platform_set_drvdata(pdev, NULL); | ||
464 | iounmap(wdt->feed_reg); | ||
465 | fail_free_feed: | ||
466 | release_mem_region(r2->start, resource_size(r2)); | ||
467 | fail_unmap_control: | ||
468 | iounmap(wdt->control_reg); | ||
469 | fail_free_control: | ||
470 | release_mem_region(r1->start, resource_size(r1)); | ||
471 | fail: | ||
472 | kfree(wdt); | ||
473 | return error; | ||
474 | } | ||
475 | |||
476 | static __devexit int ts72xx_wdt_remove(struct platform_device *pdev) | ||
477 | { | ||
478 | struct ts72xx_wdt *wdt = platform_get_drvdata(pdev); | ||
479 | struct resource *res; | ||
480 | int error; | ||
481 | |||
482 | error = misc_deregister(&ts72xx_wdt_miscdev); | ||
483 | platform_set_drvdata(pdev, NULL); | ||
484 | |||
485 | iounmap(wdt->feed_reg); | ||
486 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
487 | release_mem_region(res->start, resource_size(res)); | ||
488 | |||
489 | iounmap(wdt->control_reg); | ||
490 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
491 | release_mem_region(res->start, resource_size(res)); | ||
492 | |||
493 | kfree(wdt); | ||
494 | return error; | ||
495 | } | ||
496 | |||
497 | static struct platform_driver ts72xx_wdt_driver = { | ||
498 | .probe = ts72xx_wdt_probe, | ||
499 | .remove = __devexit_p(ts72xx_wdt_remove), | ||
500 | .driver = { | ||
501 | .name = "ts72xx-wdt", | ||
502 | .owner = THIS_MODULE, | ||
503 | }, | ||
504 | }; | ||
505 | |||
506 | static __init int ts72xx_wdt_init(void) | ||
507 | { | ||
508 | return platform_driver_register(&ts72xx_wdt_driver); | ||
509 | } | ||
510 | module_init(ts72xx_wdt_init); | ||
511 | |||
512 | static __exit void ts72xx_wdt_exit(void) | ||
513 | { | ||
514 | platform_driver_unregister(&ts72xx_wdt_driver); | ||
515 | } | ||
516 | module_exit(ts72xx_wdt_exit); | ||
517 | |||
518 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); | ||
519 | MODULE_DESCRIPTION("TS-72xx SBC Watchdog"); | ||
520 | MODULE_LICENSE("GPL"); | ||
521 | MODULE_ALIAS("platform:ts72xx-wdt"); | ||
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index cb46556f2973..dcabe77ad141 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c | |||
@@ -20,13 +20,14 @@ | |||
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/slab.h> | ||
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
25 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
26 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
27 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
28 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
29 | #include <linux/i2c/twl4030.h> | 30 | #include <linux/i2c/twl.h> |
30 | 31 | ||
31 | #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 | 32 | #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 |
32 | 33 | ||
@@ -48,7 +49,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " | |||
48 | 49 | ||
49 | static int twl4030_wdt_write(unsigned char val) | 50 | static int twl4030_wdt_write(unsigned char val) |
50 | { | 51 | { |
51 | return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, | 52 | return twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, |
52 | TWL4030_WATCHDOG_CFG_REG_OFFS); | 53 | TWL4030_WATCHDOG_CFG_REG_OFFS); |
53 | } | 54 | } |
54 | 55 | ||
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 6adab77fbbb0..9e9ed7bfabcb 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/miscdevice.h> | 13 | #include <linux/miscdevice.h> |
14 | #include <linux/watchdog.h> | 14 | #include <linux/watchdog.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/reboot.h> | ||
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
19 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *file, unsigned int cmd, | |||
166 | } | 165 | } |
167 | } | 166 | } |
168 | 167 | ||
169 | static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
170 | void *unused) | ||
171 | { | ||
172 | if (code == SYS_DOWN || code == SYS_HALT) | ||
173 | txx9wdt_stop(); | ||
174 | return NOTIFY_DONE; | ||
175 | } | ||
176 | |||
177 | static const struct file_operations txx9wdt_fops = { | 168 | static const struct file_operations txx9wdt_fops = { |
178 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
179 | .llseek = no_llseek, | 170 | .llseek = no_llseek, |
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev = { | |||
189 | .fops = &txx9wdt_fops, | 180 | .fops = &txx9wdt_fops, |
190 | }; | 181 | }; |
191 | 182 | ||
192 | static struct notifier_block txx9wdt_notifier = { | ||
193 | .notifier_call = txx9wdt_notify_sys, | ||
194 | }; | ||
195 | |||
196 | static int __init txx9wdt_probe(struct platform_device *dev) | 183 | static int __init txx9wdt_probe(struct platform_device *dev) |
197 | { | 184 | { |
198 | struct resource *res; | 185 | struct resource *res; |
@@ -214,22 +201,15 @@ static int __init txx9wdt_probe(struct platform_device *dev) | |||
214 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 201 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
215 | if (!res) | 202 | if (!res) |
216 | goto exit_busy; | 203 | goto exit_busy; |
217 | if (!devm_request_mem_region(&dev->dev, | 204 | if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), |
218 | res->start, res->end - res->start + 1, | ||
219 | "txx9wdt")) | 205 | "txx9wdt")) |
220 | goto exit_busy; | 206 | goto exit_busy; |
221 | txx9wdt_reg = devm_ioremap(&dev->dev, | 207 | txx9wdt_reg = devm_ioremap(&dev->dev, res->start, resource_size(res)); |
222 | res->start, res->end - res->start + 1); | ||
223 | if (!txx9wdt_reg) | 208 | if (!txx9wdt_reg) |
224 | goto exit_busy; | 209 | goto exit_busy; |
225 | 210 | ||
226 | ret = register_reboot_notifier(&txx9wdt_notifier); | ||
227 | if (ret) | ||
228 | goto exit; | ||
229 | |||
230 | ret = misc_register(&txx9wdt_miscdev); | 211 | ret = misc_register(&txx9wdt_miscdev); |
231 | if (ret) { | 212 | if (ret) { |
232 | unregister_reboot_notifier(&txx9wdt_notifier); | ||
233 | goto exit; | 213 | goto exit; |
234 | } | 214 | } |
235 | 215 | ||
@@ -251,14 +231,19 @@ exit: | |||
251 | static int __exit txx9wdt_remove(struct platform_device *dev) | 231 | static int __exit txx9wdt_remove(struct platform_device *dev) |
252 | { | 232 | { |
253 | misc_deregister(&txx9wdt_miscdev); | 233 | misc_deregister(&txx9wdt_miscdev); |
254 | unregister_reboot_notifier(&txx9wdt_notifier); | ||
255 | clk_disable(txx9_imclk); | 234 | clk_disable(txx9_imclk); |
256 | clk_put(txx9_imclk); | 235 | clk_put(txx9_imclk); |
257 | return 0; | 236 | return 0; |
258 | } | 237 | } |
259 | 238 | ||
239 | static void txx9wdt_shutdown(struct platform_device *dev) | ||
240 | { | ||
241 | txx9wdt_stop(); | ||
242 | } | ||
243 | |||
260 | static struct platform_driver txx9wdt_driver = { | 244 | static struct platform_driver txx9wdt_driver = { |
261 | .remove = __exit_p(txx9wdt_remove), | 245 | .remove = __exit_p(txx9wdt_remove), |
246 | .shutdown = txx9wdt_shutdown, | ||
262 | .driver = { | 247 | .driver = { |
263 | .name = "txx9wdt", | 248 | .name = "txx9wdt", |
264 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE, |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index f201accc4e3d..0f5288df0091 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
201 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
202 | int __user *p = argp; | 202 | int __user *p = argp; |
203 | int new_timeout; | 203 | int new_timeout; |
204 | static struct watchdog_info ident = { | 204 | static const struct watchdog_info ident = { |
205 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 205 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
206 | WDIOF_MAGICCLOSE, | 206 | WDIOF_MAGICCLOSE, |
207 | .firmware_version = 1, | 207 | .firmware_version = 1, |
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index 0560182a1d09..6e6743d1066f 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c | |||
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
371 | * according to their available features. | 371 | * according to their available features. |
372 | */ | 372 | */ |
373 | 373 | ||
374 | static struct watchdog_info ident = { | 374 | static const struct watchdog_info ident = { |
375 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 375 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
376 | .firmware_version = 1, | 376 | .firmware_version = 1, |
377 | .identity = WATCHDOG_NAME, | 377 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 3bde56bce63a..94ec22b9e66b 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *file, unsigned int cmd, | |||
312 | { | 312 | { |
313 | int __user *argp = (void __user *)arg; | 313 | int __user *argp = (void __user *)arg; |
314 | int i; | 314 | int i; |
315 | static struct watchdog_info wdinfo = { | 315 | static const struct watchdog_info wdinfo = { |
316 | .options = WDRTAS_SUPPORTED_MASK, | 316 | .options = WDRTAS_SUPPORTED_MASK, |
317 | .firmware_version = 0, | 317 | .firmware_version = 0, |
318 | .identity = "wdrtas", | 318 | .identity = "wdrtas", |
@@ -542,7 +542,7 @@ static struct notifier_block wdrtas_notifier = { | |||
542 | /** | 542 | /** |
543 | * wdrtas_get_tokens - reads in RTAS tokens | 543 | * wdrtas_get_tokens - reads in RTAS tokens |
544 | * | 544 | * |
545 | * returns 0 on succes, <0 on failure | 545 | * returns 0 on success, <0 on failure |
546 | * | 546 | * |
547 | * wdrtas_get_tokens reads in the tokens for the RTAS calls used in | 547 | * wdrtas_get_tokens reads in the tokens for the RTAS calls used in |
548 | * this watchdog driver. It tolerates, if "get-sensor-state" and | 548 | * this watchdog driver. It tolerates, if "get-sensor-state" and |
@@ -598,7 +598,7 @@ static void wdrtas_unregister_devs(void) | |||
598 | /** | 598 | /** |
599 | * wdrtas_register_devs - registers the misc dev handlers | 599 | * wdrtas_register_devs - registers the misc dev handlers |
600 | * | 600 | * |
601 | * returns 0 on succes, <0 on failure | 601 | * returns 0 on success, <0 on failure |
602 | * | 602 | * |
603 | * wdrtas_register_devs registers the watchdog and temperature watchdog | 603 | * wdrtas_register_devs registers the watchdog and temperature watchdog |
604 | * misc devs | 604 | * misc devs |
@@ -630,7 +630,7 @@ static int wdrtas_register_devs(void) | |||
630 | /** | 630 | /** |
631 | * wdrtas_init - init function of the watchdog driver | 631 | * wdrtas_init - init function of the watchdog driver |
632 | * | 632 | * |
633 | * returns 0 on succes, <0 on failure | 633 | * returns 0 on success, <0 on failure |
634 | * | 634 | * |
635 | * registers the file handlers and the reboot notifier | 635 | * registers the file handlers and the reboot notifier |
636 | */ | 636 | */ |
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 3bbefe9a2634..bfda2e99dd89 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c | |||
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
358 | int new_heartbeat; | 358 | int new_heartbeat; |
359 | int status; | 359 | int status; |
360 | 360 | ||
361 | static struct watchdog_info ident = { | 361 | struct watchdog_info ident = { |
362 | .options = WDIOF_SETTIMEOUT| | 362 | .options = WDIOF_SETTIMEOUT| |
363 | WDIOF_MAGICCLOSE| | 363 | WDIOF_MAGICCLOSE| |
364 | WDIOF_KEEPALIVEPING, | 364 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index f368dd87083a..7b22e3cdbc81 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, | |||
412 | int new_heartbeat; | 412 | int new_heartbeat; |
413 | int status; | 413 | int status; |
414 | 414 | ||
415 | static struct watchdog_info ident = { | 415 | struct watchdog_info ident = { |
416 | .options = WDIOF_SETTIMEOUT| | 416 | .options = WDIOF_SETTIMEOUT| |
417 | WDIOF_MAGICCLOSE| | 417 | WDIOF_MAGICCLOSE| |
418 | WDIOF_KEEPALIVEPING, | 418 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 775bcd807f31..8c4b2d5bb7da 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c | |||
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct file *file, | |||
213 | return count; | 213 | return count; |
214 | } | 214 | } |
215 | 215 | ||
216 | static struct watchdog_info ident = { | 216 | static const struct watchdog_info ident = { |
217 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 217 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
218 | .identity = "WM831x Watchdog", | 218 | .identity = "WM831x Watchdog", |
219 | }; | 219 | }; |
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index a2d2e8eb2282..89dd7b035295 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c | |||
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct file *file, | |||
177 | return count; | 177 | return count; |
178 | } | 178 | } |
179 | 179 | ||
180 | static struct watchdog_info ident = { | 180 | static const struct watchdog_info ident = { |
181 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 181 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
182 | .identity = "WM8350 Watchdog", | 182 | .identity = "WM8350 Watchdog", |
183 | }; | 183 | }; |