Skip to content

Commit 4343907

Browse files
jameshilliardWim Van Sebroeck
authored andcommitted
watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04
For the watchdog timer to work properly on the QCML04 board we need to set PWRGD enable in the Environment Controller Configuration Registers Special Configuration Register 1 when it is not already set, this may be the case when the watchdog is not enabled from within the BIOS. Signed-off-by: James Hilliard <[email protected]> Reviewed-by: Guenter Roeck <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]> Signed-off-by: Wim Van Sebroeck <[email protected]>
1 parent 90fc2c8 commit 4343907

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

drivers/watchdog/it87_wdt.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2222

23+
#include <linux/bits.h>
24+
#include <linux/dmi.h>
2325
#include <linux/init.h>
2426
#include <linux/io.h>
2527
#include <linux/kernel.h>
@@ -40,6 +42,7 @@
4042
#define VAL 0x2f
4143

4244
/* Logical device Numbers LDN */
45+
#define EC 0x04
4346
#define GPIO 0x07
4447

4548
/* Configuration Registers and Functions */
@@ -73,6 +76,12 @@
7376
#define IT8784_ID 0x8784
7477
#define IT8786_ID 0x8786
7578

79+
/* Environment Controller Configuration Registers LDN=0x04 */
80+
#define SCR1 0xfa
81+
82+
/* Environment Controller Bits SCR1 */
83+
#define WDT_PWRGD 0x20
84+
7685
/* GPIO Configuration Registers LDN=0x07 */
7786
#define WDTCTRL 0x71
7887
#define WDTCFG 0x72
@@ -240,6 +249,21 @@ static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
240249
return ret;
241250
}
242251

252+
enum {
253+
IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0),
254+
};
255+
256+
static const struct dmi_system_id it87_quirks[] = {
257+
{
258+
/* Qotom Q30900P (IT8786) */
259+
.matches = {
260+
DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"),
261+
},
262+
.driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD,
263+
},
264+
{}
265+
};
266+
243267
static const struct watchdog_info ident = {
244268
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
245269
.firmware_version = 1,
@@ -261,8 +285,10 @@ static struct watchdog_device wdt_dev = {
261285

262286
static int __init it87_wdt_init(void)
263287
{
288+
const struct dmi_system_id *dmi_id;
264289
u8 chip_rev;
265290
u8 ctrl;
291+
int quirks = 0;
266292
int rc;
267293

268294
rc = superio_enter();
@@ -273,6 +299,10 @@ static int __init it87_wdt_init(void)
273299
chip_rev = superio_inb(CHIPREV) & 0x0f;
274300
superio_exit();
275301

302+
dmi_id = dmi_first_match(it87_quirks);
303+
if (dmi_id)
304+
quirks = (long)dmi_id->driver_data;
305+
276306
switch (chip_type) {
277307
case IT8702_ID:
278308
max_units = 255;
@@ -333,6 +363,15 @@ static int __init it87_wdt_init(void)
333363
superio_outb(0x00, WDTCTRL);
334364
}
335365

366+
if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) {
367+
superio_select(EC);
368+
ctrl = superio_inb(SCR1);
369+
if (!(ctrl & WDT_PWRGD)) {
370+
ctrl |= WDT_PWRGD;
371+
superio_outb(ctrl, SCR1);
372+
}
373+
}
374+
336375
superio_exit();
337376

338377
if (timeout < 1 || timeout > max_units * 60) {

0 commit comments

Comments
 (0)