#include <linux/miscdevice.h>

#include <linux/watchdog.h>


#define DEFAULT_WATCHDOG_TIMEOUT 10 /* 10-second timeout */

#define TIMEOUT_SHIFT 5             /* To get to the timeout field

                                       in WD_CONTROL_REGISTER */
#define WENABLE_SHIFT 3             /* To get to the

                                       watchdog-enable field in
                                       WD_CONTROL_REGISTER */

/* Misc structure */
static struct miscdevice my_wdt_dev = {
    .minor = WATCHDOG_MINOR, /* defined as 130 in
                                include/linux/miscdevice.h */
    .name = "watchdog",      /* /dev/watchdog */
    .fops = &my_wdt_dog      /* Watchdog driver entry points */
};

/* Driver methods */
struct file_operations my_wdt_dog = {
    .owner = THIS_MODULE,
    .open = my_wdt_open,
    .release = my_wdt_close,
    .write = my_wdt_write,
    .ioctl = my_wdt_ioctl
}

/* Module Initialization */
static int __init
my_wdt_init(void)
{
    /* ... */
    misc_register(&my_wdt_dev);
    /* ... */
}

/* Open watchdog */
static void
my_wdt_open(struct inode *inode, struct file *file)
{
    /* Set the timeout and enable the watchdog */
    WD_CONTROL_REGISTER |= DEFAULT_WATCHDOG_TIMEOUT << TIMEOUT_SHIFT;
    WD_CONTROL_REGISTER |= 1 << WENABLE_SHIFT;
}

/* Close watchdog */
static int
my_wdt_close(struct inode *inode, struct file *file)
{
    /* If CONFIG_WATCHDOG_NOWAYOUT is chosen during kernel
       configuration, do not disable the watchdog even if the
       application desires to close it */
#ifndef CONFIG_WATCHDOG_NOWAYOUT

    /* Disable watchdog */
    WD_CONTROL_REGISTER &= ~(1 << WENABLE_SHIFT);
#endif

    return 0;
}

/* Pet the dog */
static ssize_t
my_wdt_write(struct file *file, const char *data,
             size_t len, loff_t *ppose)
{
    /* Pet the dog by writing a specified sequence of bytes to the
       watchdog service register */
    WD_SERVICE_REGISTER = 0xABCD;
}

/* Ioctl method. Look at Documentation/watchdog/watchdog-api
   for the full list of ioctl commands. This is standard across
   watchdog drivers, so conforming applications are rendered
   hardware-independent */
static int
my_wdt_ioctl(struct inode *inode, struct file *file,
             unsigned int cmd, unsigned long arg)
{
    /* ... */
    switch (cmd) {
    case WDIOC_KEEPALIVE:
        /* Write to the watchdog. Applications can invoke
           this ioctl instead of writing to the device */
        WD_SERVICE_REGISTER = 0xABCD;
        break;
    case WDIOC_SETTIMEOUT:
        copy_from_user(&timeout, (int *)arg, sizeof(int));
        /* Set the timeout that defines unresponsiveness by
           writing to the watchdog control register */
        WD_CONTROL_REGISTER = timeout << TIMEOUT_BITS;
        break;
    case WDIOC_GETTIMEOUT:
        /* Get the currently set timeout from the watchdog */
        /* ... */
        break;
    default:
        return -ENOTTY;
    }
}

/* Module Exit */
static void __exit
my_wdt_exit(void)
{
    /* ... */
    misc_deregister(&my_wdt_dev);
    /* ... */
}

module_init(my_wdt_init);
module_exit(my_wdt_exit);


syntax highlighted by Code2HTML, v. 0.9.1