diff options
author | Alan Cox <alan@redhat.com> | 2008-05-19 09:06:14 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2008-05-27 16:26:17 -0400 |
commit | 02e3814e193ff798676793016851bc222366dc6a (patch) | |
tree | 2c2a13131e73cbffaeb5547fadf44a90588c0f3d /drivers/watchdog/iop_wdt.c | |
parent | 9b9dbcca3fa13acd64dbb9258bfe997809d6073b (diff) |
[WATCHDOG 16/57] iop: watchdog switch to unlocked_ioctl
Review and switch to unlocked_ioctl
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/iop_wdt.c')
-rw-r--r-- | drivers/watchdog/iop_wdt.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c index bbbd91af754d..e54c888d2afe 100644 --- a/drivers/watchdog/iop_wdt.c +++ b/drivers/watchdog/iop_wdt.c | |||
@@ -37,6 +37,7 @@ | |||
37 | static int nowayout = WATCHDOG_NOWAYOUT; | 37 | static int nowayout = WATCHDOG_NOWAYOUT; |
38 | static unsigned long wdt_status; | 38 | static unsigned long wdt_status; |
39 | static unsigned long boot_status; | 39 | static unsigned long boot_status; |
40 | static spinlock_t wdt_lock; | ||
40 | 41 | ||
41 | #define WDT_IN_USE 0 | 42 | #define WDT_IN_USE 0 |
42 | #define WDT_OK_TO_CLOSE 1 | 43 | #define WDT_OK_TO_CLOSE 1 |
@@ -68,8 +69,10 @@ static void wdt_enable(void) | |||
68 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF | 69 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF |
69 | * Takes approx. 10.7s to timeout | 70 | * Takes approx. 10.7s to timeout |
70 | */ | 71 | */ |
72 | spin_lock(&wdt_lock); | ||
71 | write_wdtcr(IOP_WDTCR_EN_ARM); | 73 | write_wdtcr(IOP_WDTCR_EN_ARM); |
72 | write_wdtcr(IOP_WDTCR_EN); | 74 | write_wdtcr(IOP_WDTCR_EN); |
75 | spin_unlock(&wdt_lock); | ||
73 | } | 76 | } |
74 | 77 | ||
75 | /* returns 0 if the timer was successfully disabled */ | 78 | /* returns 0 if the timer was successfully disabled */ |
@@ -77,9 +80,11 @@ static int wdt_disable(void) | |||
77 | { | 80 | { |
78 | /* Stop Counting */ | 81 | /* Stop Counting */ |
79 | if (wdt_supports_disable()) { | 82 | if (wdt_supports_disable()) { |
83 | spin_lock(&wdt_lock); | ||
80 | write_wdtcr(IOP_WDTCR_DIS_ARM); | 84 | write_wdtcr(IOP_WDTCR_DIS_ARM); |
81 | write_wdtcr(IOP_WDTCR_DIS); | 85 | write_wdtcr(IOP_WDTCR_DIS); |
82 | clear_bit(WDT_ENABLED, &wdt_status); | 86 | clear_bit(WDT_ENABLED, &wdt_status); |
87 | spin_unlock(&wdt_lock); | ||
83 | printk(KERN_INFO "WATCHDOG: Disabled\n"); | 88 | printk(KERN_INFO "WATCHDOG: Disabled\n"); |
84 | return 0; | 89 | return 0; |
85 | } else | 90 | } else |
@@ -92,16 +97,12 @@ static int iop_wdt_open(struct inode *inode, struct file *file) | |||
92 | return -EBUSY; | 97 | return -EBUSY; |
93 | 98 | ||
94 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 99 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
95 | |||
96 | wdt_enable(); | 100 | wdt_enable(); |
97 | |||
98 | set_bit(WDT_ENABLED, &wdt_status); | 101 | set_bit(WDT_ENABLED, &wdt_status); |
99 | |||
100 | return nonseekable_open(inode, file); | 102 | return nonseekable_open(inode, file); |
101 | } | 103 | } |
102 | 104 | ||
103 | static ssize_t | 105 | static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len, |
104 | iop_wdt_write(struct file *file, const char *data, size_t len, | ||
105 | loff_t *ppos) | 106 | loff_t *ppos) |
106 | { | 107 | { |
107 | if (len) { | 108 | if (len) { |
@@ -121,41 +122,39 @@ iop_wdt_write(struct file *file, const char *data, size_t len, | |||
121 | } | 122 | } |
122 | wdt_enable(); | 123 | wdt_enable(); |
123 | } | 124 | } |
124 | |||
125 | return len; | 125 | return len; |
126 | } | 126 | } |
127 | 127 | ||
128 | static struct watchdog_info ident = { | 128 | static const struct watchdog_info ident = { |
129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
130 | .identity = "iop watchdog", | 130 | .identity = "iop watchdog", |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static int | 133 | static long iop_wdt_ioctl(struct file *file, |
134 | iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 134 | unsigned int cmd, unsigned long arg) |
135 | unsigned long arg) | ||
136 | { | 135 | { |
137 | int options; | 136 | int options; |
138 | int ret = -ENOTTY; | 137 | int ret = -ENOTTY; |
138 | int __user *argp = (int __user *)arg; | ||
139 | 139 | ||
140 | switch (cmd) { | 140 | switch (cmd) { |
141 | case WDIOC_GETSUPPORT: | 141 | case WDIOC_GETSUPPORT: |
142 | if (copy_to_user | 142 | if (copy_to_user(argp, &ident, sizeof ident)) |
143 | ((struct watchdog_info *)arg, &ident, sizeof ident)) | ||
144 | ret = -EFAULT; | 143 | ret = -EFAULT; |
145 | else | 144 | else |
146 | ret = 0; | 145 | ret = 0; |
147 | break; | 146 | break; |
148 | 147 | ||
149 | case WDIOC_GETSTATUS: | 148 | case WDIOC_GETSTATUS: |
150 | ret = put_user(0, (int *)arg); | 149 | ret = put_user(0, argp); |
151 | break; | 150 | break; |
152 | 151 | ||
153 | case WDIOC_GETBOOTSTATUS: | 152 | case WDIOC_GETBOOTSTATUS: |
154 | ret = put_user(boot_status, (int *)arg); | 153 | ret = put_user(boot_status, argp); |
155 | break; | 154 | break; |
156 | 155 | ||
157 | case WDIOC_GETTIMEOUT: | 156 | case WDIOC_GETTIMEOUT: |
158 | ret = put_user(iop_watchdog_timeout(), (int *)arg); | 157 | ret = put_user(iop_watchdog_timeout(), argp); |
159 | break; | 158 | break; |
160 | 159 | ||
161 | case WDIOC_KEEPALIVE: | 160 | case WDIOC_KEEPALIVE: |
@@ -177,14 +176,12 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
177 | } else | 176 | } else |
178 | ret = 0; | 177 | ret = 0; |
179 | } | 178 | } |
180 | |||
181 | if (options & WDIOS_ENABLECARD) { | 179 | if (options & WDIOS_ENABLECARD) { |
182 | wdt_enable(); | 180 | wdt_enable(); |
183 | ret = 0; | 181 | ret = 0; |
184 | } | 182 | } |
185 | break; | 183 | break; |
186 | } | 184 | } |
187 | |||
188 | return ret; | 185 | return ret; |
189 | } | 186 | } |
190 | 187 | ||
@@ -214,7 +211,7 @@ static const struct file_operations iop_wdt_fops = { | |||
214 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
215 | .llseek = no_llseek, | 212 | .llseek = no_llseek, |
216 | .write = iop_wdt_write, | 213 | .write = iop_wdt_write, |
217 | .ioctl = iop_wdt_ioctl, | 214 | .unlocked_ioctl = iop_wdt_ioctl, |
218 | .open = iop_wdt_open, | 215 | .open = iop_wdt_open, |
219 | .release = iop_wdt_release, | 216 | .release = iop_wdt_release, |
220 | }; | 217 | }; |
@@ -229,10 +226,8 @@ static int __init iop_wdt_init(void) | |||
229 | { | 226 | { |
230 | int ret; | 227 | int ret; |
231 | 228 | ||
232 | ret = misc_register(&iop_wdt_miscdev); | 229 | spin_lock_init(&wdt_lock); |
233 | if (ret == 0) | 230 | |
234 | printk("iop watchdog timer: timeout %lu sec\n", | ||
235 | iop_watchdog_timeout()); | ||
236 | 231 | ||
237 | /* check if the reset was caused by the watchdog timer */ | 232 | /* check if the reset was caused by the watchdog timer */ |
238 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; | 233 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; |
@@ -242,6 +237,13 @@ static int __init iop_wdt_init(void) | |||
242 | */ | 237 | */ |
243 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); | 238 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); |
244 | 239 | ||
240 | /* Register after we have the device set up so we cannot race | ||
241 | with an open */ | ||
242 | ret = misc_register(&iop_wdt_miscdev); | ||
243 | if (ret == 0) | ||
244 | printk("iop watchdog timer: timeout %lu sec\n", | ||
245 | iop_watchdog_timeout()); | ||
246 | |||
245 | return ret; | 247 | return ret; |
246 | } | 248 | } |
247 | 249 | ||