Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* -------------------------------------------------------------------- */ |
2 | /* setup_voyagergx.c: */ | |
3 | /* -------------------------------------------------------------------- */ | |
4 | /* This program is free software; you can redistribute it and/or modify | |
5 | it under the terms of the GNU General Public License as published by | |
6 | the Free Software Foundation; either version 2 of the License, or | |
7 | (at your option) any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
17 | ||
18 | Copyright 2003 (c) Lineo uSolutions,Inc. | |
19 | */ | |
1da177e4 LT |
20 | #include <linux/interrupt.h> |
21 | #include <linux/init.h> | |
082c44d2 | 22 | #include <linux/io.h> |
adf1890b | 23 | #include <asm/voyagergx.h> |
082c44d2 | 24 | #include <asm/rts7751r2d.h> |
1da177e4 | 25 | |
48180cab MD |
26 | enum { |
27 | UNUSED = 0, | |
28 | ||
29 | /* voyager specific interrupt sources */ | |
30 | UP, G54, G53, G52, G51, G50, G49, G48, | |
31 | I2C, PW, DMA, PCI, I2S, AC, US, | |
32 | U1, U0, CV, MC, S1, S0, | |
33 | UH, TWOD, ZD, PV, CI, | |
1da177e4 LT |
34 | }; |
35 | ||
5c37e025 | 36 | static struct intc_vect vectors[] __initdata = { |
48180cab MD |
37 | INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54), |
38 | INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52), | |
39 | INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50), | |
40 | INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48), | |
41 | INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW), | |
42 | INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI), | |
43 | INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC), | |
44 | INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1), | |
45 | INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV), | |
46 | INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1), | |
47 | INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH), | |
48 | INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD), | |
49 | INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI), | |
50 | }; | |
1da177e4 | 51 | |
5c37e025 | 52 | static struct intc_mask_reg mask_registers[] __initdata = { |
73505b44 | 53 | { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ |
48180cab MD |
54 | { UP, G54, G53, G52, G51, G50, G49, G48, |
55 | I2C, PW, 0, DMA, PCI, I2S, AC, US, | |
56 | 0, 0, U1, U0, CV, MC, S1, S0, | |
57 | 0, UH, 0, 0, TWOD, ZD, PV, CI } }, | |
58 | }; | |
1da177e4 | 59 | |
48180cab | 60 | static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors, |
7f3edee8 | 61 | NULL, mask_registers, NULL, NULL); |
48180cab MD |
62 | |
63 | static unsigned int voyagergx_stat2irq[32] = { | |
64 | IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D, | |
65 | 0, 0, IRQ_SM501_UH, 0, | |
66 | IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV, | |
67 | IRQ_SM501_U0, IRQ_SM501_U1, 0, 0, | |
68 | IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI, | |
69 | IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C, | |
70 | IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51, | |
71 | IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP | |
72 | }; | |
1da177e4 | 73 | |
48180cab | 74 | static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc) |
1da177e4 | 75 | { |
48180cab MD |
76 | unsigned long intv = ctrl_inl(INT_STATUS); |
77 | struct irq_desc *ext_desc; | |
78 | unsigned int ext_irq; | |
79 | unsigned int k = 0; | |
80 | ||
81 | while (intv) { | |
82 | ext_irq = voyagergx_stat2irq[k]; | |
83 | if (ext_irq && (intv & 1)) { | |
84 | ext_desc = irq_desc + ext_irq; | |
85 | handle_level_irq(ext_irq, ext_desc); | |
1da177e4 | 86 | } |
48180cab MD |
87 | intv >>= 1; |
88 | k++; | |
1da177e4 | 89 | } |
1da177e4 LT |
90 | } |
91 | ||
1da177e4 LT |
92 | void __init setup_voyagergx_irq(void) |
93 | { | |
48180cab | 94 | printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n", |
1da177e4 LT |
95 | IRQ_VOYAGER, |
96 | VOYAGER_IRQ_BASE, | |
97 | VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); | |
98 | ||
48180cab MD |
99 | register_intc_controller(&intc_desc); |
100 | set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux); | |
1da177e4 | 101 | } |