aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorDave Mueller <d.mueller@elsoft.ch>2012-04-11 09:43:22 -0400
committerWim Van Sebroeck <wim@iguana.be>2012-05-23 10:17:51 -0400
commit8f90a3ae8f67a6c521e2d8fcb488262833f2a4cd (patch)
treefe9ac7c0e004f88098647786ddbf732ebd088d60 /drivers/watchdog
parent3016a552a8314b2734aed0a1acbb983459e2acc4 (diff)
watchdog: sch311x_wdt.c: Remove RESGEN
The SCH311x chip contains 2 watchdogs. One is the watchdog programmable by the runtime register at address 0x65-0x68, the other is the watchdog inside the power on reset generator. This second watchdog has a fixed timeout value of ~1.6 seconds and is configurable only by the RESGEN register. The BIOS normally takes care of the RESGEN watchdog and disables it (at least) before the OS is booted. Unfortunately the sch311x_wdt driver clears bit 0 of the RESGEN register which has the effect that at the latest 1.6 seconds later, a POR is triggered. The attached patch fixes this problem by completely removing any reference to the RESGEN watchdog from the sch311x_wdt driver. Signed-off-by: Dave Mueller <d.mueller@elsoft.ch> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/sch311x_wdt.c39
1 files changed, 5 insertions, 34 deletions
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index bd86f32d63ab..f8477002b728 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -41,7 +41,6 @@
41#define DRV_NAME "sch311x_wdt" 41#define DRV_NAME "sch311x_wdt"
42 42
43/* Runtime registers */ 43/* Runtime registers */
44#define RESGEN 0x1d
45#define GP60 0x47 44#define GP60 0x47
46#define WDT_TIME_OUT 0x65 45#define WDT_TIME_OUT 0x65
47#define WDT_VAL 0x66 46#define WDT_VAL 0x66
@@ -69,10 +68,6 @@ static unsigned short force_id;
69module_param(force_id, ushort, 0); 68module_param(force_id, ushort, 0);
70MODULE_PARM_DESC(force_id, "Override the detected device ID"); 69MODULE_PARM_DESC(force_id, "Override the detected device ID");
71 70
72static unsigned short therm_trip;
73module_param(therm_trip, ushort, 0);
74MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator");
75
76#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 71#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
77static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 72static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
78module_param(timeout, int, 0); 73module_param(timeout, int, 0);
@@ -358,26 +353,16 @@ static struct miscdevice sch311x_wdt_miscdev = {
358static int __devinit sch311x_wdt_probe(struct platform_device *pdev) 353static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
359{ 354{
360 struct device *dev = &pdev->dev; 355 struct device *dev = &pdev->dev;
361 unsigned char val;
362 int err; 356 int err;
363 357
364 spin_lock_init(&sch311x_wdt_data.io_lock); 358 spin_lock_init(&sch311x_wdt_data.io_lock);
365 359
366 if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1,
367 DRV_NAME)) {
368 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
369 sch311x_wdt_data.runtime_reg + RESGEN,
370 sch311x_wdt_data.runtime_reg + RESGEN);
371 err = -EBUSY;
372 goto exit;
373 }
374
375 if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) { 360 if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) {
376 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", 361 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
377 sch311x_wdt_data.runtime_reg + GP60, 362 sch311x_wdt_data.runtime_reg + GP60,
378 sch311x_wdt_data.runtime_reg + GP60); 363 sch311x_wdt_data.runtime_reg + GP60);
379 err = -EBUSY; 364 err = -EBUSY;
380 goto exit_release_region; 365 goto exit;
381 } 366 }
382 367
383 if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4, 368 if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4,
@@ -386,7 +371,7 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
386 sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 371 sch311x_wdt_data.runtime_reg + WDT_TIME_OUT,
387 sch311x_wdt_data.runtime_reg + WDT_CTRL); 372 sch311x_wdt_data.runtime_reg + WDT_CTRL);
388 err = -EBUSY; 373 err = -EBUSY;
389 goto exit_release_region2; 374 goto exit_release_region;
390 } 375 }
391 376
392 /* Make sure that the watchdog is not running */ 377 /* Make sure that the watchdog is not running */
@@ -414,24 +399,13 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
414 /* Get status at boot */ 399 /* Get status at boot */
415 sch311x_wdt_get_status(&sch311x_wdt_data.boot_status); 400 sch311x_wdt_get_status(&sch311x_wdt_data.boot_status);
416 401
417 /* enable watchdog */
418 /* -- Reset Generator --
419 * Bit 0 Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled
420 * Bit 1 Thermtrip Source Select: O* = No Source, 1 = Source
421 * Bit 2 WDT2_CTL: WDT input bit
422 * Bit 3-7 Reserved
423 */
424 outb(0, sch311x_wdt_data.runtime_reg + RESGEN);
425 val = therm_trip ? 0x06 : 0x04;
426 outb(val, sch311x_wdt_data.runtime_reg + RESGEN);
427
428 sch311x_wdt_miscdev.parent = dev; 402 sch311x_wdt_miscdev.parent = dev;
429 403
430 err = misc_register(&sch311x_wdt_miscdev); 404 err = misc_register(&sch311x_wdt_miscdev);
431 if (err != 0) { 405 if (err != 0) {
432 dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n", 406 dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n",
433 WATCHDOG_MINOR, err); 407 WATCHDOG_MINOR, err);
434 goto exit_release_region3; 408 goto exit_release_region2;
435 } 409 }
436 410
437 dev_info(dev, 411 dev_info(dev,
@@ -440,12 +414,10 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
440 414
441 return 0; 415 return 0;
442 416
443exit_release_region3:
444 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
445exit_release_region2: 417exit_release_region2:
446 release_region(sch311x_wdt_data.runtime_reg + GP60, 1); 418 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
447exit_release_region: 419exit_release_region:
448 release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); 420 release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
449 sch311x_wdt_data.runtime_reg = 0; 421 sch311x_wdt_data.runtime_reg = 0;
450exit: 422exit:
451 return err; 423 return err;
@@ -461,7 +433,6 @@ static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
461 misc_deregister(&sch311x_wdt_miscdev); 433 misc_deregister(&sch311x_wdt_miscdev);
462 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); 434 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
463 release_region(sch311x_wdt_data.runtime_reg + GP60, 1); 435 release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
464 release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
465 sch311x_wdt_data.runtime_reg = 0; 436 sch311x_wdt_data.runtime_reg = 0;
466 return 0; 437 return 0;
467} 438}