diff options
Diffstat (limited to 'drivers/watchdog/geodewdt.c')
-rw-r--r-- | drivers/watchdog/geodewdt.c | 96 |
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 | ||
80 | static int | 80 | static int geodewdt_open(struct inode *inode, struct file *file) |
81 | geodewdt_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 | ||
93 | static int | 92 | static int geodewdt_release(struct inode *inode, struct file *file) |
94 | geodewdt_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 | ||
112 | static ssize_t | 109 | static ssize_t geodewdt_write(struct file *file, const char __user *data, |
113 | geodewdt_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 | ||
137 | static int | 133 | static int geodewdt_ioctl(struct inode *inode, struct file *file, |
138 | geodewdt_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 | ||
204 | static const struct file_operations geodewdt_fops = { | 197 | static 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 | ||
213 | static struct miscdevice geodewdt_miscdev = { | 206 | static 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 | ||
219 | static int __devinit | 212 | static int __devinit geodewdt_probe(struct platform_device *dev) |
220 | geodewdt_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 | ||
251 | static int __devexit | 243 | static int __devexit geodewdt_remove(struct platform_device *dev) |
252 | geodewdt_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 | ||
258 | static void | 249 | static void geodewdt_shutdown(struct platform_device *dev) |
259 | geodewdt_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 | ||
274 | static int __init | 264 | static int __init geodewdt_init(void) |
275 | geodewdt_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 | ||
295 | static void __exit | 284 | static void __exit geodewdt_exit(void) |
296 | geodewdt_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); |