diff options
Diffstat (limited to 'drivers/watchdog/iTCO_wdt.c')
-rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index bf31d7b67a69..b3f604669e2c 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -71,6 +71,8 @@ #define TCOBASE(p) ((p)->tco_res->start) /* SMI Control and Enable Register */ #define SMI_EN(p) ((p)->smi_res->start) +#define TCO_EN (1 << 13) +#define GBL_SMI_EN (1 << 0) #define TCO_RLD(p) (TCOBASE(p) + 0x00) /* TCO Timer Reload/Curr. Value */ #define TCOv1_TMR(p) (TCOBASE(p) + 0x01) /* TCOv1 Timer Initial Value*/ @@ -355,8 +357,12 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t) tmrval = seconds_to_ticks(p, t); - /* For TCO v1 the timer counts down twice before rebooting */ - if (p->iTCO_version == 1) + /* + * If TCO SMIs are off, the timer counts down twice before rebooting. + * Otherwise, the BIOS generally reboots when the SMI triggers. + */ + if (p->smi_res && + (SMI_EN(p) & (TCO_EN | GBL_SMI_EN)) != (TCO_EN | GBL_SMI_EN)) tmrval /= 2; /* from the specs: */ @@ -479,13 +485,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev) if (!devm_request_region(dev, p->smi_res->start, resource_size(p->smi_res), pdev->name)) { - pr_err("I/O address 0x%04llx already in use, device disabled\n", + dev_err(dev, "I/O address 0x%04llx already in use, device disabled\n", (u64)SMI_EN(p)); return -EBUSY; } } else if (iTCO_vendorsupport || turn_SMI_watchdog_clear_off >= p->iTCO_version) { - pr_err("SMI I/O resource is missing\n"); + dev_err(dev, "SMI I/O resource is missing\n"); return -ENODEV; } @@ -521,7 +527,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) * Disables TCO logic generating an SMI# */ val32 = inl(SMI_EN(p)); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + val32 &= ~TCO_EN; /* Turn off SMI clearing watchdog */ outl(val32, SMI_EN(p)); } |