1 /***************************************************************************/
4 * linux/drivers/char/resetswitch.c
6 * Basic driver to support the NETtel software reset button.
8 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
11 /***************************************************************************/
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/param.h>
17 #include <linux/init.h>
19 #include <asm/traps.h>
20 #include <asm/machdep.h>
21 #include <asm/coldfire.h>
22 #include <asm/mcftimer.h>
23 #include <asm/mcfsim.h>
24 #include <asm/delay.h>
26 /***************************************************************************/
28 /***************************************************************************/
31 * Off-course the 5272 would have to deal with setting up and
32 * acknowledging interrupts differently to all other ColdFIre's!
36 static void __inline__ mcf_enablevector(int vecnr)
38 volatile unsigned long *icrp;
39 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
40 *icrp = (*icrp & 0x07777777) | 0xf0000000;
43 static void __inline__ mcf_disablevector(void)
45 volatile unsigned long *icrp;
46 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
47 *icrp = (*icrp & 0x07777777) | 0x80000000;
50 static void __inline__ mcf_ackvector(void)
52 volatile unsigned long *icrp;
53 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
54 *icrp = (*icrp & 0x07777777) | 0xf0000000;
57 static __inline__ int mcf_isvector(void)
59 return((*((volatile unsigned long *) (MCF_MBAR + MCFSIM_ISR)) & 0x80000000) == 0);
62 /***************************************************************************/
64 /***************************************************************************/
67 * Common vector setup for 5206e, 5307 and 5407.
71 static void __inline__ mcf_enablevector(int vecnr)
75 static void __inline__ mcf_disablevec(void)
77 mcf_setimr(mcf_getimr() | MCFSIM_IMR_EINT7);
80 static void __inline__ mcf_ackvector(void)
82 mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT7);
85 static __inline__ int mcf_isvector(void)
87 return(mcf_getipr() & MCFSIM_IMR_EINT7);
90 /***************************************************************************/
91 #endif /* !CONFIG_M5272 */
92 /***************************************************************************/
94 void resetswitch_button(int irq, void *dev_id, struct pt_regs *regs)
96 extern void flash_eraseconfig(void);
97 static int inbutton = 0;
100 * IRQ7 is not maskable by the CPU core. It is possible
101 * that switch bounce mey get us back here before we have
102 * really serviced the interrupt.
108 /* Disable interrupt at SIM - best we can do... */
113 /* Try and de-bounce the switch a little... */
116 #ifdef CONFIG_BLK_DEV_BLKMEM
120 /* Don't leave here 'till button is no longer pushed! */
122 if (mcf_isvector() != 0)
127 /* Should never get here... */
134 /***************************************************************************/
136 int resetswitch_init(void)
138 mcf_enablevector(SWITCH_IRQ);
139 mcf_autovector(SWITCH_IRQ);
140 request_irq(SWITCH_IRQ, resetswitch_button,
141 (SA_INTERRUPT | IRQ_FLG_FAST), "Reset Button", NULL);
145 module_init(resetswitch_init);
147 /***************************************************************************/