aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/geodewdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog/geodewdt.c')
-rw-r--r--drivers/watchdog/geodewdt.c96
1 files changed, 42 insertions, 54 deletions
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 30d09cbbad94..614a5c7017b6 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -17,8 +17,8 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/uaccess.h>
20 21
21#include <asm/uaccess.h>
22#include <asm/geode.h> 22#include <asm/geode.h>
23 23
24#define GEODEWDT_HZ 500 24#define GEODEWDT_HZ 500
@@ -77,27 +77,24 @@ static int geodewdt_set_heartbeat(int val)
77 return 0; 77 return 0;
78} 78}
79 79
80static int 80static int geodewdt_open(struct inode *inode, struct file *file)
81geodewdt_open(struct inode *inode, struct file *file)
82{ 81{
83 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) 82 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags))
84 return -EBUSY; 83 return -EBUSY;
85 84
86 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) 85 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags))
87 __module_get(THIS_MODULE); 86 __module_get(THIS_MODULE);
88 87
89 geodewdt_ping(); 88 geodewdt_ping();
90 return nonseekable_open(inode, file); 89 return nonseekable_open(inode, file);
91} 90}
92 91
93static int 92static int geodewdt_release(struct inode *inode, struct file *file)
94geodewdt_release(struct inode *inode, struct file *file)
95{ 93{
96 if (safe_close) { 94 if (safe_close) {
97 geodewdt_disable(); 95 geodewdt_disable();
98 module_put(THIS_MODULE); 96 module_put(THIS_MODULE);
99 } 97 } else {
100 else {
101 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); 98 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n");
102 geodewdt_ping(); 99 geodewdt_ping();
103 100
@@ -109,11 +106,10 @@ geodewdt_release(struct inode *inode, struct file *file)
109 return 0; 106 return 0;
110} 107}
111 108
112static ssize_t 109static ssize_t geodewdt_write(struct file *file, const char __user *data,
113geodewdt_write(struct file *file, const char __user *data, size_t len, 110 size_t len, loff_t *ppos)
114 loff_t *ppos)
115{ 111{
116 if(len) { 112 if (len) {
117 if (!nowayout) { 113 if (!nowayout) {
118 size_t i; 114 size_t i;
119 safe_close = 0; 115 safe_close = 0;
@@ -134,9 +130,8 @@ geodewdt_write(struct file *file, const char __user *data, size_t len,
134 return len; 130 return len;
135} 131}
136 132
137static int 133static int geodewdt_ioctl(struct inode *inode, struct file *file,
138geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 134 unsigned int cmd, unsigned long arg)
139 unsigned long arg)
140{ 135{
141 void __user *argp = (void __user *)arg; 136 void __user *argp = (void __user *)arg;
142 int __user *p = argp; 137 int __user *p = argp;
@@ -147,9 +142,9 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
147 | WDIOF_MAGICCLOSE, 142 | WDIOF_MAGICCLOSE,
148 .firmware_version = 1, 143 .firmware_version = 1,
149 .identity = WATCHDOG_NAME, 144 .identity = WATCHDOG_NAME,
150 }; 145 };
151 146
152 switch(cmd) { 147 switch (cmd) {
153 case WDIOC_GETSUPPORT: 148 case WDIOC_GETSUPPORT:
154 return copy_to_user(argp, &ident, 149 return copy_to_user(argp, &ident,
155 sizeof(ident)) ? -EFAULT : 0; 150 sizeof(ident)) ? -EFAULT : 0;
@@ -159,22 +154,6 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
159 case WDIOC_GETBOOTSTATUS: 154 case WDIOC_GETBOOTSTATUS:
160 return put_user(0, p); 155 return put_user(0, p);
161 156
162 case WDIOC_KEEPALIVE:
163 geodewdt_ping();
164 return 0;
165
166 case WDIOC_SETTIMEOUT:
167 if (get_user(interval, p))
168 return -EFAULT;
169
170 if (geodewdt_set_heartbeat(interval))
171 return -EINVAL;
172
173/* Fall through */
174
175 case WDIOC_GETTIMEOUT:
176 return put_user(timeout, p);
177
178 case WDIOC_SETOPTIONS: 157 case WDIOC_SETOPTIONS:
179 { 158 {
180 int options, ret = -EINVAL; 159 int options, ret = -EINVAL;
@@ -194,6 +173,20 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
194 173
195 return ret; 174 return ret;
196 } 175 }
176 case WDIOC_KEEPALIVE:
177 geodewdt_ping();
178 return 0;
179
180 case WDIOC_SETTIMEOUT:
181 if (get_user(interval, p))
182 return -EFAULT;
183
184 if (geodewdt_set_heartbeat(interval))
185 return -EINVAL;
186 /* Fall through */
187 case WDIOC_GETTIMEOUT:
188 return put_user(timeout, p);
189
197 default: 190 default:
198 return -ENOTTY; 191 return -ENOTTY;
199 } 192 }
@@ -202,22 +195,21 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
202} 195}
203 196
204static const struct file_operations geodewdt_fops = { 197static const struct file_operations geodewdt_fops = {
205 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
206 .llseek = no_llseek, 199 .llseek = no_llseek,
207 .write = geodewdt_write, 200 .write = geodewdt_write,
208 .ioctl = geodewdt_ioctl, 201 .ioctl = geodewdt_ioctl,
209 .open = geodewdt_open, 202 .open = geodewdt_open,
210 .release = geodewdt_release, 203 .release = geodewdt_release,
211}; 204};
212 205
213static struct miscdevice geodewdt_miscdev = { 206static struct miscdevice geodewdt_miscdev = {
214 .minor = WATCHDOG_MINOR, 207 .minor = WATCHDOG_MINOR,
215 .name = "watchdog", 208 .name = "watchdog",
216 .fops = &geodewdt_fops 209 .fops = &geodewdt_fops,
217}; 210};
218 211
219static int __devinit 212static int __devinit geodewdt_probe(struct platform_device *dev)
220geodewdt_probe(struct platform_device *dev)
221{ 213{
222 int ret, timer; 214 int ret, timer;
223 215
@@ -248,15 +240,13 @@ geodewdt_probe(struct platform_device *dev)
248 return ret; 240 return ret;
249} 241}
250 242
251static int __devexit 243static int __devexit geodewdt_remove(struct platform_device *dev)
252geodewdt_remove(struct platform_device *dev)
253{ 244{
254 misc_deregister(&geodewdt_miscdev); 245 misc_deregister(&geodewdt_miscdev);
255 return 0; 246 return 0;
256} 247}
257 248
258static void 249static void geodewdt_shutdown(struct platform_device *dev)
259geodewdt_shutdown(struct platform_device *dev)
260{ 250{
261 geodewdt_disable(); 251 geodewdt_disable();
262} 252}
@@ -271,8 +261,7 @@ static struct platform_driver geodewdt_driver = {
271 }, 261 },
272}; 262};
273 263
274static int __init 264static int __init geodewdt_init(void)
275geodewdt_init(void)
276{ 265{
277 int ret; 266 int ret;
278 267
@@ -292,8 +281,7 @@ err:
292 return ret; 281 return ret;
293} 282}
294 283
295static void __exit 284static void __exit geodewdt_exit(void)
296geodewdt_exit(void)
297{ 285{
298 platform_device_unregister(geodewdt_platform_device); 286 platform_device_unregister(geodewdt_platform_device);
299 platform_driver_unregister(&geodewdt_driver); 287 platform_driver_unregister(&geodewdt_driver);