// SPDX-License-Identifier: GPL-2.0-or-later /* * MachZ ZF-Logic Watchdog Timer driver for Linux * * The author does NOT admit liability nor provide warranty for * any of this software. This material is provided "AS-IS" in * the hope that it may be useful for others. * * Author: Fernando Fuganti <fuganti@conectiva.com.br> * * Based on sbc60xxwdt.c by Jakob Oestergaard * * We have two timers (wd#1, wd#2) driven by a 32 KHz clock with the * following periods: * wd#1 - 2 seconds; * wd#2 - 7.2 ms; * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or * a system RESET and it starts wd#2 that unconditionally will RESET * the system when the counter reaches zero. * * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
*/
if (time_before(jiffies, next_heartbeat)) {
dprintk("time_before: %ld\n", next_heartbeat - jiffies); /* * reset event is activated by transition from 0 to 1 on * RESET_WD1 bit and we assume that it is already zero...
*/
/* ...and nothing changes until here */
ctrl_reg &= ~(RESET_WD1);
zf_set_control(ctrl_reg);
spin_unlock_irqrestore(&zf_port_lock, flags);
mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
} else
pr_crit("I will reset your machine\n");
}
static ssize_t zf_write(struct file *file, constchar __user *buf, size_t count,
loff_t *ppos)
{ /* See if we got the magic character */ if (count) { /* * no need to check for close confirmation * no way to disable watchdog ;)
*/ if (!nowayout) {
size_t ofs; /* * note: just in case someone wrote the magic character * five months ago...
*/
zf_expect_close = 0;
/* now scan */ for (ofs = 0; ofs != count; ofs++) { char c; if (get_user(c, buf + ofs)) return -EFAULT; if (c == 'V') {
zf_expect_close = 42;
dprintk("zf_expect_close = 42\n");
}
}
}
/* * Well, anyhow someone wrote to us, * we should return that favour
*/
next_heartbeat = jiffies + ZF_USER_TIMEO;
dprintk("user ping at %ld\n", jiffies);
} return count;
}
staticlong zf_ioctl(struct file *file, unsignedint cmd, unsignedlong arg)
{ void __user *argp = (void __user *)arg; int __user *p = argp; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user(argp, &zf_info, sizeof(zf_info))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE:
zf_ping(NULL); break; default: return -ENOTTY;
} return 0;
}
/* * The device needs to learn about soft shutdowns in order to * turn the timebomb registers off.
*/ staticstruct notifier_block zf_notifier = {
.notifier_call = zf_notify_sys,
};
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.