diff options
Diffstat (limited to 'target/linux/aruba-2.6/files/drivers/char/watchdog')
-rw-r--r-- | target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c b/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c new file mode 100644 index 000000000..de966c869 --- /dev/null +++ b/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c @@ -0,0 +1,110 @@ +#include <linux/autoconf.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/miscdevice.h> +#include <linux/watchdog.h> +#include <linux/fs.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/bootinfo.h> + +extern unsigned long mips_machtype; + +static unsigned long wdt_is_open; +static struct timer_list wdt_timer; + +static void wdt_merlot_refresh(void) +{ + volatile __u32 *wdt; + switch (mips_machtype) { + case MACH_ARUBA_AP70: + wdt = (__u32 *) 0xb8030034; + *wdt = 0x10000000; + break; + default: + wdt = (__u32 *) 0xbc00300c; + *wdt = 0x40000000; + break; + } +} + +static void wdt_merlot_timer_fn(unsigned long data) +{ + wdt_merlot_refresh(); + if (!test_bit(1, &wdt_is_open)) + mod_timer(&wdt_timer, jiffies + HZ); +} + +static int wdt_merlot_setup_timer(void) +{ + + init_timer(&wdt_timer); + wdt_timer.function = wdt_merlot_timer_fn; + wdt_timer.data = 0; + wdt_timer.expires = jiffies + HZ; + add_timer(&wdt_timer); + return 0; +} + +static int wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(0, &wdt_is_open)) + return -EBUSY; + set_bit(1, &wdt_is_open); + return nonseekable_open(inode, file); +} + +static ssize_t wdt_write(struct file *file, const char __user * buf, size_t count, loff_t * ppos) +{ + if (count) /* something was written */ + wdt_merlot_refresh(); + return count; +} + +static int wdt_release(struct inode *inode, struct file *file) +{ + clear_bit(0, &wdt_is_open); + return 0; +} + +static struct file_operations wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wdt_write, + .open = wdt_open, + .release = wdt_release, +}; + +static struct miscdevice wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops, +}; + +static void __exit wdt_exit(void) +{ + misc_deregister(&wdt_miscdev); +} + +static int __init wdt_init(void) +{ + int ret; + ret = misc_register(&wdt_miscdev); + if (ret) { + printk(KERN_ERR + "wdt: cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); + misc_deregister(&wdt_miscdev); + goto out; + } + printk("wdt: registered with refresh\n"); + wdt_merlot_refresh(); + wdt_merlot_setup_timer(); + out: + return ret; +} + +module_init(wdt_init); +module_exit(wdt_exit); |