[MIPS] signals: Share even more code.
[linux-2.6] / arch / mips / pci / fixup-vr4133.c
1 /*
2  * arch/mips/pci/fixup-vr4133.c
3  *
4  * The NEC CMB-VR4133 Board specific PCI fixups.
5  *
6  * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
7  *         Alex Sapkov <asapkov@ru.mvista.com>
8  *
9  * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
10  * the terms of the GNU General Public License version 2. This program
11  * is licensed "as is" without any warranty of any kind, whether express
12  * or implied.
13  *
14  * Modified for support in 2.6
15  * Author: Manish Lachwani (mlachwani@mvista.com)
16  *
17  */
18 #include <linux/init.h>
19 #include <linux/pci.h>
20 #include <linux/kernel.h>
21
22 #include <asm/io.h>
23 #include <asm/i8259.h>
24 #include <asm/vr41xx/cmbvr4133.h>
25
26 extern int vr4133_rockhopper;
27 extern void ali_m1535plus_init(struct pci_dev *dev);
28 extern void ali_m5229_init(struct pci_dev *dev);
29
30 /* Do platform specific device initialization at pci_enable_device() time */
31 int pcibios_plat_dev_init(struct pci_dev *dev)
32 {
33         /*
34          * We have to reset AMD PCnet adapter on Rockhopper since
35          * PMON leaves it enabled and generating interrupts. This leads
36          * to a lock if some PCI device driver later enables the IRQ line
37          * shared with PCnet and there is no AMD PCnet driver to catch its
38          * interrupts.
39          */
40 #ifdef CONFIG_ROCKHOPPER
41         if (dev->vendor == PCI_VENDOR_ID_AMD &&
42                 dev->device == PCI_DEVICE_ID_AMD_LANCE) {
43                 inl(pci_resource_start(dev, 0) + 0x18);
44         }
45 #endif
46
47         /*
48          * we have to open the bridges' windows down to 0 because otherwise
49          * we cannot access ISA south bridge I/O registers that get mapped from
50          * 0. for example, 8259 PIC would be unaccessible without that
51          */
52         if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
53                 pci_write_config_byte(dev, PCI_IO_BASE, 0);
54                 if(dev->bus->number == 0) {
55                         pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
56                 } else {
57                         pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
58                 }
59         }
60
61         return 0;
62 }
63
64 /*
65  * M1535 IRQ mapping
66  * Feel free to change this, although it shouldn't be needed
67  */
68 #define M1535_IRQ_INTA  7
69 #define M1535_IRQ_INTB  9
70 #define M1535_IRQ_INTC  10
71 #define M1535_IRQ_INTD  11
72
73 #define M1535_IRQ_USB   9
74 #define M1535_IRQ_IDE   14
75 #define M1535_IRQ_IDE2  15
76 #define M1535_IRQ_PS2   12
77 #define M1535_IRQ_RTC   8
78 #define M1535_IRQ_FDC   6
79 #define M1535_IRQ_AUDIO 5
80 #define M1535_IRQ_COM1  4
81 #define M1535_IRQ_COM2  4
82 #define M1535_IRQ_IRDA  3
83 #define M1535_IRQ_KBD   1
84 #define M1535_IRQ_TMR   0
85
86 /* Rockhopper "slots" assignment; this is hard-coded ... */
87 #define ROCKHOPPER_M5451_SLOT  1
88 #define ROCKHOPPER_M1535_SLOT  2
89 #define ROCKHOPPER_M5229_SLOT  11
90 #define ROCKHOPPER_M5237_SLOT  15
91 #define ROCKHOPPER_PMU_SLOT    12
92 /* ... and hard-wired. */
93 #define ROCKHOPPER_PCI1_SLOT   3
94 #define ROCKHOPPER_PCI2_SLOT   4
95 #define ROCKHOPPER_PCI3_SLOT   5
96 #define ROCKHOPPER_PCI4_SLOT   6
97 #define ROCKHOPPER_PCNET_SLOT  1
98
99 #define M1535_IRQ_MASK(n) (1 << (n))
100
101 #define M1535_IRQ_EDGE  (M1535_IRQ_MASK(M1535_IRQ_TMR)  | \
102                          M1535_IRQ_MASK(M1535_IRQ_KBD)  | \
103                          M1535_IRQ_MASK(M1535_IRQ_COM1) | \
104                          M1535_IRQ_MASK(M1535_IRQ_COM2) | \
105                          M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
106                          M1535_IRQ_MASK(M1535_IRQ_RTC)  | \
107                          M1535_IRQ_MASK(M1535_IRQ_FDC)  | \
108                          M1535_IRQ_MASK(M1535_IRQ_PS2))
109
110 #define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE)  | \
111                          M1535_IRQ_MASK(M1535_IRQ_USB)  | \
112                          M1535_IRQ_MASK(M1535_IRQ_INTA) | \
113                          M1535_IRQ_MASK(M1535_IRQ_INTB) | \
114                          M1535_IRQ_MASK(M1535_IRQ_INTC) | \
115                          M1535_IRQ_MASK(M1535_IRQ_INTD))
116
117 struct irq_map_entry {
118         u16 bus;
119         u8 slot;
120         u8 irq;
121 };
122 static struct irq_map_entry int_map[] = {
123         {1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO},    /* Audio controller */
124         {1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD},      /* PCI slot #1 */
125         {1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC},      /* PCI slot #2 */
126         {1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB},      /* USB host controller */
127         {1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ},    /* IDE controller */
128         {2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD},     /* AMD Am79c973 on-board
129                                                            ethernet */
130         {2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB},      /* PCI slot #3 */
131         {2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC}       /* PCI slot #4 */
132 };
133
134 static int pci_intlines[] =
135     { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };
136
137 /* Determine the Rockhopper IRQ line number for the PCI device */
138 int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
139 {
140         struct pci_bus *bus;
141         int i;
142
143         bus = dev->bus;
144         if (bus == NULL)
145                 return -1;
146
147         for (i = 0; i < ARRAY_SIZE(int_map); i++) {
148                 if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
149                         int line;
150                         for (line = 0; line < 4; line++)
151                                 if (pci_intlines[line] == int_map[i].irq)
152                                         break;
153                         if (line < 4)
154                                 return pci_intlines[(line + (pin - 1)) % 4];
155                         else
156                                 return int_map[i].irq;
157                 }
158         }
159         return -1;
160 }
161
162 #ifdef CONFIG_ROCKHOPPER
163 void i8259_init(void)
164 {
165         init_i8259_irqs();
166
167         outb(0x00, 0x4d0);
168         outb(0x02, 0x4d1);      /* USB IRQ9 is level */
169 }
170 #endif
171
172 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
173 {
174         extern int pci_probe_only;
175         pci_probe_only = 1;
176
177 #ifdef CONFIG_ROCKHOPPER
178         if( dev->bus->number == 1 && vr4133_rockhopper )  {
179                 if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
180                         dev->irq = CMBVR41XX_INTA_IRQ;
181                 else
182                         dev->irq = rockhopper_get_irq(dev, pin, slot);
183         } else
184                 dev->irq = CMBVR41XX_INTA_IRQ;
185 #else
186         dev->irq = CMBVR41XX_INTA_IRQ;
187 #endif
188
189         return dev->irq;
190 }
191
192 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
193 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);
194
195