Merge ../linux-2.6-watchdog-mm
[sfrench/cifs-2.6.git] / arch / sh / boards / renesas / rts7751r2d / irq.c
1 /*
2  * linux/arch/sh/boards/renesas/rts7751r2d/irq.c
3  *
4  * Copyright (C) 2000  Kazumoto Kojima
5  *
6  * Renesas Technology Sales RTS7751R2D Support.
7  *
8  * Modified for RTS7751R2D by
9  * Atom Create Engineering Co., Ltd. 2002.
10  */
11 #include <linux/init.h>
12 #include <linux/irq.h>
13 #include <linux/io.h>
14 #include <asm/rts7751r2d.h>
15
16 #if defined(CONFIG_RTS7751R2D_REV11)
17 static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
18 #else
19 static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0};
20 #endif
21
22 extern int voyagergx_irq_demux(int irq);
23 extern void setup_voyagergx_irq(void);
24
25 static void enable_rts7751r2d_irq(unsigned int irq);
26 static void disable_rts7751r2d_irq(unsigned int irq);
27
28 /* shutdown is same as "disable" */
29 #define shutdown_rts7751r2d_irq disable_rts7751r2d_irq
30
31 static void ack_rts7751r2d_irq(unsigned int irq);
32 static void end_rts7751r2d_irq(unsigned int irq);
33
34 static unsigned int startup_rts7751r2d_irq(unsigned int irq)
35 {
36         enable_rts7751r2d_irq(irq);
37         return 0; /* never anything pending */
38 }
39
40 static void disable_rts7751r2d_irq(unsigned int irq)
41 {
42         unsigned short val;
43         unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
44
45         /* Set the priority in IPR to 0 */
46         val = ctrl_inw(IRLCNTR1);
47         val &= mask;
48         ctrl_outw(val, IRLCNTR1);
49 }
50
51 static void enable_rts7751r2d_irq(unsigned int irq)
52 {
53         unsigned short val;
54         unsigned short value = (0x0001 << mask_pos[irq]);
55
56         /* Set priority in IPR back to original value */
57         val = ctrl_inw(IRLCNTR1);
58         val |= value;
59         ctrl_outw(val, IRLCNTR1);
60 }
61
62 int rts7751r2d_irq_demux(int irq)
63 {
64         int demux_irq;
65
66         demux_irq = voyagergx_irq_demux(irq);
67         return demux_irq;
68 }
69
70 static void ack_rts7751r2d_irq(unsigned int irq)
71 {
72         disable_rts7751r2d_irq(irq);
73 }
74
75 static void end_rts7751r2d_irq(unsigned int irq)
76 {
77         if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
78                 enable_rts7751r2d_irq(irq);
79 }
80
81 static struct hw_interrupt_type rts7751r2d_irq_type = {
82         .typename = "RTS7751R2D IRQ",
83         .startup = startup_rts7751r2d_irq,
84         .shutdown = shutdown_rts7751r2d_irq,
85         .enable = enable_rts7751r2d_irq,
86         .disable = disable_rts7751r2d_irq,
87         .ack = ack_rts7751r2d_irq,
88         .end = end_rts7751r2d_irq,
89 };
90
91 static void make_rts7751r2d_irq(unsigned int irq)
92 {
93         disable_irq_nosync(irq);
94         irq_desc[irq].chip = &rts7751r2d_irq_type;
95         disable_rts7751r2d_irq(irq);
96 }
97
98 /*
99  * Initialize IRQ setting
100  */
101 void __init init_rts7751r2d_IRQ(void)
102 {
103         int i;
104
105         /* IRL0=KEY Input
106          * IRL1=Ethernet
107          * IRL2=CF Card
108          * IRL3=CF Card Insert
109          * IRL4=PCMCIA
110          * IRL5=VOYAGER
111          * IRL6=RTC Alarm
112          * IRL7=RTC Timer
113          * IRL8=SD Card
114          * IRL9=PCI Slot #1
115          * IRL10=PCI Slot #2
116          * IRL11=Extention #0
117          * IRL12=Extention #1
118          * IRL13=Extention #2
119          * IRL14=Extention #3
120          */
121
122         for (i=0; i<15; i++)
123                 make_rts7751r2d_irq(i);
124
125         setup_voyagergx_irq();
126 }