1 /***************************************************************************/
4 * linux/drivers/char/resetswitch.c
6 * Basic driver to support the Moxart software reset button.
8 * Jimmy_chen@moxa.com.tw
11 /***************************************************************************/
13 #if 1 // add by Victor Yu. 02-09-2007
14 #include <linux/version.h>
16 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) // add by Victor Yu. 02-09-2007
17 #include <linux/config.h>
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/param.h>
23 #include <linux/init.h>
25 #include <asm/traps.h>
26 #include <linux/delay.h>
27 #include <linux/sched.h>
28 #include <linux/interrupt.h>
29 #include <linux/timer.h>
30 #include <linux/syscalls.h>
31 #include <linux/reboot.h>
32 #include <asm/uaccess.h>
34 #include <asm/arch/moxa.h>
35 #include <asm/arch/gpio.h>
37 #define SWITCH_IRQ IRQ_GPIO
38 #define MOXA_GPIO_DATAOUT 0x0
39 #define MOXA_GPIO_DATAIN 0x04
40 #define MOXA_GPIO_PINDIR 0x08
41 #define MOXA_GPIO_DATASET 0x10
42 #define MOXA_GPIO_DATACLEAR 0x14
43 #define MOXA_GPIO_PPENABLE 0x18
44 #define MOXA_GPIO_PPTYPE 0x1C
45 #define MOXA_GPIO_INTENABLE 0x20
46 #define MOXA_GPIO_INTRAWSTATE 0x24
47 #define MOXA_GPIO_INTMASKSTATE 0x28
48 #define MOXA_GPIO_INTMASK 0x2C
49 #define MOXA_GPIO_INTCLEAR 0x30
50 #define MOXA_GPIO_INTTRIG 0x34
51 #define MOXA_GPIO_INTBOTH 0x38
52 #define MOXA_GPIO_INTRISENEG 0x3C
53 #define MOXA_GPIO_BOUNCEENABLE 0x40
54 #define MOXA_GPIO_BOUNCEPRESCALE 0x44
55 /* watch dog counter */
56 #define WDBASE CPE_WATCHDOG_BASE
58 #define WDRESTART 0x08
62 #define WDINTRLEN 0x18
63 #define WDPASSWD 0x5AB9
67 static int SwitchTimer_on;
68 static struct timer_list SwitchTimer;
71 struct work_struct reset_tqueue;
75 outl(WDPASSWD,WDBASE+WDRESTART) ;
77 static void reset_to_default(void)
79 char *argv[3] , *envp[4] ;
82 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin" ;
83 envp[2] = "TERM=console" ;
86 argv[0] = "ldfactory" ;
89 printk("reset to default\n") ;
90 if(call_usermodehelper("/bin/ldfactory",argv,envp,0)==-1)
91 printk("set to default failure\n") ;
93 #define RESET_IO PIO(25)
94 #define LED_READY PIO(27)
95 static irqreturn_t resetswitch_button(int irq, void *dev_id, struct pt_regs *regs)
100 /* jimmy_chen@moxa.com.tw : kick watch dog before counter */
103 gpio_value=*(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTRAWSTATE)\
105 /* Jimmy_chen@moxa.com.tw : why border???if the user need to reset,
106 * i don't care the task in kernel , cause we will reboot after that.
107 * delay the task , we don't want other thing interrupt while we are
108 * set the user level file to default.
110 if(gpio_value&RESET_IO)
112 for(index=0 ; index<5 ; index++)
116 #if 0 // mask by Victor Yu. 04-10-2007
117 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)&~(RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
119 highlow=inl(CPE_GPIO_BASE+MOXA_GPIO_DATAIN)&(RESET_IO) ;
128 #if 0 // mask by Victor Yu. 04-10-2007
129 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)|(LED_READY|RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
131 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_DATAOUT)|LED_READY,CPE_GPIO_BASE+MOXA_GPIO_DATAOUT) ;
132 #if 0 // mask by Victor Yu. 04-10-2007
133 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)&~(LED_READY|RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
139 #if 0 // mask by Victor Yu. 04-10-2007
140 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)|(LED_READY|RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
142 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_DATAOUT)&~LED_READY,CPE_GPIO_BASE+MOXA_GPIO_DATAOUT) ;
143 #if 0 // mask by Victor Yu. 04-10-2007
144 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)&~(LED_READY|RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
150 schedule_work(&reset_tqueue);
153 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTCLEAR)=(RESET_IO);
157 /***************************************************************************/
158 static void __exit resetswitch_exit(void)
160 free_irq(SWITCH_IRQ,NULL) ;
164 int resetswitch_init(void)
166 #if 0 // mask by Victor Yu. 04-10-2007
167 printk("MoXart gpio initializing......\n") ;
169 INIT_WORK(&reset_tqueue, reset_to_default,NULL);
171 #if 1 // add by Victor Yu. 04-10-2007
172 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)&~(RESET_IO),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
173 outl(inl(CPE_GPIO_BASE+MOXA_GPIO_PINDIR)|(LED_READY),CPE_GPIO_BASE+MOXA_GPIO_PINDIR) ;
176 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_PPENABLE)|=(RESET_IO);
177 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_PPTYPE)|=(RESET_IO);
178 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTTRIG)&=~RESET_IO;
179 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTBOTH)&=~RESET_IO;
180 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTRISENEG)|=RESET_IO;
181 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTENABLE)|=RESET_IO;
182 *(volatile unsigned int *)(CPE_GPIO_BASE+MOXA_GPIO_INTCLEAR)=RESET_IO;
183 cpe_int_set_irq(SWITCH_IRQ, EDGE, H_ACTIVE);
184 if(request_irq(SWITCH_IRQ,&resetswitch_button,SA_INTERRUPT, "Reset Button",0)<0)
185 printk("Unable to allocate IRQ %d\n",SWITCH_IRQ) ;
189 module_init(resetswitch_init);
190 module_exit(resetswitch_exit);
192 /***************************************************************************/