aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog/mv64x60_wdt.c
diff options
context:
space:
mode:
authorDale Farnsworth <dale@farnsworth.org>2007-07-24 14:18:14 -0400
committerWim Van Sebroeck <wim@iguana.be>2007-07-24 17:16:20 -0400
commitbf2fc92cae3630301d98b9faa38c1a98bb57d801 (patch)
tree231e1a56f4072589fcee283a8bcfcb965805e688 /drivers/char/watchdog/mv64x60_wdt.c
parentd37a5c3ddf7f57fdc0632e279eabb1772f89dfc5 (diff)
[WATCHDOG] mv64x60_wdt: Support the WDIOF_MAGICCLOSE feature
Disallow disabling of the watchdog timer unless a particular character ('V') was recently written to the watchdog device. Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/char/watchdog/mv64x60_wdt.c')
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 009b9a2c6efa..e07007543d09 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -44,6 +44,7 @@ static int wdt_status;
44static void __iomem *mv64x60_wdt_regs; 44static void __iomem *mv64x60_wdt_regs;
45static int mv64x60_wdt_timeout; 45static int mv64x60_wdt_timeout;
46static unsigned int bus_clk; 46static unsigned int bus_clk;
47static char expect_close;
47 48
48static int nowayout = WATCHDOG_NOWAYOUT; 49static int nowayout = WATCHDOG_NOWAYOUT;
49module_param(nowayout, int, 0); 50module_param(nowayout, int, 0);
@@ -115,10 +116,14 @@ static int mv64x60_wdt_open(struct inode *inode, struct file *file)
115 116
116static int mv64x60_wdt_release(struct inode *inode, struct file *file) 117static int mv64x60_wdt_release(struct inode *inode, struct file *file)
117{ 118{
118 mv64x60_wdt_service(); 119 if (expect_close == 42)
119
120 if (!nowayout)
121 mv64x60_wdt_handler_disable(); 120 mv64x60_wdt_handler_disable();
121 else {
122 printk(KERN_CRIT
123 "mv64x60_wdt: unexpected close, not stopping timer!\n");
124 mv64x60_wdt_service();
125 }
126 expect_close = 0;
122 127
123 clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags); 128 clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
124 129
@@ -128,8 +133,22 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
128static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, 133static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
129 size_t len, loff_t * ppos) 134 size_t len, loff_t * ppos)
130{ 135{
131 if (len) 136 if (len) {
137 if (!nowayout) {
138 size_t i;
139
140 expect_close = 0;
141
142 for (i = 0; i != len; i++) {
143 char c;
144 if(get_user(c, data + i))
145 return -EFAULT;
146 if (c == 'V')
147 expect_close = 42;
148 }
149 }
132 mv64x60_wdt_service(); 150 mv64x60_wdt_service();
151 }
133 152
134 return len; 153 return len;
135} 154}
@@ -142,6 +161,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
142 void __user *argp = (void __user *)arg; 161 void __user *argp = (void __user *)arg;
143 static struct watchdog_info info = { 162 static struct watchdog_info info = {
144 .options = WDIOF_SETTIMEOUT | 163 .options = WDIOF_SETTIMEOUT |
164 WDIOF_MAGICCLOSE |
145 WDIOF_KEEPALIVEPING, 165 WDIOF_KEEPALIVEPING,
146 .firmware_version = 0, 166 .firmware_version = 0,
147 .identity = "MV64x60 watchdog", 167 .identity = "MV64x60 watchdog",