2 * Infineon AP DC COM Amazon WDT driver
3 * Copyright 2004 Wu Qi Ming <gokimi@msn.com>
6 #if defined(MODVERSIONS)
7 #include <linux/modversions.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/timer.h>
18 #include <linux/errno.h>
19 #include <linux/proc_fs.h>
20 #include <linux/stat.h>
21 #include <linux/tty.h>
22 #include <linux/selection.h>
23 #include <linux/kmod.h>
24 #include <linux/vmalloc.h>
25 #include <linux/kdev_t.h>
26 #include <linux/ioctl.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
29 #include <asm/amazon/amazon.h>
30 #include <asm/amazon/amazon_wdt.h>
32 #define AMAZON_WDT_EMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args)
34 extern unsigned int amazon_get_fpi_hz(void);
36 /* forward declarations for _fops */
37 static ssize_t
wdt_read(struct file
*file
, char *buf
, size_t count
, loff_t
*offset
);
38 static ssize_t
wdt_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*offset
);
39 static int wdt_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
);
40 static int wdt_open(struct inode
*inode
, struct file
*file
);
41 static int wdt_release(struct inode
*inode
, struct file
*file
);
42 static int wdt_proc_read(char *buf
, char **start
, off_t offset
,int count
, int *eof
, void *data
);
45 static struct file_operations wdt_fops
= {
54 static struct wdt_dev
*amazon_wdt_dev
;
55 static struct proc_dir_entry
* amazon_wdt_dir
;
56 static int occupied
=0;
61 timeout: time interval for WDT
67 2. Modify Access (change ENDINIT => 0)
68 3. Change WDT_CON1 (enable WDT)
69 4. Password Access again
70 5. Modify Access (change ENDINIT => 1)
72 int wdt_enable(int timeout
)
75 int reload_value
, divider
=0;
77 ffpi
= amazon_get_fpi_hz();
80 if((reload_value
=65536-timeout
*ffpi
/256)<0){
82 reload_value
=65536-timeout
*ffpi
/16384;
84 if (reload_value
< 0){
85 AMAZON_WDT_EMSG("timeout too large %d\n", timeout
);
89 AMAZON_WDT_EMSG("timeout:%d reload_value: %8x\n", timeout
, reload_value
);
91 hard_psw
=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1
)&0xc)+ 0xf0;
92 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=hard_psw
;
95 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=(hard_psw
&0xff00)+(reload_value
<<16)+0xf2;
98 AMAZON_WDT_REG32(AMAZON_WDT_CON1
)=divider
<<2;
101 hard_psw
=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1
)&0xc)+ 0xf0;
102 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=hard_psw
;
105 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff00)+0xf3;
110 /* Brief: Disable/stop WDT
112 void wdt_disable(void)
116 hard_psw
=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1
)&0xc)+ 0xf0;
117 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=hard_psw
;
120 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff00)+0xf2;
123 AMAZON_WDT_REG32(AMAZON_WDT_CON1
)|=8;
126 hard_psw
=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff01)+(AMAZON_WDT_REG32(AMAZON_WDT_CON1
)&0xc)+ 0xf0;
127 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=hard_psw
;
130 AMAZON_WDT_REG32(AMAZON_WDT_CON0
)=(AMAZON_WDT_REG32(AMAZON_WDT_CON0
)&0xffffff00)+0xf3;
136 static int wdt_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
139 static int timeout
=-1;
142 case AMAZON_WDT_IOC_START
:
143 AMAZON_WDT_DMSG("enable watch dog timer!\n");
144 if ( copy_from_user((void*)&timeout
, (void*)arg
, sizeof (int)) ){
145 AMAZON_WDT_EMSG("invalid argument\n");
148 if ((result
= wdt_enable(timeout
)) < 0){
153 case AMAZON_WDT_IOC_STOP
:
154 AMAZON_WDT_DMSG("disable watch dog timer\n");
159 case AMAZON_WDT_IOC_PING
:
163 result
= wdt_enable(timeout
);
169 static ssize_t
wdt_read(struct file
*file
, char *buf
, size_t count
, loff_t
*offset
)
174 static ssize_t
wdt_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*offset
)
179 static int wdt_open(struct inode
*inode
, struct file
*file
)
181 AMAZON_WDT_DMSG("wdt_open\n");
183 if (occupied
== 1) return -EBUSY
;
189 static int wdt_release(struct inode
*inode
, struct file
*file
)
191 AMAZON_WDT_DMSG("wdt_release\n");
198 int wdt_register_proc_read(char *buf
, char **start
, off_t offset
,
199 int count
, int *eof
, void *data
)
202 printk("wdt_registers:\n");
203 len
+=sprintf(buf
+len
,"NMISR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_NMISR
));
204 len
+=sprintf(buf
+len
,"RST_REQ: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_REQ
));
205 len
+=sprintf(buf
+len
,"RST_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_SR
));
206 len
+=sprintf(buf
+len
,"WDT_CON0: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON0
));
207 len
+=sprintf(buf
+len
,"WDT_CON1: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON1
));
208 len
+=sprintf(buf
+len
,"WDT_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_SR
));
214 int __init
amazon_wdt_init_module(void)
218 amazon_wdt_dev
= (wdt_dev
*)kmalloc(sizeof(wdt_dev
),GFP_KERNEL
);
219 if (amazon_wdt_dev
== NULL
){
222 memset(amazon_wdt_dev
,0,sizeof(wdt_dev
));
224 amazon_wdt_dev
->major
=result
;
225 strcpy(amazon_wdt_dev
->name
,"wdt");
227 result
= register_chrdev(0,amazon_wdt_dev
->name
,&wdt_fops
);
229 AMAZON_WDT_EMSG("cannot register device\n");
230 kfree(amazon_wdt_dev
);
234 amazon_wdt_dir
=proc_mkdir("amazon_wdt",NULL
);
235 create_proc_read_entry("wdt_register",
238 wdt_register_proc_read
,
245 void amazon_wdt_cleanup_module(void)
247 unregister_chrdev(amazon_wdt_dev
->major
,amazon_wdt_dev
->name
);
248 kfree(amazon_wdt_dev
);
249 remove_proc_entry("wdt_register",amazon_wdt_dir
);
250 remove_proc_entry("amazon_wdt",NULL
);
251 AMAZON_WDT_DMSG("unloaded\n");
255 MODULE_LICENSE ("GPL");
256 MODULE_AUTHOR("Infineon IFAP DC COM");
257 MODULE_DESCRIPTION("AMAZON WDT driver");
259 module_init(amazon_wdt_init_module
);
260 module_exit(amazon_wdt_cleanup_module
);