| From 213c9cd2aaa0ea66a0a6e786075826f37f85fbc6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 30 May 2021 13:24:23 +0200 |
| Subject: watchdog: iTCO_wdt: Account for rebooting on second timeout |
| |
| From: Jan Kiszka <jan.kiszka@siemens.com> |
| |
| [ Upstream commit cb011044e34c293e139570ce5c01aed66a34345c ] |
| |
| This was already attempted to fix via 1fccb73011ea: If the BIOS did not |
| enable TCO SMIs, the timer definitely needs to trigger twice in order to |
| cause a reboot. If TCO SMIs are on, as well as SMIs in general, we can |
| continue to assume that the BIOS will perform a reboot on the first |
| timeout. |
| |
| QEMU with its ICH9 and related BIOS falls into the former category, |
| currently taking twice the configured timeout in order to reboot the |
| machine. For iTCO version that fall under turn_SMI_watchdog_clear_off, |
| this is also true and was currently only addressed for v1, irrespective |
| of the turn_SMI_watchdog_clear_off value. |
| |
| Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> |
| Reviewed-by: Guenter Roeck <linux@roeck-us.net> |
| Link: https://lore.kernel.org/r/0b8bb307-d08b-41b5-696c-305cdac6789c@siemens.com |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/watchdog/iTCO_wdt.c | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c |
| index bf31d7b67a69..3f1324871cfd 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: */ |
| @@ -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)); |
| } |
| |
| -- |
| 2.30.2 |
| |