12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #define DRV_NAME "wdt"
15 #define DRV_VERSION "0.01"
18 #include <linux/errno.h>
20 #include <linux/hrtimer.h>
21 #include <linux/kernel.h>
25 #include <linux/module.h>
30 #include <linux/watchdog.h>
32 #include <asm/xen/hypercall.h>
41 #define WATCHDOG_TIMEOUT 60
58 static int xen_wdt_start(
void)
65 expires = set_timeout();
72 wdt_expires = expires;
77 spin_unlock(&wdt_lock);
82 static int xen_wdt_stop(
void)
94 spin_unlock(&wdt_lock);
99 static int xen_wdt_kick(
void)
104 spin_lock(&wdt_lock);
106 expires = set_timeout();
112 wdt_expires = expires;
114 spin_unlock(&wdt_lock);
127 err = xen_wdt_start();
129 err = xen_wdt_kick();
133 static int xen_wdt_release(
struct inode *inode,
struct file *file)
138 err = xen_wdt_stop();
140 pr_crit(
"unexpected close, not stopping watchdog!\n");
144 expect_release =
false;
148 static ssize_t xen_wdt_write(
struct file *file,
const char __user *
data,
149 size_t len, loff_t *ppos)
157 expect_release =
false;
161 for (i = 0; i != len; i++) {
166 expect_release =
true;
176 static long xen_wdt_ioctl(
struct file *file,
unsigned int cmd,
184 .firmware_version = 0,
201 retval = xen_wdt_stop();
203 retval = xen_wdt_start();
204 if (retval == -
EBUSY)
205 retval = xen_wdt_kick();
225 retval = wdt_expires - ktime_to_timespec(
ktime_get()).tv_sec;
235 .write = xen_wdt_write,
236 .unlocked_ioctl = xen_wdt_ioctl,
237 .open = xen_wdt_open,
238 .release = xen_wdt_release,
244 .fops = &xen_wdt_fops,
247 static int __devinit xen_wdt_probe(
struct platform_device *
dev)
261 pr_err(
"cannot register miscdev on minor=%d (%d)\n",
266 pr_info(
"initialized (timeout=%ds, nowayout=%d)\n",
276 pr_info(
"bogus return value %d\n", ret);
283 static int __devexit xen_wdt_remove(
struct platform_device *dev)
294 static void xen_wdt_shutdown(
struct platform_device *dev)
302 int rc = xen_wdt_stop();
308 static
int xen_wdt_resume(
struct platform_device *dev)
313 return xen_wdt_start();
317 .probe = xen_wdt_probe,
319 .shutdown = xen_wdt_shutdown,
320 .suspend = xen_wdt_suspend,
321 .resume = xen_wdt_resume,
328 static int __init xen_wdt_init_module(
void)
341 platform_device = platform_device_register_simple(
DRV_NAME,
343 if (IS_ERR(platform_device)) {
344 err = PTR_ERR(platform_device);
351 static void __exit xen_wdt_cleanup_module(
void)