de966c86996069304325d112eab9c51094dffbf0
[openwrt/svn-archive/archive.git] / target / linux / aruba-2.6 / files / drivers / char / watchdog / wdt_merlot.c
1 #include <linux/autoconf.h>
2 #include <linux/module.h>
3 #include <linux/types.h>
4 #include <linux/miscdevice.h>
5 #include <linux/watchdog.h>
6 #include <linux/fs.h>
7
8 #include <asm/io.h>
9 #include <asm/uaccess.h>
10 #include <asm/system.h>
11 #include <asm/bootinfo.h>
12
13 extern unsigned long mips_machtype;
14
15 static unsigned long wdt_is_open;
16 static struct timer_list wdt_timer;
17
18 static void wdt_merlot_refresh(void)
19 {
20 volatile __u32 *wdt;
21 switch (mips_machtype) {
22 case MACH_ARUBA_AP70:
23 wdt = (__u32 *) 0xb8030034;
24 *wdt = 0x10000000;
25 break;
26 default:
27 wdt = (__u32 *) 0xbc00300c;
28 *wdt = 0x40000000;
29 break;
30 }
31 }
32
33 static void wdt_merlot_timer_fn(unsigned long data)
34 {
35 wdt_merlot_refresh();
36 if (!test_bit(1, &wdt_is_open))
37 mod_timer(&wdt_timer, jiffies + HZ);
38 }
39
40 static int wdt_merlot_setup_timer(void)
41 {
42
43 init_timer(&wdt_timer);
44 wdt_timer.function = wdt_merlot_timer_fn;
45 wdt_timer.data = 0;
46 wdt_timer.expires = jiffies + HZ;
47 add_timer(&wdt_timer);
48 return 0;
49 }
50
51 static int wdt_open(struct inode *inode, struct file *file)
52 {
53 if (test_and_set_bit(0, &wdt_is_open))
54 return -EBUSY;
55 set_bit(1, &wdt_is_open);
56 return nonseekable_open(inode, file);
57 }
58
59 static ssize_t wdt_write(struct file *file, const char __user * buf, size_t count, loff_t * ppos)
60 {
61 if (count) /* something was written */
62 wdt_merlot_refresh();
63 return count;
64 }
65
66 static int wdt_release(struct inode *inode, struct file *file)
67 {
68 clear_bit(0, &wdt_is_open);
69 return 0;
70 }
71
72 static struct file_operations wdt_fops = {
73 .owner = THIS_MODULE,
74 .llseek = no_llseek,
75 .write = wdt_write,
76 .open = wdt_open,
77 .release = wdt_release,
78 };
79
80 static struct miscdevice wdt_miscdev = {
81 .minor = WATCHDOG_MINOR,
82 .name = "watchdog",
83 .fops = &wdt_fops,
84 };
85
86 static void __exit wdt_exit(void)
87 {
88 misc_deregister(&wdt_miscdev);
89 }
90
91 static int __init wdt_init(void)
92 {
93 int ret;
94 ret = misc_register(&wdt_miscdev);
95 if (ret) {
96 printk(KERN_ERR
97 "wdt: cannot register miscdev on minor=%d (err=%d)\n",
98 WATCHDOG_MINOR, ret);
99 misc_deregister(&wdt_miscdev);
100 goto out;
101 }
102 printk("wdt: registered with refresh\n");
103 wdt_merlot_refresh();
104 wdt_merlot_setup_timer();
105 out:
106 return ret;
107 }
108
109 module_init(wdt_init);
110 module_exit(wdt_exit);