blob: ade3038768411b32bf0c8af8a5fc081b76eaf489 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* -------------------------------------------------------------------- */
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*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/interrupt.h>
21#include <linux/init.h>
Paul Mundt082c44d2006-10-19 16:16:18 +090022#include <linux/io.h>
Paul Mundtadf18902006-09-27 17:17:27 +090023#include <asm/voyagergx.h>
Paul Mundt082c44d2006-10-19 16:16:18 +090024#include <asm/rts7751r2d.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
Magnus Damm48180ca2007-08-03 14:27:20 +090026enum {
27 UNUSED = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Magnus Damm48180ca2007-08-03 14:27:20 +090029 /* 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,
Linus Torvalds1da177e2005-04-16 15:20:36 -070034};
35
Magnus Damm5c37e022007-08-17 00:45:35 +090036static struct intc_vect vectors[] __initdata = {
Magnus Damm48180ca2007-08-03 14:27:20 +090037 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};
51
Magnus Damm5c37e022007-08-17 00:45:35 +090052static struct intc_mask_reg mask_registers[] __initdata = {
Magnus Damm73505b42007-08-12 15:26:12 +090053 { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */
Magnus Damm48180ca2007-08-03 14:27:20 +090054 { 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};
59
60static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors,
61 NULL, NULL, mask_registers, NULL, NULL);
62
63static 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};
73
74static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -070075{
Magnus Damm48180ca2007-08-03 14:27:20 +090076 unsigned long intv = ctrl_inl(INT_STATUS);
77 struct irq_desc *ext_desc;
78 unsigned int ext_irq;
79 unsigned int k = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
Magnus Damm48180ca2007-08-03 14:27:20 +090081 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 }
Magnus Damm48180ca2007-08-03 14:27:20 +090087 intv >>= 1;
88 k++;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070090}
91
Linus Torvalds1da177e2005-04-16 15:20:36 -070092void __init setup_voyagergx_irq(void)
93{
Magnus Damm48180ca2007-08-03 14:27:20 +090094 printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 IRQ_VOYAGER,
96 VOYAGER_IRQ_BASE,
97 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1);
98
Magnus Damm48180ca2007-08-03 14:27:20 +090099 register_intc_controller(&intc_desc);
100 set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101}