diff options
Diffstat (limited to 'drivers')
57 files changed, 2963 insertions, 2930 deletions
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 85269c365a10..269ada2f1fc3 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c | |||
@@ -58,39 +58,46 @@ | |||
58 | #include <linux/types.h> /* For standard types (like size_t) */ | 58 | #include <linux/types.h> /* For standard types (like size_t) */ |
59 | #include <linux/errno.h> /* For the -ENODEV/... values */ | 59 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
60 | #include <linux/kernel.h> /* For printk/panic/... */ | 60 | #include <linux/kernel.h> /* For printk/panic/... */ |
61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ | 61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV |
62 | (WATCHDOG_MINOR) */ | ||
62 | #include <linux/watchdog.h> /* For the watchdog specific items */ | 63 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
63 | #include <linux/fs.h> /* For file operations */ | 64 | #include <linux/fs.h> /* For file operations */ |
64 | #include <linux/ioport.h> /* For io-port access */ | 65 | #include <linux/ioport.h> /* For io-port access */ |
65 | #include <linux/platform_device.h> /* For platform_driver framework */ | 66 | #include <linux/platform_device.h> /* For platform_driver framework */ |
66 | #include <linux/init.h> /* For __init/__exit/... */ | 67 | #include <linux/init.h> /* For __init/__exit/... */ |
67 | 68 | ||
68 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 69 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ |
69 | #include <asm/io.h> /* For inb/outb/... */ | 70 | #include <linux/io.h> /* For inb/outb/... */ |
70 | 71 | ||
71 | /* Module information */ | 72 | /* Module information */ |
72 | #define DRV_NAME "acquirewdt" | 73 | #define DRV_NAME "acquirewdt" |
73 | #define PFX DRV_NAME ": " | 74 | #define PFX DRV_NAME ": " |
74 | #define WATCHDOG_NAME "Acquire WDT" | 75 | #define WATCHDOG_NAME "Acquire WDT" |
75 | #define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ | 76 | /* There is no way to see what the correct time-out period is */ |
77 | #define WATCHDOG_HEARTBEAT 0 | ||
76 | 78 | ||
77 | /* internal variables */ | 79 | /* internal variables */ |
78 | static struct platform_device *acq_platform_device; /* the watchdog platform device */ | 80 | /* the watchdog platform device */ |
81 | static struct platform_device *acq_platform_device; | ||
79 | static unsigned long acq_is_open; | 82 | static unsigned long acq_is_open; |
80 | static char expect_close; | 83 | static char expect_close; |
81 | 84 | ||
82 | /* module parameters */ | 85 | /* module parameters */ |
83 | static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ | 86 | /* You must set this - there is no sane way to probe for this board. */ |
87 | static int wdt_stop = 0x43; | ||
84 | module_param(wdt_stop, int, 0); | 88 | module_param(wdt_stop, int, 0); |
85 | MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); | 89 | MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); |
86 | 90 | ||
87 | static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ | 91 | /* You must set this - there is no sane way to probe for this board. */ |
92 | static int wdt_start = 0x443; | ||
88 | module_param(wdt_start, int, 0); | 93 | module_param(wdt_start, int, 0); |
89 | MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); | 94 | MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); |
90 | 95 | ||
91 | static int nowayout = WATCHDOG_NOWAYOUT; | 96 | static int nowayout = WATCHDOG_NOWAYOUT; |
92 | module_param(nowayout, int, 0); | 97 | module_param(nowayout, int, 0); |
93 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 98 | MODULE_PARM_DESC(nowayout, |
99 | "Watchdog cannot be stopped once started (default=" | ||
100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
94 | 101 | ||
95 | /* | 102 | /* |
96 | * Watchdog Operations | 103 | * Watchdog Operations |
@@ -112,18 +119,18 @@ static void acq_stop(void) | |||
112 | * /dev/watchdog handling | 119 | * /dev/watchdog handling |
113 | */ | 120 | */ |
114 | 121 | ||
115 | static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 122 | static ssize_t acq_write(struct file *file, const char __user *buf, |
123 | size_t count, loff_t *ppos) | ||
116 | { | 124 | { |
117 | /* See if we got the magic character 'V' and reload the timer */ | 125 | /* See if we got the magic character 'V' and reload the timer */ |
118 | if(count) { | 126 | if (count) { |
119 | if (!nowayout) { | 127 | if (!nowayout) { |
120 | size_t i; | 128 | size_t i; |
121 | |||
122 | /* note: just in case someone wrote the magic character | 129 | /* note: just in case someone wrote the magic character |
123 | * five months ago... */ | 130 | * five months ago... */ |
124 | expect_close = 0; | 131 | expect_close = 0; |
125 | 132 | /* scan to see whether or not we got the | |
126 | /* scan to see whether or not we got the magic character */ | 133 | magic character */ |
127 | for (i = 0; i != count; i++) { | 134 | for (i = 0; i != count; i++) { |
128 | char c; | 135 | char c; |
129 | if (get_user(c, buf + i)) | 136 | if (get_user(c, buf + i)) |
@@ -132,64 +139,55 @@ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count | |||
132 | expect_close = 42; | 139 | expect_close = 42; |
133 | } | 140 | } |
134 | } | 141 | } |
135 | 142 | /* Well, anyhow someone wrote to us, we should | |
136 | /* Well, anyhow someone wrote to us, we should return that favour */ | 143 | return that favour */ |
137 | acq_keepalive(); | 144 | acq_keepalive(); |
138 | } | 145 | } |
139 | return count; | 146 | return count; |
140 | } | 147 | } |
141 | 148 | ||
142 | static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 149 | static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
143 | unsigned long arg) | ||
144 | { | 150 | { |
145 | int options, retval = -EINVAL; | 151 | int options, retval = -EINVAL; |
146 | void __user *argp = (void __user *)arg; | 152 | void __user *argp = (void __user *)arg; |
147 | int __user *p = argp; | 153 | int __user *p = argp; |
148 | static struct watchdog_info ident = | 154 | static struct watchdog_info ident = { |
149 | { | ||
150 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 155 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
151 | .firmware_version = 1, | 156 | .firmware_version = 1, |
152 | .identity = WATCHDOG_NAME, | 157 | .identity = WATCHDOG_NAME, |
153 | }; | 158 | }; |
154 | 159 | ||
155 | switch(cmd) | 160 | switch (cmd) { |
156 | { | ||
157 | case WDIOC_GETSUPPORT: | 161 | case WDIOC_GETSUPPORT: |
158 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 162 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
159 | 163 | ||
160 | case WDIOC_GETSTATUS: | 164 | case WDIOC_GETSTATUS: |
161 | case WDIOC_GETBOOTSTATUS: | 165 | case WDIOC_GETBOOTSTATUS: |
162 | return put_user(0, p); | 166 | return put_user(0, p); |
163 | 167 | ||
164 | case WDIOC_KEEPALIVE: | 168 | case WDIOC_KEEPALIVE: |
165 | acq_keepalive(); | 169 | acq_keepalive(); |
166 | return 0; | 170 | return 0; |
167 | 171 | ||
168 | case WDIOC_GETTIMEOUT: | 172 | case WDIOC_GETTIMEOUT: |
169 | return put_user(WATCHDOG_HEARTBEAT, p); | 173 | return put_user(WATCHDOG_HEARTBEAT, p); |
170 | 174 | ||
171 | case WDIOC_SETOPTIONS: | 175 | case WDIOC_SETOPTIONS: |
172 | { | 176 | { |
173 | if (get_user(options, p)) | 177 | if (get_user(options, p)) |
174 | return -EFAULT; | 178 | return -EFAULT; |
175 | 179 | if (options & WDIOS_DISABLECARD) { | |
176 | if (options & WDIOS_DISABLECARD) | 180 | acq_stop(); |
177 | { | 181 | retval = 0; |
178 | acq_stop(); | 182 | } |
179 | retval = 0; | 183 | if (options & WDIOS_ENABLECARD) { |
180 | } | 184 | acq_keepalive(); |
181 | 185 | retval = 0; | |
182 | if (options & WDIOS_ENABLECARD) | 186 | } |
183 | { | 187 | return retval; |
184 | acq_keepalive(); | ||
185 | retval = 0; | ||
186 | } | ||
187 | |||
188 | return retval; | ||
189 | } | 188 | } |
190 | |||
191 | default: | 189 | default: |
192 | return -ENOTTY; | 190 | return -ENOTTY; |
193 | } | 191 | } |
194 | } | 192 | } |
195 | 193 | ||
@@ -211,7 +209,8 @@ static int acq_close(struct inode *inode, struct file *file) | |||
211 | if (expect_close == 42) { | 209 | if (expect_close == 42) { |
212 | acq_stop(); | 210 | acq_stop(); |
213 | } else { | 211 | } else { |
214 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 212 | printk(KERN_CRIT PFX |
213 | "Unexpected close, not stopping watchdog!\n"); | ||
215 | acq_keepalive(); | 214 | acq_keepalive(); |
216 | } | 215 | } |
217 | clear_bit(0, &acq_is_open); | 216 | clear_bit(0, &acq_is_open); |
@@ -227,7 +226,7 @@ static const struct file_operations acq_fops = { | |||
227 | .owner = THIS_MODULE, | 226 | .owner = THIS_MODULE, |
228 | .llseek = no_llseek, | 227 | .llseek = no_llseek, |
229 | .write = acq_write, | 228 | .write = acq_write, |
230 | .ioctl = acq_ioctl, | 229 | .unlocked_ioctl = acq_ioctl, |
231 | .open = acq_open, | 230 | .open = acq_open, |
232 | .release = acq_close, | 231 | .release = acq_close, |
233 | }; | 232 | }; |
@@ -248,32 +247,29 @@ static int __devinit acq_probe(struct platform_device *dev) | |||
248 | 247 | ||
249 | if (wdt_stop != wdt_start) { | 248 | if (wdt_stop != wdt_start) { |
250 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { | 249 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { |
251 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 250 | printk(KERN_ERR PFX |
252 | wdt_stop); | 251 | "I/O address 0x%04x already in use\n", wdt_stop); |
253 | ret = -EIO; | 252 | ret = -EIO; |
254 | goto out; | 253 | goto out; |
255 | } | 254 | } |
256 | } | 255 | } |
257 | 256 | ||
258 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { | 257 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { |
259 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 258 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
260 | wdt_start); | 259 | wdt_start); |
261 | ret = -EIO; | 260 | ret = -EIO; |
262 | goto unreg_stop; | 261 | goto unreg_stop; |
263 | } | 262 | } |
264 | |||
265 | ret = misc_register(&acq_miscdev); | 263 | ret = misc_register(&acq_miscdev); |
266 | if (ret != 0) { | 264 | if (ret != 0) { |
267 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 265 | printk(KERN_ERR PFX |
268 | WATCHDOG_MINOR, ret); | 266 | "cannot register miscdev on minor=%d (err=%d)\n", |
267 | WATCHDOG_MINOR, ret); | ||
269 | goto unreg_regions; | 268 | goto unreg_regions; |
270 | } | 269 | } |
271 | 270 | printk(KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout); | |
272 | printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", | ||
273 | nowayout); | ||
274 | 271 | ||
275 | return 0; | 272 | return 0; |
276 | |||
277 | unreg_regions: | 273 | unreg_regions: |
278 | release_region(wdt_start, 1); | 274 | release_region(wdt_start, 1); |
279 | unreg_stop: | 275 | unreg_stop: |
@@ -286,9 +282,9 @@ out: | |||
286 | static int __devexit acq_remove(struct platform_device *dev) | 282 | static int __devexit acq_remove(struct platform_device *dev) |
287 | { | 283 | { |
288 | misc_deregister(&acq_miscdev); | 284 | misc_deregister(&acq_miscdev); |
289 | release_region(wdt_start,1); | 285 | release_region(wdt_start, 1); |
290 | if(wdt_stop != wdt_start) | 286 | if (wdt_stop != wdt_start) |
291 | release_region(wdt_stop,1); | 287 | release_region(wdt_stop, 1); |
292 | 288 | ||
293 | return 0; | 289 | return 0; |
294 | } | 290 | } |
@@ -313,18 +309,19 @@ static int __init acq_init(void) | |||
313 | { | 309 | { |
314 | int err; | 310 | int err; |
315 | 311 | ||
316 | printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); | 312 | printk(KERN_INFO |
313 | "WDT driver for Acquire single board computer initialising.\n"); | ||
317 | 314 | ||
318 | err = platform_driver_register(&acquirewdt_driver); | 315 | err = platform_driver_register(&acquirewdt_driver); |
319 | if (err) | 316 | if (err) |
320 | return err; | 317 | return err; |
321 | 318 | ||
322 | acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 319 | acq_platform_device = platform_device_register_simple(DRV_NAME, |
320 | -1, NULL, 0); | ||
323 | if (IS_ERR(acq_platform_device)) { | 321 | if (IS_ERR(acq_platform_device)) { |
324 | err = PTR_ERR(acq_platform_device); | 322 | err = PTR_ERR(acq_platform_device); |
325 | goto unreg_platform_driver; | 323 | goto unreg_platform_driver; |
326 | } | 324 | } |
327 | |||
328 | return 0; | 325 | return 0; |
329 | 326 | ||
330 | unreg_platform_driver: | 327 | unreg_platform_driver: |
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 8121cc247343..220d238ee427 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c | |||
@@ -72,35 +72,35 @@ MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)"); | |||
72 | 72 | ||
73 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 73 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
74 | module_param(timeout, int, 0); | 74 | module_param(timeout, int, 0); |
75 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | 75 | MODULE_PARM_DESC(timeout, |
76 | "Watchdog timeout in seconds. 1<= timeout <=63, default=" | ||
77 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
76 | 78 | ||
77 | static int nowayout = WATCHDOG_NOWAYOUT; | 79 | static int nowayout = WATCHDOG_NOWAYOUT; |
78 | module_param(nowayout, int, 0); | 80 | module_param(nowayout, int, 0); |
79 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 81 | MODULE_PARM_DESC(nowayout, |
82 | "Watchdog cannot be stopped once started (default=" | ||
83 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
80 | 84 | ||
81 | /* | 85 | /* |
82 | * Watchdog Operations | 86 | * Watchdog Operations |
83 | */ | 87 | */ |
84 | 88 | ||
85 | static void | 89 | static void advwdt_ping(void) |
86 | advwdt_ping(void) | ||
87 | { | 90 | { |
88 | /* Write a watchdog value */ | 91 | /* Write a watchdog value */ |
89 | outb_p(timeout, wdt_start); | 92 | outb_p(timeout, wdt_start); |
90 | } | 93 | } |
91 | 94 | ||
92 | static void | 95 | static void advwdt_disable(void) |
93 | advwdt_disable(void) | ||
94 | { | 96 | { |
95 | inb_p(wdt_stop); | 97 | inb_p(wdt_stop); |
96 | } | 98 | } |
97 | 99 | ||
98 | static int | 100 | static int advwdt_set_heartbeat(int t) |
99 | advwdt_set_heartbeat(int t) | ||
100 | { | 101 | { |
101 | if ((t < 1) || (t > 63)) | 102 | if (t < 1 || t > 63) |
102 | return -EINVAL; | 103 | return -EINVAL; |
103 | |||
104 | timeout = t; | 104 | timeout = t; |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
@@ -109,8 +109,8 @@ advwdt_set_heartbeat(int t) | |||
109 | * /dev/watchdog handling | 109 | * /dev/watchdog handling |
110 | */ | 110 | */ |
111 | 111 | ||
112 | static ssize_t | 112 | static ssize_t advwdt_write(struct file *file, const char __user *buf, |
113 | advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 113 | size_t count, loff_t *ppos) |
114 | { | 114 | { |
115 | if (count) { | 115 | if (count) { |
116 | if (!nowayout) { | 116 | if (!nowayout) { |
@@ -131,9 +131,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp | |||
131 | return count; | 131 | return count; |
132 | } | 132 | } |
133 | 133 | ||
134 | static int | 134 | static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
135 | advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
136 | unsigned long arg) | ||
137 | { | 135 | { |
138 | int new_timeout; | 136 | int new_timeout; |
139 | void __user *argp = (void __user *)arg; | 137 | void __user *argp = (void __user *)arg; |
@@ -146,57 +144,50 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
146 | 144 | ||
147 | switch (cmd) { | 145 | switch (cmd) { |
148 | case WDIOC_GETSUPPORT: | 146 | case WDIOC_GETSUPPORT: |
149 | if (copy_to_user(argp, &ident, sizeof(ident))) | 147 | if (copy_to_user(argp, &ident, sizeof(ident))) |
150 | return -EFAULT; | 148 | return -EFAULT; |
151 | break; | 149 | break; |
152 | 150 | ||
153 | case WDIOC_GETSTATUS: | 151 | case WDIOC_GETSTATUS: |
154 | case WDIOC_GETBOOTSTATUS: | 152 | case WDIOC_GETBOOTSTATUS: |
155 | return put_user(0, p); | 153 | return put_user(0, p); |
156 | 154 | ||
157 | case WDIOC_KEEPALIVE: | 155 | case WDIOC_KEEPALIVE: |
158 | advwdt_ping(); | 156 | advwdt_ping(); |
159 | break; | 157 | break; |
160 | 158 | ||
161 | case WDIOC_SETTIMEOUT: | 159 | case WDIOC_SETTIMEOUT: |
162 | if (get_user(new_timeout, p)) | 160 | if (get_user(new_timeout, p)) |
163 | return -EFAULT; | 161 | return -EFAULT; |
164 | if (advwdt_set_heartbeat(new_timeout)) | 162 | if (advwdt_set_heartbeat(new_timeout)) |
165 | return -EINVAL; | 163 | return -EINVAL; |
166 | advwdt_ping(); | 164 | advwdt_ping(); |
167 | /* Fall */ | 165 | /* Fall */ |
168 | |||
169 | case WDIOC_GETTIMEOUT: | 166 | case WDIOC_GETTIMEOUT: |
170 | return put_user(timeout, p); | 167 | return put_user(timeout, p); |
171 | |||
172 | case WDIOC_SETOPTIONS: | 168 | case WDIOC_SETOPTIONS: |
173 | { | 169 | { |
174 | int options, retval = -EINVAL; | 170 | int options, retval = -EINVAL; |
175 | |||
176 | if (get_user(options, p)) | ||
177 | return -EFAULT; | ||
178 | 171 | ||
179 | if (options & WDIOS_DISABLECARD) { | 172 | if (get_user(options, p)) |
180 | advwdt_disable(); | 173 | return -EFAULT; |
181 | retval = 0; | 174 | if (options & WDIOS_DISABLECARD) { |
182 | } | 175 | advwdt_disable(); |
183 | 176 | retval = 0; | |
184 | if (options & WDIOS_ENABLECARD) { | 177 | } |
185 | advwdt_ping(); | 178 | if (options & WDIOS_ENABLECARD) { |
186 | retval = 0; | 179 | advwdt_ping(); |
187 | } | 180 | retval = 0; |
188 | 181 | } | |
189 | return retval; | 182 | return retval; |
190 | } | 183 | } |
191 | |||
192 | default: | 184 | default: |
193 | return -ENOTTY; | 185 | return -ENOTTY; |
194 | } | 186 | } |
195 | return 0; | 187 | return 0; |
196 | } | 188 | } |
197 | 189 | ||
198 | static int | 190 | static int advwdt_open(struct inode *inode, struct file *file) |
199 | advwdt_open(struct inode *inode, struct file *file) | ||
200 | { | 191 | { |
201 | if (test_and_set_bit(0, &advwdt_is_open)) | 192 | if (test_and_set_bit(0, &advwdt_is_open)) |
202 | return -EBUSY; | 193 | return -EBUSY; |
@@ -214,7 +205,8 @@ advwdt_close(struct inode *inode, struct file *file) | |||
214 | if (adv_expect_close == 42) { | 205 | if (adv_expect_close == 42) { |
215 | advwdt_disable(); | 206 | advwdt_disable(); |
216 | } else { | 207 | } else { |
217 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 208 | printk(KERN_CRIT PFX |
209 | "Unexpected close, not stopping watchdog!\n"); | ||
218 | advwdt_ping(); | 210 | advwdt_ping(); |
219 | } | 211 | } |
220 | clear_bit(0, &advwdt_is_open); | 212 | clear_bit(0, &advwdt_is_open); |
@@ -230,7 +222,7 @@ static const struct file_operations advwdt_fops = { | |||
230 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
231 | .llseek = no_llseek, | 223 | .llseek = no_llseek, |
232 | .write = advwdt_write, | 224 | .write = advwdt_write, |
233 | .ioctl = advwdt_ioctl, | 225 | .unlocked_ioctl = advwdt_ioctl, |
234 | .open = advwdt_open, | 226 | .open = advwdt_open, |
235 | .release = advwdt_close, | 227 | .release = advwdt_close, |
236 | }; | 228 | }; |
@@ -245,23 +237,24 @@ static struct miscdevice advwdt_miscdev = { | |||
245 | * Init & exit routines | 237 | * Init & exit routines |
246 | */ | 238 | */ |
247 | 239 | ||
248 | static int __devinit | 240 | static int __devinit advwdt_probe(struct platform_device *dev) |
249 | advwdt_probe(struct platform_device *dev) | ||
250 | { | 241 | { |
251 | int ret; | 242 | int ret; |
252 | 243 | ||
253 | if (wdt_stop != wdt_start) { | 244 | if (wdt_stop != wdt_start) { |
254 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { | 245 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { |
255 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 246 | printk(KERN_ERR PFX |
256 | wdt_stop); | 247 | "I/O address 0x%04x already in use\n", |
248 | wdt_stop); | ||
257 | ret = -EIO; | 249 | ret = -EIO; |
258 | goto out; | 250 | goto out; |
259 | } | 251 | } |
260 | } | 252 | } |
261 | 253 | ||
262 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { | 254 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { |
263 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 255 | printk(KERN_ERR PFX |
264 | wdt_start); | 256 | "I/O address 0x%04x already in use\n", |
257 | wdt_start); | ||
265 | ret = -EIO; | 258 | ret = -EIO; |
266 | goto unreg_stop; | 259 | goto unreg_stop; |
267 | } | 260 | } |
@@ -269,20 +262,19 @@ advwdt_probe(struct platform_device *dev) | |||
269 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 262 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ |
270 | if (advwdt_set_heartbeat(timeout)) { | 263 | if (advwdt_set_heartbeat(timeout)) { |
271 | advwdt_set_heartbeat(WATCHDOG_TIMEOUT); | 264 | advwdt_set_heartbeat(WATCHDOG_TIMEOUT); |
272 | printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", | 265 | printk(KERN_INFO PFX |
273 | timeout); | 266 | "timeout value must be 1<=x<=63, using %d\n", timeout); |
274 | } | 267 | } |
275 | 268 | ||
276 | ret = misc_register(&advwdt_miscdev); | 269 | ret = misc_register(&advwdt_miscdev); |
277 | if (ret != 0) { | 270 | if (ret != 0) { |
278 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 271 | printk(KERN_ERR PFX |
279 | WATCHDOG_MINOR, ret); | 272 | "cannot register miscdev on minor=%d (err=%d)\n", |
273 | WATCHDOG_MINOR, ret); | ||
280 | goto unreg_regions; | 274 | goto unreg_regions; |
281 | } | 275 | } |
282 | 276 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | |
283 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | ||
284 | timeout, nowayout); | 277 | timeout, nowayout); |
285 | |||
286 | out: | 278 | out: |
287 | return ret; | 279 | return ret; |
288 | unreg_regions: | 280 | unreg_regions: |
@@ -293,8 +285,7 @@ unreg_stop: | |||
293 | goto out; | 285 | goto out; |
294 | } | 286 | } |
295 | 287 | ||
296 | static int __devexit | 288 | static int __devexit advwdt_remove(struct platform_device *dev) |
297 | advwdt_remove(struct platform_device *dev) | ||
298 | { | 289 | { |
299 | misc_deregister(&advwdt_miscdev); | 290 | misc_deregister(&advwdt_miscdev); |
300 | release_region(wdt_start,1); | 291 | release_region(wdt_start,1); |
@@ -304,8 +295,7 @@ advwdt_remove(struct platform_device *dev) | |||
304 | return 0; | 295 | return 0; |
305 | } | 296 | } |
306 | 297 | ||
307 | static void | 298 | static void advwdt_shutdown(struct platform_device *dev) |
308 | advwdt_shutdown(struct platform_device *dev) | ||
309 | { | 299 | { |
310 | /* Turn the WDT off if we have a soft shutdown */ | 300 | /* Turn the WDT off if we have a soft shutdown */ |
311 | advwdt_disable(); | 301 | advwdt_disable(); |
@@ -321,8 +311,7 @@ static struct platform_driver advwdt_driver = { | |||
321 | }, | 311 | }, |
322 | }; | 312 | }; |
323 | 313 | ||
324 | static int __init | 314 | static int __init advwdt_init(void) |
325 | advwdt_init(void) | ||
326 | { | 315 | { |
327 | int err; | 316 | int err; |
328 | 317 | ||
@@ -332,7 +321,8 @@ advwdt_init(void) | |||
332 | if (err) | 321 | if (err) |
333 | return err; | 322 | return err; |
334 | 323 | ||
335 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 324 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, |
325 | -1, NULL, 0); | ||
336 | if (IS_ERR(advwdt_platform_device)) { | 326 | if (IS_ERR(advwdt_platform_device)) { |
337 | err = PTR_ERR(advwdt_platform_device); | 327 | err = PTR_ERR(advwdt_platform_device); |
338 | goto unreg_platform_driver; | 328 | goto unreg_platform_driver; |
@@ -345,8 +335,7 @@ unreg_platform_driver: | |||
345 | return err; | 335 | return err; |
346 | } | 336 | } |
347 | 337 | ||
348 | static void __exit | 338 | static void __exit advwdt_exit(void) |
349 | advwdt_exit(void) | ||
350 | { | 339 | { |
351 | platform_device_unregister(advwdt_platform_device); | 340 | platform_device_unregister(advwdt_platform_device); |
352 | platform_driver_unregister(&advwdt_driver); | 341 | platform_driver_unregister(&advwdt_driver); |
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index 2b1fbdb2fcf7..88760cb5ec13 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | 21 | ||
22 | #include <asm/uaccess.h> | 22 | #include <linux/uaccess.h> |
23 | #include <asm/io.h> | 23 | #include <linux/io.h> |
24 | 24 | ||
25 | #define WATCHDOG_NAME "ALi_M1535" | 25 | #define WATCHDOG_NAME "ALi_M1535" |
26 | #define PFX WATCHDOG_NAME ": " | 26 | #define PFX WATCHDOG_NAME ": " |
@@ -30,17 +30,21 @@ | |||
30 | static unsigned long ali_is_open; | 30 | static unsigned long ali_is_open; |
31 | static char ali_expect_release; | 31 | static char ali_expect_release; |
32 | static struct pci_dev *ali_pci; | 32 | static struct pci_dev *ali_pci; |
33 | static u32 ali_timeout_bits; /* stores the computed timeout */ | 33 | static u32 ali_timeout_bits; /* stores the computed timeout */ |
34 | static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ | 34 | static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ |
35 | 35 | ||
36 | /* module parameters */ | 36 | /* module parameters */ |
37 | static int timeout = WATCHDOG_TIMEOUT; | 37 | static int timeout = WATCHDOG_TIMEOUT; |
38 | module_param(timeout, int, 0); | 38 | module_param(timeout, int, 0); |
39 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 39 | MODULE_PARM_DESC(timeout, |
40 | "Watchdog timeout in seconds. (0 < timeout < 18000, default=" | ||
41 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
40 | 42 | ||
41 | static int nowayout = WATCHDOG_NOWAYOUT; | 43 | static int nowayout = WATCHDOG_NOWAYOUT; |
42 | module_param(nowayout, int, 0); | 44 | module_param(nowayout, int, 0); |
43 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 45 | MODULE_PARM_DESC(nowayout, |
46 | "Watchdog cannot be stopped once started (default=" | ||
47 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
44 | 48 | ||
45 | /* | 49 | /* |
46 | * ali_start - start watchdog countdown | 50 | * ali_start - start watchdog countdown |
@@ -103,15 +107,16 @@ static void ali_keepalive(void) | |||
103 | 107 | ||
104 | static int ali_settimer(int t) | 108 | static int ali_settimer(int t) |
105 | { | 109 | { |
106 | if(t < 0) | 110 | if (t < 0) |
107 | return -EINVAL; | 111 | return -EINVAL; |
108 | else if(t < 60) | 112 | else if (t < 60) |
109 | ali_timeout_bits = t|(1<<6); | 113 | ali_timeout_bits = t|(1<<6); |
110 | else if(t < 3600) | 114 | else if (t < 3600) |
111 | ali_timeout_bits = (t/60)|(1<<7); | 115 | ali_timeout_bits = (t/60)|(1<<7); |
112 | else if(t < 18000) | 116 | else if (t < 18000) |
113 | ali_timeout_bits = (t/300)|(1<<6)|(1<<7); | 117 | ali_timeout_bits = (t/300)|(1<<6)|(1<<7); |
114 | else return -EINVAL; | 118 | else |
119 | return -EINVAL; | ||
115 | 120 | ||
116 | timeout = t; | 121 | timeout = t; |
117 | return 0; | 122 | return 0; |
@@ -134,21 +139,22 @@ static int ali_settimer(int t) | |||
134 | */ | 139 | */ |
135 | 140 | ||
136 | static ssize_t ali_write(struct file *file, const char __user *data, | 141 | static ssize_t ali_write(struct file *file, const char __user *data, |
137 | size_t len, loff_t * ppos) | 142 | size_t len, loff_t *ppos) |
138 | { | 143 | { |
139 | /* See if we got the magic character 'V' and reload the timer */ | 144 | /* See if we got the magic character 'V' and reload the timer */ |
140 | if (len) { | 145 | if (len) { |
141 | if (!nowayout) { | 146 | if (!nowayout) { |
142 | size_t i; | 147 | size_t i; |
143 | 148 | ||
144 | /* note: just in case someone wrote the magic character | 149 | /* note: just in case someone wrote the |
145 | * five months ago... */ | 150 | magic character five months ago... */ |
146 | ali_expect_release = 0; | 151 | ali_expect_release = 0; |
147 | 152 | ||
148 | /* scan to see whether or not we got the magic character */ | 153 | /* scan to see whether or not we got |
154 | the magic character */ | ||
149 | for (i = 0; i != len; i++) { | 155 | for (i = 0; i != len; i++) { |
150 | char c; | 156 | char c; |
151 | if(get_user(c, data+i)) | 157 | if (get_user(c, data+i)) |
152 | return -EFAULT; | 158 | return -EFAULT; |
153 | if (c == 'V') | 159 | if (c == 'V') |
154 | ali_expect_release = 42; | 160 | ali_expect_release = 42; |
@@ -163,7 +169,6 @@ static ssize_t ali_write(struct file *file, const char __user *data, | |||
163 | 169 | ||
164 | /* | 170 | /* |
165 | * ali_ioctl - handle watchdog ioctls | 171 | * ali_ioctl - handle watchdog ioctls |
166 | * @inode: VFS inode | ||
167 | * @file: VFS file pointer | 172 | * @file: VFS file pointer |
168 | * @cmd: ioctl number | 173 | * @cmd: ioctl number |
169 | * @arg: arguments to the ioctl | 174 | * @arg: arguments to the ioctl |
@@ -172,8 +177,7 @@ static ssize_t ali_write(struct file *file, const char __user *data, | |||
172 | * we want an extension to enable irq ack monitoring and the like | 177 | * we want an extension to enable irq ack monitoring and the like |
173 | */ | 178 | */ |
174 | 179 | ||
175 | static int ali_ioctl(struct inode *inode, struct file *file, | 180 | static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
176 | unsigned int cmd, unsigned long arg) | ||
177 | { | 181 | { |
178 | void __user *argp = (void __user *)arg; | 182 | void __user *argp = (void __user *)arg; |
179 | int __user *p = argp; | 183 | int __user *p = argp; |
@@ -186,57 +190,45 @@ static int ali_ioctl(struct inode *inode, struct file *file, | |||
186 | }; | 190 | }; |
187 | 191 | ||
188 | switch (cmd) { | 192 | switch (cmd) { |
189 | case WDIOC_GETSUPPORT: | 193 | case WDIOC_GETSUPPORT: |
190 | return copy_to_user(argp, &ident, | 194 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
191 | sizeof (ident)) ? -EFAULT : 0; | ||
192 | |||
193 | case WDIOC_GETSTATUS: | ||
194 | case WDIOC_GETBOOTSTATUS: | ||
195 | return put_user(0, p); | ||
196 | |||
197 | case WDIOC_KEEPALIVE: | ||
198 | ali_keepalive(); | ||
199 | return 0; | ||
200 | |||
201 | case WDIOC_SETOPTIONS: | ||
202 | { | ||
203 | int new_options, retval = -EINVAL; | ||
204 | |||
205 | if (get_user (new_options, p)) | ||
206 | return -EFAULT; | ||
207 | |||
208 | if (new_options & WDIOS_DISABLECARD) { | ||
209 | ali_stop(); | ||
210 | retval = 0; | ||
211 | } | ||
212 | |||
213 | if (new_options & WDIOS_ENABLECARD) { | ||
214 | ali_start(); | ||
215 | retval = 0; | ||
216 | } | ||
217 | 195 | ||
218 | return retval; | 196 | case WDIOC_GETSTATUS: |
197 | case WDIOC_GETBOOTSTATUS: | ||
198 | return put_user(0, p); | ||
199 | case WDIOC_KEEPALIVE: | ||
200 | ali_keepalive(); | ||
201 | return 0; | ||
202 | case WDIOC_SETOPTIONS: | ||
203 | { | ||
204 | int new_options, retval = -EINVAL; | ||
205 | |||
206 | if (get_user(new_options, p)) | ||
207 | return -EFAULT; | ||
208 | if (new_options & WDIOS_DISABLECARD) { | ||
209 | ali_stop(); | ||
210 | retval = 0; | ||
219 | } | 211 | } |
220 | 212 | if (new_options & WDIOS_ENABLECARD) { | |
221 | case WDIOC_SETTIMEOUT: | 213 | ali_start(); |
222 | { | 214 | retval = 0; |
223 | int new_timeout; | ||
224 | |||
225 | if (get_user(new_timeout, p)) | ||
226 | return -EFAULT; | ||
227 | |||
228 | if (ali_settimer(new_timeout)) | ||
229 | return -EINVAL; | ||
230 | |||
231 | ali_keepalive(); | ||
232 | /* Fall */ | ||
233 | } | 215 | } |
234 | 216 | return retval; | |
235 | case WDIOC_GETTIMEOUT: | 217 | } |
236 | return put_user(timeout, p); | 218 | case WDIOC_SETTIMEOUT: |
237 | 219 | { | |
238 | default: | 220 | int new_timeout; |
239 | return -ENOTTY; | 221 | if (get_user(new_timeout, p)) |
222 | return -EFAULT; | ||
223 | if (ali_settimer(new_timeout)) | ||
224 | return -EINVAL; | ||
225 | ali_keepalive(); | ||
226 | /* Fall */ | ||
227 | } | ||
228 | case WDIOC_GETTIMEOUT: | ||
229 | return put_user(timeout, p); | ||
230 | default: | ||
231 | return -ENOTTY; | ||
240 | } | 232 | } |
241 | } | 233 | } |
242 | 234 | ||
@@ -274,10 +266,11 @@ static int ali_release(struct inode *inode, struct file *file) | |||
274 | /* | 266 | /* |
275 | * Shut off the timer. | 267 | * Shut off the timer. |
276 | */ | 268 | */ |
277 | if (ali_expect_release == 42) { | 269 | if (ali_expect_release == 42) |
278 | ali_stop(); | 270 | ali_stop(); |
279 | } else { | 271 | else { |
280 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 272 | printk(KERN_CRIT PFX |
273 | "Unexpected close, not stopping watchdog!\n"); | ||
281 | ali_keepalive(); | 274 | ali_keepalive(); |
282 | } | 275 | } |
283 | clear_bit(0, &ali_is_open); | 276 | clear_bit(0, &ali_is_open); |
@@ -292,13 +285,11 @@ static int ali_release(struct inode *inode, struct file *file) | |||
292 | */ | 285 | */ |
293 | 286 | ||
294 | 287 | ||
295 | static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 288 | static int ali_notify_sys(struct notifier_block *this, |
289 | unsigned long code, void *unused) | ||
296 | { | 290 | { |
297 | if (code==SYS_DOWN || code==SYS_HALT) { | 291 | if (code == SYS_DOWN || code == SYS_HALT) |
298 | /* Turn the WDT off */ | 292 | ali_stop(); /* Turn the WDT off */ |
299 | ali_stop(); | ||
300 | } | ||
301 | |||
302 | return NOTIFY_DONE; | 293 | return NOTIFY_DONE; |
303 | } | 294 | } |
304 | 295 | ||
@@ -340,10 +331,10 @@ static int __init ali_find_watchdog(void) | |||
340 | 331 | ||
341 | /* Check for the a 7101 PMU */ | 332 | /* Check for the a 7101 PMU */ |
342 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); | 333 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); |
343 | if(pdev == NULL) | 334 | if (pdev == NULL) |
344 | return -ENODEV; | 335 | return -ENODEV; |
345 | 336 | ||
346 | if(pci_enable_device(pdev)) { | 337 | if (pci_enable_device(pdev)) { |
347 | pci_dev_put(pdev); | 338 | pci_dev_put(pdev); |
348 | return -EIO; | 339 | return -EIO; |
349 | } | 340 | } |
@@ -355,9 +346,12 @@ static int __init ali_find_watchdog(void) | |||
355 | */ | 346 | */ |
356 | pci_read_config_dword(pdev, 0xCC, &wdog); | 347 | pci_read_config_dword(pdev, 0xCC, &wdog); |
357 | 348 | ||
358 | wdog &= ~0x3F; /* Timer bits */ | 349 | /* Timer bits */ |
359 | wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ | 350 | wdog &= ~0x3F; |
360 | wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ | 351 | /* Issued events */ |
352 | wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); | ||
353 | /* No monitor bits */ | ||
354 | wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); | ||
361 | 355 | ||
362 | pci_write_config_dword(pdev, 0xCC, wdog); | 356 | pci_write_config_dword(pdev, 0xCC, wdog); |
363 | 357 | ||
@@ -369,12 +363,12 @@ static int __init ali_find_watchdog(void) | |||
369 | */ | 363 | */ |
370 | 364 | ||
371 | static const struct file_operations ali_fops = { | 365 | static const struct file_operations ali_fops = { |
372 | .owner = THIS_MODULE, | 366 | .owner = THIS_MODULE, |
373 | .llseek = no_llseek, | 367 | .llseek = no_llseek, |
374 | .write = ali_write, | 368 | .write = ali_write, |
375 | .ioctl = ali_ioctl, | 369 | .unlocked_ioctl = ali_ioctl, |
376 | .open = ali_open, | 370 | .open = ali_open, |
377 | .release = ali_release, | 371 | .release = ali_release, |
378 | }; | 372 | }; |
379 | 373 | ||
380 | static struct miscdevice ali_miscdev = { | 374 | static struct miscdevice ali_miscdev = { |
@@ -399,15 +393,16 @@ static int __init watchdog_init(void) | |||
399 | int ret; | 393 | int ret; |
400 | 394 | ||
401 | /* Check whether or not the hardware watchdog is there */ | 395 | /* Check whether or not the hardware watchdog is there */ |
402 | if (ali_find_watchdog() != 0) { | 396 | if (ali_find_watchdog() != 0) |
403 | return -ENODEV; | 397 | return -ENODEV; |
404 | } | ||
405 | 398 | ||
406 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 399 | /* Check that the timeout value is within it's range; |
400 | if not reset to the default */ | ||
407 | if (timeout < 1 || timeout >= 18000) { | 401 | if (timeout < 1 || timeout >= 18000) { |
408 | timeout = WATCHDOG_TIMEOUT; | 402 | timeout = WATCHDOG_TIMEOUT; |
409 | printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", | 403 | printk(KERN_INFO PFX |
410 | timeout); | 404 | "timeout value must be 0 < timeout < 18000, using %d\n", |
405 | timeout); | ||
411 | } | 406 | } |
412 | 407 | ||
413 | /* Calculate the watchdog's timeout */ | 408 | /* Calculate the watchdog's timeout */ |
@@ -415,15 +410,16 @@ static int __init watchdog_init(void) | |||
415 | 410 | ||
416 | ret = register_reboot_notifier(&ali_notifier); | 411 | ret = register_reboot_notifier(&ali_notifier); |
417 | if (ret != 0) { | 412 | if (ret != 0) { |
418 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 413 | printk(KERN_ERR PFX |
419 | ret); | 414 | "cannot register reboot notifier (err=%d)\n", ret); |
420 | goto out; | 415 | goto out; |
421 | } | 416 | } |
422 | 417 | ||
423 | ret = misc_register(&ali_miscdev); | 418 | ret = misc_register(&ali_miscdev); |
424 | if (ret != 0) { | 419 | if (ret != 0) { |
425 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 420 | printk(KERN_ERR PFX |
426 | WATCHDOG_MINOR, ret); | 421 | "cannot register miscdev on minor=%d (err=%d)\n", |
422 | WATCHDOG_MINOR, ret); | ||
427 | goto unreg_reboot; | 423 | goto unreg_reboot; |
428 | } | 424 | } |
429 | 425 | ||
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index 238273c98656..c495f36c6aa9 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | 34 | ||
35 | #include <asm/io.h> | 35 | #include <linux/io.h> |
36 | #include <asm/uaccess.h> | 36 | #include <linux/uaccess.h> |
37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
38 | 38 | ||
39 | #define OUR_NAME "alim7101_wdt" | 39 | #define OUR_NAME "alim7101_wdt" |
@@ -60,13 +60,17 @@ | |||
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 62 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
63 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 63 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
64 | static int timeout = WATCHDOG_TIMEOUT; | ||
64 | module_param(timeout, int, 0); | 65 | module_param(timeout, int, 0); |
65 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 66 | MODULE_PARM_DESC(timeout, |
67 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
68 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
66 | 69 | ||
67 | static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ | 70 | static int use_gpio; /* Use the pic (for a1d revision alim7101) */ |
68 | module_param(use_gpio, int, 0); | 71 | module_param(use_gpio, int, 0); |
69 | MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); | 72 | MODULE_PARM_DESC(use_gpio, |
73 | "Use the gpio watchdog (required by old cobalt boards)."); | ||
70 | 74 | ||
71 | static void wdt_timer_ping(unsigned long); | 75 | static void wdt_timer_ping(unsigned long); |
72 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); | 76 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); |
@@ -77,8 +81,9 @@ static struct pci_dev *alim7101_pmu; | |||
77 | 81 | ||
78 | static int nowayout = WATCHDOG_NOWAYOUT; | 82 | static int nowayout = WATCHDOG_NOWAYOUT; |
79 | module_param(nowayout, int, 0); | 83 | module_param(nowayout, int, 0); |
80 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 84 | MODULE_PARM_DESC(nowayout, |
81 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 85 | "Watchdog cannot be stopped once started (default=" |
86 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
82 | 87 | ||
83 | /* | 88 | /* |
84 | * Whack the dog | 89 | * Whack the dog |
@@ -89,23 +94,26 @@ static void wdt_timer_ping(unsigned long data) | |||
89 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 94 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
90 | * we agree to ping the WDT | 95 | * we agree to ping the WDT |
91 | */ | 96 | */ |
92 | char tmp; | 97 | char tmp; |
93 | 98 | ||
94 | if(time_before(jiffies, next_heartbeat)) | 99 | if (time_before(jiffies, next_heartbeat)) { |
95 | { | ||
96 | /* Ping the WDT (this is actually a disarm/arm sequence) */ | 100 | /* Ping the WDT (this is actually a disarm/arm sequence) */ |
97 | pci_read_config_byte(alim7101_pmu, 0x92, &tmp); | 101 | pci_read_config_byte(alim7101_pmu, 0x92, &tmp); |
98 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | 102 | pci_write_config_byte(alim7101_pmu, |
99 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | 103 | ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); |
104 | pci_write_config_byte(alim7101_pmu, | ||
105 | ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | ||
100 | if (use_gpio) { | 106 | if (use_gpio) { |
101 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 107 | pci_read_config_byte(alim7101_pmu, |
102 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 108 | ALI_7101_GPIO_O, &tmp); |
103 | | 0x20); | 109 | pci_write_config_byte(alim7101_pmu, |
104 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 110 | ALI_7101_GPIO_O, tmp | 0x20); |
105 | & ~0x20); | 111 | pci_write_config_byte(alim7101_pmu, |
112 | ALI_7101_GPIO_O, tmp & ~0x20); | ||
106 | } | 113 | } |
107 | } else { | 114 | } else { |
108 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 115 | printk(KERN_WARNING PFX |
116 | "Heartbeat lost! Will not ping the watchdog\n"); | ||
109 | } | 117 | } |
110 | /* Re-set the timer interval */ | 118 | /* Re-set the timer interval */ |
111 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 119 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
@@ -121,17 +129,23 @@ static void wdt_change(int writeval) | |||
121 | 129 | ||
122 | pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); | 130 | pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); |
123 | if (writeval == WDT_ENABLE) { | 131 | if (writeval == WDT_ENABLE) { |
124 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | 132 | pci_write_config_byte(alim7101_pmu, |
133 | ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | ||
125 | if (use_gpio) { | 134 | if (use_gpio) { |
126 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 135 | pci_read_config_byte(alim7101_pmu, |
127 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); | 136 | ALI_7101_GPIO_O, &tmp); |
137 | pci_write_config_byte(alim7101_pmu, | ||
138 | ALI_7101_GPIO_O, tmp & ~0x20); | ||
128 | } | 139 | } |
129 | 140 | ||
130 | } else { | 141 | } else { |
131 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | 142 | pci_write_config_byte(alim7101_pmu, |
143 | ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | ||
132 | if (use_gpio) { | 144 | if (use_gpio) { |
133 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 145 | pci_read_config_byte(alim7101_pmu, |
134 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); | 146 | ALI_7101_GPIO_O, &tmp); |
147 | pci_write_config_byte(alim7101_pmu, | ||
148 | ALI_7101_GPIO_O, tmp | 0x20); | ||
135 | } | 149 | } |
136 | } | 150 | } |
137 | } | 151 | } |
@@ -169,10 +183,11 @@ static void wdt_keepalive(void) | |||
169 | * /dev/watchdog handling | 183 | * /dev/watchdog handling |
170 | */ | 184 | */ |
171 | 185 | ||
172 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 186 | static ssize_t fop_write(struct file *file, const char __user *buf, |
187 | size_t count, loff_t *ppos) | ||
173 | { | 188 | { |
174 | /* See if we got the magic character 'V' and reload the timer */ | 189 | /* See if we got the magic character 'V' and reload the timer */ |
175 | if(count) { | 190 | if (count) { |
176 | if (!nowayout) { | 191 | if (!nowayout) { |
177 | size_t ofs; | 192 | size_t ofs; |
178 | 193 | ||
@@ -195,119 +210,116 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
195 | return count; | 210 | return count; |
196 | } | 211 | } |
197 | 212 | ||
198 | static int fop_open(struct inode * inode, struct file * file) | 213 | static int fop_open(struct inode *inode, struct file *file) |
199 | { | 214 | { |
200 | /* Just in case we're already talking to someone... */ | 215 | /* Just in case we're already talking to someone... */ |
201 | if(test_and_set_bit(0, &wdt_is_open)) | 216 | if (test_and_set_bit(0, &wdt_is_open)) |
202 | return -EBUSY; | 217 | return -EBUSY; |
203 | /* Good, fire up the show */ | 218 | /* Good, fire up the show */ |
204 | wdt_startup(); | 219 | wdt_startup(); |
205 | return nonseekable_open(inode, file); | 220 | return nonseekable_open(inode, file); |
206 | } | 221 | } |
207 | 222 | ||
208 | static int fop_close(struct inode * inode, struct file * file) | 223 | static int fop_close(struct inode *inode, struct file *file) |
209 | { | 224 | { |
210 | if(wdt_expect_close == 42) | 225 | if (wdt_expect_close == 42) |
211 | wdt_turnoff(); | 226 | wdt_turnoff(); |
212 | else { | 227 | else { |
213 | /* wim: shouldn't there be a: del_timer(&timer); */ | 228 | /* wim: shouldn't there be a: del_timer(&timer); */ |
214 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 229 | printk(KERN_CRIT PFX |
230 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
215 | } | 231 | } |
216 | clear_bit(0, &wdt_is_open); | 232 | clear_bit(0, &wdt_is_open); |
217 | wdt_expect_close = 0; | 233 | wdt_expect_close = 0; |
218 | return 0; | 234 | return 0; |
219 | } | 235 | } |
220 | 236 | ||
221 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 237 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
222 | { | 238 | { |
223 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
224 | int __user *p = argp; | 240 | int __user *p = argp; |
225 | static struct watchdog_info ident = | 241 | static struct watchdog_info ident = { |
226 | { | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
227 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
228 | .firmware_version = 1, | 244 | .firmware_version = 1, |
229 | .identity = "ALiM7101", | 245 | .identity = "ALiM7101", |
230 | }; | 246 | }; |
231 | 247 | ||
232 | switch(cmd) | 248 | switch (cmd) { |
249 | case WDIOC_GETSUPPORT: | ||
250 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
251 | case WDIOC_GETSTATUS: | ||
252 | case WDIOC_GETBOOTSTATUS: | ||
253 | return put_user(0, p); | ||
254 | case WDIOC_KEEPALIVE: | ||
255 | wdt_keepalive(); | ||
256 | return 0; | ||
257 | case WDIOC_SETOPTIONS: | ||
233 | { | 258 | { |
234 | case WDIOC_GETSUPPORT: | 259 | int new_options, retval = -EINVAL; |
235 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | ||
236 | case WDIOC_GETSTATUS: | ||
237 | case WDIOC_GETBOOTSTATUS: | ||
238 | return put_user(0, p); | ||
239 | case WDIOC_KEEPALIVE: | ||
240 | wdt_keepalive(); | ||
241 | return 0; | ||
242 | case WDIOC_SETOPTIONS: | ||
243 | { | ||
244 | int new_options, retval = -EINVAL; | ||
245 | |||
246 | if(get_user(new_options, p)) | ||
247 | return -EFAULT; | ||
248 | |||
249 | if(new_options & WDIOS_DISABLECARD) { | ||
250 | wdt_turnoff(); | ||
251 | retval = 0; | ||
252 | } | ||
253 | |||
254 | if(new_options & WDIOS_ENABLECARD) { | ||
255 | wdt_startup(); | ||
256 | retval = 0; | ||
257 | } | ||
258 | 260 | ||
259 | return retval; | 261 | if (get_user(new_options, p)) |
262 | return -EFAULT; | ||
263 | if (new_options & WDIOS_DISABLECARD) { | ||
264 | wdt_turnoff(); | ||
265 | retval = 0; | ||
260 | } | 266 | } |
261 | case WDIOC_SETTIMEOUT: | 267 | if (new_options & WDIOS_ENABLECARD) { |
262 | { | 268 | wdt_startup(); |
263 | int new_timeout; | 269 | retval = 0; |
264 | |||
265 | if(get_user(new_timeout, p)) | ||
266 | return -EFAULT; | ||
267 | |||
268 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | ||
269 | return -EINVAL; | ||
270 | |||
271 | timeout = new_timeout; | ||
272 | wdt_keepalive(); | ||
273 | /* Fall through */ | ||
274 | } | 270 | } |
275 | case WDIOC_GETTIMEOUT: | 271 | return retval; |
276 | return put_user(timeout, p); | 272 | } |
277 | default: | 273 | case WDIOC_SETTIMEOUT: |
278 | return -ENOTTY; | 274 | { |
275 | int new_timeout; | ||
276 | |||
277 | if (get_user(new_timeout, p)) | ||
278 | return -EFAULT; | ||
279 | /* arbitrary upper limit */ | ||
280 | if (new_timeout < 1 || new_timeout > 3600) | ||
281 | return -EINVAL; | ||
282 | timeout = new_timeout; | ||
283 | wdt_keepalive(); | ||
284 | /* Fall through */ | ||
285 | } | ||
286 | case WDIOC_GETTIMEOUT: | ||
287 | return put_user(timeout, p); | ||
288 | default: | ||
289 | return -ENOTTY; | ||
279 | } | 290 | } |
280 | } | 291 | } |
281 | 292 | ||
282 | static const struct file_operations wdt_fops = { | 293 | static const struct file_operations wdt_fops = { |
283 | .owner= THIS_MODULE, | 294 | .owner = THIS_MODULE, |
284 | .llseek= no_llseek, | 295 | .llseek = no_llseek, |
285 | .write= fop_write, | 296 | .write = fop_write, |
286 | .open= fop_open, | 297 | .open = fop_open, |
287 | .release= fop_close, | 298 | .release = fop_close, |
288 | .ioctl= fop_ioctl, | 299 | .unlocked_ioctl = fop_ioctl, |
289 | }; | 300 | }; |
290 | 301 | ||
291 | static struct miscdevice wdt_miscdev = { | 302 | static struct miscdevice wdt_miscdev = { |
292 | .minor=WATCHDOG_MINOR, | 303 | .minor = WATCHDOG_MINOR, |
293 | .name="watchdog", | 304 | .name = "watchdog", |
294 | .fops=&wdt_fops, | 305 | .fops = &wdt_fops, |
295 | }; | 306 | }; |
296 | 307 | ||
297 | /* | 308 | /* |
298 | * Notifier for system down | 309 | * Notifier for system down |
299 | */ | 310 | */ |
300 | 311 | ||
301 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 312 | static int wdt_notify_sys(struct notifier_block *this, |
313 | unsigned long code, void *unused) | ||
302 | { | 314 | { |
303 | if (code==SYS_DOWN || code==SYS_HALT) | 315 | if (code == SYS_DOWN || code == SYS_HALT) |
304 | wdt_turnoff(); | 316 | wdt_turnoff(); |
305 | 317 | ||
306 | if (code==SYS_RESTART) { | 318 | if (code == SYS_RESTART) { |
307 | /* | 319 | /* |
308 | * Cobalt devices have no way of rebooting themselves other than | 320 | * Cobalt devices have no way of rebooting themselves other |
309 | * getting the watchdog to pull reset, so we restart the watchdog on | 321 | * than getting the watchdog to pull reset, so we restart the |
310 | * reboot with no heartbeat | 322 | * watchdog on reboot with no heartbeat |
311 | */ | 323 | */ |
312 | wdt_change(WDT_ENABLE); | 324 | wdt_change(WDT_ENABLE); |
313 | printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); | 325 | printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); |
@@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void | |||
320 | * turn the timebomb registers off. | 332 | * turn the timebomb registers off. |
321 | */ | 333 | */ |
322 | 334 | ||
323 | static struct notifier_block wdt_notifier= | 335 | static struct notifier_block wdt_notifier = { |
324 | { | ||
325 | .notifier_call = wdt_notify_sys, | 336 | .notifier_call = wdt_notify_sys, |
326 | }; | 337 | }; |
327 | 338 | ||
@@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void) | |||
354 | ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, | 365 | ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, |
355 | NULL); | 366 | NULL); |
356 | if (!ali1543_south) { | 367 | if (!ali1543_south) { |
357 | printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); | 368 | printk(KERN_INFO PFX |
369 | "ALi 1543 South-Bridge not present - WDT not set\n"); | ||
358 | goto err_out; | 370 | goto err_out; |
359 | } | 371 | } |
360 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); | 372 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); |
@@ -363,24 +375,25 @@ static int __init alim7101_wdt_init(void) | |||
363 | if (!use_gpio) { | 375 | if (!use_gpio) { |
364 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); | 376 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); |
365 | goto err_out; | 377 | goto err_out; |
366 | } | 378 | } |
367 | nowayout = 1; | 379 | nowayout = 1; |
368 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { | 380 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { |
369 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); | 381 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); |
370 | goto err_out; | 382 | goto err_out; |
371 | } | 383 | } |
372 | 384 | ||
373 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 385 | if (timeout < 1 || timeout > 3600) { |
374 | { | 386 | /* arbitrary upper limit */ |
375 | timeout = WATCHDOG_TIMEOUT; | 387 | timeout = WATCHDOG_TIMEOUT; |
376 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 388 | printk(KERN_INFO PFX |
377 | timeout); | 389 | "timeout value must be 1 <= x <= 3600, using %d\n", |
390 | timeout); | ||
378 | } | 391 | } |
379 | 392 | ||
380 | rc = register_reboot_notifier(&wdt_notifier); | 393 | rc = register_reboot_notifier(&wdt_notifier); |
381 | if (rc) { | 394 | if (rc) { |
382 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 395 | printk(KERN_ERR PFX |
383 | rc); | 396 | "cannot register reboot notifier (err=%d)\n", rc); |
384 | goto err_out; | 397 | goto err_out; |
385 | } | 398 | } |
386 | 399 | ||
@@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void) | |||
391 | goto err_out_reboot; | 404 | goto err_out_reboot; |
392 | } | 405 | } |
393 | 406 | ||
394 | if (nowayout) { | 407 | if (nowayout) |
395 | __module_get(THIS_MODULE); | 408 | __module_get(THIS_MODULE); |
396 | } | ||
397 | 409 | ||
398 | printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", | 410 | printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", |
399 | timeout, nowayout); | 411 | timeout, nowayout); |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index ae0fca5e8749..c5dc5e912fb2 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -212,8 +212,8 @@ static struct watchdog_info at32_wdt_info = { | |||
212 | /* | 212 | /* |
213 | * Handle commands from user-space. | 213 | * Handle commands from user-space. |
214 | */ | 214 | */ |
215 | static int at32_wdt_ioctl(struct inode *inode, struct file *file, | 215 | static long at32_wdt_ioctl(struct file *file, |
216 | unsigned int cmd, unsigned long arg) | 216 | unsigned int cmd, unsigned long arg) |
217 | { | 217 | { |
218 | int ret = -ENOTTY; | 218 | int ret = -ENOTTY; |
219 | int time; | 219 | int time; |
@@ -298,7 +298,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data, | |||
298 | static const struct file_operations at32_wdt_fops = { | 298 | static const struct file_operations at32_wdt_fops = { |
299 | .owner = THIS_MODULE, | 299 | .owner = THIS_MODULE, |
300 | .llseek = no_llseek, | 300 | .llseek = no_llseek, |
301 | .ioctl = at32_wdt_ioctl, | 301 | .unlocked_ioctl = at32_wdt_ioctl, |
302 | .open = at32_wdt_open, | 302 | .open = at32_wdt_open, |
303 | .release = at32_wdt_close, | 303 | .release = at32_wdt_close, |
304 | .write = at32_wdt_write, | 304 | .write = at32_wdt_write, |
@@ -391,7 +391,6 @@ static int __exit at32_wdt_remove(struct platform_device *pdev) | |||
391 | wdt = NULL; | 391 | wdt = NULL; |
392 | platform_set_drvdata(pdev, NULL); | 392 | platform_set_drvdata(pdev, NULL); |
393 | } | 393 | } |
394 | |||
395 | return 0; | 394 | return 0; |
396 | } | 395 | } |
397 | 396 | ||
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 9ff9a9565320..bb79f649dc7e 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
23 | #include <asm/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <asm/arch/at91_st.h> | 24 | #include <asm/arch/at91_st.h> |
25 | 25 | ||
26 | 26 | ||
@@ -31,11 +31,14 @@ static int wdt_time = WDT_DEFAULT_TIME; | |||
31 | static int nowayout = WATCHDOG_NOWAYOUT; | 31 | static int nowayout = WATCHDOG_NOWAYOUT; |
32 | 32 | ||
33 | module_param(wdt_time, int, 0); | 33 | module_param(wdt_time, int, 0); |
34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | 34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" |
35 | __MODULE_STRING(WDT_DEFAULT_TIME) ")"); | ||
35 | 36 | ||
36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | 37 | #ifdef CONFIG_WATCHDOG_NOWAYOUT |
37 | module_param(nowayout, int, 0); | 38 | module_param(nowayout, int, 0); |
38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 39 | MODULE_PARM_DESC(nowayout, |
40 | "Watchdog cannot be stopped once started (default=" | ||
41 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
39 | #endif | 42 | #endif |
40 | 43 | ||
41 | 44 | ||
@@ -46,7 +49,7 @@ static unsigned long at91wdt_busy; | |||
46 | /* | 49 | /* |
47 | * Disable the watchdog. | 50 | * Disable the watchdog. |
48 | */ | 51 | */ |
49 | static void inline at91_wdt_stop(void) | 52 | static inline void at91_wdt_stop(void) |
50 | { | 53 | { |
51 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); | 54 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); |
52 | } | 55 | } |
@@ -54,16 +57,17 @@ static void inline at91_wdt_stop(void) | |||
54 | /* | 57 | /* |
55 | * Enable and reset the watchdog. | 58 | * Enable and reset the watchdog. |
56 | */ | 59 | */ |
57 | static void inline at91_wdt_start(void) | 60 | static inline void at91_wdt_start(void) |
58 | { | 61 | { |
59 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); | 62 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | |
63 | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); | ||
60 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | 64 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); |
61 | } | 65 | } |
62 | 66 | ||
63 | /* | 67 | /* |
64 | * Reload the watchdog timer. (ie, pat the watchdog) | 68 | * Reload the watchdog timer. (ie, pat the watchdog) |
65 | */ | 69 | */ |
66 | static void inline at91_wdt_reload(void) | 70 | static inline void at91_wdt_reload(void) |
67 | { | 71 | { |
68 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | 72 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); |
69 | } | 73 | } |
@@ -89,8 +93,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file) | |||
89 | */ | 93 | */ |
90 | static int at91_wdt_close(struct inode *inode, struct file *file) | 94 | static int at91_wdt_close(struct inode *inode, struct file *file) |
91 | { | 95 | { |
96 | /* Disable the watchdog when file is closed */ | ||
92 | if (!nowayout) | 97 | if (!nowayout) |
93 | at91_wdt_stop(); /* Disable the watchdog when file is closed */ | 98 | at91_wdt_stop(); |
94 | 99 | ||
95 | clear_bit(0, &at91wdt_busy); | 100 | clear_bit(0, &at91wdt_busy); |
96 | return 0; | 101 | return 0; |
@@ -110,7 +115,8 @@ static int at91_wdt_settimeout(int new_time) | |||
110 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) | 115 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) |
111 | return -EINVAL; | 116 | return -EINVAL; |
112 | 117 | ||
113 | /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ | 118 | /* Set new watchdog time. It will be used when |
119 | at91_wdt_start() is called. */ | ||
114 | wdt_time = new_time; | 120 | wdt_time = new_time; |
115 | return 0; | 121 | return 0; |
116 | } | 122 | } |
@@ -123,60 +129,52 @@ static struct watchdog_info at91_wdt_info = { | |||
123 | /* | 129 | /* |
124 | * Handle commands from user-space. | 130 | * Handle commands from user-space. |
125 | */ | 131 | */ |
126 | static int at91_wdt_ioctl(struct inode *inode, struct file *file, | 132 | static long at91_wdt_ioct(struct file *file, |
127 | unsigned int cmd, unsigned long arg) | 133 | unsigned int cmd, unsigned long arg) |
128 | { | 134 | { |
129 | void __user *argp = (void __user *)arg; | 135 | void __user *argp = (void __user *)arg; |
130 | int __user *p = argp; | 136 | int __user *p = argp; |
131 | int new_value; | 137 | int new_value; |
132 | 138 | ||
133 | switch(cmd) { | 139 | switch (cmd) { |
134 | case WDIOC_KEEPALIVE: | 140 | case WDIOC_KEEPALIVE: |
135 | at91_wdt_reload(); /* pat the watchdog */ | 141 | at91_wdt_reload(); /* pat the watchdog */ |
136 | return 0; | 142 | return 0; |
137 | 143 | case WDIOC_GETSUPPORT: | |
138 | case WDIOC_GETSUPPORT: | 144 | return copy_to_user(argp, &at91_wdt_info, |
139 | return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; | 145 | sizeof(at91_wdt_info)) ? -EFAULT : 0; |
140 | 146 | case WDIOC_SETTIMEOUT: | |
141 | case WDIOC_SETTIMEOUT: | 147 | if (get_user(new_value, p)) |
142 | if (get_user(new_value, p)) | 148 | return -EFAULT; |
143 | return -EFAULT; | 149 | if (at91_wdt_settimeout(new_value)) |
144 | 150 | return -EINVAL; | |
145 | if (at91_wdt_settimeout(new_value)) | 151 | /* Enable new time value */ |
146 | return -EINVAL; | 152 | at91_wdt_start(); |
147 | 153 | /* Return current value */ | |
148 | /* Enable new time value */ | 154 | return put_user(wdt_time, p); |
155 | case WDIOC_GETTIMEOUT: | ||
156 | return put_user(wdt_time, p); | ||
157 | case WDIOC_GETSTATUS: | ||
158 | case WDIOC_GETBOOTSTATUS: | ||
159 | return put_user(0, p); | ||
160 | case WDIOC_SETOPTIONS: | ||
161 | if (get_user(new_value, p)) | ||
162 | return -EFAULT; | ||
163 | if (new_value & WDIOS_DISABLECARD) | ||
164 | at91_wdt_stop(); | ||
165 | if (new_value & WDIOS_ENABLECARD) | ||
149 | at91_wdt_start(); | 166 | at91_wdt_start(); |
150 | 167 | return 0; | |
151 | /* Return current value */ | 168 | default: |
152 | return put_user(wdt_time, p); | 169 | return -ENOTTY; |
153 | |||
154 | case WDIOC_GETTIMEOUT: | ||
155 | return put_user(wdt_time, p); | ||
156 | |||
157 | case WDIOC_GETSTATUS: | ||
158 | case WDIOC_GETBOOTSTATUS: | ||
159 | return put_user(0, p); | ||
160 | |||
161 | case WDIOC_SETOPTIONS: | ||
162 | if (get_user(new_value, p)) | ||
163 | return -EFAULT; | ||
164 | |||
165 | if (new_value & WDIOS_DISABLECARD) | ||
166 | at91_wdt_stop(); | ||
167 | if (new_value & WDIOS_ENABLECARD) | ||
168 | at91_wdt_start(); | ||
169 | return 0; | ||
170 | |||
171 | default: | ||
172 | return -ENOTTY; | ||
173 | } | 170 | } |
174 | } | 171 | } |
175 | 172 | ||
176 | /* | 173 | /* |
177 | * Pat the watchdog whenever device is written to. | 174 | * Pat the watchdog whenever device is written to. |
178 | */ | 175 | */ |
179 | static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 176 | static ssize_t at91_wdt_write(struct file *file, const char *data, |
177 | size_t len, loff_t *ppos) | ||
180 | { | 178 | { |
181 | at91_wdt_reload(); /* pat the watchdog */ | 179 | at91_wdt_reload(); /* pat the watchdog */ |
182 | return len; | 180 | return len; |
@@ -187,7 +185,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l | |||
187 | static const struct file_operations at91wdt_fops = { | 185 | static const struct file_operations at91wdt_fops = { |
188 | .owner = THIS_MODULE, | 186 | .owner = THIS_MODULE, |
189 | .llseek = no_llseek, | 187 | .llseek = no_llseek, |
190 | .ioctl = at91_wdt_ioctl, | 188 | .unlocked_ioctl = at91_wdt_ioctl, |
191 | .open = at91_wdt_open, | 189 | .open = at91_wdt_open, |
192 | .release = at91_wdt_close, | 190 | .release = at91_wdt_close, |
193 | .write = at91_wdt_write, | 191 | .write = at91_wdt_write, |
@@ -211,7 +209,8 @@ static int __init at91wdt_probe(struct platform_device *pdev) | |||
211 | if (res) | 209 | if (res) |
212 | return res; | 210 | return res; |
213 | 211 | ||
214 | printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); | 212 | printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n", |
213 | wdt_time, nowayout ? ", nowayout" : ""); | ||
215 | return 0; | 214 | return 0; |
216 | } | 215 | } |
217 | 216 | ||
@@ -265,7 +264,8 @@ static struct platform_driver at91wdt_driver = { | |||
265 | 264 | ||
266 | static int __init at91_wdt_init(void) | 265 | static int __init at91_wdt_init(void) |
267 | { | 266 | { |
268 | /* Check that the heartbeat value is within range; if not reset to the default */ | 267 | /* Check that the heartbeat value is within range; |
268 | if not reset to the default */ | ||
269 | if (at91_wdt_settimeout(wdt_time)) { | 269 | if (at91_wdt_settimeout(wdt_time)) { |
270 | at91_wdt_settimeout(WDT_DEFAULT_TIME); | 270 | at91_wdt_settimeout(WDT_DEFAULT_TIME); |
271 | pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); | 271 | pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 03b3e3d91e7c..2b92818cc664 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <asm/blackfin.h> | 27 | #include <asm/blackfin.h> |
28 | #include <asm/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | 29 | ||
30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) | 30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) |
31 | #define stampit() stamp("here i am") | 31 | #define stampit() stamp("here i am") |
@@ -148,7 +148,8 @@ static int bfin_wdt_set_timeout(unsigned long t) | |||
148 | int run = bfin_wdt_running(); | 148 | int run = bfin_wdt_running(); |
149 | bfin_wdt_stop(); | 149 | bfin_wdt_stop(); |
150 | bfin_write_WDOG_CNT(cnt); | 150 | bfin_write_WDOG_CNT(cnt); |
151 | if (run) bfin_wdt_start(); | 151 | if (run) |
152 | bfin_wdt_start(); | ||
152 | } | 153 | } |
153 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | 154 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); |
154 | 155 | ||
@@ -191,16 +192,15 @@ static int bfin_wdt_release(struct inode *inode, struct file *file) | |||
191 | { | 192 | { |
192 | stampit(); | 193 | stampit(); |
193 | 194 | ||
194 | if (expect_close == 42) { | 195 | if (expect_close == 42) |
195 | bfin_wdt_stop(); | 196 | bfin_wdt_stop(); |
196 | } else { | 197 | else { |
197 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 198 | printk(KERN_CRIT PFX |
199 | "Unexpected close, not stopping watchdog!\n"); | ||
198 | bfin_wdt_keepalive(); | 200 | bfin_wdt_keepalive(); |
199 | } | 201 | } |
200 | |||
201 | expect_close = 0; | 202 | expect_close = 0; |
202 | clear_bit(0, &open_check); | 203 | clear_bit(0, &open_check); |
203 | |||
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | 206 | ||
@@ -214,7 +214,7 @@ static int bfin_wdt_release(struct inode *inode, struct file *file) | |||
214 | * Pings the watchdog on write. | 214 | * Pings the watchdog on write. |
215 | */ | 215 | */ |
216 | static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | 216 | static ssize_t bfin_wdt_write(struct file *file, const char __user *data, |
217 | size_t len, loff_t *ppos) | 217 | size_t len, loff_t *ppos) |
218 | { | 218 | { |
219 | stampit(); | 219 | stampit(); |
220 | 220 | ||
@@ -241,7 +241,6 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | |||
241 | 241 | ||
242 | /** | 242 | /** |
243 | * bfin_wdt_ioctl - Query Device | 243 | * bfin_wdt_ioctl - Query Device |
244 | * @inode: inode of device | ||
245 | * @file: file handle of device | 244 | * @file: file handle of device |
246 | * @cmd: watchdog command | 245 | * @cmd: watchdog command |
247 | * @arg: argument | 246 | * @arg: argument |
@@ -249,8 +248,8 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | |||
249 | * Query basic information from the device or ping it, as outlined by the | 248 | * Query basic information from the device or ping it, as outlined by the |
250 | * watchdog API. | 249 | * watchdog API. |
251 | */ | 250 | */ |
252 | static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | 251 | static long bfin_wdt_ioctl(struct file *file, |
253 | unsigned int cmd, unsigned long arg) | 252 | unsigned int cmd, unsigned long arg) |
254 | { | 253 | { |
255 | void __user *argp = (void __user *)arg; | 254 | void __user *argp = (void __user *)arg; |
256 | int __user *p = argp; | 255 | int __user *p = argp; |
@@ -258,59 +257,49 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | |||
258 | stampit(); | 257 | stampit(); |
259 | 258 | ||
260 | switch (cmd) { | 259 | switch (cmd) { |
261 | default: | 260 | case WDIOC_GETSUPPORT: |
262 | return -ENOTTY; | 261 | if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info))) |
263 | 262 | return -EFAULT; | |
264 | case WDIOC_GETSUPPORT: | 263 | else |
265 | if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info))) | ||
266 | return -EFAULT; | ||
267 | else | ||
268 | return 0; | ||
269 | |||
270 | case WDIOC_GETSTATUS: | ||
271 | case WDIOC_GETBOOTSTATUS: | ||
272 | return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p); | ||
273 | |||
274 | case WDIOC_KEEPALIVE: | ||
275 | bfin_wdt_keepalive(); | ||
276 | return 0; | 264 | return 0; |
277 | 265 | case WDIOC_GETSTATUS: | |
278 | case WDIOC_SETTIMEOUT: { | 266 | case WDIOC_GETBOOTSTATUS: |
279 | int new_timeout; | 267 | return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p); |
280 | 268 | case WDIOC_KEEPALIVE: | |
281 | if (get_user(new_timeout, p)) | 269 | bfin_wdt_keepalive(); |
282 | return -EFAULT; | 270 | return 0; |
283 | 271 | case WDIOC_SETTIMEOUT: { | |
284 | if (bfin_wdt_set_timeout(new_timeout)) | 272 | int new_timeout; |
285 | return -EINVAL; | 273 | |
274 | if (get_user(new_timeout, p)) | ||
275 | return -EFAULT; | ||
276 | if (bfin_wdt_set_timeout(new_timeout)) | ||
277 | return -EINVAL; | ||
278 | } | ||
279 | /* Fall */ | ||
280 | case WDIOC_GETTIMEOUT: | ||
281 | return put_user(timeout, p); | ||
282 | case WDIOC_SETOPTIONS: { | ||
283 | unsigned long flags; | ||
284 | int options, ret = -EINVAL; | ||
285 | |||
286 | if (get_user(options, p)) | ||
287 | return -EFAULT; | ||
288 | |||
289 | spin_lock_irqsave(&bfin_wdt_spinlock, flags); | ||
290 | if (options & WDIOS_DISABLECARD) { | ||
291 | bfin_wdt_stop(); | ||
292 | ret = 0; | ||
286 | } | 293 | } |
287 | /* Fall */ | 294 | if (options & WDIOS_ENABLECARD) { |
288 | case WDIOC_GETTIMEOUT: | 295 | bfin_wdt_start(); |
289 | return put_user(timeout, p); | 296 | ret = 0; |
290 | |||
291 | case WDIOC_SETOPTIONS: { | ||
292 | unsigned long flags; | ||
293 | int options, ret = -EINVAL; | ||
294 | |||
295 | if (get_user(options, p)) | ||
296 | return -EFAULT; | ||
297 | |||
298 | spin_lock_irqsave(&bfin_wdt_spinlock, flags); | ||
299 | |||
300 | if (options & WDIOS_DISABLECARD) { | ||
301 | bfin_wdt_stop(); | ||
302 | ret = 0; | ||
303 | } | ||
304 | |||
305 | if (options & WDIOS_ENABLECARD) { | ||
306 | bfin_wdt_start(); | ||
307 | ret = 0; | ||
308 | } | ||
309 | |||
310 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | ||
311 | |||
312 | return ret; | ||
313 | } | 297 | } |
298 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | ||
299 | return ret; | ||
300 | } | ||
301 | default: | ||
302 | return -ENOTTY; | ||
314 | } | 303 | } |
315 | } | 304 | } |
316 | 305 | ||
@@ -323,8 +312,8 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | |||
323 | * Handles specific events, such as turning off the watchdog during a | 312 | * Handles specific events, such as turning off the watchdog during a |
324 | * shutdown event. | 313 | * shutdown event. |
325 | */ | 314 | */ |
326 | static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code, | 315 | static int bfin_wdt_notify_sys(struct notifier_block *this, |
327 | void *unused) | 316 | unsigned long code, void *unused) |
328 | { | 317 | { |
329 | stampit(); | 318 | stampit(); |
330 | 319 | ||
@@ -379,12 +368,12 @@ static int bfin_wdt_resume(struct platform_device *pdev) | |||
379 | #endif | 368 | #endif |
380 | 369 | ||
381 | static const struct file_operations bfin_wdt_fops = { | 370 | static const struct file_operations bfin_wdt_fops = { |
382 | .owner = THIS_MODULE, | 371 | .owner = THIS_MODULE, |
383 | .llseek = no_llseek, | 372 | .llseek = no_llseek, |
384 | .write = bfin_wdt_write, | 373 | .write = bfin_wdt_write, |
385 | .ioctl = bfin_wdt_ioctl, | 374 | .unlocked_ioctl = bfin_wdt_ioctl, |
386 | .open = bfin_wdt_open, | 375 | .open = bfin_wdt_open, |
387 | .release = bfin_wdt_release, | 376 | .release = bfin_wdt_release, |
388 | }; | 377 | }; |
389 | 378 | ||
390 | static struct miscdevice bfin_wdt_miscdev = { | 379 | static struct miscdevice bfin_wdt_miscdev = { |
@@ -396,8 +385,8 @@ static struct miscdevice bfin_wdt_miscdev = { | |||
396 | static struct watchdog_info bfin_wdt_info = { | 385 | static struct watchdog_info bfin_wdt_info = { |
397 | .identity = "Blackfin Watchdog", | 386 | .identity = "Blackfin Watchdog", |
398 | .options = WDIOF_SETTIMEOUT | | 387 | .options = WDIOF_SETTIMEOUT | |
399 | WDIOF_KEEPALIVEPING | | 388 | WDIOF_KEEPALIVEPING | |
400 | WDIOF_MAGICCLOSE, | 389 | WDIOF_MAGICCLOSE, |
401 | }; | 390 | }; |
402 | 391 | ||
403 | static struct notifier_block bfin_wdt_notifier = { | 392 | static struct notifier_block bfin_wdt_notifier = { |
@@ -416,14 +405,16 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev) | |||
416 | 405 | ||
417 | ret = register_reboot_notifier(&bfin_wdt_notifier); | 406 | ret = register_reboot_notifier(&bfin_wdt_notifier); |
418 | if (ret) { | 407 | if (ret) { |
419 | pr_devinit(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); | 408 | pr_devinit(KERN_ERR PFX |
409 | "cannot register reboot notifier (err=%d)\n", ret); | ||
420 | return ret; | 410 | return ret; |
421 | } | 411 | } |
422 | 412 | ||
423 | ret = misc_register(&bfin_wdt_miscdev); | 413 | ret = misc_register(&bfin_wdt_miscdev); |
424 | if (ret) { | 414 | if (ret) { |
425 | pr_devinit(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 415 | pr_devinit(KERN_ERR PFX |
426 | WATCHDOG_MINOR, ret); | 416 | "cannot register miscdev on minor=%d (err=%d)\n", |
417 | WATCHDOG_MINOR, ret); | ||
427 | unregister_reboot_notifier(&bfin_wdt_notifier); | 418 | unregister_reboot_notifier(&bfin_wdt_notifier); |
428 | return ret; | 419 | return ret; |
429 | } | 420 | } |
@@ -516,7 +507,11 @@ MODULE_LICENSE("GPL"); | |||
516 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 507 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
517 | 508 | ||
518 | module_param(timeout, uint, 0); | 509 | module_param(timeout, uint, 0); |
519 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 510 | MODULE_PARM_DESC(timeout, |
511 | "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" | ||
512 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
520 | 513 | ||
521 | module_param(nowayout, int, 0); | 514 | module_param(nowayout, int, 0); |
522 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 515 | MODULE_PARM_DESC(nowayout, |
516 | "Watchdog cannot be stopped once started (default=" | ||
517 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 770824458d45..06b7a17a60e7 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -18,9 +18,9 @@ | |||
18 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
19 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/uaccess.h> | ||
21 | 22 | ||
22 | #include <asm/reg_booke.h> | 23 | #include <asm/reg_booke.h> |
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/system.h> | 24 | #include <asm/system.h> |
25 | 25 | ||
26 | /* If the kernel parameter wdt=1, the watchdog will be enabled at boot. | 26 | /* If the kernel parameter wdt=1, the watchdog will be enabled at boot. |
@@ -32,7 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #ifdef CONFIG_FSL_BOOKE | 34 | #ifdef CONFIG_FSL_BOOKE |
35 | #define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ | 35 | #define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */ |
36 | #else | 36 | #else |
37 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ | 37 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ |
38 | #endif /* for timing information */ | 38 | #endif /* for timing information */ |
@@ -82,16 +82,15 @@ static struct watchdog_info ident = { | |||
82 | .identity = "PowerPC Book-E Watchdog", | 82 | .identity = "PowerPC Book-E Watchdog", |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static int booke_wdt_ioctl(struct inode *inode, struct file *file, | 85 | static long booke_wdt_ioctl(struct file *file, |
86 | unsigned int cmd, unsigned long arg) | 86 | unsigned int cmd, unsigned long arg) |
87 | { | 87 | { |
88 | u32 tmp = 0; | 88 | u32 tmp = 0; |
89 | u32 __user *p = (u32 __user *)arg; | 89 | u32 __user *p = (u32 __user *)arg; |
90 | 90 | ||
91 | switch (cmd) { | 91 | switch (cmd) { |
92 | case WDIOC_GETSUPPORT: | 92 | case WDIOC_GETSUPPORT: |
93 | if (copy_to_user((struct watchdog_info __user *)arg, &ident, | 93 | if (copy_to_user(arg, &ident, sizeof(struct watchdog_info))) |
94 | sizeof(struct watchdog_info))) | ||
95 | return -EFAULT; | 94 | return -EFAULT; |
96 | case WDIOC_GETSTATUS: | 95 | case WDIOC_GETSTATUS: |
97 | return put_user(ident.options, p); | 96 | return put_user(ident.options, p); |
@@ -106,7 +105,8 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file, | |||
106 | case WDIOC_SETTIMEOUT: | 105 | case WDIOC_SETTIMEOUT: |
107 | if (get_user(booke_wdt_period, p)) | 106 | if (get_user(booke_wdt_period, p)) |
108 | return -EFAULT; | 107 | return -EFAULT; |
109 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period)); | 108 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) | |
109 | WDTP(booke_wdt_period)); | ||
110 | return 0; | 110 | return 0; |
111 | case WDIOC_GETTIMEOUT: | 111 | case WDIOC_GETTIMEOUT: |
112 | return put_user(booke_wdt_period, p); | 112 | return put_user(booke_wdt_period, p); |
@@ -132,8 +132,9 @@ static int booke_wdt_open(struct inode *inode, struct file *file) | |||
132 | if (booke_wdt_enabled == 0) { | 132 | if (booke_wdt_enabled == 0) { |
133 | booke_wdt_enabled = 1; | 133 | booke_wdt_enabled = 1; |
134 | on_each_cpu(__booke_wdt_enable, NULL, 0); | 134 | on_each_cpu(__booke_wdt_enable, NULL, 0); |
135 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " | 135 | printk(KERN_INFO |
136 | "(wdt_period=%d)\n", booke_wdt_period); | 136 | "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", |
137 | booke_wdt_period); | ||
137 | } | 138 | } |
138 | spin_unlock(&booke_wdt_lock); | 139 | spin_unlock(&booke_wdt_lock); |
139 | 140 | ||
@@ -144,7 +145,7 @@ static const struct file_operations booke_wdt_fops = { | |||
144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
145 | .llseek = no_llseek, | 146 | .llseek = no_llseek, |
146 | .write = booke_wdt_write, | 147 | .write = booke_wdt_write, |
147 | .ioctl = booke_wdt_ioctl, | 148 | .unlocked_ioctl = booke_wdt_ioctl, |
148 | .open = booke_wdt_open, | 149 | .open = booke_wdt_open, |
149 | }; | 150 | }; |
150 | 151 | ||
@@ -175,8 +176,9 @@ static int __init booke_wdt_init(void) | |||
175 | 176 | ||
176 | spin_lock(&booke_wdt_lock); | 177 | spin_lock(&booke_wdt_lock); |
177 | if (booke_wdt_enabled == 1) { | 178 | if (booke_wdt_enabled == 1) { |
178 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " | 179 | printk(KERN_INFO |
179 | "(wdt_period=%d)\n", booke_wdt_period); | 180 | "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", |
181 | booke_wdt_period); | ||
180 | on_each_cpu(__booke_wdt_enable, NULL, 0); | 182 | on_each_cpu(__booke_wdt_enable, NULL, 0); |
181 | } | 183 | } |
182 | spin_unlock(&booke_wdt_lock); | 184 | spin_unlock(&booke_wdt_lock); |
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index df72f90123df..ec324e5e1c99 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
@@ -30,16 +30,16 @@ | |||
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/completion.h> | 31 | #include <linux/completion.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <asm/io.h> | 33 | #include <linux/io.h> |
34 | #include <asm/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | |||
36 | #include <linux/watchdog.h> | 35 | #include <linux/watchdog.h> |
37 | 36 | ||
38 | /* adjustable parameters */ | 37 | /* adjustable parameters */ |
39 | 38 | ||
40 | static int verbose = 0; | 39 | static int verbose; |
41 | static int port = 0x91; | 40 | static int port = 0x91; |
42 | static int ticks = 10000; | 41 | static int ticks = 10000; |
42 | static spinlock_t cpu5wdt_lock; | ||
43 | 43 | ||
44 | #define PFX "cpu5wdt: " | 44 | #define PFX "cpu5wdt: " |
45 | 45 | ||
@@ -70,12 +70,13 @@ static struct { | |||
70 | 70 | ||
71 | static void cpu5wdt_trigger(unsigned long unused) | 71 | static void cpu5wdt_trigger(unsigned long unused) |
72 | { | 72 | { |
73 | if ( verbose > 2 ) | 73 | if (verbose > 2) |
74 | printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); | 74 | printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); |
75 | 75 | ||
76 | if( cpu5wdt_device.running ) | 76 | if (cpu5wdt_device.running) |
77 | ticks--; | 77 | ticks--; |
78 | 78 | ||
79 | spin_lock(&cpu5wdt_lock); | ||
79 | /* keep watchdog alive */ | 80 | /* keep watchdog alive */ |
80 | outb(1, port + CPU5WDT_TRIGGER_REG); | 81 | outb(1, port + CPU5WDT_TRIGGER_REG); |
81 | 82 | ||
@@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused) | |||
86 | /* ticks doesn't matter anyway */ | 87 | /* ticks doesn't matter anyway */ |
87 | complete(&cpu5wdt_device.stop); | 88 | complete(&cpu5wdt_device.stop); |
88 | } | 89 | } |
90 | spin_unlock(&cpu5wdt_lock); | ||
89 | 91 | ||
90 | } | 92 | } |
91 | 93 | ||
@@ -93,14 +95,17 @@ static void cpu5wdt_reset(void) | |||
93 | { | 95 | { |
94 | ticks = cpu5wdt_device.default_ticks; | 96 | ticks = cpu5wdt_device.default_ticks; |
95 | 97 | ||
96 | if ( verbose ) | 98 | if (verbose) |
97 | printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); | 99 | printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); |
98 | 100 | ||
99 | } | 101 | } |
100 | 102 | ||
101 | static void cpu5wdt_start(void) | 103 | static void cpu5wdt_start(void) |
102 | { | 104 | { |
103 | if ( !cpu5wdt_device.queue ) { | 105 | unsigned long flags; |
106 | |||
107 | spin_lock_irqsave(&cpu5wdt_lock, flags); | ||
108 | if (!cpu5wdt_device.queue) { | ||
104 | cpu5wdt_device.queue = 1; | 109 | cpu5wdt_device.queue = 1; |
105 | outb(0, port + CPU5WDT_TIME_A_REG); | 110 | outb(0, port + CPU5WDT_TIME_A_REG); |
106 | outb(0, port + CPU5WDT_TIME_B_REG); | 111 | outb(0, port + CPU5WDT_TIME_B_REG); |
@@ -111,18 +116,20 @@ static void cpu5wdt_start(void) | |||
111 | } | 116 | } |
112 | /* if process dies, counter is not decremented */ | 117 | /* if process dies, counter is not decremented */ |
113 | cpu5wdt_device.running++; | 118 | cpu5wdt_device.running++; |
119 | spin_unlock_irqrestore(&cpu5wdt_lock, flags); | ||
114 | } | 120 | } |
115 | 121 | ||
116 | static int cpu5wdt_stop(void) | 122 | static int cpu5wdt_stop(void) |
117 | { | 123 | { |
118 | if ( cpu5wdt_device.running ) | 124 | unsigned long flags; |
119 | cpu5wdt_device.running = 0; | ||
120 | 125 | ||
126 | spin_lock_irqsave(&cpu5wdt_lock, flags); | ||
127 | if (cpu5wdt_device.running) | ||
128 | cpu5wdt_device.running = 0; | ||
121 | ticks = cpu5wdt_device.default_ticks; | 129 | ticks = cpu5wdt_device.default_ticks; |
122 | 130 | spin_unlock_irqrestore(&cpu5wdt_lock, flags); | |
123 | if ( verbose ) | 131 | if (verbose) |
124 | printk(KERN_CRIT PFX "stop not possible\n"); | 132 | printk(KERN_CRIT PFX "stop not possible\n"); |
125 | |||
126 | return -EIO; | 133 | return -EIO; |
127 | } | 134 | } |
128 | 135 | ||
@@ -130,9 +137,8 @@ static int cpu5wdt_stop(void) | |||
130 | 137 | ||
131 | static int cpu5wdt_open(struct inode *inode, struct file *file) | 138 | static int cpu5wdt_open(struct inode *inode, struct file *file) |
132 | { | 139 | { |
133 | if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) | 140 | if (test_and_set_bit(0, &cpu5wdt_device.inuse)) |
134 | return -EBUSY; | 141 | return -EBUSY; |
135 | |||
136 | return nonseekable_open(inode, file); | 142 | return nonseekable_open(inode, file); |
137 | } | 143 | } |
138 | 144 | ||
@@ -142,67 +148,58 @@ static int cpu5wdt_release(struct inode *inode, struct file *file) | |||
142 | return 0; | 148 | return 0; |
143 | } | 149 | } |
144 | 150 | ||
145 | static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 151 | static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, |
152 | unsigned long arg) | ||
146 | { | 153 | { |
147 | void __user *argp = (void __user *)arg; | 154 | void __user *argp = (void __user *)arg; |
155 | int __user *p = argp; | ||
148 | unsigned int value; | 156 | unsigned int value; |
149 | static struct watchdog_info ident = | 157 | static struct watchdog_info ident = { |
150 | { | ||
151 | .options = WDIOF_CARDRESET, | 158 | .options = WDIOF_CARDRESET, |
152 | .identity = "CPU5 WDT", | 159 | .identity = "CPU5 WDT", |
153 | }; | 160 | }; |
154 | 161 | ||
155 | switch(cmd) { | 162 | switch (cmd) { |
156 | case WDIOC_KEEPALIVE: | 163 | case WDIOC_KEEPALIVE: |
157 | cpu5wdt_reset(); | 164 | cpu5wdt_reset(); |
158 | break; | 165 | break; |
159 | case WDIOC_GETSTATUS: | 166 | case WDIOC_GETSTATUS: |
160 | value = inb(port + CPU5WDT_STATUS_REG); | 167 | value = inb(port + CPU5WDT_STATUS_REG); |
161 | value = (value >> 2) & 1; | 168 | value = (value >> 2) & 1; |
162 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 169 | return put_user(value, p); |
163 | return -EFAULT; | 170 | case WDIOC_GETBOOTSTATUS: |
164 | break; | 171 | return put_user(0, p); |
165 | case WDIOC_GETBOOTSTATUS: | 172 | case WDIOC_GETSUPPORT: |
166 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 173 | if (copy_to_user(argp, &ident, sizeof(ident))) |
167 | return -EFAULT; | 174 | return -EFAULT; |
168 | break; | 175 | break; |
169 | case WDIOC_GETSUPPORT: | 176 | case WDIOC_SETOPTIONS: |
170 | if ( copy_to_user(argp, &ident, sizeof(ident)) ) | 177 | if (get_user(value, p)) |
171 | return -EFAULT; | 178 | return -EFAULT; |
172 | break; | 179 | if (value & WDIOS_ENABLECARD) |
173 | case WDIOC_SETOPTIONS: | 180 | cpu5wdt_start(); |
174 | if ( copy_from_user(&value, argp, sizeof(int)) ) | 181 | if (value & WDIOS_DISABLECARD) |
175 | return -EFAULT; | 182 | cpu5wdt_stop(); |
176 | switch(value) { | 183 | break; |
177 | case WDIOS_ENABLECARD: | 184 | default: |
178 | cpu5wdt_start(); | 185 | return -ENOTTY; |
179 | break; | ||
180 | case WDIOS_DISABLECARD: | ||
181 | return cpu5wdt_stop(); | ||
182 | default: | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | break; | ||
186 | default: | ||
187 | return -ENOTTY; | ||
188 | } | 186 | } |
189 | return 0; | 187 | return 0; |
190 | } | 188 | } |
191 | 189 | ||
192 | static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 190 | static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, |
191 | size_t count, loff_t *ppos) | ||
193 | { | 192 | { |
194 | if ( !count ) | 193 | if (!count) |
195 | return -EIO; | 194 | return -EIO; |
196 | |||
197 | cpu5wdt_reset(); | 195 | cpu5wdt_reset(); |
198 | |||
199 | return count; | 196 | return count; |
200 | } | 197 | } |
201 | 198 | ||
202 | static const struct file_operations cpu5wdt_fops = { | 199 | static const struct file_operations cpu5wdt_fops = { |
203 | .owner = THIS_MODULE, | 200 | .owner = THIS_MODULE, |
204 | .llseek = no_llseek, | 201 | .llseek = no_llseek, |
205 | .ioctl = cpu5wdt_ioctl, | 202 | .unlocked_ioctl = cpu5wdt_ioctl, |
206 | .open = cpu5wdt_open, | 203 | .open = cpu5wdt_open, |
207 | .write = cpu5wdt_write, | 204 | .write = cpu5wdt_write, |
208 | .release = cpu5wdt_release, | 205 | .release = cpu5wdt_release, |
@@ -221,37 +218,36 @@ static int __devinit cpu5wdt_init(void) | |||
221 | unsigned int val; | 218 | unsigned int val; |
222 | int err; | 219 | int err; |
223 | 220 | ||
224 | if ( verbose ) | 221 | if (verbose) |
225 | printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); | 222 | printk(KERN_DEBUG PFX |
223 | "port=0x%x, verbose=%i\n", port, verbose); | ||
226 | 224 | ||
227 | if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { | 225 | init_completion(&cpu5wdt_device.stop); |
226 | spin_lock_init(&cpu5wdt_lock); | ||
227 | cpu5wdt_device.queue = 0; | ||
228 | setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); | ||
229 | cpu5wdt_device.default_ticks = ticks; | ||
230 | |||
231 | if (!request_region(port, CPU5WDT_EXTENT, PFX)) { | ||
228 | printk(KERN_ERR PFX "request_region failed\n"); | 232 | printk(KERN_ERR PFX "request_region failed\n"); |
229 | err = -EBUSY; | 233 | err = -EBUSY; |
230 | goto no_port; | 234 | goto no_port; |
231 | } | 235 | } |
232 | 236 | ||
233 | if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { | ||
234 | printk(KERN_ERR PFX "misc_register failed\n"); | ||
235 | goto no_misc; | ||
236 | } | ||
237 | |||
238 | /* watchdog reboot? */ | 237 | /* watchdog reboot? */ |
239 | val = inb(port + CPU5WDT_STATUS_REG); | 238 | val = inb(port + CPU5WDT_STATUS_REG); |
240 | val = (val >> 2) & 1; | 239 | val = (val >> 2) & 1; |
241 | if ( !val ) | 240 | if (!val) |
242 | printk(KERN_INFO PFX "sorry, was my fault\n"); | 241 | printk(KERN_INFO PFX "sorry, was my fault\n"); |
243 | 242 | ||
244 | init_completion(&cpu5wdt_device.stop); | 243 | err = misc_register(&cpu5wdt_misc); |
245 | cpu5wdt_device.queue = 0; | 244 | if (err < 0) { |
246 | 245 | printk(KERN_ERR PFX "misc_register failed\n"); | |
247 | clear_bit(0, &cpu5wdt_device.inuse); | 246 | goto no_misc; |
248 | 247 | } | |
249 | setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); | ||
250 | 248 | ||
251 | cpu5wdt_device.default_ticks = ticks; | ||
252 | 249 | ||
253 | printk(KERN_INFO PFX "init success\n"); | 250 | printk(KERN_INFO PFX "init success\n"); |
254 | |||
255 | return 0; | 251 | return 0; |
256 | 252 | ||
257 | no_misc: | 253 | no_misc: |
@@ -267,7 +263,7 @@ static int __devinit cpu5wdt_init_module(void) | |||
267 | 263 | ||
268 | static void __devexit cpu5wdt_exit(void) | 264 | static void __devexit cpu5wdt_exit(void) |
269 | { | 265 | { |
270 | if ( cpu5wdt_device.queue ) { | 266 | if (cpu5wdt_device.queue) { |
271 | cpu5wdt_device.queue = 0; | 267 | cpu5wdt_device.queue = 0; |
272 | wait_for_completion(&cpu5wdt_device.stop); | 268 | wait_for_completion(&cpu5wdt_device.stop); |
273 | } | 269 | } |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 1782c79eff06..926b59c41186 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -22,10 +22,10 @@ | |||
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/uaccess.h> | ||
26 | #include <linux/io.h> | ||
25 | 27 | ||
26 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
27 | #include <asm/uaccess.h> | ||
28 | #include <asm/io.h> | ||
29 | 29 | ||
30 | #define MODULE_NAME "DAVINCI-WDT: " | 30 | #define MODULE_NAME "DAVINCI-WDT: " |
31 | 31 | ||
@@ -143,9 +143,8 @@ static struct watchdog_info ident = { | |||
143 | .identity = "DaVinci Watchdog", | 143 | .identity = "DaVinci Watchdog", |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static int | 146 | static long davinci_wdt_ioctl(struct file *file, |
147 | davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 147 | unsigned int cmd, unsigned long arg) |
148 | unsigned long arg) | ||
149 | { | 148 | { |
150 | int ret = -ENOTTY; | 149 | int ret = -ENOTTY; |
151 | 150 | ||
@@ -184,7 +183,7 @@ static const struct file_operations davinci_wdt_fops = { | |||
184 | .owner = THIS_MODULE, | 183 | .owner = THIS_MODULE, |
185 | .llseek = no_llseek, | 184 | .llseek = no_llseek, |
186 | .write = davinci_wdt_write, | 185 | .write = davinci_wdt_write, |
187 | .ioctl = davinci_wdt_ioctl, | 186 | .unlocked_ioctl = davinci_wdt_ioctl, |
188 | .open = davinci_wdt_open, | 187 | .open = davinci_wdt_open, |
189 | .release = davinci_wdt_release, | 188 | .release = davinci_wdt_release, |
190 | }; | 189 | }; |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index 0e4787a0bb87..cdcdd11173a7 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/uaccess.h> | ||
31 | 32 | ||
32 | #include <asm/hardware.h> | 33 | #include <asm/hardware.h> |
33 | #include <asm/uaccess.h> | ||
34 | 34 | ||
35 | #define WDT_VERSION "0.3" | 35 | #define WDT_VERSION "0.3" |
36 | #define PFX "ep93xx_wdt: " | 36 | #define PFX "ep93xx_wdt: " |
@@ -136,9 +136,8 @@ static struct watchdog_info ident = { | |||
136 | .identity = "EP93xx Watchdog", | 136 | .identity = "EP93xx Watchdog", |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static int | 139 | static long ep93xx_wdt_ioctl(struct file *file, |
140 | ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 140 | unsigned int cmd, unsigned long arg) |
141 | unsigned long arg) | ||
142 | { | 141 | { |
143 | int ret = -ENOTTY; | 142 | int ret = -ENOTTY; |
144 | 143 | ||
@@ -174,8 +173,8 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file) | |||
174 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | 173 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
175 | wdt_shutdown(); | 174 | wdt_shutdown(); |
176 | else | 175 | else |
177 | printk(KERN_CRIT PFX "Device closed unexpectedly - " | 176 | printk(KERN_CRIT PFX |
178 | "timer will not stop\n"); | 177 | "Device closed unexpectedly - timer will not stop\n"); |
179 | 178 | ||
180 | clear_bit(WDT_IN_USE, &wdt_status); | 179 | clear_bit(WDT_IN_USE, &wdt_status); |
181 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 180 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
@@ -186,7 +185,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file) | |||
186 | static const struct file_operations ep93xx_wdt_fops = { | 185 | static const struct file_operations ep93xx_wdt_fops = { |
187 | .owner = THIS_MODULE, | 186 | .owner = THIS_MODULE, |
188 | .write = ep93xx_wdt_write, | 187 | .write = ep93xx_wdt_write, |
189 | .ioctl = ep93xx_wdt_ioctl, | 188 | .unlocked_ioctl = ep93xx_wdt_ioctl, |
190 | .open = ep93xx_wdt_open, | 189 | .open = ep93xx_wdt_open, |
191 | .release = ep93xx_wdt_release, | 190 | .release = ep93xx_wdt_release, |
192 | }; | 191 | }; |
@@ -243,7 +242,9 @@ module_param(nowayout, int, 0); | |||
243 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 242 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); |
244 | 243 | ||
245 | module_param(timeout, int, 0); | 244 | module_param(timeout, int, 0); |
246 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 245 | MODULE_PARM_DESC(timeout, |
246 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
247 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
247 | 248 | ||
248 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," | 249 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," |
249 | "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 b14e9d1f164d..b94e6ef4c7a7 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c | |||
@@ -56,14 +56,15 @@ | |||
56 | #include <linux/notifier.h> | 56 | #include <linux/notifier.h> |
57 | #include <linux/reboot.h> | 57 | #include <linux/reboot.h> |
58 | #include <linux/init.h> | 58 | #include <linux/init.h> |
59 | #include <linux/io.h> | ||
60 | #include <linux/uaccess.h> | ||
59 | 61 | ||
60 | #include <asm/io.h> | ||
61 | #include <asm/uaccess.h> | ||
62 | #include <asm/system.h> | 62 | #include <asm/system.h> |
63 | 63 | ||
64 | static unsigned long eurwdt_is_open; | 64 | static unsigned long eurwdt_is_open; |
65 | static int eurwdt_timeout; | 65 | static int eurwdt_timeout; |
66 | static char eur_expect_close; | 66 | static char eur_expect_close; |
67 | static spinlock_t eurwdt_lock; | ||
67 | 68 | ||
68 | /* | 69 | /* |
69 | * You must set these - there is no sane way to probe for this board. | 70 | * You must set these - there is no sane way to probe for this board. |
@@ -78,7 +79,9 @@ static char *ev = "int"; | |||
78 | 79 | ||
79 | static int nowayout = WATCHDOG_NOWAYOUT; | 80 | static int nowayout = WATCHDOG_NOWAYOUT; |
80 | module_param(nowayout, int, 0); | 81 | module_param(nowayout, int, 0); |
81 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 82 | MODULE_PARM_DESC(nowayout, |
83 | "Watchdog cannot be stopped once started (default=" | ||
84 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
82 | 85 | ||
83 | /* | 86 | /* |
84 | * Some symbolic names | 87 | * Some symbolic names |
@@ -137,7 +140,8 @@ static void eurwdt_activate_timer(void) | |||
137 | { | 140 | { |
138 | eurwdt_disable_timer(); | 141 | eurwdt_disable_timer(); |
139 | eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ | 142 | eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ |
140 | eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); | 143 | eurwdt_write_reg(WDT_OUTPIN_CFG, |
144 | !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); | ||
141 | 145 | ||
142 | /* Setting interrupt line */ | 146 | /* Setting interrupt line */ |
143 | if (irq == 2 || irq > 15 || irq < 0) { | 147 | if (irq == 2 || irq > 15 || irq < 0) { |
@@ -206,21 +210,21 @@ size_t count, loff_t *ppos) | |||
206 | 210 | ||
207 | for (i = 0; i != count; i++) { | 211 | for (i = 0; i != count; i++) { |
208 | char c; | 212 | char c; |
209 | if(get_user(c, buf+i)) | 213 | if (get_user(c, buf+i)) |
210 | return -EFAULT; | 214 | return -EFAULT; |
211 | if (c == 'V') | 215 | if (c == 'V') |
212 | eur_expect_close = 42; | 216 | eur_expect_close = 42; |
213 | } | 217 | } |
214 | } | 218 | } |
219 | spin_lock(&eurwdt_lock); | ||
215 | eurwdt_ping(); /* the default timeout */ | 220 | eurwdt_ping(); /* the default timeout */ |
221 | spin_unlock(&eurwdt_lock); | ||
216 | } | 222 | } |
217 | |||
218 | return count; | 223 | return count; |
219 | } | 224 | } |
220 | 225 | ||
221 | /** | 226 | /** |
222 | * eurwdt_ioctl: | 227 | * eurwdt_ioctl: |
223 | * @inode: inode of the device | ||
224 | * @file: file handle to the device | 228 | * @file: file handle to the device |
225 | * @cmd: watchdog command | 229 | * @cmd: watchdog command |
226 | * @arg: argument pointer | 230 | * @arg: argument pointer |
@@ -229,13 +233,14 @@ size_t count, loff_t *ppos) | |||
229 | * according to their available features. | 233 | * according to their available features. |
230 | */ | 234 | */ |
231 | 235 | ||
232 | static int eurwdt_ioctl(struct inode *inode, struct file *file, | 236 | static long eurwdt_ioctl(struct file *file, |
233 | unsigned int cmd, unsigned long arg) | 237 | unsigned int cmd, unsigned long arg) |
234 | { | 238 | { |
235 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
236 | int __user *p = argp; | 240 | int __user *p = argp; |
237 | static struct watchdog_info ident = { | 241 | static struct watchdog_info ident = { |
238 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
243 | | WDIOF_MAGICCLOSE, | ||
239 | .firmware_version = 1, | 244 | .firmware_version = 1, |
240 | .identity = "WDT Eurotech CPU-1220/1410", | 245 | .identity = "WDT Eurotech CPU-1220/1410", |
241 | }; | 246 | }; |
@@ -243,7 +248,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
243 | int time; | 248 | int time; |
244 | int options, retval = -EINVAL; | 249 | int options, retval = -EINVAL; |
245 | 250 | ||
246 | switch(cmd) { | 251 | switch (cmd) { |
247 | default: | 252 | default: |
248 | return -ENOTTY; | 253 | return -ENOTTY; |
249 | 254 | ||
@@ -255,7 +260,9 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
255 | return put_user(0, p); | 260 | return put_user(0, p); |
256 | 261 | ||
257 | case WDIOC_KEEPALIVE: | 262 | case WDIOC_KEEPALIVE: |
263 | spin_lock(&eurwdt_lock); | ||
258 | eurwdt_ping(); | 264 | eurwdt_ping(); |
265 | spin_unlock(&eurwdt_lock); | ||
259 | return 0; | 266 | return 0; |
260 | 267 | ||
261 | case WDIOC_SETTIMEOUT: | 268 | case WDIOC_SETTIMEOUT: |
@@ -266,8 +273,10 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
266 | if (time < 0 || time > 255) | 273 | if (time < 0 || time > 255) |
267 | return -EINVAL; | 274 | return -EINVAL; |
268 | 275 | ||
276 | spin_lock(&eurwdt_lock); | ||
269 | eurwdt_timeout = time; | 277 | eurwdt_timeout = time; |
270 | eurwdt_set_timeout(time); | 278 | eurwdt_set_timeout(time); |
279 | spin_unlock(&eurwdt_lock); | ||
271 | /* Fall */ | 280 | /* Fall */ |
272 | 281 | ||
273 | case WDIOC_GETTIMEOUT: | 282 | case WDIOC_GETTIMEOUT: |
@@ -276,6 +285,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
276 | case WDIOC_SETOPTIONS: | 285 | case WDIOC_SETOPTIONS: |
277 | if (get_user(options, p)) | 286 | if (get_user(options, p)) |
278 | return -EFAULT; | 287 | return -EFAULT; |
288 | spin_lock(&eurwdt_lock); | ||
279 | if (options & WDIOS_DISABLECARD) { | 289 | if (options & WDIOS_DISABLECARD) { |
280 | eurwdt_disable_timer(); | 290 | eurwdt_disable_timer(); |
281 | retval = 0; | 291 | retval = 0; |
@@ -285,6 +295,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
285 | eurwdt_ping(); | 295 | eurwdt_ping(); |
286 | retval = 0; | 296 | retval = 0; |
287 | } | 297 | } |
298 | spin_unlock(&eurwdt_lock); | ||
288 | return retval; | 299 | return retval; |
289 | } | 300 | } |
290 | } | 301 | } |
@@ -322,10 +333,11 @@ static int eurwdt_open(struct inode *inode, struct file *file) | |||
322 | 333 | ||
323 | static int eurwdt_release(struct inode *inode, struct file *file) | 334 | static int eurwdt_release(struct inode *inode, struct file *file) |
324 | { | 335 | { |
325 | if (eur_expect_close == 42) { | 336 | if (eur_expect_close == 42) |
326 | eurwdt_disable_timer(); | 337 | eurwdt_disable_timer(); |
327 | } else { | 338 | else { |
328 | printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n"); | 339 | printk(KERN_CRIT |
340 | "eurwdt: Unexpected close, not stopping watchdog!\n"); | ||
329 | eurwdt_ping(); | 341 | eurwdt_ping(); |
330 | } | 342 | } |
331 | clear_bit(0, &eurwdt_is_open); | 343 | clear_bit(0, &eurwdt_is_open); |
@@ -362,11 +374,11 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
362 | 374 | ||
363 | 375 | ||
364 | static const struct file_operations eurwdt_fops = { | 376 | static const struct file_operations eurwdt_fops = { |
365 | .owner = THIS_MODULE, | 377 | .owner = THIS_MODULE, |
366 | .llseek = no_llseek, | 378 | .llseek = no_llseek, |
367 | .write = eurwdt_write, | 379 | .write = eurwdt_write, |
368 | .ioctl = eurwdt_ioctl, | 380 | .unlocked_ioctl = eurwdt_ioctl, |
369 | .open = eurwdt_open, | 381 | .open = eurwdt_open, |
370 | .release = eurwdt_release, | 382 | .release = eurwdt_release, |
371 | }; | 383 | }; |
372 | 384 | ||
@@ -419,7 +431,7 @@ static int __init eurwdt_init(void) | |||
419 | int ret; | 431 | int ret; |
420 | 432 | ||
421 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); | 433 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); |
422 | if(ret) { | 434 | if (ret) { |
423 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); | 435 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); |
424 | goto out; | 436 | goto out; |
425 | } | 437 | } |
@@ -432,10 +444,13 @@ static int __init eurwdt_init(void) | |||
432 | 444 | ||
433 | ret = register_reboot_notifier(&eurwdt_notifier); | 445 | ret = register_reboot_notifier(&eurwdt_notifier); |
434 | if (ret) { | 446 | if (ret) { |
435 | printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret); | 447 | printk(KERN_ERR |
448 | "eurwdt: can't register reboot notifier (err=%d)\n", ret); | ||
436 | goto outreg; | 449 | goto outreg; |
437 | } | 450 | } |
438 | 451 | ||
452 | spin_lock_init(&eurwdt_lock); | ||
453 | |||
439 | ret = misc_register(&eurwdt_miscdev); | 454 | ret = misc_register(&eurwdt_miscdev); |
440 | if (ret) { | 455 | if (ret) { |
441 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", | 456 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index ccd6c530782d..d20f591e3fd7 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -39,9 +39,9 @@ | |||
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/bootmem.h> | 40 | #include <linux/bootmem.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <asm/dmi.h> | 42 | #include <linux/dmi.h> |
43 | #include <asm/desc.h> | 43 | #include <asm/desc.h> |
44 | #include <asm/kdebug.h> | 44 | #include <linux/kdebug.h> |
45 | 45 | ||
46 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ | 46 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ |
47 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 | 47 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index ca44fd9b19bb..01a283f7a271 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -38,9 +38,8 @@ | |||
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
41 | 41 | #include <linux/uaccess.h> | |
42 | #include <asm/uaccess.h> | 42 | #include <linux/io.h> |
43 | #include <asm/io.h> | ||
44 | 43 | ||
45 | /* Module and version information */ | 44 | /* Module and version information */ |
46 | #define ESB_VERSION "0.03" | 45 | #define ESB_VERSION "0.03" |
@@ -59,17 +58,17 @@ | |||
59 | #define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ | 58 | #define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ |
60 | 59 | ||
61 | /* Lock register bits */ | 60 | /* Lock register bits */ |
62 | #define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */ | 61 | #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */ |
63 | #define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */ | 62 | #define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */ |
64 | #define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */ | 63 | #define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */ |
65 | 64 | ||
66 | /* Config register bits */ | 65 | /* Config register bits */ |
67 | #define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */ | 66 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ |
68 | #define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */ | 67 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ |
69 | #define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */ | 68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ |
70 | 69 | ||
71 | /* Reload register bits */ | 70 | /* Reload register bits */ |
72 | #define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */ | 71 | #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */ |
73 | 72 | ||
74 | /* Magic constants */ | 73 | /* Magic constants */ |
75 | #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ | 74 | #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ |
@@ -84,14 +83,20 @@ static unsigned short triggered; /* The status of the watchdog upon boot */ | |||
84 | static char esb_expect_close; | 83 | static char esb_expect_close; |
85 | 84 | ||
86 | /* module parameters */ | 85 | /* module parameters */ |
87 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */ | 86 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
87 | #define WATCHDOG_HEARTBEAT 30 | ||
88 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 88 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
89 | |||
89 | module_param(heartbeat, int, 0); | 90 | module_param(heartbeat, int, 0); |
90 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 91 | MODULE_PARM_DESC(heartbeat, |
92 | "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" | ||
93 | __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | ||
91 | 94 | ||
92 | static int nowayout = WATCHDOG_NOWAYOUT; | 95 | static int nowayout = WATCHDOG_NOWAYOUT; |
93 | module_param(nowayout, int, 0); | 96 | module_param(nowayout, int, 0); |
94 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 97 | MODULE_PARM_DESC(nowayout, |
98 | "Watchdog cannot be stopped once started (default=" | ||
99 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
95 | 100 | ||
96 | /* | 101 | /* |
97 | * Some i6300ESB specific functions | 102 | * Some i6300ESB specific functions |
@@ -104,8 +109,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _ | |||
104 | * to once before they need to be unlocked again. | 109 | * to once before they need to be unlocked again. |
105 | */ | 110 | */ |
106 | static inline void esb_unlock_registers(void) { | 111 | static inline void esb_unlock_registers(void) { |
107 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); | 112 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); |
108 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | 113 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); |
109 | } | 114 | } |
110 | 115 | ||
111 | static void esb_timer_start(void) | 116 | static void esb_timer_start(void) |
@@ -114,8 +119,7 @@ static void esb_timer_start(void) | |||
114 | 119 | ||
115 | /* Enable or Enable + Lock? */ | 120 | /* Enable or Enable + Lock? */ |
116 | val = 0x02 | (nowayout ? 0x01 : 0x00); | 121 | val = 0x02 | (nowayout ? 0x01 : 0x00); |
117 | 122 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); | |
118 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); | ||
119 | } | 123 | } |
120 | 124 | ||
121 | static int esb_timer_stop(void) | 125 | static int esb_timer_stop(void) |
@@ -140,7 +144,7 @@ static void esb_timer_keepalive(void) | |||
140 | spin_lock(&esb_lock); | 144 | spin_lock(&esb_lock); |
141 | esb_unlock_registers(); | 145 | esb_unlock_registers(); |
142 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); | 146 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); |
143 | /* FIXME: Do we need to flush anything here? */ | 147 | /* FIXME: Do we need to flush anything here? */ |
144 | spin_unlock(&esb_lock); | 148 | spin_unlock(&esb_lock); |
145 | } | 149 | } |
146 | 150 | ||
@@ -167,7 +171,7 @@ static int esb_timer_set_heartbeat(int time) | |||
167 | esb_unlock_registers(); | 171 | esb_unlock_registers(); |
168 | writel(val, ESB_TIMER2_REG); | 172 | writel(val, ESB_TIMER2_REG); |
169 | 173 | ||
170 | /* Reload */ | 174 | /* Reload */ |
171 | esb_unlock_registers(); | 175 | esb_unlock_registers(); |
172 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); | 176 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); |
173 | 177 | ||
@@ -179,54 +183,55 @@ static int esb_timer_set_heartbeat(int time) | |||
179 | return 0; | 183 | return 0; |
180 | } | 184 | } |
181 | 185 | ||
182 | static int esb_timer_read (void) | 186 | static int esb_timer_read(void) |
183 | { | 187 | { |
184 | u32 count; | 188 | u32 count; |
185 | 189 | ||
186 | /* This isn't documented, and doesn't take into | 190 | /* This isn't documented, and doesn't take into |
187 | * acount which stage is running, but it looks | 191 | * acount which stage is running, but it looks |
188 | * like a 20 bit count down, so we might as well report it. | 192 | * like a 20 bit count down, so we might as well report it. |
189 | */ | 193 | */ |
190 | pci_read_config_dword(esb_pci, 0x64, &count); | 194 | pci_read_config_dword(esb_pci, 0x64, &count); |
191 | return (int)count; | 195 | return (int)count; |
192 | } | 196 | } |
193 | 197 | ||
194 | /* | 198 | /* |
195 | * /dev/watchdog handling | 199 | * /dev/watchdog handling |
196 | */ | 200 | */ |
197 | 201 | ||
198 | static int esb_open (struct inode *inode, struct file *file) | 202 | static int esb_open(struct inode *inode, struct file *file) |
199 | { | 203 | { |
200 | /* /dev/watchdog can only be opened once */ | 204 | /* /dev/watchdog can only be opened once */ |
201 | if (test_and_set_bit(0, &timer_alive)) | 205 | if (test_and_set_bit(0, &timer_alive)) |
202 | return -EBUSY; | 206 | return -EBUSY; |
203 | 207 | ||
204 | /* Reload and activate timer */ | 208 | /* Reload and activate timer */ |
205 | esb_timer_keepalive (); | 209 | esb_timer_keepalive(); |
206 | esb_timer_start (); | 210 | esb_timer_start(); |
207 | 211 | ||
208 | return nonseekable_open(inode, file); | 212 | return nonseekable_open(inode, file); |
209 | } | 213 | } |
210 | 214 | ||
211 | static int esb_release (struct inode *inode, struct file *file) | 215 | static int esb_release(struct inode *inode, struct file *file) |
212 | { | 216 | { |
213 | /* Shut off the timer. */ | 217 | /* Shut off the timer. */ |
214 | if (esb_expect_close == 42) { | 218 | if (esb_expect_close == 42) |
215 | esb_timer_stop (); | 219 | esb_timer_stop(); |
216 | } else { | 220 | else { |
217 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 221 | printk(KERN_CRIT PFX |
218 | esb_timer_keepalive (); | 222 | "Unexpected close, not stopping watchdog!\n"); |
219 | } | 223 | esb_timer_keepalive(); |
220 | clear_bit(0, &timer_alive); | 224 | } |
221 | esb_expect_close = 0; | 225 | clear_bit(0, &timer_alive); |
222 | return 0; | 226 | esb_expect_close = 0; |
227 | return 0; | ||
223 | } | 228 | } |
224 | 229 | ||
225 | static ssize_t esb_write (struct file *file, const char __user *data, | 230 | static ssize_t esb_write(struct file *file, const char __user *data, |
226 | size_t len, loff_t * ppos) | 231 | size_t len, loff_t *ppos) |
227 | { | 232 | { |
228 | /* See if we got the magic character 'V' and reload the timer */ | 233 | /* See if we got the magic character 'V' and reload the timer */ |
229 | if (len) { | 234 | if (len) { |
230 | if (!nowayout) { | 235 | if (!nowayout) { |
231 | size_t i; | 236 | size_t i; |
232 | 237 | ||
@@ -237,7 +242,7 @@ static ssize_t esb_write (struct file *file, const char __user *data, | |||
237 | /* scan to see whether or not we got the magic character */ | 242 | /* scan to see whether or not we got the magic character */ |
238 | for (i = 0; i != len; i++) { | 243 | for (i = 0; i != len; i++) { |
239 | char c; | 244 | char c; |
240 | if(get_user(c, data+i)) | 245 | if (get_user(c, data+i)) |
241 | return -EFAULT; | 246 | return -EFAULT; |
242 | if (c == 'V') | 247 | if (c == 'V') |
243 | esb_expect_close = 42; | 248 | esb_expect_close = 42; |
@@ -245,13 +250,12 @@ static ssize_t esb_write (struct file *file, const char __user *data, | |||
245 | } | 250 | } |
246 | 251 | ||
247 | /* someone wrote to us, we should reload the timer */ | 252 | /* someone wrote to us, we should reload the timer */ |
248 | esb_timer_keepalive (); | 253 | esb_timer_keepalive(); |
249 | } | 254 | } |
250 | return len; | 255 | return len; |
251 | } | 256 | } |
252 | 257 | ||
253 | static int esb_ioctl (struct inode *inode, struct file *file, | 258 | static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
254 | unsigned int cmd, unsigned long arg) | ||
255 | { | 259 | { |
256 | int new_options, retval = -EINVAL; | 260 | int new_options, retval = -EINVAL; |
257 | int new_heartbeat; | 261 | int new_heartbeat; |
@@ -266,71 +270,65 @@ static int esb_ioctl (struct inode *inode, struct file *file, | |||
266 | }; | 270 | }; |
267 | 271 | ||
268 | switch (cmd) { | 272 | switch (cmd) { |
269 | case WDIOC_GETSUPPORT: | 273 | case WDIOC_GETSUPPORT: |
270 | return copy_to_user(argp, &ident, | 274 | return copy_to_user(argp, &ident, |
271 | sizeof (ident)) ? -EFAULT : 0; | 275 | sizeof(ident)) ? -EFAULT : 0; |
272 | |||
273 | case WDIOC_GETSTATUS: | ||
274 | return put_user (esb_timer_read(), p); | ||
275 | |||
276 | case WDIOC_GETBOOTSTATUS: | ||
277 | return put_user (triggered, p); | ||
278 | |||
279 | case WDIOC_KEEPALIVE: | ||
280 | esb_timer_keepalive (); | ||
281 | return 0; | ||
282 | 276 | ||
283 | case WDIOC_SETOPTIONS: | 277 | case WDIOC_GETSTATUS: |
284 | { | 278 | return put_user(esb_timer_read(), p); |
285 | if (get_user (new_options, p)) | ||
286 | return -EFAULT; | ||
287 | 279 | ||
288 | if (new_options & WDIOS_DISABLECARD) { | 280 | case WDIOC_GETBOOTSTATUS: |
289 | esb_timer_stop (); | 281 | return put_user(triggered, p); |
290 | retval = 0; | ||
291 | } | ||
292 | 282 | ||
293 | if (new_options & WDIOS_ENABLECARD) { | 283 | case WDIOC_KEEPALIVE: |
294 | esb_timer_keepalive (); | 284 | esb_timer_keepalive(); |
295 | esb_timer_start (); | 285 | return 0; |
296 | retval = 0; | ||
297 | } | ||
298 | 286 | ||
299 | return retval; | 287 | case WDIOC_SETOPTIONS: |
300 | } | 288 | { |
289 | if (get_user(new_options, p)) | ||
290 | return -EFAULT; | ||
301 | 291 | ||
302 | case WDIOC_SETTIMEOUT: | 292 | if (new_options & WDIOS_DISABLECARD) { |
303 | { | 293 | esb_timer_stop(); |
304 | if (get_user(new_heartbeat, p)) | 294 | retval = 0; |
305 | return -EFAULT; | 295 | } |
306 | |||
307 | if (esb_timer_set_heartbeat(new_heartbeat)) | ||
308 | return -EINVAL; | ||
309 | |||
310 | esb_timer_keepalive (); | ||
311 | /* Fall */ | ||
312 | } | ||
313 | |||
314 | case WDIOC_GETTIMEOUT: | ||
315 | return put_user(heartbeat, p); | ||
316 | 296 | ||
317 | default: | 297 | if (new_options & WDIOS_ENABLECARD) { |
318 | return -ENOTTY; | 298 | esb_timer_keepalive(); |
319 | } | 299 | esb_timer_start(); |
300 | retval = 0; | ||
301 | } | ||
302 | return retval; | ||
303 | } | ||
304 | case WDIOC_SETTIMEOUT: | ||
305 | { | ||
306 | if (get_user(new_heartbeat, p)) | ||
307 | return -EFAULT; | ||
308 | if (esb_timer_set_heartbeat(new_heartbeat)) | ||
309 | return -EINVAL; | ||
310 | esb_timer_keepalive(); | ||
311 | /* Fall */ | ||
312 | } | ||
313 | case WDIOC_GETTIMEOUT: | ||
314 | return put_user(heartbeat, p); | ||
315 | default: | ||
316 | return -ENOTTY; | ||
317 | } | ||
320 | } | 318 | } |
321 | 319 | ||
322 | /* | 320 | /* |
323 | * Notify system | 321 | * Notify system |
324 | */ | 322 | */ |
325 | 323 | ||
326 | static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused) | 324 | static int esb_notify_sys(struct notifier_block *this, |
325 | unsigned long code, void *unused) | ||
327 | { | 326 | { |
328 | if (code==SYS_DOWN || code==SYS_HALT) { | 327 | if (code == SYS_DOWN || code == SYS_HALT) { |
329 | /* Turn the WDT off */ | 328 | /* Turn the WDT off */ |
330 | esb_timer_stop (); | 329 | esb_timer_stop(); |
331 | } | 330 | } |
332 | 331 | return NOTIFY_DONE; | |
333 | return NOTIFY_DONE; | ||
334 | } | 332 | } |
335 | 333 | ||
336 | /* | 334 | /* |
@@ -338,22 +336,22 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void | |||
338 | */ | 336 | */ |
339 | 337 | ||
340 | static const struct file_operations esb_fops = { | 338 | static const struct file_operations esb_fops = { |
341 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
342 | .llseek = no_llseek, | 340 | .llseek = no_llseek, |
343 | .write = esb_write, | 341 | .write = esb_write, |
344 | .ioctl = esb_ioctl, | 342 | .unlocked_ioctl = esb_ioctl, |
345 | .open = esb_open, | 343 | .open = esb_open, |
346 | .release = esb_release, | 344 | .release = esb_release, |
347 | }; | 345 | }; |
348 | 346 | ||
349 | static struct miscdevice esb_miscdev = { | 347 | static struct miscdevice esb_miscdev = { |
350 | .minor = WATCHDOG_MINOR, | 348 | .minor = WATCHDOG_MINOR, |
351 | .name = "watchdog", | 349 | .name = "watchdog", |
352 | .fops = &esb_fops, | 350 | .fops = &esb_fops, |
353 | }; | 351 | }; |
354 | 352 | ||
355 | static struct notifier_block esb_notifier = { | 353 | static struct notifier_block esb_notifier = { |
356 | .notifier_call = esb_notify_sys, | 354 | .notifier_call = esb_notify_sys, |
357 | }; | 355 | }; |
358 | 356 | ||
359 | /* | 357 | /* |
@@ -365,50 +363,44 @@ static struct notifier_block esb_notifier = { | |||
365 | * want to register another driver on the same PCI id. | 363 | * want to register another driver on the same PCI id. |
366 | */ | 364 | */ |
367 | static struct pci_device_id esb_pci_tbl[] = { | 365 | static struct pci_device_id esb_pci_tbl[] = { |
368 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, | 366 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, |
369 | { 0, }, /* End of list */ | 367 | { 0, }, /* End of list */ |
370 | }; | 368 | }; |
371 | MODULE_DEVICE_TABLE (pci, esb_pci_tbl); | 369 | MODULE_DEVICE_TABLE(pci, esb_pci_tbl); |
372 | 370 | ||
373 | /* | 371 | /* |
374 | * Init & exit routines | 372 | * Init & exit routines |
375 | */ | 373 | */ |
376 | 374 | ||
377 | static unsigned char __init esb_getdevice (void) | 375 | static unsigned char __init esb_getdevice(void) |
378 | { | 376 | { |
379 | u8 val1; | 377 | u8 val1; |
380 | unsigned short val2; | 378 | unsigned short val2; |
379 | /* | ||
380 | * Find the PCI device | ||
381 | */ | ||
381 | 382 | ||
382 | struct pci_dev *dev = NULL; | 383 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, |
383 | /* | 384 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); |
384 | * Find the PCI device | ||
385 | */ | ||
386 | |||
387 | for_each_pci_dev(dev) { | ||
388 | if (pci_match_id(esb_pci_tbl, dev)) { | ||
389 | esb_pci = dev; | ||
390 | break; | ||
391 | } | ||
392 | } | ||
393 | 385 | ||
394 | if (esb_pci) { | 386 | if (esb_pci) { |
395 | if (pci_enable_device(esb_pci)) { | 387 | if (pci_enable_device(esb_pci)) { |
396 | printk (KERN_ERR PFX "failed to enable device\n"); | 388 | printk(KERN_ERR PFX "failed to enable device\n"); |
397 | goto err_devput; | 389 | goto err_devput; |
398 | } | 390 | } |
399 | 391 | ||
400 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 392 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { |
401 | printk (KERN_ERR PFX "failed to request region\n"); | 393 | printk(KERN_ERR PFX "failed to request region\n"); |
402 | goto err_disable; | 394 | goto err_disable; |
403 | } | 395 | } |
404 | 396 | ||
405 | BASEADDR = ioremap(pci_resource_start(esb_pci, 0), | 397 | BASEADDR = ioremap(pci_resource_start(esb_pci, 0), |
406 | pci_resource_len(esb_pci, 0)); | 398 | pci_resource_len(esb_pci, 0)); |
407 | if (BASEADDR == NULL) { | 399 | if (BASEADDR == NULL) { |
408 | /* Something's wrong here, BASEADDR has to be set */ | 400 | /* Something's wrong here, BASEADDR has to be set */ |
409 | printk (KERN_ERR PFX "failed to get BASEADDR\n"); | 401 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
410 | goto err_release; | 402 | goto err_release; |
411 | } | 403 | } |
412 | 404 | ||
413 | /* | 405 | /* |
414 | * The watchdog has two timers, it can be setup so that the | 406 | * The watchdog has two timers, it can be setup so that the |
@@ -425,7 +417,7 @@ static unsigned char __init esb_getdevice (void) | |||
425 | /* Check that the WDT isn't already locked */ | 417 | /* Check that the WDT isn't already locked */ |
426 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); | 418 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); |
427 | if (val1 & ESB_WDT_LOCK) | 419 | if (val1 & ESB_WDT_LOCK) |
428 | printk (KERN_WARNING PFX "nowayout already set\n"); | 420 | printk(KERN_WARNING PFX "nowayout already set\n"); |
429 | 421 | ||
430 | /* Set the timer to watchdog mode and disable it for now */ | 422 | /* Set the timer to watchdog mode and disable it for now */ |
431 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); | 423 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); |
@@ -452,44 +444,44 @@ err_devput: | |||
452 | return 0; | 444 | return 0; |
453 | } | 445 | } |
454 | 446 | ||
455 | static int __init watchdog_init (void) | 447 | static int __init watchdog_init(void) |
456 | { | 448 | { |
457 | int ret; | 449 | int ret; |
458 | 450 | ||
459 | /* Check whether or not the hardware watchdog is there */ | 451 | /* Check whether or not the hardware watchdog is there */ |
460 | if (!esb_getdevice () || esb_pci == NULL) | 452 | if (!esb_getdevice() || esb_pci == NULL) |
461 | return -ENODEV; | 453 | return -ENODEV; |
462 | 454 | ||
463 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 455 | /* Check that the heartbeat value is within it's range; |
464 | if (esb_timer_set_heartbeat (heartbeat)) { | 456 | if not reset to the default */ |
465 | esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT); | 457 | if (esb_timer_set_heartbeat(heartbeat)) { |
466 | printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n", | 458 | esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT); |
467 | heartbeat); | 459 | printk(KERN_INFO PFX |
468 | } | 460 | "heartbeat value must be 1<heartbeat<2046, using %d\n", |
469 | 461 | heartbeat); | |
470 | ret = register_reboot_notifier(&esb_notifier); | 462 | } |
471 | if (ret != 0) { | 463 | ret = register_reboot_notifier(&esb_notifier); |
472 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 464 | if (ret != 0) { |
473 | ret); | 465 | printk(KERN_ERR PFX |
474 | goto err_unmap; | 466 | "cannot register reboot notifier (err=%d)\n", ret); |
475 | } | 467 | goto err_unmap; |
476 | 468 | } | |
477 | ret = misc_register(&esb_miscdev); | ||
478 | if (ret != 0) { | ||
479 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | ||
480 | WATCHDOG_MINOR, ret); | ||
481 | goto err_notifier; | ||
482 | } | ||
483 | |||
484 | esb_timer_stop (); | ||
485 | |||
486 | printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", | ||
487 | BASEADDR, heartbeat, nowayout); | ||
488 | 469 | ||
489 | return 0; | 470 | ret = misc_register(&esb_miscdev); |
471 | if (ret != 0) { | ||
472 | printk(KERN_ERR PFX | ||
473 | "cannot register miscdev on minor=%d (err=%d)\n", | ||
474 | WATCHDOG_MINOR, ret); | ||
475 | goto err_notifier; | ||
476 | } | ||
477 | esb_timer_stop(); | ||
478 | printk(KERN_INFO PFX | ||
479 | "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", | ||
480 | BASEADDR, heartbeat, nowayout); | ||
481 | return 0; | ||
490 | 482 | ||
491 | err_notifier: | 483 | err_notifier: |
492 | unregister_reboot_notifier(&esb_notifier); | 484 | unregister_reboot_notifier(&esb_notifier); |
493 | err_unmap: | 485 | err_unmap: |
494 | iounmap(BASEADDR); | 486 | iounmap(BASEADDR); |
495 | /* err_release: */ | 487 | /* err_release: */ |
@@ -498,18 +490,18 @@ err_unmap: | |||
498 | pci_disable_device(esb_pci); | 490 | pci_disable_device(esb_pci); |
499 | /* err_devput: */ | 491 | /* err_devput: */ |
500 | pci_dev_put(esb_pci); | 492 | pci_dev_put(esb_pci); |
501 | return ret; | 493 | return ret; |
502 | } | 494 | } |
503 | 495 | ||
504 | static void __exit watchdog_cleanup (void) | 496 | static void __exit watchdog_cleanup(void) |
505 | { | 497 | { |
506 | /* Stop the timer before we leave */ | 498 | /* Stop the timer before we leave */ |
507 | if (!nowayout) | 499 | if (!nowayout) |
508 | esb_timer_stop (); | 500 | esb_timer_stop(); |
509 | 501 | ||
510 | /* Deregister */ | 502 | /* Deregister */ |
511 | misc_deregister(&esb_miscdev); | 503 | misc_deregister(&esb_miscdev); |
512 | unregister_reboot_notifier(&esb_notifier); | 504 | unregister_reboot_notifier(&esb_notifier); |
513 | iounmap(BASEADDR); | 505 | iounmap(BASEADDR); |
514 | pci_release_region(esb_pci, 0); | 506 | pci_release_region(esb_pci, 0); |
515 | pci_disable_device(esb_pci); | 507 | pci_disable_device(esb_pci); |
diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h new file mode 100644 index 000000000000..9e27e6422f66 --- /dev/null +++ b/drivers/watchdog/iTCO_vendor.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* iTCO Vendor Specific Support hooks */ | ||
2 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | ||
3 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | ||
4 | extern void iTCO_vendor_pre_stop(unsigned long); | ||
5 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | ||
6 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | ||
7 | extern int iTCO_vendor_check_noreboot_on(void); | ||
8 | #else | ||
9 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | ||
10 | #define iTCO_vendor_pre_stop(acpibase) {} | ||
11 | #define iTCO_vendor_pre_keepalive(acpibase, heartbeat) {} | ||
12 | #define iTCO_vendor_pre_set_heartbeat(heartbeat) {} | ||
13 | #define iTCO_vendor_check_noreboot_on() 1 | ||
14 | /* 1=check noreboot; 0=don't check */ | ||
15 | #endif | ||
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index cafc465f2ae3..09e9534ac2e4 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c | |||
@@ -32,7 +32,9 @@ | |||
32 | #include <linux/init.h> /* For __init/__exit/... */ | 32 | #include <linux/init.h> /* For __init/__exit/... */ |
33 | #include <linux/ioport.h> /* For io-port access */ | 33 | #include <linux/ioport.h> /* For io-port access */ |
34 | 34 | ||
35 | #include <asm/io.h> /* For inb/outb/... */ | 35 | #include <linux/io.h> /* For inb/outb/... */ |
36 | |||
37 | #include "iTCO_vendor.h" | ||
36 | 38 | ||
37 | /* iTCO defines */ | 39 | /* iTCO defines */ |
38 | #define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ | 40 | #define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ |
@@ -40,10 +42,12 @@ | |||
40 | #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ | 42 | #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ |
41 | 43 | ||
42 | /* List of vendor support modes */ | 44 | /* List of vendor support modes */ |
43 | #define SUPERMICRO_OLD_BOARD 1 /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ | 45 | /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ |
44 | #define SUPERMICRO_NEW_BOARD 2 /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ | 46 | #define SUPERMICRO_OLD_BOARD 1 |
47 | /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ | ||
48 | #define SUPERMICRO_NEW_BOARD 2 | ||
45 | 49 | ||
46 | static int vendorsupport = 0; | 50 | static int vendorsupport; |
47 | module_param(vendorsupport, int, 0); | 51 | module_param(vendorsupport, int, 0); |
48 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); | 52 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); |
49 | 53 | ||
@@ -143,34 +147,35 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase) | |||
143 | */ | 147 | */ |
144 | 148 | ||
145 | /* I/O Port's */ | 149 | /* I/O Port's */ |
146 | #define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ | 150 | #define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ |
147 | #define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ | 151 | #define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ |
148 | 152 | ||
149 | /* Control Register's */ | 153 | /* Control Register's */ |
150 | #define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ | 154 | #define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ |
151 | #define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ | 155 | #define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ |
152 | 156 | ||
153 | #define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ | 157 | #define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ |
154 | 158 | ||
155 | #define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ | 159 | #define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ |
156 | 160 | ||
157 | #define SM_ENDWATCH 0xAA /* Watchdog lock control page */ | 161 | #define SM_ENDWATCH 0xAA /* Watchdog lock control page */ |
158 | 162 | ||
159 | #define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ | 163 | #define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ |
160 | /* (Bit 3: 0 = seconds, 1 = minutes */ | 164 | /* (Bit 3: 0 = seconds, 1 = minutes */ |
161 | 165 | ||
162 | #define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ | 166 | #define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ |
163 | 167 | ||
164 | #define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ | 168 | #define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ |
165 | /* Bit 6: timer is reset by kbd interrupt */ | 169 | /* Bit 6: timer is reset by kbd interrupt */ |
166 | /* Bit 7: timer is reset by mouse interrupt */ | 170 | /* Bit 7: timer is reset by mouse interrupt */ |
167 | 171 | ||
168 | static void supermicro_new_unlock_watchdog(void) | 172 | static void supermicro_new_unlock_watchdog(void) |
169 | { | 173 | { |
170 | outb(SM_WATCHPAGE, SM_REGINDEX); /* Write 0x87 to port 0x2e twice */ | 174 | /* Write 0x87 to port 0x2e twice */ |
171 | outb(SM_WATCHPAGE, SM_REGINDEX); | 175 | outb(SM_WATCHPAGE, SM_REGINDEX); |
172 | 176 | outb(SM_WATCHPAGE, SM_REGINDEX); | |
173 | outb(SM_CTLPAGESW, SM_REGINDEX); /* Switch to watchdog control page */ | 177 | /* Switch to watchdog control page */ |
178 | outb(SM_CTLPAGESW, SM_REGINDEX); | ||
174 | outb(SM_CTLPAGE, SM_DATAIO); | 179 | outb(SM_CTLPAGE, SM_DATAIO); |
175 | } | 180 | } |
176 | 181 | ||
@@ -192,7 +197,7 @@ static void supermicro_new_pre_start(unsigned int heartbeat) | |||
192 | outb(val, SM_DATAIO); | 197 | outb(val, SM_DATAIO); |
193 | 198 | ||
194 | /* Write heartbeat interval to WDOG */ | 199 | /* Write heartbeat interval to WDOG */ |
195 | outb (SM_WATCHTIMER, SM_REGINDEX); | 200 | outb(SM_WATCHTIMER, SM_REGINDEX); |
196 | outb((heartbeat & 255), SM_DATAIO); | 201 | outb((heartbeat & 255), SM_DATAIO); |
197 | 202 | ||
198 | /* Make sure keyboard/mouse interrupts don't interfere */ | 203 | /* Make sure keyboard/mouse interrupts don't interfere */ |
@@ -277,7 +282,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat); | |||
277 | 282 | ||
278 | int iTCO_vendor_check_noreboot_on(void) | 283 | int iTCO_vendor_check_noreboot_on(void) |
279 | { | 284 | { |
280 | switch(vendorsupport) { | 285 | switch (vendorsupport) { |
281 | case SUPERMICRO_OLD_BOARD: | 286 | case SUPERMICRO_OLD_BOARD: |
282 | return 0; | 287 | return 0; |
283 | default: | 288 | default: |
@@ -288,13 +293,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); | |||
288 | 293 | ||
289 | static int __init iTCO_vendor_init_module(void) | 294 | static int __init iTCO_vendor_init_module(void) |
290 | { | 295 | { |
291 | printk (KERN_INFO PFX "vendor-support=%d\n", vendorsupport); | 296 | printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport); |
292 | return 0; | 297 | return 0; |
293 | } | 298 | } |
294 | 299 | ||
295 | static void __exit iTCO_vendor_exit_module(void) | 300 | static void __exit iTCO_vendor_exit_module(void) |
296 | { | 301 | { |
297 | printk (KERN_INFO PFX "Module Unloaded\n"); | 302 | printk(KERN_INFO PFX "Module Unloaded\n"); |
298 | } | 303 | } |
299 | 304 | ||
300 | module_init(iTCO_vendor_init_module); | 305 | module_init(iTCO_vendor_init_module); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 95ba985bd341..c9ca8f691d81 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -66,7 +66,8 @@ | |||
66 | #include <linux/types.h> /* For standard types (like size_t) */ | 66 | #include <linux/types.h> /* For standard types (like size_t) */ |
67 | #include <linux/errno.h> /* For the -ENODEV/... values */ | 67 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
68 | #include <linux/kernel.h> /* For printk/panic/... */ | 68 | #include <linux/kernel.h> /* For printk/panic/... */ |
69 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ | 69 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV |
70 | (WATCHDOG_MINOR) */ | ||
70 | #include <linux/watchdog.h> /* For the watchdog specific items */ | 71 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
71 | #include <linux/init.h> /* For __init/__exit/... */ | 72 | #include <linux/init.h> /* For __init/__exit/... */ |
72 | #include <linux/fs.h> /* For file operations */ | 73 | #include <linux/fs.h> /* For file operations */ |
@@ -74,9 +75,10 @@ | |||
74 | #include <linux/pci.h> /* For pci functions */ | 75 | #include <linux/pci.h> /* For pci functions */ |
75 | #include <linux/ioport.h> /* For io-port access */ | 76 | #include <linux/ioport.h> /* For io-port access */ |
76 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 77 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
78 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | ||
79 | #include <linux/io.h> /* For inb/outb/... */ | ||
77 | 80 | ||
78 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 81 | #include "iTCO_vendor.h" |
79 | #include <asm/io.h> /* For inb/outb/... */ | ||
80 | 82 | ||
81 | /* TCO related info */ | 83 | /* TCO related info */ |
82 | enum iTCO_chipsets { | 84 | enum iTCO_chipsets { |
@@ -140,7 +142,7 @@ static struct { | |||
140 | {"ICH9DH", 2}, | 142 | {"ICH9DH", 2}, |
141 | {"ICH9DO", 2}, | 143 | {"ICH9DO", 2}, |
142 | {"631xESB/632xESB", 2}, | 144 | {"631xESB/632xESB", 2}, |
143 | {NULL,0} | 145 | {NULL, 0} |
144 | }; | 146 | }; |
145 | 147 | ||
146 | #define ITCO_PCI_DEVICE(dev, data) \ | 148 | #define ITCO_PCI_DEVICE(dev, data) \ |
@@ -159,32 +161,32 @@ static struct { | |||
159 | * functions that probably will be registered by other drivers. | 161 | * functions that probably will be registered by other drivers. |
160 | */ | 162 | */ |
161 | static struct pci_device_id iTCO_wdt_pci_tbl[] = { | 163 | static struct pci_device_id iTCO_wdt_pci_tbl[] = { |
162 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH )}, | 164 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)}, |
163 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0 )}, | 165 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)}, |
164 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2 )}, | 166 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)}, |
165 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M )}, | 167 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M)}, |
166 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3 )}, | 168 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3)}, |
167 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M )}, | 169 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M)}, |
168 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4 )}, | 170 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4)}, |
169 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M )}, | 171 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M)}, |
170 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH )}, | 172 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH)}, |
171 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5 )}, | 173 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5)}, |
172 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, | 174 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, |
173 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6 )}, | 175 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)}, |
174 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M )}, | 176 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)}, |
175 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W )}, | 177 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)}, |
176 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7 )}, | 178 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)}, |
177 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M )}, | 179 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, |
178 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, | 180 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, |
179 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8 )}, | 181 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, |
180 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME )}, | 182 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)}, |
181 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH )}, | 183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, |
182 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO )}, | 184 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, |
183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M )}, | 185 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)}, |
184 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, | 186 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)}, |
185 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, | 187 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)}, |
186 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, | 188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)}, |
187 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO )}, | 189 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)}, |
188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, | 190 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, |
189 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, | 191 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, |
190 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, | 192 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, |
@@ -203,13 +205,15 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
203 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, | 205 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, |
204 | { 0, }, /* End of list */ | 206 | { 0, }, /* End of list */ |
205 | }; | 207 | }; |
206 | MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); | 208 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
207 | 209 | ||
208 | /* Address definitions for the TCO */ | 210 | /* Address definitions for the TCO */ |
209 | #define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* TCO base address */ | 211 | /* TCO base address */ |
210 | #define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 /* SMI Control and Enable Register */ | 212 | #define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 |
213 | /* SMI Control and Enable Register */ | ||
214 | #define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 | ||
211 | 215 | ||
212 | #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */ | 216 | #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ |
213 | #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ | 217 | #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ |
214 | #define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ | 218 | #define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ |
215 | #define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ | 219 | #define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ |
@@ -222,15 +226,21 @@ MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); | |||
222 | /* internal variables */ | 226 | /* internal variables */ |
223 | static unsigned long is_active; | 227 | static unsigned long is_active; |
224 | static char expect_release; | 228 | static char expect_release; |
225 | static struct { /* this is private data for the iTCO_wdt device */ | 229 | static struct { /* this is private data for the iTCO_wdt device */ |
226 | unsigned int iTCO_version; /* TCO version/generation */ | 230 | /* TCO version/generation */ |
227 | unsigned long ACPIBASE; /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ | 231 | unsigned int iTCO_version; |
228 | unsigned long __iomem *gcs; /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */ | 232 | /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ |
229 | spinlock_t io_lock; /* the lock for io operations */ | 233 | unsigned long ACPIBASE; |
230 | struct pci_dev *pdev; /* the PCI-device */ | 234 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ |
235 | unsigned long __iomem *gcs; | ||
236 | /* the lock for io operations */ | ||
237 | spinlock_t io_lock; | ||
238 | /* the PCI-device */ | ||
239 | struct pci_dev *pdev; | ||
231 | } iTCO_wdt_private; | 240 | } iTCO_wdt_private; |
232 | 241 | ||
233 | static struct platform_device *iTCO_wdt_platform_device; /* the watchdog platform device */ | 242 | /* the watchdog platform device */ |
243 | static struct platform_device *iTCO_wdt_platform_device; | ||
234 | 244 | ||
235 | /* module parameters */ | 245 | /* module parameters */ |
236 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 246 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
@@ -240,22 +250,9 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO | |||
240 | 250 | ||
241 | static int nowayout = WATCHDOG_NOWAYOUT; | 251 | static int nowayout = WATCHDOG_NOWAYOUT; |
242 | module_param(nowayout, int, 0); | 252 | module_param(nowayout, int, 0); |
243 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 253 | MODULE_PARM_DESC(nowayout, |
244 | 254 | "Watchdog cannot be stopped once started (default=" | |
245 | /* iTCO Vendor Specific Support hooks */ | 255 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
246 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | ||
247 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | ||
248 | extern void iTCO_vendor_pre_stop(unsigned long); | ||
249 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | ||
250 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | ||
251 | extern int iTCO_vendor_check_noreboot_on(void); | ||
252 | #else | ||
253 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | ||
254 | #define iTCO_vendor_pre_stop(acpibase) {} | ||
255 | #define iTCO_vendor_pre_keepalive(acpibase,heartbeat) {} | ||
256 | #define iTCO_vendor_pre_set_heartbeat(heartbeat) {} | ||
257 | #define iTCO_vendor_check_noreboot_on() 1 /* 1=check noreboot; 0=don't check */ | ||
258 | #endif | ||
259 | 256 | ||
260 | /* | 257 | /* |
261 | * Some TCO specific functions | 258 | * Some TCO specific functions |
@@ -369,11 +366,10 @@ static int iTCO_wdt_keepalive(void) | |||
369 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); | 366 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); |
370 | 367 | ||
371 | /* Reload the timer by writing to the TCO Timer Counter register */ | 368 | /* Reload the timer by writing to the TCO Timer Counter register */ |
372 | if (iTCO_wdt_private.iTCO_version == 2) { | 369 | if (iTCO_wdt_private.iTCO_version == 2) |
373 | outw(0x01, TCO_RLD); | 370 | outw(0x01, TCO_RLD); |
374 | } else if (iTCO_wdt_private.iTCO_version == 1) { | 371 | else if (iTCO_wdt_private.iTCO_version == 1) |
375 | outb(0x01, TCO_RLD); | 372 | outb(0x01, TCO_RLD); |
376 | } | ||
377 | 373 | ||
378 | spin_unlock(&iTCO_wdt_private.io_lock); | 374 | spin_unlock(&iTCO_wdt_private.io_lock); |
379 | return 0; | 375 | return 0; |
@@ -425,7 +421,7 @@ static int iTCO_wdt_set_heartbeat(int t) | |||
425 | return 0; | 421 | return 0; |
426 | } | 422 | } |
427 | 423 | ||
428 | static int iTCO_wdt_get_timeleft (int *time_left) | 424 | static int iTCO_wdt_get_timeleft(int *time_left) |
429 | { | 425 | { |
430 | unsigned int val16; | 426 | unsigned int val16; |
431 | unsigned char val8; | 427 | unsigned char val8; |
@@ -454,7 +450,7 @@ static int iTCO_wdt_get_timeleft (int *time_left) | |||
454 | * /dev/watchdog handling | 450 | * /dev/watchdog handling |
455 | */ | 451 | */ |
456 | 452 | ||
457 | static int iTCO_wdt_open (struct inode *inode, struct file *file) | 453 | static int iTCO_wdt_open(struct inode *inode, struct file *file) |
458 | { | 454 | { |
459 | /* /dev/watchdog can only be opened once */ | 455 | /* /dev/watchdog can only be opened once */ |
460 | if (test_and_set_bit(0, &is_active)) | 456 | if (test_and_set_bit(0, &is_active)) |
@@ -468,7 +464,7 @@ static int iTCO_wdt_open (struct inode *inode, struct file *file) | |||
468 | return nonseekable_open(inode, file); | 464 | return nonseekable_open(inode, file); |
469 | } | 465 | } |
470 | 466 | ||
471 | static int iTCO_wdt_release (struct inode *inode, struct file *file) | 467 | static int iTCO_wdt_release(struct inode *inode, struct file *file) |
472 | { | 468 | { |
473 | /* | 469 | /* |
474 | * Shut off the timer. | 470 | * Shut off the timer. |
@@ -476,7 +472,8 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file) | |||
476 | if (expect_release == 42) { | 472 | if (expect_release == 42) { |
477 | iTCO_wdt_stop(); | 473 | iTCO_wdt_stop(); |
478 | } else { | 474 | } else { |
479 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 475 | printk(KERN_CRIT PFX |
476 | "Unexpected close, not stopping watchdog!\n"); | ||
480 | iTCO_wdt_keepalive(); | 477 | iTCO_wdt_keepalive(); |
481 | } | 478 | } |
482 | clear_bit(0, &is_active); | 479 | clear_bit(0, &is_active); |
@@ -484,19 +481,20 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file) | |||
484 | return 0; | 481 | return 0; |
485 | } | 482 | } |
486 | 483 | ||
487 | static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, | 484 | static ssize_t iTCO_wdt_write(struct file *file, const char __user *data, |
488 | size_t len, loff_t * ppos) | 485 | size_t len, loff_t *ppos) |
489 | { | 486 | { |
490 | /* See if we got the magic character 'V' and reload the timer */ | 487 | /* See if we got the magic character 'V' and reload the timer */ |
491 | if (len) { | 488 | if (len) { |
492 | if (!nowayout) { | 489 | if (!nowayout) { |
493 | size_t i; | 490 | size_t i; |
494 | 491 | ||
495 | /* note: just in case someone wrote the magic character | 492 | /* note: just in case someone wrote the magic |
496 | * five months ago... */ | 493 | character five months ago... */ |
497 | expect_release = 0; | 494 | expect_release = 0; |
498 | 495 | ||
499 | /* scan to see whether or not we got the magic character */ | 496 | /* scan to see whether or not we got the |
497 | magic character */ | ||
500 | for (i = 0; i != len; i++) { | 498 | for (i = 0; i != len; i++) { |
501 | char c; | 499 | char c; |
502 | if (get_user(c, data+i)) | 500 | if (get_user(c, data+i)) |
@@ -512,8 +510,8 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, | |||
512 | return len; | 510 | return len; |
513 | } | 511 | } |
514 | 512 | ||
515 | static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | 513 | static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, |
516 | unsigned int cmd, unsigned long arg) | 514 | unsigned long arg) |
517 | { | 515 | { |
518 | int new_options, retval = -EINVAL; | 516 | int new_options, retval = -EINVAL; |
519 | int new_heartbeat; | 517 | int new_heartbeat; |
@@ -528,64 +526,52 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
528 | }; | 526 | }; |
529 | 527 | ||
530 | switch (cmd) { | 528 | switch (cmd) { |
531 | case WDIOC_GETSUPPORT: | 529 | case WDIOC_GETSUPPORT: |
532 | return copy_to_user(argp, &ident, | 530 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
533 | sizeof (ident)) ? -EFAULT : 0; | 531 | case WDIOC_GETSTATUS: |
534 | 532 | case WDIOC_GETBOOTSTATUS: | |
535 | case WDIOC_GETSTATUS: | 533 | return put_user(0, p); |
536 | case WDIOC_GETBOOTSTATUS: | ||
537 | return put_user(0, p); | ||
538 | |||
539 | case WDIOC_KEEPALIVE: | ||
540 | iTCO_wdt_keepalive(); | ||
541 | return 0; | ||
542 | 534 | ||
543 | case WDIOC_SETOPTIONS: | 535 | case WDIOC_KEEPALIVE: |
544 | { | 536 | iTCO_wdt_keepalive(); |
545 | if (get_user(new_options, p)) | 537 | return 0; |
546 | return -EFAULT; | ||
547 | |||
548 | if (new_options & WDIOS_DISABLECARD) { | ||
549 | iTCO_wdt_stop(); | ||
550 | retval = 0; | ||
551 | } | ||
552 | 538 | ||
553 | if (new_options & WDIOS_ENABLECARD) { | 539 | case WDIOC_SETOPTIONS: |
554 | iTCO_wdt_keepalive(); | 540 | { |
555 | iTCO_wdt_start(); | 541 | if (get_user(new_options, p)) |
556 | retval = 0; | 542 | return -EFAULT; |
557 | } | ||
558 | 543 | ||
559 | return retval; | 544 | if (new_options & WDIOS_DISABLECARD) { |
545 | iTCO_wdt_stop(); | ||
546 | retval = 0; | ||
560 | } | 547 | } |
561 | 548 | if (new_options & WDIOS_ENABLECARD) { | |
562 | case WDIOC_SETTIMEOUT: | ||
563 | { | ||
564 | if (get_user(new_heartbeat, p)) | ||
565 | return -EFAULT; | ||
566 | |||
567 | if (iTCO_wdt_set_heartbeat(new_heartbeat)) | ||
568 | return -EINVAL; | ||
569 | |||
570 | iTCO_wdt_keepalive(); | 549 | iTCO_wdt_keepalive(); |
571 | /* Fall */ | 550 | iTCO_wdt_start(); |
551 | retval = 0; | ||
572 | } | 552 | } |
573 | 553 | return retval; | |
574 | case WDIOC_GETTIMEOUT: | 554 | } |
575 | return put_user(heartbeat, p); | 555 | case WDIOC_SETTIMEOUT: |
576 | 556 | { | |
577 | case WDIOC_GETTIMELEFT: | 557 | if (get_user(new_heartbeat, p)) |
578 | { | 558 | return -EFAULT; |
579 | int time_left; | 559 | if (iTCO_wdt_set_heartbeat(new_heartbeat)) |
580 | 560 | return -EINVAL; | |
581 | if (iTCO_wdt_get_timeleft(&time_left)) | 561 | iTCO_wdt_keepalive(); |
582 | return -EINVAL; | 562 | /* Fall */ |
583 | 563 | } | |
584 | return put_user(time_left, p); | 564 | case WDIOC_GETTIMEOUT: |
585 | } | 565 | return put_user(heartbeat, p); |
586 | 566 | case WDIOC_GETTIMELEFT: | |
587 | default: | 567 | { |
588 | return -ENOTTY; | 568 | int time_left; |
569 | if (iTCO_wdt_get_timeleft(&time_left)) | ||
570 | return -EINVAL; | ||
571 | return put_user(time_left, p); | ||
572 | } | ||
573 | default: | ||
574 | return -ENOTTY; | ||
589 | } | 575 | } |
590 | } | 576 | } |
591 | 577 | ||
@@ -594,12 +580,12 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
594 | */ | 580 | */ |
595 | 581 | ||
596 | static const struct file_operations iTCO_wdt_fops = { | 582 | static const struct file_operations iTCO_wdt_fops = { |
597 | .owner = THIS_MODULE, | 583 | .owner = THIS_MODULE, |
598 | .llseek = no_llseek, | 584 | .llseek = no_llseek, |
599 | .write = iTCO_wdt_write, | 585 | .write = iTCO_wdt_write, |
600 | .ioctl = iTCO_wdt_ioctl, | 586 | .unlocked_ioctl = iTCO_wdt_ioctl, |
601 | .open = iTCO_wdt_open, | 587 | .open = iTCO_wdt_open, |
602 | .release = iTCO_wdt_release, | 588 | .release = iTCO_wdt_release, |
603 | }; | 589 | }; |
604 | 590 | ||
605 | static struct miscdevice iTCO_wdt_miscdev = { | 591 | static struct miscdevice iTCO_wdt_miscdev = { |
@@ -612,7 +598,8 @@ static struct miscdevice iTCO_wdt_miscdev = { | |||
612 | * Init & exit routines | 598 | * Init & exit routines |
613 | */ | 599 | */ |
614 | 600 | ||
615 | static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev) | 601 | static int __devinit iTCO_wdt_init(struct pci_dev *pdev, |
602 | const struct pci_device_id *ent, struct platform_device *dev) | ||
616 | { | 603 | { |
617 | int ret; | 604 | int ret; |
618 | u32 base_address; | 605 | u32 base_address; |
@@ -632,17 +619,19 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
632 | pci_dev_put(pdev); | 619 | pci_dev_put(pdev); |
633 | return -ENODEV; | 620 | return -ENODEV; |
634 | } | 621 | } |
635 | iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version; | 622 | iTCO_wdt_private.iTCO_version = |
623 | iTCO_chipset_info[ent->driver_data].iTCO_version; | ||
636 | iTCO_wdt_private.ACPIBASE = base_address; | 624 | iTCO_wdt_private.ACPIBASE = base_address; |
637 | iTCO_wdt_private.pdev = pdev; | 625 | iTCO_wdt_private.pdev = pdev; |
638 | 626 | ||
639 | /* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */ | 627 | /* Get the Memory-Mapped GCS register, we need it for the |
640 | /* To get access to it you have to read RCBA from PCI Config space 0xf0 | 628 | NO_REBOOT flag (TCO v2). To get access to it you have to |
641 | and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */ | 629 | read RCBA from PCI Config space 0xf0 and use it as base. |
630 | GCS = RCBA + ICH6_GCS(0x3410). */ | ||
642 | if (iTCO_wdt_private.iTCO_version == 2) { | 631 | if (iTCO_wdt_private.iTCO_version == 2) { |
643 | pci_read_config_dword(pdev, 0xf0, &base_address); | 632 | pci_read_config_dword(pdev, 0xf0, &base_address); |
644 | RCBA = base_address & 0xffffc000; | 633 | RCBA = base_address & 0xffffc000; |
645 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4); | 634 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); |
646 | } | 635 | } |
647 | 636 | ||
648 | /* Check chipset's NO_REBOOT bit */ | 637 | /* Check chipset's NO_REBOOT bit */ |
@@ -657,8 +646,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
657 | 646 | ||
658 | /* Set the TCO_EN bit in SMI_EN register */ | 647 | /* Set the TCO_EN bit in SMI_EN register */ |
659 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { | 648 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { |
660 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 649 | printk(KERN_ERR PFX |
661 | SMI_EN ); | 650 | "I/O address 0x%04lx already in use\n", SMI_EN); |
662 | ret = -EIO; | 651 | ret = -EIO; |
663 | goto out; | 652 | goto out; |
664 | } | 653 | } |
@@ -667,18 +656,20 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
667 | outl(val32, SMI_EN); | 656 | outl(val32, SMI_EN); |
668 | release_region(SMI_EN, 4); | 657 | release_region(SMI_EN, 4); |
669 | 658 | ||
670 | /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ | 659 | /* The TCO I/O registers reside in a 32-byte range pointed to |
671 | if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) { | 660 | by the TCOBASE value */ |
672 | printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 661 | if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { |
662 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | ||
673 | TCOBASE); | 663 | TCOBASE); |
674 | ret = -EIO; | 664 | ret = -EIO; |
675 | goto out; | 665 | goto out; |
676 | } | 666 | } |
677 | 667 | ||
678 | printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", | 668 | printk(KERN_INFO PFX |
679 | iTCO_chipset_info[ent->driver_data].name, | 669 | "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", |
680 | iTCO_chipset_info[ent->driver_data].iTCO_version, | 670 | iTCO_chipset_info[ent->driver_data].name, |
681 | TCOBASE); | 671 | iTCO_chipset_info[ent->driver_data].iTCO_version, |
672 | TCOBASE); | ||
682 | 673 | ||
683 | /* Clear out the (probably old) status */ | 674 | /* Clear out the (probably old) status */ |
684 | outb(0, TCO1_STS); | 675 | outb(0, TCO1_STS); |
@@ -687,27 +678,29 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
687 | /* Make sure the watchdog is not running */ | 678 | /* Make sure the watchdog is not running */ |
688 | iTCO_wdt_stop(); | 679 | iTCO_wdt_stop(); |
689 | 680 | ||
690 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 681 | /* Check that the heartbeat value is within it's range; |
682 | if not reset to the default */ | ||
691 | if (iTCO_wdt_set_heartbeat(heartbeat)) { | 683 | if (iTCO_wdt_set_heartbeat(heartbeat)) { |
692 | iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); | 684 | iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); |
693 | printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n", | 685 | printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n", |
694 | heartbeat); | 686 | heartbeat); |
695 | } | 687 | } |
696 | 688 | ||
697 | ret = misc_register(&iTCO_wdt_miscdev); | 689 | ret = misc_register(&iTCO_wdt_miscdev); |
698 | if (ret != 0) { | 690 | if (ret != 0) { |
699 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 691 | printk(KERN_ERR PFX |
700 | WATCHDOG_MINOR, ret); | 692 | "cannot register miscdev on minor=%d (err=%d)\n", |
693 | WATCHDOG_MINOR, ret); | ||
701 | goto unreg_region; | 694 | goto unreg_region; |
702 | } | 695 | } |
703 | 696 | ||
704 | printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 697 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", |
705 | heartbeat, nowayout); | 698 | heartbeat, nowayout); |
706 | 699 | ||
707 | return 0; | 700 | return 0; |
708 | 701 | ||
709 | unreg_region: | 702 | unreg_region: |
710 | release_region (TCOBASE, 0x20); | 703 | release_region(TCOBASE, 0x20); |
711 | out: | 704 | out: |
712 | if (iTCO_wdt_private.iTCO_version == 2) | 705 | if (iTCO_wdt_private.iTCO_version == 2) |
713 | iounmap(iTCO_wdt_private.gcs); | 706 | iounmap(iTCO_wdt_private.gcs); |
@@ -796,7 +789,8 @@ static int __init iTCO_wdt_init_module(void) | |||
796 | if (err) | 789 | if (err) |
797 | return err; | 790 | return err; |
798 | 791 | ||
799 | iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 792 | iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, |
793 | -1, NULL, 0); | ||
800 | if (IS_ERR(iTCO_wdt_platform_device)) { | 794 | if (IS_ERR(iTCO_wdt_platform_device)) { |
801 | err = PTR_ERR(iTCO_wdt_platform_device); | 795 | err = PTR_ERR(iTCO_wdt_platform_device); |
802 | goto unreg_platform_driver; | 796 | goto unreg_platform_driver; |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 4b89f401691a..805a54b02aa1 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -42,8 +42,8 @@ | |||
42 | #include <linux/moduleparam.h> | 42 | #include <linux/moduleparam.h> |
43 | #include <linux/platform_device.h> | 43 | #include <linux/platform_device.h> |
44 | 44 | ||
45 | #include <asm/io.h> | 45 | #include <linux/io.h> |
46 | #include <asm/uaccess.h> | 46 | #include <linux/uaccess.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | 48 | ||
49 | static struct platform_device *ibwdt_platform_device; | 49 | static struct platform_device *ibwdt_platform_device; |
@@ -120,7 +120,9 @@ static int wd_margin = WD_TIMO; | |||
120 | 120 | ||
121 | static int nowayout = WATCHDOG_NOWAYOUT; | 121 | static int nowayout = WATCHDOG_NOWAYOUT; |
122 | module_param(nowayout, int, 0); | 122 | module_param(nowayout, int, 0); |
123 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 123 | MODULE_PARM_DESC(nowayout, |
124 | "Watchdog cannot be stopped once started (default=" | ||
125 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
124 | 126 | ||
125 | 127 | ||
126 | /* | 128 | /* |
@@ -165,8 +167,8 @@ ibwdt_set_heartbeat(int t) | |||
165 | * /dev/watchdog handling | 167 | * /dev/watchdog handling |
166 | */ | 168 | */ |
167 | 169 | ||
168 | static ssize_t | 170 | static ssize_t ibwdt_write(struct file *file, const char __user *buf, |
169 | ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 171 | size_t count, loff_t *ppos) |
170 | { | 172 | { |
171 | if (count) { | 173 | if (count) { |
172 | if (!nowayout) { | 174 | if (!nowayout) { |
@@ -188,77 +190,71 @@ ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo | |||
188 | return count; | 190 | return count; |
189 | } | 191 | } |
190 | 192 | ||
191 | static int | 193 | static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
192 | ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
193 | unsigned long arg) | ||
194 | { | 194 | { |
195 | int new_margin; | 195 | int new_margin; |
196 | void __user *argp = (void __user *)arg; | 196 | void __user *argp = (void __user *)arg; |
197 | int __user *p = argp; | 197 | int __user *p = argp; |
198 | 198 | ||
199 | static struct watchdog_info ident = { | 199 | static struct watchdog_info ident = { |
200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
201 | | WDIOF_MAGICCLOSE, | ||
201 | .firmware_version = 1, | 202 | .firmware_version = 1, |
202 | .identity = "IB700 WDT", | 203 | .identity = "IB700 WDT", |
203 | }; | 204 | }; |
204 | 205 | ||
205 | switch (cmd) { | 206 | switch (cmd) { |
206 | case WDIOC_GETSUPPORT: | 207 | case WDIOC_GETSUPPORT: |
207 | if (copy_to_user(argp, &ident, sizeof(ident))) | 208 | if (copy_to_user(argp, &ident, sizeof(ident))) |
208 | return -EFAULT; | 209 | return -EFAULT; |
209 | break; | 210 | break; |
210 | 211 | ||
211 | case WDIOC_GETSTATUS: | 212 | case WDIOC_GETSTATUS: |
212 | case WDIOC_GETBOOTSTATUS: | 213 | case WDIOC_GETBOOTSTATUS: |
213 | return put_user(0, p); | 214 | return put_user(0, p); |
214 | 215 | ||
215 | case WDIOC_KEEPALIVE: | 216 | case WDIOC_KEEPALIVE: |
216 | ibwdt_ping(); | 217 | ibwdt_ping(); |
217 | break; | 218 | break; |
218 | 219 | ||
219 | case WDIOC_SETTIMEOUT: | 220 | case WDIOC_SETTIMEOUT: |
220 | if (get_user(new_margin, p)) | 221 | if (get_user(new_margin, p)) |
221 | return -EFAULT; | 222 | return -EFAULT; |
222 | if (ibwdt_set_heartbeat(new_margin)) | 223 | if (ibwdt_set_heartbeat(new_margin)) |
223 | return -EINVAL; | 224 | return -EINVAL; |
224 | ibwdt_ping(); | 225 | ibwdt_ping(); |
225 | /* Fall */ | 226 | /* Fall */ |
226 | 227 | ||
227 | case WDIOC_GETTIMEOUT: | 228 | case WDIOC_GETTIMEOUT: |
228 | return put_user(wd_times[wd_margin], p); | 229 | return put_user(wd_times[wd_margin], p); |
229 | 230 | ||
230 | case WDIOC_SETOPTIONS: | 231 | case WDIOC_SETOPTIONS: |
231 | { | 232 | { |
232 | int options, retval = -EINVAL; | 233 | int options, retval = -EINVAL; |
233 | 234 | ||
234 | if (get_user(options, p)) | 235 | if (get_user(options, p)) |
235 | return -EFAULT; | 236 | return -EFAULT; |
236 | 237 | ||
237 | if (options & WDIOS_DISABLECARD) { | 238 | if (options & WDIOS_DISABLECARD) { |
238 | ibwdt_disable(); | 239 | ibwdt_disable(); |
239 | retval = 0; | 240 | retval = 0; |
240 | } | 241 | } |
241 | 242 | if (options & WDIOS_ENABLECARD) { | |
242 | if (options & WDIOS_ENABLECARD) { | 243 | ibwdt_ping(); |
243 | ibwdt_ping(); | 244 | retval = 0; |
244 | retval = 0; | 245 | } |
245 | } | 246 | return retval; |
246 | |||
247 | return retval; | ||
248 | } | 247 | } |
249 | |||
250 | default: | 248 | default: |
251 | return -ENOTTY; | 249 | return -ENOTTY; |
252 | } | 250 | } |
253 | return 0; | 251 | return 0; |
254 | } | 252 | } |
255 | 253 | ||
256 | static int | 254 | static int ibwdt_open(struct inode *inode, struct file *file) |
257 | ibwdt_open(struct inode *inode, struct file *file) | ||
258 | { | 255 | { |
259 | if (test_and_set_bit(0, &ibwdt_is_open)) { | 256 | if (test_and_set_bit(0, &ibwdt_is_open)) |
260 | return -EBUSY; | 257 | return -EBUSY; |
261 | } | ||
262 | if (nowayout) | 258 | if (nowayout) |
263 | __module_get(THIS_MODULE); | 259 | __module_get(THIS_MODULE); |
264 | 260 | ||
@@ -273,7 +269,8 @@ ibwdt_close(struct inode *inode, struct file *file) | |||
273 | if (expect_close == 42) { | 269 | if (expect_close == 42) { |
274 | ibwdt_disable(); | 270 | ibwdt_disable(); |
275 | } else { | 271 | } else { |
276 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 272 | printk(KERN_CRIT PFX |
273 | "WDT device closed unexpectedly. WDT will not stop!\n"); | ||
277 | ibwdt_ping(); | 274 | ibwdt_ping(); |
278 | } | 275 | } |
279 | clear_bit(0, &ibwdt_is_open); | 276 | clear_bit(0, &ibwdt_is_open); |
@@ -289,7 +286,7 @@ static const struct file_operations ibwdt_fops = { | |||
289 | .owner = THIS_MODULE, | 286 | .owner = THIS_MODULE, |
290 | .llseek = no_llseek, | 287 | .llseek = no_llseek, |
291 | .write = ibwdt_write, | 288 | .write = ibwdt_write, |
292 | .ioctl = ibwdt_ioctl, | 289 | .unlocked_ioctl = ibwdt_ioctl, |
293 | .open = ibwdt_open, | 290 | .open = ibwdt_open, |
294 | .release = ibwdt_close, | 291 | .release = ibwdt_close, |
295 | }; | 292 | }; |
@@ -310,21 +307,23 @@ static int __devinit ibwdt_probe(struct platform_device *dev) | |||
310 | 307 | ||
311 | #if WDT_START != WDT_STOP | 308 | #if WDT_START != WDT_STOP |
312 | if (!request_region(WDT_STOP, 1, "IB700 WDT")) { | 309 | if (!request_region(WDT_STOP, 1, "IB700 WDT")) { |
313 | printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP); | 310 | printk(KERN_ERR PFX "STOP method I/O %X is not available.\n", |
311 | WDT_STOP); | ||
314 | res = -EIO; | 312 | res = -EIO; |
315 | goto out_nostopreg; | 313 | goto out_nostopreg; |
316 | } | 314 | } |
317 | #endif | 315 | #endif |
318 | 316 | ||
319 | if (!request_region(WDT_START, 1, "IB700 WDT")) { | 317 | if (!request_region(WDT_START, 1, "IB700 WDT")) { |
320 | printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START); | 318 | printk(KERN_ERR PFX "START method I/O %X is not available.\n", |
319 | WDT_START); | ||
321 | res = -EIO; | 320 | res = -EIO; |
322 | goto out_nostartreg; | 321 | goto out_nostartreg; |
323 | } | 322 | } |
324 | 323 | ||
325 | res = misc_register(&ibwdt_miscdev); | 324 | res = misc_register(&ibwdt_miscdev); |
326 | if (res) { | 325 | if (res) { |
327 | printk (KERN_ERR PFX "failed to register misc device\n"); | 326 | printk(KERN_ERR PFX "failed to register misc device\n"); |
328 | goto out_nomisc; | 327 | goto out_nomisc; |
329 | } | 328 | } |
330 | return 0; | 329 | return 0; |
@@ -342,9 +341,9 @@ out_nostopreg: | |||
342 | static int __devexit ibwdt_remove(struct platform_device *dev) | 341 | static int __devexit ibwdt_remove(struct platform_device *dev) |
343 | { | 342 | { |
344 | misc_deregister(&ibwdt_miscdev); | 343 | misc_deregister(&ibwdt_miscdev); |
345 | release_region(WDT_START,1); | 344 | release_region(WDT_START, 1); |
346 | #if WDT_START != WDT_STOP | 345 | #if WDT_START != WDT_STOP |
347 | release_region(WDT_STOP,1); | 346 | release_region(WDT_STOP, 1); |
348 | #endif | 347 | #endif |
349 | return 0; | 348 | return 0; |
350 | } | 349 | } |
@@ -369,13 +368,15 @@ static int __init ibwdt_init(void) | |||
369 | { | 368 | { |
370 | int err; | 369 | int err; |
371 | 370 | ||
372 | printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n"); | 371 | printk(KERN_INFO PFX |
372 | "WDT driver for IB700 single board computer initialising.\n"); | ||
373 | 373 | ||
374 | err = platform_driver_register(&ibwdt_driver); | 374 | err = platform_driver_register(&ibwdt_driver); |
375 | if (err) | 375 | if (err) |
376 | return err; | 376 | return err; |
377 | 377 | ||
378 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 378 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, |
379 | -1, NULL, 0); | ||
379 | if (IS_ERR(ibwdt_platform_device)) { | 380 | if (IS_ERR(ibwdt_platform_device)) { |
380 | err = PTR_ERR(ibwdt_platform_device); | 381 | err = PTR_ERR(ibwdt_platform_device); |
381 | goto unreg_platform_driver; | 382 | goto unreg_platform_driver; |
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index 94155f6136c2..6824bf80b37e 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c | |||
@@ -19,9 +19,8 @@ | |||
19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
22 | 22 | #include <linux/io.h> | |
23 | #include <asm/io.h> | 23 | #include <linux/uaccess.h> |
24 | #include <asm/uaccess.h> | ||
25 | 24 | ||
26 | 25 | ||
27 | enum { | 26 | enum { |
@@ -70,10 +69,13 @@ static char asr_expect_close; | |||
70 | static unsigned int asr_type, asr_base, asr_length; | 69 | static unsigned int asr_type, asr_base, asr_length; |
71 | static unsigned int asr_read_addr, asr_write_addr; | 70 | static unsigned int asr_read_addr, asr_write_addr; |
72 | static unsigned char asr_toggle_mask, asr_disable_mask; | 71 | static unsigned char asr_toggle_mask, asr_disable_mask; |
72 | static spinlock_t asr_lock; | ||
73 | 73 | ||
74 | static void asr_toggle(void) | 74 | static void __asr_toggle(void) |
75 | { | 75 | { |
76 | unsigned char reg = inb(asr_read_addr); | 76 | unsigned char reg; |
77 | |||
78 | reg = inb(asr_read_addr); | ||
77 | 79 | ||
78 | outb(reg & ~asr_toggle_mask, asr_write_addr); | 80 | outb(reg & ~asr_toggle_mask, asr_write_addr); |
79 | reg = inb(asr_read_addr); | 81 | reg = inb(asr_read_addr); |
@@ -83,12 +85,21 @@ static void asr_toggle(void) | |||
83 | 85 | ||
84 | outb(reg & ~asr_toggle_mask, asr_write_addr); | 86 | outb(reg & ~asr_toggle_mask, asr_write_addr); |
85 | reg = inb(asr_read_addr); | 87 | reg = inb(asr_read_addr); |
88 | spin_unlock(&asr_lock); | ||
89 | } | ||
90 | |||
91 | static void asr_toggle(void) | ||
92 | { | ||
93 | spin_lock(&asr_lock); | ||
94 | __asr_toggle(); | ||
95 | spin_unlock(&asr_lock); | ||
86 | } | 96 | } |
87 | 97 | ||
88 | static void asr_enable(void) | 98 | static void asr_enable(void) |
89 | { | 99 | { |
90 | unsigned char reg; | 100 | unsigned char reg; |
91 | 101 | ||
102 | spin_lock(&asr_lock); | ||
92 | if (asr_type == ASMTYPE_TOPAZ) { | 103 | if (asr_type == ASMTYPE_TOPAZ) { |
93 | /* asr_write_addr == asr_read_addr */ | 104 | /* asr_write_addr == asr_read_addr */ |
94 | reg = inb(asr_read_addr); | 105 | reg = inb(asr_read_addr); |
@@ -99,17 +110,21 @@ static void asr_enable(void) | |||
99 | * First make sure the hardware timer is reset by toggling | 110 | * First make sure the hardware timer is reset by toggling |
100 | * ASR hardware timer line. | 111 | * ASR hardware timer line. |
101 | */ | 112 | */ |
102 | asr_toggle(); | 113 | __asr_toggle(); |
103 | 114 | ||
104 | reg = inb(asr_read_addr); | 115 | reg = inb(asr_read_addr); |
105 | outb(reg & ~asr_disable_mask, asr_write_addr); | 116 | outb(reg & ~asr_disable_mask, asr_write_addr); |
106 | } | 117 | } |
107 | reg = inb(asr_read_addr); | 118 | reg = inb(asr_read_addr); |
119 | spin_unlock(&asr_lock); | ||
108 | } | 120 | } |
109 | 121 | ||
110 | static void asr_disable(void) | 122 | static void asr_disable(void) |
111 | { | 123 | { |
112 | unsigned char reg = inb(asr_read_addr); | 124 | unsigned char reg; |
125 | |||
126 | spin_lock(&asr_lock); | ||
127 | reg = inb(asr_read_addr); | ||
113 | 128 | ||
114 | if (asr_type == ASMTYPE_TOPAZ) | 129 | if (asr_type == ASMTYPE_TOPAZ) |
115 | /* asr_write_addr == asr_read_addr */ | 130 | /* asr_write_addr == asr_read_addr */ |
@@ -122,6 +137,7 @@ static void asr_disable(void) | |||
122 | outb(reg | asr_disable_mask, asr_write_addr); | 137 | outb(reg | asr_disable_mask, asr_write_addr); |
123 | } | 138 | } |
124 | reg = inb(asr_read_addr); | 139 | reg = inb(asr_read_addr); |
140 | spin_unlock(&asr_lock); | ||
125 | } | 141 | } |
126 | 142 | ||
127 | static int __init asr_get_base_address(void) | 143 | static int __init asr_get_base_address(void) |
@@ -133,7 +149,8 @@ static int __init asr_get_base_address(void) | |||
133 | 149 | ||
134 | switch (asr_type) { | 150 | switch (asr_type) { |
135 | case ASMTYPE_TOPAZ: | 151 | case ASMTYPE_TOPAZ: |
136 | /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ | 152 | /* SELECT SuperIO CHIP FOR QUERYING |
153 | (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ | ||
137 | outb(0x07, 0x2e); | 154 | outb(0x07, 0x2e); |
138 | outb(0x07, 0x2f); | 155 | outb(0x07, 0x2f); |
139 | 156 | ||
@@ -154,14 +171,26 @@ static int __init asr_get_base_address(void) | |||
154 | 171 | ||
155 | case ASMTYPE_JASPER: | 172 | case ASMTYPE_JASPER: |
156 | type = "Jaspers "; | 173 | type = "Jaspers "; |
157 | 174 | #if 0 | |
158 | /* FIXME: need to use pci_config_lock here, but it's not exported */ | 175 | u32 r; |
176 | /* Suggested fix */ | ||
177 | pdev = pci_get_bus_and_slot(0, DEVFN(0x1f, 0)); | ||
178 | if (pdev == NULL) | ||
179 | return -ENODEV; | ||
180 | pci_read_config_dword(pdev, 0x58, &r); | ||
181 | asr_base = r & 0xFFFE; | ||
182 | pci_dev_put(pdev); | ||
183 | #else | ||
184 | /* FIXME: need to use pci_config_lock here, | ||
185 | but it's not exported */ | ||
159 | 186 | ||
160 | /* spin_lock_irqsave(&pci_config_lock, flags);*/ | 187 | /* spin_lock_irqsave(&pci_config_lock, flags);*/ |
161 | 188 | ||
162 | /* Select the SuperIO chip in the PCI I/O port register */ | 189 | /* Select the SuperIO chip in the PCI I/O port register */ |
163 | outl(0x8000f858, 0xcf8); | 190 | outl(0x8000f858, 0xcf8); |
164 | 191 | ||
192 | /* BUS 0, Slot 1F, fnc 0, offset 58 */ | ||
193 | |||
165 | /* | 194 | /* |
166 | * Read the base address for the SuperIO chip. | 195 | * Read the base address for the SuperIO chip. |
167 | * Only the lower 16 bits are valid, but the address is word | 196 | * Only the lower 16 bits are valid, but the address is word |
@@ -170,7 +199,7 @@ static int __init asr_get_base_address(void) | |||
170 | asr_base = inl(0xcfc) & 0xfffe; | 199 | asr_base = inl(0xcfc) & 0xfffe; |
171 | 200 | ||
172 | /* spin_unlock_irqrestore(&pci_config_lock, flags);*/ | 201 | /* spin_unlock_irqrestore(&pci_config_lock, flags);*/ |
173 | 202 | #endif | |
174 | asr_read_addr = asr_write_addr = | 203 | asr_read_addr = asr_write_addr = |
175 | asr_base + JASPER_ASR_REG_OFFSET; | 204 | asr_base + JASPER_ASR_REG_OFFSET; |
176 | asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; | 205 | asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; |
@@ -241,11 +270,10 @@ static ssize_t asr_write(struct file *file, const char __user *buf, | |||
241 | return count; | 270 | return count; |
242 | } | 271 | } |
243 | 272 | ||
244 | static int asr_ioctl(struct inode *inode, struct file *file, | 273 | static long asr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
245 | unsigned int cmd, unsigned long arg) | ||
246 | { | 274 | { |
247 | static const struct watchdog_info ident = { | 275 | static const struct watchdog_info ident = { |
248 | .options = WDIOF_KEEPALIVEPING | | 276 | .options = WDIOF_KEEPALIVEPING | |
249 | WDIOF_MAGICCLOSE, | 277 | WDIOF_MAGICCLOSE, |
250 | .identity = "IBM ASR" | 278 | .identity = "IBM ASR" |
251 | }; | 279 | }; |
@@ -254,53 +282,45 @@ static int asr_ioctl(struct inode *inode, struct file *file, | |||
254 | int heartbeat; | 282 | int heartbeat; |
255 | 283 | ||
256 | switch (cmd) { | 284 | switch (cmd) { |
257 | case WDIOC_GETSUPPORT: | 285 | case WDIOC_GETSUPPORT: |
258 | return copy_to_user(argp, &ident, sizeof(ident)) ? | 286 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
259 | -EFAULT : 0; | 287 | case WDIOC_GETSTATUS: |
260 | 288 | case WDIOC_GETBOOTSTATUS: | |
261 | case WDIOC_GETSTATUS: | 289 | return put_user(0, p); |
262 | case WDIOC_GETBOOTSTATUS: | 290 | case WDIOC_KEEPALIVE: |
263 | return put_user(0, p); | 291 | asr_toggle(); |
264 | 292 | return 0; | |
265 | case WDIOC_KEEPALIVE: | 293 | /* |
294 | * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT | ||
295 | * and WDIOC_GETTIMEOUT always returns 256. | ||
296 | */ | ||
297 | case WDIOC_GETTIMEOUT: | ||
298 | heartbeat = 256; | ||
299 | return put_user(heartbeat, p); | ||
300 | case WDIOC_SETOPTIONS: | ||
301 | { | ||
302 | int new_options, retval = -EINVAL; | ||
303 | if (get_user(new_options, p)) | ||
304 | return -EFAULT; | ||
305 | if (new_options & WDIOS_DISABLECARD) { | ||
306 | asr_disable(); | ||
307 | retval = 0; | ||
308 | } | ||
309 | if (new_options & WDIOS_ENABLECARD) { | ||
310 | asr_enable(); | ||
266 | asr_toggle(); | 311 | asr_toggle(); |
267 | return 0; | 312 | retval = 0; |
268 | |||
269 | /* | ||
270 | * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT | ||
271 | * and WDIOC_GETTIMEOUT always returns 256. | ||
272 | */ | ||
273 | case WDIOC_GETTIMEOUT: | ||
274 | heartbeat = 256; | ||
275 | return put_user(heartbeat, p); | ||
276 | |||
277 | case WDIOC_SETOPTIONS: { | ||
278 | int new_options, retval = -EINVAL; | ||
279 | |||
280 | if (get_user(new_options, p)) | ||
281 | return -EFAULT; | ||
282 | |||
283 | if (new_options & WDIOS_DISABLECARD) { | ||
284 | asr_disable(); | ||
285 | retval = 0; | ||
286 | } | ||
287 | |||
288 | if (new_options & WDIOS_ENABLECARD) { | ||
289 | asr_enable(); | ||
290 | asr_toggle(); | ||
291 | retval = 0; | ||
292 | } | ||
293 | |||
294 | return retval; | ||
295 | } | 313 | } |
314 | return retval; | ||
315 | } | ||
316 | default: | ||
317 | return -ENOTTY; | ||
296 | } | 318 | } |
297 | |||
298 | return -ENOTTY; | ||
299 | } | 319 | } |
300 | 320 | ||
301 | static int asr_open(struct inode *inode, struct file *file) | 321 | static int asr_open(struct inode *inode, struct file *file) |
302 | { | 322 | { |
303 | if(test_and_set_bit(0, &asr_is_open)) | 323 | if (test_and_set_bit(0, &asr_is_open)) |
304 | return -EBUSY; | 324 | return -EBUSY; |
305 | 325 | ||
306 | asr_toggle(); | 326 | asr_toggle(); |
@@ -314,7 +334,8 @@ static int asr_release(struct inode *inode, struct file *file) | |||
314 | if (asr_expect_close == 42) | 334 | if (asr_expect_close == 42) |
315 | asr_disable(); | 335 | asr_disable(); |
316 | else { | 336 | else { |
317 | printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); | 337 | printk(KERN_CRIT PFX |
338 | "unexpected close, not stopping watchdog!\n"); | ||
318 | asr_toggle(); | 339 | asr_toggle(); |
319 | } | 340 | } |
320 | clear_bit(0, &asr_is_open); | 341 | clear_bit(0, &asr_is_open); |
@@ -323,12 +344,12 @@ static int asr_release(struct inode *inode, struct file *file) | |||
323 | } | 344 | } |
324 | 345 | ||
325 | static const struct file_operations asr_fops = { | 346 | static const struct file_operations asr_fops = { |
326 | .owner = THIS_MODULE, | 347 | .owner = THIS_MODULE, |
327 | .llseek = no_llseek, | 348 | .llseek = no_llseek, |
328 | .write = asr_write, | 349 | .write = asr_write, |
329 | .ioctl = asr_ioctl, | 350 | .unlocked_ioctl = asr_ioctl, |
330 | .open = asr_open, | 351 | .open = asr_open, |
331 | .release = asr_release, | 352 | .release = asr_release, |
332 | }; | 353 | }; |
333 | 354 | ||
334 | static struct miscdevice asr_miscdev = { | 355 | static struct miscdevice asr_miscdev = { |
@@ -367,6 +388,8 @@ static int __init ibmasr_init(void) | |||
367 | if (!asr_type) | 388 | if (!asr_type) |
368 | return -ENODEV; | 389 | return -ENODEV; |
369 | 390 | ||
391 | spin_lock_init(&asr_lock); | ||
392 | |||
370 | rc = asr_get_base_address(); | 393 | rc = asr_get_base_address(); |
371 | if (rc) | 394 | if (rc) |
372 | return rc; | 395 | return rc; |
@@ -395,7 +418,9 @@ module_init(ibmasr_init); | |||
395 | module_exit(ibmasr_exit); | 418 | module_exit(ibmasr_exit); |
396 | 419 | ||
397 | module_param(nowayout, int, 0); | 420 | module_param(nowayout, int, 0); |
398 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 421 | MODULE_PARM_DESC(nowayout, |
422 | "Watchdog cannot be stopped once started (default=" | ||
423 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
399 | 424 | ||
400 | MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); | 425 | MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); |
401 | MODULE_AUTHOR("Andrey Panin"); | 426 | MODULE_AUTHOR("Andrey Panin"); |
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index 788245bdaa7f..0bffea37404e 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 | 2 | * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 |
3 | * | 3 | * |
4 | * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved. | 4 | * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, |
5 | * All Rights Reserved. | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -22,32 +23,42 @@ | |||
22 | #include <linux/notifier.h> | 23 | #include <linux/notifier.h> |
23 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
25 | #include <asm/uaccess.h> | 26 | #include <linux/uaccess.h> |
26 | #include <asm/sgi/mc.h> | 27 | #include <asm/sgi/mc.h> |
27 | 28 | ||
28 | #define PFX "indydog: " | 29 | #define PFX "indydog: " |
29 | static int indydog_alive; | 30 | static unsigned long indydog_alive; |
31 | static spinlock_t indydog_lock; | ||
30 | 32 | ||
31 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 33 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
32 | 34 | ||
33 | static int nowayout = WATCHDOG_NOWAYOUT; | 35 | static int nowayout = WATCHDOG_NOWAYOUT; |
34 | module_param(nowayout, int, 0); | 36 | module_param(nowayout, int, 0); |
35 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 37 | MODULE_PARM_DESC(nowayout, |
38 | "Watchdog cannot be stopped once started (default=" | ||
39 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
36 | 40 | ||
37 | static void indydog_start(void) | 41 | static void indydog_start(void) |
38 | { | 42 | { |
39 | u32 mc_ctrl0 = sgimc->cpuctrl0; | 43 | u32 mc_ctrl0; |
40 | 44 | ||
45 | spin_lock(&indydog_lock); | ||
46 | mc_ctrl0 = sgimc->cpuctrl0; | ||
41 | mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; | 47 | mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; |
42 | sgimc->cpuctrl0 = mc_ctrl0; | 48 | sgimc->cpuctrl0 = mc_ctrl0; |
49 | spin_unlock(&indydog_lock); | ||
43 | } | 50 | } |
44 | 51 | ||
45 | static void indydog_stop(void) | 52 | static void indydog_stop(void) |
46 | { | 53 | { |
47 | u32 mc_ctrl0 = sgimc->cpuctrl0; | 54 | u32 mc_ctrl0; |
48 | 55 | ||
56 | spin_lock(&indydog_lock); | ||
57 | |||
58 | mc_ctrl0 = sgimc->cpuctrl0; | ||
49 | mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; | 59 | mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; |
50 | sgimc->cpuctrl0 = mc_ctrl0; | 60 | sgimc->cpuctrl0 = mc_ctrl0; |
61 | spin_unlock(&indydog_lock); | ||
51 | 62 | ||
52 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); | 63 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); |
53 | } | 64 | } |
@@ -62,7 +73,7 @@ static void indydog_ping(void) | |||
62 | */ | 73 | */ |
63 | static int indydog_open(struct inode *inode, struct file *file) | 74 | static int indydog_open(struct inode *inode, struct file *file) |
64 | { | 75 | { |
65 | if (indydog_alive) | 76 | if (test_and_set_bit(0, &indydog_alive)) |
66 | return -EBUSY; | 77 | return -EBUSY; |
67 | 78 | ||
68 | if (nowayout) | 79 | if (nowayout) |
@@ -84,23 +95,21 @@ static int indydog_release(struct inode *inode, struct file *file) | |||
84 | * Lock it in if it's a module and we defined ...NOWAYOUT */ | 95 | * Lock it in if it's a module and we defined ...NOWAYOUT */ |
85 | if (!nowayout) | 96 | if (!nowayout) |
86 | indydog_stop(); /* Turn the WDT off */ | 97 | indydog_stop(); /* Turn the WDT off */ |
87 | 98 | clear_bit(0, &indydog_alive); | |
88 | indydog_alive = 0; | ||
89 | |||
90 | return 0; | 99 | return 0; |
91 | } | 100 | } |
92 | 101 | ||
93 | static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 102 | static ssize_t indydog_write(struct file *file, const char *data, |
103 | size_t len, loff_t *ppos) | ||
94 | { | 104 | { |
95 | /* Refresh the timer. */ | 105 | /* Refresh the timer. */ |
96 | if (len) { | 106 | if (len) |
97 | indydog_ping(); | 107 | indydog_ping(); |
98 | } | ||
99 | return len; | 108 | return len; |
100 | } | 109 | } |
101 | 110 | ||
102 | static int indydog_ioctl(struct inode *inode, struct file *file, | 111 | static long indydog_ioctl(struct file *file, unsigned int cmd, |
103 | unsigned int cmd, unsigned long arg) | 112 | unsigned long arg) |
104 | { | 113 | { |
105 | int options, retval = -EINVAL; | 114 | int options, retval = -EINVAL; |
106 | static struct watchdog_info ident = { | 115 | static struct watchdog_info ident = { |
@@ -111,42 +120,40 @@ static int indydog_ioctl(struct inode *inode, struct file *file, | |||
111 | }; | 120 | }; |
112 | 121 | ||
113 | switch (cmd) { | 122 | switch (cmd) { |
114 | default: | 123 | case WDIOC_GETSUPPORT: |
115 | return -ENOTTY; | 124 | if (copy_to_user((struct watchdog_info *)arg, |
116 | case WDIOC_GETSUPPORT: | 125 | &ident, sizeof(ident))) |
117 | if (copy_to_user((struct watchdog_info *)arg, | 126 | return -EFAULT; |
118 | &ident, sizeof(ident))) | 127 | return 0; |
119 | return -EFAULT; | 128 | case WDIOC_GETSTATUS: |
120 | return 0; | 129 | case WDIOC_GETBOOTSTATUS: |
121 | case WDIOC_GETSTATUS: | 130 | return put_user(0, (int *)arg); |
122 | case WDIOC_GETBOOTSTATUS: | 131 | case WDIOC_KEEPALIVE: |
123 | return put_user(0,(int *)arg); | 132 | indydog_ping(); |
124 | case WDIOC_KEEPALIVE: | 133 | return 0; |
125 | indydog_ping(); | 134 | case WDIOC_GETTIMEOUT: |
126 | return 0; | 135 | return put_user(WATCHDOG_TIMEOUT, (int *)arg); |
127 | case WDIOC_GETTIMEOUT: | 136 | case WDIOC_SETOPTIONS: |
128 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 137 | { |
129 | case WDIOC_SETOPTIONS: | 138 | if (get_user(options, (int *)arg)) |
130 | { | 139 | return -EFAULT; |
131 | if (get_user(options, (int *)arg)) | 140 | if (options & WDIOS_DISABLECARD) { |
132 | return -EFAULT; | 141 | indydog_stop(); |
133 | 142 | retval = 0; | |
134 | if (options & WDIOS_DISABLECARD) { | 143 | } |
135 | indydog_stop(); | 144 | if (options & WDIOS_ENABLECARD) { |
136 | retval = 0; | 145 | indydog_start(); |
137 | } | 146 | retval = 0; |
138 | |||
139 | if (options & WDIOS_ENABLECARD) { | ||
140 | indydog_start(); | ||
141 | retval = 0; | ||
142 | } | ||
143 | |||
144 | return retval; | ||
145 | } | 147 | } |
148 | return retval; | ||
149 | } | ||
150 | default: | ||
151 | return -ENOTTY; | ||
146 | } | 152 | } |
147 | } | 153 | } |
148 | 154 | ||
149 | static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 155 | static int indydog_notify_sys(struct notifier_block *this, |
156 | unsigned long code, void *unused) | ||
150 | { | 157 | { |
151 | if (code == SYS_DOWN || code == SYS_HALT) | 158 | if (code == SYS_DOWN || code == SYS_HALT) |
152 | indydog_stop(); /* Turn the WDT off */ | 159 | indydog_stop(); /* Turn the WDT off */ |
@@ -158,7 +165,7 @@ static const struct file_operations indydog_fops = { | |||
158 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
159 | .llseek = no_llseek, | 166 | .llseek = no_llseek, |
160 | .write = indydog_write, | 167 | .write = indydog_write, |
161 | .ioctl = indydog_ioctl, | 168 | .unlocked_ioctl = indydog_ioctl, |
162 | .open = indydog_open, | 169 | .open = indydog_open, |
163 | .release = indydog_release, | 170 | .release = indydog_release, |
164 | }; | 171 | }; |
@@ -180,17 +187,20 @@ static int __init watchdog_init(void) | |||
180 | { | 187 | { |
181 | int ret; | 188 | int ret; |
182 | 189 | ||
190 | spin_lock_init(&indydog_lock); | ||
191 | |||
183 | ret = register_reboot_notifier(&indydog_notifier); | 192 | ret = register_reboot_notifier(&indydog_notifier); |
184 | if (ret) { | 193 | if (ret) { |
185 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 194 | printk(KERN_ERR PFX |
186 | ret); | 195 | "cannot register reboot notifier (err=%d)\n", ret); |
187 | return ret; | 196 | return ret; |
188 | } | 197 | } |
189 | 198 | ||
190 | ret = misc_register(&indydog_miscdev); | 199 | ret = misc_register(&indydog_miscdev); |
191 | if (ret) { | 200 | if (ret) { |
192 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 201 | printk(KERN_ERR PFX |
193 | WATCHDOG_MINOR, ret); | 202 | "cannot register miscdev on minor=%d (err=%d)\n", |
203 | WATCHDOG_MINOR, ret); | ||
194 | unregister_reboot_notifier(&indydog_notifier); | 204 | unregister_reboot_notifier(&indydog_notifier); |
195 | return ret; | 205 | return ret; |
196 | } | 206 | } |
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c index bbbd91af754d..e54c888d2afe 100644 --- a/drivers/watchdog/iop_wdt.c +++ b/drivers/watchdog/iop_wdt.c | |||
@@ -37,6 +37,7 @@ | |||
37 | static int nowayout = WATCHDOG_NOWAYOUT; | 37 | static int nowayout = WATCHDOG_NOWAYOUT; |
38 | static unsigned long wdt_status; | 38 | static unsigned long wdt_status; |
39 | static unsigned long boot_status; | 39 | static unsigned long boot_status; |
40 | static spinlock_t wdt_lock; | ||
40 | 41 | ||
41 | #define WDT_IN_USE 0 | 42 | #define WDT_IN_USE 0 |
42 | #define WDT_OK_TO_CLOSE 1 | 43 | #define WDT_OK_TO_CLOSE 1 |
@@ -68,8 +69,10 @@ static void wdt_enable(void) | |||
68 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF | 69 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF |
69 | * Takes approx. 10.7s to timeout | 70 | * Takes approx. 10.7s to timeout |
70 | */ | 71 | */ |
72 | spin_lock(&wdt_lock); | ||
71 | write_wdtcr(IOP_WDTCR_EN_ARM); | 73 | write_wdtcr(IOP_WDTCR_EN_ARM); |
72 | write_wdtcr(IOP_WDTCR_EN); | 74 | write_wdtcr(IOP_WDTCR_EN); |
75 | spin_unlock(&wdt_lock); | ||
73 | } | 76 | } |
74 | 77 | ||
75 | /* returns 0 if the timer was successfully disabled */ | 78 | /* returns 0 if the timer was successfully disabled */ |
@@ -77,9 +80,11 @@ static int wdt_disable(void) | |||
77 | { | 80 | { |
78 | /* Stop Counting */ | 81 | /* Stop Counting */ |
79 | if (wdt_supports_disable()) { | 82 | if (wdt_supports_disable()) { |
83 | spin_lock(&wdt_lock); | ||
80 | write_wdtcr(IOP_WDTCR_DIS_ARM); | 84 | write_wdtcr(IOP_WDTCR_DIS_ARM); |
81 | write_wdtcr(IOP_WDTCR_DIS); | 85 | write_wdtcr(IOP_WDTCR_DIS); |
82 | clear_bit(WDT_ENABLED, &wdt_status); | 86 | clear_bit(WDT_ENABLED, &wdt_status); |
87 | spin_unlock(&wdt_lock); | ||
83 | printk(KERN_INFO "WATCHDOG: Disabled\n"); | 88 | printk(KERN_INFO "WATCHDOG: Disabled\n"); |
84 | return 0; | 89 | return 0; |
85 | } else | 90 | } else |
@@ -92,16 +97,12 @@ static int iop_wdt_open(struct inode *inode, struct file *file) | |||
92 | return -EBUSY; | 97 | return -EBUSY; |
93 | 98 | ||
94 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 99 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
95 | |||
96 | wdt_enable(); | 100 | wdt_enable(); |
97 | |||
98 | set_bit(WDT_ENABLED, &wdt_status); | 101 | set_bit(WDT_ENABLED, &wdt_status); |
99 | |||
100 | return nonseekable_open(inode, file); | 102 | return nonseekable_open(inode, file); |
101 | } | 103 | } |
102 | 104 | ||
103 | static ssize_t | 105 | static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len, |
104 | iop_wdt_write(struct file *file, const char *data, size_t len, | ||
105 | loff_t *ppos) | 106 | loff_t *ppos) |
106 | { | 107 | { |
107 | if (len) { | 108 | if (len) { |
@@ -121,41 +122,39 @@ iop_wdt_write(struct file *file, const char *data, size_t len, | |||
121 | } | 122 | } |
122 | wdt_enable(); | 123 | wdt_enable(); |
123 | } | 124 | } |
124 | |||
125 | return len; | 125 | return len; |
126 | } | 126 | } |
127 | 127 | ||
128 | static struct watchdog_info ident = { | 128 | static const struct watchdog_info ident = { |
129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
130 | .identity = "iop watchdog", | 130 | .identity = "iop watchdog", |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static int | 133 | static long iop_wdt_ioctl(struct file *file, |
134 | iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 134 | unsigned int cmd, unsigned long arg) |
135 | unsigned long arg) | ||
136 | { | 135 | { |
137 | int options; | 136 | int options; |
138 | int ret = -ENOTTY; | 137 | int ret = -ENOTTY; |
138 | int __user *argp = (int __user *)arg; | ||
139 | 139 | ||
140 | switch (cmd) { | 140 | switch (cmd) { |
141 | case WDIOC_GETSUPPORT: | 141 | case WDIOC_GETSUPPORT: |
142 | if (copy_to_user | 142 | if (copy_to_user(argp, &ident, sizeof ident)) |
143 | ((struct watchdog_info *)arg, &ident, sizeof ident)) | ||
144 | ret = -EFAULT; | 143 | ret = -EFAULT; |
145 | else | 144 | else |
146 | ret = 0; | 145 | ret = 0; |
147 | break; | 146 | break; |
148 | 147 | ||
149 | case WDIOC_GETSTATUS: | 148 | case WDIOC_GETSTATUS: |
150 | ret = put_user(0, (int *)arg); | 149 | ret = put_user(0, argp); |
151 | break; | 150 | break; |
152 | 151 | ||
153 | case WDIOC_GETBOOTSTATUS: | 152 | case WDIOC_GETBOOTSTATUS: |
154 | ret = put_user(boot_status, (int *)arg); | 153 | ret = put_user(boot_status, argp); |
155 | break; | 154 | break; |
156 | 155 | ||
157 | case WDIOC_GETTIMEOUT: | 156 | case WDIOC_GETTIMEOUT: |
158 | ret = put_user(iop_watchdog_timeout(), (int *)arg); | 157 | ret = put_user(iop_watchdog_timeout(), argp); |
159 | break; | 158 | break; |
160 | 159 | ||
161 | case WDIOC_KEEPALIVE: | 160 | case WDIOC_KEEPALIVE: |
@@ -177,14 +176,12 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
177 | } else | 176 | } else |
178 | ret = 0; | 177 | ret = 0; |
179 | } | 178 | } |
180 | |||
181 | if (options & WDIOS_ENABLECARD) { | 179 | if (options & WDIOS_ENABLECARD) { |
182 | wdt_enable(); | 180 | wdt_enable(); |
183 | ret = 0; | 181 | ret = 0; |
184 | } | 182 | } |
185 | break; | 183 | break; |
186 | } | 184 | } |
187 | |||
188 | return ret; | 185 | return ret; |
189 | } | 186 | } |
190 | 187 | ||
@@ -214,7 +211,7 @@ static const struct file_operations iop_wdt_fops = { | |||
214 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
215 | .llseek = no_llseek, | 212 | .llseek = no_llseek, |
216 | .write = iop_wdt_write, | 213 | .write = iop_wdt_write, |
217 | .ioctl = iop_wdt_ioctl, | 214 | .unlocked_ioctl = iop_wdt_ioctl, |
218 | .open = iop_wdt_open, | 215 | .open = iop_wdt_open, |
219 | .release = iop_wdt_release, | 216 | .release = iop_wdt_release, |
220 | }; | 217 | }; |
@@ -229,10 +226,8 @@ static int __init iop_wdt_init(void) | |||
229 | { | 226 | { |
230 | int ret; | 227 | int ret; |
231 | 228 | ||
232 | ret = misc_register(&iop_wdt_miscdev); | 229 | spin_lock_init(&wdt_lock); |
233 | if (ret == 0) | 230 | |
234 | printk("iop watchdog timer: timeout %lu sec\n", | ||
235 | iop_watchdog_timeout()); | ||
236 | 231 | ||
237 | /* check if the reset was caused by the watchdog timer */ | 232 | /* check if the reset was caused by the watchdog timer */ |
238 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; | 233 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; |
@@ -242,6 +237,13 @@ static int __init iop_wdt_init(void) | |||
242 | */ | 237 | */ |
243 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); | 238 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); |
244 | 239 | ||
240 | /* Register after we have the device set up so we cannot race | ||
241 | with an open */ | ||
242 | ret = misc_register(&iop_wdt_miscdev); | ||
243 | if (ret == 0) | ||
244 | printk("iop watchdog timer: timeout %lu sec\n", | ||
245 | iop_watchdog_timeout()); | ||
246 | |||
245 | return ret; | 247 | return ret; |
246 | } | 248 | } |
247 | 249 | ||
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index dc7548dcaf35..943ceffbd683 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c | |||
@@ -25,42 +25,45 @@ | |||
25 | #include <linux/watchdog.h> | 25 | #include <linux/watchdog.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
28 | #include <linux/uaccess.h> | ||
28 | 29 | ||
29 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
30 | #include <asm/uaccess.h> | ||
31 | 31 | ||
32 | static int nowayout = WATCHDOG_NOWAYOUT; | 32 | static int nowayout = WATCHDOG_NOWAYOUT; |
33 | static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ | 33 | static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ |
34 | static unsigned long wdt_status; | 34 | static unsigned long wdt_status; |
35 | static spinlock_t wdt_lock; | ||
35 | 36 | ||
36 | #define WDT_IN_USE 0 | 37 | #define WDT_IN_USE 0 |
37 | #define WDT_OK_TO_CLOSE 1 | 38 | #define WDT_OK_TO_CLOSE 1 |
38 | 39 | ||
39 | static unsigned long wdt_tick_rate; | 40 | static unsigned long wdt_tick_rate; |
40 | 41 | ||
41 | static void | 42 | static void wdt_enable(void) |
42 | wdt_enable(void) | ||
43 | { | 43 | { |
44 | spin_lock(&wdt_lock); | ||
44 | ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); | 45 | ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); |
45 | ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); | 46 | ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); |
46 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); | 47 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); |
47 | ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); | 48 | ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); |
49 | spin_unlock(&wdt_lock); | ||
48 | } | 50 | } |
49 | 51 | ||
50 | static void | 52 | static void wdt_disable(void) |
51 | wdt_disable(void) | ||
52 | { | 53 | { |
54 | spin_lock(&wdt_lock); | ||
53 | ixp2000_reg_write(IXP2000_T4_CTL, 0); | 55 | ixp2000_reg_write(IXP2000_T4_CTL, 0); |
56 | spin_unlock(&wdt_lock); | ||
54 | } | 57 | } |
55 | 58 | ||
56 | static void | 59 | static void wdt_keepalive(void) |
57 | wdt_keepalive(void) | ||
58 | { | 60 | { |
61 | spin_lock(&wdt_lock); | ||
59 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); | 62 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); |
63 | spin_unlock(&wdt_lock); | ||
60 | } | 64 | } |
61 | 65 | ||
62 | static int | 66 | static int ixp2000_wdt_open(struct inode *inode, struct file *file) |
63 | ixp2000_wdt_open(struct inode *inode, struct file *file) | ||
64 | { | 67 | { |
65 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 68 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
66 | return -EBUSY; | 69 | return -EBUSY; |
@@ -72,8 +75,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file) | |||
72 | return nonseekable_open(inode, file); | 75 | return nonseekable_open(inode, file); |
73 | } | 76 | } |
74 | 77 | ||
75 | static ssize_t | 78 | static ssize_t ixp2000_wdt_write(struct file *file, const char *data, |
76 | ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 79 | size_t len, loff_t *ppos) |
77 | { | 80 | { |
78 | if (len) { | 81 | if (len) { |
79 | if (!nowayout) { | 82 | if (!nowayout) { |
@@ -103,9 +106,8 @@ static struct watchdog_info ident = { | |||
103 | .identity = "IXP2000 Watchdog", | 106 | .identity = "IXP2000 Watchdog", |
104 | }; | 107 | }; |
105 | 108 | ||
106 | static int | 109 | static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd, |
107 | ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 110 | unsigned long arg) |
108 | unsigned long arg) | ||
109 | { | 111 | { |
110 | int ret = -ENOTTY; | 112 | int ret = -ENOTTY; |
111 | int time; | 113 | int time; |
@@ -151,16 +153,13 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
151 | return ret; | 153 | return ret; |
152 | } | 154 | } |
153 | 155 | ||
154 | static int | 156 | static int ixp2000_wdt_release(struct inode *inode, struct file *file) |
155 | ixp2000_wdt_release(struct inode *inode, struct file *file) | ||
156 | { | 157 | { |
157 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 158 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
158 | wdt_disable(); | 159 | wdt_disable(); |
159 | } else { | 160 | else |
160 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | 161 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
161 | "timer will not stop\n"); | 162 | "timer will not stop\n"); |
162 | } | ||
163 | |||
164 | clear_bit(WDT_IN_USE, &wdt_status); | 163 | clear_bit(WDT_IN_USE, &wdt_status); |
165 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 164 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
166 | 165 | ||
@@ -168,18 +167,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) | |||
168 | } | 167 | } |
169 | 168 | ||
170 | 169 | ||
171 | static const struct file_operations ixp2000_wdt_fops = | 170 | static const struct file_operations ixp2000_wdt_fops = { |
172 | { | ||
173 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
174 | .llseek = no_llseek, | 172 | .llseek = no_llseek, |
175 | .write = ixp2000_wdt_write, | 173 | .write = ixp2000_wdt_write, |
176 | .ioctl = ixp2000_wdt_ioctl, | 174 | .unlocked_ioctl = ixp2000_wdt_ioctl, |
177 | .open = ixp2000_wdt_open, | 175 | .open = ixp2000_wdt_open, |
178 | .release = ixp2000_wdt_release, | 176 | .release = ixp2000_wdt_release, |
179 | }; | 177 | }; |
180 | 178 | ||
181 | static struct miscdevice ixp2000_wdt_miscdev = | 179 | static struct miscdevice ixp2000_wdt_miscdev = { |
182 | { | ||
183 | .minor = WATCHDOG_MINOR, | 180 | .minor = WATCHDOG_MINOR, |
184 | .name = "watchdog", | 181 | .name = "watchdog", |
185 | .fops = &ixp2000_wdt_fops, | 182 | .fops = &ixp2000_wdt_fops, |
@@ -191,9 +188,8 @@ static int __init ixp2000_wdt_init(void) | |||
191 | printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); | 188 | printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); |
192 | return -EIO; | 189 | return -EIO; |
193 | } | 190 | } |
194 | |||
195 | wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; | 191 | wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; |
196 | 192 | spin_lock_init(&wdt_lock); | |
197 | return misc_register(&ixp2000_wdt_miscdev); | 193 | return misc_register(&ixp2000_wdt_miscdev); |
198 | } | 194 | } |
199 | 195 | ||
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index 5864bb865cfe..24e624c847ae 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c | |||
@@ -30,40 +30,40 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
30 | static int heartbeat = 60; /* (secs) Default is 1 minute */ | 30 | static int heartbeat = 60; /* (secs) Default is 1 minute */ |
31 | static unsigned long wdt_status; | 31 | static unsigned long wdt_status; |
32 | static unsigned long boot_status; | 32 | static unsigned long boot_status; |
33 | static spin_lock_t wdt_lock; | ||
33 | 34 | ||
34 | #define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) | 35 | #define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) |
35 | 36 | ||
36 | #define WDT_IN_USE 0 | 37 | #define WDT_IN_USE 0 |
37 | #define WDT_OK_TO_CLOSE 1 | 38 | #define WDT_OK_TO_CLOSE 1 |
38 | 39 | ||
39 | static void | 40 | static void wdt_enable(void) |
40 | wdt_enable(void) | ||
41 | { | 41 | { |
42 | spin_lock(&wdt_lock); | ||
42 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; | 43 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; |
43 | *IXP4XX_OSWE = 0; | 44 | *IXP4XX_OSWE = 0; |
44 | *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; | 45 | *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; |
45 | *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; | 46 | *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; |
46 | *IXP4XX_OSWK = 0; | 47 | *IXP4XX_OSWK = 0; |
48 | spin_unlock(&wdt_lock); | ||
47 | } | 49 | } |
48 | 50 | ||
49 | static void | 51 | static void wdt_disable(void) |
50 | wdt_disable(void) | ||
51 | { | 52 | { |
53 | spin_lock(&wdt_lock); | ||
52 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; | 54 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; |
53 | *IXP4XX_OSWE = 0; | 55 | *IXP4XX_OSWE = 0; |
54 | *IXP4XX_OSWK = 0; | 56 | *IXP4XX_OSWK = 0; |
57 | spin_unlock(&wdt_lock); | ||
55 | } | 58 | } |
56 | 59 | ||
57 | static int | 60 | static int ixp4xx_wdt_open(struct inode *inode, struct file *file) |
58 | ixp4xx_wdt_open(struct inode *inode, struct file *file) | ||
59 | { | 61 | { |
60 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 62 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
61 | return -EBUSY; | 63 | return -EBUSY; |
62 | 64 | ||
63 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 65 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
64 | |||
65 | wdt_enable(); | 66 | wdt_enable(); |
66 | |||
67 | return nonseekable_open(inode, file); | 67 | return nonseekable_open(inode, file); |
68 | } | 68 | } |
69 | 69 | ||
@@ -87,7 +87,6 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
87 | } | 87 | } |
88 | wdt_enable(); | 88 | wdt_enable(); |
89 | } | 89 | } |
90 | |||
91 | return len; | 90 | return len; |
92 | } | 91 | } |
93 | 92 | ||
@@ -98,9 +97,8 @@ static struct watchdog_info ident = { | |||
98 | }; | 97 | }; |
99 | 98 | ||
100 | 99 | ||
101 | static int | 100 | static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd, |
102 | ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 101 | unsigned long arg) |
103 | unsigned long arg) | ||
104 | { | 102 | { |
105 | int ret = -ENOTTY; | 103 | int ret = -ENOTTY; |
106 | int time; | 104 | int time; |
@@ -145,16 +143,13 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
145 | return ret; | 143 | return ret; |
146 | } | 144 | } |
147 | 145 | ||
148 | static int | 146 | static int ixp4xx_wdt_release(struct inode *inode, struct file *file) |
149 | ixp4xx_wdt_release(struct inode *inode, struct file *file) | ||
150 | { | 147 | { |
151 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 148 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
152 | wdt_disable(); | 149 | wdt_disable(); |
153 | } else { | 150 | else |
154 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | 151 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
155 | "timer will not stop\n"); | 152 | "timer will not stop\n"); |
156 | } | ||
157 | |||
158 | clear_bit(WDT_IN_USE, &wdt_status); | 153 | clear_bit(WDT_IN_USE, &wdt_status); |
159 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 154 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
160 | 155 | ||
@@ -167,7 +162,7 @@ static const struct file_operations ixp4xx_wdt_fops = | |||
167 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
168 | .llseek = no_llseek, | 163 | .llseek = no_llseek, |
169 | .write = ixp4xx_wdt_write, | 164 | .write = ixp4xx_wdt_write, |
170 | .ioctl = ixp4xx_wdt_ioctl, | 165 | .unlocked_ioctl = ixp4xx_wdt_ioctl, |
171 | .open = ixp4xx_wdt_open, | 166 | .open = ixp4xx_wdt_open, |
172 | .release = ixp4xx_wdt_release, | 167 | .release = ixp4xx_wdt_release, |
173 | }; | 168 | }; |
@@ -191,14 +186,12 @@ static int __init ixp4xx_wdt_init(void) | |||
191 | 186 | ||
192 | return -ENODEV; | 187 | return -ENODEV; |
193 | } | 188 | } |
194 | 189 | spin_lock_init(&wdt_lock); | |
190 | boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? | ||
191 | WDIOF_CARDRESET : 0; | ||
195 | ret = misc_register(&ixp4xx_wdt_miscdev); | 192 | ret = misc_register(&ixp4xx_wdt_miscdev); |
196 | if (ret == 0) | 193 | if (ret == 0) |
197 | printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat); | 194 | printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat); |
198 | |||
199 | boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? | ||
200 | WDIOF_CARDRESET : 0; | ||
201 | |||
202 | return ret; | 195 | return ret; |
203 | } | 196 | } |
204 | 197 | ||
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index df5a6b811ccd..6d052b80aa20 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
23 | #include <asm/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <asm/arch/regs-timer.h> | 24 | #include <asm/arch/regs-timer.h> |
25 | 25 | ||
26 | 26 | ||
@@ -31,38 +31,44 @@ static int wdt_time = WDT_DEFAULT_TIME; | |||
31 | static int nowayout = WATCHDOG_NOWAYOUT; | 31 | static int nowayout = WATCHDOG_NOWAYOUT; |
32 | 32 | ||
33 | module_param(wdt_time, int, 0); | 33 | module_param(wdt_time, int, 0); |
34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | 34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" |
35 | __MODULE_STRING(WDT_DEFAULT_TIME) ")"); | ||
35 | 36 | ||
36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | 37 | #ifdef CONFIG_WATCHDOG_NOWAYOUT |
37 | module_param(nowayout, int, 0); | 38 | module_param(nowayout, int, 0); |
38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 39 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
40 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | 43 | ||
42 | static unsigned long ks8695wdt_busy; | 44 | static unsigned long ks8695wdt_busy; |
45 | static spinlock_t ks8695_lock; | ||
43 | 46 | ||
44 | /* ......................................................................... */ | 47 | /* ......................................................................... */ |
45 | 48 | ||
46 | /* | 49 | /* |
47 | * Disable the watchdog. | 50 | * Disable the watchdog. |
48 | */ | 51 | */ |
49 | static void inline ks8695_wdt_stop(void) | 52 | static inline void ks8695_wdt_stop(void) |
50 | { | 53 | { |
51 | unsigned long tmcon; | 54 | unsigned long tmcon; |
52 | 55 | ||
56 | spin_lock(&ks8695_lock); | ||
53 | /* disable timer0 */ | 57 | /* disable timer0 */ |
54 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 58 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
55 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 59 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
60 | spin_unlock(&ks8695_lock); | ||
56 | } | 61 | } |
57 | 62 | ||
58 | /* | 63 | /* |
59 | * Enable and reset the watchdog. | 64 | * Enable and reset the watchdog. |
60 | */ | 65 | */ |
61 | static void inline ks8695_wdt_start(void) | 66 | static inline void ks8695_wdt_start(void) |
62 | { | 67 | { |
63 | unsigned long tmcon; | 68 | unsigned long tmcon; |
64 | unsigned long tval = wdt_time * CLOCK_TICK_RATE; | 69 | unsigned long tval = wdt_time * CLOCK_TICK_RATE; |
65 | 70 | ||
71 | spin_lock(&ks8695_lock); | ||
66 | /* disable timer0 */ | 72 | /* disable timer0 */ |
67 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 73 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
68 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 74 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
@@ -73,19 +79,22 @@ static void inline ks8695_wdt_start(void) | |||
73 | /* re-enable timer0 */ | 79 | /* re-enable timer0 */ |
74 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 80 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
75 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 81 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
82 | spin_unlock(&ks8695_lock); | ||
76 | } | 83 | } |
77 | 84 | ||
78 | /* | 85 | /* |
79 | * Reload the watchdog timer. (ie, pat the watchdog) | 86 | * Reload the watchdog timer. (ie, pat the watchdog) |
80 | */ | 87 | */ |
81 | static void inline ks8695_wdt_reload(void) | 88 | static inline void ks8695_wdt_reload(void) |
82 | { | 89 | { |
83 | unsigned long tmcon; | 90 | unsigned long tmcon; |
84 | 91 | ||
92 | spin_lock(&ks8695_lock); | ||
85 | /* disable, then re-enable timer0 */ | 93 | /* disable, then re-enable timer0 */ |
86 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 94 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
87 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 95 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
88 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 96 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
97 | spin_unlock(&ks8695_lock); | ||
89 | } | 98 | } |
90 | 99 | ||
91 | /* | 100 | /* |
@@ -102,7 +111,8 @@ static int ks8695_wdt_settimeout(int new_time) | |||
102 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) | 111 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) |
103 | return -EINVAL; | 112 | return -EINVAL; |
104 | 113 | ||
105 | /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */ | 114 | /* Set new watchdog time. It will be used when |
115 | ks8695_wdt_start() is called. */ | ||
106 | wdt_time = new_time; | 116 | wdt_time = new_time; |
107 | return 0; | 117 | return 0; |
108 | } | 118 | } |
@@ -128,9 +138,9 @@ static int ks8695_wdt_open(struct inode *inode, struct file *file) | |||
128 | */ | 138 | */ |
129 | static int ks8695_wdt_close(struct inode *inode, struct file *file) | 139 | static int ks8695_wdt_close(struct inode *inode, struct file *file) |
130 | { | 140 | { |
141 | /* Disable the watchdog when file is closed */ | ||
131 | if (!nowayout) | 142 | if (!nowayout) |
132 | ks8695_wdt_stop(); /* Disable the watchdog when file is closed */ | 143 | ks8695_wdt_stop(); |
133 | |||
134 | clear_bit(0, &ks8695wdt_busy); | 144 | clear_bit(0, &ks8695wdt_busy); |
135 | return 0; | 145 | return 0; |
136 | } | 146 | } |
@@ -143,60 +153,52 @@ static struct watchdog_info ks8695_wdt_info = { | |||
143 | /* | 153 | /* |
144 | * Handle commands from user-space. | 154 | * Handle commands from user-space. |
145 | */ | 155 | */ |
146 | static int ks8695_wdt_ioctl(struct inode *inode, struct file *file, | 156 | static long ks8695_wdt_ioctl(struct file *file, unsigned int cmd, |
147 | unsigned int cmd, unsigned long arg) | 157 | unsigned long arg) |
148 | { | 158 | { |
149 | void __user *argp = (void __user *)arg; | 159 | void __user *argp = (void __user *)arg; |
150 | int __user *p = argp; | 160 | int __user *p = argp; |
151 | int new_value; | 161 | int new_value; |
152 | 162 | ||
153 | switch(cmd) { | 163 | switch (cmd) { |
154 | case WDIOC_KEEPALIVE: | 164 | case WDIOC_KEEPALIVE: |
155 | ks8695_wdt_reload(); /* pat the watchdog */ | 165 | ks8695_wdt_reload(); /* pat the watchdog */ |
156 | return 0; | 166 | return 0; |
157 | 167 | case WDIOC_GETSUPPORT: | |
158 | case WDIOC_GETSUPPORT: | 168 | return copy_to_user(argp, &ks8695_wdt_info, |
159 | return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0; | 169 | sizeof(ks8695_wdt_info)) ? -EFAULT : 0; |
160 | 170 | case WDIOC_SETTIMEOUT: | |
161 | case WDIOC_SETTIMEOUT: | 171 | if (get_user(new_value, p)) |
162 | if (get_user(new_value, p)) | 172 | return -EFAULT; |
163 | return -EFAULT; | 173 | if (ks8695_wdt_settimeout(new_value)) |
164 | 174 | return -EINVAL; | |
165 | if (ks8695_wdt_settimeout(new_value)) | 175 | /* Enable new time value */ |
166 | return -EINVAL; | 176 | ks8695_wdt_start(); |
167 | 177 | /* Return current value */ | |
168 | /* Enable new time value */ | 178 | return put_user(wdt_time, p); |
179 | case WDIOC_GETTIMEOUT: | ||
180 | return put_user(wdt_time, p); | ||
181 | case WDIOC_GETSTATUS: | ||
182 | case WDIOC_GETBOOTSTATUS: | ||
183 | return put_user(0, p); | ||
184 | case WDIOC_SETOPTIONS: | ||
185 | if (get_user(new_value, p)) | ||
186 | return -EFAULT; | ||
187 | if (new_value & WDIOS_DISABLECARD) | ||
188 | ks8695_wdt_stop(); | ||
189 | if (new_value & WDIOS_ENABLECARD) | ||
169 | ks8695_wdt_start(); | 190 | ks8695_wdt_start(); |
170 | 191 | return 0; | |
171 | /* Return current value */ | 192 | default: |
172 | return put_user(wdt_time, p); | 193 | return -ENOTTY; |
173 | |||
174 | case WDIOC_GETTIMEOUT: | ||
175 | return put_user(wdt_time, p); | ||
176 | |||
177 | case WDIOC_GETSTATUS: | ||
178 | case WDIOC_GETBOOTSTATUS: | ||
179 | return put_user(0, p); | ||
180 | |||
181 | case WDIOC_SETOPTIONS: | ||
182 | if (get_user(new_value, p)) | ||
183 | return -EFAULT; | ||
184 | |||
185 | if (new_value & WDIOS_DISABLECARD) | ||
186 | ks8695_wdt_stop(); | ||
187 | if (new_value & WDIOS_ENABLECARD) | ||
188 | ks8695_wdt_start(); | ||
189 | return 0; | ||
190 | |||
191 | default: | ||
192 | return -ENOTTY; | ||
193 | } | 194 | } |
194 | } | 195 | } |
195 | 196 | ||
196 | /* | 197 | /* |
197 | * Pat the watchdog whenever device is written to. | 198 | * Pat the watchdog whenever device is written to. |
198 | */ | 199 | */ |
199 | static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 200 | static ssize_t ks8695_wdt_write(struct file *file, const char *data, |
201 | size_t len, loff_t *ppos) | ||
200 | { | 202 | { |
201 | ks8695_wdt_reload(); /* pat the watchdog */ | 203 | ks8695_wdt_reload(); /* pat the watchdog */ |
202 | return len; | 204 | return len; |
@@ -207,7 +209,7 @@ static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, | |||
207 | static const struct file_operations ks8695wdt_fops = { | 209 | static const struct file_operations ks8695wdt_fops = { |
208 | .owner = THIS_MODULE, | 210 | .owner = THIS_MODULE, |
209 | .llseek = no_llseek, | 211 | .llseek = no_llseek, |
210 | .ioctl = ks8695_wdt_ioctl, | 212 | .unlocked_ioctl = ks8695_wdt_ioctl, |
211 | .open = ks8695_wdt_open, | 213 | .open = ks8695_wdt_open, |
212 | .release = ks8695_wdt_close, | 214 | .release = ks8695_wdt_close, |
213 | .write = ks8695_wdt_write, | 215 | .write = ks8695_wdt_write, |
@@ -231,7 +233,8 @@ static int __init ks8695wdt_probe(struct platform_device *pdev) | |||
231 | if (res) | 233 | if (res) |
232 | return res; | 234 | return res; |
233 | 235 | ||
234 | printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); | 236 | printk(KERN_INFO "KS8695 Watchdog Timer enabled (%d seconds%s)\n", |
237 | wdt_time, nowayout ? ", nowayout" : ""); | ||
235 | return 0; | 238 | return 0; |
236 | } | 239 | } |
237 | 240 | ||
@@ -285,12 +288,14 @@ static struct platform_driver ks8695wdt_driver = { | |||
285 | 288 | ||
286 | static int __init ks8695_wdt_init(void) | 289 | static int __init ks8695_wdt_init(void) |
287 | { | 290 | { |
288 | /* Check that the heartbeat value is within range; if not reset to the default */ | 291 | spin_lock_init(&ks8695_lock); |
292 | /* Check that the heartbeat value is within range; | ||
293 | if not reset to the default */ | ||
289 | if (ks8695_wdt_settimeout(wdt_time)) { | 294 | if (ks8695_wdt_settimeout(wdt_time)) { |
290 | ks8695_wdt_settimeout(WDT_DEFAULT_TIME); | 295 | ks8695_wdt_settimeout(WDT_DEFAULT_TIME); |
291 | pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME); | 296 | pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", |
297 | wdt_time, WDT_MAX_TIME); | ||
292 | } | 298 | } |
293 | |||
294 | return platform_driver_register(&ks8695wdt_driver); | 299 | return platform_driver_register(&ks8695wdt_driver); |
295 | } | 300 | } |
296 | 301 | ||
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index 6905135a776c..2dfc27559bf7 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c | |||
@@ -40,9 +40,9 @@ | |||
40 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
41 | #include <linux/reboot.h> | 41 | #include <linux/reboot.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/io.h> | ||
44 | #include <linux/uaccess.h> | ||
43 | 45 | ||
44 | #include <asm/io.h> | ||
45 | #include <asm/uaccess.h> | ||
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | 47 | ||
48 | /* ports */ | 48 | /* ports */ |
@@ -95,7 +95,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | |||
95 | 95 | ||
96 | static int nowayout = WATCHDOG_NOWAYOUT; | 96 | static int nowayout = WATCHDOG_NOWAYOUT; |
97 | module_param(nowayout, int, 0); | 97 | module_param(nowayout, int, 0); |
98 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 98 | MODULE_PARM_DESC(nowayout, |
99 | "Watchdog cannot be stopped once started (default=" | ||
100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
99 | 101 | ||
100 | #define PFX "machzwd" | 102 | #define PFX "machzwd" |
101 | 103 | ||
@@ -114,7 +116,7 @@ static struct watchdog_info zf_info = { | |||
114 | * 3 = GEN_SCI | 116 | * 3 = GEN_SCI |
115 | * defaults to GEN_RESET (0) | 117 | * defaults to GEN_RESET (0) |
116 | */ | 118 | */ |
117 | static int action = 0; | 119 | static int action; |
118 | module_param(action, int, 0); | 120 | module_param(action, int, 0); |
119 | MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); | 121 | MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); |
120 | 122 | ||
@@ -123,10 +125,9 @@ static void zf_ping(unsigned long data); | |||
123 | static int zf_action = GEN_RESET; | 125 | static int zf_action = GEN_RESET; |
124 | static unsigned long zf_is_open; | 126 | static unsigned long zf_is_open; |
125 | static char zf_expect_close; | 127 | static char zf_expect_close; |
126 | static DEFINE_SPINLOCK(zf_lock); | ||
127 | static DEFINE_SPINLOCK(zf_port_lock); | 128 | static DEFINE_SPINLOCK(zf_port_lock); |
128 | static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); | 129 | static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); |
129 | static unsigned long next_heartbeat = 0; | 130 | static unsigned long next_heartbeat; |
130 | 131 | ||
131 | 132 | ||
132 | /* timeout for user land heart beat (10 seconds) */ | 133 | /* timeout for user land heart beat (10 seconds) */ |
@@ -171,13 +172,13 @@ static inline void zf_set_control(unsigned short new) | |||
171 | 172 | ||
172 | static inline void zf_set_timer(unsigned short new, unsigned char n) | 173 | static inline void zf_set_timer(unsigned short new, unsigned char n) |
173 | { | 174 | { |
174 | switch(n){ | 175 | switch (n) { |
175 | case WD1: | 176 | case WD1: |
176 | zf_writew(COUNTER_1, new); | 177 | zf_writew(COUNTER_1, new); |
177 | case WD2: | 178 | case WD2: |
178 | zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); | 179 | zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); |
179 | default: | 180 | default: |
180 | return; | 181 | return; |
181 | } | 182 | } |
182 | } | 183 | } |
183 | 184 | ||
@@ -241,10 +242,8 @@ static void zf_ping(unsigned long data) | |||
241 | 242 | ||
242 | zf_writeb(COUNTER_2, 0xff); | 243 | zf_writeb(COUNTER_2, 0xff); |
243 | 244 | ||
244 | if(time_before(jiffies, next_heartbeat)){ | 245 | if (time_before(jiffies, next_heartbeat)) { |
245 | |||
246 | dprintk("time_before: %ld\n", next_heartbeat - jiffies); | 246 | dprintk("time_before: %ld\n", next_heartbeat - jiffies); |
247 | |||
248 | /* | 247 | /* |
249 | * reset event is activated by transition from 0 to 1 on | 248 | * reset event is activated by transition from 0 to 1 on |
250 | * RESET_WD1 bit and we assume that it is already zero... | 249 | * RESET_WD1 bit and we assume that it is already zero... |
@@ -261,24 +260,21 @@ static void zf_ping(unsigned long data) | |||
261 | spin_unlock_irqrestore(&zf_port_lock, flags); | 260 | spin_unlock_irqrestore(&zf_port_lock, flags); |
262 | 261 | ||
263 | mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); | 262 | mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); |
264 | }else{ | 263 | } else |
265 | printk(KERN_CRIT PFX ": I will reset your machine\n"); | 264 | printk(KERN_CRIT PFX ": I will reset your machine\n"); |
266 | } | ||
267 | } | 265 | } |
268 | 266 | ||
269 | static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | 267 | static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, |
270 | loff_t *ppos) | 268 | loff_t *ppos) |
271 | { | 269 | { |
272 | /* See if we got the magic character */ | 270 | /* See if we got the magic character */ |
273 | if(count){ | 271 | if (count) { |
274 | |||
275 | /* | 272 | /* |
276 | * no need to check for close confirmation | 273 | * no need to check for close confirmation |
277 | * no way to disable watchdog ;) | 274 | * no way to disable watchdog ;) |
278 | */ | 275 | */ |
279 | if (!nowayout) { | 276 | if (!nowayout) { |
280 | size_t ofs; | 277 | size_t ofs; |
281 | |||
282 | /* | 278 | /* |
283 | * note: just in case someone wrote the magic character | 279 | * note: just in case someone wrote the magic character |
284 | * five months ago... | 280 | * five months ago... |
@@ -286,11 +282,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | |||
286 | zf_expect_close = 0; | 282 | zf_expect_close = 0; |
287 | 283 | ||
288 | /* now scan */ | 284 | /* now scan */ |
289 | for (ofs = 0; ofs != count; ofs++){ | 285 | for (ofs = 0; ofs != count; ofs++) { |
290 | char c; | 286 | char c; |
291 | if (get_user(c, buf + ofs)) | 287 | if (get_user(c, buf + ofs)) |
292 | return -EFAULT; | 288 | return -EFAULT; |
293 | if (c == 'V'){ | 289 | if (c == 'V') { |
294 | zf_expect_close = 42; | 290 | zf_expect_close = 42; |
295 | dprintk("zf_expect_close = 42\n"); | 291 | dprintk("zf_expect_close = 42\n"); |
296 | } | 292 | } |
@@ -303,14 +299,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | |||
303 | */ | 299 | */ |
304 | next_heartbeat = jiffies + ZF_USER_TIMEO; | 300 | next_heartbeat = jiffies + ZF_USER_TIMEO; |
305 | dprintk("user ping at %ld\n", jiffies); | 301 | dprintk("user ping at %ld\n", jiffies); |
306 | |||
307 | } | 302 | } |
308 | |||
309 | return count; | 303 | return count; |
310 | } | 304 | } |
311 | 305 | ||
312 | static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 306 | static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
313 | unsigned long arg) | ||
314 | { | 307 | { |
315 | void __user *argp = (void __user *)arg; | 308 | void __user *argp = (void __user *)arg; |
316 | int __user *p = argp; | 309 | int __user *p = argp; |
@@ -319,55 +312,38 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
319 | if (copy_to_user(argp, &zf_info, sizeof(zf_info))) | 312 | if (copy_to_user(argp, &zf_info, sizeof(zf_info))) |
320 | return -EFAULT; | 313 | return -EFAULT; |
321 | break; | 314 | break; |
322 | |||
323 | case WDIOC_GETSTATUS: | 315 | case WDIOC_GETSTATUS: |
324 | case WDIOC_GETBOOTSTATUS: | 316 | case WDIOC_GETBOOTSTATUS: |
325 | return put_user(0, p); | 317 | return put_user(0, p); |
326 | |||
327 | case WDIOC_KEEPALIVE: | 318 | case WDIOC_KEEPALIVE: |
328 | zf_ping(0); | 319 | zf_ping(0); |
329 | break; | 320 | break; |
330 | |||
331 | default: | 321 | default: |
332 | return -ENOTTY; | 322 | return -ENOTTY; |
333 | } | 323 | } |
334 | |||
335 | return 0; | 324 | return 0; |
336 | } | 325 | } |
337 | 326 | ||
338 | static int zf_open(struct inode *inode, struct file *file) | 327 | static int zf_open(struct inode *inode, struct file *file) |
339 | { | 328 | { |
340 | spin_lock(&zf_lock); | 329 | if (test_and_set_bit(0, &zf_is_open)) |
341 | if(test_and_set_bit(0, &zf_is_open)) { | ||
342 | spin_unlock(&zf_lock); | ||
343 | return -EBUSY; | 330 | return -EBUSY; |
344 | } | ||
345 | |||
346 | if (nowayout) | 331 | if (nowayout) |
347 | __module_get(THIS_MODULE); | 332 | __module_get(THIS_MODULE); |
348 | |||
349 | spin_unlock(&zf_lock); | ||
350 | |||
351 | zf_timer_on(); | 333 | zf_timer_on(); |
352 | |||
353 | return nonseekable_open(inode, file); | 334 | return nonseekable_open(inode, file); |
354 | } | 335 | } |
355 | 336 | ||
356 | static int zf_close(struct inode *inode, struct file *file) | 337 | static int zf_close(struct inode *inode, struct file *file) |
357 | { | 338 | { |
358 | if(zf_expect_close == 42){ | 339 | if (zf_expect_close == 42) |
359 | zf_timer_off(); | 340 | zf_timer_off(); |
360 | } else { | 341 | else { |
361 | del_timer(&zf_timer); | 342 | del_timer(&zf_timer); |
362 | printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); | 343 | printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); |
363 | } | 344 | } |
364 | |||
365 | spin_lock(&zf_lock); | ||
366 | clear_bit(0, &zf_is_open); | 345 | clear_bit(0, &zf_is_open); |
367 | spin_unlock(&zf_lock); | ||
368 | |||
369 | zf_expect_close = 0; | 346 | zf_expect_close = 0; |
370 | |||
371 | return 0; | 347 | return 0; |
372 | } | 348 | } |
373 | 349 | ||
@@ -378,23 +354,18 @@ static int zf_close(struct inode *inode, struct file *file) | |||
378 | static int zf_notify_sys(struct notifier_block *this, unsigned long code, | 354 | static int zf_notify_sys(struct notifier_block *this, unsigned long code, |
379 | void *unused) | 355 | void *unused) |
380 | { | 356 | { |
381 | if(code == SYS_DOWN || code == SYS_HALT){ | 357 | if (code == SYS_DOWN || code == SYS_HALT) |
382 | zf_timer_off(); | 358 | zf_timer_off(); |
383 | } | ||
384 | |||
385 | return NOTIFY_DONE; | 359 | return NOTIFY_DONE; |
386 | } | 360 | } |
387 | 361 | ||
388 | |||
389 | |||
390 | |||
391 | static const struct file_operations zf_fops = { | 362 | static const struct file_operations zf_fops = { |
392 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
393 | .llseek = no_llseek, | 364 | .llseek = no_llseek, |
394 | .write = zf_write, | 365 | .write = zf_write, |
395 | .ioctl = zf_ioctl, | 366 | .unlocked_ioctl = zf_ioctl, |
396 | .open = zf_open, | 367 | .open = zf_open, |
397 | .release = zf_close, | 368 | .release = zf_close, |
398 | }; | 369 | }; |
399 | 370 | ||
400 | static struct miscdevice zf_miscdev = { | 371 | static struct miscdevice zf_miscdev = { |
@@ -402,7 +373,7 @@ static struct miscdevice zf_miscdev = { | |||
402 | .name = "watchdog", | 373 | .name = "watchdog", |
403 | .fops = &zf_fops, | 374 | .fops = &zf_fops, |
404 | }; | 375 | }; |
405 | 376 | ||
406 | 377 | ||
407 | /* | 378 | /* |
408 | * The device needs to learn about soft shutdowns in order to | 379 | * The device needs to learn about soft shutdowns in order to |
@@ -423,22 +394,23 @@ static int __init zf_init(void) | |||
423 | { | 394 | { |
424 | int ret; | 395 | int ret; |
425 | 396 | ||
426 | printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); | 397 | printk(KERN_INFO PFX |
398 | ": MachZ ZF-Logic Watchdog driver initializing.\n"); | ||
427 | 399 | ||
428 | ret = zf_get_ZFL_version(); | 400 | ret = zf_get_ZFL_version(); |
429 | if ((!ret) || (ret == 0xffff)) { | 401 | if (!ret || ret == 0xffff) { |
430 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); | 402 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); |
431 | return -ENODEV; | 403 | return -ENODEV; |
432 | } | 404 | } |
433 | 405 | ||
434 | if((action <= 3) && (action >= 0)){ | 406 | if (action <= 3 && action >= 0) |
435 | zf_action = zf_action>>action; | 407 | zf_action = zf_action >> action; |
436 | } else | 408 | else |
437 | action = 0; | 409 | action = 0; |
438 | 410 | ||
439 | zf_show_action(action); | 411 | zf_show_action(action); |
440 | 412 | ||
441 | if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ | 413 | if (!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")) { |
442 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", | 414 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", |
443 | ZF_IOBASE); | 415 | ZF_IOBASE); |
444 | ret = -EBUSY; | 416 | ret = -EBUSY; |
@@ -446,14 +418,14 @@ static int __init zf_init(void) | |||
446 | } | 418 | } |
447 | 419 | ||
448 | ret = register_reboot_notifier(&zf_notifier); | 420 | ret = register_reboot_notifier(&zf_notifier); |
449 | if(ret){ | 421 | if (ret) { |
450 | printk(KERN_ERR "can't register reboot notifier (err=%d)\n", | 422 | printk(KERN_ERR "can't register reboot notifier (err=%d)\n", |
451 | ret); | 423 | ret); |
452 | goto no_reboot; | 424 | goto no_reboot; |
453 | } | 425 | } |
454 | 426 | ||
455 | ret = misc_register(&zf_miscdev); | 427 | ret = misc_register(&zf_miscdev); |
456 | if (ret){ | 428 | if (ret) { |
457 | printk(KERN_ERR "can't misc_register on minor=%d\n", | 429 | printk(KERN_ERR "can't misc_register on minor=%d\n", |
458 | WATCHDOG_MINOR); | 430 | WATCHDOG_MINOR); |
459 | goto no_misc; | 431 | goto no_misc; |
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 1adf1d56027d..2248a8187590 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c | |||
@@ -29,7 +29,8 @@ | |||
29 | * - support for one more type board | 29 | * - support for one more type board |
30 | * | 30 | * |
31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> | 31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> |
32 | * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT | 32 | * - added nowayout module option to override |
33 | * CONFIG_WATCHDOG_NOWAYOUT | ||
33 | * | 34 | * |
34 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> | 35 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> |
35 | * - make mixcomwd_opened unsigned, | 36 | * - make mixcomwd_opened unsigned, |
@@ -53,8 +54,8 @@ | |||
53 | #include <linux/init.h> | 54 | #include <linux/init.h> |
54 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
55 | #include <linux/timer.h> | 56 | #include <linux/timer.h> |
56 | #include <asm/uaccess.h> | 57 | #include <linux/uaccess.h> |
57 | #include <asm/io.h> | 58 | #include <linux/io.h> |
58 | 59 | ||
59 | /* | 60 | /* |
60 | * We have two types of cards that can be probed: | 61 | * We have two types of cards that can be probed: |
@@ -108,18 +109,19 @@ static char expect_close; | |||
108 | 109 | ||
109 | static int nowayout = WATCHDOG_NOWAYOUT; | 110 | static int nowayout = WATCHDOG_NOWAYOUT; |
110 | module_param(nowayout, int, 0); | 111 | module_param(nowayout, int, 0); |
111 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 112 | MODULE_PARM_DESC(nowayout, |
113 | "Watchdog cannot be stopped once started (default=" | ||
114 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
112 | 115 | ||
113 | static void mixcomwd_ping(void) | 116 | static void mixcomwd_ping(void) |
114 | { | 117 | { |
115 | outb_p(55,watchdog_port); | 118 | outb_p(55, watchdog_port); |
116 | return; | 119 | return; |
117 | } | 120 | } |
118 | 121 | ||
119 | static void mixcomwd_timerfun(unsigned long d) | 122 | static void mixcomwd_timerfun(unsigned long d) |
120 | { | 123 | { |
121 | mixcomwd_ping(); | 124 | mixcomwd_ping(); |
122 | |||
123 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 125 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
124 | } | 126 | } |
125 | 127 | ||
@@ -129,22 +131,22 @@ static void mixcomwd_timerfun(unsigned long d) | |||
129 | 131 | ||
130 | static int mixcomwd_open(struct inode *inode, struct file *file) | 132 | static int mixcomwd_open(struct inode *inode, struct file *file) |
131 | { | 133 | { |
132 | if(test_and_set_bit(0,&mixcomwd_opened)) { | 134 | if (test_and_set_bit(0, &mixcomwd_opened)) |
133 | return -EBUSY; | 135 | return -EBUSY; |
134 | } | 136 | |
135 | mixcomwd_ping(); | 137 | mixcomwd_ping(); |
136 | 138 | ||
137 | if (nowayout) { | 139 | if (nowayout) |
138 | /* | 140 | /* |
139 | * fops_get() code via open() has already done | 141 | * fops_get() code via open() has already done |
140 | * a try_module_get() so it is safe to do the | 142 | * a try_module_get() so it is safe to do the |
141 | * __module_get(). | 143 | * __module_get(). |
142 | */ | 144 | */ |
143 | __module_get(THIS_MODULE); | 145 | __module_get(THIS_MODULE); |
144 | } else { | 146 | else { |
145 | if(mixcomwd_timer_alive) { | 147 | if (mixcomwd_timer_alive) { |
146 | del_timer(&mixcomwd_timer); | 148 | del_timer(&mixcomwd_timer); |
147 | mixcomwd_timer_alive=0; | 149 | mixcomwd_timer_alive = 0; |
148 | } | 150 | } |
149 | } | 151 | } |
150 | return nonseekable_open(inode, file); | 152 | return nonseekable_open(inode, file); |
@@ -153,26 +155,27 @@ static int mixcomwd_open(struct inode *inode, struct file *file) | |||
153 | static int mixcomwd_release(struct inode *inode, struct file *file) | 155 | static int mixcomwd_release(struct inode *inode, struct file *file) |
154 | { | 156 | { |
155 | if (expect_close == 42) { | 157 | if (expect_close == 42) { |
156 | if(mixcomwd_timer_alive) { | 158 | if (mixcomwd_timer_alive) { |
157 | printk(KERN_ERR PFX "release called while internal timer alive"); | 159 | printk(KERN_ERR PFX |
160 | "release called while internal timer alive"); | ||
158 | return -EBUSY; | 161 | return -EBUSY; |
159 | } | 162 | } |
160 | mixcomwd_timer_alive=1; | 163 | mixcomwd_timer_alive = 1; |
161 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 164 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
162 | } else { | 165 | } else |
163 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 166 | printk(KERN_CRIT PFX |
164 | } | 167 | "WDT device closed unexpectedly. WDT will not stop!\n"); |
165 | 168 | ||
166 | clear_bit(0,&mixcomwd_opened); | 169 | clear_bit(0, &mixcomwd_opened); |
167 | expect_close=0; | 170 | expect_close = 0; |
168 | return 0; | 171 | return 0; |
169 | } | 172 | } |
170 | 173 | ||
171 | 174 | ||
172 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 175 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, |
176 | size_t len, loff_t *ppos) | ||
173 | { | 177 | { |
174 | if(len) | 178 | if (len) { |
175 | { | ||
176 | if (!nowayout) { | 179 | if (!nowayout) { |
177 | size_t i; | 180 | size_t i; |
178 | 181 | ||
@@ -192,8 +195,8 @@ static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t | |||
192 | return len; | 195 | return len; |
193 | } | 196 | } |
194 | 197 | ||
195 | static int mixcomwd_ioctl(struct inode *inode, struct file *file, | 198 | static long mixcomwd_ioctl(struct file *file, |
196 | unsigned int cmd, unsigned long arg) | 199 | unsigned int cmd, unsigned long arg) |
197 | { | 200 | { |
198 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
199 | int __user *p = argp; | 202 | int __user *p = argp; |
@@ -204,32 +207,23 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, | |||
204 | .identity = "MixCOM watchdog", | 207 | .identity = "MixCOM watchdog", |
205 | }; | 208 | }; |
206 | 209 | ||
207 | switch(cmd) | 210 | switch (cmd) { |
208 | { | 211 | case WDIOC_GETSTATUS: |
209 | case WDIOC_GETSTATUS: | 212 | status = mixcomwd_opened; |
210 | status=mixcomwd_opened; | 213 | if (!nowayout) |
211 | if (!nowayout) { | 214 | status |= mixcomwd_timer_alive; |
212 | status|=mixcomwd_timer_alive; | 215 | return put_user(status, p); |
213 | } | 216 | case WDIOC_GETBOOTSTATUS: |
214 | if (copy_to_user(p, &status, sizeof(int))) { | 217 | return put_user(0, p); |
215 | return -EFAULT; | 218 | case WDIOC_GETSUPPORT: |
216 | } | 219 | if (copy_to_user(argp, &ident, sizeof(ident))) |
217 | break; | 220 | return -EFAULT; |
218 | case WDIOC_GETBOOTSTATUS: | 221 | break; |
219 | if (copy_to_user(p, &status, sizeof(int))) { | 222 | case WDIOC_KEEPALIVE: |
220 | return -EFAULT; | 223 | mixcomwd_ping(); |
221 | } | 224 | break; |
222 | break; | 225 | default: |
223 | case WDIOC_GETSUPPORT: | 226 | return -ENOTTY; |
224 | if (copy_to_user(argp, &ident, sizeof(ident))) { | ||
225 | return -EFAULT; | ||
226 | } | ||
227 | break; | ||
228 | case WDIOC_KEEPALIVE: | ||
229 | mixcomwd_ping(); | ||
230 | break; | ||
231 | default: | ||
232 | return -ENOTTY; | ||
233 | } | 227 | } |
234 | return 0; | 228 | return 0; |
235 | } | 229 | } |
@@ -238,7 +232,7 @@ static const struct file_operations mixcomwd_fops = { | |||
238 | .owner = THIS_MODULE, | 232 | .owner = THIS_MODULE, |
239 | .llseek = no_llseek, | 233 | .llseek = no_llseek, |
240 | .write = mixcomwd_write, | 234 | .write = mixcomwd_write, |
241 | .ioctl = mixcomwd_ioctl, | 235 | .unlocked_ioctl = mixcomwd_ioctl, |
242 | .open = mixcomwd_open, | 236 | .open = mixcomwd_open, |
243 | .release = mixcomwd_release, | 237 | .release = mixcomwd_release, |
244 | }; | 238 | }; |
@@ -253,15 +247,14 @@ static int __init checkcard(int port, int card_id) | |||
253 | { | 247 | { |
254 | int id; | 248 | int id; |
255 | 249 | ||
256 | if (!request_region(port, 1, "MixCOM watchdog")) { | 250 | if (!request_region(port, 1, "MixCOM watchdog")) |
257 | return 0; | 251 | return 0; |
258 | } | ||
259 | 252 | ||
260 | id=inb_p(port); | 253 | id = inb_p(port); |
261 | if (card_id==MIXCOM_ID) | 254 | if (card_id == MIXCOM_ID) |
262 | id &= 0x3f; | 255 | id &= 0x3f; |
263 | 256 | ||
264 | if (id!=card_id) { | 257 | if (id != card_id) { |
265 | release_region(port, 1); | 258 | release_region(port, 1); |
266 | return 0; | 259 | return 0; |
267 | } | 260 | } |
@@ -270,9 +263,7 @@ static int __init checkcard(int port, int card_id) | |||
270 | 263 | ||
271 | static int __init mixcomwd_init(void) | 264 | static int __init mixcomwd_init(void) |
272 | { | 265 | { |
273 | int i; | 266 | int i, ret, found = 0; |
274 | int ret; | ||
275 | int found=0; | ||
276 | 267 | ||
277 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { | 268 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { |
278 | if (checkcard(mixcomwd_io_info[i].ioport, | 269 | if (checkcard(mixcomwd_io_info[i].ioport, |
@@ -283,20 +274,22 @@ static int __init mixcomwd_init(void) | |||
283 | } | 274 | } |
284 | 275 | ||
285 | if (!found) { | 276 | if (!found) { |
286 | printk(KERN_ERR PFX "No card detected, or port not available.\n"); | 277 | printk(KERN_ERR PFX |
278 | "No card detected, or port not available.\n"); | ||
287 | return -ENODEV; | 279 | return -ENODEV; |
288 | } | 280 | } |
289 | 281 | ||
290 | ret = misc_register(&mixcomwd_miscdev); | 282 | ret = misc_register(&mixcomwd_miscdev); |
291 | if (ret) | 283 | if (ret) { |
292 | { | 284 | printk(KERN_ERR PFX |
293 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 285 | "cannot register miscdev on minor=%d (err=%d)\n", |
294 | WATCHDOG_MINOR, ret); | 286 | WATCHDOG_MINOR, ret); |
295 | goto error_misc_register_watchdog; | 287 | goto error_misc_register_watchdog; |
296 | } | 288 | } |
297 | 289 | ||
298 | printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", | 290 | printk(KERN_INFO |
299 | VERSION, watchdog_port); | 291 | "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", |
292 | VERSION, watchdog_port); | ||
300 | 293 | ||
301 | return 0; | 294 | return 0; |
302 | 295 | ||
@@ -309,15 +302,15 @@ error_misc_register_watchdog: | |||
309 | static void __exit mixcomwd_exit(void) | 302 | static void __exit mixcomwd_exit(void) |
310 | { | 303 | { |
311 | if (!nowayout) { | 304 | if (!nowayout) { |
312 | if(mixcomwd_timer_alive) { | 305 | if (mixcomwd_timer_alive) { |
313 | printk(KERN_WARNING PFX "I quit now, hardware will" | 306 | printk(KERN_WARNING PFX "I quit now, hardware will" |
314 | " probably reboot!\n"); | 307 | " probably reboot!\n"); |
315 | del_timer_sync(&mixcomwd_timer); | 308 | del_timer_sync(&mixcomwd_timer); |
316 | mixcomwd_timer_alive=0; | 309 | mixcomwd_timer_alive = 0; |
317 | } | 310 | } |
318 | } | 311 | } |
319 | misc_deregister(&mixcomwd_miscdev); | 312 | misc_deregister(&mixcomwd_miscdev); |
320 | release_region(watchdog_port,1); | 313 | release_region(watchdog_port, 1); |
321 | } | 314 | } |
322 | 315 | ||
323 | module_init(mixcomwd_init); | 316 | module_init(mixcomwd_init); |
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 77c1c2ae2cc2..ce1811d5d6b1 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/io.h> | 5 | #include <linux/io.h> |
6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
7 | #include <linux/of_platform.h> | 7 | #include <linux/of_platform.h> |
8 | #include <asm/uaccess.h> | 8 | #include <linux/uaccess.h> |
9 | #include <asm/mpc52xx.h> | 9 | #include <asm/mpc52xx.h> |
10 | 10 | ||
11 | 11 | ||
@@ -57,7 +57,8 @@ static int mpc5200_wdt_start(struct mpc5200_wdt *wdt) | |||
57 | /* set timeout, with maximum prescaler */ | 57 | /* set timeout, with maximum prescaler */ |
58 | out_be32(&wdt->regs->count, 0x0 | wdt->count); | 58 | out_be32(&wdt->regs->count, 0x0 | wdt->count); |
59 | /* enable watchdog */ | 59 | /* enable watchdog */ |
60 | out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER); | 60 | out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | |
61 | GPT_MODE_MS_TIMER); | ||
61 | spin_unlock(&wdt->io_lock); | 62 | spin_unlock(&wdt->io_lock); |
62 | 63 | ||
63 | return 0; | 64 | return 0; |
@@ -66,7 +67,8 @@ static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt) | |||
66 | { | 67 | { |
67 | spin_lock(&wdt->io_lock); | 68 | spin_lock(&wdt->io_lock); |
68 | /* writing A5 to OCPW resets the watchdog */ | 69 | /* writing A5 to OCPW resets the watchdog */ |
69 | out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode))); | 70 | out_be32(&wdt->regs->mode, 0xA5000000 | |
71 | (0xffffff & in_be32(&wdt->regs->mode))); | ||
70 | spin_unlock(&wdt->io_lock); | 72 | spin_unlock(&wdt->io_lock); |
71 | return 0; | 73 | return 0; |
72 | } | 74 | } |
@@ -92,8 +94,8 @@ static struct watchdog_info mpc5200_wdt_info = { | |||
92 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 94 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
93 | .identity = "mpc5200 watchdog on GPT0", | 95 | .identity = "mpc5200 watchdog on GPT0", |
94 | }; | 96 | }; |
95 | static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | 97 | static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd, |
96 | unsigned int cmd, unsigned long arg) | 98 | unsigned long arg) |
97 | { | 99 | { |
98 | struct mpc5200_wdt *wdt = file->private_data; | 100 | struct mpc5200_wdt *wdt = file->private_data; |
99 | int __user *data = (int __user *)arg; | 101 | int __user *data = (int __user *)arg; |
@@ -103,7 +105,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | |||
103 | switch (cmd) { | 105 | switch (cmd) { |
104 | case WDIOC_GETSUPPORT: | 106 | case WDIOC_GETSUPPORT: |
105 | ret = copy_to_user(data, &mpc5200_wdt_info, | 107 | ret = copy_to_user(data, &mpc5200_wdt_info, |
106 | sizeof(mpc5200_wdt_info)); | 108 | sizeof(mpc5200_wdt_info)); |
107 | if (ret) | 109 | if (ret) |
108 | ret = -EFAULT; | 110 | ret = -EFAULT; |
109 | break; | 111 | break; |
@@ -135,6 +137,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | |||
135 | } | 137 | } |
136 | return ret; | 138 | return ret; |
137 | } | 139 | } |
140 | |||
138 | static int mpc5200_wdt_open(struct inode *inode, struct file *file) | 141 | static int mpc5200_wdt_open(struct inode *inode, struct file *file) |
139 | { | 142 | { |
140 | /* /dev/watchdog can only be opened once */ | 143 | /* /dev/watchdog can only be opened once */ |
@@ -167,7 +170,8 @@ static const struct file_operations mpc5200_wdt_fops = { | |||
167 | }; | 170 | }; |
168 | 171 | ||
169 | /* module operations */ | 172 | /* module operations */ |
170 | static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match) | 173 | static int mpc5200_wdt_probe(struct of_device *op, |
174 | const struct of_device_id *match) | ||
171 | { | 175 | { |
172 | struct mpc5200_wdt *wdt; | 176 | struct mpc5200_wdt *wdt; |
173 | int err; | 177 | int err; |
diff --git a/drivers/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c index b16c5cd972eb..109eea0df2d0 100644 --- a/drivers/watchdog/mpc83xx_wdt.c +++ b/drivers/watchdog/mpc83xx_wdt.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/watchdog.h> | 24 | #include <linux/watchdog.h> |
25 | #include <asm/io.h> | 25 | #include <linux/io.h> |
26 | #include <asm/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | 27 | ||
28 | struct mpc83xx_wdt { | 28 | struct mpc83xx_wdt { |
29 | __be32 res0; | 29 | __be32 res0; |
@@ -42,11 +42,13 @@ static struct mpc83xx_wdt __iomem *wd_base; | |||
42 | 42 | ||
43 | static u16 timeout = 0xffff; | 43 | static u16 timeout = 0xffff; |
44 | module_param(timeout, ushort, 0); | 44 | module_param(timeout, ushort, 0); |
45 | MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535"); | 45 | MODULE_PARM_DESC(timeout, |
46 | "Watchdog timeout in ticks. (0<timeout<65536, default=65535"); | ||
46 | 47 | ||
47 | static int reset = 1; | 48 | static int reset = 1; |
48 | module_param(reset, bool, 0); | 49 | module_param(reset, bool, 0); |
49 | MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset"); | 50 | MODULE_PARM_DESC(reset, |
51 | "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset"); | ||
50 | 52 | ||
51 | /* | 53 | /* |
52 | * We always prescale, but if someone really doesn't want to they can set this | 54 | * We always prescale, but if someone really doesn't want to they can set this |
@@ -105,8 +107,8 @@ static int mpc83xx_wdt_release(struct inode *inode, struct file *file) | |||
105 | return 0; | 107 | return 0; |
106 | } | 108 | } |
107 | 109 | ||
108 | static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, | 110 | static long mpc83xx_wdt_ioctl(struct file *file, unsigned int cmd, |
109 | unsigned int cmd, unsigned long arg) | 111 | unsigned long arg) |
110 | { | 112 | { |
111 | void __user *argp = (void __user *)arg; | 113 | void __user *argp = (void __user *)arg; |
112 | int __user *p = argp; | 114 | int __user *p = argp; |
@@ -136,7 +138,7 @@ static const struct file_operations mpc83xx_wdt_fops = { | |||
136 | .owner = THIS_MODULE, | 138 | .owner = THIS_MODULE, |
137 | .llseek = no_llseek, | 139 | .llseek = no_llseek, |
138 | .write = mpc83xx_wdt_write, | 140 | .write = mpc83xx_wdt_write, |
139 | .ioctl = mpc83xx_wdt_ioctl, | 141 | .unlocked_ioctl = mpc83xx_wdt_ioctl, |
140 | .open = mpc83xx_wdt_open, | 142 | .open = mpc83xx_wdt_open, |
141 | .release = mpc83xx_wdt_release, | 143 | .release = mpc83xx_wdt_release, |
142 | }; | 144 | }; |
@@ -161,8 +163,7 @@ static int __devinit mpc83xx_wdt_probe(struct platform_device *dev) | |||
161 | goto err_out; | 163 | goto err_out; |
162 | } | 164 | } |
163 | 165 | ||
164 | wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt)); | 166 | wd_base = ioremap(r->start, sizeof(struct mpc83xx_wdt)); |
165 | |||
166 | if (wd_base == NULL) { | 167 | if (wd_base == NULL) { |
167 | ret = -ENOMEM; | 168 | ret = -ENOMEM; |
168 | goto err_out; | 169 | goto err_out; |
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c index 85b5734403a5..1336425acf20 100644 --- a/drivers/watchdog/mpc8xx_wdt.c +++ b/drivers/watchdog/mpc8xx_wdt.c | |||
@@ -16,36 +16,35 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/watchdog.h> | 17 | #include <linux/watchdog.h> |
18 | #include <asm/8xx_immap.h> | 18 | #include <asm/8xx_immap.h> |
19 | #include <asm/uaccess.h> | 19 | #include <linux/uaccess.h> |
20 | #include <asm/io.h> | 20 | #include <linux/io.h> |
21 | #include <syslib/m8xx_wdt.h> | 21 | #include <syslib/m8xx_wdt.h> |
22 | 22 | ||
23 | static unsigned long wdt_opened; | 23 | static unsigned long wdt_opened; |
24 | static int wdt_status; | 24 | static int wdt_status; |
25 | static spinlock_t wdt_lock; | ||
25 | 26 | ||
26 | static void mpc8xx_wdt_handler_disable(void) | 27 | static void mpc8xx_wdt_handler_disable(void) |
27 | { | 28 | { |
28 | volatile uint __iomem *piscr; | 29 | volatile uint __iomem *piscr; |
29 | piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; | 30 | piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr; |
30 | 31 | ||
31 | if (!m8xx_has_internal_rtc) | 32 | if (!m8xx_has_internal_rtc) |
32 | m8xx_wdt_stop_timer(); | 33 | m8xx_wdt_stop_timer(); |
33 | else | 34 | else |
34 | out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); | 35 | out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); |
35 | |||
36 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); | 36 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void mpc8xx_wdt_handler_enable(void) | 39 | static void mpc8xx_wdt_handler_enable(void) |
40 | { | 40 | { |
41 | volatile uint __iomem *piscr; | 41 | volatile uint __iomem *piscr; |
42 | piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; | 42 | piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr; |
43 | 43 | ||
44 | if (!m8xx_has_internal_rtc) | 44 | if (!m8xx_has_internal_rtc) |
45 | m8xx_wdt_install_timer(); | 45 | m8xx_wdt_install_timer(); |
46 | else | 46 | else |
47 | out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); | 47 | out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); |
48 | |||
49 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); | 48 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); |
50 | } | 49 | } |
51 | 50 | ||
@@ -53,37 +52,34 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file) | |||
53 | { | 52 | { |
54 | if (test_and_set_bit(0, &wdt_opened)) | 53 | if (test_and_set_bit(0, &wdt_opened)) |
55 | return -EBUSY; | 54 | return -EBUSY; |
56 | |||
57 | m8xx_wdt_reset(); | 55 | m8xx_wdt_reset(); |
58 | mpc8xx_wdt_handler_disable(); | 56 | mpc8xx_wdt_handler_disable(); |
59 | |||
60 | return nonseekable_open(inode, file); | 57 | return nonseekable_open(inode, file); |
61 | } | 58 | } |
62 | 59 | ||
63 | static int mpc8xx_wdt_release(struct inode *inode, struct file *file) | 60 | static int mpc8xx_wdt_release(struct inode *inode, struct file *file) |
64 | { | 61 | { |
65 | m8xx_wdt_reset(); | 62 | m8xx_wdt_reset(); |
66 | |||
67 | #if !defined(CONFIG_WATCHDOG_NOWAYOUT) | 63 | #if !defined(CONFIG_WATCHDOG_NOWAYOUT) |
68 | mpc8xx_wdt_handler_enable(); | 64 | mpc8xx_wdt_handler_enable(); |
69 | #endif | 65 | #endif |
70 | |||
71 | clear_bit(0, &wdt_opened); | 66 | clear_bit(0, &wdt_opened); |
72 | |||
73 | return 0; | 67 | return 0; |
74 | } | 68 | } |
75 | 69 | ||
76 | static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, | 70 | static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, |
77 | loff_t * ppos) | 71 | size_t len, loff_t *ppos) |
78 | { | 72 | { |
79 | if (len) | 73 | if (len) { |
74 | spin_lock(&wdt_lock); | ||
80 | m8xx_wdt_reset(); | 75 | m8xx_wdt_reset(); |
81 | 76 | spin_unlock(&wdt_lock); | |
77 | } | ||
82 | return len; | 78 | return len; |
83 | } | 79 | } |
84 | 80 | ||
85 | static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | 81 | static long mpc8xx_wdt_ioctl(struct file *file, |
86 | unsigned int cmd, unsigned long arg) | 82 | unsigned int cmd, unsigned long arg) |
87 | { | 83 | { |
88 | int timeout; | 84 | int timeout; |
89 | static struct watchdog_info info = { | 85 | static struct watchdog_info info = { |
@@ -112,15 +108,19 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
112 | return -EOPNOTSUPP; | 108 | return -EOPNOTSUPP; |
113 | 109 | ||
114 | case WDIOC_KEEPALIVE: | 110 | case WDIOC_KEEPALIVE: |
111 | spin_lock(&wdt_lock); | ||
115 | m8xx_wdt_reset(); | 112 | m8xx_wdt_reset(); |
116 | wdt_status |= WDIOF_KEEPALIVEPING; | 113 | wdt_status |= WDIOF_KEEPALIVEPING; |
114 | spin_unlock(&wdt_lock); | ||
117 | break; | 115 | break; |
118 | 116 | ||
119 | case WDIOC_SETTIMEOUT: | 117 | case WDIOC_SETTIMEOUT: |
120 | return -EOPNOTSUPP; | 118 | return -EOPNOTSUPP; |
121 | 119 | ||
122 | case WDIOC_GETTIMEOUT: | 120 | case WDIOC_GETTIMEOUT: |
121 | spin_lock(&wdt_lock); | ||
123 | timeout = m8xx_wdt_get_timeout(); | 122 | timeout = m8xx_wdt_get_timeout(); |
123 | spin_unlock(&wdt_lock); | ||
124 | if (put_user(timeout, (int *)arg)) | 124 | if (put_user(timeout, (int *)arg)) |
125 | return -EFAULT; | 125 | return -EFAULT; |
126 | break; | 126 | break; |
@@ -136,7 +136,7 @@ static const struct file_operations mpc8xx_wdt_fops = { | |||
136 | .owner = THIS_MODULE, | 136 | .owner = THIS_MODULE, |
137 | .llseek = no_llseek, | 137 | .llseek = no_llseek, |
138 | .write = mpc8xx_wdt_write, | 138 | .write = mpc8xx_wdt_write, |
139 | .ioctl = mpc8xx_wdt_ioctl, | 139 | .unlocked_ioctl = mpc8xx_wdt_ioctl, |
140 | .open = mpc8xx_wdt_open, | 140 | .open = mpc8xx_wdt_open, |
141 | .release = mpc8xx_wdt_release, | 141 | .release = mpc8xx_wdt_release, |
142 | }; | 142 | }; |
@@ -149,6 +149,7 @@ static struct miscdevice mpc8xx_wdt_miscdev = { | |||
149 | 149 | ||
150 | static int __init mpc8xx_wdt_init(void) | 150 | static int __init mpc8xx_wdt_init(void) |
151 | { | 151 | { |
152 | spin_lock_init(&wdt_lock); | ||
152 | return misc_register(&mpc8xx_wdt_miscdev); | 153 | return misc_register(&mpc8xx_wdt_miscdev); |
153 | } | 154 | } |
154 | 155 | ||
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 009573b81496..5e58f8b73d00 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
@@ -29,9 +29,9 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
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 | 33 | ||
33 | #include <asm/hardware/arm_twd.h> | 34 | #include <asm/hardware/arm_twd.h> |
34 | #include <asm/uaccess.h> | ||
35 | 35 | ||
36 | struct mpcore_wdt { | 36 | struct mpcore_wdt { |
37 | unsigned long timer_alive; | 37 | unsigned long timer_alive; |
@@ -43,17 +43,20 @@ struct mpcore_wdt { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct platform_device *mpcore_wdt_dev; | 45 | static struct platform_device *mpcore_wdt_dev; |
46 | |||
47 | extern unsigned int mpcore_timer_rate; | 46 | extern unsigned int mpcore_timer_rate; |
48 | 47 | ||
49 | #define TIMER_MARGIN 60 | 48 | #define TIMER_MARGIN 60 |
50 | static int mpcore_margin = TIMER_MARGIN; | 49 | static int mpcore_margin = TIMER_MARGIN; |
51 | module_param(mpcore_margin, int, 0); | 50 | module_param(mpcore_margin, int, 0); |
52 | MODULE_PARM_DESC(mpcore_margin, "MPcore timer margin in seconds. (0<mpcore_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); | 51 | MODULE_PARM_DESC(mpcore_margin, |
52 | "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default=" | ||
53 | __MODULE_STRING(TIMER_MARGIN) ")"); | ||
53 | 54 | ||
54 | static int nowayout = WATCHDOG_NOWAYOUT; | 55 | static int nowayout = WATCHDOG_NOWAYOUT; |
55 | module_param(nowayout, int, 0); | 56 | module_param(nowayout, int, 0); |
56 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 57 | MODULE_PARM_DESC(nowayout, |
58 | "Watchdog cannot be stopped once started (default=" | ||
59 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
57 | 60 | ||
58 | #define ONLY_TESTING 0 | 61 | #define ONLY_TESTING 0 |
59 | static int mpcore_noboot = ONLY_TESTING; | 62 | static int mpcore_noboot = ONLY_TESTING; |
@@ -70,14 +73,12 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) | |||
70 | 73 | ||
71 | /* Check it really was our interrupt */ | 74 | /* Check it really was our interrupt */ |
72 | if (readl(wdt->base + TWD_WDOG_INTSTAT)) { | 75 | if (readl(wdt->base + TWD_WDOG_INTSTAT)) { |
73 | dev_printk(KERN_CRIT, wdt->dev, "Triggered - Reboot ignored.\n"); | 76 | dev_printk(KERN_CRIT, wdt->dev, |
74 | 77 | "Triggered - Reboot ignored.\n"); | |
75 | /* Clear the interrupt on the watchdog */ | 78 | /* Clear the interrupt on the watchdog */ |
76 | writel(1, wdt->base + TWD_WDOG_INTSTAT); | 79 | writel(1, wdt->base + TWD_WDOG_INTSTAT); |
77 | |||
78 | return IRQ_HANDLED; | 80 | return IRQ_HANDLED; |
79 | } | 81 | } |
80 | |||
81 | return IRQ_NONE; | 82 | return IRQ_NONE; |
82 | } | 83 | } |
83 | 84 | ||
@@ -96,22 +97,26 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) | |||
96 | count = (mpcore_timer_rate / 256) * mpcore_margin; | 97 | count = (mpcore_timer_rate / 256) * mpcore_margin; |
97 | 98 | ||
98 | /* Reload the counter */ | 99 | /* Reload the counter */ |
100 | spin_lock(&wdt_lock); | ||
99 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); | 101 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); |
100 | |||
101 | wdt->perturb = wdt->perturb ? 0 : 1; | 102 | wdt->perturb = wdt->perturb ? 0 : 1; |
103 | spin_unlock(&wdt_lock); | ||
102 | } | 104 | } |
103 | 105 | ||
104 | static void mpcore_wdt_stop(struct mpcore_wdt *wdt) | 106 | static void mpcore_wdt_stop(struct mpcore_wdt *wdt) |
105 | { | 107 | { |
108 | spin_lock(&wdt_lock); | ||
106 | writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); | 109 | writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); |
107 | writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); | 110 | writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); |
108 | writel(0x0, wdt->base + TWD_WDOG_CONTROL); | 111 | writel(0x0, wdt->base + TWD_WDOG_CONTROL); |
112 | spin_unlock(&wdt_lock); | ||
109 | } | 113 | } |
110 | 114 | ||
111 | static void mpcore_wdt_start(struct mpcore_wdt *wdt) | 115 | static void mpcore_wdt_start(struct mpcore_wdt *wdt) |
112 | { | 116 | { |
113 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); | 117 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); |
114 | 118 | ||
119 | spin_lock(&wdt_lock); | ||
115 | /* This loads the count register but does NOT start the count yet */ | 120 | /* This loads the count register but does NOT start the count yet */ |
116 | mpcore_wdt_keepalive(wdt); | 121 | mpcore_wdt_keepalive(wdt); |
117 | 122 | ||
@@ -122,6 +127,7 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
122 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ | 127 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ |
123 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); | 128 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); |
124 | } | 129 | } |
130 | spin_unlock(&wdt_lock); | ||
125 | } | 131 | } |
126 | 132 | ||
127 | static int mpcore_wdt_set_heartbeat(int t) | 133 | static int mpcore_wdt_set_heartbeat(int t) |
@@ -164,10 +170,11 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file) | |||
164 | * Shut off the timer. | 170 | * Shut off the timer. |
165 | * Lock it in if it's a module and we set nowayout | 171 | * Lock it in if it's a module and we set nowayout |
166 | */ | 172 | */ |
167 | if (wdt->expect_close == 42) { | 173 | if (wdt->expect_close == 42) |
168 | mpcore_wdt_stop(wdt); | 174 | mpcore_wdt_stop(wdt); |
169 | } else { | 175 | else { |
170 | dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); | 176 | dev_printk(KERN_CRIT, wdt->dev, |
177 | "unexpected close, not stopping watchdog!\n"); | ||
171 | mpcore_wdt_keepalive(wdt); | 178 | mpcore_wdt_keepalive(wdt); |
172 | } | 179 | } |
173 | clear_bit(0, &wdt->timer_alive); | 180 | clear_bit(0, &wdt->timer_alive); |
@@ -175,7 +182,8 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file) | |||
175 | return 0; | 182 | return 0; |
176 | } | 183 | } |
177 | 184 | ||
178 | static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 185 | static ssize_t mpcore_wdt_write(struct file *file, const char *data, |
186 | size_t len, loff_t *ppos) | ||
179 | { | 187 | { |
180 | struct mpcore_wdt *wdt = file->private_data; | 188 | struct mpcore_wdt *wdt = file->private_data; |
181 | 189 | ||
@@ -210,8 +218,8 @@ static struct watchdog_info ident = { | |||
210 | .identity = "MPcore Watchdog", | 218 | .identity = "MPcore Watchdog", |
211 | }; | 219 | }; |
212 | 220 | ||
213 | static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | 221 | static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd, |
214 | unsigned int cmd, unsigned long arg) | 222 | unsigned long arg) |
215 | { | 223 | { |
216 | struct mpcore_wdt *wdt = file->private_data; | 224 | struct mpcore_wdt *wdt = file->private_data; |
217 | int ret; | 225 | int ret; |
@@ -301,7 +309,7 @@ static const struct file_operations mpcore_wdt_fops = { | |||
301 | .owner = THIS_MODULE, | 309 | .owner = THIS_MODULE, |
302 | .llseek = no_llseek, | 310 | .llseek = no_llseek, |
303 | .write = mpcore_wdt_write, | 311 | .write = mpcore_wdt_write, |
304 | .ioctl = mpcore_wdt_ioctl, | 312 | .unlocked_ioctl = mpcore_wdt_ioctl, |
305 | .open = mpcore_wdt_open, | 313 | .open = mpcore_wdt_open, |
306 | .release = mpcore_wdt_release, | 314 | .release = mpcore_wdt_release, |
307 | }; | 315 | }; |
@@ -349,14 +357,17 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
349 | mpcore_wdt_miscdev.parent = &dev->dev; | 357 | mpcore_wdt_miscdev.parent = &dev->dev; |
350 | ret = misc_register(&mpcore_wdt_miscdev); | 358 | ret = misc_register(&mpcore_wdt_miscdev); |
351 | if (ret) { | 359 | if (ret) { |
352 | dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n", | 360 | dev_printk(KERN_ERR, _dev, |
353 | WATCHDOG_MINOR, ret); | 361 | "cannot register miscdev on minor=%d (err=%d)\n", |
362 | WATCHDOG_MINOR, ret); | ||
354 | goto err_misc; | 363 | goto err_misc; |
355 | } | 364 | } |
356 | 365 | ||
357 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, "mpcore_wdt", wdt); | 366 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, |
367 | "mpcore_wdt", wdt); | ||
358 | if (ret) { | 368 | if (ret) { |
359 | dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq); | 369 | dev_printk(KERN_ERR, _dev, |
370 | "cannot register IRQ%d for watchdog\n", wdt->irq); | ||
360 | goto err_irq; | 371 | goto err_irq; |
361 | } | 372 | } |
362 | 373 | ||
@@ -415,7 +426,7 @@ static int __init mpcore_wdt_init(void) | |||
415 | */ | 426 | */ |
416 | if (mpcore_wdt_set_heartbeat(mpcore_margin)) { | 427 | if (mpcore_wdt_set_heartbeat(mpcore_margin)) { |
417 | mpcore_wdt_set_heartbeat(TIMER_MARGIN); | 428 | mpcore_wdt_set_heartbeat(TIMER_MARGIN); |
418 | printk(KERN_INFO "mpcore_margin value must be 0<mpcore_margin<65536, using %d\n", | 429 | printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n", |
419 | TIMER_MARGIN); | 430 | TIMER_MARGIN); |
420 | } | 431 | } |
421 | 432 | ||
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index a8e67383784e..e0b8cdfa5e70 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the MTX-1 Watchdog. | 2 | * Driver for the MTX-1 Watchdog. |
3 | * | 3 | * |
4 | * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, All Rights Reserved. | 4 | * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, |
5 | * All Rights Reserved. | ||
5 | * http://www.4g-systems.biz | 6 | * http://www.4g-systems.biz |
6 | * | 7 | * |
7 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> | 8 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> |
@@ -46,12 +47,11 @@ | |||
46 | #include <linux/jiffies.h> | 47 | #include <linux/jiffies.h> |
47 | #include <linux/watchdog.h> | 48 | #include <linux/watchdog.h> |
48 | #include <linux/platform_device.h> | 49 | #include <linux/platform_device.h> |
49 | 50 | #include <linux/io.h> | |
50 | #include <asm/io.h> | 51 | #include <linux/uaccess.h> |
51 | #include <asm/uaccess.h> | 52 | #include <linux/gpio.h> |
52 | 53 | ||
53 | #include <asm/mach-au1x00/au1000.h> | 54 | #include <asm/mach-au1x00/au1000.h> |
54 | #include <asm/gpio.h> | ||
55 | 55 | ||
56 | #define MTX1_WDT_INTERVAL (5 * HZ) | 56 | #define MTX1_WDT_INTERVAL (5 * HZ) |
57 | 57 | ||
@@ -59,6 +59,7 @@ static int ticks = 100 * HZ; | |||
59 | 59 | ||
60 | static struct { | 60 | static struct { |
61 | struct completion stop; | 61 | struct completion stop; |
62 | spinlock_t lock; | ||
62 | int running; | 63 | int running; |
63 | struct timer_list timer; | 64 | struct timer_list timer; |
64 | int queue; | 65 | int queue; |
@@ -71,6 +72,7 @@ static void mtx1_wdt_trigger(unsigned long unused) | |||
71 | { | 72 | { |
72 | u32 tmp; | 73 | u32 tmp; |
73 | 74 | ||
75 | spin_lock(&mtx1_wdt_device.lock); | ||
74 | if (mtx1_wdt_device.running) | 76 | if (mtx1_wdt_device.running) |
75 | ticks--; | 77 | ticks--; |
76 | /* | 78 | /* |
@@ -79,13 +81,13 @@ static void mtx1_wdt_trigger(unsigned long unused) | |||
79 | tmp = au_readl(GPIO2_DIR); | 81 | tmp = au_readl(GPIO2_DIR); |
80 | tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | | 82 | tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | |
81 | ((~tmp) & (1 << mtx1_wdt_device.gpio)); | 83 | ((~tmp) & (1 << mtx1_wdt_device.gpio)); |
82 | au_writel (tmp, GPIO2_DIR); | 84 | au_writel(tmp, GPIO2_DIR); |
83 | 85 | ||
84 | if (mtx1_wdt_device.queue && ticks) | 86 | if (mtx1_wdt_device.queue && ticks) |
85 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 87 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
86 | else { | 88 | else |
87 | complete(&mtx1_wdt_device.stop); | 89 | complete(&mtx1_wdt_device.stop); |
88 | } | 90 | spin_unlock(&mtx1_wdt_device.lock); |
89 | } | 91 | } |
90 | 92 | ||
91 | static void mtx1_wdt_reset(void) | 93 | static void mtx1_wdt_reset(void) |
@@ -96,23 +98,25 @@ static void mtx1_wdt_reset(void) | |||
96 | 98 | ||
97 | static void mtx1_wdt_start(void) | 99 | static void mtx1_wdt_start(void) |
98 | { | 100 | { |
101 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | ||
99 | if (!mtx1_wdt_device.queue) { | 102 | if (!mtx1_wdt_device.queue) { |
100 | mtx1_wdt_device.queue = 1; | 103 | mtx1_wdt_device.queue = 1; |
101 | gpio_set_value(mtx1_wdt_device.gpio, 1); | 104 | gpio_set_value(mtx1_wdt_device.gpio, 1); |
102 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 105 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
103 | } | 106 | } |
104 | mtx1_wdt_device.running++; | 107 | mtx1_wdt_device.running++; |
108 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); | ||
105 | } | 109 | } |
106 | 110 | ||
107 | static int mtx1_wdt_stop(void) | 111 | static int mtx1_wdt_stop(void) |
108 | { | 112 | { |
113 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | ||
109 | if (mtx1_wdt_device.queue) { | 114 | if (mtx1_wdt_device.queue) { |
110 | mtx1_wdt_device.queue = 0; | 115 | mtx1_wdt_device.queue = 0; |
111 | gpio_set_value(mtx1_wdt_device.gpio, 0); | 116 | gpio_set_value(mtx1_wdt_device.gpio, 0); |
112 | } | 117 | } |
113 | |||
114 | ticks = mtx1_wdt_device.default_ticks; | 118 | ticks = mtx1_wdt_device.default_ticks; |
115 | 119 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); | |
116 | return 0; | 120 | return 0; |
117 | } | 121 | } |
118 | 122 | ||
@@ -122,7 +126,6 @@ static int mtx1_wdt_open(struct inode *inode, struct file *file) | |||
122 | { | 126 | { |
123 | if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) | 127 | if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) |
124 | return -EBUSY; | 128 | return -EBUSY; |
125 | |||
126 | return nonseekable_open(inode, file); | 129 | return nonseekable_open(inode, file); |
127 | } | 130 | } |
128 | 131 | ||
@@ -133,54 +136,51 @@ static int mtx1_wdt_release(struct inode *inode, struct file *file) | |||
133 | return 0; | 136 | return 0; |
134 | } | 137 | } |
135 | 138 | ||
136 | static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 139 | static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd, |
140 | unsigned long arg) | ||
137 | { | 141 | { |
138 | void __user *argp = (void __user *)arg; | 142 | void __user *argp = (void __user *)arg; |
143 | int __user *p = (int __user *)argp; | ||
139 | unsigned int value; | 144 | unsigned int value; |
140 | static struct watchdog_info ident = | 145 | static const struct watchdog_info ident = { |
141 | { | ||
142 | .options = WDIOF_CARDRESET, | 146 | .options = WDIOF_CARDRESET, |
143 | .identity = "MTX-1 WDT", | 147 | .identity = "MTX-1 WDT", |
144 | }; | 148 | }; |
145 | 149 | ||
146 | switch(cmd) { | 150 | switch (cmd) { |
147 | case WDIOC_KEEPALIVE: | 151 | case WDIOC_KEEPALIVE: |
148 | mtx1_wdt_reset(); | 152 | mtx1_wdt_reset(); |
149 | break; | 153 | break; |
150 | case WDIOC_GETSTATUS: | 154 | case WDIOC_GETSTATUS: |
151 | case WDIOC_GETBOOTSTATUS: | 155 | case WDIOC_GETBOOTSTATUS: |
152 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 156 | put_user(0, p); |
153 | return -EFAULT; | 157 | break; |
154 | break; | 158 | case WDIOC_GETSUPPORT: |
155 | case WDIOC_GETSUPPORT: | 159 | if (copy_to_user(argp, &ident, sizeof(ident))) |
156 | if ( copy_to_user(argp, &ident, sizeof(ident)) ) | 160 | return -EFAULT; |
157 | return -EFAULT; | 161 | break; |
158 | break; | 162 | case WDIOC_SETOPTIONS: |
159 | case WDIOC_SETOPTIONS: | 163 | if (get_user(value, p)) |
160 | if ( copy_from_user(&value, argp, sizeof(int)) ) | 164 | return -EFAULT; |
161 | return -EFAULT; | 165 | if (value & WDIOS_ENABLECARD) |
162 | switch(value) { | 166 | mtx1_wdt_start(); |
163 | case WDIOS_ENABLECARD: | 167 | else if (value & WDIOS_DISABLECARD) |
164 | mtx1_wdt_start(); | 168 | mtx1_wdt_stop(); |
165 | break; | 169 | else |
166 | case WDIOS_DISABLECARD: | 170 | return -EINVAL; |
167 | return mtx1_wdt_stop(); | 171 | return 0; |
168 | default: | 172 | default: |
169 | return -EINVAL; | 173 | return -ENOTTY; |
170 | } | ||
171 | break; | ||
172 | default: | ||
173 | return -ENOTTY; | ||
174 | } | 174 | } |
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | 178 | ||
179 | static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | 179 | static ssize_t mtx1_wdt_write(struct file *file, const char *buf, |
180 | size_t count, loff_t *ppos) | ||
180 | { | 181 | { |
181 | if (!count) | 182 | if (!count) |
182 | return -EIO; | 183 | return -EIO; |
183 | |||
184 | mtx1_wdt_reset(); | 184 | mtx1_wdt_reset(); |
185 | return count; | 185 | return count; |
186 | } | 186 | } |
@@ -188,7 +188,7 @@ static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, | |||
188 | static const struct file_operations mtx1_wdt_fops = { | 188 | static const struct file_operations mtx1_wdt_fops = { |
189 | .owner = THIS_MODULE, | 189 | .owner = THIS_MODULE, |
190 | .llseek = no_llseek, | 190 | .llseek = no_llseek, |
191 | .ioctl = mtx1_wdt_ioctl, | 191 | .unlocked_ioctl = mtx1_wdt_ioctl, |
192 | .open = mtx1_wdt_open, | 192 | .open = mtx1_wdt_open, |
193 | .write = mtx1_wdt_write, | 193 | .write = mtx1_wdt_write, |
194 | .release = mtx1_wdt_release | 194 | .release = mtx1_wdt_release |
@@ -208,29 +208,26 @@ static int mtx1_wdt_probe(struct platform_device *pdev) | |||
208 | 208 | ||
209 | mtx1_wdt_device.gpio = pdev->resource[0].start; | 209 | mtx1_wdt_device.gpio = pdev->resource[0].start; |
210 | 210 | ||
211 | if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { | 211 | spin_lock_init(&mtx1_wdt_device.lock); |
212 | printk(KERN_ERR " mtx-1_wdt : failed to register\n"); | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | init_completion(&mtx1_wdt_device.stop); | 212 | init_completion(&mtx1_wdt_device.stop); |
217 | mtx1_wdt_device.queue = 0; | 213 | mtx1_wdt_device.queue = 0; |
218 | |||
219 | clear_bit(0, &mtx1_wdt_device.inuse); | 214 | clear_bit(0, &mtx1_wdt_device.inuse); |
220 | |||
221 | setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); | 215 | setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); |
222 | |||
223 | mtx1_wdt_device.default_ticks = ticks; | 216 | mtx1_wdt_device.default_ticks = ticks; |
224 | 217 | ||
218 | ret = misc_register(&mtx1_wdt_misc); | ||
219 | if (ret < 0) { | ||
220 | printk(KERN_ERR " mtx-1_wdt : failed to register\n"); | ||
221 | return ret; | ||
222 | } | ||
225 | mtx1_wdt_start(); | 223 | mtx1_wdt_start(); |
226 | |||
227 | printk(KERN_INFO "MTX-1 Watchdog driver\n"); | 224 | printk(KERN_INFO "MTX-1 Watchdog driver\n"); |
228 | |||
229 | return 0; | 225 | return 0; |
230 | } | 226 | } |
231 | 227 | ||
232 | static int mtx1_wdt_remove(struct platform_device *pdev) | 228 | static int mtx1_wdt_remove(struct platform_device *pdev) |
233 | { | 229 | { |
230 | /* FIXME: do we need to lock this test ? */ | ||
234 | if (mtx1_wdt_device.queue) { | 231 | if (mtx1_wdt_device.queue) { |
235 | mtx1_wdt_device.queue = 0; | 232 | mtx1_wdt_device.queue = 0; |
236 | wait_for_completion(&mtx1_wdt_device.stop); | 233 | wait_for_completion(&mtx1_wdt_device.stop); |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index b59ca3273967..ac09fe4d9573 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * and services the watchdog. | 8 | * and services the watchdog. |
9 | * | 9 | * |
10 | * Derived from mpc8xx_wdt.c, with the following copyright. | 10 | * Derived from mpc8xx_wdt.c, with the following copyright. |
11 | * | 11 | * |
12 | * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under | 12 | * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under |
13 | * the terms of the GNU General Public License version 2. This program | 13 | * the terms of the GNU General Public License version 2. This program |
14 | * is licensed "as is" without any warranty of any kind, whether express | 14 | * is licensed "as is" without any warranty of any kind, whether express |
@@ -24,8 +24,8 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | 25 | ||
26 | #include <linux/mv643xx.h> | 26 | #include <linux/mv643xx.h> |
27 | #include <asm/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <asm/io.h> | 28 | #include <linux/io.h> |
29 | 29 | ||
30 | #define MV64x60_WDT_WDC_OFFSET 0 | 30 | #define MV64x60_WDT_WDC_OFFSET 0 |
31 | 31 | ||
@@ -61,7 +61,9 @@ static DEFINE_SPINLOCK(mv64x60_wdt_spinlock); | |||
61 | 61 | ||
62 | static int nowayout = WATCHDOG_NOWAYOUT; | 62 | static int nowayout = WATCHDOG_NOWAYOUT; |
63 | module_param(nowayout, int, 0); | 63 | module_param(nowayout, int, 0); |
64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 64 | MODULE_PARM_DESC(nowayout, |
65 | "Watchdog cannot be stopped once started (default=" | ||
66 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
65 | 67 | ||
66 | static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) | 68 | static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) |
67 | { | 69 | { |
@@ -150,7 +152,7 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file) | |||
150 | } | 152 | } |
151 | 153 | ||
152 | static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | 154 | static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, |
153 | size_t len, loff_t * ppos) | 155 | size_t len, loff_t *ppos) |
154 | { | 156 | { |
155 | if (len) { | 157 | if (len) { |
156 | if (!nowayout) { | 158 | if (!nowayout) { |
@@ -160,7 +162,7 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | |||
160 | 162 | ||
161 | for (i = 0; i != len; i++) { | 163 | for (i = 0; i != len; i++) { |
162 | char c; | 164 | char c; |
163 | if(get_user(c, data + i)) | 165 | if (get_user(c, data + i)) |
164 | return -EFAULT; | 166 | return -EFAULT; |
165 | if (c == 'V') | 167 | if (c == 'V') |
166 | expect_close = 42; | 168 | expect_close = 42; |
@@ -172,8 +174,8 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | |||
172 | return len; | 174 | return len; |
173 | } | 175 | } |
174 | 176 | ||
175 | static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, | 177 | static long mv64x60_wdt_ioctl(struct file *file, |
176 | unsigned int cmd, unsigned long arg) | 178 | unsigned int cmd, unsigned long arg) |
177 | { | 179 | { |
178 | int timeout; | 180 | int timeout; |
179 | int options; | 181 | int options; |
@@ -240,7 +242,7 @@ static const struct file_operations mv64x60_wdt_fops = { | |||
240 | .owner = THIS_MODULE, | 242 | .owner = THIS_MODULE, |
241 | .llseek = no_llseek, | 243 | .llseek = no_llseek, |
242 | .write = mv64x60_wdt_write, | 244 | .write = mv64x60_wdt_write, |
243 | .ioctl = mv64x60_wdt_ioctl, | 245 | .unlocked_ioctl = mv64x60_wdt_ioctl, |
244 | .open = mv64x60_wdt_open, | 246 | .open = mv64x60_wdt_open, |
245 | .release = mv64x60_wdt_release, | 247 | .release = mv64x60_wdt_release, |
246 | }; | 248 | }; |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 74bc39aa1ce8..ccdf069792d9 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -41,9 +41,9 @@ | |||
41 | #include <linux/clk.h> | 41 | #include <linux/clk.h> |
42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
43 | 43 | ||
44 | #include <asm/io.h> | 44 | #include </io.h> |
45 | #include <asm/uaccess.h> | 45 | #include <linux/uaccess.h> |
46 | #include <asm/hardware.h> | 46 | #include <linux/hardware.h> |
47 | 47 | ||
48 | #include <asm/arch/prcm.h> | 48 | #include <asm/arch/prcm.h> |
49 | 49 | ||
@@ -54,11 +54,12 @@ module_param(timer_margin, uint, 0); | |||
54 | MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); | 54 | MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); |
55 | 55 | ||
56 | static int omap_wdt_users; | 56 | static int omap_wdt_users; |
57 | static struct clk *armwdt_ck = NULL; | 57 | static struct clk *armwdt_ck; |
58 | static struct clk *mpu_wdt_ick = NULL; | 58 | static struct clk *mpu_wdt_ick; |
59 | static struct clk *mpu_wdt_fck = NULL; | 59 | static struct clk *mpu_wdt_fck; |
60 | 60 | ||
61 | static unsigned int wdt_trgr_pattern = 0x1234; | 61 | static unsigned int wdt_trgr_pattern = 0x1234; |
62 | static spinlock_t wdt_lock; | ||
62 | 63 | ||
63 | static void omap_wdt_ping(void) | 64 | static void omap_wdt_ping(void) |
64 | { | 65 | { |
@@ -174,22 +175,23 @@ static int omap_wdt_release(struct inode *inode, struct file *file) | |||
174 | return 0; | 175 | return 0; |
175 | } | 176 | } |
176 | 177 | ||
177 | static ssize_t | 178 | static ssize_t omap_wdt_write(struct file *file, const char __user *data, |
178 | omap_wdt_write(struct file *file, const char __user *data, | ||
179 | size_t len, loff_t *ppos) | 179 | size_t len, loff_t *ppos) |
180 | { | 180 | { |
181 | /* Refresh LOAD_TIME. */ | 181 | /* Refresh LOAD_TIME. */ |
182 | if (len) | 182 | if (len) { |
183 | spin_lock(&wdt_lock); | ||
183 | omap_wdt_ping(); | 184 | omap_wdt_ping(); |
185 | spin_unlock(&wdt_lock); | ||
186 | } | ||
184 | return len; | 187 | return len; |
185 | } | 188 | } |
186 | 189 | ||
187 | static int | 190 | static long omap_wdt_ioctl(struct file *file, unsigned int cmd, |
188 | omap_wdt_ioctl(struct inode *inode, struct file *file, | 191 | unsigned long arg) |
189 | unsigned int cmd, unsigned long arg) | ||
190 | { | 192 | { |
191 | int new_margin; | 193 | int new_margin; |
192 | static struct watchdog_info ident = { | 194 | static const struct watchdog_info ident = { |
193 | .identity = "OMAP Watchdog", | 195 | .identity = "OMAP Watchdog", |
194 | .options = WDIOF_SETTIMEOUT, | 196 | .options = WDIOF_SETTIMEOUT, |
195 | .firmware_version = 0, | 197 | .firmware_version = 0, |
@@ -211,18 +213,22 @@ omap_wdt_ioctl(struct inode *inode, struct file *file, | |||
211 | return put_user(omap_prcm_get_reset_sources(), | 213 | return put_user(omap_prcm_get_reset_sources(), |
212 | (int __user *)arg); | 214 | (int __user *)arg); |
213 | case WDIOC_KEEPALIVE: | 215 | case WDIOC_KEEPALIVE: |
216 | spin_lock(&wdt_lock); | ||
214 | omap_wdt_ping(); | 217 | omap_wdt_ping(); |
218 | spin_unlock(&wdt_lock); | ||
215 | return 0; | 219 | return 0; |
216 | case WDIOC_SETTIMEOUT: | 220 | case WDIOC_SETTIMEOUT: |
217 | if (get_user(new_margin, (int __user *)arg)) | 221 | if (get_user(new_margin, (int __user *)arg)) |
218 | return -EFAULT; | 222 | return -EFAULT; |
219 | omap_wdt_adjust_timeout(new_margin); | 223 | omap_wdt_adjust_timeout(new_margin); |
220 | 224 | ||
225 | spin_lock(&wdt_lock); | ||
221 | omap_wdt_disable(); | 226 | omap_wdt_disable(); |
222 | omap_wdt_set_timeout(); | 227 | omap_wdt_set_timeout(); |
223 | omap_wdt_enable(); | 228 | omap_wdt_enable(); |
224 | 229 | ||
225 | omap_wdt_ping(); | 230 | omap_wdt_ping(); |
231 | spin_unlock(&wdt_lock); | ||
226 | /* Fall */ | 232 | /* Fall */ |
227 | case WDIOC_GETTIMEOUT: | 233 | case WDIOC_GETTIMEOUT: |
228 | return put_user(timer_margin, (int __user *)arg); | 234 | return put_user(timer_margin, (int __user *)arg); |
@@ -232,7 +238,7 @@ omap_wdt_ioctl(struct inode *inode, struct file *file, | |||
232 | static const struct file_operations omap_wdt_fops = { | 238 | static const struct file_operations omap_wdt_fops = { |
233 | .owner = THIS_MODULE, | 239 | .owner = THIS_MODULE, |
234 | .write = omap_wdt_write, | 240 | .write = omap_wdt_write, |
235 | .ioctl = omap_wdt_ioctl, | 241 | .unlocked_ioctl = omap_wdt_ioctl, |
236 | .open = omap_wdt_open, | 242 | .open = omap_wdt_open, |
237 | .release = omap_wdt_release, | 243 | .release = omap_wdt_release, |
238 | }; | 244 | }; |
@@ -373,6 +379,7 @@ static struct platform_driver omap_wdt_driver = { | |||
373 | 379 | ||
374 | static int __init omap_wdt_init(void) | 380 | static int __init omap_wdt_init(void) |
375 | { | 381 | { |
382 | spin_lock_init(&wdt_lock); | ||
376 | return platform_driver_register(&omap_wdt_driver); | 383 | return platform_driver_register(&omap_wdt_driver); |
377 | } | 384 | } |
378 | 385 | ||
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 15e4f8887a9e..326f2d2ded3b 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c | |||
@@ -31,9 +31,9 @@ | |||
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
33 | #include <linux/version.h> | 33 | #include <linux/version.h> |
34 | #include <linux/io.h> | ||
35 | #include <linux/uaccess.h> | ||
34 | 36 | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
38 | 38 | ||
39 | /* #define DEBUG 1 */ | 39 | /* #define DEBUG 1 */ |
@@ -56,12 +56,12 @@ | |||
56 | 56 | ||
57 | static int io = 0x2E; /* Address used on Portwell Boards */ | 57 | static int io = 0x2E; /* Address used on Portwell Boards */ |
58 | 58 | ||
59 | static int timeout = DEFAULT_TIMEOUT; /* timeout value */ | 59 | static int timeout = DEFAULT_TIMEOUT; /* timeout value */ |
60 | static unsigned long timer_enabled = 0; /* is the timer enabled? */ | 60 | static unsigned long timer_enabled; /* is the timer enabled? */ |
61 | 61 | ||
62 | static char expect_close; /* is the close expected? */ | 62 | static char expect_close; /* is the close expected? */ |
63 | 63 | ||
64 | static DEFINE_SPINLOCK(io_lock);/* to guard the watchdog from io races */ | 64 | static DEFINE_SPINLOCK(io_lock); /* to guard us from io races */ |
65 | 65 | ||
66 | static int nowayout = WATCHDOG_NOWAYOUT; | 66 | static int nowayout = WATCHDOG_NOWAYOUT; |
67 | 67 | ||
@@ -69,7 +69,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
69 | 69 | ||
70 | /* Select pins for Watchdog output */ | 70 | /* Select pins for Watchdog output */ |
71 | 71 | ||
72 | static inline void pc87413_select_wdt_out (void) | 72 | static inline void pc87413_select_wdt_out(void) |
73 | { | 73 | { |
74 | unsigned int cr_data = 0; | 74 | unsigned int cr_data = 0; |
75 | 75 | ||
@@ -77,7 +77,7 @@ static inline void pc87413_select_wdt_out (void) | |||
77 | 77 | ||
78 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); | 78 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); |
79 | 79 | ||
80 | cr_data = inb (WDT_DATA_IO_PORT); | 80 | cr_data = inb(WDT_DATA_IO_PORT); |
81 | 81 | ||
82 | cr_data |= 0x80; /* Set Bit7 to 1*/ | 82 | cr_data |= 0x80; /* Set Bit7 to 1*/ |
83 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); | 83 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); |
@@ -85,8 +85,9 @@ static inline void pc87413_select_wdt_out (void) | |||
85 | outb_p(cr_data, WDT_DATA_IO_PORT); | 85 | outb_p(cr_data, WDT_DATA_IO_PORT); |
86 | 86 | ||
87 | #ifdef DEBUG | 87 | #ifdef DEBUG |
88 | printk(KERN_INFO DPFX "Select multiple pin,pin55,as WDT output:" | 88 | printk(KERN_INFO DPFX |
89 | " Bit7 to 1: %d\n", cr_data); | 89 | "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n", |
90 | cr_data); | ||
90 | #endif | 91 | #endif |
91 | } | 92 | } |
92 | 93 | ||
@@ -94,7 +95,7 @@ static inline void pc87413_select_wdt_out (void) | |||
94 | 95 | ||
95 | static inline void pc87413_enable_swc(void) | 96 | static inline void pc87413_enable_swc(void) |
96 | { | 97 | { |
97 | unsigned int cr_data=0; | 98 | unsigned int cr_data = 0; |
98 | 99 | ||
99 | /* Step 2: Enable SWC functions */ | 100 | /* Step 2: Enable SWC functions */ |
100 | 101 | ||
@@ -129,12 +130,11 @@ static inline unsigned int pc87413_get_swc_base(void) | |||
129 | addr_l = inb(WDT_DATA_IO_PORT); | 130 | addr_l = inb(WDT_DATA_IO_PORT); |
130 | 131 | ||
131 | swc_base_addr = (addr_h << 8) + addr_l; | 132 | swc_base_addr = (addr_h << 8) + addr_l; |
132 | |||
133 | #ifdef DEBUG | 133 | #ifdef DEBUG |
134 | printk(KERN_INFO DPFX "Read SWC I/O Base Address: low %d, high %d," | 134 | printk(KERN_INFO DPFX |
135 | " res %d\n", addr_l, addr_h, swc_base_addr); | 135 | "Read SWC I/O Base Address: low %d, high %d, res %d\n", |
136 | addr_l, addr_h, swc_base_addr); | ||
136 | #endif | 137 | #endif |
137 | |||
138 | return swc_base_addr; | 138 | return swc_base_addr; |
139 | } | 139 | } |
140 | 140 | ||
@@ -143,9 +143,7 @@ static inline unsigned int pc87413_get_swc_base(void) | |||
143 | static inline void pc87413_swc_bank3(unsigned int swc_base_addr) | 143 | static inline void pc87413_swc_bank3(unsigned int swc_base_addr) |
144 | { | 144 | { |
145 | /* Step 4: Select Bank3 of SWC */ | 145 | /* Step 4: Select Bank3 of SWC */ |
146 | |||
147 | outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); | 146 | outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); |
148 | |||
149 | #ifdef DEBUG | 147 | #ifdef DEBUG |
150 | printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); | 148 | printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); |
151 | #endif | 149 | #endif |
@@ -157,9 +155,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr, | |||
157 | char pc87413_time) | 155 | char pc87413_time) |
158 | { | 156 | { |
159 | /* Step 5: Programm WDTO, Twd. */ | 157 | /* Step 5: Programm WDTO, Twd. */ |
160 | |||
161 | outb_p(pc87413_time, swc_base_addr + WDTO); | 158 | outb_p(pc87413_time, swc_base_addr + WDTO); |
162 | |||
163 | #ifdef DEBUG | 159 | #ifdef DEBUG |
164 | printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); | 160 | printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); |
165 | #endif | 161 | #endif |
@@ -170,9 +166,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr, | |||
170 | static inline void pc87413_enable_wden(unsigned int swc_base_addr) | 166 | static inline void pc87413_enable_wden(unsigned int swc_base_addr) |
171 | { | 167 | { |
172 | /* Step 6: Enable WDEN */ | 168 | /* Step 6: Enable WDEN */ |
173 | 169 | outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL); | |
174 | outb_p(inb (swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL); | ||
175 | |||
176 | #ifdef DEBUG | 170 | #ifdef DEBUG |
177 | printk(KERN_INFO DPFX "Enable WDEN\n"); | 171 | printk(KERN_INFO DPFX "Enable WDEN\n"); |
178 | #endif | 172 | #endif |
@@ -182,9 +176,7 @@ static inline void pc87413_enable_wden(unsigned int swc_base_addr) | |||
182 | static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) | 176 | static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) |
183 | { | 177 | { |
184 | /* Enable SW_WD_TREN */ | 178 | /* Enable SW_WD_TREN */ |
185 | 179 | outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG); | |
186 | outb_p(inb (swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG); | ||
187 | |||
188 | #ifdef DEBUG | 180 | #ifdef DEBUG |
189 | printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); | 181 | printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); |
190 | #endif | 182 | #endif |
@@ -195,9 +187,7 @@ static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) | |||
195 | static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) | 187 | static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) |
196 | { | 188 | { |
197 | /* Disable SW_WD_TREN */ | 189 | /* Disable SW_WD_TREN */ |
198 | 190 | outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG); | |
199 | outb_p(inb (swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG); | ||
200 | |||
201 | #ifdef DEBUG | 191 | #ifdef DEBUG |
202 | printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); | 192 | printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); |
203 | #endif | 193 | #endif |
@@ -208,9 +198,7 @@ static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) | |||
208 | static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) | 198 | static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) |
209 | { | 199 | { |
210 | /* Enable SW_WD_TRG */ | 200 | /* Enable SW_WD_TRG */ |
211 | 201 | outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL); | |
212 | outb_p(inb (swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL); | ||
213 | |||
214 | #ifdef DEBUG | 202 | #ifdef DEBUG |
215 | printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); | 203 | printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); |
216 | #endif | 204 | #endif |
@@ -221,9 +209,7 @@ static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) | |||
221 | static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) | 209 | static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) |
222 | { | 210 | { |
223 | /* Disable SW_WD_TRG */ | 211 | /* Disable SW_WD_TRG */ |
224 | 212 | outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL); | |
225 | outb_p(inb (swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL); | ||
226 | |||
227 | #ifdef DEBUG | 213 | #ifdef DEBUG |
228 | printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); | 214 | printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); |
229 | #endif | 215 | #endif |
@@ -314,8 +300,8 @@ static int pc87413_open(struct inode *inode, struct file *file) | |||
314 | /* Reload and activate timer */ | 300 | /* Reload and activate timer */ |
315 | pc87413_refresh(); | 301 | pc87413_refresh(); |
316 | 302 | ||
317 | printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to" | 303 | printk(KERN_INFO MODNAME |
318 | " %d minute(s).\n", timeout); | 304 | "Watchdog enabled. Timeout set to %d minute(s).\n", timeout); |
319 | 305 | ||
320 | return nonseekable_open(inode, file); | 306 | return nonseekable_open(inode, file); |
321 | } | 307 | } |
@@ -338,17 +324,15 @@ static int pc87413_release(struct inode *inode, struct file *file) | |||
338 | 324 | ||
339 | if (expect_close == 42) { | 325 | if (expect_close == 42) { |
340 | pc87413_disable(); | 326 | pc87413_disable(); |
341 | printk(KERN_INFO MODNAME "Watchdog disabled," | 327 | printk(KERN_INFO MODNAME |
342 | " sleeping again...\n"); | 328 | "Watchdog disabled, sleeping again...\n"); |
343 | } else { | 329 | } else { |
344 | printk(KERN_CRIT MODNAME "Unexpected close, not stopping" | 330 | printk(KERN_CRIT MODNAME |
345 | " watchdog!\n"); | 331 | "Unexpected close, not stopping watchdog!\n"); |
346 | pc87413_refresh(); | 332 | pc87413_refresh(); |
347 | } | 333 | } |
348 | |||
349 | clear_bit(0, &timer_enabled); | 334 | clear_bit(0, &timer_enabled); |
350 | expect_close = 0; | 335 | expect_close = 0; |
351 | |||
352 | return 0; | 336 | return 0; |
353 | } | 337 | } |
354 | 338 | ||
@@ -386,7 +370,8 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
386 | /* reset expect flag */ | 370 | /* reset expect flag */ |
387 | expect_close = 0; | 371 | expect_close = 0; |
388 | 372 | ||
389 | /* scan to see whether or not we got the magic character */ | 373 | /* scan to see whether or not we got the |
374 | magic character */ | ||
390 | for (i = 0; i != len; i++) { | 375 | for (i = 0; i != len; i++) { |
391 | char c; | 376 | char c; |
392 | if (get_user(c, data+i)) | 377 | if (get_user(c, data+i)) |
@@ -404,7 +389,6 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
404 | 389 | ||
405 | /** | 390 | /** |
406 | * pc87413_ioctl: | 391 | * pc87413_ioctl: |
407 | * @inode: inode of the device | ||
408 | * @file: file handle to the device | 392 | * @file: file handle to the device |
409 | * @cmd: watchdog command | 393 | * @cmd: watchdog command |
410 | * @arg: argument pointer | 394 | * @arg: argument pointer |
@@ -414,8 +398,8 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
414 | * querying capabilities and current status. | 398 | * querying capabilities and current status. |
415 | */ | 399 | */ |
416 | 400 | ||
417 | static int pc87413_ioctl(struct inode *inode, struct file *file, | 401 | static long pc87413_ioctl(struct file *file, unsigned int cmd, |
418 | unsigned int cmd, unsigned long arg) | 402 | unsigned long arg) |
419 | { | 403 | { |
420 | int new_timeout; | 404 | int new_timeout; |
421 | 405 | ||
@@ -426,75 +410,58 @@ static int pc87413_ioctl(struct inode *inode, struct file *file, | |||
426 | 410 | ||
427 | static struct watchdog_info ident = { | 411 | static struct watchdog_info ident = { |
428 | .options = WDIOF_KEEPALIVEPING | | 412 | .options = WDIOF_KEEPALIVEPING | |
429 | WDIOF_SETTIMEOUT | | 413 | WDIOF_SETTIMEOUT | |
430 | WDIOF_MAGICCLOSE, | 414 | WDIOF_MAGICCLOSE, |
431 | .firmware_version = 1, | 415 | .firmware_version = 1, |
432 | .identity = "PC87413(HF/F) watchdog" | 416 | .identity = "PC87413(HF/F) watchdog" |
433 | }; | 417 | }; |
434 | 418 | ||
435 | uarg.i = (int __user *)arg; | 419 | uarg.i = (int __user *)arg; |
436 | 420 | ||
437 | switch(cmd) { | 421 | switch (cmd) { |
438 | default: | 422 | case WDIOC_GETSUPPORT: |
439 | return -ENOTTY; | 423 | return copy_to_user(uarg.ident, &ident, |
440 | 424 | sizeof(ident)) ? -EFAULT : 0; | |
441 | case WDIOC_GETSUPPORT: | 425 | case WDIOC_GETSTATUS: |
442 | return copy_to_user(uarg.ident, &ident, | 426 | return put_user(pc87413_status(), uarg.i); |
443 | sizeof(ident)) ? -EFAULT : 0; | 427 | case WDIOC_GETBOOTSTATUS: |
444 | 428 | return put_user(0, uarg.i); | |
445 | case WDIOC_GETSTATUS: | 429 | case WDIOC_KEEPALIVE: |
446 | return put_user(pc87413_status(), uarg.i); | 430 | pc87413_refresh(); |
447 | |||
448 | case WDIOC_GETBOOTSTATUS: | ||
449 | return put_user(0, uarg.i); | ||
450 | |||
451 | case WDIOC_KEEPALIVE: | ||
452 | pc87413_refresh(); | ||
453 | #ifdef DEBUG | 431 | #ifdef DEBUG |
454 | printk(KERN_INFO DPFX "keepalive\n"); | 432 | printk(KERN_INFO DPFX "keepalive\n"); |
455 | #endif | 433 | #endif |
456 | return 0; | 434 | return 0; |
457 | 435 | case WDIOC_SETTIMEOUT: | |
458 | case WDIOC_SETTIMEOUT: | 436 | if (get_user(new_timeout, uarg.i)) |
459 | if (get_user(new_timeout, uarg.i)) | 437 | return -EFAULT; |
460 | return -EFAULT; | 438 | /* the API states this is given in secs */ |
461 | 439 | new_timeout /= 60; | |
462 | // the API states this is given in secs | 440 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) |
463 | new_timeout /= 60; | 441 | return -EINVAL; |
464 | 442 | timeout = new_timeout; | |
465 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | 443 | pc87413_refresh(); |
466 | return -EINVAL; | 444 | /* fall through and return the new timeout... */ |
467 | 445 | case WDIOC_GETTIMEOUT: | |
468 | timeout = new_timeout; | 446 | new_timeout = timeout * 60; |
469 | pc87413_refresh(); | 447 | return put_user(new_timeout, uarg.i); |
470 | 448 | case WDIOC_SETOPTIONS: | |
471 | // fall through and return the new timeout... | 449 | { |
472 | 450 | int options, retval = -EINVAL; | |
473 | case WDIOC_GETTIMEOUT: | 451 | if (get_user(options, uarg.i)) |
474 | 452 | return -EFAULT; | |
475 | new_timeout = timeout * 60; | 453 | if (options & WDIOS_DISABLECARD) { |
476 | 454 | pc87413_disable(); | |
477 | return put_user(new_timeout, uarg.i); | 455 | retval = 0; |
478 | |||
479 | case WDIOC_SETOPTIONS: | ||
480 | { | ||
481 | int options, retval = -EINVAL; | ||
482 | |||
483 | if (get_user(options, uarg.i)) | ||
484 | return -EFAULT; | ||
485 | |||
486 | if (options & WDIOS_DISABLECARD) { | ||
487 | pc87413_disable(); | ||
488 | retval = 0; | ||
489 | } | ||
490 | |||
491 | if (options & WDIOS_ENABLECARD) { | ||
492 | pc87413_enable(); | ||
493 | retval = 0; | ||
494 | } | ||
495 | |||
496 | return retval; | ||
497 | } | 456 | } |
457 | if (options & WDIOS_ENABLECARD) { | ||
458 | pc87413_enable(); | ||
459 | retval = 0; | ||
460 | } | ||
461 | return retval; | ||
462 | } | ||
463 | default: | ||
464 | return -ENOTTY; | ||
498 | } | 465 | } |
499 | } | 466 | } |
500 | 467 | ||
@@ -517,10 +484,8 @@ static int pc87413_notify_sys(struct notifier_block *this, | |||
517 | void *unused) | 484 | void *unused) |
518 | { | 485 | { |
519 | if (code == SYS_DOWN || code == SYS_HALT) | 486 | if (code == SYS_DOWN || code == SYS_HALT) |
520 | { | ||
521 | /* Turn the card off */ | 487 | /* Turn the card off */ |
522 | pc87413_disable(); | 488 | pc87413_disable(); |
523 | } | ||
524 | return NOTIFY_DONE; | 489 | return NOTIFY_DONE; |
525 | } | 490 | } |
526 | 491 | ||
@@ -530,18 +495,16 @@ static const struct file_operations pc87413_fops = { | |||
530 | .owner = THIS_MODULE, | 495 | .owner = THIS_MODULE, |
531 | .llseek = no_llseek, | 496 | .llseek = no_llseek, |
532 | .write = pc87413_write, | 497 | .write = pc87413_write, |
533 | .ioctl = pc87413_ioctl, | 498 | .unlocked_ioctl = pc87413_ioctl, |
534 | .open = pc87413_open, | 499 | .open = pc87413_open, |
535 | .release = pc87413_release, | 500 | .release = pc87413_release, |
536 | }; | 501 | }; |
537 | 502 | ||
538 | static struct notifier_block pc87413_notifier = | 503 | static struct notifier_block pc87413_notifier = { |
539 | { | ||
540 | .notifier_call = pc87413_notify_sys, | 504 | .notifier_call = pc87413_notify_sys, |
541 | }; | 505 | }; |
542 | 506 | ||
543 | static struct miscdevice pc87413_miscdev= | 507 | static struct miscdevice pc87413_miscdev = { |
544 | { | ||
545 | .minor = WATCHDOG_MINOR, | 508 | .minor = WATCHDOG_MINOR, |
546 | .name = "watchdog", | 509 | .name = "watchdog", |
547 | .fops = &pc87413_fops | 510 | .fops = &pc87413_fops |
@@ -561,29 +524,26 @@ static int __init pc87413_init(void) | |||
561 | { | 524 | { |
562 | int ret; | 525 | int ret; |
563 | 526 | ||
564 | printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", WDT_INDEX_IO_PORT); | 527 | printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", |
528 | WDT_INDEX_IO_PORT); | ||
565 | 529 | ||
566 | /* request_region(io, 2, "pc87413"); */ | 530 | /* request_region(io, 2, "pc87413"); */ |
567 | 531 | ||
568 | ret = register_reboot_notifier(&pc87413_notifier); | 532 | ret = register_reboot_notifier(&pc87413_notifier); |
569 | if (ret != 0) { | 533 | if (ret != 0) { |
570 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 534 | printk(KERN_ERR PFX |
571 | ret); | 535 | "cannot register reboot notifier (err=%d)\n", ret); |
572 | } | 536 | } |
573 | 537 | ||
574 | ret = misc_register(&pc87413_miscdev); | 538 | ret = misc_register(&pc87413_miscdev); |
575 | |||
576 | if (ret != 0) { | 539 | if (ret != 0) { |
577 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 540 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
578 | WATCHDOG_MINOR, ret); | 541 | WATCHDOG_MINOR, ret); |
579 | unregister_reboot_notifier(&pc87413_notifier); | 542 | unregister_reboot_notifier(&pc87413_notifier); |
580 | return ret; | 543 | return ret; |
581 | } | 544 | } |
582 | |||
583 | printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); | 545 | printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); |
584 | |||
585 | pc87413_enable(); | 546 | pc87413_enable(); |
586 | |||
587 | return 0; | 547 | return 0; |
588 | } | 548 | } |
589 | 549 | ||
@@ -600,8 +560,7 @@ static int __init pc87413_init(void) | |||
600 | static void __exit pc87413_exit(void) | 560 | static void __exit pc87413_exit(void) |
601 | { | 561 | { |
602 | /* Stop the timer before we leave */ | 562 | /* Stop the timer before we leave */ |
603 | if (!nowayout) | 563 | if (!nowayout) { |
604 | { | ||
605 | pc87413_disable(); | 564 | pc87413_disable(); |
606 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); | 565 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); |
607 | } | 566 | } |
@@ -626,8 +585,12 @@ module_param(io, int, 0); | |||
626 | MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); | 585 | MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); |
627 | 586 | ||
628 | module_param(timeout, int, 0); | 587 | module_param(timeout, int, 0); |
629 | MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); | 588 | MODULE_PARM_DESC(timeout, |
589 | "Watchdog timeout in minutes (default=" | ||
590 | __MODULE_STRING(timeout) ")."); | ||
630 | 591 | ||
631 | module_param(nowayout, int, 0); | 592 | module_param(nowayout, int, 0); |
632 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 593 | MODULE_PARM_DESC(nowayout, |
594 | "Watchdog cannot be stopped once started (default=" | ||
595 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
633 | 596 | ||
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index 7b41434fac8c..e1259adf09f9 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c | |||
@@ -40,13 +40,15 @@ | |||
40 | * fairly useless proc entry. | 40 | * fairly useless proc entry. |
41 | * 990610 removed said useless proc code for the merge <alan> | 41 | * 990610 removed said useless proc code for the merge <alan> |
42 | * 000403 Removed last traces of proc code. <davej> | 42 | * 000403 Removed last traces of proc code. <davej> |
43 | * 011214 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> | 43 | * 011214 Added nowayout module option to override |
44 | * CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> | ||
44 | * Added timeout module option to override default | 45 | * Added timeout module option to override default |
45 | */ | 46 | */ |
46 | 47 | ||
47 | /* | 48 | /* |
48 | * A bells and whistles driver is available from http://www.pcwd.de/ | 49 | * A bells and whistles driver is available from http://www.pcwd.de/ |
49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ | 50 | * More info available at http://www.berkprod.com/ or |
51 | * http://www.pcwatchdog.com/ | ||
50 | */ | 52 | */ |
51 | 53 | ||
52 | #include <linux/module.h> /* For module specific items */ | 54 | #include <linux/module.h> /* For module specific items */ |
@@ -65,9 +67,8 @@ | |||
65 | #include <linux/isa.h> /* For isa devices */ | 67 | #include <linux/isa.h> /* For isa devices */ |
66 | #include <linux/ioport.h> /* For io-port access */ | 68 | #include <linux/ioport.h> /* For io-port access */ |
67 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 69 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
68 | 70 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
69 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 71 | #include <linux/io.h> /* For inb/outb/... */ |
70 | #include <asm/io.h> /* For inb/outb/... */ | ||
71 | 72 | ||
72 | /* Module and version information */ | 73 | /* Module and version information */ |
73 | #define WATCHDOG_VERSION "1.20" | 74 | #define WATCHDOG_VERSION "1.20" |
@@ -111,14 +112,16 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 }; | |||
111 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ | 112 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ |
112 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ | 113 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ |
113 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ | 114 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ |
114 | #define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */ | 115 | #define WD_REVC_RL2A 0x08 /* Relay 2 activated by |
116 | on-board processor */ | ||
115 | #define WD_REVC_RL1A 0x10 /* Relay 1 active */ | 117 | #define WD_REVC_RL1A 0x10 /* Relay 1 active */ |
116 | #define WD_REVC_R2DS 0x40 /* Relay 2 disable */ | 118 | #define WD_REVC_R2DS 0x40 /* Relay 2 disable */ |
117 | #define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ | 119 | #define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ |
118 | /* Port 2 : Control Status #2 */ | 120 | /* Port 2 : Control Status #2 */ |
119 | #define WD_WDIS 0x10 /* Watchdog Disabled */ | 121 | #define WD_WDIS 0x10 /* Watchdog Disabled */ |
120 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ | 122 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ |
121 | #define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ | 123 | #define WD_SSEL 0x40 /* Watchdog Switch Select |
124 | (1:SW1 <-> 0:SW2) */ | ||
122 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ | 125 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ |
123 | 126 | ||
124 | /* max. time we give an ISA watchdog card to process a command */ | 127 | /* max. time we give an ISA watchdog card to process a command */ |
@@ -168,11 +171,15 @@ static int cards_found; | |||
168 | static atomic_t open_allowed = ATOMIC_INIT(1); | 171 | static atomic_t open_allowed = ATOMIC_INIT(1); |
169 | static char expect_close; | 172 | static char expect_close; |
170 | static int temp_panic; | 173 | static int temp_panic; |
171 | static struct { /* this is private data for each ISA-PC watchdog card */ | 174 | |
175 | /* this is private data for each ISA-PC watchdog card */ | ||
176 | static struct { | ||
172 | char fw_ver_str[6]; /* The cards firmware version */ | 177 | char fw_ver_str[6]; /* The cards firmware version */ |
173 | int revision; /* The card's revision */ | 178 | int revision; /* The card's revision */ |
174 | int supports_temp; /* Wether or not the card has a temperature device */ | 179 | int supports_temp; /* Whether or not the card has |
175 | int command_mode; /* Wether or not the card is in command mode */ | 180 | a temperature device */ |
181 | int command_mode; /* Whether or not the card is in | ||
182 | command mode */ | ||
176 | int boot_status; /* The card's boot status */ | 183 | int boot_status; /* The card's boot status */ |
177 | int io_addr; /* The cards I/O address */ | 184 | int io_addr; /* The cards I/O address */ |
178 | spinlock_t io_lock; /* the lock for io operations */ | 185 | spinlock_t io_lock; /* the lock for io operations */ |
@@ -186,16 +193,20 @@ static struct { /* this is private data for each ISA-PC watchdog card */ | |||
186 | #define DEBUG 2 /* print fancy stuff too */ | 193 | #define DEBUG 2 /* print fancy stuff too */ |
187 | static int debug = QUIET; | 194 | static int debug = QUIET; |
188 | module_param(debug, int, 0); | 195 | module_param(debug, int, 0); |
189 | MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | 196 | MODULE_PARM_DESC(debug, |
197 | "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | ||
190 | 198 | ||
191 | #define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ | 199 | /* default heartbeat = delay-time from dip-switches */ |
200 | #define WATCHDOG_HEARTBEAT 0 | ||
192 | static int heartbeat = WATCHDOG_HEARTBEAT; | 201 | static int heartbeat = WATCHDOG_HEARTBEAT; |
193 | module_param(heartbeat, int, 0); | 202 | module_param(heartbeat, int, 0); |
194 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 203 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); |
195 | 204 | ||
196 | static int nowayout = WATCHDOG_NOWAYOUT; | 205 | static int nowayout = WATCHDOG_NOWAYOUT; |
197 | module_param(nowayout, int, 0); | 206 | module_param(nowayout, int, 0); |
198 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 207 | MODULE_PARM_DESC(nowayout, |
208 | "Watchdog cannot be stopped once started (default=" | ||
209 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
199 | 210 | ||
200 | /* | 211 | /* |
201 | * Internal functions | 212 | * Internal functions |
@@ -224,7 +235,7 @@ static int send_isa_command(int cmd) | |||
224 | if (port0 == last_port0) | 235 | if (port0 == last_port0) |
225 | break; /* Data is stable */ | 236 | break; /* Data is stable */ |
226 | 237 | ||
227 | udelay (250); | 238 | udelay(250); |
228 | } | 239 | } |
229 | 240 | ||
230 | if (debug >= DEBUG) | 241 | if (debug >= DEBUG) |
@@ -236,7 +247,7 @@ static int send_isa_command(int cmd) | |||
236 | 247 | ||
237 | static int set_command_mode(void) | 248 | static int set_command_mode(void) |
238 | { | 249 | { |
239 | int i, found=0, count=0; | 250 | int i, found = 0, count = 0; |
240 | 251 | ||
241 | /* Set the card into command mode */ | 252 | /* Set the card into command mode */ |
242 | spin_lock(&pcwd_private.io_lock); | 253 | spin_lock(&pcwd_private.io_lock); |
@@ -296,7 +307,8 @@ static inline void pcwd_get_firmware(void) | |||
296 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | 307 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); |
297 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | 308 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); |
298 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | 309 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); |
299 | sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor); | 310 | sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", |
311 | one, ten, hund, minor); | ||
300 | } | 312 | } |
301 | unset_command_mode(); | 313 | unset_command_mode(); |
302 | 314 | ||
@@ -305,7 +317,7 @@ static inline void pcwd_get_firmware(void) | |||
305 | 317 | ||
306 | static inline int pcwd_get_option_switches(void) | 318 | static inline int pcwd_get_option_switches(void) |
307 | { | 319 | { |
308 | int option_switches=0; | 320 | int option_switches = 0; |
309 | 321 | ||
310 | if (set_command_mode()) { | 322 | if (set_command_mode()) { |
311 | /* Get switch settings */ | 323 | /* Get switch settings */ |
@@ -322,7 +334,9 @@ static void pcwd_show_card_info(void) | |||
322 | 334 | ||
323 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | 335 | /* Get some extra info from the hardware (in command/debug/diag mode) */ |
324 | if (pcwd_private.revision == PCWD_REVISION_A) | 336 | if (pcwd_private.revision == PCWD_REVISION_A) |
325 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); | 337 | printk(KERN_INFO PFX |
338 | "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", | ||
339 | pcwd_private.io_addr); | ||
326 | else if (pcwd_private.revision == PCWD_REVISION_C) { | 340 | else if (pcwd_private.revision == PCWD_REVISION_C) { |
327 | pcwd_get_firmware(); | 341 | pcwd_get_firmware(); |
328 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | 342 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", |
@@ -347,12 +361,15 @@ static void pcwd_show_card_info(void) | |||
347 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | 361 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); |
348 | 362 | ||
349 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { | 363 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { |
350 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | 364 | printk(KERN_EMERG PFX |
351 | printk(KERN_EMERG PFX "CPU Overheat\n"); | 365 | "Card senses a CPU Overheat. Panicking!\n"); |
366 | printk(KERN_EMERG PFX | ||
367 | "CPU Overheat\n"); | ||
352 | } | 368 | } |
353 | 369 | ||
354 | if (pcwd_private.boot_status == 0) | 370 | if (pcwd_private.boot_status == 0) |
355 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | 371 | printk(KERN_INFO PFX |
372 | "No previous trip detected - Cold boot or reset\n"); | ||
356 | } | 373 | } |
357 | 374 | ||
358 | static void pcwd_timer_ping(unsigned long data) | 375 | static void pcwd_timer_ping(unsigned long data) |
@@ -361,11 +378,12 @@ static void pcwd_timer_ping(unsigned long data) | |||
361 | 378 | ||
362 | /* If we got a heartbeat pulse within the WDT_INTERVAL | 379 | /* If we got a heartbeat pulse within the WDT_INTERVAL |
363 | * we agree to ping the WDT */ | 380 | * we agree to ping the WDT */ |
364 | if(time_before(jiffies, pcwd_private.next_heartbeat)) { | 381 | if (time_before(jiffies, pcwd_private.next_heartbeat)) { |
365 | /* Ping the watchdog */ | 382 | /* Ping the watchdog */ |
366 | spin_lock(&pcwd_private.io_lock); | 383 | spin_lock(&pcwd_private.io_lock); |
367 | if (pcwd_private.revision == PCWD_REVISION_A) { | 384 | if (pcwd_private.revision == PCWD_REVISION_A) { |
368 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ | 385 | /* Rev A cards are reset by setting the |
386 | WD_WDRST bit in register 1 */ | ||
369 | wdrst_stat = inb_p(pcwd_private.io_addr); | 387 | wdrst_stat = inb_p(pcwd_private.io_addr); |
370 | wdrst_stat &= 0x0F; | 388 | wdrst_stat &= 0x0F; |
371 | wdrst_stat |= WD_WDRST; | 389 | wdrst_stat |= WD_WDRST; |
@@ -381,7 +399,8 @@ static void pcwd_timer_ping(unsigned long data) | |||
381 | 399 | ||
382 | spin_unlock(&pcwd_private.io_lock); | 400 | spin_unlock(&pcwd_private.io_lock); |
383 | } else { | 401 | } else { |
384 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 402 | printk(KERN_WARNING PFX |
403 | "Heartbeat lost! Will not ping the watchdog\n"); | ||
385 | } | 404 | } |
386 | } | 405 | } |
387 | 406 | ||
@@ -454,7 +473,7 @@ static int pcwd_keepalive(void) | |||
454 | 473 | ||
455 | static int pcwd_set_heartbeat(int t) | 474 | static int pcwd_set_heartbeat(int t) |
456 | { | 475 | { |
457 | if ((t < 2) || (t > 7200)) /* arbitrary upper limit */ | 476 | if (t < 2 || t > 7200) /* arbitrary upper limit */ |
458 | return -EINVAL; | 477 | return -EINVAL; |
459 | 478 | ||
460 | heartbeat = t; | 479 | heartbeat = t; |
@@ -470,7 +489,7 @@ static int pcwd_get_status(int *status) | |||
470 | { | 489 | { |
471 | int control_status; | 490 | int control_status; |
472 | 491 | ||
473 | *status=0; | 492 | *status = 0; |
474 | spin_lock(&pcwd_private.io_lock); | 493 | spin_lock(&pcwd_private.io_lock); |
475 | if (pcwd_private.revision == PCWD_REVISION_A) | 494 | if (pcwd_private.revision == PCWD_REVISION_A) |
476 | /* Rev A cards return status information from | 495 | /* Rev A cards return status information from |
@@ -494,9 +513,9 @@ static int pcwd_get_status(int *status) | |||
494 | if (control_status & WD_T110) { | 513 | if (control_status & WD_T110) { |
495 | *status |= WDIOF_OVERHEAT; | 514 | *status |= WDIOF_OVERHEAT; |
496 | if (temp_panic) { | 515 | if (temp_panic) { |
497 | printk(KERN_INFO PFX "Temperature overheat trip!\n"); | 516 | printk(KERN_INFO PFX |
517 | "Temperature overheat trip!\n"); | ||
498 | kernel_power_off(); | 518 | kernel_power_off(); |
499 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
500 | } | 519 | } |
501 | } | 520 | } |
502 | } else { | 521 | } else { |
@@ -506,9 +525,9 @@ static int pcwd_get_status(int *status) | |||
506 | if (control_status & WD_REVC_TTRP) { | 525 | if (control_status & WD_REVC_TTRP) { |
507 | *status |= WDIOF_OVERHEAT; | 526 | *status |= WDIOF_OVERHEAT; |
508 | if (temp_panic) { | 527 | if (temp_panic) { |
509 | printk(KERN_INFO PFX "Temperature overheat trip!\n"); | 528 | printk(KERN_INFO PFX |
529 | "Temperature overheat trip!\n"); | ||
510 | kernel_power_off(); | 530 | kernel_power_off(); |
511 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
512 | } | 531 | } |
513 | } | 532 | } |
514 | } | 533 | } |
@@ -524,18 +543,21 @@ static int pcwd_clear_status(void) | |||
524 | spin_lock(&pcwd_private.io_lock); | 543 | spin_lock(&pcwd_private.io_lock); |
525 | 544 | ||
526 | if (debug >= VERBOSE) | 545 | if (debug >= VERBOSE) |
527 | printk(KERN_INFO PFX "clearing watchdog trip status\n"); | 546 | printk(KERN_INFO PFX |
547 | "clearing watchdog trip status\n"); | ||
528 | 548 | ||
529 | control_status = inb_p(pcwd_private.io_addr + 1); | 549 | control_status = inb_p(pcwd_private.io_addr + 1); |
530 | 550 | ||
531 | if (debug >= DEBUG) { | 551 | if (debug >= DEBUG) { |
532 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); | 552 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", |
553 | control_status); | ||
533 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", | 554 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", |
534 | (control_status & WD_REVC_R2DS)); | 555 | (control_status & WD_REVC_R2DS)); |
535 | } | 556 | } |
536 | 557 | ||
537 | /* clear reset status & Keep Relay 2 disable state as it is */ | 558 | /* clear reset status & Keep Relay 2 disable state as it is */ |
538 | outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1); | 559 | outb_p((control_status & WD_REVC_R2DS), |
560 | pcwd_private.io_addr + 1); | ||
539 | 561 | ||
540 | spin_unlock(&pcwd_private.io_lock); | 562 | spin_unlock(&pcwd_private.io_lock); |
541 | } | 563 | } |
@@ -572,8 +594,7 @@ static int pcwd_get_temperature(int *temperature) | |||
572 | * /dev/watchdog handling | 594 | * /dev/watchdog handling |
573 | */ | 595 | */ |
574 | 596 | ||
575 | static int pcwd_ioctl(struct inode *inode, struct file *file, | 597 | static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
576 | unsigned int cmd, unsigned long arg) | ||
577 | { | 598 | { |
578 | int rv; | 599 | int rv; |
579 | int status; | 600 | int status; |
@@ -590,12 +611,12 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
590 | .identity = "PCWD", | 611 | .identity = "PCWD", |
591 | }; | 612 | }; |
592 | 613 | ||
593 | switch(cmd) { | 614 | switch (cmd) { |
594 | default: | 615 | default: |
595 | return -ENOTTY; | 616 | return -ENOTTY; |
596 | 617 | ||
597 | case WDIOC_GETSUPPORT: | 618 | case WDIOC_GETSUPPORT: |
598 | if(copy_to_user(argp, &ident, sizeof(ident))) | 619 | if (copy_to_user(argp, &ident, sizeof(ident))) |
599 | return -EFAULT; | 620 | return -EFAULT; |
600 | return 0; | 621 | return 0; |
601 | 622 | ||
@@ -613,25 +634,22 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
613 | return put_user(temperature, argp); | 634 | return put_user(temperature, argp); |
614 | 635 | ||
615 | case WDIOC_SETOPTIONS: | 636 | case WDIOC_SETOPTIONS: |
616 | if (pcwd_private.revision == PCWD_REVISION_C) | 637 | if (pcwd_private.revision == PCWD_REVISION_C) { |
617 | { | 638 | if (get_user(rv, argp)) |
618 | if(copy_from_user(&rv, argp, sizeof(int))) | ||
619 | return -EFAULT; | 639 | return -EFAULT; |
620 | 640 | ||
621 | if (rv & WDIOS_DISABLECARD) | 641 | if (rv & WDIOS_DISABLECARD) { |
622 | { | 642 | status = pcwd_stop(); |
623 | return pcwd_stop(); | 643 | if (status < 0) |
644 | return status; | ||
624 | } | 645 | } |
625 | 646 | if (rv & WDIOS_ENABLECARD) { | |
626 | if (rv & WDIOS_ENABLECARD) | 647 | status = pcwd_start(); |
627 | { | 648 | if (status < 0) |
628 | return pcwd_start(); | 649 | return status; |
629 | } | 650 | } |
630 | |||
631 | if (rv & WDIOS_TEMPPANIC) | 651 | if (rv & WDIOS_TEMPPANIC) |
632 | { | ||
633 | temp_panic = 1; | 652 | temp_panic = 1; |
634 | } | ||
635 | } | 653 | } |
636 | return -EINVAL; | 654 | return -EINVAL; |
637 | 655 | ||
@@ -682,16 +700,10 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len, | |||
682 | 700 | ||
683 | static int pcwd_open(struct inode *inode, struct file *file) | 701 | static int pcwd_open(struct inode *inode, struct file *file) |
684 | { | 702 | { |
685 | if (!atomic_dec_and_test(&open_allowed) ) { | 703 | if (test_and_set_bit(0, &open_allowed)) |
686 | if (debug >= VERBOSE) | ||
687 | printk(KERN_ERR PFX "Attempt to open already opened device.\n"); | ||
688 | atomic_inc( &open_allowed ); | ||
689 | return -EBUSY; | 704 | return -EBUSY; |
690 | } | ||
691 | |||
692 | if (nowayout) | 705 | if (nowayout) |
693 | __module_get(THIS_MODULE); | 706 | __module_get(THIS_MODULE); |
694 | |||
695 | /* Activate */ | 707 | /* Activate */ |
696 | pcwd_start(); | 708 | pcwd_start(); |
697 | pcwd_keepalive(); | 709 | pcwd_keepalive(); |
@@ -700,14 +712,15 @@ static int pcwd_open(struct inode *inode, struct file *file) | |||
700 | 712 | ||
701 | static int pcwd_close(struct inode *inode, struct file *file) | 713 | static int pcwd_close(struct inode *inode, struct file *file) |
702 | { | 714 | { |
703 | if (expect_close == 42) { | 715 | if (expect_close == 42) |
704 | pcwd_stop(); | 716 | pcwd_stop(); |
705 | } else { | 717 | else { |
706 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 718 | printk(KERN_CRIT PFX |
719 | "Unexpected close, not stopping watchdog!\n"); | ||
707 | pcwd_keepalive(); | 720 | pcwd_keepalive(); |
708 | } | 721 | } |
709 | expect_close = 0; | 722 | expect_close = 0; |
710 | atomic_inc( &open_allowed ); | 723 | clear_bit(0, &open_allowed); |
711 | return 0; | 724 | return 0; |
712 | } | 725 | } |
713 | 726 | ||
@@ -750,7 +763,7 @@ static const struct file_operations pcwd_fops = { | |||
750 | .owner = THIS_MODULE, | 763 | .owner = THIS_MODULE, |
751 | .llseek = no_llseek, | 764 | .llseek = no_llseek, |
752 | .write = pcwd_write, | 765 | .write = pcwd_write, |
753 | .ioctl = pcwd_ioctl, | 766 | .unlocked_ioctl = pcwd_ioctl, |
754 | .open = pcwd_open, | 767 | .open = pcwd_open, |
755 | .release = pcwd_close, | 768 | .release = pcwd_close, |
756 | }; | 769 | }; |
@@ -788,7 +801,7 @@ static inline int get_revision(void) | |||
788 | * presumes a floating bus reads as 0xff. */ | 801 | * presumes a floating bus reads as 0xff. */ |
789 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || | 802 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || |
790 | (inb(pcwd_private.io_addr + 3) == 0xFF)) | 803 | (inb(pcwd_private.io_addr + 3) == 0xFF)) |
791 | r=PCWD_REVISION_A; | 804 | r = PCWD_REVISION_A; |
792 | spin_unlock(&pcwd_private.io_lock); | 805 | spin_unlock(&pcwd_private.io_lock); |
793 | 806 | ||
794 | return r; | 807 | return r; |
@@ -803,7 +816,7 @@ static inline int get_revision(void) | |||
803 | */ | 816 | */ |
804 | static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | 817 | static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) |
805 | { | 818 | { |
806 | int base_addr=pcwd_ioports[id]; | 819 | int base_addr = pcwd_ioports[id]; |
807 | int port0, last_port0; /* Reg 0, in case it's REV A */ | 820 | int port0, last_port0; /* Reg 0, in case it's REV A */ |
808 | int port1, last_port1; /* Register 1 for REV C cards */ | 821 | int port1, last_port1; /* Register 1 for REV C cards */ |
809 | int i; | 822 | int i; |
@@ -813,7 +826,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | |||
813 | printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", | 826 | printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", |
814 | id); | 827 | id); |
815 | 828 | ||
816 | if (!request_region (base_addr, 4, "PCWD")) { | 829 | if (!request_region(base_addr, 4, "PCWD")) { |
817 | printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); | 830 | printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); |
818 | return 0; | 831 | return 0; |
819 | } | 832 | } |
@@ -842,7 +855,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | |||
842 | } | 855 | } |
843 | } | 856 | } |
844 | } | 857 | } |
845 | release_region (base_addr, 4); | 858 | release_region(base_addr, 4); |
846 | 859 | ||
847 | return retval; | 860 | return retval; |
848 | } | 861 | } |
@@ -857,7 +870,8 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
857 | 870 | ||
858 | cards_found++; | 871 | cards_found++; |
859 | if (cards_found == 1) | 872 | if (cards_found == 1) |
860 | printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); | 873 | printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", |
874 | WD_VER); | ||
861 | 875 | ||
862 | if (cards_found > 1) { | 876 | if (cards_found > 1) { |
863 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); | 877 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); |
@@ -875,10 +889,11 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
875 | /* Check card's revision */ | 889 | /* Check card's revision */ |
876 | pcwd_private.revision = get_revision(); | 890 | pcwd_private.revision = get_revision(); |
877 | 891 | ||
878 | if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | 892 | if (!request_region(pcwd_private.io_addr, |
893 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | ||
879 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 894 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
880 | pcwd_private.io_addr); | 895 | pcwd_private.io_addr); |
881 | ret=-EIO; | 896 | ret = -EIO; |
882 | goto error_request_region; | 897 | goto error_request_region; |
883 | } | 898 | } |
884 | 899 | ||
@@ -908,26 +923,30 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
908 | if (heartbeat == 0) | 923 | if (heartbeat == 0) |
909 | heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; | 924 | heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; |
910 | 925 | ||
911 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 926 | /* Check that the heartbeat value is within it's range; |
927 | if not reset to the default */ | ||
912 | if (pcwd_set_heartbeat(heartbeat)) { | 928 | if (pcwd_set_heartbeat(heartbeat)) { |
913 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); | 929 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); |
914 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", | 930 | printk(KERN_INFO PFX |
915 | WATCHDOG_HEARTBEAT); | 931 | "heartbeat value must be 2 <= heartbeat <= 7200, using %d\n", |
932 | WATCHDOG_HEARTBEAT); | ||
916 | } | 933 | } |
917 | 934 | ||
918 | if (pcwd_private.supports_temp) { | 935 | if (pcwd_private.supports_temp) { |
919 | ret = misc_register(&temp_miscdev); | 936 | ret = misc_register(&temp_miscdev); |
920 | if (ret) { | 937 | if (ret) { |
921 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 938 | printk(KERN_ERR PFX |
922 | TEMP_MINOR, ret); | 939 | "cannot register miscdev on minor=%d (err=%d)\n", |
940 | TEMP_MINOR, ret); | ||
923 | goto error_misc_register_temp; | 941 | goto error_misc_register_temp; |
924 | } | 942 | } |
925 | } | 943 | } |
926 | 944 | ||
927 | ret = misc_register(&pcwd_miscdev); | 945 | ret = misc_register(&pcwd_miscdev); |
928 | if (ret) { | 946 | if (ret) { |
929 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 947 | printk(KERN_ERR PFX |
930 | WATCHDOG_MINOR, ret); | 948 | "cannot register miscdev on minor=%d (err=%d)\n", |
949 | WATCHDOG_MINOR, ret); | ||
931 | goto error_misc_register_watchdog; | 950 | goto error_misc_register_watchdog; |
932 | } | 951 | } |
933 | 952 | ||
@@ -940,7 +959,8 @@ error_misc_register_watchdog: | |||
940 | if (pcwd_private.supports_temp) | 959 | if (pcwd_private.supports_temp) |
941 | misc_deregister(&temp_miscdev); | 960 | misc_deregister(&temp_miscdev); |
942 | error_misc_register_temp: | 961 | error_misc_register_temp: |
943 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | 962 | release_region(pcwd_private.io_addr, |
963 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | ||
944 | error_request_region: | 964 | error_request_region: |
945 | pcwd_private.io_addr = 0x0000; | 965 | pcwd_private.io_addr = 0x0000; |
946 | cards_found--; | 966 | cards_found--; |
@@ -964,7 +984,8 @@ static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id) | |||
964 | misc_deregister(&pcwd_miscdev); | 984 | misc_deregister(&pcwd_miscdev); |
965 | if (pcwd_private.supports_temp) | 985 | if (pcwd_private.supports_temp) |
966 | misc_deregister(&temp_miscdev); | 986 | misc_deregister(&temp_miscdev); |
967 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | 987 | release_region(pcwd_private.io_addr, |
988 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | ||
968 | pcwd_private.io_addr = 0x0000; | 989 | pcwd_private.io_addr = 0x0000; |
969 | cards_found--; | 990 | cards_found--; |
970 | 991 | ||
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 6b8483d3c783..8cd0d53941e7 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | 31 | ||
32 | #include <asm/hardware.h> | 32 | #include <asm/hardware.h> |
33 | #include <asm/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <asm/io.h> | 34 | #include <linux/io.h> |
35 | 35 | ||
36 | #define MODULE_NAME "PNX4008-WDT: " | 36 | #define MODULE_NAME "PNX4008-WDT: " |
37 | 37 | ||
@@ -144,9 +144,8 @@ static int pnx4008_wdt_open(struct inode *inode, struct file *file) | |||
144 | return nonseekable_open(inode, file); | 144 | return nonseekable_open(inode, file); |
145 | } | 145 | } |
146 | 146 | ||
147 | static ssize_t | 147 | static ssize_t pnx4008_wdt_write(struct file *file, const char *data, |
148 | pnx4008_wdt_write(struct file *file, const char *data, size_t len, | 148 | size_t len, loff_t *ppos) |
149 | loff_t * ppos) | ||
150 | { | 149 | { |
151 | if (len) { | 150 | if (len) { |
152 | if (!nowayout) { | 151 | if (!nowayout) { |
@@ -169,15 +168,14 @@ pnx4008_wdt_write(struct file *file, const char *data, size_t len, | |||
169 | return len; | 168 | return len; |
170 | } | 169 | } |
171 | 170 | ||
172 | static struct watchdog_info ident = { | 171 | static const struct watchdog_info ident = { |
173 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | 172 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | |
174 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 173 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
175 | .identity = "PNX4008 Watchdog", | 174 | .identity = "PNX4008 Watchdog", |
176 | }; | 175 | }; |
177 | 176 | ||
178 | static int | 177 | static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file, |
179 | pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 178 | unsigned int cmd, unsigned long arg) |
180 | unsigned long arg) | ||
181 | { | 179 | { |
182 | int ret = -ENOTTY; | 180 | int ret = -ENOTTY; |
183 | int time; | 181 | int time; |
@@ -238,7 +236,7 @@ static const struct file_operations pnx4008_wdt_fops = { | |||
238 | .owner = THIS_MODULE, | 236 | .owner = THIS_MODULE, |
239 | .llseek = no_llseek, | 237 | .llseek = no_llseek, |
240 | .write = pnx4008_wdt_write, | 238 | .write = pnx4008_wdt_write, |
241 | .ioctl = pnx4008_wdt_ioctl, | 239 | .unlocked_ioctl = pnx4008_wdt_ioctl, |
242 | .open = pnx4008_wdt_open, | 240 | .open = pnx4008_wdt_open, |
243 | .release = pnx4008_wdt_release, | 241 | .release = pnx4008_wdt_release, |
244 | }; | 242 | }; |
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c index 5c921e471564..c172906b553c 100644 --- a/drivers/watchdog/rm9k_wdt.c +++ b/drivers/watchdog/rm9k_wdt.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | #include <linux/miscdevice.h> | 30 | #include <linux/miscdevice.h> |
31 | #include <linux/watchdog.h> | 31 | #include <linux/watchdog.h> |
32 | #include <asm/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/uaccess.h> | ||
33 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
34 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
35 | #include <asm/uaccess.h> | ||
36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
37 | #include <asm/rm9k-ocd.h> | 37 | #include <asm/rm9k-ocd.h> |
38 | 38 | ||
@@ -53,10 +53,12 @@ static void wdt_gpi_stop(void); | |||
53 | static void wdt_gpi_set_timeout(unsigned int); | 53 | static void wdt_gpi_set_timeout(unsigned int); |
54 | static int wdt_gpi_open(struct inode *, struct file *); | 54 | static int wdt_gpi_open(struct inode *, struct file *); |
55 | static int wdt_gpi_release(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, loff_t *); | 56 | static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, |
57 | loff_t *); | ||
57 | static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); | 58 | static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); |
58 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); | 59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); |
59 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int); | 60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, |
61 | const char *, unsigned int); | ||
60 | static int __init wdt_gpi_probe(struct device *); | 62 | static int __init wdt_gpi_probe(struct device *); |
61 | static int __exit wdt_gpi_remove(struct device *); | 63 | static int __exit wdt_gpi_remove(struct device *); |
62 | 64 | ||
@@ -68,7 +70,7 @@ static int locked; | |||
68 | 70 | ||
69 | 71 | ||
70 | /* These are set from device resources */ | 72 | /* These are set from device resources */ |
71 | static void __iomem * wd_regs; | 73 | static void __iomem *wd_regs; |
72 | static unsigned int wd_irq, wd_ctr; | 74 | static unsigned int wd_irq, wd_ctr; |
73 | 75 | ||
74 | 76 | ||
@@ -216,7 +218,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file) | |||
216 | if (expect_close) { | 218 | if (expect_close) { |
217 | wdt_gpi_stop(); | 219 | wdt_gpi_stop(); |
218 | free_irq(wd_irq, &miscdev); | 220 | free_irq(wd_irq, &miscdev); |
219 | printk(KERN_INFO "%s: watchdog stopped\n", wdt_gpi_name); | 221 | printk(KERN_INFO "%s: watchdog stopped\n", |
222 | wdt_gpi_name); | ||
220 | } else { | 223 | } else { |
221 | printk(KERN_CRIT "%s: unexpected close() -" | 224 | printk(KERN_CRIT "%s: unexpected close() -" |
222 | " watchdog left running\n", | 225 | " watchdog left running\n", |
@@ -241,8 +244,7 @@ wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) | |||
241 | return s ? 1 : 0; | 244 | return s ? 1 : 0; |
242 | } | 245 | } |
243 | 246 | ||
244 | static long | 247 | static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
245 | wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
246 | { | 248 | { |
247 | long res = -ENOTTY; | 249 | long res = -ENOTTY; |
248 | const long size = _IOC_SIZE(cmd); | 250 | const long size = _IOC_SIZE(cmd); |
@@ -271,7 +273,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
271 | case WDIOC_GETSUPPORT: | 273 | case WDIOC_GETSUPPORT: |
272 | wdinfo.options = nowayout ? | 274 | wdinfo.options = nowayout ? |
273 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : | 275 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : |
274 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE; | 276 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
277 | WDIOF_MAGICCLOSE; | ||
275 | res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; | 278 | res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; |
276 | break; | 279 | break; |
277 | 280 | ||
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 34a2b3b81800..869d538c02f9 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c | |||
@@ -26,13 +26,13 @@ | |||
26 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/uaccess.h> | ||
29 | 30 | ||
30 | #ifdef CONFIG_ARCH_PXA | 31 | #ifdef CONFIG_ARCH_PXA |
31 | #include <asm/arch/pxa-regs.h> | 32 | #include <asm/arch/pxa-regs.h> |
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | #include <asm/hardware.h> | 35 | #include <asm/hardware.h> |
35 | #include <asm/uaccess.h> | ||
36 | 36 | ||
37 | #define OSCR_FREQ CLOCK_TICK_RATE | 37 | #define OSCR_FREQ CLOCK_TICK_RATE |
38 | 38 | ||
@@ -45,7 +45,7 @@ static int boot_status; | |||
45 | */ | 45 | */ |
46 | static int sa1100dog_open(struct inode *inode, struct file *file) | 46 | static int sa1100dog_open(struct inode *inode, struct file *file) |
47 | { | 47 | { |
48 | if (test_and_set_bit(1,&sa1100wdt_users)) | 48 | if (test_and_set_bit(1, &sa1100wdt_users)) |
49 | return -EBUSY; | 49 | return -EBUSY; |
50 | 50 | ||
51 | /* Activate SA1100 Watchdog timer */ | 51 | /* Activate SA1100 Watchdog timer */ |
@@ -66,28 +66,27 @@ static int sa1100dog_open(struct inode *inode, struct file *file) | |||
66 | static int sa1100dog_release(struct inode *inode, struct file *file) | 66 | static int sa1100dog_release(struct inode *inode, struct file *file) |
67 | { | 67 | { |
68 | printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); | 68 | printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); |
69 | |||
70 | clear_bit(1, &sa1100wdt_users); | 69 | clear_bit(1, &sa1100wdt_users); |
71 | |||
72 | return 0; | 70 | return 0; |
73 | } | 71 | } |
74 | 72 | ||
75 | static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 73 | static ssize_t sa1100dog_write(struct file *file, const char __user *data, |
74 | size_t len, loff_t *ppos) | ||
76 | { | 75 | { |
77 | if (len) | 76 | if (len) |
78 | /* Refresh OSMR3 timer. */ | 77 | /* Refresh OSMR3 timer. */ |
79 | OSMR3 = OSCR + pre_margin; | 78 | OSMR3 = OSCR + pre_margin; |
80 | |||
81 | return len; | 79 | return len; |
82 | } | 80 | } |
83 | 81 | ||
84 | static struct watchdog_info ident = { | 82 | static const struct watchdog_info ident = { |
85 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 83 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
84 | | WDIOF_KEEPALIVEPING, | ||
86 | .identity = "SA1100/PXA255 Watchdog", | 85 | .identity = "SA1100/PXA255 Watchdog", |
87 | }; | 86 | }; |
88 | 87 | ||
89 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, | 88 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, |
90 | unsigned int cmd, unsigned long arg) | 89 | unsigned long arg) |
91 | { | 90 | { |
92 | int ret = -ENOTTY; | 91 | int ret = -ENOTTY; |
93 | int time; | 92 | int time; |
@@ -134,18 +133,16 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
134 | return ret; | 133 | return ret; |
135 | } | 134 | } |
136 | 135 | ||
137 | static const struct file_operations sa1100dog_fops = | 136 | static const struct file_operations sa1100dog_fops = { |
138 | { | ||
139 | .owner = THIS_MODULE, | 137 | .owner = THIS_MODULE, |
140 | .llseek = no_llseek, | 138 | .llseek = no_llseek, |
141 | .write = sa1100dog_write, | 139 | .write = sa1100dog_write, |
142 | .ioctl = sa1100dog_ioctl, | 140 | .unlocked_ioctl = sa1100dog_ioctl, |
143 | .open = sa1100dog_open, | 141 | .open = sa1100dog_open, |
144 | .release = sa1100dog_release, | 142 | .release = sa1100dog_release, |
145 | }; | 143 | }; |
146 | 144 | ||
147 | static struct miscdevice sa1100dog_miscdev = | 145 | static struct miscdevice sa1100dog_miscdev = { |
148 | { | ||
149 | .minor = WATCHDOG_MINOR, | 146 | .minor = WATCHDOG_MINOR, |
150 | .name = "watchdog", | 147 | .name = "watchdog", |
151 | .fops = &sa1100dog_fops, | 148 | .fops = &sa1100dog_fops, |
@@ -167,8 +164,9 @@ static int __init sa1100dog_init(void) | |||
167 | 164 | ||
168 | ret = misc_register(&sa1100dog_miscdev); | 165 | ret = misc_register(&sa1100dog_miscdev); |
169 | if (ret == 0) | 166 | if (ret == 0) |
170 | printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", | 167 | printk(KERN_INFO |
171 | margin); | 168 | "SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", |
169 | margin); | ||
172 | return ret; | 170 | return ret; |
173 | } | 171 | } |
174 | 172 | ||
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c index b94431433695..c8b544ce77fb 100644 --- a/drivers/watchdog/sb_wdog.c +++ b/drivers/watchdog/sb_wdog.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <asm/sibyte/sb1250_int.h> | 57 | #include <asm/sibyte/sb1250_int.h> |
58 | #include <asm/sibyte/sb1250_scd.h> | 58 | #include <asm/sibyte/sb1250_scd.h> |
59 | 59 | ||
60 | static DEFINE_SPINLOCK(sbwd_lock); | ||
60 | 61 | ||
61 | /* | 62 | /* |
62 | * set the initial count value of a timer | 63 | * set the initial count value of a timer |
@@ -65,8 +66,10 @@ | |||
65 | */ | 66 | */ |
66 | void sbwdog_set(char __iomem *wdog, unsigned long t) | 67 | void sbwdog_set(char __iomem *wdog, unsigned long t) |
67 | { | 68 | { |
69 | spin_lock(&sbwd_lock); | ||
68 | __raw_writeb(0, wdog - 0x10); | 70 | __raw_writeb(0, wdog - 0x10); |
69 | __raw_writeq(t & 0x7fffffUL, wdog); | 71 | __raw_writeq(t & 0x7fffffUL, wdog); |
72 | spin_unlock(&sbwd_lock); | ||
70 | } | 73 | } |
71 | 74 | ||
72 | /* | 75 | /* |
@@ -77,7 +80,9 @@ void sbwdog_set(char __iomem *wdog, unsigned long t) | |||
77 | */ | 80 | */ |
78 | void sbwdog_pet(char __iomem *wdog) | 81 | void sbwdog_pet(char __iomem *wdog) |
79 | { | 82 | { |
83 | spin_lock(&sbwd_lock); | ||
80 | __raw_writeb(__raw_readb(wdog) | 1, wdog); | 84 | __raw_writeb(__raw_readb(wdog) | 1, wdog); |
85 | spin_unlock(&sbwd_lock); | ||
81 | } | 86 | } |
82 | 87 | ||
83 | static unsigned long sbwdog_gate; /* keeps it to one thread only */ | 88 | static unsigned long sbwdog_gate; /* keeps it to one thread only */ |
@@ -86,8 +91,9 @@ static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1)); | |||
86 | static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ | 91 | static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ |
87 | static int expect_close; | 92 | static int expect_close; |
88 | 93 | ||
89 | static struct watchdog_info ident = { | 94 | static const struct watchdog_info ident = { |
90 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 95 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | |
96 | WDIOF_KEEPALIVEPING, | ||
91 | .identity = "SiByte Watchdog", | 97 | .identity = "SiByte Watchdog", |
92 | }; | 98 | }; |
93 | 99 | ||
@@ -97,9 +103,8 @@ static struct watchdog_info ident = { | |||
97 | static int sbwdog_open(struct inode *inode, struct file *file) | 103 | static int sbwdog_open(struct inode *inode, struct file *file) |
98 | { | 104 | { |
99 | nonseekable_open(inode, file); | 105 | nonseekable_open(inode, file); |
100 | if (test_and_set_bit(0, &sbwdog_gate)) { | 106 | if (test_and_set_bit(0, &sbwdog_gate)) |
101 | return -EBUSY; | 107 | return -EBUSY; |
102 | } | ||
103 | __module_get(THIS_MODULE); | 108 | __module_get(THIS_MODULE); |
104 | 109 | ||
105 | /* | 110 | /* |
@@ -120,8 +125,9 @@ static int sbwdog_release(struct inode *inode, struct file *file) | |||
120 | __raw_writeb(0, user_dog); | 125 | __raw_writeb(0, user_dog); |
121 | module_put(THIS_MODULE); | 126 | module_put(THIS_MODULE); |
122 | } else { | 127 | } else { |
123 | printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", | 128 | printk(KERN_CRIT |
124 | ident.identity); | 129 | "%s: Unexpected close, not stopping watchdog!\n", |
130 | ident.identity); | ||
125 | sbwdog_pet(user_dog); | 131 | sbwdog_pet(user_dog); |
126 | } | 132 | } |
127 | clear_bit(0, &sbwdog_gate); | 133 | clear_bit(0, &sbwdog_gate); |
@@ -147,12 +153,10 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data, | |||
147 | for (i = 0; i != len; i++) { | 153 | for (i = 0; i != len; i++) { |
148 | char c; | 154 | char c; |
149 | 155 | ||
150 | if (get_user(c, data + i)) { | 156 | if (get_user(c, data + i)) |
151 | return -EFAULT; | 157 | return -EFAULT; |
152 | } | 158 | if (c == 'V') |
153 | if (c == 'V') { | ||
154 | expect_close = 42; | 159 | expect_close = 42; |
155 | } | ||
156 | } | 160 | } |
157 | sbwdog_pet(user_dog); | 161 | sbwdog_pet(user_dog); |
158 | } | 162 | } |
@@ -160,8 +164,8 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data, | |||
160 | return len; | 164 | return len; |
161 | } | 165 | } |
162 | 166 | ||
163 | static int sbwdog_ioctl(struct inode *inode, struct file *file, | 167 | static long sbwdog_ioctl(struct file *file, unsigned int cmd, |
164 | unsigned int cmd, unsigned long arg) | 168 | unsigned long arg) |
165 | { | 169 | { |
166 | int ret = -ENOTTY; | 170 | int ret = -ENOTTY; |
167 | unsigned long time; | 171 | unsigned long time; |
@@ -180,9 +184,8 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file, | |||
180 | 184 | ||
181 | case WDIOC_SETTIMEOUT: | 185 | case WDIOC_SETTIMEOUT: |
182 | ret = get_user(time, p); | 186 | ret = get_user(time, p); |
183 | if (ret) { | 187 | if (ret) |
184 | break; | 188 | break; |
185 | } | ||
186 | 189 | ||
187 | time *= 1000000; | 190 | time *= 1000000; |
188 | if (time > 0x7fffffUL) { | 191 | if (time > 0x7fffffUL) { |
@@ -226,18 +229,16 @@ sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) | |||
226 | return NOTIFY_DONE; | 229 | return NOTIFY_DONE; |
227 | } | 230 | } |
228 | 231 | ||
229 | static const struct file_operations sbwdog_fops = | 232 | static const struct file_operations sbwdog_fops = { |
230 | { | ||
231 | .owner = THIS_MODULE, | 233 | .owner = THIS_MODULE, |
232 | .llseek = no_llseek, | 234 | .llseek = no_llseek, |
233 | .write = sbwdog_write, | 235 | .write = sbwdog_write, |
234 | .ioctl = sbwdog_ioctl, | 236 | .unlocked_ioctl = sbwdog_ioctl, |
235 | .open = sbwdog_open, | 237 | .open = sbwdog_open, |
236 | .release = sbwdog_release, | 238 | .release = sbwdog_release, |
237 | }; | 239 | }; |
238 | 240 | ||
239 | static struct miscdevice sbwdog_miscdev = | 241 | static struct miscdevice sbwdog_miscdev = { |
240 | { | ||
241 | .minor = WATCHDOG_MINOR, | 242 | .minor = WATCHDOG_MINOR, |
242 | .name = "watchdog", | 243 | .name = "watchdog", |
243 | .fops = &sbwdog_fops, | 244 | .fops = &sbwdog_fops, |
@@ -267,13 +268,12 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr) | |||
267 | /* | 268 | /* |
268 | * if it's the second watchdog timer, it's for those users | 269 | * if it's the second watchdog timer, it's for those users |
269 | */ | 270 | */ |
270 | if (wd_cfg_reg == user_dog) { | 271 | if (wd_cfg_reg == user_dog) |
271 | printk(KERN_CRIT | 272 | printk(KERN_CRIT |
272 | "%s in danger of initiating system reset in %ld.%01ld seconds\n", | 273 | "%s in danger of initiating system reset in %ld.%01ld seconds\n", |
273 | ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); | 274 | ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); |
274 | } else { | 275 | else |
275 | cfg |= 1; | 276 | cfg |= 1; |
276 | } | ||
277 | 277 | ||
278 | __raw_writeb(cfg, wd_cfg_reg); | 278 | __raw_writeb(cfg, wd_cfg_reg); |
279 | 279 | ||
@@ -289,28 +289,31 @@ static int __init sbwdog_init(void) | |||
289 | */ | 289 | */ |
290 | ret = register_reboot_notifier(&sbwdog_notifier); | 290 | ret = register_reboot_notifier(&sbwdog_notifier); |
291 | if (ret) { | 291 | if (ret) { |
292 | printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", | 292 | printk(KERN_ERR |
293 | ident.identity, ret); | 293 | "%s: cannot register reboot notifier (err=%d)\n", |
294 | ident.identity, ret); | ||
294 | return ret; | 295 | return ret; |
295 | } | 296 | } |
296 | 297 | ||
297 | /* | 298 | /* |
298 | * get the resources | 299 | * get the resources |
299 | */ | 300 | */ |
300 | ret = misc_register(&sbwdog_miscdev); | ||
301 | if (ret == 0) { | ||
302 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity, | ||
303 | timeout / 1000000, (timeout / 100000) % 10); | ||
304 | } | ||
305 | 301 | ||
306 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, | 302 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, |
307 | ident.identity, (void *)user_dog); | 303 | ident.identity, (void *)user_dog); |
308 | if (ret) { | 304 | if (ret) { |
309 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, | 305 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", |
310 | ret); | 306 | ident.identity, ret); |
311 | misc_deregister(&sbwdog_miscdev); | 307 | return ret; |
312 | } | 308 | } |
313 | 309 | ||
310 | ret = misc_register(&sbwdog_miscdev); | ||
311 | if (ret == 0) { | ||
312 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", | ||
313 | ident.identity, | ||
314 | timeout / 1000000, (timeout / 100000) % 10); | ||
315 | } else | ||
316 | free_irq(1, (void *)user_dog); | ||
314 | return ret; | 317 | return ret; |
315 | } | 318 | } |
316 | 319 | ||
@@ -327,7 +330,7 @@ MODULE_DESCRIPTION("SiByte Watchdog"); | |||
327 | 330 | ||
328 | module_param(timeout, ulong, 0); | 331 | module_param(timeout, ulong, 0); |
329 | MODULE_PARM_DESC(timeout, | 332 | MODULE_PARM_DESC(timeout, |
330 | "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); | 333 | "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); |
331 | 334 | ||
332 | MODULE_LICENSE("GPL"); | 335 | MODULE_LICENSE("GPL"); |
333 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 336 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
@@ -336,16 +339,15 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | |||
336 | * example code that can be put in a platform code area to utilize the | 339 | * example code that can be put in a platform code area to utilize the |
337 | * first watchdog timer for the kernels own purpose. | 340 | * first watchdog timer for the kernels own purpose. |
338 | 341 | ||
339 | void | 342 | void platform_wd_setup(void) |
340 | platform_wd_setup(void) | ||
341 | { | 343 | { |
342 | int ret; | 344 | int ret; |
343 | 345 | ||
344 | ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, | 346 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, |
345 | "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); | 347 | "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); |
346 | if (ret) { | 348 | if (ret) { |
347 | printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", | 349 | printk(KERN_CRIT |
348 | ret); | 350 | "Watchdog IRQ zero(0) failed to be requested - %d\n", ret); |
349 | } | 351 | } |
350 | } | 352 | } |
351 | 353 | ||
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c index ef76f01625e7..e284a5d4fb1b 100644 --- a/drivers/watchdog/sbc60xxwdt.c +++ b/drivers/watchdog/sbc60xxwdt.c | |||
@@ -16,19 +16,23 @@ | |||
16 | * | 16 | * |
17 | * 12/4 - 2000 [Initial revision] | 17 | * 12/4 - 2000 [Initial revision] |
18 | * 25/4 - 2000 Added /dev/watchdog support | 18 | * 25/4 - 2000 Added /dev/watchdog support |
19 | * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" on success | 19 | * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" |
20 | * on success | ||
20 | * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read | 21 | * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read |
21 | * fix possible wdt_is_open race | 22 | * fix possible wdt_is_open race |
22 | * add CONFIG_WATCHDOG_NOWAYOUT support | 23 | * add CONFIG_WATCHDOG_NOWAYOUT support |
23 | * remove lock_kernel/unlock_kernel pairs | 24 | * remove lock_kernel/unlock_kernel pairs |
24 | * added KERN_* to printk's | 25 | * added KERN_* to printk's |
25 | * got rid of extraneous comments | 26 | * got rid of extraneous comments |
26 | * changed watchdog_info to correctly reflect what the driver offers | 27 | * changed watchdog_info to correctly reflect what |
27 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, | 28 | * the driver offers |
28 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls | 29 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, |
30 | * WDIOC_SETTIMEOUT, WDIOC_GETTIMEOUT, and | ||
31 | * WDIOC_SETOPTIONS ioctls | ||
29 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces | 32 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces |
30 | * use module_param | 33 | * use module_param |
31 | * made timeout (the emulated heartbeat) a module_param | 34 | * made timeout (the emulated heartbeat) a |
35 | * module_param | ||
32 | * made the keepalive ping an internal subroutine | 36 | * made the keepalive ping an internal subroutine |
33 | * made wdt_stop and wdt_start module params | 37 | * made wdt_stop and wdt_start module params |
34 | * added extra printk's for startup problems | 38 | * added extra printk's for startup problems |
@@ -56,9 +60,9 @@ | |||
56 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
57 | #include <linux/reboot.h> | 61 | #include <linux/reboot.h> |
58 | #include <linux/init.h> | 62 | #include <linux/init.h> |
63 | #include <linux/io.h> | ||
64 | #include <linux/uaccess.h> | ||
59 | 65 | ||
60 | #include <asm/io.h> | ||
61 | #include <asm/uaccess.h> | ||
62 | #include <asm/system.h> | 66 | #include <asm/system.h> |
63 | 67 | ||
64 | #define OUR_NAME "sbc60xxwdt" | 68 | #define OUR_NAME "sbc60xxwdt" |
@@ -94,13 +98,18 @@ MODULE_PARM_DESC(wdt_start, "SBC60xx WDT 'start' io port (default 0x443)"); | |||
94 | */ | 98 | */ |
95 | 99 | ||
96 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 100 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
97 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 101 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, multiplied by HZ to |
102 | get seconds to wait for a ping */ | ||
98 | module_param(timeout, int, 0); | 103 | module_param(timeout, int, 0); |
99 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 104 | MODULE_PARM_DESC(timeout, |
105 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
106 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
100 | 107 | ||
101 | static int nowayout = WATCHDOG_NOWAYOUT; | 108 | static int nowayout = WATCHDOG_NOWAYOUT; |
102 | module_param(nowayout, int, 0); | 109 | module_param(nowayout, int, 0); |
103 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 110 | MODULE_PARM_DESC(nowayout, |
111 | "Watchdog cannot be stopped once started (default=" | ||
112 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
104 | 113 | ||
105 | static void wdt_timer_ping(unsigned long); | 114 | static void wdt_timer_ping(unsigned long); |
106 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); | 115 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); |
@@ -117,15 +126,14 @@ static void wdt_timer_ping(unsigned long data) | |||
117 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 126 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
118 | * we agree to ping the WDT | 127 | * we agree to ping the WDT |
119 | */ | 128 | */ |
120 | if(time_before(jiffies, next_heartbeat)) | 129 | if (time_before(jiffies, next_heartbeat)) { |
121 | { | ||
122 | /* Ping the WDT by reading from wdt_start */ | 130 | /* Ping the WDT by reading from wdt_start */ |
123 | inb_p(wdt_start); | 131 | inb_p(wdt_start); |
124 | /* Re-set the timer interval */ | 132 | /* Re-set the timer interval */ |
125 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 133 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
126 | } else { | 134 | } else |
127 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 135 | printk(KERN_WARNING PFX |
128 | } | 136 | "Heartbeat lost! Will not ping the watchdog\n"); |
129 | } | 137 | } |
130 | 138 | ||
131 | /* | 139 | /* |
@@ -159,40 +167,40 @@ static void wdt_keepalive(void) | |||
159 | * /dev/watchdog handling | 167 | * /dev/watchdog handling |
160 | */ | 168 | */ |
161 | 169 | ||
162 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 170 | static ssize_t fop_write(struct file *file, const char __user *buf, |
171 | size_t count, loff_t *ppos) | ||
163 | { | 172 | { |
164 | /* See if we got the magic character 'V' and reload the timer */ | 173 | /* See if we got the magic character 'V' and reload the timer */ |
165 | if(count) | 174 | if (count) { |
166 | { | 175 | if (!nowayout) { |
167 | if (!nowayout) | ||
168 | { | ||
169 | size_t ofs; | 176 | size_t ofs; |
170 | 177 | ||
171 | /* note: just in case someone wrote the magic character | 178 | /* note: just in case someone wrote the |
172 | * five months ago... */ | 179 | magic character five months ago... */ |
173 | wdt_expect_close = 0; | 180 | wdt_expect_close = 0; |
174 | 181 | ||
175 | /* scan to see whether or not we got the magic character */ | 182 | /* scan to see whether or not we got the |
176 | for(ofs = 0; ofs != count; ofs++) | 183 | magic character */ |
177 | { | 184 | for (ofs = 0; ofs != count; ofs++) { |
178 | char c; | 185 | char c; |
179 | if(get_user(c, buf+ofs)) | 186 | if (get_user(c, buf+ofs)) |
180 | return -EFAULT; | 187 | return -EFAULT; |
181 | if(c == 'V') | 188 | if (c == 'V') |
182 | wdt_expect_close = 42; | 189 | wdt_expect_close = 42; |
183 | } | 190 | } |
184 | } | 191 | } |
185 | 192 | ||
186 | /* Well, anyhow someone wrote to us, we should return that favour */ | 193 | /* Well, anyhow someone wrote to us, we should |
194 | return that favour */ | ||
187 | wdt_keepalive(); | 195 | wdt_keepalive(); |
188 | } | 196 | } |
189 | return count; | 197 | return count; |
190 | } | 198 | } |
191 | 199 | ||
192 | static int fop_open(struct inode * inode, struct file * file) | 200 | static int fop_open(struct inode *inode, struct file *file) |
193 | { | 201 | { |
194 | /* Just in case we're already talking to someone... */ | 202 | /* Just in case we're already talking to someone... */ |
195 | if(test_and_set_bit(0, &wdt_is_open)) | 203 | if (test_and_set_bit(0, &wdt_is_open)) |
196 | return -EBUSY; | 204 | return -EBUSY; |
197 | 205 | ||
198 | if (nowayout) | 206 | if (nowayout) |
@@ -203,78 +211,72 @@ static int fop_open(struct inode * inode, struct file * file) | |||
203 | return nonseekable_open(inode, file); | 211 | return nonseekable_open(inode, file); |
204 | } | 212 | } |
205 | 213 | ||
206 | static int fop_close(struct inode * inode, struct file * file) | 214 | static int fop_close(struct inode *inode, struct file *file) |
207 | { | 215 | { |
208 | if(wdt_expect_close == 42) | 216 | if (wdt_expect_close == 42) |
209 | wdt_turnoff(); | 217 | wdt_turnoff(); |
210 | else { | 218 | else { |
211 | del_timer(&timer); | 219 | del_timer(&timer); |
212 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 220 | printk(KERN_CRIT PFX |
221 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
213 | } | 222 | } |
214 | clear_bit(0, &wdt_is_open); | 223 | clear_bit(0, &wdt_is_open); |
215 | wdt_expect_close = 0; | 224 | wdt_expect_close = 0; |
216 | return 0; | 225 | return 0; |
217 | } | 226 | } |
218 | 227 | ||
219 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 228 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
220 | unsigned long arg) | ||
221 | { | 229 | { |
222 | void __user *argp = (void __user *)arg; | 230 | void __user *argp = (void __user *)arg; |
223 | int __user *p = argp; | 231 | int __user *p = argp; |
224 | static struct watchdog_info ident= | 232 | static const struct watchdog_info ident = { |
225 | { | 233 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
226 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 234 | WDIOF_MAGICCLOSE, |
227 | .firmware_version = 1, | 235 | .firmware_version = 1, |
228 | .identity = "SBC60xx", | 236 | .identity = "SBC60xx", |
229 | }; | 237 | }; |
230 | 238 | ||
231 | switch(cmd) | 239 | switch (cmd) { |
240 | default: | ||
241 | return -ENOTTY; | ||
242 | case WDIOC_GETSUPPORT: | ||
243 | return copy_to_user(argp, &ident, sizeof(ident))? -EFAULT : 0; | ||
244 | case WDIOC_GETSTATUS: | ||
245 | case WDIOC_GETBOOTSTATUS: | ||
246 | return put_user(0, p); | ||
247 | case WDIOC_KEEPALIVE: | ||
248 | wdt_keepalive(); | ||
249 | return 0; | ||
250 | case WDIOC_SETOPTIONS: | ||
232 | { | 251 | { |
233 | default: | 252 | int new_options, retval = -EINVAL; |
234 | return -ENOTTY; | 253 | if (get_user(new_options, p)) |
235 | case WDIOC_GETSUPPORT: | 254 | return -EFAULT; |
236 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 255 | if (new_options & WDIOS_DISABLECARD) { |
237 | case WDIOC_GETSTATUS: | 256 | wdt_turnoff(); |
238 | case WDIOC_GETBOOTSTATUS: | 257 | retval = 0; |
239 | return put_user(0, p); | ||
240 | case WDIOC_KEEPALIVE: | ||
241 | wdt_keepalive(); | ||
242 | return 0; | ||
243 | case WDIOC_SETOPTIONS: | ||
244 | { | ||
245 | int new_options, retval = -EINVAL; | ||
246 | |||
247 | if(get_user(new_options, p)) | ||
248 | return -EFAULT; | ||
249 | |||
250 | if(new_options & WDIOS_DISABLECARD) { | ||
251 | wdt_turnoff(); | ||
252 | retval = 0; | ||
253 | } | ||
254 | |||
255 | if(new_options & WDIOS_ENABLECARD) { | ||
256 | wdt_startup(); | ||
257 | retval = 0; | ||
258 | } | ||
259 | |||
260 | return retval; | ||
261 | } | 258 | } |
262 | case WDIOC_SETTIMEOUT: | 259 | if (new_options & WDIOS_ENABLECARD) { |
263 | { | 260 | wdt_startup(); |
264 | int new_timeout; | 261 | retval = 0; |
265 | |||
266 | if(get_user(new_timeout, p)) | ||
267 | return -EFAULT; | ||
268 | |||
269 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | ||
270 | return -EINVAL; | ||
271 | |||
272 | timeout = new_timeout; | ||
273 | wdt_keepalive(); | ||
274 | /* Fall through */ | ||
275 | } | 262 | } |
276 | case WDIOC_GETTIMEOUT: | 263 | return retval; |
277 | return put_user(timeout, p); | 264 | } |
265 | case WDIOC_SETTIMEOUT: | ||
266 | { | ||
267 | int new_timeout; | ||
268 | if (get_user(new_timeout, p)) | ||
269 | return -EFAULT; | ||
270 | /* arbitrary upper limit */ | ||
271 | if (new_timeout < 1 || new_timeout > 3600) | ||
272 | return -EINVAL; | ||
273 | |||
274 | timeout = new_timeout; | ||
275 | wdt_keepalive(); | ||
276 | /* Fall through */ | ||
277 | } | ||
278 | case WDIOC_GETTIMEOUT: | ||
279 | return put_user(timeout, p); | ||
278 | } | 280 | } |
279 | } | 281 | } |
280 | 282 | ||
@@ -284,7 +286,7 @@ static const struct file_operations wdt_fops = { | |||
284 | .write = fop_write, | 286 | .write = fop_write, |
285 | .open = fop_open, | 287 | .open = fop_open, |
286 | .release = fop_close, | 288 | .release = fop_close, |
287 | .ioctl = fop_ioctl, | 289 | .unlocked_ioctl = fop_ioctl, |
288 | }; | 290 | }; |
289 | 291 | ||
290 | static struct miscdevice wdt_miscdev = { | 292 | static struct miscdevice wdt_miscdev = { |
@@ -300,7 +302,7 @@ static struct miscdevice wdt_miscdev = { | |||
300 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 302 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
301 | void *unused) | 303 | void *unused) |
302 | { | 304 | { |
303 | if(code==SYS_DOWN || code==SYS_HALT) | 305 | if (code == SYS_DOWN || code == SYS_HALT) |
304 | wdt_turnoff(); | 306 | wdt_turnoff(); |
305 | return NOTIFY_DONE; | 307 | return NOTIFY_DONE; |
306 | } | 308 | } |
@@ -310,8 +312,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
310 | * turn the timebomb registers off. | 312 | * turn the timebomb registers off. |
311 | */ | 313 | */ |
312 | 314 | ||
313 | static struct notifier_block wdt_notifier= | 315 | static struct notifier_block wdt_notifier = { |
314 | { | ||
315 | .notifier_call = wdt_notify_sys, | 316 | .notifier_call = wdt_notify_sys, |
316 | }; | 317 | }; |
317 | 318 | ||
@@ -324,23 +325,22 @@ static void __exit sbc60xxwdt_unload(void) | |||
324 | 325 | ||
325 | unregister_reboot_notifier(&wdt_notifier); | 326 | unregister_reboot_notifier(&wdt_notifier); |
326 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 327 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) |
327 | release_region(wdt_stop,1); | 328 | release_region(wdt_stop, 1); |
328 | release_region(wdt_start,1); | 329 | release_region(wdt_start, 1); |
329 | } | 330 | } |
330 | 331 | ||
331 | static int __init sbc60xxwdt_init(void) | 332 | static int __init sbc60xxwdt_init(void) |
332 | { | 333 | { |
333 | int rc = -EBUSY; | 334 | int rc = -EBUSY; |
334 | 335 | ||
335 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 336 | if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ |
336 | { | ||
337 | timeout = WATCHDOG_TIMEOUT; | 337 | timeout = WATCHDOG_TIMEOUT; |
338 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 338 | printk(KERN_INFO PFX |
339 | timeout); | 339 | "timeout value must be 1 <= x <= 3600, using %d\n", |
340 | } | 340 | timeout); |
341 | } | ||
341 | 342 | ||
342 | if (!request_region(wdt_start, 1, "SBC 60XX WDT")) | 343 | if (!request_region(wdt_start, 1, "SBC 60XX WDT")) { |
343 | { | ||
344 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 344 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
345 | wdt_start); | 345 | wdt_start); |
346 | rc = -EIO; | 346 | rc = -EIO; |
@@ -348,33 +348,30 @@ static int __init sbc60xxwdt_init(void) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | /* We cannot reserve 0x45 - the kernel already has! */ | 350 | /* We cannot reserve 0x45 - the kernel already has! */ |
351 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 351 | if (wdt_stop != 0x45 && wdt_stop != wdt_start) { |
352 | { | 352 | if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) { |
353 | if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) | 353 | printk(KERN_ERR PFX |
354 | { | 354 | "I/O address 0x%04x already in use\n", |
355 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 355 | wdt_stop); |
356 | wdt_stop); | ||
357 | rc = -EIO; | 356 | rc = -EIO; |
358 | goto err_out_region1; | 357 | goto err_out_region1; |
359 | } | 358 | } |
360 | } | 359 | } |
361 | 360 | ||
362 | rc = register_reboot_notifier(&wdt_notifier); | 361 | rc = register_reboot_notifier(&wdt_notifier); |
363 | if (rc) | 362 | if (rc) { |
364 | { | 363 | printk(KERN_ERR PFX |
365 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 364 | "cannot register reboot notifier (err=%d)\n", rc); |
366 | rc); | ||
367 | goto err_out_region2; | 365 | goto err_out_region2; |
368 | } | 366 | } |
369 | 367 | ||
370 | rc = misc_register(&wdt_miscdev); | 368 | rc = misc_register(&wdt_miscdev); |
371 | if (rc) | 369 | if (rc) { |
372 | { | 370 | printk(KERN_ERR PFX |
373 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 371 | "cannot register miscdev on minor=%d (err=%d)\n", |
374 | wdt_miscdev.minor, rc); | 372 | wdt_miscdev.minor, rc); |
375 | goto err_out_reboot; | 373 | goto err_out_reboot; |
376 | } | 374 | } |
377 | |||
378 | printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", | 375 | printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", |
379 | timeout, nowayout); | 376 | timeout, nowayout); |
380 | 377 | ||
@@ -383,10 +380,10 @@ static int __init sbc60xxwdt_init(void) | |||
383 | err_out_reboot: | 380 | err_out_reboot: |
384 | unregister_reboot_notifier(&wdt_notifier); | 381 | unregister_reboot_notifier(&wdt_notifier); |
385 | err_out_region2: | 382 | err_out_region2: |
386 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 383 | if (wdt_stop != 0x45 && wdt_stop != wdt_start) |
387 | release_region(wdt_stop,1); | 384 | release_region(wdt_stop, 1); |
388 | err_out_region1: | 385 | err_out_region1: |
389 | release_region(wdt_start,1); | 386 | release_region(wdt_start, 1); |
390 | err_out: | 387 | err_out: |
391 | return rc; | 388 | return rc; |
392 | } | 389 | } |
diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c index 4c8cefbd8627..abccbe265249 100644 --- a/drivers/watchdog/sbc7240_wdt.c +++ b/drivers/watchdog/sbc7240_wdt.c | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
30 | #include <linux/io.h> | ||
31 | #include <linux/uaccess.h> | ||
30 | #include <asm/atomic.h> | 32 | #include <asm/atomic.h> |
31 | #include <asm/io.h> | ||
32 | #include <asm/system.h> | 33 | #include <asm/system.h> |
33 | #include <asm/uaccess.h> | ||
34 | 34 | ||
35 | #define SBC7240_PREFIX "sbc7240_wdt: " | 35 | #define SBC7240_PREFIX "sbc7240_wdt: " |
36 | 36 | ||
@@ -159,7 +159,7 @@ static int fop_close(struct inode *inode, struct file *file) | |||
159 | return 0; | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | static struct watchdog_info ident = { | 162 | static const struct watchdog_info ident = { |
163 | .options = WDIOF_KEEPALIVEPING| | 163 | .options = WDIOF_KEEPALIVEPING| |
164 | WDIOF_SETTIMEOUT| | 164 | WDIOF_SETTIMEOUT| |
165 | WDIOF_MAGICCLOSE, | 165 | WDIOF_MAGICCLOSE, |
@@ -168,14 +168,12 @@ static struct watchdog_info ident = { | |||
168 | }; | 168 | }; |
169 | 169 | ||
170 | 170 | ||
171 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 171 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
172 | unsigned long arg) | ||
173 | { | 172 | { |
174 | switch (cmd) { | 173 | switch (cmd) { |
175 | case WDIOC_GETSUPPORT: | 174 | case WDIOC_GETSUPPORT: |
176 | return copy_to_user | 175 | return copy_to_user((void __user *)arg, &ident, sizeof(ident)) |
177 | ((void __user *)arg, &ident, sizeof(ident)) | 176 | ? -EFAULT : 0; |
178 | ? -EFAULT : 0; | ||
179 | case WDIOC_GETSTATUS: | 177 | case WDIOC_GETSTATUS: |
180 | case WDIOC_GETBOOTSTATUS: | 178 | case WDIOC_GETBOOTSTATUS: |
181 | return put_user(0, (int __user *)arg); | 179 | return put_user(0, (int __user *)arg); |
@@ -225,7 +223,7 @@ static const struct file_operations wdt_fops = { | |||
225 | .write = fop_write, | 223 | .write = fop_write, |
226 | .open = fop_open, | 224 | .open = fop_open, |
227 | .release = fop_close, | 225 | .release = fop_close, |
228 | .ioctl = fop_ioctl, | 226 | .unlocked_ioctl = fop_ioctl, |
229 | }; | 227 | }; |
230 | 228 | ||
231 | static struct miscdevice wdt_miscdev = { | 229 | static struct miscdevice wdt_miscdev = { |
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c index 2ee2677f3648..c66fa6694fc3 100644 --- a/drivers/watchdog/sbc8360.c +++ b/drivers/watchdog/sbc8360.c | |||
@@ -48,13 +48,12 @@ | |||
48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/spinlock.h> | 49 | #include <linux/spinlock.h> |
50 | #include <linux/moduleparam.h> | 50 | #include <linux/moduleparam.h> |
51 | #include <linux/io.h> | ||
52 | #include <linux/uaccess.h> | ||
51 | 53 | ||
52 | #include <asm/io.h> | ||
53 | #include <asm/uaccess.h> | ||
54 | #include <asm/system.h> | 54 | #include <asm/system.h> |
55 | 55 | ||
56 | static unsigned long sbc8360_is_open; | 56 | static unsigned long sbc8360_is_open; |
57 | static DEFINE_SPINLOCK(sbc8360_lock); | ||
58 | static char expect_close; | 57 | static char expect_close; |
59 | 58 | ||
60 | #define PFX "sbc8360: " | 59 | #define PFX "sbc8360: " |
@@ -204,7 +203,8 @@ module_param(timeout, int, 0); | |||
204 | MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); | 203 | MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); |
205 | module_param(nowayout, int, 0); | 204 | module_param(nowayout, int, 0); |
206 | MODULE_PARM_DESC(nowayout, | 205 | MODULE_PARM_DESC(nowayout, |
207 | "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 206 | "Watchdog cannot be stopped once started (default=" |
207 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
208 | 208 | ||
209 | /* | 209 | /* |
210 | * Kernel methods. | 210 | * Kernel methods. |
@@ -232,8 +232,8 @@ static void sbc8360_ping(void) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | /* Userspace pings kernel driver, or requests clean close */ | 234 | /* Userspace pings kernel driver, or requests clean close */ |
235 | static ssize_t sbc8360_write(struct file *file, const char __user * buf, | 235 | static ssize_t sbc8360_write(struct file *file, const char __user *buf, |
236 | size_t count, loff_t * ppos) | 236 | size_t count, loff_t *ppos) |
237 | { | 237 | { |
238 | if (count) { | 238 | if (count) { |
239 | if (!nowayout) { | 239 | if (!nowayout) { |
@@ -257,16 +257,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf, | |||
257 | 257 | ||
258 | static int sbc8360_open(struct inode *inode, struct file *file) | 258 | static int sbc8360_open(struct inode *inode, struct file *file) |
259 | { | 259 | { |
260 | spin_lock(&sbc8360_lock); | 260 | if (test_and_set_bit(0, &sbc8360_is_open)) |
261 | if (test_and_set_bit(0, &sbc8360_is_open)) { | ||
262 | spin_unlock(&sbc8360_lock); | ||
263 | return -EBUSY; | 261 | return -EBUSY; |
264 | } | ||
265 | if (nowayout) | 262 | if (nowayout) |
266 | __module_get(THIS_MODULE); | 263 | __module_get(THIS_MODULE); |
267 | 264 | ||
268 | /* Activate and ping once to start the countdown */ | 265 | /* Activate and ping once to start the countdown */ |
269 | spin_unlock(&sbc8360_lock); | ||
270 | sbc8360_activate(); | 266 | sbc8360_activate(); |
271 | sbc8360_ping(); | 267 | sbc8360_ping(); |
272 | return nonseekable_open(inode, file); | 268 | return nonseekable_open(inode, file); |
@@ -274,16 +270,14 @@ static int sbc8360_open(struct inode *inode, struct file *file) | |||
274 | 270 | ||
275 | static int sbc8360_close(struct inode *inode, struct file *file) | 271 | static int sbc8360_close(struct inode *inode, struct file *file) |
276 | { | 272 | { |
277 | spin_lock(&sbc8360_lock); | ||
278 | if (expect_close == 42) | 273 | if (expect_close == 42) |
279 | outb(0, SBC8360_ENABLE); | 274 | outb(0, SBC8360_ENABLE); |
280 | else | 275 | else |
281 | printk(KERN_CRIT PFX | 276 | printk(KERN_CRIT PFX |
282 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); | 277 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); |
283 | 278 | ||
284 | clear_bit(0, &sbc8360_is_open); | 279 | clear_bit(0, &sbc8360_is_open); |
285 | expect_close = 0; | 280 | expect_close = 0; |
286 | spin_unlock(&sbc8360_lock); | ||
287 | return 0; | 281 | return 0; |
288 | } | 282 | } |
289 | 283 | ||
@@ -382,13 +376,13 @@ static int __init sbc8360_init(void) | |||
382 | 376 | ||
383 | return 0; | 377 | return 0; |
384 | 378 | ||
385 | out_nomisc: | 379 | out_nomisc: |
386 | unregister_reboot_notifier(&sbc8360_notifier); | 380 | unregister_reboot_notifier(&sbc8360_notifier); |
387 | out_noreboot: | 381 | out_noreboot: |
388 | release_region(SBC8360_BASETIME, 1); | 382 | release_region(SBC8360_BASETIME, 1); |
389 | out_nobasetimereg: | 383 | out_nobasetimereg: |
390 | release_region(SBC8360_ENABLE, 1); | 384 | release_region(SBC8360_ENABLE, 1); |
391 | out: | 385 | out: |
392 | return res; | 386 | return res; |
393 | } | 387 | } |
394 | 388 | ||
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c index 82cbd8809a69..70ff9cbc8e9b 100644 --- a/drivers/watchdog/sbc_epx_c3.c +++ b/drivers/watchdog/sbc_epx_c3.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <linux/reboot.h> | 25 | #include <linux/reboot.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <asm/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
30 | 30 | ||
31 | #define PFX "epx_c3: " | 31 | #define PFX "epx_c3: " |
32 | static int epx_c3_alive; | 32 | static int epx_c3_alive; |
@@ -100,12 +100,12 @@ static ssize_t epx_c3_write(struct file *file, const char __user *data, | |||
100 | return len; | 100 | return len; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int epx_c3_ioctl(struct inode *inode, struct file *file, | 103 | static long epx_c3_ioctl(struct file *file, unsigned int cmd, |
104 | unsigned int cmd, unsigned long arg) | 104 | unsigned long arg) |
105 | { | 105 | { |
106 | int options, retval = -EINVAL; | 106 | int options, retval = -EINVAL; |
107 | int __user *argp = (void __user *)arg; | 107 | int __user *argp = (void __user *)arg; |
108 | static struct watchdog_info ident = { | 108 | static const struct watchdog_info ident = { |
109 | .options = WDIOF_KEEPALIVEPING | | 109 | .options = WDIOF_KEEPALIVEPING | |
110 | WDIOF_MAGICCLOSE, | 110 | WDIOF_MAGICCLOSE, |
111 | .firmware_version = 0, | 111 | .firmware_version = 0, |
@@ -158,7 +158,7 @@ static const struct file_operations epx_c3_fops = { | |||
158 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
159 | .llseek = no_llseek, | 159 | .llseek = no_llseek, |
160 | .write = epx_c3_write, | 160 | .write = epx_c3_write, |
161 | .ioctl = epx_c3_ioctl, | 161 | .unlocked_ioctl = epx_c3_ioctl, |
162 | .open = epx_c3_open, | 162 | .open = epx_c3_open, |
163 | .release = epx_c3_release, | 163 | .release = epx_c3_release, |
164 | }; | 164 | }; |
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c index 2847324a2be2..01de239f49e8 100644 --- a/drivers/watchdog/sc520_wdt.c +++ b/drivers/watchdog/sc520_wdt.c | |||
@@ -64,9 +64,9 @@ | |||
64 | #include <linux/reboot.h> | 64 | #include <linux/reboot.h> |
65 | #include <linux/init.h> | 65 | #include <linux/init.h> |
66 | #include <linux/jiffies.h> | 66 | #include <linux/jiffies.h> |
67 | #include <linux/io.h> | ||
68 | #include <linux/uaccess.h> | ||
67 | 69 | ||
68 | #include <asm/io.h> | ||
69 | #include <asm/uaccess.h> | ||
70 | #include <asm/system.h> | 70 | #include <asm/system.h> |
71 | 71 | ||
72 | #define OUR_NAME "sc520_wdt" | 72 | #define OUR_NAME "sc520_wdt" |
@@ -91,13 +91,18 @@ | |||
91 | */ | 91 | */ |
92 | 92 | ||
93 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 93 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
94 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 94 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
95 | static int timeout = WATCHDOG_TIMEOUT; | ||
95 | module_param(timeout, int, 0); | 96 | module_param(timeout, int, 0); |
96 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 97 | MODULE_PARM_DESC(timeout, |
98 | "Watchdog timeout in seconds. (1 <= timeout <= 3600, default=" | ||
99 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
97 | 100 | ||
98 | static int nowayout = WATCHDOG_NOWAYOUT; | 101 | static int nowayout = WATCHDOG_NOWAYOUT; |
99 | module_param(nowayout, int, 0); | 102 | module_param(nowayout, int, 0); |
100 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 103 | MODULE_PARM_DESC(nowayout, |
104 | "Watchdog cannot be stopped once started (default=" | ||
105 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
101 | 106 | ||
102 | /* | 107 | /* |
103 | * AMD Elan SC520 - Watchdog Timer Registers | 108 | * AMD Elan SC520 - Watchdog Timer Registers |
@@ -136,8 +141,7 @@ static void wdt_timer_ping(unsigned long data) | |||
136 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 141 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
137 | * we agree to ping the WDT | 142 | * we agree to ping the WDT |
138 | */ | 143 | */ |
139 | if(time_before(jiffies, next_heartbeat)) | 144 | if (time_before(jiffies, next_heartbeat)) { |
140 | { | ||
141 | /* Ping the WDT */ | 145 | /* Ping the WDT */ |
142 | spin_lock(&wdt_spinlock); | 146 | spin_lock(&wdt_spinlock); |
143 | writew(0xAAAA, wdtmrctl); | 147 | writew(0xAAAA, wdtmrctl); |
@@ -146,9 +150,9 @@ static void wdt_timer_ping(unsigned long data) | |||
146 | 150 | ||
147 | /* Re-set the timer interval */ | 151 | /* Re-set the timer interval */ |
148 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 152 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
149 | } else { | 153 | } else |
150 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 154 | printk(KERN_WARNING PFX |
151 | } | 155 | "Heartbeat lost! Will not ping the watchdog\n"); |
152 | } | 156 | } |
153 | 157 | ||
154 | /* | 158 | /* |
@@ -162,7 +166,7 @@ static void wdt_config(int writeval) | |||
162 | 166 | ||
163 | /* buy some time (ping) */ | 167 | /* buy some time (ping) */ |
164 | spin_lock_irqsave(&wdt_spinlock, flags); | 168 | spin_lock_irqsave(&wdt_spinlock, flags); |
165 | dummy=readw(wdtmrctl); /* ensure write synchronization */ | 169 | dummy = readw(wdtmrctl); /* ensure write synchronization */ |
166 | writew(0xAAAA, wdtmrctl); | 170 | writew(0xAAAA, wdtmrctl); |
167 | writew(0x5555, wdtmrctl); | 171 | writew(0x5555, wdtmrctl); |
168 | /* unlock WDT = make WDT configuration register writable one time */ | 172 | /* unlock WDT = make WDT configuration register writable one time */ |
@@ -219,10 +223,11 @@ static int wdt_set_heartbeat(int t) | |||
219 | * /dev/watchdog handling | 223 | * /dev/watchdog handling |
220 | */ | 224 | */ |
221 | 225 | ||
222 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 226 | static ssize_t fop_write(struct file *file, const char __user *buf, |
227 | size_t count, loff_t *ppos) | ||
223 | { | 228 | { |
224 | /* See if we got the magic character 'V' and reload the timer */ | 229 | /* See if we got the magic character 'V' and reload the timer */ |
225 | if(count) { | 230 | if (count) { |
226 | if (!nowayout) { | 231 | if (!nowayout) { |
227 | size_t ofs; | 232 | size_t ofs; |
228 | 233 | ||
@@ -231,25 +236,26 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
231 | wdt_expect_close = 0; | 236 | wdt_expect_close = 0; |
232 | 237 | ||
233 | /* now scan */ | 238 | /* now scan */ |
234 | for(ofs = 0; ofs != count; ofs++) { | 239 | for (ofs = 0; ofs != count; ofs++) { |
235 | char c; | 240 | char c; |
236 | if (get_user(c, buf + ofs)) | 241 | if (get_user(c, buf + ofs)) |
237 | return -EFAULT; | 242 | return -EFAULT; |
238 | if(c == 'V') | 243 | if (c == 'V') |
239 | wdt_expect_close = 42; | 244 | wdt_expect_close = 42; |
240 | } | 245 | } |
241 | } | 246 | } |
242 | 247 | ||
243 | /* Well, anyhow someone wrote to us, we should return that favour */ | 248 | /* Well, anyhow someone wrote to us, we should |
249 | return that favour */ | ||
244 | wdt_keepalive(); | 250 | wdt_keepalive(); |
245 | } | 251 | } |
246 | return count; | 252 | return count; |
247 | } | 253 | } |
248 | 254 | ||
249 | static int fop_open(struct inode * inode, struct file * file) | 255 | static int fop_open(struct inode *inode, struct file *file) |
250 | { | 256 | { |
251 | /* Just in case we're already talking to someone... */ | 257 | /* Just in case we're already talking to someone... */ |
252 | if(test_and_set_bit(0, &wdt_is_open)) | 258 | if (test_and_set_bit(0, &wdt_is_open)) |
253 | return -EBUSY; | 259 | return -EBUSY; |
254 | if (nowayout) | 260 | if (nowayout) |
255 | __module_get(THIS_MODULE); | 261 | __module_get(THIS_MODULE); |
@@ -259,12 +265,13 @@ static int fop_open(struct inode * inode, struct file * file) | |||
259 | return nonseekable_open(inode, file); | 265 | return nonseekable_open(inode, file); |
260 | } | 266 | } |
261 | 267 | ||
262 | static int fop_close(struct inode * inode, struct file * file) | 268 | static int fop_close(struct inode *inode, struct file *file) |
263 | { | 269 | { |
264 | if(wdt_expect_close == 42) { | 270 | if (wdt_expect_close == 42) |
265 | wdt_turnoff(); | 271 | wdt_turnoff(); |
266 | } else { | 272 | else { |
267 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 273 | printk(KERN_CRIT PFX |
274 | "Unexpected close, not stopping watchdog!\n"); | ||
268 | wdt_keepalive(); | 275 | wdt_keepalive(); |
269 | } | 276 | } |
270 | clear_bit(0, &wdt_is_open); | 277 | clear_bit(0, &wdt_is_open); |
@@ -272,63 +279,63 @@ static int fop_close(struct inode * inode, struct file * file) | |||
272 | return 0; | 279 | return 0; |
273 | } | 280 | } |
274 | 281 | ||
275 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 282 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
276 | unsigned long arg) | ||
277 | { | 283 | { |
278 | void __user *argp = (void __user *)arg; | 284 | void __user *argp = (void __user *)arg; |
279 | int __user *p = argp; | 285 | int __user *p = argp; |
280 | static struct watchdog_info ident = { | 286 | static const struct watchdog_info ident = { |
281 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 287 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
288 | | WDIOF_MAGICCLOSE, | ||
282 | .firmware_version = 1, | 289 | .firmware_version = 1, |
283 | .identity = "SC520", | 290 | .identity = "SC520", |
284 | }; | 291 | }; |
285 | 292 | ||
286 | switch(cmd) | 293 | switch (cmd) |
287 | { | 294 | { |
288 | default: | 295 | default: |
289 | return -ENOTTY; | 296 | return -ENOTTY; |
290 | case WDIOC_GETSUPPORT: | 297 | case WDIOC_GETSUPPORT: |
291 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 298 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
292 | case WDIOC_GETSTATUS: | 299 | case WDIOC_GETSTATUS: |
293 | case WDIOC_GETBOOTSTATUS: | 300 | case WDIOC_GETBOOTSTATUS: |
294 | return put_user(0, p); | 301 | return put_user(0, p); |
295 | case WDIOC_KEEPALIVE: | 302 | case WDIOC_KEEPALIVE: |
296 | wdt_keepalive(); | 303 | wdt_keepalive(); |
297 | return 0; | 304 | return 0; |
298 | case WDIOC_SETOPTIONS: | 305 | case WDIOC_SETOPTIONS: |
299 | { | 306 | { |
300 | int new_options, retval = -EINVAL; | 307 | int new_options, retval = -EINVAL; |
301 | |||
302 | if(get_user(new_options, p)) | ||
303 | return -EFAULT; | ||
304 | |||
305 | if(new_options & WDIOS_DISABLECARD) { | ||
306 | wdt_turnoff(); | ||
307 | retval = 0; | ||
308 | } | ||
309 | 308 | ||
310 | if(new_options & WDIOS_ENABLECARD) { | 309 | if (get_user(new_options, p)) |
311 | wdt_startup(); | 310 | return -EFAULT; |
312 | retval = 0; | 311 | |
313 | } | 312 | if (new_options & WDIOS_DISABLECARD) { |
313 | wdt_turnoff(); | ||
314 | retval = 0; | ||
315 | } | ||
314 | 316 | ||
315 | return retval; | 317 | if (new_options & WDIOS_ENABLECARD) { |
318 | wdt_startup(); | ||
319 | retval = 0; | ||
316 | } | 320 | } |
317 | case WDIOC_SETTIMEOUT: | ||
318 | { | ||
319 | int new_timeout; | ||
320 | 321 | ||
321 | if(get_user(new_timeout, p)) | 322 | return retval; |
322 | return -EFAULT; | 323 | } |
324 | case WDIOC_SETTIMEOUT: | ||
325 | { | ||
326 | int new_timeout; | ||
323 | 327 | ||
324 | if(wdt_set_heartbeat(new_timeout)) | 328 | if (get_user(new_timeout, p)) |
325 | return -EINVAL; | 329 | return -EFAULT; |
326 | 330 | ||
327 | wdt_keepalive(); | 331 | if (wdt_set_heartbeat(new_timeout)) |
328 | /* Fall through */ | 332 | return -EINVAL; |
329 | } | 333 | |
330 | case WDIOC_GETTIMEOUT: | 334 | wdt_keepalive(); |
331 | return put_user(timeout, p); | 335 | /* Fall through */ |
336 | } | ||
337 | case WDIOC_GETTIMEOUT: | ||
338 | return put_user(timeout, p); | ||
332 | } | 339 | } |
333 | } | 340 | } |
334 | 341 | ||
@@ -338,7 +345,7 @@ static const struct file_operations wdt_fops = { | |||
338 | .write = fop_write, | 345 | .write = fop_write, |
339 | .open = fop_open, | 346 | .open = fop_open, |
340 | .release = fop_close, | 347 | .release = fop_close, |
341 | .ioctl = fop_ioctl, | 348 | .unlocked_ioctl = fop_ioctl, |
342 | }; | 349 | }; |
343 | 350 | ||
344 | static struct miscdevice wdt_miscdev = { | 351 | static struct miscdevice wdt_miscdev = { |
@@ -354,7 +361,7 @@ static struct miscdevice wdt_miscdev = { | |||
354 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 361 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
355 | void *unused) | 362 | void *unused) |
356 | { | 363 | { |
357 | if(code==SYS_DOWN || code==SYS_HALT) | 364 | if (code == SYS_DOWN || code == SYS_HALT) |
358 | wdt_turnoff(); | 365 | wdt_turnoff(); |
359 | return NOTIFY_DONE; | 366 | return NOTIFY_DONE; |
360 | } | 367 | } |
@@ -383,11 +390,13 @@ static int __init sc520_wdt_init(void) | |||
383 | { | 390 | { |
384 | int rc = -EBUSY; | 391 | int rc = -EBUSY; |
385 | 392 | ||
386 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 393 | /* Check that the timeout value is within it's range ; |
394 | if not reset to the default */ | ||
387 | if (wdt_set_heartbeat(timeout)) { | 395 | if (wdt_set_heartbeat(timeout)) { |
388 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 396 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
389 | printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", | 397 | printk(KERN_INFO PFX |
390 | WATCHDOG_TIMEOUT); | 398 | "timeout value must be 1 <= timeout <= 3600, using %d\n", |
399 | WATCHDOG_TIMEOUT); | ||
391 | } | 400 | } |
392 | 401 | ||
393 | wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); | 402 | wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); |
@@ -399,20 +408,22 @@ static int __init sc520_wdt_init(void) | |||
399 | 408 | ||
400 | rc = register_reboot_notifier(&wdt_notifier); | 409 | rc = register_reboot_notifier(&wdt_notifier); |
401 | if (rc) { | 410 | if (rc) { |
402 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 411 | printk(KERN_ERR PFX |
403 | rc); | 412 | "cannot register reboot notifier (err=%d)\n", rc); |
404 | goto err_out_ioremap; | 413 | goto err_out_ioremap; |
405 | } | 414 | } |
406 | 415 | ||
407 | rc = misc_register(&wdt_miscdev); | 416 | rc = misc_register(&wdt_miscdev); |
408 | if (rc) { | 417 | if (rc) { |
409 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 418 | printk(KERN_ERR PFX |
410 | WATCHDOG_MINOR, rc); | 419 | "cannot register miscdev on minor=%d (err=%d)\n", |
420 | WATCHDOG_MINOR, rc); | ||
411 | goto err_out_notifier; | 421 | goto err_out_notifier; |
412 | } | 422 | } |
413 | 423 | ||
414 | printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", | 424 | printk(KERN_INFO PFX |
415 | timeout,nowayout); | 425 | "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", |
426 | timeout, nowayout); | ||
416 | 427 | ||
417 | return 0; | 428 | return 0; |
418 | 429 | ||
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c index d55882bca319..7c1de94704f3 100644 --- a/drivers/watchdog/scx200_wdt.c +++ b/drivers/watchdog/scx200_wdt.c | |||
@@ -27,9 +27,8 @@ | |||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/scx200.h> | 29 | #include <linux/scx200.h> |
30 | 30 | #include <linux/uaccess.h> | |
31 | #include <asm/uaccess.h> | 31 | #include <linux/io.h> |
32 | #include <asm/io.h> | ||
33 | 32 | ||
34 | #define NAME "scx200_wdt" | 33 | #define NAME "scx200_wdt" |
35 | 34 | ||
@@ -47,8 +46,9 @@ module_param(nowayout, int, 0); | |||
47 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | 46 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); |
48 | 47 | ||
49 | static u16 wdto_restart; | 48 | static u16 wdto_restart; |
50 | static struct semaphore open_semaphore; | ||
51 | static char expect_close; | 49 | static char expect_close; |
50 | static unsigned long open_lock; | ||
51 | static DEFINE_SPINLOCK(scx_lock); | ||
52 | 52 | ||
53 | /* Bits of the WDCNFG register */ | 53 | /* Bits of the WDCNFG register */ |
54 | #define W_ENABLE 0x00fa /* Enable watchdog */ | 54 | #define W_ENABLE 0x00fa /* Enable watchdog */ |
@@ -59,7 +59,9 @@ static char expect_close; | |||
59 | 59 | ||
60 | static void scx200_wdt_ping(void) | 60 | static void scx200_wdt_ping(void) |
61 | { | 61 | { |
62 | spin_lock(&scx_lock); | ||
62 | outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); | 63 | outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); |
64 | spin_unlock(&scx_lock); | ||
63 | } | 65 | } |
64 | 66 | ||
65 | static void scx200_wdt_update_margin(void) | 67 | static void scx200_wdt_update_margin(void) |
@@ -73,9 +75,11 @@ static void scx200_wdt_enable(void) | |||
73 | printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", | 75 | printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", |
74 | wdto_restart); | 76 | wdto_restart); |
75 | 77 | ||
78 | spin_lock(&scx_lock); | ||
76 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); | 79 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); |
77 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); | 80 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); |
78 | outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); | 81 | outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); |
82 | spin_unlock(&scx_lock); | ||
79 | 83 | ||
80 | scx200_wdt_ping(); | 84 | scx200_wdt_ping(); |
81 | } | 85 | } |
@@ -84,15 +88,17 @@ static void scx200_wdt_disable(void) | |||
84 | { | 88 | { |
85 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); | 89 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); |
86 | 90 | ||
91 | spin_lock(&scx_lock); | ||
87 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); | 92 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); |
88 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); | 93 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); |
89 | outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); | 94 | outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); |
95 | spin_unlock(&scx_lock); | ||
90 | } | 96 | } |
91 | 97 | ||
92 | static int scx200_wdt_open(struct inode *inode, struct file *file) | 98 | static int scx200_wdt_open(struct inode *inode, struct file *file) |
93 | { | 99 | { |
94 | /* only allow one at a time */ | 100 | /* only allow one at a time */ |
95 | if (down_trylock(&open_semaphore)) | 101 | if (test_and_set_bit(0, &open_lock)) |
96 | return -EBUSY; | 102 | return -EBUSY; |
97 | scx200_wdt_enable(); | 103 | scx200_wdt_enable(); |
98 | 104 | ||
@@ -101,13 +107,12 @@ static int scx200_wdt_open(struct inode *inode, struct file *file) | |||
101 | 107 | ||
102 | static int scx200_wdt_release(struct inode *inode, struct file *file) | 108 | static int scx200_wdt_release(struct inode *inode, struct file *file) |
103 | { | 109 | { |
104 | if (expect_close != 42) { | 110 | if (expect_close != 42) |
105 | printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); | 111 | printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); |
106 | } else if (!nowayout) { | 112 | else if (!nowayout) |
107 | scx200_wdt_disable(); | 113 | scx200_wdt_disable(); |
108 | } | ||
109 | expect_close = 0; | 114 | expect_close = 0; |
110 | up(&open_semaphore); | 115 | clear_bit(0, &open_lock); |
111 | 116 | ||
112 | return 0; | 117 | return 0; |
113 | } | 118 | } |
@@ -122,8 +127,7 @@ static int scx200_wdt_notify_sys(struct notifier_block *this, | |||
122 | return NOTIFY_DONE; | 127 | return NOTIFY_DONE; |
123 | } | 128 | } |
124 | 129 | ||
125 | static struct notifier_block scx200_wdt_notifier = | 130 | static struct notifier_block scx200_wdt_notifier = { |
126 | { | ||
127 | .notifier_call = scx200_wdt_notify_sys, | 131 | .notifier_call = scx200_wdt_notify_sys, |
128 | }; | 132 | }; |
129 | 133 | ||
@@ -131,8 +135,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data, | |||
131 | size_t len, loff_t *ppos) | 135 | size_t len, loff_t *ppos) |
132 | { | 136 | { |
133 | /* check for a magic close character */ | 137 | /* check for a magic close character */ |
134 | if (len) | 138 | if (len) { |
135 | { | ||
136 | size_t i; | 139 | size_t i; |
137 | 140 | ||
138 | scx200_wdt_ping(); | 141 | scx200_wdt_ping(); |
@@ -152,15 +155,15 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data, | |||
152 | return 0; | 155 | return 0; |
153 | } | 156 | } |
154 | 157 | ||
155 | static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | 158 | static long scx200_wdt_ioctl(struct file *file, unsigned int cmd, |
156 | unsigned int cmd, unsigned long arg) | 159 | unsigned long arg) |
157 | { | 160 | { |
158 | void __user *argp = (void __user *)arg; | 161 | void __user *argp = (void __user *)arg; |
159 | int __user *p = argp; | 162 | int __user *p = argp; |
160 | static struct watchdog_info ident = { | 163 | static const struct watchdog_info ident = { |
161 | .identity = "NatSemi SCx200 Watchdog", | 164 | .identity = "NatSemi SCx200 Watchdog", |
162 | .firmware_version = 1, | 165 | .firmware_version = 1, |
163 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), | 166 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
164 | }; | 167 | }; |
165 | int new_margin; | 168 | int new_margin; |
166 | 169 | ||
@@ -168,7 +171,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | |||
168 | default: | 171 | default: |
169 | return -ENOTTY; | 172 | return -ENOTTY; |
170 | case WDIOC_GETSUPPORT: | 173 | case WDIOC_GETSUPPORT: |
171 | if(copy_to_user(argp, &ident, sizeof(ident))) | 174 | if (copy_to_user(argp, &ident, sizeof(ident))) |
172 | return -EFAULT; | 175 | return -EFAULT; |
173 | return 0; | 176 | return 0; |
174 | case WDIOC_GETSTATUS: | 177 | case WDIOC_GETSTATUS: |
@@ -195,18 +198,18 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | |||
195 | } | 198 | } |
196 | 199 | ||
197 | static const struct file_operations scx200_wdt_fops = { | 200 | static const struct file_operations scx200_wdt_fops = { |
198 | .owner = THIS_MODULE, | 201 | .owner = THIS_MODULE, |
199 | .llseek = no_llseek, | 202 | .llseek = no_llseek, |
200 | .write = scx200_wdt_write, | 203 | .write = scx200_wdt_write, |
201 | .ioctl = scx200_wdt_ioctl, | 204 | .unlocked_ioctl = scx200_wdt_ioctl, |
202 | .open = scx200_wdt_open, | 205 | .open = scx200_wdt_open, |
203 | .release = scx200_wdt_release, | 206 | .release = scx200_wdt_release, |
204 | }; | 207 | }; |
205 | 208 | ||
206 | static struct miscdevice scx200_wdt_miscdev = { | 209 | static struct miscdevice scx200_wdt_miscdev = { |
207 | .minor = WATCHDOG_MINOR, | 210 | .minor = WATCHDOG_MINOR, |
208 | .name = "watchdog", | 211 | .name = "watchdog", |
209 | .fops = &scx200_wdt_fops, | 212 | .fops = &scx200_wdt_fops, |
210 | }; | 213 | }; |
211 | 214 | ||
212 | static int __init scx200_wdt_init(void) | 215 | static int __init scx200_wdt_init(void) |
@@ -229,8 +232,6 @@ static int __init scx200_wdt_init(void) | |||
229 | scx200_wdt_update_margin(); | 232 | scx200_wdt_update_margin(); |
230 | scx200_wdt_disable(); | 233 | scx200_wdt_disable(); |
231 | 234 | ||
232 | sema_init(&open_semaphore, 1); | ||
233 | |||
234 | r = register_reboot_notifier(&scx200_wdt_notifier); | 235 | r = register_reboot_notifier(&scx200_wdt_notifier); |
235 | if (r) { | 236 | if (r) { |
236 | printk(KERN_ERR NAME ": unable to register reboot notifier"); | 237 | printk(KERN_ERR NAME ": unable to register reboot notifier"); |
@@ -263,7 +264,7 @@ module_exit(scx200_wdt_cleanup); | |||
263 | 264 | ||
264 | /* | 265 | /* |
265 | Local variables: | 266 | Local variables: |
266 | compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" | 267 | compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" |
267 | c-basic-offset: 8 | 268 | c-basic-offset: 8 |
268 | End: | 269 | End: |
269 | */ | 270 | */ |
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 1277f7e9cc54..60f0036aaca6 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <asm/io.h> | 31 | #include <linux/io.h> |
32 | #include <asm/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <asm/watchdog.h> | 33 | #include <linux/watchdog.h> |
34 | 34 | ||
35 | #define PFX "shwdt: " | 35 | #define PFX "shwdt: " |
36 | 36 | ||
@@ -72,6 +72,7 @@ static struct watchdog_info sh_wdt_info; | |||
72 | static char shwdt_expect_close; | 72 | static char shwdt_expect_close; |
73 | static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); | 73 | static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); |
74 | static unsigned long next_heartbeat; | 74 | static unsigned long next_heartbeat; |
75 | static DEFINE_SPINLOCK(shwdt_lock); | ||
75 | 76 | ||
76 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 77 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
77 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 78 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
@@ -86,6 +87,9 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
86 | static void sh_wdt_start(void) | 87 | static void sh_wdt_start(void) |
87 | { | 88 | { |
88 | __u8 csr; | 89 | __u8 csr; |
90 | unsigned long flags; | ||
91 | |||
92 | spin_lock_irqsave(&wdt_lock, flags); | ||
89 | 93 | ||
90 | next_heartbeat = jiffies + (heartbeat * HZ); | 94 | next_heartbeat = jiffies + (heartbeat * HZ); |
91 | mod_timer(&timer, next_ping_period(clock_division_ratio)); | 95 | mod_timer(&timer, next_ping_period(clock_division_ratio)); |
@@ -123,6 +127,7 @@ static void sh_wdt_start(void) | |||
123 | csr &= ~RSTCSR_RSTS; | 127 | csr &= ~RSTCSR_RSTS; |
124 | sh_wdt_write_rstcsr(csr); | 128 | sh_wdt_write_rstcsr(csr); |
125 | #endif | 129 | #endif |
130 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
126 | } | 131 | } |
127 | 132 | ||
128 | /** | 133 | /** |
@@ -132,12 +137,16 @@ static void sh_wdt_start(void) | |||
132 | static void sh_wdt_stop(void) | 137 | static void sh_wdt_stop(void) |
133 | { | 138 | { |
134 | __u8 csr; | 139 | __u8 csr; |
140 | unsigned long flags; | ||
141 | |||
142 | spin_lock_irqsave(&wdt_lock, flags); | ||
135 | 143 | ||
136 | del_timer(&timer); | 144 | del_timer(&timer); |
137 | 145 | ||
138 | csr = sh_wdt_read_csr(); | 146 | csr = sh_wdt_read_csr(); |
139 | csr &= ~WTCSR_TME; | 147 | csr &= ~WTCSR_TME; |
140 | sh_wdt_write_csr(csr); | 148 | sh_wdt_write_csr(csr); |
149 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
141 | } | 150 | } |
142 | 151 | ||
143 | /** | 152 | /** |
@@ -146,7 +155,11 @@ static void sh_wdt_stop(void) | |||
146 | */ | 155 | */ |
147 | static inline void sh_wdt_keepalive(void) | 156 | static inline void sh_wdt_keepalive(void) |
148 | { | 157 | { |
158 | unsigned long flags; | ||
159 | |||
160 | spin_lock_irqsave(&wdt_lock, flags); | ||
149 | next_heartbeat = jiffies + (heartbeat * HZ); | 161 | next_heartbeat = jiffies + (heartbeat * HZ); |
162 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
150 | } | 163 | } |
151 | 164 | ||
152 | /** | 165 | /** |
@@ -155,10 +168,14 @@ static inline void sh_wdt_keepalive(void) | |||
155 | */ | 168 | */ |
156 | static int sh_wdt_set_heartbeat(int t) | 169 | static int sh_wdt_set_heartbeat(int t) |
157 | { | 170 | { |
158 | if (unlikely((t < 1) || (t > 3600))) /* arbitrary upper limit */ | 171 | unsigned long flags; |
172 | |||
173 | if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ | ||
159 | return -EINVAL; | 174 | return -EINVAL; |
160 | 175 | ||
176 | spin_lock_irqsave(&wdt_lock, flags); | ||
161 | heartbeat = t; | 177 | heartbeat = t; |
178 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
162 | return 0; | 179 | return 0; |
163 | } | 180 | } |
164 | 181 | ||
@@ -170,6 +187,9 @@ static int sh_wdt_set_heartbeat(int t) | |||
170 | */ | 187 | */ |
171 | static void sh_wdt_ping(unsigned long data) | 188 | static void sh_wdt_ping(unsigned long data) |
172 | { | 189 | { |
190 | unsigned long flags; | ||
191 | |||
192 | spin_lock_irqsave(&wdt_lock, flags); | ||
173 | if (time_before(jiffies, next_heartbeat)) { | 193 | if (time_before(jiffies, next_heartbeat)) { |
174 | __u8 csr; | 194 | __u8 csr; |
175 | 195 | ||
@@ -183,6 +203,7 @@ static void sh_wdt_ping(unsigned long data) | |||
183 | } else | 203 | } else |
184 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " | 204 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " |
185 | "the watchdog\n"); | 205 | "the watchdog\n"); |
206 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
186 | } | 207 | } |
187 | 208 | ||
188 | /** | 209 | /** |
@@ -310,7 +331,6 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | |||
310 | 331 | ||
311 | /** | 332 | /** |
312 | * sh_wdt_ioctl - Query Device | 333 | * sh_wdt_ioctl - Query Device |
313 | * @inode: inode of device | ||
314 | * @file: file handle of device | 334 | * @file: file handle of device |
315 | * @cmd: watchdog command | 335 | * @cmd: watchdog command |
316 | * @arg: argument | 336 | * @arg: argument |
@@ -318,53 +338,51 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | |||
318 | * Query basic information from the device or ping it, as outlined by the | 338 | * Query basic information from the device or ping it, as outlined by the |
319 | * watchdog API. | 339 | * watchdog API. |
320 | */ | 340 | */ |
321 | static int sh_wdt_ioctl(struct inode *inode, struct file *file, | 341 | static long sh_wdt_ioctl(struct file *file, unsigned int cmd, |
322 | unsigned int cmd, unsigned long arg) | 342 | unsigned long arg) |
323 | { | 343 | { |
324 | int new_heartbeat; | 344 | int new_heartbeat; |
325 | int options, retval = -EINVAL; | 345 | int options, retval = -EINVAL; |
326 | 346 | ||
327 | switch (cmd) { | 347 | switch (cmd) { |
328 | case WDIOC_GETSUPPORT: | 348 | case WDIOC_GETSUPPORT: |
329 | return copy_to_user((struct watchdog_info *)arg, | 349 | return copy_to_user((struct watchdog_info *)arg, |
330 | &sh_wdt_info, | 350 | &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0; |
331 | sizeof(sh_wdt_info)) ? -EFAULT : 0; | 351 | case WDIOC_GETSTATUS: |
332 | case WDIOC_GETSTATUS: | 352 | case WDIOC_GETBOOTSTATUS: |
333 | case WDIOC_GETBOOTSTATUS: | 353 | return put_user(0, (int *)arg); |
334 | return put_user(0, (int *)arg); | 354 | case WDIOC_KEEPALIVE: |
335 | case WDIOC_KEEPALIVE: | 355 | sh_wdt_keepalive(); |
336 | sh_wdt_keepalive(); | 356 | return 0; |
337 | return 0; | 357 | case WDIOC_SETTIMEOUT: |
338 | case WDIOC_SETTIMEOUT: | 358 | if (get_user(new_heartbeat, (int *)arg)) |
339 | if (get_user(new_heartbeat, (int *)arg)) | 359 | return -EFAULT; |
340 | return -EFAULT; | ||
341 | |||
342 | if (sh_wdt_set_heartbeat(new_heartbeat)) | ||
343 | return -EINVAL; | ||
344 | |||
345 | sh_wdt_keepalive(); | ||
346 | /* Fall */ | ||
347 | case WDIOC_GETTIMEOUT: | ||
348 | return put_user(heartbeat, (int *)arg); | ||
349 | case WDIOC_SETOPTIONS: | ||
350 | if (get_user(options, (int *)arg)) | ||
351 | return -EFAULT; | ||
352 | |||
353 | if (options & WDIOS_DISABLECARD) { | ||
354 | sh_wdt_stop(); | ||
355 | retval = 0; | ||
356 | } | ||
357 | 360 | ||
358 | if (options & WDIOS_ENABLECARD) { | 361 | if (sh_wdt_set_heartbeat(new_heartbeat)) |
359 | sh_wdt_start(); | 362 | return -EINVAL; |
360 | retval = 0; | ||
361 | } | ||
362 | 363 | ||
363 | return retval; | 364 | sh_wdt_keepalive(); |
364 | default: | 365 | /* Fall */ |
365 | return -ENOTTY; | 366 | case WDIOC_GETTIMEOUT: |
366 | } | 367 | return put_user(heartbeat, (int *)arg); |
368 | case WDIOC_SETOPTIONS: | ||
369 | if (get_user(options, (int *)arg)) | ||
370 | return -EFAULT; | ||
371 | |||
372 | if (options & WDIOS_DISABLECARD) { | ||
373 | sh_wdt_stop(); | ||
374 | retval = 0; | ||
375 | } | ||
376 | |||
377 | if (options & WDIOS_ENABLECARD) { | ||
378 | sh_wdt_start(); | ||
379 | retval = 0; | ||
380 | } | ||
367 | 381 | ||
382 | return retval; | ||
383 | default: | ||
384 | return -ENOTTY; | ||
385 | } | ||
368 | return 0; | 386 | return 0; |
369 | } | 387 | } |
370 | 388 | ||
@@ -390,13 +408,13 @@ static const struct file_operations sh_wdt_fops = { | |||
390 | .owner = THIS_MODULE, | 408 | .owner = THIS_MODULE, |
391 | .llseek = no_llseek, | 409 | .llseek = no_llseek, |
392 | .write = sh_wdt_write, | 410 | .write = sh_wdt_write, |
393 | .ioctl = sh_wdt_ioctl, | 411 | .unlocked_ioctl = sh_wdt_ioctl, |
394 | .open = sh_wdt_open, | 412 | .open = sh_wdt_open, |
395 | .release = sh_wdt_close, | 413 | .release = sh_wdt_close, |
396 | .mmap = sh_wdt_mmap, | 414 | .mmap = sh_wdt_mmap, |
397 | }; | 415 | }; |
398 | 416 | ||
399 | static struct watchdog_info sh_wdt_info = { | 417 | static const struct watchdog_info sh_wdt_info = { |
400 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 418 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
401 | WDIOF_MAGICCLOSE, | 419 | WDIOF_MAGICCLOSE, |
402 | .firmware_version = 1, | 420 | .firmware_version = 1, |
@@ -422,30 +440,33 @@ static int __init sh_wdt_init(void) | |||
422 | { | 440 | { |
423 | int rc; | 441 | int rc; |
424 | 442 | ||
425 | if ((clock_division_ratio < 0x5) || (clock_division_ratio > 0x7)) { | 443 | if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) { |
426 | clock_division_ratio = WTCSR_CKS_4096; | 444 | clock_division_ratio = WTCSR_CKS_4096; |
427 | printk(KERN_INFO PFX "clock_division_ratio value must " | 445 | printk(KERN_INFO PFX |
428 | "be 0x5<=x<=0x7, using %d\n", clock_division_ratio); | 446 | "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n", |
447 | clock_division_ratio); | ||
429 | } | 448 | } |
430 | 449 | ||
431 | rc = sh_wdt_set_heartbeat(heartbeat); | 450 | rc = sh_wdt_set_heartbeat(heartbeat); |
432 | if (unlikely(rc)) { | 451 | if (unlikely(rc)) { |
433 | heartbeat = WATCHDOG_HEARTBEAT; | 452 | heartbeat = WATCHDOG_HEARTBEAT; |
434 | printk(KERN_INFO PFX "heartbeat value must " | 453 | printk(KERN_INFO PFX |
435 | "be 1<=x<=3600, using %d\n", heartbeat); | 454 | "heartbeat value must be 1<=x<=3600, using %d\n", |
455 | heartbeat); | ||
436 | } | 456 | } |
437 | 457 | ||
438 | rc = register_reboot_notifier(&sh_wdt_notifier); | 458 | rc = register_reboot_notifier(&sh_wdt_notifier); |
439 | if (unlikely(rc)) { | 459 | if (unlikely(rc)) { |
440 | printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", | 460 | printk(KERN_ERR PFX |
441 | rc); | 461 | "Can't register reboot notifier (err=%d)\n", rc); |
442 | return rc; | 462 | return rc; |
443 | } | 463 | } |
444 | 464 | ||
445 | rc = misc_register(&sh_wdt_miscdev); | 465 | rc = misc_register(&sh_wdt_miscdev); |
446 | if (unlikely(rc)) { | 466 | if (unlikely(rc)) { |
447 | printk(KERN_ERR PFX "Can't register miscdev on " | 467 | printk(KERN_ERR PFX |
448 | "minor=%d (err=%d)\n", sh_wdt_miscdev.minor, rc); | 468 | "Can't register miscdev on minor=%d (err=%d)\n", |
469 | sh_wdt_miscdev.minor, rc); | ||
449 | unregister_reboot_notifier(&sh_wdt_notifier); | 470 | unregister_reboot_notifier(&sh_wdt_notifier); |
450 | return rc; | 471 | return rc; |
451 | } | 472 | } |
@@ -476,10 +497,14 @@ module_param(clock_division_ratio, int, 0); | |||
476 | MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); | 497 | MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); |
477 | 498 | ||
478 | module_param(heartbeat, int, 0); | 499 | module_param(heartbeat, int, 0); |
479 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<=heartbeat<=3600, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 500 | MODULE_PARM_DESC(heartbeat, |
501 | "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=" | ||
502 | __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | ||
480 | 503 | ||
481 | module_param(nowayout, int, 0); | 504 | module_param(nowayout, int, 0); |
482 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 505 | MODULE_PARM_DESC(nowayout, |
506 | "Watchdog cannot be stopped once started (default=" | ||
507 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
483 | 508 | ||
484 | module_init(sh_wdt_init); | 509 | module_init(sh_wdt_init); |
485 | module_exit(sh_wdt_exit); | 510 | module_exit(sh_wdt_exit); |
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 5d2b5ba61414..b7c6394b7d70 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * History: | 18 | * History: |
19 | * 2003 - Created version 1.0 for Linux 2.4.x. | 19 | * 2003 - Created version 1.0 for Linux 2.4.x. |
20 | * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE | 20 | * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE |
21 | * features. Released version 1.1 | 21 | * features. Released version 1.1 |
22 | * | 22 | * |
23 | * Theory of operation: | 23 | * Theory of operation: |
24 | * | 24 | * |
@@ -55,9 +55,9 @@ | |||
55 | #include <linux/reboot.h> | 55 | #include <linux/reboot.h> |
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/spinlock.h> | 57 | #include <linux/spinlock.h> |
58 | #include <linux/io.h> | ||
59 | #include <linux/uaccess.h> | ||
58 | 60 | ||
59 | #include <asm/io.h> | ||
60 | #include <asm/uaccess.h> | ||
61 | #include <asm/system.h> | 61 | #include <asm/system.h> |
62 | 62 | ||
63 | /* enable support for minutes as units? */ | 63 | /* enable support for minutes as units? */ |
@@ -71,15 +71,15 @@ | |||
71 | #define UNIT_MINUTE 1 | 71 | #define UNIT_MINUTE 1 |
72 | 72 | ||
73 | #define MODNAME "smsc37b787_wdt: " | 73 | #define MODNAME "smsc37b787_wdt: " |
74 | #define VERSION "1.1" | 74 | #define VERSION "1.1" |
75 | 75 | ||
76 | #define IOPORT 0x3F0 | 76 | #define IOPORT 0x3F0 |
77 | #define IOPORT_SIZE 2 | 77 | #define IOPORT_SIZE 2 |
78 | #define IODEV_NO 8 | 78 | #define IODEV_NO 8 |
79 | 79 | ||
80 | static int unit = UNIT_SECOND; /* timer's unit */ | 80 | static int unit = UNIT_SECOND; /* timer's unit */ |
81 | static int timeout = 60; /* timeout value: default is 60 "units" */ | 81 | static int timeout = 60; /* timeout value: default is 60 "units" */ |
82 | static unsigned long timer_enabled = 0; /* is the timer enabled? */ | 82 | static unsigned long timer_enabled; /* is the timer enabled? */ |
83 | 83 | ||
84 | static char expect_close; /* is the close expected? */ | 84 | static char expect_close; /* is the close expected? */ |
85 | 85 | ||
@@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
93 | 93 | ||
94 | static inline void open_io_config(void) | 94 | static inline void open_io_config(void) |
95 | { | 95 | { |
96 | outb(0x55, IOPORT); | 96 | outb(0x55, IOPORT); |
97 | mdelay(1); | 97 | mdelay(1); |
98 | outb(0x55, IOPORT); | 98 | outb(0x55, IOPORT); |
99 | } | 99 | } |
100 | 100 | ||
101 | /* lock the IO chip */ | 101 | /* lock the IO chip */ |
102 | static inline void close_io_config(void) | 102 | static inline void close_io_config(void) |
103 | { | 103 | { |
104 | outb(0xAA, IOPORT); | 104 | outb(0xAA, IOPORT); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* select the IO device */ | 107 | /* select the IO device */ |
108 | static inline void select_io_device(unsigned char devno) | 108 | static inline void select_io_device(unsigned char devno) |
109 | { | 109 | { |
110 | outb(0x07, IOPORT); | 110 | outb(0x07, IOPORT); |
111 | outb(devno, IOPORT+1); | 111 | outb(devno, IOPORT+1); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* write to the control register */ | 114 | /* write to the control register */ |
115 | static inline void write_io_cr(unsigned char reg, unsigned char data) | 115 | static inline void write_io_cr(unsigned char reg, unsigned char data) |
116 | { | 116 | { |
117 | outb(reg, IOPORT); | 117 | outb(reg, IOPORT); |
118 | outb(data, IOPORT+1); | 118 | outb(data, IOPORT+1); |
119 | } | 119 | } |
120 | 120 | ||
121 | /* read from the control register */ | 121 | /* read from the control register */ |
122 | static inline char read_io_cr(unsigned char reg) | 122 | static inline char read_io_cr(unsigned char reg) |
123 | { | 123 | { |
124 | outb(reg, IOPORT); | 124 | outb(reg, IOPORT); |
125 | return inb(IOPORT+1); | 125 | return inb(IOPORT+1); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* -- Medium level functions ------------------------------------*/ | 128 | /* -- Medium level functions ------------------------------------*/ |
129 | 129 | ||
130 | static inline void gpio_bit12(unsigned char reg) | 130 | static inline void gpio_bit12(unsigned char reg) |
131 | { | 131 | { |
132 | // -- General Purpose I/O Bit 1.2 -- | 132 | /* -- General Purpose I/O Bit 1.2 -- |
133 | // Bit 0, In/Out: 0 = Output, 1 = Input | 133 | * Bit 0, In/Out: 0 = Output, 1 = Input |
134 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | 134 | * Bit 1, Polarity: 0 = No Invert, 1 = Invert |
135 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | 135 | * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable |
136 | // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, | 136 | * Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, |
137 | // 11 = Either Edge Triggered Intr. 2 | 137 | * 11 = Either Edge Triggered Intr. 2 |
138 | // Bit 5/6 (Reserved) | 138 | * Bit 5/6 (Reserved) |
139 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | 139 | * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain |
140 | write_io_cr(0xE2, reg); | 140 | */ |
141 | write_io_cr(0xE2, reg); | ||
141 | } | 142 | } |
142 | 143 | ||
143 | static inline void gpio_bit13(unsigned char reg) | 144 | static inline void gpio_bit13(unsigned char reg) |
144 | { | 145 | { |
145 | // -- General Purpose I/O Bit 1.3 -- | 146 | /* -- General Purpose I/O Bit 1.3 -- |
146 | // Bit 0, In/Out: 0 = Output, 1 = Input | 147 | * Bit 0, In/Out: 0 = Output, 1 = Input |
147 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | 148 | * Bit 1, Polarity: 0 = No Invert, 1 = Invert |
148 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | 149 | * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable |
149 | // Bit 3, Function select: 0 = GPI/O, 1 = LED | 150 | * Bit 3, Function select: 0 = GPI/O, 1 = LED |
150 | // Bit 4-6 (Reserved) | 151 | * Bit 4-6 (Reserved) |
151 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | 152 | * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain |
152 | write_io_cr(0xE3, reg); | 153 | */ |
154 | write_io_cr(0xE3, reg); | ||
153 | } | 155 | } |
154 | 156 | ||
155 | static inline void wdt_timer_units(unsigned char new_units) | 157 | static inline void wdt_timer_units(unsigned char new_units) |
156 | { | 158 | { |
157 | // -- Watchdog timer units -- | 159 | /* -- Watchdog timer units -- |
158 | // Bit 0-6 (Reserved) | 160 | * Bit 0-6 (Reserved) |
159 | // Bit 7, WDT Time-out Value Units Select | 161 | * Bit 7, WDT Time-out Value Units Select |
160 | // (0 = Minutes, 1 = Seconds) | 162 | * (0 = Minutes, 1 = Seconds) |
161 | write_io_cr(0xF1, new_units); | 163 | */ |
164 | write_io_cr(0xF1, new_units); | ||
162 | } | 165 | } |
163 | 166 | ||
164 | static inline void wdt_timeout_value(unsigned char new_timeout) | 167 | static inline void wdt_timeout_value(unsigned char new_timeout) |
165 | { | 168 | { |
166 | // -- Watchdog Timer Time-out Value -- | 169 | /* -- Watchdog Timer Time-out Value -- |
167 | // Bit 0-7 Binary coded units (0=Disabled, 1..255) | 170 | * Bit 0-7 Binary coded units (0=Disabled, 1..255) |
168 | write_io_cr(0xF2, new_timeout); | 171 | */ |
172 | write_io_cr(0xF2, new_timeout); | ||
169 | } | 173 | } |
170 | 174 | ||
171 | static inline void wdt_timer_conf(unsigned char conf) | 175 | static inline void wdt_timer_conf(unsigned char conf) |
172 | { | 176 | { |
173 | // -- Watchdog timer configuration -- | 177 | /* -- Watchdog timer configuration -- |
174 | // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O | 178 | * Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon |
175 | // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. | 179 | * Gameport I/O |
176 | // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. | 180 | * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. |
177 | // Bit 3 Reset the timer | 181 | * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr |
178 | // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) | 182 | * Bit 3 Reset the timer |
179 | // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, | 183 | * (Wrong in SMsC documentation? Given as: PowerLED Timout |
180 | // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | 184 | * Enabled) |
181 | write_io_cr(0xF3, conf); | 185 | * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, |
186 | * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | ||
187 | */ | ||
188 | write_io_cr(0xF3, conf); | ||
182 | } | 189 | } |
183 | 190 | ||
184 | static inline void wdt_timer_ctrl(unsigned char reg) | 191 | static inline void wdt_timer_ctrl(unsigned char reg) |
185 | { | 192 | { |
186 | // -- Watchdog timer control -- | 193 | /* -- Watchdog timer control -- |
187 | // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured | 194 | * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured |
188 | // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz | 195 | * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz |
189 | // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) | 196 | * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) |
190 | // Bit 3 P20 Force Timeout enabled: | 197 | * Bit 3 P20 Force Timeout enabled: |
191 | // 0 = P20 activity does not generate the WD timeout event | 198 | * 0 = P20 activity does not generate the WD timeout event |
192 | // 1 = P20 Allows rising edge of P20, from the keyboard | 199 | * 1 = P20 Allows rising edge of P20, from the keyboard |
193 | // controller, to force the WD timeout event. | 200 | * controller, to force the WD timeout event. |
194 | // Bit 4 (Reserved) | 201 | * Bit 4 (Reserved) |
195 | // -- Soft power management -- | 202 | * -- Soft power management -- |
196 | // Bit 5 Stop Counter: 1 = Stop software power down counter | 203 | * Bit 5 Stop Counter: 1 = Stop software power down counter |
197 | // set via register 0xB8, (self-cleaning) | 204 | * set via register 0xB8, (self-cleaning) |
198 | // (Upon read: 0 = Counter running, 1 = Counter stopped) | 205 | * (Upon read: 0 = Counter running, 1 = Counter stopped) |
199 | // Bit 6 Restart Counter: 1 = Restart software power down counter | 206 | * Bit 6 Restart Counter: 1 = Restart software power down counter |
200 | // set via register 0xB8, (self-cleaning) | 207 | * set via register 0xB8, (self-cleaning) |
201 | // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) | 208 | * Bit 7 SPOFF: 1 = Force software power down (self-cleaning) |
202 | 209 | */ | |
203 | write_io_cr(0xF4, reg); | 210 | write_io_cr(0xF4, reg); |
204 | } | 211 | } |
205 | 212 | ||
206 | /* -- Higher level functions ------------------------------------*/ | 213 | /* -- Higher level functions ------------------------------------*/ |
@@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg) | |||
209 | 216 | ||
210 | static void wb_smsc_wdt_initialize(void) | 217 | static void wb_smsc_wdt_initialize(void) |
211 | { | 218 | { |
212 | unsigned char old; | 219 | unsigned char old; |
213 | 220 | ||
214 | spin_lock(&io_lock); | 221 | spin_lock(&io_lock); |
215 | open_io_config(); | 222 | open_io_config(); |
216 | select_io_device(IODEV_NO); | 223 | select_io_device(IODEV_NO); |
217 | 224 | ||
218 | // enable the watchdog | 225 | /* enable the watchdog */ |
219 | gpio_bit13(0x08); // Select pin 80 = LED not GPIO | 226 | gpio_bit13(0x08); /* Select pin 80 = LED not GPIO */ |
220 | gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert | 227 | gpio_bit12(0x0A); /* Set pin 79 = WDT not |
228 | GPIO/Output/Polarity=Invert */ | ||
229 | /* disable the timeout */ | ||
230 | wdt_timeout_value(0); | ||
221 | 231 | ||
222 | // disable the timeout | 232 | /* reset control register */ |
223 | wdt_timeout_value(0); | 233 | wdt_timer_ctrl(0x00); |
224 | 234 | ||
225 | // reset control register | 235 | /* reset configuration register */ |
226 | wdt_timer_ctrl(0x00); | ||
227 | |||
228 | // reset configuration register | ||
229 | wdt_timer_conf(0x00); | 236 | wdt_timer_conf(0x00); |
230 | 237 | ||
231 | // read old (timer units) register | 238 | /* read old (timer units) register */ |
232 | old = read_io_cr(0xF1) & 0x7F; | 239 | old = read_io_cr(0xF1) & 0x7F; |
233 | if (unit == UNIT_SECOND) old |= 0x80; // set to seconds | 240 | if (unit == UNIT_SECOND) |
241 | old |= 0x80; /* set to seconds */ | ||
234 | 242 | ||
235 | // set the watchdog timer units | 243 | /* set the watchdog timer units */ |
236 | wdt_timer_units(old); | 244 | wdt_timer_units(old); |
237 | 245 | ||
238 | close_io_config(); | 246 | close_io_config(); |
239 | spin_unlock(&io_lock); | 247 | spin_unlock(&io_lock); |
240 | } | 248 | } |
241 | 249 | ||
@@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void) | |||
244 | static void wb_smsc_wdt_shutdown(void) | 252 | static void wb_smsc_wdt_shutdown(void) |
245 | { | 253 | { |
246 | spin_lock(&io_lock); | 254 | spin_lock(&io_lock); |
247 | open_io_config(); | 255 | open_io_config(); |
248 | select_io_device(IODEV_NO); | 256 | select_io_device(IODEV_NO); |
249 | 257 | ||
250 | // disable the watchdog | 258 | /* disable the watchdog */ |
251 | gpio_bit13(0x09); | 259 | gpio_bit13(0x09); |
252 | gpio_bit12(0x09); | 260 | gpio_bit12(0x09); |
253 | 261 | ||
254 | // reset watchdog config register | 262 | /* reset watchdog config register */ |
255 | wdt_timer_conf(0x00); | 263 | wdt_timer_conf(0x00); |
256 | 264 | ||
257 | // reset watchdog control register | 265 | /* reset watchdog control register */ |
258 | wdt_timer_ctrl(0x00); | 266 | wdt_timer_ctrl(0x00); |
259 | 267 | ||
260 | // disable timeout | 268 | /* disable timeout */ |
261 | wdt_timeout_value(0x00); | 269 | wdt_timeout_value(0x00); |
262 | 270 | ||
263 | close_io_config(); | 271 | close_io_config(); |
264 | spin_unlock(&io_lock); | 272 | spin_unlock(&io_lock); |
265 | } | 273 | } |
266 | 274 | ||
@@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void) | |||
269 | static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) | 277 | static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) |
270 | { | 278 | { |
271 | spin_lock(&io_lock); | 279 | spin_lock(&io_lock); |
272 | open_io_config(); | 280 | open_io_config(); |
273 | select_io_device(IODEV_NO); | 281 | select_io_device(IODEV_NO); |
274 | 282 | ||
275 | // set Power LED to blink, if we enable the timeout | 283 | /* set Power LED to blink, if we enable the timeout */ |
276 | wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); | 284 | wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); |
277 | 285 | ||
278 | // set timeout value | 286 | /* set timeout value */ |
279 | wdt_timeout_value(new_timeout); | 287 | wdt_timeout_value(new_timeout); |
280 | 288 | ||
281 | close_io_config(); | 289 | close_io_config(); |
282 | spin_unlock(&io_lock); | 290 | spin_unlock(&io_lock); |
283 | } | 291 | } |
284 | 292 | ||
@@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) | |||
286 | 294 | ||
287 | static unsigned char wb_smsc_wdt_get_timeout(void) | 295 | static unsigned char wb_smsc_wdt_get_timeout(void) |
288 | { | 296 | { |
289 | unsigned char set_timeout; | 297 | unsigned char set_timeout; |
290 | 298 | ||
291 | spin_lock(&io_lock); | 299 | spin_lock(&io_lock); |
292 | open_io_config(); | 300 | open_io_config(); |
293 | select_io_device(IODEV_NO); | 301 | select_io_device(IODEV_NO); |
294 | set_timeout = read_io_cr(0xF2); | 302 | set_timeout = read_io_cr(0xF2); |
295 | close_io_config(); | 303 | close_io_config(); |
296 | spin_unlock(&io_lock); | 304 | spin_unlock(&io_lock); |
297 | 305 | ||
298 | return set_timeout; | 306 | return set_timeout; |
299 | } | 307 | } |
300 | 308 | ||
301 | /* disable watchdog */ | 309 | /* disable watchdog */ |
302 | 310 | ||
303 | static void wb_smsc_wdt_disable(void) | 311 | static void wb_smsc_wdt_disable(void) |
304 | { | 312 | { |
305 | // set the timeout to 0 to disable the watchdog | 313 | /* set the timeout to 0 to disable the watchdog */ |
306 | wb_smsc_wdt_set_timeout(0); | 314 | wb_smsc_wdt_set_timeout(0); |
307 | } | 315 | } |
308 | 316 | ||
309 | /* enable watchdog by setting the current timeout */ | 317 | /* enable watchdog by setting the current timeout */ |
310 | 318 | ||
311 | static void wb_smsc_wdt_enable(void) | 319 | static void wb_smsc_wdt_enable(void) |
312 | { | 320 | { |
313 | // set the current timeout... | 321 | /* set the current timeout... */ |
314 | wb_smsc_wdt_set_timeout(timeout); | 322 | wb_smsc_wdt_set_timeout(timeout); |
315 | } | 323 | } |
316 | 324 | ||
317 | /* reset the timer */ | 325 | /* reset the timer */ |
@@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void) | |||
319 | static void wb_smsc_wdt_reset_timer(void) | 327 | static void wb_smsc_wdt_reset_timer(void) |
320 | { | 328 | { |
321 | spin_lock(&io_lock); | 329 | spin_lock(&io_lock); |
322 | open_io_config(); | 330 | open_io_config(); |
323 | select_io_device(IODEV_NO); | 331 | select_io_device(IODEV_NO); |
324 | 332 | ||
325 | // reset the timer | 333 | /* reset the timer */ |
326 | wdt_timeout_value(timeout); | 334 | wdt_timeout_value(timeout); |
327 | wdt_timer_conf(0x08); | 335 | wdt_timer_conf(0x08); |
328 | 336 | ||
329 | close_io_config(); | 337 | close_io_config(); |
330 | spin_unlock(&io_lock); | 338 | spin_unlock(&io_lock); |
331 | } | 339 | } |
332 | 340 | ||
@@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file) | |||
355 | /* Reload and activate timer */ | 363 | /* Reload and activate timer */ |
356 | wb_smsc_wdt_enable(); | 364 | wb_smsc_wdt_enable(); |
357 | 365 | ||
358 | printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | 366 | printk(KERN_INFO MODNAME |
367 | "Watchdog enabled. Timeout set to %d %s.\n", | ||
368 | timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | ||
359 | 369 | ||
360 | return nonseekable_open(inode, file); | 370 | return nonseekable_open(inode, file); |
361 | } | 371 | } |
@@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file) | |||
367 | /* Shut off the timer. */ | 377 | /* Shut off the timer. */ |
368 | 378 | ||
369 | if (expect_close == 42) { | 379 | if (expect_close == 42) { |
370 | wb_smsc_wdt_disable(); | 380 | wb_smsc_wdt_disable(); |
371 | printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); | 381 | printk(KERN_INFO MODNAME |
382 | "Watchdog disabled, sleeping again...\n"); | ||
372 | } else { | 383 | } else { |
373 | printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); | 384 | printk(KERN_CRIT MODNAME |
385 | "Unexpected close, not stopping watchdog!\n"); | ||
374 | wb_smsc_wdt_reset_timer(); | 386 | wb_smsc_wdt_reset_timer(); |
375 | } | 387 | } |
376 | 388 | ||
@@ -392,7 +404,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, | |||
392 | /* reset expect flag */ | 404 | /* reset expect flag */ |
393 | expect_close = 0; | 405 | expect_close = 0; |
394 | 406 | ||
395 | /* scan to see whether or not we got the magic character */ | 407 | /* scan to see whether or not we got the |
408 | magic character */ | ||
396 | for (i = 0; i != len; i++) { | 409 | for (i = 0; i != len; i++) { |
397 | char c; | 410 | char c; |
398 | if (get_user(c, data+i)) | 411 | if (get_user(c, data+i)) |
@@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, | |||
410 | 423 | ||
411 | /* ioctl => control interface */ | 424 | /* ioctl => control interface */ |
412 | 425 | ||
413 | static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | 426 | static long wb_smsc_wdt_ioctl(struct file *file, |
414 | unsigned int cmd, unsigned long arg) | 427 | unsigned int cmd, unsigned long arg) |
415 | { | 428 | { |
416 | int new_timeout; | 429 | int new_timeout; |
417 | 430 | ||
@@ -420,9 +433,9 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | |||
420 | int __user *i; | 433 | int __user *i; |
421 | } uarg; | 434 | } uarg; |
422 | 435 | ||
423 | static struct watchdog_info ident = { | 436 | static const struct watchdog_info ident = { |
424 | .options = WDIOF_KEEPALIVEPING | | 437 | .options = WDIOF_KEEPALIVEPING | |
425 | WDIOF_SETTIMEOUT | | 438 | WDIOF_SETTIMEOUT | |
426 | WDIOF_MAGICCLOSE, | 439 | WDIOF_MAGICCLOSE, |
427 | .firmware_version = 0, | 440 | .firmware_version = 0, |
428 | .identity = "SMsC 37B787 Watchdog" | 441 | .identity = "SMsC 37B787 Watchdog" |
@@ -431,78 +444,62 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | |||
431 | uarg.i = (int __user *)arg; | 444 | uarg.i = (int __user *)arg; |
432 | 445 | ||
433 | switch (cmd) { | 446 | switch (cmd) { |
434 | default: | 447 | case WDIOC_GETSUPPORT: |
435 | return -ENOTTY; | 448 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) |
436 | 449 | ? -EFAULT : 0; | |
437 | case WDIOC_GETSUPPORT: | 450 | case WDIOC_GETSTATUS: |
438 | return copy_to_user(uarg.ident, &ident, | 451 | return put_user(wb_smsc_wdt_status(), uarg.i); |
439 | sizeof(ident)) ? -EFAULT : 0; | 452 | case WDIOC_GETBOOTSTATUS: |
440 | 453 | return put_user(0, uarg.i); | |
441 | case WDIOC_GETSTATUS: | 454 | case WDIOC_KEEPALIVE: |
442 | return put_user(wb_smsc_wdt_status(), uarg.i); | 455 | wb_smsc_wdt_reset_timer(); |
443 | 456 | return 0; | |
444 | case WDIOC_GETBOOTSTATUS: | 457 | case WDIOC_SETTIMEOUT: |
445 | return put_user(0, uarg.i); | 458 | if (get_user(new_timeout, uarg.i)) |
446 | 459 | return -EFAULT; | |
447 | case WDIOC_KEEPALIVE: | 460 | /* the API states this is given in secs */ |
448 | wb_smsc_wdt_reset_timer(); | 461 | if (unit == UNIT_MINUTE) |
449 | return 0; | 462 | new_timeout /= 60; |
450 | 463 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | |
451 | case WDIOC_SETTIMEOUT: | 464 | return -EINVAL; |
452 | if (get_user(new_timeout, uarg.i)) | 465 | timeout = new_timeout; |
453 | return -EFAULT; | 466 | wb_smsc_wdt_set_timeout(timeout); |
454 | 467 | /* fall through and return the new timeout... */ | |
455 | // the API states this is given in secs | 468 | case WDIOC_GETTIMEOUT: |
456 | if (unit == UNIT_MINUTE) | 469 | new_timeout = timeout; |
457 | new_timeout /= 60; | 470 | if (unit == UNIT_MINUTE) |
458 | |||
459 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
460 | return -EINVAL; | ||
461 | |||
462 | timeout = new_timeout; | ||
463 | wb_smsc_wdt_set_timeout(timeout); | ||
464 | |||
465 | // fall through and return the new timeout... | ||
466 | |||
467 | case WDIOC_GETTIMEOUT: | ||
468 | |||
469 | new_timeout = timeout; | ||
470 | |||
471 | if (unit == UNIT_MINUTE) | ||
472 | new_timeout *= 60; | 471 | new_timeout *= 60; |
472 | return put_user(new_timeout, uarg.i); | ||
473 | case WDIOC_SETOPTIONS: | ||
474 | { | ||
475 | int options, retval = -EINVAL; | ||
473 | 476 | ||
474 | return put_user(new_timeout, uarg.i); | 477 | if (get_user(options, uarg.i)) |
475 | 478 | return -EFAULT; | |
476 | case WDIOC_SETOPTIONS: | ||
477 | { | ||
478 | int options, retval = -EINVAL; | ||
479 | |||
480 | if (get_user(options, uarg.i)) | ||
481 | return -EFAULT; | ||
482 | |||
483 | if (options & WDIOS_DISABLECARD) { | ||
484 | wb_smsc_wdt_disable(); | ||
485 | retval = 0; | ||
486 | } | ||
487 | |||
488 | if (options & WDIOS_ENABLECARD) { | ||
489 | wb_smsc_wdt_enable(); | ||
490 | retval = 0; | ||
491 | } | ||
492 | 479 | ||
493 | return retval; | 480 | if (options & WDIOS_DISABLECARD) { |
481 | wb_smsc_wdt_disable(); | ||
482 | retval = 0; | ||
494 | } | 483 | } |
484 | if (options & WDIOS_ENABLECARD) { | ||
485 | wb_smsc_wdt_enable(); | ||
486 | retval = 0; | ||
487 | } | ||
488 | return retval; | ||
489 | } | ||
490 | default: | ||
491 | return -ENOTTY; | ||
495 | } | 492 | } |
496 | } | 493 | } |
497 | 494 | ||
498 | /* -- Notifier funtions -----------------------------------------*/ | 495 | /* -- Notifier funtions -----------------------------------------*/ |
499 | 496 | ||
500 | static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 497 | static int wb_smsc_wdt_notify_sys(struct notifier_block *this, |
498 | unsigned long code, void *unused) | ||
501 | { | 499 | { |
502 | if (code == SYS_DOWN || code == SYS_HALT) | 500 | if (code == SYS_DOWN || code == SYS_HALT) { |
503 | { | 501 | /* set timeout to 0, to avoid possible race-condition */ |
504 | // set timeout to 0, to avoid possible race-condition | 502 | timeout = 0; |
505 | timeout = 0; | ||
506 | wb_smsc_wdt_disable(); | 503 | wb_smsc_wdt_disable(); |
507 | } | 504 | } |
508 | return NOTIFY_DONE; | 505 | return NOTIFY_DONE; |
@@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod | |||
510 | 507 | ||
511 | /* -- Module's structures ---------------------------------------*/ | 508 | /* -- Module's structures ---------------------------------------*/ |
512 | 509 | ||
513 | static const struct file_operations wb_smsc_wdt_fops = | 510 | static const struct file_operations wb_smsc_wdt_fops = { |
514 | { | 511 | .owner = THIS_MODULE, |
515 | .owner = THIS_MODULE, | ||
516 | .llseek = no_llseek, | 512 | .llseek = no_llseek, |
517 | .write = wb_smsc_wdt_write, | 513 | .write = wb_smsc_wdt_write, |
518 | .ioctl = wb_smsc_wdt_ioctl, | 514 | .unlocked_ioctl = wb_smsc_wdt_ioctl, |
519 | .open = wb_smsc_wdt_open, | 515 | .open = wb_smsc_wdt_open, |
520 | .release = wb_smsc_wdt_release, | 516 | .release = wb_smsc_wdt_release, |
521 | }; | 517 | }; |
522 | 518 | ||
523 | static struct notifier_block wb_smsc_wdt_notifier = | 519 | static struct notifier_block wb_smsc_wdt_notifier = { |
524 | { | ||
525 | .notifier_call = wb_smsc_wdt_notify_sys, | 520 | .notifier_call = wb_smsc_wdt_notify_sys, |
526 | }; | 521 | }; |
527 | 522 | ||
528 | static struct miscdevice wb_smsc_wdt_miscdev = | 523 | static struct miscdevice wb_smsc_wdt_miscdev = { |
529 | { | ||
530 | .minor = WATCHDOG_MINOR, | 524 | .minor = WATCHDOG_MINOR, |
531 | .name = "watchdog", | 525 | .name = "watchdog", |
532 | .fops = &wb_smsc_wdt_fops, | 526 | .fops = &wb_smsc_wdt_fops, |
@@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void) | |||
540 | { | 534 | { |
541 | int ret; | 535 | int ret; |
542 | 536 | ||
543 | printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); | 537 | printk(KERN_INFO "SMsC 37B787 watchdog component driver " |
538 | VERSION " initialising...\n"); | ||
544 | 539 | ||
545 | if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { | 540 | if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { |
546 | printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); | 541 | printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", |
542 | IOPORT); | ||
547 | ret = -EBUSY; | 543 | ret = -EBUSY; |
548 | goto out_pnp; | 544 | goto out_pnp; |
549 | } | 545 | } |
550 | 546 | ||
551 | // set new maximum, if it's too big | 547 | /* set new maximum, if it's too big */ |
552 | if (timeout > MAX_TIMEOUT) | 548 | if (timeout > MAX_TIMEOUT) |
553 | timeout = MAX_TIMEOUT; | 549 | timeout = MAX_TIMEOUT; |
554 | 550 | ||
555 | // init the watchdog timer | 551 | /* init the watchdog timer */ |
556 | wb_smsc_wdt_initialize(); | 552 | wb_smsc_wdt_initialize(); |
557 | 553 | ||
558 | ret = register_reboot_notifier(&wb_smsc_wdt_notifier); | 554 | ret = register_reboot_notifier(&wb_smsc_wdt_notifier); |
559 | if (ret) { | 555 | if (ret) { |
560 | printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); | 556 | printk(KERN_ERR MODNAME |
557 | "Unable to register reboot notifier err = %d\n", ret); | ||
561 | goto out_io; | 558 | goto out_io; |
562 | } | 559 | } |
563 | 560 | ||
564 | ret = misc_register(&wb_smsc_wdt_miscdev); | 561 | ret = misc_register(&wb_smsc_wdt_miscdev); |
565 | if (ret) { | 562 | if (ret) { |
566 | printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); | 563 | printk(KERN_ERR MODNAME |
564 | "Unable to register miscdev on minor %d\n", | ||
565 | WATCHDOG_MINOR); | ||
567 | goto out_rbt; | 566 | goto out_rbt; |
568 | } | 567 | } |
569 | 568 | ||
570 | // output info | 569 | /* output info */ |
571 | printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | 570 | printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", |
572 | printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); | 571 | timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); |
573 | 572 | printk(KERN_INFO MODNAME | |
574 | // ret = 0 | 573 | "Watchdog initialized and sleeping (nowayout=%d)...\n", |
575 | 574 | nowayout); | |
576 | out_clean: | 575 | out_clean: |
577 | return ret; | 576 | return ret; |
578 | 577 | ||
@@ -591,8 +590,7 @@ out_pnp: | |||
591 | static void __exit wb_smsc_wdt_exit(void) | 590 | static void __exit wb_smsc_wdt_exit(void) |
592 | { | 591 | { |
593 | /* Stop the timer before we leave */ | 592 | /* Stop the timer before we leave */ |
594 | if (!nowayout) | 593 | if (!nowayout) { |
595 | { | ||
596 | wb_smsc_wdt_shutdown(); | 594 | wb_smsc_wdt_shutdown(); |
597 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); | 595 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); |
598 | } | 596 | } |
@@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void) | |||
601 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); | 599 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); |
602 | release_region(IOPORT, IOPORT_SIZE); | 600 | release_region(IOPORT, IOPORT_SIZE); |
603 | 601 | ||
604 | printk("SMsC 37B787 watchdog component driver removed.\n"); | 602 | printk(KERN_INFO "SMsC 37B787 watchdog component driver removed.\n"); |
605 | } | 603 | } |
606 | 604 | ||
607 | module_init(wb_smsc_wdt_init); | 605 | module_init(wb_smsc_wdt_init); |
608 | module_exit(wb_smsc_wdt_exit); | 606 | module_exit(wb_smsc_wdt_exit); |
609 | 607 | ||
610 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); | 608 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); |
611 | MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); | 609 | MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " |
610 | VERSION ")"); | ||
612 | MODULE_LICENSE("GPL"); | 611 | MODULE_LICENSE("GPL"); |
613 | 612 | ||
614 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 613 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
615 | 614 | ||
616 | #ifdef SMSC_SUPPORT_MINUTES | 615 | #ifdef SMSC_SUPPORT_MINUTES |
617 | module_param(unit, int, 0); | 616 | module_param(unit, int, 0); |
618 | MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); | 617 | MODULE_PARM_DESC(unit, |
618 | "set unit to use, 0=seconds or 1=minutes, default is 0"); | ||
619 | #endif | 619 | #endif |
620 | 620 | ||
621 | module_param(timeout, int, 0); | 621 | module_param(timeout, int, 0); |
622 | MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); | 622 | MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); |
623 | 623 | ||
624 | module_param(nowayout, int, 0); | 624 | module_param(nowayout, int, 0); |
625 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 625 | MODULE_PARM_DESC(nowayout, |
626 | "Watchdog cannot be stopped once started (default=" | ||
627 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c index 9c3694909243..bb3c75eed9df 100644 --- a/drivers/watchdog/softdog.c +++ b/drivers/watchdog/softdog.c | |||
@@ -47,19 +47,22 @@ | |||
47 | #include <linux/reboot.h> | 47 | #include <linux/reboot.h> |
48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/jiffies.h> | 49 | #include <linux/jiffies.h> |
50 | 50 | #include <linux/uaccess.h> | |
51 | #include <asm/uaccess.h> | ||
52 | 51 | ||
53 | #define PFX "SoftDog: " | 52 | #define PFX "SoftDog: " |
54 | 53 | ||
55 | #define TIMER_MARGIN 60 /* Default is 60 seconds */ | 54 | #define TIMER_MARGIN 60 /* Default is 60 seconds */ |
56 | static int soft_margin = TIMER_MARGIN; /* in seconds */ | 55 | static int soft_margin = TIMER_MARGIN; /* in seconds */ |
57 | module_param(soft_margin, int, 0); | 56 | module_param(soft_margin, int, 0); |
58 | MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); | 57 | MODULE_PARM_DESC(soft_margin, |
58 | "Watchdog soft_margin in seconds. (0 < soft_margin < 65536, default=" | ||
59 | __MODULE_STRING(TIMER_MARGIN) ")"); | ||
59 | 60 | ||
60 | static int nowayout = WATCHDOG_NOWAYOUT; | 61 | static int nowayout = WATCHDOG_NOWAYOUT; |
61 | module_param(nowayout, int, 0); | 62 | module_param(nowayout, int, 0); |
62 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 63 | MODULE_PARM_DESC(nowayout, |
64 | "Watchdog cannot be stopped once started (default=" | ||
65 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
63 | 66 | ||
64 | #ifdef ONLY_TESTING | 67 | #ifdef ONLY_TESTING |
65 | static int soft_noboot = 1; | 68 | static int soft_noboot = 1; |
@@ -93,8 +96,7 @@ static void watchdog_fire(unsigned long data) | |||
93 | 96 | ||
94 | if (soft_noboot) | 97 | if (soft_noboot) |
95 | printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); | 98 | printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); |
96 | else | 99 | else { |
97 | { | ||
98 | printk(KERN_CRIT PFX "Initiating system reboot.\n"); | 100 | printk(KERN_CRIT PFX "Initiating system reboot.\n"); |
99 | emergency_restart(); | 101 | emergency_restart(); |
100 | printk(KERN_CRIT PFX "Reboot didn't ?????\n"); | 102 | printk(KERN_CRIT PFX "Reboot didn't ?????\n"); |
@@ -153,7 +155,8 @@ static int softdog_release(struct inode *inode, struct file *file) | |||
153 | softdog_stop(); | 155 | softdog_stop(); |
154 | module_put(THIS_MODULE); | 156 | module_put(THIS_MODULE); |
155 | } else { | 157 | } else { |
156 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 158 | printk(KERN_CRIT PFX |
159 | "Unexpected close, not stopping watchdog!\n"); | ||
157 | set_bit(0, &orphan_timer); | 160 | set_bit(0, &orphan_timer); |
158 | softdog_keepalive(); | 161 | softdog_keepalive(); |
159 | } | 162 | } |
@@ -162,12 +165,13 @@ static int softdog_release(struct inode *inode, struct file *file) | |||
162 | return 0; | 165 | return 0; |
163 | } | 166 | } |
164 | 167 | ||
165 | static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 168 | static ssize_t softdog_write(struct file *file, const char __user *data, |
169 | size_t len, loff_t *ppos) | ||
166 | { | 170 | { |
167 | /* | 171 | /* |
168 | * Refresh the timer. | 172 | * Refresh the timer. |
169 | */ | 173 | */ |
170 | if(len) { | 174 | if (len) { |
171 | if (!nowayout) { | 175 | if (!nowayout) { |
172 | size_t i; | 176 | size_t i; |
173 | 177 | ||
@@ -188,13 +192,13 @@ static ssize_t softdog_write(struct file *file, const char __user *data, size_t | |||
188 | return len; | 192 | return len; |
189 | } | 193 | } |
190 | 194 | ||
191 | static int softdog_ioctl(struct inode *inode, struct file *file, | 195 | static long softdog_ioctl(struct file *file, unsigned int cmd, |
192 | unsigned int cmd, unsigned long arg) | 196 | unsigned long arg) |
193 | { | 197 | { |
194 | void __user *argp = (void __user *)arg; | 198 | void __user *argp = (void __user *)arg; |
195 | int __user *p = argp; | 199 | int __user *p = argp; |
196 | int new_margin; | 200 | int new_margin; |
197 | static struct watchdog_info ident = { | 201 | static const struct watchdog_info ident = { |
198 | .options = WDIOF_SETTIMEOUT | | 202 | .options = WDIOF_SETTIMEOUT | |
199 | WDIOF_KEEPALIVEPING | | 203 | WDIOF_KEEPALIVEPING | |
200 | WDIOF_MAGICCLOSE, | 204 | WDIOF_MAGICCLOSE, |
@@ -202,26 +206,25 @@ static int softdog_ioctl(struct inode *inode, struct file *file, | |||
202 | .identity = "Software Watchdog", | 206 | .identity = "Software Watchdog", |
203 | }; | 207 | }; |
204 | switch (cmd) { | 208 | switch (cmd) { |
205 | default: | 209 | default: |
206 | return -ENOTTY; | 210 | return -ENOTTY; |
207 | case WDIOC_GETSUPPORT: | 211 | case WDIOC_GETSUPPORT: |
208 | return copy_to_user(argp, &ident, | 212 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
209 | sizeof(ident)) ? -EFAULT : 0; | 213 | case WDIOC_GETSTATUS: |
210 | case WDIOC_GETSTATUS: | 214 | case WDIOC_GETBOOTSTATUS: |
211 | case WDIOC_GETBOOTSTATUS: | 215 | return put_user(0, p); |
212 | return put_user(0, p); | 216 | case WDIOC_KEEPALIVE: |
213 | case WDIOC_KEEPALIVE: | 217 | softdog_keepalive(); |
214 | softdog_keepalive(); | 218 | return 0; |
215 | return 0; | 219 | case WDIOC_SETTIMEOUT: |
216 | case WDIOC_SETTIMEOUT: | 220 | if (get_user(new_margin, p)) |
217 | if (get_user(new_margin, p)) | 221 | return -EFAULT; |
218 | return -EFAULT; | 222 | if (softdog_set_heartbeat(new_margin)) |
219 | if (softdog_set_heartbeat(new_margin)) | 223 | return -EINVAL; |
220 | return -EINVAL; | 224 | softdog_keepalive(); |
221 | softdog_keepalive(); | 225 | /* Fall */ |
222 | /* Fall */ | 226 | case WDIOC_GETTIMEOUT: |
223 | case WDIOC_GETTIMEOUT: | 227 | return put_user(soft_margin, p); |
224 | return put_user(soft_margin, p); | ||
225 | } | 228 | } |
226 | } | 229 | } |
227 | 230 | ||
@@ -232,10 +235,9 @@ static int softdog_ioctl(struct inode *inode, struct file *file, | |||
232 | static int softdog_notify_sys(struct notifier_block *this, unsigned long code, | 235 | static int softdog_notify_sys(struct notifier_block *this, unsigned long code, |
233 | void *unused) | 236 | void *unused) |
234 | { | 237 | { |
235 | if(code==SYS_DOWN || code==SYS_HALT) { | 238 | if (code == SYS_DOWN || code == SYS_HALT) |
236 | /* Turn the WDT off */ | 239 | /* Turn the WDT off */ |
237 | softdog_stop(); | 240 | softdog_stop(); |
238 | } | ||
239 | return NOTIFY_DONE; | 241 | return NOTIFY_DONE; |
240 | } | 242 | } |
241 | 243 | ||
@@ -247,7 +249,7 @@ static const struct file_operations softdog_fops = { | |||
247 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE, |
248 | .llseek = no_llseek, | 250 | .llseek = no_llseek, |
249 | .write = softdog_write, | 251 | .write = softdog_write, |
250 | .ioctl = softdog_ioctl, | 252 | .unlocked_ioctl = softdog_ioctl, |
251 | .open = softdog_open, | 253 | .open = softdog_open, |
252 | .release = softdog_release, | 254 | .release = softdog_release, |
253 | }; | 255 | }; |
@@ -268,24 +270,27 @@ static int __init watchdog_init(void) | |||
268 | { | 270 | { |
269 | int ret; | 271 | int ret; |
270 | 272 | ||
271 | /* Check that the soft_margin value is within it's range ; if not reset to the default */ | 273 | /* Check that the soft_margin value is within it's range; |
274 | if not reset to the default */ | ||
272 | if (softdog_set_heartbeat(soft_margin)) { | 275 | if (softdog_set_heartbeat(soft_margin)) { |
273 | softdog_set_heartbeat(TIMER_MARGIN); | 276 | softdog_set_heartbeat(TIMER_MARGIN); |
274 | printk(KERN_INFO PFX "soft_margin value must be 0<soft_margin<65536, using %d\n", | 277 | printk(KERN_INFO PFX |
278 | "soft_margin must be 0 < soft_margin < 65536, using %d\n", | ||
275 | TIMER_MARGIN); | 279 | TIMER_MARGIN); |
276 | } | 280 | } |
277 | 281 | ||
278 | ret = register_reboot_notifier(&softdog_notifier); | 282 | ret = register_reboot_notifier(&softdog_notifier); |
279 | if (ret) { | 283 | if (ret) { |
280 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 284 | printk(KERN_ERR PFX |
281 | ret); | 285 | "cannot register reboot notifier (err=%d)\n", ret); |
282 | return ret; | 286 | return ret; |
283 | } | 287 | } |
284 | 288 | ||
285 | ret = misc_register(&softdog_miscdev); | 289 | ret = misc_register(&softdog_miscdev); |
286 | if (ret) { | 290 | if (ret) { |
287 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 291 | printk(KERN_ERR PFX |
288 | WATCHDOG_MINOR, ret); | 292 | "cannot register miscdev on minor=%d (err=%d)\n", |
293 | WATCHDOG_MINOR, ret); | ||
289 | unregister_reboot_notifier(&softdog_notifier); | 294 | unregister_reboot_notifier(&softdog_notifier); |
290 | return ret; | 295 | return ret; |
291 | } | 296 | } |
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 57cefef27ce3..b729cc447df3 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
@@ -45,27 +45,34 @@ static unsigned long txx9wdt_alive; | |||
45 | static int expect_close; | 45 | static int expect_close; |
46 | static struct txx9_tmr_reg __iomem *txx9wdt_reg; | 46 | static struct txx9_tmr_reg __iomem *txx9wdt_reg; |
47 | static struct clk *txx9_imclk; | 47 | static struct clk *txx9_imclk; |
48 | static DECLARE_LOCK(txx9_lock); | ||
48 | 49 | ||
49 | static void txx9wdt_ping(void) | 50 | static void txx9wdt_ping(void) |
50 | { | 51 | { |
52 | spin_lock(&txx9_lock); | ||
51 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); | 53 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); |
54 | spin_unlock(&txx9_lock); | ||
52 | } | 55 | } |
53 | 56 | ||
54 | static void txx9wdt_start(void) | 57 | static void txx9wdt_start(void) |
55 | { | 58 | { |
59 | spin_lock(&txx9_lock); | ||
56 | __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); | 60 | __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); |
57 | __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); | 61 | __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); |
58 | __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ | 62 | __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ |
59 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, | 63 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, |
60 | &txx9wdt_reg->tcr); | 64 | &txx9wdt_reg->tcr); |
61 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); | 65 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); |
66 | spin_unlock(&txx9_lock); | ||
62 | } | 67 | } |
63 | 68 | ||
64 | static void txx9wdt_stop(void) | 69 | static void txx9wdt_stop(void) |
65 | { | 70 | { |
71 | spin_lock(&txx9_lock); | ||
66 | __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); | 72 | __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); |
67 | __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, | 73 | __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, |
68 | &txx9wdt_reg->tcr); | 74 | &txx9wdt_reg->tcr); |
75 | spin_unlock(&txx9_lock); | ||
69 | } | 76 | } |
70 | 77 | ||
71 | static int txx9wdt_open(struct inode *inode, struct file *file) | 78 | static int txx9wdt_open(struct inode *inode, struct file *file) |
@@ -120,13 +127,13 @@ static ssize_t txx9wdt_write(struct file *file, const char __user *data, | |||
120 | return len; | 127 | return len; |
121 | } | 128 | } |
122 | 129 | ||
123 | static int txx9wdt_ioctl(struct inode *inode, struct file *file, | 130 | static long txx9wdt_ioctl(struct file *file, unsigned int cmd, |
124 | unsigned int cmd, unsigned long arg) | 131 | unsigned long arg) |
125 | { | 132 | { |
126 | void __user *argp = (void __user *)arg; | 133 | void __user *argp = (void __user *)arg; |
127 | int __user *p = argp; | 134 | int __user *p = argp; |
128 | int new_timeout; | 135 | int new_timeout; |
129 | static struct watchdog_info ident = { | 136 | static const struct watchdog_info ident = { |
130 | .options = WDIOF_SETTIMEOUT | | 137 | .options = WDIOF_SETTIMEOUT | |
131 | WDIOF_KEEPALIVEPING | | 138 | WDIOF_KEEPALIVEPING | |
132 | WDIOF_MAGICCLOSE, | 139 | WDIOF_MAGICCLOSE, |
@@ -168,18 +175,18 @@ static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
168 | } | 175 | } |
169 | 176 | ||
170 | static const struct file_operations txx9wdt_fops = { | 177 | static const struct file_operations txx9wdt_fops = { |
171 | .owner = THIS_MODULE, | 178 | .owner = THIS_MODULE, |
172 | .llseek = no_llseek, | 179 | .llseek = no_llseek, |
173 | .write = txx9wdt_write, | 180 | .write = txx9wdt_write, |
174 | .ioctl = txx9wdt_ioctl, | 181 | .unlocked_ioctl = txx9wdt_ioctl, |
175 | .open = txx9wdt_open, | 182 | .open = txx9wdt_open, |
176 | .release = txx9wdt_release, | 183 | .release = txx9wdt_release, |
177 | }; | 184 | }; |
178 | 185 | ||
179 | static struct miscdevice txx9wdt_miscdev = { | 186 | static struct miscdevice txx9wdt_miscdev = { |
180 | .minor = WATCHDOG_MINOR, | 187 | .minor = WATCHDOG_MINOR, |
181 | .name = "watchdog", | 188 | .name = "watchdog", |
182 | .fops = &txx9wdt_fops, | 189 | .fops = &txx9wdt_fops, |
183 | }; | 190 | }; |
184 | 191 | ||
185 | static struct notifier_block txx9wdt_notifier = { | 192 | static struct notifier_block txx9wdt_notifier = { |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 386492821fc2..70c843f4201a 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -37,9 +37,9 @@ | |||
37 | #include <linux/reboot.h> | 37 | #include <linux/reboot.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/io.h> | ||
41 | #include <linux/uaccess.h> | ||
40 | 42 | ||
41 | #include <asm/io.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
44 | 44 | ||
45 | #define WATCHDOG_NAME "w83627hf/thf/hg WDT" | 45 | #define WATCHDOG_NAME "w83627hf/thf/hg WDT" |
@@ -57,22 +57,26 @@ MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)"); | |||
57 | 57 | ||
58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
59 | module_param(timeout, int, 0); | 59 | module_param(timeout, int, 0); |
60 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | 60 | MODULE_PARM_DESC(timeout, |
61 | "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" | ||
62 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
61 | 63 | ||
62 | static int nowayout = WATCHDOG_NOWAYOUT; | 64 | static int nowayout = WATCHDOG_NOWAYOUT; |
63 | module_param(nowayout, int, 0); | 65 | module_param(nowayout, int, 0); |
64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 66 | MODULE_PARM_DESC(nowayout, |
67 | "Watchdog cannot be stopped once started (default=" | ||
68 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
65 | 69 | ||
66 | /* | 70 | /* |
67 | * Kernel methods. | 71 | * Kernel methods. |
68 | */ | 72 | */ |
69 | 73 | ||
70 | #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ | 74 | #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ |
71 | #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ | 75 | #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register |
76 | (same as EFER) */ | ||
72 | #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ | 77 | #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ |
73 | 78 | ||
74 | static void | 79 | static void w83627hf_select_wd_register(void) |
75 | w83627hf_select_wd_register(void) | ||
76 | { | 80 | { |
77 | unsigned char c; | 81 | unsigned char c; |
78 | outb_p(0x87, WDT_EFER); /* Enter extended function mode */ | 82 | outb_p(0x87, WDT_EFER); /* Enter extended function mode */ |
@@ -93,43 +97,45 @@ w83627hf_select_wd_register(void) | |||
93 | outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ | 97 | outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ |
94 | } | 98 | } |
95 | 99 | ||
96 | static void | 100 | static void w83627hf_unselect_wd_register(void) |
97 | w83627hf_unselect_wd_register(void) | ||
98 | { | 101 | { |
99 | outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ | 102 | outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ |
100 | } | 103 | } |
101 | 104 | ||
102 | /* tyan motherboards seem to set F5 to 0x4C ? | 105 | /* tyan motherboards seem to set F5 to 0x4C ? |
103 | * So explicitly init to appropriate value. */ | 106 | * So explicitly init to appropriate value. */ |
104 | static void | 107 | |
105 | w83627hf_init(void) | 108 | static void w83627hf_init(void) |
106 | { | 109 | { |
107 | unsigned char t; | 110 | unsigned char t; |
108 | 111 | ||
109 | w83627hf_select_wd_register(); | 112 | w83627hf_select_wd_register(); |
110 | 113 | ||
111 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ | 114 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ |
112 | t=inb_p(WDT_EFDR); /* read CRF6 */ | 115 | t = inb_p(WDT_EFDR); /* read CRF6 */ |
113 | if (t != 0) { | 116 | if (t != 0) { |
114 | printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); | 117 | printk(KERN_INFO PFX |
118 | "Watchdog already running. Resetting timeout to %d sec\n", | ||
119 | timeout); | ||
115 | outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ | 120 | outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ |
116 | } | 121 | } |
117 | 122 | ||
118 | outb_p(0xF5, WDT_EFER); /* Select CRF5 */ | 123 | outb_p(0xF5, WDT_EFER); /* Select CRF5 */ |
119 | t=inb_p(WDT_EFDR); /* read CRF5 */ | 124 | t = inb_p(WDT_EFDR); /* read CRF5 */ |
120 | t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ | 125 | t &= ~0x0C; /* set second mode & disable keyboard |
126 | turning off watchdog */ | ||
121 | outb_p(t, WDT_EFDR); /* Write back to CRF5 */ | 127 | outb_p(t, WDT_EFDR); /* Write back to CRF5 */ |
122 | 128 | ||
123 | outb_p(0xF7, WDT_EFER); /* Select CRF7 */ | 129 | outb_p(0xF7, WDT_EFER); /* Select CRF7 */ |
124 | t=inb_p(WDT_EFDR); /* read CRF7 */ | 130 | t = inb_p(WDT_EFDR); /* read CRF7 */ |
125 | t&=~0xC0; /* disable keyboard & mouse turning off watchdog */ | 131 | t &= ~0xC0; /* disable keyboard & mouse turning off |
132 | watchdog */ | ||
126 | outb_p(t, WDT_EFDR); /* Write back to CRF7 */ | 133 | outb_p(t, WDT_EFDR); /* Write back to CRF7 */ |
127 | 134 | ||
128 | w83627hf_unselect_wd_register(); | 135 | w83627hf_unselect_wd_register(); |
129 | } | 136 | } |
130 | 137 | ||
131 | static void | 138 | static void wdt_ctrl(int timeout) |
132 | wdt_ctrl(int timeout) | ||
133 | { | 139 | { |
134 | spin_lock(&io_lock); | 140 | spin_lock(&io_lock); |
135 | 141 | ||
@@ -143,32 +149,28 @@ wdt_ctrl(int timeout) | |||
143 | spin_unlock(&io_lock); | 149 | spin_unlock(&io_lock); |
144 | } | 150 | } |
145 | 151 | ||
146 | static int | 152 | static int wdt_ping(void) |
147 | wdt_ping(void) | ||
148 | { | 153 | { |
149 | wdt_ctrl(timeout); | 154 | wdt_ctrl(timeout); |
150 | return 0; | 155 | return 0; |
151 | } | 156 | } |
152 | 157 | ||
153 | static int | 158 | static int wdt_disable(void) |
154 | wdt_disable(void) | ||
155 | { | 159 | { |
156 | wdt_ctrl(0); | 160 | wdt_ctrl(0); |
157 | return 0; | 161 | return 0; |
158 | } | 162 | } |
159 | 163 | ||
160 | static int | 164 | static int wdt_set_heartbeat(int t) |
161 | wdt_set_heartbeat(int t) | ||
162 | { | 165 | { |
163 | if ((t < 1) || (t > 255)) | 166 | if (t < 1 || t > 255) |
164 | return -EINVAL; | 167 | return -EINVAL; |
165 | |||
166 | timeout = t; | 168 | timeout = t; |
167 | return 0; | 169 | return 0; |
168 | } | 170 | } |
169 | 171 | ||
170 | static ssize_t | 172 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
171 | wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 173 | size_t count, loff_t *ppos) |
172 | { | 174 | { |
173 | if (count) { | 175 | if (count) { |
174 | if (!nowayout) { | 176 | if (!nowayout) { |
@@ -189,72 +191,61 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
189 | return count; | 191 | return count; |
190 | } | 192 | } |
191 | 193 | ||
192 | static int | 194 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
193 | wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
194 | unsigned long arg) | ||
195 | { | 195 | { |
196 | void __user *argp = (void __user *)arg; | 196 | void __user *argp = (void __user *)arg; |
197 | int __user *p = argp; | 197 | int __user *p = argp; |
198 | int new_timeout; | 198 | int new_timeout; |
199 | static struct watchdog_info ident = { | 199 | static struct watchdog_info ident = { |
200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
201 | WDIOF_MAGICCLOSE, | ||
201 | .firmware_version = 1, | 202 | .firmware_version = 1, |
202 | .identity = "W83627HF WDT", | 203 | .identity = "W83627HF WDT", |
203 | }; | 204 | }; |
204 | 205 | ||
205 | switch (cmd) { | 206 | switch (cmd) { |
206 | case WDIOC_GETSUPPORT: | 207 | case WDIOC_GETSUPPORT: |
207 | if (copy_to_user(argp, &ident, sizeof(ident))) | 208 | if (copy_to_user(argp, &ident, sizeof(ident))) |
208 | return -EFAULT; | 209 | return -EFAULT; |
209 | break; | 210 | break; |
210 | |||
211 | case WDIOC_GETSTATUS: | 211 | case WDIOC_GETSTATUS: |
212 | case WDIOC_GETBOOTSTATUS: | 212 | case WDIOC_GETBOOTSTATUS: |
213 | return put_user(0, p); | 213 | return put_user(0, p); |
214 | |||
215 | case WDIOC_KEEPALIVE: | 214 | case WDIOC_KEEPALIVE: |
216 | wdt_ping(); | 215 | wdt_ping(); |
217 | break; | 216 | break; |
218 | |||
219 | case WDIOC_SETTIMEOUT: | 217 | case WDIOC_SETTIMEOUT: |
220 | if (get_user(new_timeout, p)) | 218 | if (get_user(new_timeout, p)) |
221 | return -EFAULT; | 219 | return -EFAULT; |
222 | if (wdt_set_heartbeat(new_timeout)) | 220 | if (wdt_set_heartbeat(new_timeout)) |
223 | return -EINVAL; | 221 | return -EINVAL; |
224 | wdt_ping(); | 222 | wdt_ping(); |
225 | /* Fall */ | 223 | /* Fall */ |
226 | |||
227 | case WDIOC_GETTIMEOUT: | 224 | case WDIOC_GETTIMEOUT: |
228 | return put_user(timeout, p); | 225 | return put_user(timeout, p); |
229 | |||
230 | case WDIOC_SETOPTIONS: | 226 | case WDIOC_SETOPTIONS: |
231 | { | 227 | { |
232 | int options, retval = -EINVAL; | 228 | int options, retval = -EINVAL; |
233 | |||
234 | if (get_user(options, p)) | ||
235 | return -EFAULT; | ||
236 | |||
237 | if (options & WDIOS_DISABLECARD) { | ||
238 | wdt_disable(); | ||
239 | retval = 0; | ||
240 | } | ||
241 | |||
242 | if (options & WDIOS_ENABLECARD) { | ||
243 | wdt_ping(); | ||
244 | retval = 0; | ||
245 | } | ||
246 | 229 | ||
247 | return retval; | 230 | if (get_user(options, p)) |
231 | return -EFAULT; | ||
232 | if (options & WDIOS_DISABLECARD) { | ||
233 | wdt_disable(); | ||
234 | retval = 0; | ||
235 | } | ||
236 | if (options & WDIOS_ENABLECARD) { | ||
237 | wdt_ping(); | ||
238 | retval = 0; | ||
239 | } | ||
240 | return retval; | ||
248 | } | 241 | } |
249 | |||
250 | default: | 242 | default: |
251 | return -ENOTTY; | 243 | return -ENOTTY; |
252 | } | 244 | } |
253 | return 0; | 245 | return 0; |
254 | } | 246 | } |
255 | 247 | ||
256 | static int | 248 | static int wdt_open(struct inode *inode, struct file *file) |
257 | wdt_open(struct inode *inode, struct file *file) | ||
258 | { | 249 | { |
259 | if (test_and_set_bit(0, &wdt_is_open)) | 250 | if (test_and_set_bit(0, &wdt_is_open)) |
260 | return -EBUSY; | 251 | return -EBUSY; |
@@ -266,13 +257,13 @@ wdt_open(struct inode *inode, struct file *file) | |||
266 | return nonseekable_open(inode, file); | 257 | return nonseekable_open(inode, file); |
267 | } | 258 | } |
268 | 259 | ||
269 | static int | 260 | static int wdt_close(struct inode *inode, struct file *file) |
270 | wdt_close(struct inode *inode, struct file *file) | ||
271 | { | 261 | { |
272 | if (expect_close == 42) { | 262 | if (expect_close == 42) |
273 | wdt_disable(); | 263 | wdt_disable(); |
274 | } else { | 264 | else { |
275 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 265 | printk(KERN_CRIT PFX |
266 | "Unexpected close, not stopping watchdog!\n"); | ||
276 | wdt_ping(); | 267 | wdt_ping(); |
277 | } | 268 | } |
278 | expect_close = 0; | 269 | expect_close = 0; |
@@ -284,8 +275,7 @@ wdt_close(struct inode *inode, struct file *file) | |||
284 | * Notifier for system down | 275 | * Notifier for system down |
285 | */ | 276 | */ |
286 | 277 | ||
287 | static int | 278 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
288 | wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
289 | void *unused) | 279 | void *unused) |
290 | { | 280 | { |
291 | if (code == SYS_DOWN || code == SYS_HALT) { | 281 | if (code == SYS_DOWN || code == SYS_HALT) { |
@@ -303,7 +293,7 @@ static const struct file_operations wdt_fops = { | |||
303 | .owner = THIS_MODULE, | 293 | .owner = THIS_MODULE, |
304 | .llseek = no_llseek, | 294 | .llseek = no_llseek, |
305 | .write = wdt_write, | 295 | .write = wdt_write, |
306 | .ioctl = wdt_ioctl, | 296 | .unlocked_ioctl = wdt_ioctl, |
307 | .open = wdt_open, | 297 | .open = wdt_open, |
308 | .release = wdt_close, | 298 | .release = wdt_close, |
309 | }; | 299 | }; |
@@ -323,8 +313,7 @@ static struct notifier_block wdt_notifier = { | |||
323 | .notifier_call = wdt_notify_sys, | 313 | .notifier_call = wdt_notify_sys, |
324 | }; | 314 | }; |
325 | 315 | ||
326 | static int __init | 316 | static int __init wdt_init(void) |
327 | wdt_init(void) | ||
328 | { | 317 | { |
329 | int ret; | 318 | int ret; |
330 | 319 | ||
@@ -332,12 +321,13 @@ wdt_init(void) | |||
332 | 321 | ||
333 | if (wdt_set_heartbeat(timeout)) { | 322 | if (wdt_set_heartbeat(timeout)) { |
334 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 323 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
335 | printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", | 324 | printk(KERN_INFO PFX |
336 | WATCHDOG_TIMEOUT); | 325 | "timeout value must be 1 <= timeout <= 255, using %d\n", |
326 | WATCHDOG_TIMEOUT); | ||
337 | } | 327 | } |
338 | 328 | ||
339 | if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { | 329 | if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { |
340 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 330 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
341 | wdt_io); | 331 | wdt_io); |
342 | ret = -EIO; | 332 | ret = -EIO; |
343 | goto out; | 333 | goto out; |
@@ -347,20 +337,22 @@ wdt_init(void) | |||
347 | 337 | ||
348 | ret = register_reboot_notifier(&wdt_notifier); | 338 | ret = register_reboot_notifier(&wdt_notifier); |
349 | if (ret != 0) { | 339 | if (ret != 0) { |
350 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 340 | printk(KERN_ERR PFX |
351 | ret); | 341 | "cannot register reboot notifier (err=%d)\n", ret); |
352 | goto unreg_regions; | 342 | goto unreg_regions; |
353 | } | 343 | } |
354 | 344 | ||
355 | ret = misc_register(&wdt_miscdev); | 345 | ret = misc_register(&wdt_miscdev); |
356 | if (ret != 0) { | 346 | if (ret != 0) { |
357 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 347 | printk(KERN_ERR PFX |
358 | WATCHDOG_MINOR, ret); | 348 | "cannot register miscdev on minor=%d (err=%d)\n", |
349 | WATCHDOG_MINOR, ret); | ||
359 | goto unreg_reboot; | 350 | goto unreg_reboot; |
360 | } | 351 | } |
361 | 352 | ||
362 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 353 | printk(KERN_INFO PFX |
363 | timeout, nowayout); | 354 | "initialized. timeout=%d sec (nowayout=%d)\n", |
355 | timeout, nowayout); | ||
364 | 356 | ||
365 | out: | 357 | out: |
366 | return ret; | 358 | return ret; |
@@ -371,12 +363,11 @@ unreg_regions: | |||
371 | goto out; | 363 | goto out; |
372 | } | 364 | } |
373 | 365 | ||
374 | static void __exit | 366 | static void __exit wdt_exit(void) |
375 | wdt_exit(void) | ||
376 | { | 367 | { |
377 | misc_deregister(&wdt_miscdev); | 368 | misc_deregister(&wdt_miscdev); |
378 | unregister_reboot_notifier(&wdt_notifier); | 369 | unregister_reboot_notifier(&wdt_notifier); |
379 | release_region(wdt_io,1); | 370 | release_region(wdt_io, 1); |
380 | } | 371 | } |
381 | 372 | ||
382 | module_init(wdt_init); | 373 | module_init(wdt_init); |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index 528b882420b6..06ddd38675bd 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
@@ -36,9 +36,9 @@ | |||
36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/io.h> | ||
40 | #include <linux/uaccess.h> | ||
39 | 41 | ||
40 | #include <asm/io.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
43 | 43 | ||
44 | #define WATCHDOG_NAME "w83697hf/hg WDT" | 44 | #define WATCHDOG_NAME "w83697hf/hg WDT" |
@@ -53,37 +53,43 @@ static DEFINE_SPINLOCK(io_lock); | |||
53 | /* You must set this - there is no sane way to probe for this board. */ | 53 | /* You must set this - there is no sane way to probe for this board. */ |
54 | static int wdt_io = 0x2e; | 54 | static int wdt_io = 0x2e; |
55 | module_param(wdt_io, int, 0); | 55 | module_param(wdt_io, int, 0); |
56 | MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); | 56 | MODULE_PARM_DESC(wdt_io, |
57 | "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); | ||
57 | 58 | ||
58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 59 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
59 | module_param(timeout, int, 0); | 60 | module_param(timeout, int, 0); |
60 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 61 | MODULE_PARM_DESC(timeout, |
62 | "Watchdog timeout in seconds. 1<= timeout <=255 (default=" | ||
63 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
61 | 64 | ||
62 | static int nowayout = WATCHDOG_NOWAYOUT; | 65 | static int nowayout = WATCHDOG_NOWAYOUT; |
63 | module_param(nowayout, int, 0); | 66 | module_param(nowayout, int, 0); |
64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 67 | MODULE_PARM_DESC(nowayout, |
68 | "Watchdog cannot be stopped once started (default=" | ||
69 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
65 | 70 | ||
66 | static int early_disable = WATCHDOG_EARLY_DISABLE; | 71 | static int early_disable = WATCHDOG_EARLY_DISABLE; |
67 | module_param(early_disable, int, 0); | 72 | module_param(early_disable, int, 0); |
68 | MODULE_PARM_DESC(early_disable, "Watchdog gets disabled at boot time (default=" __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); | 73 | MODULE_PARM_DESC(early_disable, |
74 | "Watchdog gets disabled at boot time (default=" | ||
75 | __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); | ||
69 | 76 | ||
70 | /* | 77 | /* |
71 | * Kernel methods. | 78 | * Kernel methods. |
72 | */ | 79 | */ |
73 | 80 | ||
74 | #define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ | 81 | #define W83697HF_EFER (wdt_io + 0) /* Extended Function Enable Register */ |
75 | #define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ | 82 | #define W83697HF_EFIR (wdt_io + 0) /* Extended Function Index Register |
76 | #define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ | 83 | (same as EFER) */ |
84 | #define W83697HF_EFDR (wdt_io + 1) /* Extended Function Data Register */ | ||
77 | 85 | ||
78 | static inline void | 86 | static inline void w83697hf_unlock(void) |
79 | w83697hf_unlock(void) | ||
80 | { | 87 | { |
81 | outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ | 88 | outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ |
82 | outb_p(0x87, W83697HF_EFER); /* Again according to manual */ | 89 | outb_p(0x87, W83697HF_EFER); /* Again according to manual */ |
83 | } | 90 | } |
84 | 91 | ||
85 | static inline void | 92 | static inline void w83697hf_lock(void) |
86 | w83697hf_lock(void) | ||
87 | { | 93 | { |
88 | outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ | 94 | outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ |
89 | } | 95 | } |
@@ -93,41 +99,36 @@ w83697hf_lock(void) | |||
93 | * w83697hf_write_timeout() must be called with the device unlocked. | 99 | * w83697hf_write_timeout() must be called with the device unlocked. |
94 | */ | 100 | */ |
95 | 101 | ||
96 | static unsigned char | 102 | static unsigned char w83697hf_get_reg(unsigned char reg) |
97 | w83697hf_get_reg(unsigned char reg) | ||
98 | { | 103 | { |
99 | outb_p(reg, W83697HF_EFIR); | 104 | outb_p(reg, W83697HF_EFIR); |
100 | return inb_p(W83697HF_EFDR); | 105 | return inb_p(W83697HF_EFDR); |
101 | } | 106 | } |
102 | 107 | ||
103 | static void | 108 | static void w83697hf_set_reg(unsigned char reg, unsigned char data) |
104 | w83697hf_set_reg(unsigned char reg, unsigned char data) | ||
105 | { | 109 | { |
106 | outb_p(reg, W83697HF_EFIR); | 110 | outb_p(reg, W83697HF_EFIR); |
107 | outb_p(data, W83697HF_EFDR); | 111 | outb_p(data, W83697HF_EFDR); |
108 | } | 112 | } |
109 | 113 | ||
110 | static void | 114 | static void w83697hf_write_timeout(int timeout) |
111 | w83697hf_write_timeout(int timeout) | ||
112 | { | 115 | { |
113 | w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ | 116 | /* Write Timeout counter to CRF4 */ |
117 | w83697hf_set_reg(0xF4, timeout); | ||
114 | } | 118 | } |
115 | 119 | ||
116 | static void | 120 | static void w83697hf_select_wdt(void) |
117 | w83697hf_select_wdt(void) | ||
118 | { | 121 | { |
119 | w83697hf_unlock(); | 122 | w83697hf_unlock(); |
120 | w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ | 123 | w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ |
121 | } | 124 | } |
122 | 125 | ||
123 | static inline void | 126 | static inline void w83697hf_deselect_wdt(void) |
124 | w83697hf_deselect_wdt(void) | ||
125 | { | 127 | { |
126 | w83697hf_lock(); | 128 | w83697hf_lock(); |
127 | } | 129 | } |
128 | 130 | ||
129 | static void | 131 | static void w83697hf_init(void) |
130 | w83697hf_init(void) | ||
131 | { | 132 | { |
132 | unsigned char bbuf; | 133 | unsigned char bbuf; |
133 | 134 | ||
@@ -136,7 +137,9 @@ w83697hf_init(void) | |||
136 | bbuf = w83697hf_get_reg(0x29); | 137 | bbuf = w83697hf_get_reg(0x29); |
137 | bbuf &= ~0x60; | 138 | bbuf &= ~0x60; |
138 | bbuf |= 0x20; | 139 | bbuf |= 0x20; |
139 | w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ | 140 | |
141 | /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ | ||
142 | w83697hf_set_reg(0x29, bbuf); | ||
140 | 143 | ||
141 | bbuf = w83697hf_get_reg(0xF3); | 144 | bbuf = w83697hf_get_reg(0xF3); |
142 | bbuf &= ~0x04; | 145 | bbuf &= ~0x04; |
@@ -145,8 +148,7 @@ w83697hf_init(void) | |||
145 | w83697hf_deselect_wdt(); | 148 | w83697hf_deselect_wdt(); |
146 | } | 149 | } |
147 | 150 | ||
148 | static void | 151 | static void wdt_ping(void) |
149 | wdt_ping(void) | ||
150 | { | 152 | { |
151 | spin_lock(&io_lock); | 153 | spin_lock(&io_lock); |
152 | w83697hf_select_wdt(); | 154 | w83697hf_select_wdt(); |
@@ -157,8 +159,7 @@ wdt_ping(void) | |||
157 | spin_unlock(&io_lock); | 159 | spin_unlock(&io_lock); |
158 | } | 160 | } |
159 | 161 | ||
160 | static void | 162 | static void wdt_enable(void) |
161 | wdt_enable(void) | ||
162 | { | 163 | { |
163 | spin_lock(&io_lock); | 164 | spin_lock(&io_lock); |
164 | w83697hf_select_wdt(); | 165 | w83697hf_select_wdt(); |
@@ -170,8 +171,7 @@ wdt_enable(void) | |||
170 | spin_unlock(&io_lock); | 171 | spin_unlock(&io_lock); |
171 | } | 172 | } |
172 | 173 | ||
173 | static void | 174 | static void wdt_disable(void) |
174 | wdt_disable(void) | ||
175 | { | 175 | { |
176 | spin_lock(&io_lock); | 176 | spin_lock(&io_lock); |
177 | w83697hf_select_wdt(); | 177 | w83697hf_select_wdt(); |
@@ -183,8 +183,7 @@ wdt_disable(void) | |||
183 | spin_unlock(&io_lock); | 183 | spin_unlock(&io_lock); |
184 | } | 184 | } |
185 | 185 | ||
186 | static unsigned char | 186 | static unsigned char wdt_running(void) |
187 | wdt_running(void) | ||
188 | { | 187 | { |
189 | unsigned char t; | 188 | unsigned char t; |
190 | 189 | ||
@@ -199,18 +198,17 @@ wdt_running(void) | |||
199 | return t; | 198 | return t; |
200 | } | 199 | } |
201 | 200 | ||
202 | static int | 201 | static int wdt_set_heartbeat(int t) |
203 | wdt_set_heartbeat(int t) | ||
204 | { | 202 | { |
205 | if ((t < 1) || (t > 255)) | 203 | if (t < 1 || t > 255) |
206 | return -EINVAL; | 204 | return -EINVAL; |
207 | 205 | ||
208 | timeout = t; | 206 | timeout = t; |
209 | return 0; | 207 | return 0; |
210 | } | 208 | } |
211 | 209 | ||
212 | static ssize_t | 210 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
213 | wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 211 | size_t count, loff_t *ppos) |
214 | { | 212 | { |
215 | if (count) { | 213 | if (count) { |
216 | if (!nowayout) { | 214 | if (!nowayout) { |
@@ -231,15 +229,14 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
231 | return count; | 229 | return count; |
232 | } | 230 | } |
233 | 231 | ||
234 | static int | 232 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
235 | wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
236 | unsigned long arg) | ||
237 | { | 233 | { |
238 | void __user *argp = (void __user *)arg; | 234 | void __user *argp = (void __user *)arg; |
239 | int __user *p = argp; | 235 | int __user *p = argp; |
240 | int new_timeout; | 236 | int new_timeout; |
241 | static struct watchdog_info ident = { | 237 | static const struct watchdog_info ident = { |
242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 238 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
239 | | WDIOF_MAGICCLOSE, | ||
243 | .firmware_version = 1, | 240 | .firmware_version = 1, |
244 | .identity = "W83697HF WDT", | 241 | .identity = "W83697HF WDT", |
245 | }; | 242 | }; |
@@ -295,8 +292,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
295 | return 0; | 292 | return 0; |
296 | } | 293 | } |
297 | 294 | ||
298 | static int | 295 | static int wdt_open(struct inode *inode, struct file *file) |
299 | wdt_open(struct inode *inode, struct file *file) | ||
300 | { | 296 | { |
301 | if (test_and_set_bit(0, &wdt_is_open)) | 297 | if (test_and_set_bit(0, &wdt_is_open)) |
302 | return -EBUSY; | 298 | return -EBUSY; |
@@ -308,13 +304,13 @@ wdt_open(struct inode *inode, struct file *file) | |||
308 | return nonseekable_open(inode, file); | 304 | return nonseekable_open(inode, file); |
309 | } | 305 | } |
310 | 306 | ||
311 | static int | 307 | static int wdt_close(struct inode *inode, struct file *file) |
312 | wdt_close(struct inode *inode, struct file *file) | ||
313 | { | 308 | { |
314 | if (expect_close == 42) { | 309 | if (expect_close == 42) |
315 | wdt_disable(); | 310 | wdt_disable(); |
316 | } else { | 311 | else { |
317 | printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 312 | printk(KERN_CRIT PFX |
313 | "Unexpected close, not stopping watchdog!\n"); | ||
318 | wdt_ping(); | 314 | wdt_ping(); |
319 | } | 315 | } |
320 | expect_close = 0; | 316 | expect_close = 0; |
@@ -326,8 +322,7 @@ wdt_close(struct inode *inode, struct file *file) | |||
326 | * Notifier for system down | 322 | * Notifier for system down |
327 | */ | 323 | */ |
328 | 324 | ||
329 | static int | 325 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
330 | wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
331 | void *unused) | 326 | void *unused) |
332 | { | 327 | { |
333 | if (code == SYS_DOWN || code == SYS_HALT) { | 328 | if (code == SYS_DOWN || code == SYS_HALT) { |
@@ -345,7 +340,7 @@ static const struct file_operations wdt_fops = { | |||
345 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
346 | .llseek = no_llseek, | 341 | .llseek = no_llseek, |
347 | .write = wdt_write, | 342 | .write = wdt_write, |
348 | .ioctl = wdt_ioctl, | 343 | .unlocked_ioctl = wdt_ioctl, |
349 | .open = wdt_open, | 344 | .open = wdt_open, |
350 | .release = wdt_close, | 345 | .release = wdt_close, |
351 | }; | 346 | }; |
@@ -365,36 +360,38 @@ static struct notifier_block wdt_notifier = { | |||
365 | .notifier_call = wdt_notify_sys, | 360 | .notifier_call = wdt_notify_sys, |
366 | }; | 361 | }; |
367 | 362 | ||
368 | static int | 363 | static int w83697hf_check_wdt(void) |
369 | w83697hf_check_wdt(void) | ||
370 | { | 364 | { |
371 | if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { | 365 | if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { |
372 | printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); | 366 | printk(KERN_ERR PFX |
367 | "I/O address 0x%x already in use\n", wdt_io); | ||
373 | return -EIO; | 368 | return -EIO; |
374 | } | 369 | } |
375 | 370 | ||
376 | printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); | 371 | printk(KERN_DEBUG PFX |
372 | "Looking for watchdog at address 0x%x\n", wdt_io); | ||
377 | w83697hf_unlock(); | 373 | w83697hf_unlock(); |
378 | if (w83697hf_get_reg(0x20) == 0x60) { | 374 | if (w83697hf_get_reg(0x20) == 0x60) { |
379 | printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); | 375 | printk(KERN_INFO PFX |
376 | "watchdog found at address 0x%x\n", wdt_io); | ||
380 | w83697hf_lock(); | 377 | w83697hf_lock(); |
381 | return 0; | 378 | return 0; |
382 | } | 379 | } |
383 | w83697hf_lock(); /* Reprotect in case it was a compatible device */ | 380 | /* Reprotect in case it was a compatible device */ |
381 | w83697hf_lock(); | ||
384 | 382 | ||
385 | printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); | 383 | printk(KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); |
386 | release_region(wdt_io, 2); | 384 | release_region(wdt_io, 2); |
387 | return -EIO; | 385 | return -EIO; |
388 | } | 386 | } |
389 | 387 | ||
390 | static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; | 388 | static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; |
391 | 389 | ||
392 | static int __init | 390 | static int __init wdt_init(void) |
393 | wdt_init(void) | ||
394 | { | 391 | { |
395 | int ret, i, found = 0; | 392 | int ret, i, found = 0; |
396 | 393 | ||
397 | printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); | 394 | printk(KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); |
398 | 395 | ||
399 | if (wdt_io == 0) { | 396 | if (wdt_io == 0) { |
400 | /* we will autodetect the W83697HF/HG watchdog */ | 397 | /* we will autodetect the W83697HF/HG watchdog */ |
@@ -409,7 +406,7 @@ wdt_init(void) | |||
409 | } | 406 | } |
410 | 407 | ||
411 | if (!found) { | 408 | if (!found) { |
412 | printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); | 409 | printk(KERN_ERR PFX "No W83697HF/HG could be found\n"); |
413 | ret = -EIO; | 410 | ret = -EIO; |
414 | goto out; | 411 | goto out; |
415 | } | 412 | } |
@@ -423,25 +420,27 @@ wdt_init(void) | |||
423 | 420 | ||
424 | if (wdt_set_heartbeat(timeout)) { | 421 | if (wdt_set_heartbeat(timeout)) { |
425 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 422 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
426 | printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", | 423 | printk(KERN_INFO PFX |
427 | WATCHDOG_TIMEOUT); | 424 | "timeout value must be 1 <= timeout <= 255, using %d\n", |
425 | WATCHDOG_TIMEOUT); | ||
428 | } | 426 | } |
429 | 427 | ||
430 | ret = register_reboot_notifier(&wdt_notifier); | 428 | ret = register_reboot_notifier(&wdt_notifier); |
431 | if (ret != 0) { | 429 | if (ret != 0) { |
432 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 430 | printk(KERN_ERR PFX |
433 | ret); | 431 | "cannot register reboot notifier (err=%d)\n", ret); |
434 | goto unreg_regions; | 432 | goto unreg_regions; |
435 | } | 433 | } |
436 | 434 | ||
437 | ret = misc_register(&wdt_miscdev); | 435 | ret = misc_register(&wdt_miscdev); |
438 | if (ret != 0) { | 436 | if (ret != 0) { |
439 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 437 | printk(KERN_ERR PFX |
440 | WATCHDOG_MINOR, ret); | 438 | "cannot register miscdev on minor=%d (err=%d)\n", |
439 | WATCHDOG_MINOR, ret); | ||
441 | goto unreg_reboot; | 440 | goto unreg_reboot; |
442 | } | 441 | } |
443 | 442 | ||
444 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 443 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", |
445 | timeout, nowayout); | 444 | timeout, nowayout); |
446 | 445 | ||
447 | out: | 446 | out: |
@@ -453,8 +452,7 @@ unreg_regions: | |||
453 | goto out; | 452 | goto out; |
454 | } | 453 | } |
455 | 454 | ||
456 | static void __exit | 455 | static void __exit wdt_exit(void) |
457 | wdt_exit(void) | ||
458 | { | 456 | { |
459 | misc_deregister(&wdt_miscdev); | 457 | misc_deregister(&wdt_miscdev); |
460 | unregister_reboot_notifier(&wdt_notifier); | 458 | unregister_reboot_notifier(&wdt_notifier); |
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c index f510a3a595e6..75b546d7d8c2 100644 --- a/drivers/watchdog/w83877f_wdt.c +++ b/drivers/watchdog/w83877f_wdt.c | |||
@@ -23,13 +23,16 @@ | |||
23 | * Added KERN_* tags to printks | 23 | * Added KERN_* tags to printks |
24 | * add CONFIG_WATCHDOG_NOWAYOUT support | 24 | * add CONFIG_WATCHDOG_NOWAYOUT support |
25 | * fix possible wdt_is_open race | 25 | * fix possible wdt_is_open race |
26 | * changed watchdog_info to correctly reflect what the driver offers | 26 | * changed watchdog_info to correctly reflect what |
27 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, | 27 | * the driver offers |
28 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, | ||
29 | * WDIOC_SETTIMEOUT, | ||
28 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls | 30 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls |
29 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces | 31 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces |
30 | * added extra printk's for startup problems | 32 | * added extra printk's for startup problems |
31 | * use module_param | 33 | * use module_param |
32 | * made timeout (the emulated heartbeat) a module_param | 34 | * made timeout (the emulated heartbeat) a |
35 | * module_param | ||
33 | * made the keepalive ping an internal subroutine | 36 | * made the keepalive ping an internal subroutine |
34 | * | 37 | * |
35 | * This WDT driver is different from most other Linux WDT | 38 | * This WDT driver is different from most other Linux WDT |
@@ -51,8 +54,8 @@ | |||
51 | #include <linux/notifier.h> | 54 | #include <linux/notifier.h> |
52 | #include <linux/reboot.h> | 55 | #include <linux/reboot.h> |
53 | #include <linux/init.h> | 56 | #include <linux/init.h> |
54 | #include <asm/io.h> | 57 | #include <linux/io.h> |
55 | #include <asm/uaccess.h> | 58 | #include <linux/uaccess.h> |
56 | #include <asm/system.h> | 59 | #include <asm/system.h> |
57 | 60 | ||
58 | #define OUR_NAME "w83877f_wdt" | 61 | #define OUR_NAME "w83877f_wdt" |
@@ -80,14 +83,19 @@ | |||
80 | */ | 83 | */ |
81 | 84 | ||
82 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 85 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
83 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 86 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
87 | static int timeout = WATCHDOG_TIMEOUT; | ||
84 | module_param(timeout, int, 0); | 88 | module_param(timeout, int, 0); |
85 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 89 | MODULE_PARM_DESC(timeout, |
90 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
91 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
86 | 92 | ||
87 | 93 | ||
88 | static int nowayout = WATCHDOG_NOWAYOUT; | 94 | static int nowayout = WATCHDOG_NOWAYOUT; |
89 | module_param(nowayout, int, 0); | 95 | module_param(nowayout, int, 0); |
90 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 96 | MODULE_PARM_DESC(nowayout, |
97 | "Watchdog cannot be stopped once started (default=" | ||
98 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
91 | 99 | ||
92 | static void wdt_timer_ping(unsigned long); | 100 | static void wdt_timer_ping(unsigned long); |
93 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); | 101 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); |
@@ -105,8 +113,7 @@ static void wdt_timer_ping(unsigned long data) | |||
105 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 113 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
106 | * we agree to ping the WDT | 114 | * we agree to ping the WDT |
107 | */ | 115 | */ |
108 | if(time_before(jiffies, next_heartbeat)) | 116 | if (time_before(jiffies, next_heartbeat)) { |
109 | { | ||
110 | /* Ping the WDT */ | 117 | /* Ping the WDT */ |
111 | spin_lock(&wdt_spinlock); | 118 | spin_lock(&wdt_spinlock); |
112 | 119 | ||
@@ -118,9 +125,9 @@ static void wdt_timer_ping(unsigned long data) | |||
118 | 125 | ||
119 | spin_unlock(&wdt_spinlock); | 126 | spin_unlock(&wdt_spinlock); |
120 | 127 | ||
121 | } else { | 128 | } else |
122 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 129 | printk(KERN_WARNING PFX |
123 | } | 130 | "Heartbeat lost! Will not ping the watchdog\n"); |
124 | } | 131 | } |
125 | 132 | ||
126 | /* | 133 | /* |
@@ -181,22 +188,21 @@ static void wdt_keepalive(void) | |||
181 | * /dev/watchdog handling | 188 | * /dev/watchdog handling |
182 | */ | 189 | */ |
183 | 190 | ||
184 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 191 | static ssize_t fop_write(struct file *file, const char __user *buf, |
192 | size_t count, loff_t *ppos) | ||
185 | { | 193 | { |
186 | /* See if we got the magic character 'V' and reload the timer */ | 194 | /* See if we got the magic character 'V' and reload the timer */ |
187 | if(count) | 195 | if (count) { |
188 | { | 196 | if (!nowayout) { |
189 | if (!nowayout) | ||
190 | { | ||
191 | size_t ofs; | 197 | size_t ofs; |
192 | 198 | ||
193 | /* note: just in case someone wrote the magic character | 199 | /* note: just in case someone wrote the magic |
194 | * five months ago... */ | 200 | character five months ago... */ |
195 | wdt_expect_close = 0; | 201 | wdt_expect_close = 0; |
196 | 202 | ||
197 | /* scan to see whether or not we got the magic character */ | 203 | /* scan to see whether or not we got the |
198 | for(ofs = 0; ofs != count; ofs++) | 204 | magic character */ |
199 | { | 205 | for (ofs = 0; ofs != count; ofs++) { |
200 | char c; | 206 | char c; |
201 | if (get_user(c, buf + ofs)) | 207 | if (get_user(c, buf + ofs)) |
202 | return -EFAULT; | 208 | return -EFAULT; |
@@ -211,10 +217,10 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
211 | return count; | 217 | return count; |
212 | } | 218 | } |
213 | 219 | ||
214 | static int fop_open(struct inode * inode, struct file * file) | 220 | static int fop_open(struct inode *inode, struct file *file) |
215 | { | 221 | { |
216 | /* Just in case we're already talking to someone... */ | 222 | /* Just in case we're already talking to someone... */ |
217 | if(test_and_set_bit(0, &wdt_is_open)) | 223 | if (test_and_set_bit(0, &wdt_is_open)) |
218 | return -EBUSY; | 224 | return -EBUSY; |
219 | 225 | ||
220 | /* Good, fire up the show */ | 226 | /* Good, fire up the show */ |
@@ -222,78 +228,78 @@ static int fop_open(struct inode * inode, struct file * file) | |||
222 | return nonseekable_open(inode, file); | 228 | return nonseekable_open(inode, file); |
223 | } | 229 | } |
224 | 230 | ||
225 | static int fop_close(struct inode * inode, struct file * file) | 231 | static int fop_close(struct inode *inode, struct file *file) |
226 | { | 232 | { |
227 | if(wdt_expect_close == 42) | 233 | if (wdt_expect_close == 42) |
228 | wdt_turnoff(); | 234 | wdt_turnoff(); |
229 | else { | 235 | else { |
230 | del_timer(&timer); | 236 | del_timer(&timer); |
231 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 237 | printk(KERN_CRIT PFX |
238 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
232 | } | 239 | } |
233 | clear_bit(0, &wdt_is_open); | 240 | clear_bit(0, &wdt_is_open); |
234 | wdt_expect_close = 0; | 241 | wdt_expect_close = 0; |
235 | return 0; | 242 | return 0; |
236 | } | 243 | } |
237 | 244 | ||
238 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 245 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
239 | unsigned long arg) | ||
240 | { | 246 | { |
241 | void __user *argp = (void __user *)arg; | 247 | void __user *argp = (void __user *)arg; |
242 | int __user *p = argp; | 248 | int __user *p = argp; |
243 | static struct watchdog_info ident= | 249 | static const struct watchdog_info ident = { |
244 | { | 250 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
245 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 251 | | WDIOF_MAGICCLOSE, |
246 | .firmware_version = 1, | 252 | .firmware_version = 1, |
247 | .identity = "W83877F", | 253 | .identity = "W83877F", |
248 | }; | 254 | }; |
249 | 255 | ||
250 | switch(cmd) | 256 | switch (cmd) { |
257 | default: | ||
258 | return -ENOTTY; | ||
259 | case WDIOC_GETSUPPORT: | ||
260 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
261 | case WDIOC_GETSTATUS: | ||
262 | case WDIOC_GETBOOTSTATUS: | ||
263 | return put_user(0, p); | ||
264 | case WDIOC_KEEPALIVE: | ||
265 | wdt_keepalive(); | ||
266 | return 0; | ||
267 | case WDIOC_SETOPTIONS: | ||
251 | { | 268 | { |
252 | default: | 269 | int new_options, retval = -EINVAL; |
253 | return -ENOTTY; | ||
254 | case WDIOC_GETSUPPORT: | ||
255 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | ||
256 | case WDIOC_GETSTATUS: | ||
257 | case WDIOC_GETBOOTSTATUS: | ||
258 | return put_user(0, p); | ||
259 | case WDIOC_KEEPALIVE: | ||
260 | wdt_keepalive(); | ||
261 | return 0; | ||
262 | case WDIOC_SETOPTIONS: | ||
263 | { | ||
264 | int new_options, retval = -EINVAL; | ||
265 | |||
266 | if(get_user(new_options, p)) | ||
267 | return -EFAULT; | ||
268 | |||
269 | if(new_options & WDIOS_DISABLECARD) { | ||
270 | wdt_turnoff(); | ||
271 | retval = 0; | ||
272 | } | ||
273 | 270 | ||
274 | if(new_options & WDIOS_ENABLECARD) { | 271 | if (get_user(new_options, p)) |
275 | wdt_startup(); | 272 | return -EFAULT; |
276 | retval = 0; | ||
277 | } | ||
278 | 273 | ||
279 | return retval; | 274 | if (new_options & WDIOS_DISABLECARD) { |
275 | wdt_turnoff(); | ||
276 | retval = 0; | ||
280 | } | 277 | } |
281 | case WDIOC_SETTIMEOUT: | ||
282 | { | ||
283 | int new_timeout; | ||
284 | 278 | ||
285 | if(get_user(new_timeout, p)) | 279 | if (new_options & WDIOS_ENABLECARD) { |
286 | return -EFAULT; | 280 | wdt_startup(); |
281 | retval = 0; | ||
282 | } | ||
287 | 283 | ||
288 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | 284 | return retval; |
289 | return -EINVAL; | 285 | } |
286 | case WDIOC_SETTIMEOUT: | ||
287 | { | ||
288 | int new_timeout; | ||
290 | 289 | ||
291 | timeout = new_timeout; | 290 | if (get_user(new_timeout, p)) |
292 | wdt_keepalive(); | 291 | return -EFAULT; |
293 | /* Fall through */ | 292 | |
294 | } | 293 | /* arbitrary upper limit */ |
295 | case WDIOC_GETTIMEOUT: | 294 | if (new_timeout < 1 || new_timeout > 3600) |
296 | return put_user(timeout, p); | 295 | return -EINVAL; |
296 | |||
297 | timeout = new_timeout; | ||
298 | wdt_keepalive(); | ||
299 | /* Fall through */ | ||
300 | } | ||
301 | case WDIOC_GETTIMEOUT: | ||
302 | return put_user(timeout, p); | ||
297 | } | 303 | } |
298 | } | 304 | } |
299 | 305 | ||
@@ -303,7 +309,7 @@ static const struct file_operations wdt_fops = { | |||
303 | .write = fop_write, | 309 | .write = fop_write, |
304 | .open = fop_open, | 310 | .open = fop_open, |
305 | .release = fop_close, | 311 | .release = fop_close, |
306 | .ioctl = fop_ioctl, | 312 | .unlocked_ioctl = fop_ioctl, |
307 | }; | 313 | }; |
308 | 314 | ||
309 | static struct miscdevice wdt_miscdev = { | 315 | static struct miscdevice wdt_miscdev = { |
@@ -319,7 +325,7 @@ static struct miscdevice wdt_miscdev = { | |||
319 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 325 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
320 | void *unused) | 326 | void *unused) |
321 | { | 327 | { |
322 | if(code==SYS_DOWN || code==SYS_HALT) | 328 | if (code == SYS_DOWN || code == SYS_HALT) |
323 | wdt_turnoff(); | 329 | wdt_turnoff(); |
324 | return NOTIFY_DONE; | 330 | return NOTIFY_DONE; |
325 | } | 331 | } |
@@ -329,8 +335,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
329 | * turn the timebomb registers off. | 335 | * turn the timebomb registers off. |
330 | */ | 336 | */ |
331 | 337 | ||
332 | static struct notifier_block wdt_notifier= | 338 | static struct notifier_block wdt_notifier = { |
333 | { | ||
334 | .notifier_call = wdt_notify_sys, | 339 | .notifier_call = wdt_notify_sys, |
335 | }; | 340 | }; |
336 | 341 | ||
@@ -342,31 +347,29 @@ static void __exit w83877f_wdt_unload(void) | |||
342 | misc_deregister(&wdt_miscdev); | 347 | misc_deregister(&wdt_miscdev); |
343 | 348 | ||
344 | unregister_reboot_notifier(&wdt_notifier); | 349 | unregister_reboot_notifier(&wdt_notifier); |
345 | release_region(WDT_PING,1); | 350 | release_region(WDT_PING, 1); |
346 | release_region(ENABLE_W83877F_PORT,2); | 351 | release_region(ENABLE_W83877F_PORT, 2); |
347 | } | 352 | } |
348 | 353 | ||
349 | static int __init w83877f_wdt_init(void) | 354 | static int __init w83877f_wdt_init(void) |
350 | { | 355 | { |
351 | int rc = -EBUSY; | 356 | int rc = -EBUSY; |
352 | 357 | ||
353 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 358 | if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ |
354 | { | ||
355 | timeout = WATCHDOG_TIMEOUT; | 359 | timeout = WATCHDOG_TIMEOUT; |
356 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 360 | printk(KERN_INFO PFX |
357 | timeout); | 361 | "timeout value must be 1 <= x <= 3600, using %d\n", |
362 | timeout); | ||
358 | } | 363 | } |
359 | 364 | ||
360 | if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) | 365 | if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) { |
361 | { | ||
362 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 366 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
363 | ENABLE_W83877F_PORT); | 367 | ENABLE_W83877F_PORT); |
364 | rc = -EIO; | 368 | rc = -EIO; |
365 | goto err_out; | 369 | goto err_out; |
366 | } | 370 | } |
367 | 371 | ||
368 | if (!request_region(WDT_PING, 1, "W8387FF WDT")) | 372 | if (!request_region(WDT_PING, 1, "W8387FF WDT")) { |
369 | { | ||
370 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 373 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
371 | WDT_PING); | 374 | WDT_PING); |
372 | rc = -EIO; | 375 | rc = -EIO; |
@@ -374,22 +377,22 @@ static int __init w83877f_wdt_init(void) | |||
374 | } | 377 | } |
375 | 378 | ||
376 | rc = register_reboot_notifier(&wdt_notifier); | 379 | rc = register_reboot_notifier(&wdt_notifier); |
377 | if (rc) | 380 | if (rc) { |
378 | { | 381 | printk(KERN_ERR PFX |
379 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 382 | "cannot register reboot notifier (err=%d)\n", rc); |
380 | rc); | ||
381 | goto err_out_region2; | 383 | goto err_out_region2; |
382 | } | 384 | } |
383 | 385 | ||
384 | rc = misc_register(&wdt_miscdev); | 386 | rc = misc_register(&wdt_miscdev); |
385 | if (rc) | 387 | if (rc) { |
386 | { | 388 | printk(KERN_ERR PFX |
387 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 389 | "cannot register miscdev on minor=%d (err=%d)\n", |
388 | wdt_miscdev.minor, rc); | 390 | wdt_miscdev.minor, rc); |
389 | goto err_out_reboot; | 391 | goto err_out_reboot; |
390 | } | 392 | } |
391 | 393 | ||
392 | printk(KERN_INFO PFX "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", | 394 | printk(KERN_INFO PFX |
395 | "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", | ||
393 | timeout, nowayout); | 396 | timeout, nowayout); |
394 | 397 | ||
395 | return 0; | 398 | return 0; |
@@ -397,9 +400,9 @@ static int __init w83877f_wdt_init(void) | |||
397 | err_out_reboot: | 400 | err_out_reboot: |
398 | unregister_reboot_notifier(&wdt_notifier); | 401 | unregister_reboot_notifier(&wdt_notifier); |
399 | err_out_region2: | 402 | err_out_region2: |
400 | release_region(WDT_PING,1); | 403 | release_region(WDT_PING, 1); |
401 | err_out_region1: | 404 | err_out_region1: |
402 | release_region(ENABLE_W83877F_PORT,2); | 405 | release_region(ENABLE_W83877F_PORT, 2); |
403 | err_out: | 406 | err_out: |
404 | return rc; | 407 | return rc; |
405 | } | 408 | } |
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index b209bcd7f789..6860a13f5bb9 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c | |||
@@ -26,10 +26,10 @@ | |||
26 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
27 | #include <linux/notifier.h> | 27 | #include <linux/notifier.h> |
28 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
29 | #include <linux/uaccess.h> | ||
30 | #include <linux/io.h> | ||
29 | 31 | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
32 | #include <asm/uaccess.h> | ||
33 | 33 | ||
34 | #define WATCHDOG_VERSION "1.00" | 34 | #define WATCHDOG_VERSION "1.00" |
35 | #define WATCHDOG_NAME "W83977F WDT" | 35 | #define WATCHDOG_NAME "W83977F WDT" |
@@ -53,13 +53,17 @@ static char expect_close; | |||
53 | static DEFINE_SPINLOCK(spinlock); | 53 | static DEFINE_SPINLOCK(spinlock); |
54 | 54 | ||
55 | module_param(timeout, int, 0); | 55 | module_param(timeout, int, 0); |
56 | MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | 56 | MODULE_PARM_DESC(timeout, |
57 | "Watchdog timeout in seconds (15..7635), default=" | ||
58 | __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | ||
57 | module_param(testmode, int, 0); | 59 | module_param(testmode, int, 0); |
58 | MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); | 60 | MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); |
59 | 61 | ||
60 | static int nowayout = WATCHDOG_NOWAYOUT; | 62 | static int nowayout = WATCHDOG_NOWAYOUT; |
61 | module_param(nowayout, int, 0); | 63 | module_param(nowayout, int, 0); |
62 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 64 | MODULE_PARM_DESC(nowayout, |
65 | "Watchdog cannot be stopped once started (default=" | ||
66 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
63 | 67 | ||
64 | /* | 68 | /* |
65 | * Start the watchdog | 69 | * Start the watchdog |
@@ -72,8 +76,8 @@ static int wdt_start(void) | |||
72 | spin_lock_irqsave(&spinlock, flags); | 76 | spin_lock_irqsave(&spinlock, flags); |
73 | 77 | ||
74 | /* Unlock the SuperIO chip */ | 78 | /* Unlock the SuperIO chip */ |
75 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 79 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
76 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 80 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
77 | 81 | ||
78 | /* | 82 | /* |
79 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. | 83 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. |
@@ -81,50 +85,49 @@ static int wdt_start(void) | |||
81 | * F3 is set to enable watchdog LED blink at timeout. | 85 | * F3 is set to enable watchdog LED blink at timeout. |
82 | * F4 is used to just clear the TIMEOUT'ed state (bit 0). | 86 | * F4 is used to just clear the TIMEOUT'ed state (bit 0). |
83 | */ | 87 | */ |
84 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 88 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
85 | outb_p(0x08,IO_DATA_PORT); | 89 | outb_p(0x08, IO_DATA_PORT); |
86 | outb_p(0xF2,IO_INDEX_PORT); | 90 | outb_p(0xF2, IO_INDEX_PORT); |
87 | outb_p(timeoutW,IO_DATA_PORT); | 91 | outb_p(timeoutW, IO_DATA_PORT); |
88 | outb_p(0xF3,IO_INDEX_PORT); | 92 | outb_p(0xF3, IO_INDEX_PORT); |
89 | outb_p(0x08,IO_DATA_PORT); | 93 | outb_p(0x08, IO_DATA_PORT); |
90 | outb_p(0xF4,IO_INDEX_PORT); | 94 | outb_p(0xF4, IO_INDEX_PORT); |
91 | outb_p(0x00,IO_DATA_PORT); | 95 | outb_p(0x00, IO_DATA_PORT); |
92 | 96 | ||
93 | /* Set device Aux2 active */ | 97 | /* Set device Aux2 active */ |
94 | outb_p(0x30,IO_INDEX_PORT); | 98 | outb_p(0x30, IO_INDEX_PORT); |
95 | outb_p(0x01,IO_DATA_PORT); | 99 | outb_p(0x01, IO_DATA_PORT); |
96 | 100 | ||
97 | /* | 101 | /* |
98 | * Select device Aux1 (dev=7) to set GP16 as the watchdog output | 102 | * Select device Aux1 (dev=7) to set GP16 as the watchdog output |
99 | * (in reg E6) and GP13 as the watchdog LED output (in reg E3). | 103 | * (in reg E6) and GP13 as the watchdog LED output (in reg E3). |
100 | * Map GP16 at pin 119. | 104 | * Map GP16 at pin 119. |
101 | * In test mode watch the bit 0 on F4 to indicate "triggered" or | 105 | * In test mode watch the bit 0 on F4 to indicate "triggered" or |
102 | * check watchdog LED on SBC. | 106 | * check watchdog LED on SBC. |
103 | */ | 107 | */ |
104 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 108 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
105 | outb_p(0x07,IO_DATA_PORT); | 109 | outb_p(0x07, IO_DATA_PORT); |
106 | if (!testmode) | 110 | if (!testmode) { |
107 | { | ||
108 | unsigned pin_map; | 111 | unsigned pin_map; |
109 | 112 | ||
110 | outb_p(0xE6,IO_INDEX_PORT); | 113 | outb_p(0xE6, IO_INDEX_PORT); |
111 | outb_p(0x0A,IO_DATA_PORT); | 114 | outb_p(0x0A, IO_DATA_PORT); |
112 | outb_p(0x2C,IO_INDEX_PORT); | 115 | outb_p(0x2C, IO_INDEX_PORT); |
113 | pin_map = inb_p(IO_DATA_PORT); | 116 | pin_map = inb_p(IO_DATA_PORT); |
114 | pin_map |= 0x10; | 117 | pin_map |= 0x10; |
115 | pin_map &= ~(0x20); | 118 | pin_map &= ~(0x20); |
116 | outb_p(0x2C,IO_INDEX_PORT); | 119 | outb_p(0x2C, IO_INDEX_PORT); |
117 | outb_p(pin_map,IO_DATA_PORT); | 120 | outb_p(pin_map, IO_DATA_PORT); |
118 | } | 121 | } |
119 | outb_p(0xE3,IO_INDEX_PORT); | 122 | outb_p(0xE3, IO_INDEX_PORT); |
120 | outb_p(0x08,IO_DATA_PORT); | 123 | outb_p(0x08, IO_DATA_PORT); |
121 | 124 | ||
122 | /* Set device Aux1 active */ | 125 | /* Set device Aux1 active */ |
123 | outb_p(0x30,IO_INDEX_PORT); | 126 | outb_p(0x30, IO_INDEX_PORT); |
124 | outb_p(0x01,IO_DATA_PORT); | 127 | outb_p(0x01, IO_DATA_PORT); |
125 | 128 | ||
126 | /* Lock the SuperIO chip */ | 129 | /* Lock the SuperIO chip */ |
127 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 130 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
128 | 131 | ||
129 | spin_unlock_irqrestore(&spinlock, flags); | 132 | spin_unlock_irqrestore(&spinlock, flags); |
130 | 133 | ||
@@ -144,42 +147,41 @@ static int wdt_stop(void) | |||
144 | spin_lock_irqsave(&spinlock, flags); | 147 | spin_lock_irqsave(&spinlock, flags); |
145 | 148 | ||
146 | /* Unlock the SuperIO chip */ | 149 | /* Unlock the SuperIO chip */ |
147 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 150 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
148 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 151 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
149 | 152 | ||
150 | /* | 153 | /* |
151 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. | 154 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. |
152 | * F2 is reset to its default value (watchdog timer disabled). | 155 | * F2 is reset to its default value (watchdog timer disabled). |
153 | * F3 is reset to its default state. | 156 | * F3 is reset to its default state. |
154 | * F4 clears the TIMEOUT'ed state (bit 0) - back to default. | 157 | * F4 clears the TIMEOUT'ed state (bit 0) - back to default. |
155 | */ | 158 | */ |
156 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 159 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
157 | outb_p(0x08,IO_DATA_PORT); | 160 | outb_p(0x08, IO_DATA_PORT); |
158 | outb_p(0xF2,IO_INDEX_PORT); | 161 | outb_p(0xF2, IO_INDEX_PORT); |
159 | outb_p(0xFF,IO_DATA_PORT); | 162 | outb_p(0xFF, IO_DATA_PORT); |
160 | outb_p(0xF3,IO_INDEX_PORT); | 163 | outb_p(0xF3, IO_INDEX_PORT); |
161 | outb_p(0x00,IO_DATA_PORT); | 164 | outb_p(0x00, IO_DATA_PORT); |
162 | outb_p(0xF4,IO_INDEX_PORT); | 165 | outb_p(0xF4, IO_INDEX_PORT); |
163 | outb_p(0x00,IO_DATA_PORT); | 166 | outb_p(0x00, IO_DATA_PORT); |
164 | outb_p(0xF2,IO_INDEX_PORT); | 167 | outb_p(0xF2, IO_INDEX_PORT); |
165 | outb_p(0x00,IO_DATA_PORT); | 168 | outb_p(0x00, IO_DATA_PORT); |
166 | 169 | ||
167 | /* | 170 | /* |
168 | * Select device Aux1 (dev=7) to set GP16 (in reg E6) and | 171 | * Select device Aux1 (dev=7) to set GP16 (in reg E6) and |
169 | * Gp13 (in reg E3) as inputs. | 172 | * Gp13 (in reg E3) as inputs. |
170 | */ | 173 | */ |
171 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 174 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
172 | outb_p(0x07,IO_DATA_PORT); | 175 | outb_p(0x07, IO_DATA_PORT); |
173 | if (!testmode) | 176 | if (!testmode) { |
174 | { | 177 | outb_p(0xE6, IO_INDEX_PORT); |
175 | outb_p(0xE6,IO_INDEX_PORT); | 178 | outb_p(0x01, IO_DATA_PORT); |
176 | outb_p(0x01,IO_DATA_PORT); | ||
177 | } | 179 | } |
178 | outb_p(0xE3,IO_INDEX_PORT); | 180 | outb_p(0xE3, IO_INDEX_PORT); |
179 | outb_p(0x01,IO_DATA_PORT); | 181 | outb_p(0x01, IO_DATA_PORT); |
180 | 182 | ||
181 | /* Lock the SuperIO chip */ | 183 | /* Lock the SuperIO chip */ |
182 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 184 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
183 | 185 | ||
184 | spin_unlock_irqrestore(&spinlock, flags); | 186 | spin_unlock_irqrestore(&spinlock, flags); |
185 | 187 | ||
@@ -200,17 +202,17 @@ static int wdt_keepalive(void) | |||
200 | spin_lock_irqsave(&spinlock, flags); | 202 | spin_lock_irqsave(&spinlock, flags); |
201 | 203 | ||
202 | /* Unlock the SuperIO chip */ | 204 | /* Unlock the SuperIO chip */ |
203 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 205 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
204 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 206 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
205 | 207 | ||
206 | /* Select device Aux2 (device=8) to kick watchdog reg F2 */ | 208 | /* Select device Aux2 (device=8) to kick watchdog reg F2 */ |
207 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 209 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
208 | outb_p(0x08,IO_DATA_PORT); | 210 | outb_p(0x08, IO_DATA_PORT); |
209 | outb_p(0xF2,IO_INDEX_PORT); | 211 | outb_p(0xF2, IO_INDEX_PORT); |
210 | outb_p(timeoutW,IO_DATA_PORT); | 212 | outb_p(timeoutW, IO_DATA_PORT); |
211 | 213 | ||
212 | /* Lock the SuperIO chip */ | 214 | /* Lock the SuperIO chip */ |
213 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 215 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
214 | 216 | ||
215 | spin_unlock_irqrestore(&spinlock, flags); | 217 | spin_unlock_irqrestore(&spinlock, flags); |
216 | 218 | ||
@@ -227,7 +229,7 @@ static int wdt_set_timeout(int t) | |||
227 | 229 | ||
228 | /* | 230 | /* |
229 | * Convert seconds to watchdog counter time units, rounding up. | 231 | * Convert seconds to watchdog counter time units, rounding up. |
230 | * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup | 232 | * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup |
231 | * value. This information is supplied in the PCM-5335 manual and was | 233 | * value. This information is supplied in the PCM-5335 manual and was |
232 | * checked by me on a real board. This is a bit strange because W83977f | 234 | * checked by me on a real board. This is a bit strange because W83977f |
233 | * datasheet says counter unit is in minutes! | 235 | * datasheet says counter unit is in minutes! |
@@ -241,7 +243,7 @@ static int wdt_set_timeout(int t) | |||
241 | return -EINVAL; | 243 | return -EINVAL; |
242 | 244 | ||
243 | /* | 245 | /* |
244 | * timeout is the timeout in seconds, | 246 | * timeout is the timeout in seconds, |
245 | * timeoutW is the timeout in watchdog counter units. | 247 | * timeoutW is the timeout in watchdog counter units. |
246 | */ | 248 | */ |
247 | timeoutW = tmrval; | 249 | timeoutW = tmrval; |
@@ -261,17 +263,17 @@ static int wdt_get_status(int *status) | |||
261 | spin_lock_irqsave(&spinlock, flags); | 263 | spin_lock_irqsave(&spinlock, flags); |
262 | 264 | ||
263 | /* Unlock the SuperIO chip */ | 265 | /* Unlock the SuperIO chip */ |
264 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 266 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
265 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 267 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
266 | 268 | ||
267 | /* Select device Aux2 (device=8) to read watchdog reg F4 */ | 269 | /* Select device Aux2 (device=8) to read watchdog reg F4 */ |
268 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 270 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
269 | outb_p(0x08,IO_DATA_PORT); | 271 | outb_p(0x08, IO_DATA_PORT); |
270 | outb_p(0xF4,IO_INDEX_PORT); | 272 | outb_p(0xF4, IO_INDEX_PORT); |
271 | new_status = inb_p(IO_DATA_PORT); | 273 | new_status = inb_p(IO_DATA_PORT); |
272 | 274 | ||
273 | /* Lock the SuperIO chip */ | 275 | /* Lock the SuperIO chip */ |
274 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 276 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
275 | 277 | ||
276 | spin_unlock_irqrestore(&spinlock, flags); | 278 | spin_unlock_irqrestore(&spinlock, flags); |
277 | 279 | ||
@@ -290,7 +292,7 @@ static int wdt_get_status(int *status) | |||
290 | static int wdt_open(struct inode *inode, struct file *file) | 292 | static int wdt_open(struct inode *inode, struct file *file) |
291 | { | 293 | { |
292 | /* If the watchdog is alive we don't need to start it again */ | 294 | /* If the watchdog is alive we don't need to start it again */ |
293 | if( test_and_set_bit(0, &timer_alive) ) | 295 | if (test_and_set_bit(0, &timer_alive)) |
294 | return -EBUSY; | 296 | return -EBUSY; |
295 | 297 | ||
296 | if (nowayout) | 298 | if (nowayout) |
@@ -306,13 +308,13 @@ static int wdt_release(struct inode *inode, struct file *file) | |||
306 | * Shut off the timer. | 308 | * Shut off the timer. |
307 | * Lock it in if it's a module and we set nowayout | 309 | * Lock it in if it's a module and we set nowayout |
308 | */ | 310 | */ |
309 | if (expect_close == 42) | 311 | if (expect_close == 42) { |
310 | { | ||
311 | wdt_stop(); | 312 | wdt_stop(); |
312 | clear_bit(0, &timer_alive); | 313 | clear_bit(0, &timer_alive); |
313 | } else { | 314 | } else { |
314 | wdt_keepalive(); | 315 | wdt_keepalive(); |
315 | printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); | 316 | printk(KERN_CRIT PFX |
317 | "unexpected close, not stopping watchdog!\n"); | ||
316 | } | 318 | } |
317 | expect_close = 0; | 319 | expect_close = 0; |
318 | return 0; | 320 | return 0; |
@@ -333,24 +335,22 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
333 | size_t count, loff_t *ppos) | 335 | size_t count, loff_t *ppos) |
334 | { | 336 | { |
335 | /* See if we got the magic character 'V' and reload the timer */ | 337 | /* See if we got the magic character 'V' and reload the timer */ |
336 | if(count) | 338 | if (count) { |
337 | { | 339 | if (!nowayout) { |
338 | if (!nowayout) | ||
339 | { | ||
340 | size_t ofs; | 340 | size_t ofs; |
341 | 341 | ||
342 | /* note: just in case someone wrote the magic character long ago */ | 342 | /* note: just in case someone wrote the |
343 | magic character long ago */ | ||
343 | expect_close = 0; | 344 | expect_close = 0; |
344 | 345 | ||
345 | /* scan to see whether or not we got the magic character */ | 346 | /* scan to see whether or not we got the |
346 | for(ofs = 0; ofs != count; ofs++) | 347 | magic character */ |
347 | { | 348 | for (ofs = 0; ofs != count; ofs++) { |
348 | char c; | 349 | char c; |
349 | if (get_user(c, buf + ofs)) | 350 | if (get_user(c, buf + ofs)) |
350 | return -EFAULT; | 351 | return -EFAULT; |
351 | if (c == 'V') { | 352 | if (c == 'V') |
352 | expect_close = 42; | 353 | expect_close = 42; |
353 | } | ||
354 | } | 354 | } |
355 | } | 355 | } |
356 | 356 | ||
@@ -377,8 +377,7 @@ static struct watchdog_info ident = { | |||
377 | .identity = WATCHDOG_NAME, | 377 | .identity = WATCHDOG_NAME, |
378 | }; | 378 | }; |
379 | 379 | ||
380 | static int wdt_ioctl(struct inode *inode, struct file *file, | 380 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
381 | unsigned int cmd, unsigned long arg) | ||
382 | { | 381 | { |
383 | int status; | 382 | int status; |
384 | int new_options, retval = -EINVAL; | 383 | int new_options, retval = -EINVAL; |
@@ -390,13 +389,13 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
390 | 389 | ||
391 | uarg.i = (int __user *)arg; | 390 | uarg.i = (int __user *)arg; |
392 | 391 | ||
393 | switch(cmd) | 392 | switch (cmd) { |
394 | { | ||
395 | default: | 393 | default: |
396 | return -ENOTTY; | 394 | return -ENOTTY; |
397 | 395 | ||
398 | case WDIOC_GETSUPPORT: | 396 | case WDIOC_GETSUPPORT: |
399 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; | 397 | return copy_to_user(uarg.ident, &ident, |
398 | sizeof(ident)) ? -EFAULT : 0; | ||
400 | 399 | ||
401 | case WDIOC_GETSTATUS: | 400 | case WDIOC_GETSTATUS: |
402 | wdt_get_status(&status); | 401 | wdt_get_status(&status); |
@@ -410,7 +409,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
410 | return 0; | 409 | return 0; |
411 | 410 | ||
412 | case WDIOC_SETOPTIONS: | 411 | case WDIOC_SETOPTIONS: |
413 | if (get_user (new_options, uarg.i)) | 412 | if (get_user(new_options, uarg.i)) |
414 | return -EFAULT; | 413 | return -EFAULT; |
415 | 414 | ||
416 | if (new_options & WDIOS_DISABLECARD) { | 415 | if (new_options & WDIOS_DISABLECARD) { |
@@ -444,23 +443,21 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
444 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 443 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
445 | void *unused) | 444 | void *unused) |
446 | { | 445 | { |
447 | if (code==SYS_DOWN || code==SYS_HALT) | 446 | if (code == SYS_DOWN || code == SYS_HALT) |
448 | wdt_stop(); | 447 | wdt_stop(); |
449 | return NOTIFY_DONE; | 448 | return NOTIFY_DONE; |
450 | } | 449 | } |
451 | 450 | ||
452 | static const struct file_operations wdt_fops= | 451 | static const struct file_operations wdt_fops = { |
453 | { | ||
454 | .owner = THIS_MODULE, | 452 | .owner = THIS_MODULE, |
455 | .llseek = no_llseek, | 453 | .llseek = no_llseek, |
456 | .write = wdt_write, | 454 | .write = wdt_write, |
457 | .ioctl = wdt_ioctl, | 455 | .unlocked_ioctl = wdt_ioctl, |
458 | .open = wdt_open, | 456 | .open = wdt_open, |
459 | .release = wdt_release, | 457 | .release = wdt_release, |
460 | }; | 458 | }; |
461 | 459 | ||
462 | static struct miscdevice wdt_miscdev= | 460 | static struct miscdevice wdt_miscdev = { |
463 | { | ||
464 | .minor = WATCHDOG_MINOR, | 461 | .minor = WATCHDOG_MINOR, |
465 | .name = "watchdog", | 462 | .name = "watchdog", |
466 | .fops = &wdt_fops, | 463 | .fops = &wdt_fops, |
@@ -474,20 +471,20 @@ static int __init w83977f_wdt_init(void) | |||
474 | { | 471 | { |
475 | int rc; | 472 | int rc; |
476 | 473 | ||
477 | printk(KERN_INFO PFX DRIVER_VERSION); | 474 | printk(KERN_INFO PFX DRIVER_VERSION); |
478 | 475 | ||
479 | /* | 476 | /* |
480 | * Check that the timeout value is within it's range ; | 477 | * Check that the timeout value is within it's range; |
481 | * if not reset to the default | 478 | * if not reset to the default |
482 | */ | 479 | */ |
483 | if (wdt_set_timeout(timeout)) { | 480 | if (wdt_set_timeout(timeout)) { |
484 | wdt_set_timeout(DEFAULT_TIMEOUT); | 481 | wdt_set_timeout(DEFAULT_TIMEOUT); |
485 | printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n", | 482 | printk(KERN_INFO PFX |
486 | DEFAULT_TIMEOUT); | 483 | "timeout value must be 15 <= timeout <= 7635, using %d\n", |
484 | DEFAULT_TIMEOUT); | ||
487 | } | 485 | } |
488 | 486 | ||
489 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) | 487 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) { |
490 | { | ||
491 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 488 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
492 | IO_INDEX_PORT); | 489 | IO_INDEX_PORT); |
493 | rc = -EIO; | 490 | rc = -EIO; |
@@ -495,30 +492,30 @@ static int __init w83977f_wdt_init(void) | |||
495 | } | 492 | } |
496 | 493 | ||
497 | rc = register_reboot_notifier(&wdt_notifier); | 494 | rc = register_reboot_notifier(&wdt_notifier); |
498 | if (rc) | 495 | if (rc) { |
499 | { | 496 | printk(KERN_ERR PFX |
500 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 497 | "cannot register reboot notifier (err=%d)\n", rc); |
501 | rc); | ||
502 | goto err_out_region; | 498 | goto err_out_region; |
503 | } | 499 | } |
504 | 500 | ||
505 | rc = misc_register(&wdt_miscdev); | 501 | rc = misc_register(&wdt_miscdev); |
506 | if (rc) | 502 | if (rc) { |
507 | { | 503 | printk(KERN_ERR PFX |
508 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 504 | "cannot register miscdev on minor=%d (err=%d)\n", |
509 | wdt_miscdev.minor, rc); | 505 | wdt_miscdev.minor, rc); |
510 | goto err_out_reboot; | 506 | goto err_out_reboot; |
511 | } | 507 | } |
512 | 508 | ||
513 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", | 509 | printk(KERN_INFO PFX |
514 | timeout, nowayout, testmode); | 510 | "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", |
511 | timeout, nowayout, testmode); | ||
515 | 512 | ||
516 | return 0; | 513 | return 0; |
517 | 514 | ||
518 | err_out_reboot: | 515 | err_out_reboot: |
519 | unregister_reboot_notifier(&wdt_notifier); | 516 | unregister_reboot_notifier(&wdt_notifier); |
520 | err_out_region: | 517 | err_out_region: |
521 | release_region(IO_INDEX_PORT,2); | 518 | release_region(IO_INDEX_PORT, 2); |
522 | err_out: | 519 | err_out: |
523 | return rc; | 520 | return rc; |
524 | } | 521 | } |
@@ -528,7 +525,7 @@ static void __exit w83977f_wdt_exit(void) | |||
528 | wdt_stop(); | 525 | wdt_stop(); |
529 | misc_deregister(&wdt_miscdev); | 526 | misc_deregister(&wdt_miscdev); |
530 | unregister_reboot_notifier(&wdt_notifier); | 527 | unregister_reboot_notifier(&wdt_notifier); |
531 | release_region(IO_INDEX_PORT,2); | 528 | release_region(IO_INDEX_PORT, 2); |
532 | } | 529 | } |
533 | 530 | ||
534 | module_init(w83977f_wdt_init); | 531 | module_init(w83977f_wdt_init); |
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c index 9e368091f799..886cbbcf3eed 100644 --- a/drivers/watchdog/wafer5823wdt.c +++ b/drivers/watchdog/wafer5823wdt.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <asm/io.h> | 39 | #include <linux/io.h> |
40 | #include <asm/uaccess.h> | 40 | #include <linux/uaccess.h> |
41 | 41 | ||
42 | #define WATCHDOG_NAME "Wafer 5823 WDT" | 42 | #define WATCHDOG_NAME "Wafer 5823 WDT" |
43 | #define PFX WATCHDOG_NAME ": " | 43 | #define PFX WATCHDOG_NAME ": " |
@@ -61,11 +61,15 @@ static int wdt_start = 0x443; | |||
61 | 61 | ||
62 | static int timeout = WD_TIMO; /* in seconds */ | 62 | static int timeout = WD_TIMO; /* in seconds */ |
63 | module_param(timeout, int, 0); | 63 | module_param(timeout, int, 0); |
64 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); | 64 | MODULE_PARM_DESC(timeout, |
65 | "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" | ||
66 | __MODULE_STRING(WD_TIMO) "."); | ||
65 | 67 | ||
66 | static int nowayout = WATCHDOG_NOWAYOUT; | 68 | static int nowayout = WATCHDOG_NOWAYOUT; |
67 | module_param(nowayout, int, 0); | 69 | module_param(nowayout, int, 0); |
68 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 70 | MODULE_PARM_DESC(nowayout, |
71 | "Watchdog cannot be stopped once started (default=" | ||
72 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
69 | 73 | ||
70 | static void wafwdt_ping(void) | 74 | static void wafwdt_ping(void) |
71 | { | 75 | { |
@@ -90,7 +94,8 @@ wafwdt_stop(void) | |||
90 | inb_p(wdt_stop); | 94 | inb_p(wdt_stop); |
91 | } | 95 | } |
92 | 96 | ||
93 | static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) | 97 | static ssize_t wafwdt_write(struct file *file, const char __user *buf, |
98 | size_t count, loff_t *ppos) | ||
94 | { | 99 | { |
95 | /* See if we got the magic character 'V' and reload the timer */ | 100 | /* See if we got the magic character 'V' and reload the timer */ |
96 | if (count) { | 101 | if (count) { |
@@ -100,7 +105,8 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co | |||
100 | /* In case it was set long ago */ | 105 | /* In case it was set long ago */ |
101 | expect_close = 0; | 106 | expect_close = 0; |
102 | 107 | ||
103 | /* scan to see whether or not we got the magic character */ | 108 | /* scan to see whether or not we got the magic |
109 | character */ | ||
104 | for (i = 0; i != count; i++) { | 110 | for (i = 0; i != count; i++) { |
105 | char c; | 111 | char c; |
106 | if (get_user(c, buf + i)) | 112 | if (get_user(c, buf + i)) |
@@ -109,27 +115,29 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co | |||
109 | expect_close = 42; | 115 | expect_close = 42; |
110 | } | 116 | } |
111 | } | 117 | } |
112 | /* Well, anyhow someone wrote to us, we should return that favour */ | 118 | /* Well, anyhow someone wrote to us, we should |
119 | return that favour */ | ||
113 | wafwdt_ping(); | 120 | wafwdt_ping(); |
114 | } | 121 | } |
115 | return count; | 122 | return count; |
116 | } | 123 | } |
117 | 124 | ||
118 | static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 125 | static long wafwdt_ioctl(struct file *file, unsigned int cmd, |
119 | unsigned long arg) | 126 | unsigned long arg) |
120 | { | 127 | { |
121 | int new_timeout; | 128 | int new_timeout; |
122 | void __user *argp = (void __user *)arg; | 129 | void __user *argp = (void __user *)arg; |
123 | int __user *p = argp; | 130 | int __user *p = argp; |
124 | static struct watchdog_info ident = { | 131 | static const struct watchdog_info ident = { |
125 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 132 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
133 | WDIOF_MAGICCLOSE, | ||
126 | .firmware_version = 1, | 134 | .firmware_version = 1, |
127 | .identity = "Wafer 5823 WDT", | 135 | .identity = "Wafer 5823 WDT", |
128 | }; | 136 | }; |
129 | 137 | ||
130 | switch (cmd) { | 138 | switch (cmd) { |
131 | case WDIOC_GETSUPPORT: | 139 | case WDIOC_GETSUPPORT: |
132 | if (copy_to_user(argp, &ident, sizeof (ident))) | 140 | if (copy_to_user(argp, &ident, sizeof(ident))) |
133 | return -EFAULT; | 141 | return -EFAULT; |
134 | break; | 142 | break; |
135 | 143 | ||
@@ -194,10 +202,11 @@ static int wafwdt_open(struct inode *inode, struct file *file) | |||
194 | static int | 202 | static int |
195 | wafwdt_close(struct inode *inode, struct file *file) | 203 | wafwdt_close(struct inode *inode, struct file *file) |
196 | { | 204 | { |
197 | if (expect_close == 42) { | 205 | if (expect_close == 42) |
198 | wafwdt_stop(); | 206 | wafwdt_stop(); |
199 | } else { | 207 | else { |
200 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 208 | printk(KERN_CRIT PFX |
209 | "WDT device closed unexpectedly. WDT will not stop!\n"); | ||
201 | wafwdt_ping(); | 210 | wafwdt_ping(); |
202 | } | 211 | } |
203 | clear_bit(0, &wafwdt_is_open); | 212 | clear_bit(0, &wafwdt_is_open); |
@@ -209,12 +218,11 @@ wafwdt_close(struct inode *inode, struct file *file) | |||
209 | * Notifier for system down | 218 | * Notifier for system down |
210 | */ | 219 | */ |
211 | 220 | ||
212 | static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 221 | static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, |
222 | void *unused) | ||
213 | { | 223 | { |
214 | if (code == SYS_DOWN || code == SYS_HALT) { | 224 | if (code == SYS_DOWN || code == SYS_HALT) |
215 | /* Turn the WDT off */ | ||
216 | wafwdt_stop(); | 225 | wafwdt_stop(); |
217 | } | ||
218 | return NOTIFY_DONE; | 226 | return NOTIFY_DONE; |
219 | } | 227 | } |
220 | 228 | ||
@@ -226,7 +234,7 @@ static const struct file_operations wafwdt_fops = { | |||
226 | .owner = THIS_MODULE, | 234 | .owner = THIS_MODULE, |
227 | .llseek = no_llseek, | 235 | .llseek = no_llseek, |
228 | .write = wafwdt_write, | 236 | .write = wafwdt_write, |
229 | .ioctl = wafwdt_ioctl, | 237 | .unlocked_ioctl = wafwdt_ioctl, |
230 | .open = wafwdt_open, | 238 | .open = wafwdt_open, |
231 | .release = wafwdt_close, | 239 | .release = wafwdt_close, |
232 | }; | 240 | }; |
@@ -250,25 +258,28 @@ static int __init wafwdt_init(void) | |||
250 | { | 258 | { |
251 | int ret; | 259 | int ret; |
252 | 260 | ||
253 | printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); | 261 | printk(KERN_INFO |
262 | "WDT driver for Wafer 5823 single board computer initialising.\n"); | ||
254 | 263 | ||
255 | if (timeout < 1 || timeout > 255) { | 264 | if (timeout < 1 || timeout > 255) { |
256 | timeout = WD_TIMO; | 265 | timeout = WD_TIMO; |
257 | printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", | 266 | printk(KERN_INFO PFX |
258 | timeout); | 267 | "timeout value must be 1 <= x <= 255, using %d\n", |
268 | timeout); | ||
259 | } | 269 | } |
260 | 270 | ||
261 | if (wdt_stop != wdt_start) { | 271 | if (wdt_stop != wdt_start) { |
262 | if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { | 272 | if (!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { |
263 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 273 | printk(KERN_ERR PFX |
264 | wdt_stop); | 274 | "I/O address 0x%04x already in use\n", |
275 | wdt_stop); | ||
265 | ret = -EIO; | 276 | ret = -EIO; |
266 | goto error; | 277 | goto error; |
267 | } | 278 | } |
268 | } | 279 | } |
269 | 280 | ||
270 | if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { | 281 | if (!request_region(wdt_start, 1, "Wafer 5823 WDT")) { |
271 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 282 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
272 | wdt_start); | 283 | wdt_start); |
273 | ret = -EIO; | 284 | ret = -EIO; |
274 | goto error2; | 285 | goto error2; |
@@ -276,19 +287,20 @@ static int __init wafwdt_init(void) | |||
276 | 287 | ||
277 | ret = register_reboot_notifier(&wafwdt_notifier); | 288 | ret = register_reboot_notifier(&wafwdt_notifier); |
278 | if (ret != 0) { | 289 | if (ret != 0) { |
279 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 290 | printk(KERN_ERR PFX |
280 | ret); | 291 | "cannot register reboot notifier (err=%d)\n", ret); |
281 | goto error3; | 292 | goto error3; |
282 | } | 293 | } |
283 | 294 | ||
284 | ret = misc_register(&wafwdt_miscdev); | 295 | ret = misc_register(&wafwdt_miscdev); |
285 | if (ret != 0) { | 296 | if (ret != 0) { |
286 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 297 | printk(KERN_ERR PFX |
287 | WATCHDOG_MINOR, ret); | 298 | "cannot register miscdev on minor=%d (err=%d)\n", |
299 | WATCHDOG_MINOR, ret); | ||
288 | goto error4; | 300 | goto error4; |
289 | } | 301 | } |
290 | 302 | ||
291 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 303 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", |
292 | timeout, nowayout); | 304 | timeout, nowayout); |
293 | 305 | ||
294 | return ret; | 306 | return ret; |
@@ -307,7 +319,7 @@ static void __exit wafwdt_exit(void) | |||
307 | { | 319 | { |
308 | misc_deregister(&wafwdt_miscdev); | 320 | misc_deregister(&wafwdt_miscdev); |
309 | unregister_reboot_notifier(&wafwdt_notifier); | 321 | unregister_reboot_notifier(&wafwdt_notifier); |
310 | if(wdt_stop != wdt_start) | 322 | if (wdt_stop != wdt_start) |
311 | release_region(wdt_stop, 1); | 323 | release_region(wdt_stop, 1); |
312 | release_region(wdt_start, 1); | 324 | release_region(wdt_start, 1); |
313 | } | 325 | } |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 1d64e277567d..20fd6715f25f 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include <linux/reboot.h> | 35 | #include <linux/reboot.h> |
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/watchdog.h> | 37 | #include <linux/watchdog.h> |
38 | #include <linux/uaccess.h> | ||
38 | 39 | ||
39 | #include <asm/rtas.h> | 40 | #include <asm/rtas.h> |
40 | #include <asm/uaccess.h> | ||
41 | 41 | ||
42 | #define WDRTAS_MAGIC_CHAR 42 | 42 | #define WDRTAS_MAGIC_CHAR 42 |
43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ | 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ |
@@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0; | |||
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); | 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); |
59 | static char wdrtas_expect_close = 0; | 59 | static char wdrtas_expect_close; |
60 | 60 | ||
61 | static int wdrtas_interval; | 61 | static int wdrtas_interval; |
62 | 62 | ||
@@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN]; | |||
86 | * RTAS function set-indicator (surveillance). The unit of interval is | 86 | * RTAS function set-indicator (surveillance). The unit of interval is |
87 | * seconds. | 87 | * seconds. |
88 | */ | 88 | */ |
89 | static int | 89 | |
90 | wdrtas_set_interval(int interval) | 90 | static int wdrtas_set_interval(int interval) |
91 | { | 91 | { |
92 | long result; | 92 | long result; |
93 | static int print_msg = 10; | 93 | static int print_msg = 10; |
@@ -97,7 +97,7 @@ wdrtas_set_interval(int interval) | |||
97 | 97 | ||
98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, | 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, |
99 | WDRTAS_SURVEILLANCE_IND, 0, interval); | 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); |
100 | if ( (result < 0) && (print_msg) ) { | 100 | if (result < 0 && print_msg) { |
101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " | 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " |
102 | "timeout failed: %li\n", interval, result); | 102 | "timeout failed: %li\n", interval, result); |
103 | print_msg--; | 103 | print_msg--; |
@@ -116,16 +116,14 @@ wdrtas_set_interval(int interval) | |||
116 | * as reported by the RTAS function ibm,get-system-parameter. The unit | 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit |
117 | * of the return value is seconds. | 117 | * of the return value is seconds. |
118 | */ | 118 | */ |
119 | static int | 119 | static int wdrtas_get_interval(int fallback_value) |
120 | wdrtas_get_interval(int fallback_value) | ||
121 | { | 120 | { |
122 | long result; | 121 | long result; |
123 | char value[4]; | 122 | char value[4]; |
124 | 123 | ||
125 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, | 124 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, |
126 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); | 125 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); |
127 | if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || | 126 | if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) { |
128 | (result < 0) ) { | ||
129 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " | 127 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " |
130 | "timeout (%li). Continuing\n", result); | 128 | "timeout (%li). Continuing\n", result); |
131 | return fallback_value; | 129 | return fallback_value; |
@@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value) | |||
141 | * wdrtas_timer_start starts the watchdog by calling the RTAS function | 139 | * wdrtas_timer_start starts the watchdog by calling the RTAS function |
142 | * set-interval (surveillance) | 140 | * set-interval (surveillance) |
143 | */ | 141 | */ |
144 | static void | 142 | static void wdrtas_timer_start(void) |
145 | wdrtas_timer_start(void) | ||
146 | { | 143 | { |
147 | wdrtas_set_interval(wdrtas_interval); | 144 | wdrtas_set_interval(wdrtas_interval); |
148 | } | 145 | } |
@@ -153,8 +150,7 @@ wdrtas_timer_start(void) | |||
153 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function | 150 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function |
154 | * set-interval (surveillance) | 151 | * set-interval (surveillance) |
155 | */ | 152 | */ |
156 | static void | 153 | static void wdrtas_timer_stop(void) |
157 | wdrtas_timer_stop(void) | ||
158 | { | 154 | { |
159 | wdrtas_set_interval(0); | 155 | wdrtas_set_interval(0); |
160 | } | 156 | } |
@@ -165,8 +161,7 @@ wdrtas_timer_stop(void) | |||
165 | * wdrtas_log_scanned_event prints a message to the log buffer dumping | 161 | * wdrtas_log_scanned_event prints a message to the log buffer dumping |
166 | * the results of the last event-scan call | 162 | * the results of the last event-scan call |
167 | */ | 163 | */ |
168 | static void | 164 | static void wdrtas_log_scanned_event(void) |
169 | wdrtas_log_scanned_event(void) | ||
170 | { | 165 | { |
171 | int i; | 166 | int i; |
172 | 167 | ||
@@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void) | |||
175 | "%02x %02x %02x %02x %02x %02x %02x %02x " | 170 | "%02x %02x %02x %02x %02x %02x %02x %02x " |
176 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 171 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
177 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), | 172 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), |
178 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], | 173 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], |
179 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], | 174 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], |
180 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], | 175 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], |
181 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], | 176 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], |
182 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], | 177 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], |
183 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], | 178 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], |
184 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], | 179 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], |
185 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); | 180 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); |
186 | } | 181 | } |
187 | 182 | ||
@@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void) | |||
192 | * RTAS function event-scan and repeats these calls as long as there are | 187 | * RTAS function event-scan and repeats these calls as long as there are |
193 | * events available. All events will be dumped. | 188 | * events available. All events will be dumped. |
194 | */ | 189 | */ |
195 | static void | 190 | static void wdrtas_timer_keepalive(void) |
196 | wdrtas_timer_keepalive(void) | ||
197 | { | 191 | { |
198 | long result; | 192 | long result; |
199 | 193 | ||
@@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void) | |||
218 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It | 212 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It |
219 | * uses the RTAS call get-sensor-state, token 3 to do so | 213 | * uses the RTAS call get-sensor-state, token 3 to do so |
220 | */ | 214 | */ |
221 | static int | 215 | static int wdrtas_get_temperature(void) |
222 | wdrtas_get_temperature(void) | ||
223 | { | 216 | { |
224 | long result; | 217 | long result; |
225 | int temperature = 0; | 218 | int temperature = 0; |
@@ -243,8 +236,7 @@ wdrtas_get_temperature(void) | |||
243 | * returns a bitmask of defines WDIOF_... as defined in | 236 | * returns a bitmask of defines WDIOF_... as defined in |
244 | * include/linux/watchdog.h | 237 | * include/linux/watchdog.h |
245 | */ | 238 | */ |
246 | static int | 239 | static int wdrtas_get_status(void) |
247 | wdrtas_get_status(void) | ||
248 | { | 240 | { |
249 | return 0; /* TODO */ | 241 | return 0; /* TODO */ |
250 | } | 242 | } |
@@ -255,8 +247,7 @@ wdrtas_get_status(void) | |||
255 | * returns a bitmask of defines WDIOF_... as defined in | 247 | * returns a bitmask of defines WDIOF_... as defined in |
256 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system | 248 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system |
257 | */ | 249 | */ |
258 | static int | 250 | static int wdrtas_get_boot_status(void) |
259 | wdrtas_get_boot_status(void) | ||
260 | { | 251 | { |
261 | return 0; /* TODO */ | 252 | return 0; /* TODO */ |
262 | } | 253 | } |
@@ -276,8 +267,7 @@ wdrtas_get_boot_status(void) | |||
276 | * character 'V'. This character allows the watchdog device to be closed | 267 | * character 'V'. This character allows the watchdog device to be closed |
277 | * properly. | 268 | * properly. |
278 | */ | 269 | */ |
279 | static ssize_t | 270 | static ssize_t wdrtas_write(struct file *file, const char __user *buf, |
280 | wdrtas_write(struct file *file, const char __user *buf, | ||
281 | size_t len, loff_t *ppos) | 271 | size_t len, loff_t *ppos) |
282 | { | 272 | { |
283 | int i; | 273 | int i; |
@@ -306,7 +296,6 @@ out: | |||
306 | 296 | ||
307 | /** | 297 | /** |
308 | * wdrtas_ioctl - ioctl function for the watchdog device | 298 | * wdrtas_ioctl - ioctl function for the watchdog device |
309 | * @inode: inode structure | ||
310 | * @file: file structure | 299 | * @file: file structure |
311 | * @cmd: command for ioctl | 300 | * @cmd: command for ioctl |
312 | * @arg: argument pointer | 301 | * @arg: argument pointer |
@@ -315,9 +304,9 @@ out: | |||
315 | * | 304 | * |
316 | * wdrtas_ioctl implements the watchdog API ioctls | 305 | * wdrtas_ioctl implements the watchdog API ioctls |
317 | */ | 306 | */ |
318 | static int | 307 | |
319 | wdrtas_ioctl(struct inode *inode, struct file *file, | 308 | static long wdrtas_ioctl(struct file *file, unsigned int cmd, |
320 | unsigned int cmd, unsigned long arg) | 309 | unsigned long arg) |
321 | { | 310 | { |
322 | int __user *argp = (void __user *)arg; | 311 | int __user *argp = (void __user *)arg; |
323 | int i; | 312 | int i; |
@@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
357 | wdrtas_timer_keepalive(); | 346 | wdrtas_timer_keepalive(); |
358 | wdrtas_timer_start(); | 347 | wdrtas_timer_start(); |
359 | } | 348 | } |
349 | /* not implemented. Done by H8 | ||
360 | if (i & WDIOS_TEMPPANIC) { | 350 | if (i & WDIOS_TEMPPANIC) { |
361 | /* not implemented. Done by H8 */ | 351 | } */ |
362 | } | ||
363 | return 0; | 352 | return 0; |
364 | 353 | ||
365 | case WDIOC_KEEPALIVE: | 354 | case WDIOC_KEEPALIVE: |
@@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
399 | * | 388 | * |
400 | * function called when watchdog device is opened | 389 | * function called when watchdog device is opened |
401 | */ | 390 | */ |
402 | static int | 391 | static int wdrtas_open(struct inode *inode, struct file *file) |
403 | wdrtas_open(struct inode *inode, struct file *file) | ||
404 | { | 392 | { |
405 | /* only open once */ | 393 | /* only open once */ |
406 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { | 394 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { |
@@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file) | |||
423 | * | 411 | * |
424 | * close function. Always succeeds | 412 | * close function. Always succeeds |
425 | */ | 413 | */ |
426 | static int | 414 | static int wdrtas_close(struct inode *inode, struct file *file) |
427 | wdrtas_close(struct inode *inode, struct file *file) | ||
428 | { | 415 | { |
429 | /* only stop watchdog, if this was announced using 'V' before */ | 416 | /* only stop watchdog, if this was announced using 'V' before */ |
430 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) | 417 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) |
@@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file) | |||
453 | * wdrtas_temp_read gives the temperature to the users by copying this | 440 | * wdrtas_temp_read gives the temperature to the users by copying this |
454 | * value as one byte into the user space buffer. The unit is Fahrenheit... | 441 | * value as one byte into the user space buffer. The unit is Fahrenheit... |
455 | */ | 442 | */ |
456 | static ssize_t | 443 | static ssize_t wdrtas_temp_read(struct file *file, char __user *buf, |
457 | wdrtas_temp_read(struct file *file, char __user *buf, | ||
458 | size_t count, loff_t *ppos) | 444 | size_t count, loff_t *ppos) |
459 | { | 445 | { |
460 | int temperature = 0; | 446 | int temperature = 0; |
@@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf, | |||
478 | * | 464 | * |
479 | * function called when temperature device is opened | 465 | * function called when temperature device is opened |
480 | */ | 466 | */ |
481 | static int | 467 | static int wdrtas_temp_open(struct inode *inode, struct file *file) |
482 | wdrtas_temp_open(struct inode *inode, struct file *file) | ||
483 | { | 468 | { |
484 | return nonseekable_open(inode, file); | 469 | return nonseekable_open(inode, file); |
485 | } | 470 | } |
@@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file) | |||
493 | * | 478 | * |
494 | * close function. Always succeeds | 479 | * close function. Always succeeds |
495 | */ | 480 | */ |
496 | static int | 481 | static int wdrtas_temp_close(struct inode *inode, struct file *file) |
497 | wdrtas_temp_close(struct inode *inode, struct file *file) | ||
498 | { | 482 | { |
499 | return 0; | 483 | return 0; |
500 | } | 484 | } |
@@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file) | |||
509 | * | 493 | * |
510 | * wdrtas_reboot stops the watchdog in case of a reboot | 494 | * wdrtas_reboot stops the watchdog in case of a reboot |
511 | */ | 495 | */ |
512 | static int | 496 | static int wdrtas_reboot(struct notifier_block *this, |
513 | wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | 497 | unsigned long code, void *ptr) |
514 | { | 498 | { |
515 | if ( (code==SYS_DOWN) || (code==SYS_HALT) ) | 499 | if (code == SYS_DOWN || code == SYS_HALT) |
516 | wdrtas_timer_stop(); | 500 | wdrtas_timer_stop(); |
517 | 501 | ||
518 | return NOTIFY_DONE; | 502 | return NOTIFY_DONE; |
@@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = { | |||
524 | .owner = THIS_MODULE, | 508 | .owner = THIS_MODULE, |
525 | .llseek = no_llseek, | 509 | .llseek = no_llseek, |
526 | .write = wdrtas_write, | 510 | .write = wdrtas_write, |
527 | .ioctl = wdrtas_ioctl, | 511 | .unlocked_ioctl = wdrtas_ioctl, |
528 | .open = wdrtas_open, | 512 | .open = wdrtas_open, |
529 | .release = wdrtas_close, | 513 | .release = wdrtas_close, |
530 | }; | 514 | }; |
@@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = { | |||
562 | * this watchdog driver. It tolerates, if "get-sensor-state" and | 546 | * this watchdog driver. It tolerates, if "get-sensor-state" and |
563 | * "ibm,get-system-parameter" are not available. | 547 | * "ibm,get-system-parameter" are not available. |
564 | */ | 548 | */ |
565 | static int | 549 | static int wdrtas_get_tokens(void) |
566 | wdrtas_get_tokens(void) | ||
567 | { | 550 | { |
568 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); | 551 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); |
569 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { | 552 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { |
@@ -603,8 +586,7 @@ wdrtas_get_tokens(void) | |||
603 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog | 586 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog |
604 | * misc devs | 587 | * misc devs |
605 | */ | 588 | */ |
606 | static void | 589 | static void wdrtas_unregister_devs(void) |
607 | wdrtas_unregister_devs(void) | ||
608 | { | 590 | { |
609 | misc_deregister(&wdrtas_miscdev); | 591 | misc_deregister(&wdrtas_miscdev); |
610 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) | 592 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) |
@@ -619,8 +601,7 @@ wdrtas_unregister_devs(void) | |||
619 | * wdrtas_register_devs registers the watchdog and temperature watchdog | 601 | * wdrtas_register_devs registers the watchdog and temperature watchdog |
620 | * misc devs | 602 | * misc devs |
621 | */ | 603 | */ |
622 | static int | 604 | static int wdrtas_register_devs(void) |
623 | wdrtas_register_devs(void) | ||
624 | { | 605 | { |
625 | int result; | 606 | int result; |
626 | 607 | ||
@@ -651,8 +632,7 @@ wdrtas_register_devs(void) | |||
651 | * | 632 | * |
652 | * registers the file handlers and the reboot notifier | 633 | * registers the file handlers and the reboot notifier |
653 | */ | 634 | */ |
654 | static int __init | 635 | static int __init wdrtas_init(void) |
655 | wdrtas_init(void) | ||
656 | { | 636 | { |
657 | if (wdrtas_get_tokens()) | 637 | if (wdrtas_get_tokens()) |
658 | return -ENODEV; | 638 | return -ENODEV; |
@@ -680,8 +660,7 @@ wdrtas_init(void) | |||
680 | * | 660 | * |
681 | * unregisters the file handlers and the reboot notifier | 661 | * unregisters the file handlers and the reboot notifier |
682 | */ | 662 | */ |
683 | static void __exit | 663 | static void __exit wdrtas_exit(void) |
684 | wdrtas_exit(void) | ||
685 | { | 664 | { |
686 | if (!wdrtas_nowayout) | 665 | if (!wdrtas_nowayout) |
687 | wdrtas_timer_stop(); | 666 | wdrtas_timer_stop(); |
diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index e4cf661dc890..fea398a4ca32 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c | |||
@@ -26,9 +26,9 @@ | |||
26 | #include <linux/reboot.h> | 26 | #include <linux/reboot.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/uaccess.h> | ||
30 | #include <linux/irq.h> | ||
29 | 31 | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/uaccess.h> | ||
32 | #include <asm/hardware.h> | 32 | #include <asm/hardware.h> |
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | #include <asm/hardware/dec21285.h> | 34 | #include <asm/hardware/dec21285.h> |
@@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file) | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | static ssize_t | 118 | static ssize_t watchdog_write(struct file *file, const char *data, |
119 | watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 119 | size_t len, loff_t *ppos) |
120 | { | 120 | { |
121 | /* | 121 | /* |
122 | * Refresh the timer. | 122 | * Refresh the timer. |
@@ -127,19 +127,18 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
127 | return len; | 127 | return len; |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct watchdog_info ident = { | 130 | static const struct watchdog_info ident = { |
131 | .options = WDIOF_SETTIMEOUT, | 131 | .options = WDIOF_SETTIMEOUT, |
132 | .identity = "Footbridge Watchdog", | 132 | .identity = "Footbridge Watchdog", |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static int | 135 | static long watchdog_ioctl(struct file *file, unsigned int cmd, |
136 | watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 136 | unsigned long arg) |
137 | unsigned long arg) | ||
138 | { | 137 | { |
139 | unsigned int new_margin; | 138 | unsigned int new_margin; |
140 | int ret = -ENOTTY; | 139 | int ret = -ENOTTY; |
141 | 140 | ||
142 | switch(cmd) { | 141 | switch (cmd) { |
143 | case WDIOC_GETSUPPORT: | 142 | case WDIOC_GETSUPPORT: |
144 | ret = 0; | 143 | ret = 0; |
145 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) | 144 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) |
@@ -148,7 +147,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
148 | 147 | ||
149 | case WDIOC_GETSTATUS: | 148 | case WDIOC_GETSTATUS: |
150 | case WDIOC_GETBOOTSTATUS: | 149 | case WDIOC_GETBOOTSTATUS: |
151 | ret = put_user(0,(int *)arg); | 150 | ret = put_user(0, (int *)arg); |
152 | break; | 151 | break; |
153 | 152 | ||
154 | case WDIOC_KEEPALIVE: | 153 | case WDIOC_KEEPALIVE: |
@@ -182,7 +181,7 @@ static const struct file_operations watchdog_fops = { | |||
182 | .owner = THIS_MODULE, | 181 | .owner = THIS_MODULE, |
183 | .llseek = no_llseek, | 182 | .llseek = no_llseek, |
184 | .write = watchdog_write, | 183 | .write = watchdog_write, |
185 | .ioctl = watchdog_ioctl, | 184 | .unlocked_ioctl = watchdog_ioctl, |
186 | .open = watchdog_open, | 185 | .open = watchdog_open, |
187 | .release = watchdog_release, | 186 | .release = watchdog_release, |
188 | }; | 187 | }; |
@@ -204,11 +203,13 @@ static int __init footbridge_watchdog_init(void) | |||
204 | if (retval < 0) | 203 | if (retval < 0) |
205 | return retval; | 204 | return retval; |
206 | 205 | ||
207 | printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", | 206 | printk(KERN_INFO |
208 | soft_margin); | 207 | "Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", |
208 | soft_margin); | ||
209 | 209 | ||
210 | if (machine_is_cats()) | 210 | if (machine_is_cats()) |
211 | printk("Warning: Watchdog reset may not work on this machine.\n"); | 211 | printk(KERN_WARN |
212 | "Warning: Watchdog reset may not work on this machine.\n"); | ||
212 | return 0; | 213 | return 0; |
213 | } | 214 | } |
214 | 215 | ||
@@ -223,7 +224,7 @@ MODULE_LICENSE("GPL"); | |||
223 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 224 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
224 | 225 | ||
225 | module_param(soft_margin, int, 0); | 226 | module_param(soft_margin, int, 0); |
226 | MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds"); | 227 | MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); |
227 | 228 | ||
228 | module_init(footbridge_watchdog_init); | 229 | module_init(footbridge_watchdog_init); |
229 | module_exit(footbridge_watchdog_exit); | 230 | module_exit(footbridge_watchdog_exit); |
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c index fb4b876c9fda..bdc28e522f03 100644 --- a/drivers/watchdog/wdt977.c +++ b/drivers/watchdog/wdt977.c | |||
@@ -19,7 +19,8 @@ | |||
19 | * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in | 19 | * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in |
20 | * nwwatchdog_init. | 20 | * nwwatchdog_init. |
21 | * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks | 21 | * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks |
22 | * remove limitiation to be used on Netwinders only | 22 | * remove limitiation to be used on |
23 | * Netwinders only | ||
23 | */ | 24 | */ |
24 | 25 | ||
25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -33,11 +34,11 @@ | |||
33 | #include <linux/watchdog.h> | 34 | #include <linux/watchdog.h> |
34 | #include <linux/notifier.h> | 35 | #include <linux/notifier.h> |
35 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/io.h> | ||
38 | #include <linux/uaccess.h> | ||
36 | 39 | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/system.h> | 40 | #include <asm/system.h> |
39 | #include <asm/mach-types.h> | 41 | #include <asm/mach-types.h> |
40 | #include <asm/uaccess.h> | ||
41 | 42 | ||
42 | #define WATCHDOG_VERSION "0.04" | 43 | #define WATCHDOG_VERSION "0.04" |
43 | #define WATCHDOG_NAME "Wdt977" | 44 | #define WATCHDOG_NAME "Wdt977" |
@@ -45,7 +46,7 @@ | |||
45 | #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" | 46 | #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" |
46 | 47 | ||
47 | #define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ | 48 | #define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ |
48 | #define IO_DATA_PORT (IO_INDEX_PORT+1) | 49 | #define IO_DATA_PORT (IO_INDEX_PORT + 1) |
49 | 50 | ||
50 | #define UNLOCK_DATA 0x87 | 51 | #define UNLOCK_DATA 0x87 |
51 | #define LOCK_DATA 0xAA | 52 | #define LOCK_DATA 0xAA |
@@ -62,13 +63,16 @@ static char expect_close; | |||
62 | static DEFINE_SPINLOCK(spinlock); | 63 | static DEFINE_SPINLOCK(spinlock); |
63 | 64 | ||
64 | module_param(timeout, int, 0); | 65 | module_param(timeout, int, 0); |
65 | MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | 66 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300), default=" |
67 | __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | ||
66 | module_param(testmode, int, 0); | 68 | module_param(testmode, int, 0); |
67 | MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); | 69 | MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); |
68 | 70 | ||
69 | static int nowayout = WATCHDOG_NOWAYOUT; | 71 | static int nowayout = WATCHDOG_NOWAYOUT; |
70 | module_param(nowayout, int, 0); | 72 | module_param(nowayout, int, 0); |
71 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 73 | MODULE_PARM_DESC(nowayout, |
74 | "Watchdog cannot be stopped once started (default=" | ||
75 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
72 | 76 | ||
73 | /* | 77 | /* |
74 | * Start the watchdog | 78 | * Start the watchdog |
@@ -95,14 +99,16 @@ static int wdt977_start(void) | |||
95 | outb_p(0xF2, IO_INDEX_PORT); | 99 | outb_p(0xF2, IO_INDEX_PORT); |
96 | outb_p(timeoutM, IO_DATA_PORT); | 100 | outb_p(timeoutM, IO_DATA_PORT); |
97 | outb_p(0xF3, IO_INDEX_PORT); | 101 | outb_p(0xF3, IO_INDEX_PORT); |
98 | outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ | 102 | outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for |
103 | kbd/mouse/LED */ | ||
99 | outb_p(0xF4, IO_INDEX_PORT); | 104 | outb_p(0xF4, IO_INDEX_PORT); |
100 | outb_p(0x00, IO_DATA_PORT); | 105 | outb_p(0x00, IO_DATA_PORT); |
101 | 106 | ||
102 | /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ | 107 | /* At last select device Aux1 (dev=7) and set GP16 as a |
103 | /* in test mode watch the bit 1 on F4 to indicate "triggered" */ | 108 | * watchdog output. In test mode watch the bit 1 on F4 to |
104 | if (!testmode) | 109 | * indicate "triggered" |
105 | { | 110 | */ |
111 | if (!testmode) { | ||
106 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); | 112 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
107 | outb_p(0x07, IO_DATA_PORT); | 113 | outb_p(0x07, IO_DATA_PORT); |
108 | outb_p(0xE6, IO_INDEX_PORT); | 114 | outb_p(0xE6, IO_INDEX_PORT); |
@@ -147,7 +153,8 @@ static int wdt977_stop(void) | |||
147 | outb_p(0xF2, IO_INDEX_PORT); | 153 | outb_p(0xF2, IO_INDEX_PORT); |
148 | outb_p(0x00, IO_DATA_PORT); | 154 | outb_p(0x00, IO_DATA_PORT); |
149 | 155 | ||
150 | /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ | 156 | /* at last select device Aux1 (dev=7) and set |
157 | GP16 as a watchdog output */ | ||
151 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); | 158 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
152 | outb_p(0x07, IO_DATA_PORT); | 159 | outb_p(0x07, IO_DATA_PORT); |
153 | outb_p(0xE6, IO_INDEX_PORT); | 160 | outb_p(0xE6, IO_INDEX_PORT); |
@@ -202,16 +209,18 @@ static int wdt977_set_timeout(int t) | |||
202 | tmrval = (t + 59) / 60; | 209 | tmrval = (t + 59) / 60; |
203 | 210 | ||
204 | if (machine_is_netwinder()) { | 211 | if (machine_is_netwinder()) { |
205 | /* we have a hw bug somewhere, so each 977 minute is actually only 30sec | 212 | /* we have a hw bug somewhere, so each 977 minute is actually |
206 | * this limits the max timeout to half of device max of 255 minutes... | 213 | * only 30sec. This limits the max timeout to half of device |
214 | * max of 255 minutes... | ||
207 | */ | 215 | */ |
208 | tmrval += tmrval; | 216 | tmrval += tmrval; |
209 | } | 217 | } |
210 | 218 | ||
211 | if ((tmrval < 1) || (tmrval > 255)) | 219 | if (tmrval < 1 || tmrval > 255) |
212 | return -EINVAL; | 220 | return -EINVAL; |
213 | 221 | ||
214 | /* timeout is the timeout in seconds, timeoutM is the timeout in minutes) */ | 222 | /* timeout is the timeout in seconds, timeoutM is |
223 | the timeout in minutes) */ | ||
215 | timeout = t; | 224 | timeout = t; |
216 | timeoutM = tmrval; | 225 | timeoutM = tmrval; |
217 | return 0; | 226 | return 0; |
@@ -243,7 +252,7 @@ static int wdt977_get_status(int *status) | |||
243 | 252 | ||
244 | spin_unlock_irqrestore(&spinlock, flags); | 253 | spin_unlock_irqrestore(&spinlock, flags); |
245 | 254 | ||
246 | *status=0; | 255 | *status = 0; |
247 | if (new_status & 1) | 256 | if (new_status & 1) |
248 | *status |= WDIOF_CARDRESET; | 257 | *status |= WDIOF_CARDRESET; |
249 | 258 | ||
@@ -258,7 +267,7 @@ static int wdt977_get_status(int *status) | |||
258 | static int wdt977_open(struct inode *inode, struct file *file) | 267 | static int wdt977_open(struct inode *inode, struct file *file) |
259 | { | 268 | { |
260 | /* If the watchdog is alive we don't need to start it again */ | 269 | /* If the watchdog is alive we don't need to start it again */ |
261 | if( test_and_set_bit(0,&timer_alive) ) | 270 | if (test_and_set_bit(0, &timer_alive)) |
262 | return -EBUSY; | 271 | return -EBUSY; |
263 | 272 | ||
264 | if (nowayout) | 273 | if (nowayout) |
@@ -274,13 +283,13 @@ static int wdt977_release(struct inode *inode, struct file *file) | |||
274 | * Shut off the timer. | 283 | * Shut off the timer. |
275 | * Lock it in if it's a module and we set nowayout | 284 | * Lock it in if it's a module and we set nowayout |
276 | */ | 285 | */ |
277 | if (expect_close == 42) | 286 | if (expect_close == 42) { |
278 | { | ||
279 | wdt977_stop(); | 287 | wdt977_stop(); |
280 | clear_bit(0,&timer_alive); | 288 | clear_bit(0, &timer_alive); |
281 | } else { | 289 | } else { |
282 | wdt977_keepalive(); | 290 | wdt977_keepalive(); |
283 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 291 | printk(KERN_CRIT PFX |
292 | "Unexpected close, not stopping watchdog!\n"); | ||
284 | } | 293 | } |
285 | expect_close = 0; | 294 | expect_close = 0; |
286 | return 0; | 295 | return 0; |
@@ -301,17 +310,14 @@ static int wdt977_release(struct inode *inode, struct file *file) | |||
301 | static ssize_t wdt977_write(struct file *file, const char __user *buf, | 310 | static ssize_t wdt977_write(struct file *file, const char __user *buf, |
302 | size_t count, loff_t *ppos) | 311 | size_t count, loff_t *ppos) |
303 | { | 312 | { |
304 | if (count) | 313 | if (count) { |
305 | { | 314 | if (!nowayout) { |
306 | if (!nowayout) | ||
307 | { | ||
308 | size_t i; | 315 | size_t i; |
309 | 316 | ||
310 | /* In case it was set long ago */ | 317 | /* In case it was set long ago */ |
311 | expect_close = 0; | 318 | expect_close = 0; |
312 | 319 | ||
313 | for (i = 0; i != count; i++) | 320 | for (i = 0; i != count; i++) { |
314 | { | ||
315 | char c; | 321 | char c; |
316 | if (get_user(c, buf + i)) | 322 | if (get_user(c, buf + i)) |
317 | return -EFAULT; | 323 | return -EFAULT; |
@@ -326,6 +332,14 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf, | |||
326 | return count; | 332 | return count; |
327 | } | 333 | } |
328 | 334 | ||
335 | static const struct watchdog_info ident = { | ||
336 | .options = WDIOF_SETTIMEOUT | | ||
337 | WDIOF_MAGICCLOSE | | ||
338 | WDIOF_KEEPALIVEPING, | ||
339 | .firmware_version = 1, | ||
340 | .identity = WATCHDOG_NAME, | ||
341 | }; | ||
342 | |||
329 | /* | 343 | /* |
330 | * wdt977_ioctl: | 344 | * wdt977_ioctl: |
331 | * @inode: inode of the device | 345 | * @inode: inode of the device |
@@ -337,16 +351,8 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf, | |||
337 | * according to their available features. | 351 | * according to their available features. |
338 | */ | 352 | */ |
339 | 353 | ||
340 | static struct watchdog_info ident = { | 354 | static long wdt977_ioctl(struct file *file, unsigned int cmd, |
341 | .options = WDIOF_SETTIMEOUT | | 355 | unsigned long arg) |
342 | WDIOF_MAGICCLOSE | | ||
343 | WDIOF_KEEPALIVEPING, | ||
344 | .firmware_version = 1, | ||
345 | .identity = WATCHDOG_NAME, | ||
346 | }; | ||
347 | |||
348 | static int wdt977_ioctl(struct inode *inode, struct file *file, | ||
349 | unsigned int cmd, unsigned long arg) | ||
350 | { | 356 | { |
351 | int status; | 357 | int status; |
352 | int new_options, retval = -EINVAL; | 358 | int new_options, retval = -EINVAL; |
@@ -358,8 +364,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
358 | 364 | ||
359 | uarg.i = (int __user *)arg; | 365 | uarg.i = (int __user *)arg; |
360 | 366 | ||
361 | switch(cmd) | 367 | switch (cmd) { |
362 | { | ||
363 | default: | 368 | default: |
364 | return -ENOTTY; | 369 | return -ENOTTY; |
365 | 370 | ||
@@ -379,7 +384,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
379 | return 0; | 384 | return 0; |
380 | 385 | ||
381 | case WDIOC_SETOPTIONS: | 386 | case WDIOC_SETOPTIONS: |
382 | if (get_user (new_options, uarg.i)) | 387 | if (get_user(new_options, uarg.i)) |
383 | return -EFAULT; | 388 | return -EFAULT; |
384 | 389 | ||
385 | if (new_options & WDIOS_DISABLECARD) { | 390 | if (new_options & WDIOS_DISABLECARD) { |
@@ -413,23 +418,21 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
413 | static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, | 418 | static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, |
414 | void *unused) | 419 | void *unused) |
415 | { | 420 | { |
416 | if(code==SYS_DOWN || code==SYS_HALT) | 421 | if (code == SYS_DOWN || code == SYS_HALT) |
417 | wdt977_stop(); | 422 | wdt977_stop(); |
418 | return NOTIFY_DONE; | 423 | return NOTIFY_DONE; |
419 | } | 424 | } |
420 | 425 | ||
421 | static const struct file_operations wdt977_fops= | 426 | static const struct file_operations wdt977_fops = { |
422 | { | ||
423 | .owner = THIS_MODULE, | 427 | .owner = THIS_MODULE, |
424 | .llseek = no_llseek, | 428 | .llseek = no_llseek, |
425 | .write = wdt977_write, | 429 | .write = wdt977_write, |
426 | .ioctl = wdt977_ioctl, | 430 | .unlocked_ioctl = wdt977_ioctl, |
427 | .open = wdt977_open, | 431 | .open = wdt977_open, |
428 | .release = wdt977_release, | 432 | .release = wdt977_release, |
429 | }; | 433 | }; |
430 | 434 | ||
431 | static struct miscdevice wdt977_miscdev= | 435 | static struct miscdevice wdt977_miscdev = { |
432 | { | ||
433 | .minor = WATCHDOG_MINOR, | 436 | .minor = WATCHDOG_MINOR, |
434 | .name = "watchdog", | 437 | .name = "watchdog", |
435 | .fops = &wdt977_fops, | 438 | .fops = &wdt977_fops, |
@@ -443,51 +446,48 @@ static int __init wd977_init(void) | |||
443 | { | 446 | { |
444 | int rc; | 447 | int rc; |
445 | 448 | ||
446 | //if (!machine_is_netwinder()) | ||
447 | // return -ENODEV; | ||
448 | |||
449 | printk(KERN_INFO PFX DRIVER_VERSION); | 449 | printk(KERN_INFO PFX DRIVER_VERSION); |
450 | 450 | ||
451 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 451 | /* Check that the timeout value is within its range; |
452 | if (wdt977_set_timeout(timeout)) | 452 | if not reset to the default */ |
453 | { | 453 | if (wdt977_set_timeout(timeout)) { |
454 | wdt977_set_timeout(DEFAULT_TIMEOUT); | 454 | wdt977_set_timeout(DEFAULT_TIMEOUT); |
455 | printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n", | 455 | printk(KERN_INFO PFX |
456 | DEFAULT_TIMEOUT); | 456 | "timeout value must be 60 < timeout < 15300, using %d\n", |
457 | DEFAULT_TIMEOUT); | ||
457 | } | 458 | } |
458 | 459 | ||
459 | /* on Netwinder the IOports are already reserved by | 460 | /* on Netwinder the IOports are already reserved by |
460 | * arch/arm/mach-footbridge/netwinder-hw.c | 461 | * arch/arm/mach-footbridge/netwinder-hw.c |
461 | */ | 462 | */ |
462 | if (!machine_is_netwinder()) | 463 | if (!machine_is_netwinder()) { |
463 | { | 464 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) { |
464 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) | 465 | printk(KERN_ERR PFX |
465 | { | 466 | "I/O address 0x%04x already in use\n", |
466 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 467 | IO_INDEX_PORT); |
467 | IO_INDEX_PORT); | ||
468 | rc = -EIO; | 468 | rc = -EIO; |
469 | goto err_out; | 469 | goto err_out; |
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | rc = register_reboot_notifier(&wdt977_notifier); | 473 | rc = register_reboot_notifier(&wdt977_notifier); |
474 | if (rc) | 474 | if (rc) { |
475 | { | 475 | printk(KERN_ERR PFX |
476 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 476 | "cannot register reboot notifier (err=%d)\n", rc); |
477 | rc); | ||
478 | goto err_out_region; | 477 | goto err_out_region; |
479 | } | 478 | } |
480 | 479 | ||
481 | rc = misc_register(&wdt977_miscdev); | 480 | rc = misc_register(&wdt977_miscdev); |
482 | if (rc) | 481 | if (rc) { |
483 | { | 482 | printk(KERN_ERR PFX |
484 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 483 | "cannot register miscdev on minor=%d (err=%d)\n", |
485 | wdt977_miscdev.minor, rc); | 484 | wdt977_miscdev.minor, rc); |
486 | goto err_out_reboot; | 485 | goto err_out_reboot; |
487 | } | 486 | } |
488 | 487 | ||
489 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", | 488 | printk(KERN_INFO PFX |
490 | timeout, nowayout, testmode); | 489 | "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", |
490 | timeout, nowayout, testmode); | ||
491 | 491 | ||
492 | return 0; | 492 | return 0; |
493 | 493 | ||
@@ -495,7 +495,7 @@ err_out_reboot: | |||
495 | unregister_reboot_notifier(&wdt977_notifier); | 495 | unregister_reboot_notifier(&wdt977_notifier); |
496 | err_out_region: | 496 | err_out_region: |
497 | if (!machine_is_netwinder()) | 497 | if (!machine_is_netwinder()) |
498 | release_region(IO_INDEX_PORT,2); | 498 | release_region(IO_INDEX_PORT, 2); |
499 | err_out: | 499 | err_out: |
500 | return rc; | 500 | return rc; |
501 | } | 501 | } |
@@ -505,7 +505,7 @@ static void __exit wd977_exit(void) | |||
505 | wdt977_stop(); | 505 | wdt977_stop(); |
506 | misc_deregister(&wdt977_miscdev); | 506 | misc_deregister(&wdt977_miscdev); |
507 | unregister_reboot_notifier(&wdt977_notifier); | 507 | unregister_reboot_notifier(&wdt977_notifier); |
508 | release_region(IO_INDEX_PORT,2); | 508 | release_region(IO_INDEX_PORT, 2); |
509 | } | 509 | } |
510 | 510 | ||
511 | module_init(wd977_init); | 511 | module_init(wd977_init); |