Merge branch 'misc' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc...
[pandora-kernel.git] / arch / mips / ddb5xxx / ddb5476 / irq.c
1 /*
2  *  arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
3  *
4  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
5  *                     Sony Software Development Center Europe (SDCE), Brussels
6  *
7  * Re-write the whole thing to use new irq.c file.
8  * Copyright (C) 2001 MontaVista Software Inc.
9  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
10  *
11  */
12 #include <linux/init.h>
13 #include <linux/sched.h>
14 #include <linux/types.h>
15 #include <linux/interrupt.h>
16
17 #include <asm/i8259.h>
18 #include <asm/io.h>
19 #include <asm/ptrace.h>
20
21 #include <asm/ddb5xxx/ddb5xxx.h>
22
23 #define M1543_PNP_CONFIG        0x03f0  /* PnP Config Port */
24 #define M1543_PNP_INDEX         0x03f0  /* PnP Index Port */
25 #define M1543_PNP_DATA          0x03f1  /* PnP Data Port */
26
27 #define M1543_PNP_ALT_CONFIG    0x0370  /* Alternative PnP Config Port */
28 #define M1543_PNP_ALT_INDEX     0x0370  /* Alternative PnP Index Port */
29 #define M1543_PNP_ALT_DATA      0x0371  /* Alternative PnP Data Port */
30
31 #define M1543_INT1_MASTER_CTRL  0x0020  /* INT_1 (master) Control Register */
32 #define M1543_INT1_MASTER_MASK  0x0021  /* INT_1 (master) Mask Register */
33
34 #define M1543_INT1_SLAVE_CTRL   0x00a0  /* INT_1 (slave) Control Register */
35 #define M1543_INT1_SLAVE_MASK   0x00a1  /* INT_1 (slave) Mask Register */
36
37 #define M1543_INT1_MASTER_ELCR  0x04d0  /* INT_1 (master) Edge/Level Control */
38 #define M1543_INT1_SLAVE_ELCR   0x04d1  /* INT_1 (slave) Edge/Level Control */
39
40 static void m1543_irq_setup(void)
41 {
42         /*
43          *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
44          *  the possible IO sources in the M1543 are in use by us.  We will
45          *  use the following mapping:
46          *
47          *      IRQ1  - keyboard (default set by M1543)
48          *      IRQ3  - reserved for UART B (default set by M1543) (note that
49          *              the schematics for the DDB Vrc-5476 board seem to
50          *              indicate that IRQ3 is connected to the DS1386
51          *              watchdog timer interrupt output so we might have
52          *              a conflict)
53          *      IRQ4  - reserved for UART A (default set by M1543)
54          *      IRQ5  - parallel (default set by M1543)
55          *      IRQ8  - DS1386 time of day (RTC) interrupt
56          *      IRQ9  - USB (hardwired in ddb_setup)
57          *      IRQ10 - PMU (hardwired in ddb_setup)
58          *      IRQ12 - mouse
59          *      IRQ14,15 - IDE controller (need to be confirmed, jsun)
60          */
61
62         /*
63          *  Assing mouse interrupt to IRQ12
64          */
65
66         /* Enter configuration mode */
67         outb(0x51, M1543_PNP_CONFIG);
68         outb(0x23, M1543_PNP_CONFIG);
69
70         /* Select logical device 7 (Keyboard) */
71         outb(0x07, M1543_PNP_INDEX);
72         outb(0x07, M1543_PNP_DATA);
73
74         /* Select IRQ12 */
75         outb(0x72, M1543_PNP_INDEX);
76         outb(0x0c, M1543_PNP_DATA);
77
78         /* Leave configration mode */
79         outb(0xbb, M1543_PNP_CONFIG);
80 }
81
82 static void nile4_irq_setup(void)
83 {
84         int i;
85
86         /* Map all interrupts to CPU int #0 (IP2) */
87         nile4_map_irq_all(0);
88
89         /* PCI INTA#-E# must be level triggered */
90         nile4_set_pci_irq_level_or_edge(0, 1);
91         nile4_set_pci_irq_level_or_edge(1, 1);
92         nile4_set_pci_irq_level_or_edge(2, 1);
93         nile4_set_pci_irq_level_or_edge(3, 1);
94
95         /* PCI INTA#, B#, D# must be active low, INTC# must be active high */
96         nile4_set_pci_irq_polarity(0, 0);
97         nile4_set_pci_irq_polarity(1, 0);
98         nile4_set_pci_irq_polarity(2, 1);
99         nile4_set_pci_irq_polarity(3, 0);
100
101         for (i = 0; i < 16; i++)
102                 nile4_clear_irq(i);
103
104         /* Enable CPU int #0 */
105         nile4_enable_irq_output(0);
106
107         /* memory resource acquire in ddb_setup */
108 }
109
110 static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
111 static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
112
113 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
114 extern void mips_cpu_irq_init(u32 irq_base);
115 extern void vrc5476_irq_init(u32 irq_base);
116
117 extern void vrc5476_irq_dispatch(struct pt_regs *regs);
118
119 asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
120 {
121         unsigned int pending = read_c0_cause() & read_c0_status();
122
123         if (pending & STATUSF_IP7)
124                 do_IRQ(CPU_IRQ_BASE + 7, regs);
125         else if (pending & STATUSF_IP2)
126                 vrc5476_irq_dispatch(regs);
127         else if (pending & STATUSF_IP3)
128                 do_IRQ(CPU_IRQ_BASE + 3, regs);
129         else if (pending & STATUSF_IP4)
130                 do_IRQ(CPU_IRQ_BASE + 4, regs);
131         else if (pending & STATUSF_IP5)
132                 do_IRQ(CPU_IRQ_BASE + 5, regs);
133         else if (pending & STATUSF_IP6)
134                 do_IRQ(CPU_IRQ_BASE + 6, regs);
135         else if (pending & STATUSF_IP0)
136                 do_IRQ(CPU_IRQ_BASE, regs);
137         else if (pending & STATUSF_IP1)
138                 do_IRQ(CPU_IRQ_BASE + 1, regs);
139
140         vrc5476_irq_dispatch(regs);
141 }
142
143 void __init arch_init_irq(void)
144 {
145         /* hardware initialization */
146         nile4_irq_setup();
147         m1543_irq_setup();
148
149         /* controller setup */
150         init_i8259_irqs();
151         vrc5476_irq_init(VRC5476_IRQ_BASE);
152         mips_cpu_irq_init(CPU_IRQ_BASE);
153
154         /* setup cascade interrupts */
155         setup_irq(VRC5476_IRQ_BASE + VRC5476_I8259_CASCADE, &irq_cascade);
156         setup_irq(CPU_IRQ_BASE + CPU_VRC5476_CASCADE, &irq_cascade);
157
158         /* setup error interrupts for debugging */
159         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CPCE, &irq_error);
160         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CNTD, &irq_error);
161         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_MCE, &irq_error);
162         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
163         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
164         setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
165 }