hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/watchdog/sp5100_tco.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * sp5100_tco : TCO timer driver for sp5100 chipsets
34 *
....@@ -6,12 +7,7 @@
67 * Based on i8xx_tco.c:
78 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights
89 * Reserved.
9
- * http://www.kernelconcepts.de
10
- *
11
- * This program is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU General Public License
13
- * as published by the Free Software Foundation; either version
14
- * 2 of the License, or (at your option) any later version.
10
+ * https://www.kernelconcepts.de
1511 *
1612 * See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide",
1713 * AMD Publication 45482 "AMD SB800-Series Southbridges Register
....@@ -21,6 +17,12 @@
2117 * AMD Publication 51192 "AMD Bolton FCH Register Reference Guide"
2218 * AMD Publication 52740 "BIOS and Kernel Developer’s Guide (BKDG)
2319 * for AMD Family 16h Models 30h-3Fh Processors"
20
+ * AMD Publication 55570-B1-PUB "Processor Programming Reference (PPR)
21
+ * for AMD Family 17h Model 18h, Revision B1
22
+ * Processors (PUB)
23
+ * AMD Publication 55772-A1-PUB "Processor Programming Reference (PPR)
24
+ * for AMD Family 17h Model 20h, Revision A1
25
+ * Processors (PUB)
2426 */
2527
2628 /*
....@@ -100,6 +102,10 @@
100102
101103 val = readl(SP5100_WDT_CONTROL(tco->tcobase));
102104 val |= SP5100_WDT_START_STOP_BIT;
105
+ writel(val, SP5100_WDT_CONTROL(tco->tcobase));
106
+
107
+ /* This must be a distinct write. */
108
+ val |= SP5100_WDT_TRIGGER_BIT;
103109 writel(val, SP5100_WDT_CONTROL(tco->tcobase));
104110
105111 return 0;
....@@ -245,6 +251,18 @@
245251 break;
246252 case efch:
247253 dev_name = SB800_DEVNAME;
254
+ /*
255
+ * On Family 17h devices, the EFCH_PM_DECODEEN_WDT_TMREN bit of
256
+ * EFCH_PM_DECODEEN not only enables the EFCH_PM_WDT_ADDR memory
257
+ * region, it also enables the watchdog itself.
258
+ */
259
+ if (boot_cpu_data.x86 == 0x17) {
260
+ val = sp5100_tco_read_pm_reg8(EFCH_PM_DECODEEN);
261
+ if (!(val & EFCH_PM_DECODEEN_WDT_TMREN)) {
262
+ sp5100_tco_update_pm_reg8(EFCH_PM_DECODEEN, 0xff,
263
+ EFCH_PM_DECODEEN_WDT_TMREN);
264
+ }
265
+ }
248266 val = sp5100_tco_read_pm_reg8(EFCH_PM_DECODEEN);
249267 if (val & EFCH_PM_DECODEEN_WDT_TMREN)
250268 mmio_addr = EFCH_PM_WDT_ADDR;
....@@ -395,9 +413,7 @@
395413 wdd->min_timeout = 1;
396414 wdd->max_timeout = 0xffff;
397415
398
- if (watchdog_init_timeout(wdd, heartbeat, NULL))
399
- dev_info(dev, "timeout value invalid, using %d\n",
400
- wdd->timeout);
416
+ watchdog_init_timeout(wdd, heartbeat, NULL);
401417 watchdog_set_nowayout(wdd, nowayout);
402418 watchdog_stop_on_reboot(wdd);
403419 watchdog_stop_on_unregister(wdd);
....@@ -408,10 +424,8 @@
408424 return ret;
409425
410426 ret = devm_watchdog_register_device(dev, wdd);
411
- if (ret) {
412
- dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
427
+ if (ret)
413428 return ret;
414
- }
415429
416430 /* Show module parameters */
417431 dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",