Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into...
[pandora-kernel.git] / arch / h8300 / platform / h8s / ints_h8s.c
1 /*
2  * linux/arch/h8300/platform/h8s/ints_h8s.c
3  * Interrupt handling CPU variants
4  *
5  * Yoshinori Sato <ysato@users.sourceforge.jp>
6  *
7  */
8
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12
13 #include <asm/ptrace.h>
14 #include <asm/traps.h>
15 #include <asm/irq.h>
16 #include <asm/io.h>
17 #include <asm/gpio.h>
18 #include <asm/regs267x.h>
19
20 /* saved vector list */
21 const int __initdata h8300_saved_vectors[]={
22 #if defined(CONFIG_GDB_DEBUG)
23         TRACE_VEC,
24         TRAP3_VEC,
25 #endif
26         -1
27 };
28
29 /* trap entry table */
30 const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
31         0,0,0,0,0,
32         (unsigned long)trace_break,  /* TRACE */
33         0,0,
34         (unsigned long)system_call,  /* TRAPA #0 */
35         0,0,0,0,0,0,0
36 };
37
38 /* IRQ pin assignment */
39 struct irq_pins {
40         unsigned char port_no;
41         unsigned char bit_no;
42 } __attribute__((aligned(1),packed));
43 /* ISTR = 0 */
44 static const struct irq_pins irq_assign_table0[16]={
45         {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
46         {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
47         {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
48         {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
49         {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
50         {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
51         {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
52         {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
53 }; 
54 /* ISTR = 1 */
55 static const struct irq_pins irq_assign_table1[16]={
56         {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
57         {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
58         {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
59         {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
60         {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
61         {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
62         {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
63         {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
64 };
65
66 /* IRQ to GPIO pinno transrate */
67 #define IRQ_GPIO_MAP(irqbit,irq,port,bit)                         \
68 do {                                                              \
69         if (*(volatile unsigned short *)ITSR & irqbit) {          \
70                 port = irq_assign_table1[irq - EXT_IRQ0].port_no; \
71                 bit  = irq_assign_table1[irq - EXT_IRQ0].bit_no;  \
72         } else {                                                  \
73                 port = irq_assign_table0[irq - EXT_IRQ0].port_no; \
74                 bit  = irq_assign_table0[irq - EXT_IRQ0].bit_no;  \
75         }                                                         \
76 } while(0)
77
78 int h8300_enable_irq_pin(unsigned int irq)
79 {
80         if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
81                 unsigned short ptn = 1 << (irq - EXT_IRQ0);
82                 unsigned int port_no,bit_no;
83                 IRQ_GPIO_MAP(ptn, irq, port_no, bit_no);
84                 if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
85                         return -EBUSY;                   /* pin already use */
86                 H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
87                 *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
88         }
89
90         return 0;
91 }
92
93 void h8300_disable_irq_pin(unsigned int irq)
94 {
95         if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
96                 /* disable interrupt & release IRQ pin */
97                 unsigned short ptn = 1 << (irq - EXT_IRQ0);
98                 unsigned short port_no,bit_no;
99                 *(volatile unsigned short *)ISR &= ~ptn;
100                 *(volatile unsigned short *)IER &= ~ptn;
101                 IRQ_GPIO_MAP(ptn, irq, port_no, bit_no);
102                 H8300_GPIO_FREE(port_no, bit_no);
103         }
104 }