diff options
Diffstat (limited to 'drivers/watchdog/sbc8360.c')
-rw-r--r-- | drivers/watchdog/sbc8360.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c index 2ee2677f3648..fd83dd052d8c 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. |
@@ -231,9 +231,16 @@ static void sbc8360_ping(void) | |||
231 | outb(wd_margin, SBC8360_BASETIME); | 231 | outb(wd_margin, SBC8360_BASETIME); |
232 | } | 232 | } |
233 | 233 | ||
234 | /* stop watchdog */ | ||
235 | static void sbc8360_stop(void) | ||
236 | { | ||
237 | /* De-activate the watchdog */ | ||
238 | outb(0, SBC8360_ENABLE); | ||
239 | } | ||
240 | |||
234 | /* Userspace pings kernel driver, or requests clean close */ | 241 | /* Userspace pings kernel driver, or requests clean close */ |
235 | static ssize_t sbc8360_write(struct file *file, const char __user * buf, | 242 | static ssize_t sbc8360_write(struct file *file, const char __user *buf, |
236 | size_t count, loff_t * ppos) | 243 | size_t count, loff_t *ppos) |
237 | { | 244 | { |
238 | if (count) { | 245 | if (count) { |
239 | if (!nowayout) { | 246 | if (!nowayout) { |
@@ -257,16 +264,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf, | |||
257 | 264 | ||
258 | static int sbc8360_open(struct inode *inode, struct file *file) | 265 | static int sbc8360_open(struct inode *inode, struct file *file) |
259 | { | 266 | { |
260 | spin_lock(&sbc8360_lock); | 267 | 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; | 268 | return -EBUSY; |
264 | } | ||
265 | if (nowayout) | 269 | if (nowayout) |
266 | __module_get(THIS_MODULE); | 270 | __module_get(THIS_MODULE); |
267 | 271 | ||
268 | /* Activate and ping once to start the countdown */ | 272 | /* Activate and ping once to start the countdown */ |
269 | spin_unlock(&sbc8360_lock); | ||
270 | sbc8360_activate(); | 273 | sbc8360_activate(); |
271 | sbc8360_ping(); | 274 | sbc8360_ping(); |
272 | return nonseekable_open(inode, file); | 275 | return nonseekable_open(inode, file); |
@@ -274,16 +277,14 @@ static int sbc8360_open(struct inode *inode, struct file *file) | |||
274 | 277 | ||
275 | static int sbc8360_close(struct inode *inode, struct file *file) | 278 | static int sbc8360_close(struct inode *inode, struct file *file) |
276 | { | 279 | { |
277 | spin_lock(&sbc8360_lock); | ||
278 | if (expect_close == 42) | 280 | if (expect_close == 42) |
279 | outb(0, SBC8360_ENABLE); | 281 | sbc8360_stop(); |
280 | else | 282 | else |
281 | printk(KERN_CRIT PFX | 283 | printk(KERN_CRIT PFX |
282 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); | 284 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); |
283 | 285 | ||
284 | clear_bit(0, &sbc8360_is_open); | 286 | clear_bit(0, &sbc8360_is_open); |
285 | expect_close = 0; | 287 | expect_close = 0; |
286 | spin_unlock(&sbc8360_lock); | ||
287 | return 0; | 288 | return 0; |
288 | } | 289 | } |
289 | 290 | ||
@@ -294,10 +295,9 @@ static int sbc8360_close(struct inode *inode, struct file *file) | |||
294 | static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, | 295 | static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, |
295 | void *unused) | 296 | void *unused) |
296 | { | 297 | { |
297 | if (code == SYS_DOWN || code == SYS_HALT) { | 298 | if (code == SYS_DOWN || code == SYS_HALT) |
298 | /* Disable the SBC8360 Watchdog */ | 299 | sbc8360_stop(); /* Disable the SBC8360 Watchdog */ |
299 | outb(0, SBC8360_ENABLE); | 300 | |
300 | } | ||
301 | return NOTIFY_DONE; | 301 | return NOTIFY_DONE; |
302 | } | 302 | } |
303 | 303 | ||
@@ -382,13 +382,13 @@ static int __init sbc8360_init(void) | |||
382 | 382 | ||
383 | return 0; | 383 | return 0; |
384 | 384 | ||
385 | out_nomisc: | 385 | out_nomisc: |
386 | unregister_reboot_notifier(&sbc8360_notifier); | 386 | unregister_reboot_notifier(&sbc8360_notifier); |
387 | out_noreboot: | 387 | out_noreboot: |
388 | release_region(SBC8360_BASETIME, 1); | 388 | release_region(SBC8360_BASETIME, 1); |
389 | out_nobasetimereg: | 389 | out_nobasetimereg: |
390 | release_region(SBC8360_ENABLE, 1); | 390 | release_region(SBC8360_ENABLE, 1); |
391 | out: | 391 | out: |
392 | return res; | 392 | return res; |
393 | } | 393 | } |
394 | 394 | ||