// SPDX-License-Identifier: GPL-2.0+ /* * IB700 Single Board Computer WDT driver * * (c) Copyright 2001 Charles Howes <[email protected]> * * Based on advantechwdt.c which is based on acquirewdt.c which * is based on wdt.c. * * (c) Copyright 2000-2001 Marek Michalkiewicz <[email protected]> * * Based on acquirewdt.c which is based on wdt.c. * Original copyright messages: * * (c) Copyright 1996 Alan Cox <[email protected]>, * 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 <[email protected]> * * 14-Dec-2001 Matt Domsch <[email protected]> * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT * Added timeout module option to override default * */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/types.h> #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/ioport.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/uaccess.h> static struct platform_device *ibwdt_platform_device; static unsigned long ibwdt_is_open; static DEFINE_SPINLOCK(ibwdt_lock); static char expect_close; /* Module information */ #define DRV_NAME … /* * * Watchdog Timer Configuration * * The function of the watchdog timer is to reset the system * automatically and is defined at I/O port 0443H. To enable the * watchdog timer and allow the system to reset, write I/O port 0443H. * To disable the timer, write I/O port 0441H for the system to stop the * watchdog function. The timer has a tolerance of 20% for its * intervals. * * The following describes how the timer should be programmed. * * Enabling Watchdog: * MOV AX,000FH (Choose the values from 0 to F) * MOV DX,0443H * OUT DX,AX * * Disabling Watchdog: * MOV AX,000FH (Any value is fine.) * MOV DX,0441H * OUT DX,AX * * Watchdog timer control table: * Level Value Time/sec | Level Value Time/sec * 1 F 0 | 9 7 16 * 2 E 2 | 10 6 18 * 3 D 4 | 11 5 20 * 4 C 6 | 12 4 22 * 5 B 8 | 13 3 24 * 6 A 10 | 14 2 26 * 7 9 12 | 15 1 28 * 8 8 14 | 16 0 30 * */ #define WDT_STOP … #define WDT_START … /* Default timeout */ #define WATCHDOG_TIMEOUT … static int timeout = …; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(…) …; static bool nowayout = … WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(…) …; /* * Watchdog Operations */ static void ibwdt_ping(void) { … } static void ibwdt_disable(void) { … } static int ibwdt_set_heartbeat(int t) { … } /* * /dev/watchdog handling */ static ssize_t ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { … } static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } static int ibwdt_open(struct inode *inode, struct file *file) { … } static int ibwdt_close(struct inode *inode, struct file *file) { … } /* * Kernel Interfaces */ static const struct file_operations ibwdt_fops = …; static struct miscdevice ibwdt_miscdev = …; /* * Init & exit routines */ static int __init ibwdt_probe(struct platform_device *dev) { … } static void ibwdt_remove(struct platform_device *dev) { … } static void ibwdt_shutdown(struct platform_device *dev) { … } static struct platform_driver ibwdt_driver = …; static int __init ibwdt_init(void) { … } static void __exit ibwdt_exit(void) { … } module_init(…) …; module_exit(ibwdt_exit); MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; /* end of ib700wdt.c */