aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/it8712f_wdt.c
diff options
context:
space:
mode:
authorNat Gurumoorthy <natg@google.com>2011-05-09 14:45:07 -0400
committerWim Van Sebroeck <wim@iguana.be>2011-07-22 04:55:23 -0400
commita134b825608df6382dbcf4fe2c54232ba8f7355f (patch)
tree2e8d11aa67426d64e4084bdbce42a752d5be01ab /drivers/watchdog/it8712f_wdt.c
parent02f8c6aee8df3cdc935e9bdd4f2d020306035dbe (diff)
watchdog: Use "request_muxed_region" in it87 watchdog drivers
Changes the it87 watchdog drivers to use "request_muxed_region". Serialize access to the hardware by using "request_muxed_region" macro defined by Alan Cox. Call to this macro will hold off the requestor if the resource is currently busy. The use of the above macro makes it possible to get rid of spinlocks in it8712f_wdt.c and it87_wdt.c watchdog drivers. This also greatly simplifies the implementation of it87_wdt.c driver. "superio_enter" will return an error if call to "request_muxed_region" fails. Rest of the code change is to ripple an error return from superio_enter to the top level. Signed-off-by: Nat Gurumoorthy <natg@google.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/it8712f_wdt.c')
-rw-r--r--drivers/watchdog/it8712f_wdt.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 6143f52ba6b8..690144917a4d 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -51,7 +51,6 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
51 51
52static unsigned long wdt_open; 52static unsigned long wdt_open;
53static unsigned expect_close; 53static unsigned expect_close;
54static spinlock_t io_lock;
55static unsigned char revision; 54static unsigned char revision;
56 55
57/* Dog Food address - We use the game port address */ 56/* Dog Food address - We use the game port address */
@@ -121,20 +120,26 @@ static inline void superio_select(int ldn)
121 outb(ldn, VAL); 120 outb(ldn, VAL);
122} 121}
123 122
124static inline void superio_enter(void) 123static inline int superio_enter(void)
125{ 124{
126 spin_lock(&io_lock); 125 /*
126 * Try to reserve REG and REG + 1 for exclusive access.
127 */
128 if (!request_muxed_region(REG, 2, NAME))
129 return -EBUSY;
130
127 outb(0x87, REG); 131 outb(0x87, REG);
128 outb(0x01, REG); 132 outb(0x01, REG);
129 outb(0x55, REG); 133 outb(0x55, REG);
130 outb(0x55, REG); 134 outb(0x55, REG);
135 return 0;
131} 136}
132 137
133static inline void superio_exit(void) 138static inline void superio_exit(void)
134{ 139{
135 outb(0x02, REG); 140 outb(0x02, REG);
136 outb(0x02, VAL); 141 outb(0x02, VAL);
137 spin_unlock(&io_lock); 142 release_region(REG, 2);
138} 143}
139 144
140static inline void it8712f_wdt_ping(void) 145static inline void it8712f_wdt_ping(void)
@@ -173,10 +178,13 @@ static int it8712f_wdt_get_status(void)
173 return 0; 178 return 0;
174} 179}
175 180
176static void it8712f_wdt_enable(void) 181static int it8712f_wdt_enable(void)
177{ 182{
183 int ret = superio_enter();
184 if (ret)
185 return ret;
186
178 printk(KERN_DEBUG NAME ": enabling watchdog timer\n"); 187 printk(KERN_DEBUG NAME ": enabling watchdog timer\n");
179 superio_enter();
180 superio_select(LDN_GPIO); 188 superio_select(LDN_GPIO);
181 189
182 superio_outb(wdt_control_reg, WDT_CONTROL); 190 superio_outb(wdt_control_reg, WDT_CONTROL);
@@ -186,13 +194,17 @@ static void it8712f_wdt_enable(void)
186 superio_exit(); 194 superio_exit();
187 195
188 it8712f_wdt_ping(); 196 it8712f_wdt_ping();
197
198 return 0;
189} 199}
190 200
191static void it8712f_wdt_disable(void) 201static int it8712f_wdt_disable(void)
192{ 202{
193 printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); 203 int ret = superio_enter();
204 if (ret)
205 return ret;
194 206
195 superio_enter(); 207 printk(KERN_DEBUG NAME ": disabling watchdog timer\n");
196 superio_select(LDN_GPIO); 208 superio_select(LDN_GPIO);
197 209
198 superio_outb(0, WDT_CONFIG); 210 superio_outb(0, WDT_CONFIG);
@@ -202,6 +214,7 @@ static void it8712f_wdt_disable(void)
202 superio_outb(0, WDT_TIMEOUT); 214 superio_outb(0, WDT_TIMEOUT);
203 215
204 superio_exit(); 216 superio_exit();
217 return 0;
205} 218}
206 219
207static int it8712f_wdt_notify(struct notifier_block *this, 220static int it8712f_wdt_notify(struct notifier_block *this,
@@ -252,6 +265,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
252 WDIOF_MAGICCLOSE, 265 WDIOF_MAGICCLOSE,
253 }; 266 };
254 int value; 267 int value;
268 int ret;
255 269
256 switch (cmd) { 270 switch (cmd) {
257 case WDIOC_GETSUPPORT: 271 case WDIOC_GETSUPPORT:
@@ -259,7 +273,9 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
259 return -EFAULT; 273 return -EFAULT;
260 return 0; 274 return 0;
261 case WDIOC_GETSTATUS: 275 case WDIOC_GETSTATUS:
262 superio_enter(); 276 ret = superio_enter();
277 if (ret)
278 return ret;
263 superio_select(LDN_GPIO); 279 superio_select(LDN_GPIO);
264 280
265 value = it8712f_wdt_get_status(); 281 value = it8712f_wdt_get_status();
@@ -280,7 +296,9 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
280 if (value > (max_units * 60)) 296 if (value > (max_units * 60))
281 return -EINVAL; 297 return -EINVAL;
282 margin = value; 298 margin = value;
283 superio_enter(); 299 ret = superio_enter();
300 if (ret)
301 return ret;
284 superio_select(LDN_GPIO); 302 superio_select(LDN_GPIO);
285 303
286 it8712f_wdt_update_margin(); 304 it8712f_wdt_update_margin();
@@ -299,10 +317,14 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
299 317
300static int it8712f_wdt_open(struct inode *inode, struct file *file) 318static int it8712f_wdt_open(struct inode *inode, struct file *file)
301{ 319{
320 int ret;
302 /* only allow one at a time */ 321 /* only allow one at a time */
303 if (test_and_set_bit(0, &wdt_open)) 322 if (test_and_set_bit(0, &wdt_open))
304 return -EBUSY; 323 return -EBUSY;
305 it8712f_wdt_enable(); 324
325 ret = it8712f_wdt_enable();
326 if (ret)
327 return ret;
306 return nonseekable_open(inode, file); 328 return nonseekable_open(inode, file);
307} 329}
308 330
@@ -313,7 +335,8 @@ static int it8712f_wdt_release(struct inode *inode, struct file *file)
313 ": watchdog device closed unexpectedly, will not" 335 ": watchdog device closed unexpectedly, will not"
314 " disable the watchdog timer\n"); 336 " disable the watchdog timer\n");
315 } else if (!nowayout) { 337 } else if (!nowayout) {
316 it8712f_wdt_disable(); 338 if (it8712f_wdt_disable())
339 printk(KERN_WARNING NAME "Watchdog disable failed\n");
317 } 340 }
318 expect_close = 0; 341 expect_close = 0;
319 clear_bit(0, &wdt_open); 342 clear_bit(0, &wdt_open);
@@ -340,8 +363,10 @@ static int __init it8712f_wdt_find(unsigned short *address)
340{ 363{
341 int err = -ENODEV; 364 int err = -ENODEV;
342 int chip_type; 365 int chip_type;
366 int ret = superio_enter();
367 if (ret)
368 return ret;
343 369
344 superio_enter();
345 chip_type = superio_inw(DEVID); 370 chip_type = superio_inw(DEVID);
346 if (chip_type != IT8712F_DEVID) 371 if (chip_type != IT8712F_DEVID)
347 goto exit; 372 goto exit;
@@ -382,8 +407,6 @@ static int __init it8712f_wdt_init(void)
382{ 407{
383 int err = 0; 408 int err = 0;
384 409
385 spin_lock_init(&io_lock);
386
387 if (it8712f_wdt_find(&address)) 410 if (it8712f_wdt_find(&address))
388 return -ENODEV; 411 return -ENODEV;
389 412
@@ -392,7 +415,11 @@ static int __init it8712f_wdt_init(void)
392 return -EBUSY; 415 return -EBUSY;
393 } 416 }
394 417
395 it8712f_wdt_disable(); 418 err = it8712f_wdt_disable();
419 if (err) {
420 printk(KERN_ERR NAME ": unable to disable watchdog timer.\n");
421 goto out;
422 }
396 423
397 err = register_reboot_notifier(&it8712f_wdt_notifier); 424 err = register_reboot_notifier(&it8712f_wdt_notifier);
398 if (err) { 425 if (err) {