aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-08-03 16:09:43 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-03 16:09:43 -0400
commit194d0710e1a7fe92dcf860ddd31fded8c3103b7a (patch)
treeda03b56fa4dee221c53af5770492d391f0d09459 /drivers
parenta68d2ebc1581a3aec57bd032651e013fa609f530 (diff)
parent9bbd03758945858c9303f3258b418b94c4ffd735 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c49
1 files changed, 10 insertions, 39 deletions
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 1b2132617dc3..fb88b4041dca 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -36,13 +36,10 @@
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37 37
38#define OSCR_FREQ CLOCK_TICK_RATE 38#define OSCR_FREQ CLOCK_TICK_RATE
39#define SA1100_CLOSE_MAGIC (0x5afc4453)
40 39
41static unsigned long sa1100wdt_users; 40static unsigned long sa1100wdt_users;
42static int expect_close;
43static int pre_margin; 41static int pre_margin;
44static int boot_status; 42static int boot_status;
45static int nowayout = WATCHDOG_NOWAYOUT;
46 43
47/* 44/*
48 * Allow only one person to hold it open 45 * Allow only one person to hold it open
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
62} 59}
63 60
64/* 61/*
65 * Shut off the timer. 62 * The watchdog cannot be disabled.
66 * Lock it in if it's a module and we defined ...NOWAYOUT 63 *
67 * Oddly, the watchdog can only be enabled, but we can turn off 64 * Previous comments suggested that turning off the interrupt by
68 * the interrupt, which appears to prevent the watchdog timing out. 65 * clearing OIER[E3] would prevent the watchdog timing out but this
66 * does not appear to be true (at least on the PXA255).
69 */ 67 */
70static int sa1100dog_release(struct inode *inode, struct file *file) 68static int sa1100dog_release(struct inode *inode, struct file *file)
71{ 69{
72 OSMR3 = OSCR + pre_margin; 70 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
73
74 if (expect_close == SA1100_CLOSE_MAGIC) {
75 OIER &= ~OIER_E3;
76 } else {
77 printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n");
78 }
79 71
80 clear_bit(1, &sa1100wdt_users); 72 clear_bit(1, &sa1100wdt_users);
81 expect_close = 0;
82 73
83 return 0; 74 return 0;
84} 75}
85 76
86static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 77static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
87{ 78{
88 if (len) { 79 if (len)
89 if (!nowayout) {
90 size_t i;
91
92 expect_close = 0;
93
94 for (i = 0; i != len; i++) {
95 char c;
96
97 if (get_user(c, data + i))
98 return -EFAULT;
99 if (c == 'V')
100 expect_close = SA1100_CLOSE_MAGIC;
101 }
102 }
103 /* Refresh OSMR3 timer. */ 80 /* Refresh OSMR3 timer. */
104 OSMR3 = OSCR + pre_margin; 81 OSMR3 = OSCR + pre_margin;
105 }
106 82
107 return len; 83 return len;
108} 84}
109 85
110static struct watchdog_info ident = { 86static struct watchdog_info ident = {
111 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 87 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
112 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 88 .identity = "SA1100/PXA255 Watchdog",
113 .identity = "SA1100 Watchdog",
114}; 89};
115 90
116static int sa1100dog_ioctl(struct inode *inode, struct file *file, 91static int sa1100dog_ioctl(struct inode *inode, struct file *file,
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
172static struct miscdevice sa1100dog_miscdev = 147static struct miscdevice sa1100dog_miscdev =
173{ 148{
174 .minor = WATCHDOG_MINOR, 149 .minor = WATCHDOG_MINOR,
175 .name = "SA1100/PXA2xx watchdog", 150 .name = "watchdog",
176 .fops = &sa1100dog_fops, 151 .fops = &sa1100dog_fops,
177}; 152};
178 153
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
194 if (ret == 0) 169 if (ret == 0)
195 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 170 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
196 margin); 171 margin);
197
198 return ret; 172 return ret;
199} 173}
200 174
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
212module_param(margin, int, 0); 186module_param(margin, int, 0);
213MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); 187MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
214 188
215module_param(nowayout, int, 0);
216MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
217
218MODULE_LICENSE("GPL"); 189MODULE_LICENSE("GPL");
219MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 190MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);