// SPDX-License-Identifier: GPL-2.0+ /* * w83627hf/thf WDT driver * * (c) Copyright 2013 Guenter Roeck * converted to watchdog infrastructure * * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com> * added support for W83627THF. * * (c) Copyright 2003,2007 Pádraig Brady <P@draigBrady.com> * * Based on advantechwdt.c which is based on wdt.c. * Original copyright messages: * * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl> * * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>, * All Rights Reserved. * * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide * warranty for any of this software. This material is provided * "AS-IS" and at no charge. * * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
staticbool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
staticint early_disable;
module_param(early_disable, int, 0);
MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)");
/* * Kernel methods.
*/
#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register
(same as EFER) */ #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
/* set CR30 bit 0 to activate GPIO2 */
t = superio_inb(0x30); if (!(t & 0x01))
superio_outb(0x30, t | 0x01);
switch (chip) { case w83627hf: case w83627s:
t = superio_inb(0x2B) & ~0x10;
superio_outb(0x2B, t); /* set GPIO24 to WDT0 */ break; case w83697hf: /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
t = superio_inb(0x29) & ~0x60;
t |= 0x20;
superio_outb(0x29, t); break; case w83697ug: /* Set pin 118 to WDTO# mode */
t = superio_inb(0x2b) & ~0x04;
superio_outb(0x2b, t); break; case w83627thf:
t = (superio_inb(0x2B) & ~0x08) | 0x04;
superio_outb(0x2B, t); /* set GPIO3 to WDT0 */ break; case w83627dhg: case w83627dhg_p:
t = superio_inb(0x2D) & ~0x01; /* PIN77 -> WDT0# */
superio_outb(0x2D, t); /* set GPIO5 to WDT0 */
t = superio_inb(cr_wdt_control);
t |= 0x02; /* enable the WDTO# output low pulse
* to the KBRST# pin */
superio_outb(cr_wdt_control, t); break; case w83637hf: break; case w83687thf:
t = superio_inb(0x2C) & ~0x80; /* PIN47 -> WDT0# */
superio_outb(0x2C, t); break; case w83627ehf: case w83627uhg: case w83667hg: case w83667hg_b: case nct6775: case nct6776: case nct6779: case nct6791: case nct6792: case nct6793: case nct6795: case nct6796: case nct6102: case nct6116: /* * These chips have a fixed WDTO# output pin (W83627UHG), * or support more than one WDTO# output pin. * Don't touch its configuration, and hope the BIOS * does the right thing.
*/
t = superio_inb(cr_wdt_control);
t |= 0x02; /* enable the WDTO# output low pulse
* to the KBRST# pin */
superio_outb(cr_wdt_control, t); break; default: break;
}
t = superio_inb(cr_wdt_timeout); if (t != 0) { if (early_disable) {
pr_warn("Stopping previously enabled watchdog until userland kicks in\n");
superio_outb(cr_wdt_timeout, 0);
} else {
pr_info("Watchdog already running. Resetting timeout to %d sec\n",
wdog->timeout);
superio_outb(cr_wdt_timeout, wdog->timeout);
}
}
/* set second mode & disable keyboard turning off watchdog */
t = superio_inb(cr_wdt_control) & ~0x0C;
superio_outb(cr_wdt_control, t);
t = superio_inb(cr_wdt_csr); if (t & WDT_CSR_STATUS)
wdog->bootstatus |= WDIOF_CARDRESET;
/* reset status, disable keyboard & mouse turning off watchdog */
t &= ~(WDT_CSR_STATUS | WDT_CSR_KBD | WDT_CSR_MOUSE);
superio_outb(cr_wdt_csr, t);
superio_exit();
return 0;
}
staticint wdt_set_time(unsignedint timeout)
{ int ret;
ret = superio_enter(); if (ret) return ret;
superio_select(W83627HF_LD_WDT);
val = superio_inb(0x20); switch (val) { case W83627HF_ID:
ret = w83627hf; break; case W83627S_ID:
ret = w83627s; break; case W83697HF_ID:
ret = w83697hf;
cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
cr_wdt_control = W83697HF_WDT_CONTROL; break; case W83697UG_ID:
ret = w83697ug;
cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
cr_wdt_control = W83697HF_WDT_CONTROL; break; case W83637HF_ID:
ret = w83637hf; break; case W83627THF_ID:
ret = w83627thf; break; case W83687THF_ID:
ret = w83687thf; break; case W83627EHF_ID:
ret = w83627ehf; break; case W83627DHG_ID:
ret = w83627dhg; break; case W83627DHG_P_ID:
ret = w83627dhg_p; break; case W83627UHG_ID:
ret = w83627uhg; break; case W83667HG_ID:
ret = w83667hg; break; case W83667HG_B_ID:
ret = w83667hg_b; break; case NCT6775_ID:
ret = nct6775; break; case NCT6776_ID:
ret = nct6776; break; case NCT6779_ID:
ret = nct6779; break; case NCT6791_ID:
ret = nct6791; break; case NCT6792_ID:
ret = nct6792; break; case NCT6793_ID:
ret = nct6793; break; case NCT6795_ID:
ret = nct6795; break; case NCT6796_ID:
ret = nct6796; break; case NCT6102_ID:
ret = nct6102;
cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
cr_wdt_control = NCT6102D_WDT_CONTROL;
cr_wdt_csr = NCT6102D_WDT_CSR; break; case NCT6116_ID:
ret = nct6116;
cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
cr_wdt_control = NCT6102D_WDT_CONTROL;
cr_wdt_csr = NCT6102D_WDT_CSR; break; case 0xff:
ret = -ENODEV; break; default:
ret = -ENODEV;
pr_err("Unsupported chip ID: 0x%02x\n", val); break;
}
superio_exit(); return ret;
}
/* * On some systems, the NCT6791D comes with a companion chip and the * watchdog function is in this companion chip. We must use a different * unlocking sequence to access the companion chip.
*/ staticint __init wdt_use_alt_key(conststruct dmi_system_id *d)
{
wdt_cfg_enter = 0x88;
wdt_cfg_leave = 0xBB;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.