aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog/sbc_epx_c3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/watchdog/sbc_epx_c3.c')
-rw-r--r--drivers/char/watchdog/sbc_epx_c3.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index 951764614ebf..837b1ec3ffe3 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -25,6 +25,7 @@
25#include <linux/notifier.h> 25#include <linux/notifier.h>
26#include <linux/reboot.h> 26#include <linux/reboot.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/ioport.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/io.h> 30#include <asm/io.h>
30 31
@@ -91,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file)
91 return 0; 92 return 0;
92} 93}
93 94
94static ssize_t epx_c3_write(struct file *file, const char *data, 95static ssize_t epx_c3_write(struct file *file, const char __user *data,
95 size_t len, loff_t *ppos) 96 size_t len, loff_t *ppos)
96{ 97{
97 /* Refresh the timer. */ 98 /* Refresh the timer. */
@@ -104,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
104 unsigned int cmd, unsigned long arg) 105 unsigned int cmd, unsigned long arg)
105{ 106{
106 int options, retval = -EINVAL; 107 int options, retval = -EINVAL;
108 int __user *argp = (void __user *)arg;
107 static struct watchdog_info ident = { 109 static struct watchdog_info ident = {
108 .options = WDIOF_KEEPALIVEPING | 110 .options = WDIOF_KEEPALIVEPING |
109 WDIOF_MAGICCLOSE, 111 WDIOF_MAGICCLOSE,
@@ -113,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
113 115
114 switch (cmd) { 116 switch (cmd) {
115 case WDIOC_GETSUPPORT: 117 case WDIOC_GETSUPPORT:
116 if (copy_to_user((struct watchdog_info *)arg, 118 if (copy_to_user(argp, &ident, sizeof(ident)))
117 &ident, sizeof(ident)))
118 return -EFAULT; 119 return -EFAULT;
119 return 0; 120 return 0;
120 case WDIOC_GETSTATUS: 121 case WDIOC_GETSTATUS:
121 case WDIOC_GETBOOTSTATUS: 122 case WDIOC_GETBOOTSTATUS:
122 return put_user(0,(int *)arg); 123 return put_user(0, argp);
123 case WDIOC_KEEPALIVE: 124 case WDIOC_KEEPALIVE:
124 epx_c3_pet(); 125 epx_c3_pet();
125 return 0; 126 return 0;
126 case WDIOC_GETTIMEOUT: 127 case WDIOC_GETTIMEOUT:
127 return put_user(WATCHDOG_TIMEOUT,(int *)arg); 128 return put_user(WATCHDOG_TIMEOUT, argp);
128 case WDIOC_SETOPTIONS: { 129 case WDIOC_SETOPTIONS:
129 if (get_user(options, (int *)arg)) 130 if (get_user(options, argp))
130 return -EFAULT; 131 return -EFAULT;
131 132
132 if (options & WDIOS_DISABLECARD) { 133 if (options & WDIOS_DISABLECARD) {
@@ -140,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
140 } 141 }
141 142
142 return retval; 143 return retval;
143 }
144 default: 144 default:
145 return -ENOIOCTLCMD; 145 return -ENOIOCTLCMD;
146 } 146 }
@@ -181,11 +181,14 @@ static int __init watchdog_init(void)
181{ 181{
182 int ret; 182 int ret;
183 183
184 if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog"))
185 return -EBUSY;
186
184 ret = register_reboot_notifier(&epx_c3_notifier); 187 ret = register_reboot_notifier(&epx_c3_notifier);
185 if (ret) { 188 if (ret) {
186 printk(KERN_ERR PFX "cannot register reboot notifier " 189 printk(KERN_ERR PFX "cannot register reboot notifier "
187 "(err=%d)\n", ret); 190 "(err=%d)\n", ret);
188 return ret; 191 goto out;
189 } 192 }
190 193
191 ret = misc_register(&epx_c3_miscdev); 194 ret = misc_register(&epx_c3_miscdev);
@@ -193,18 +196,23 @@ static int __init watchdog_init(void)
193 printk(KERN_ERR PFX "cannot register miscdev on minor=%d " 196 printk(KERN_ERR PFX "cannot register miscdev on minor=%d "
194 "(err=%d)\n", WATCHDOG_MINOR, ret); 197 "(err=%d)\n", WATCHDOG_MINOR, ret);
195 unregister_reboot_notifier(&epx_c3_notifier); 198 unregister_reboot_notifier(&epx_c3_notifier);
196 return ret; 199 goto out;
197 } 200 }
198 201
199 printk(banner); 202 printk(banner);
200 203
201 return 0; 204 return 0;
205
206out:
207 release_region(EPXC3_WATCHDOG_CTL_REG, 2);
208 return ret;
202} 209}
203 210
204static void __exit watchdog_exit(void) 211static void __exit watchdog_exit(void)
205{ 212{
206 misc_deregister(&epx_c3_miscdev); 213 misc_deregister(&epx_c3_miscdev);
207 unregister_reboot_notifier(&epx_c3_notifier); 214 unregister_reboot_notifier(&epx_c3_notifier);
215 release_region(EPXC3_WATCHDOG_CTL_REG, 2);
208} 216}
209 217
210module_init(watchdog_init); 218module_init(watchdog_init);