11 #include <linux/kernel.h>
12 #include <linux/types.h>
14 #include <linux/sched.h>
15 #include <linux/pci.h>
18 #include <asm/ptrace.h>
21 #include <asm/mmu_context.h>
23 #include <asm/pgtable.h>
25 #include <asm/tlbflush.h>
34 static unsigned long cached_irq_mask[2] = { -1, -1 };
37 takara_update_irq_hw(
unsigned long irq,
unsigned long mask)
41 mask = (irq >= 64 ? mask << 16 : mask >> ((irq - 16) & 0x30));
42 regaddr = 0x510 + (((
irq - 16) >> 2) & 0x0c);
51 mask = (cached_irq_mask[irq >= 64] &= ~(1
UL << (irq & 63)));
52 takara_update_irq_hw(irq, mask);
60 mask = (cached_irq_mask[irq >= 64] |= 1
UL << (irq & 63));
61 takara_update_irq_hw(irq, mask);
64 static struct irq_chip takara_irq_type = {
66 .irq_unmask = takara_enable_irq,
67 .irq_mask = takara_disable_irq,
68 .irq_mask_ack = takara_disable_irq,
72 takara_device_interrupt(
unsigned long vector)
92 intstatus =
inw(0x500) & 15;
109 takara_srm_device_interrupt(
unsigned long vector)
111 int irq = (vector - 0x800) >> 4;
116 takara_init_irq(
void)
122 if (alpha_using_srm) {
123 alpha_mv.device_interrupt = takara_srm_device_interrupt;
125 unsigned int ctlreg =
inl(0x500);
136 for (i = 16; i < 128; i += 16)
137 takara_update_irq_hw(i, -1);
139 for (i = 16; i < 128; ++
i) {
140 irq_set_chip_and_handler(i, &takara_irq_type,
162 { 16+3, 16+3, 16+3, 16+3, 16+3},
163 { 16+2, 16+2, 16+2, 16+2, 16+2},
164 { 16+1, 16+1, 16+1, 16+1, 16+1},
165 { -1, -1, -1, -1, -1},
166 { -1, -1, -1, -1, -1},
167 { -1, -1, -1, -1, -1},
169 { 12, 12, 13, 14, 15},
173 { -1, -1, -1, -1, -1},
174 {64+ 0, 64+0, 64+1, 64+2, 64+3},
175 {48+ 0, 48+0, 48+1, 48+2, 48+3},
176 {32+ 0, 32+0, 32+1, 32+2, 32+3},
177 {16+ 0, 16+0, 16+1, 16+2, 16+3},
179 const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
181 if (irq >= 0 && irq < 16) {
183 unsigned int busslot =
PCI_SLOT(dev->
bus->self->devfn);
184 irq += irq_tab[busslot-min_idsel][0];
190 takara_map_irq(
const struct pci_dev *dev,
u8 slot,
u8 pin)
192 static char irq_tab[15][5] __initdata = {
193 { 16+3, 16+3, 16+3, 16+3, 16+3},
194 { 16+2, 16+2, 16+2, 16+2, 16+2},
195 { 16+1, 16+1, 16+1, 16+1, 16+1},
196 { -1, -1, -1, -1, -1},
197 { -1, -1, -1, -1, -1},
198 { -1, -1, -1, -1, -1},
199 { -1, -1, -1, -1, -1},
200 { -1, -1, -1, -1, -1},
201 { -1, -1, -1, -1, -1},
202 { -1, -1, -1, -1, -1},
203 { -1, -1, -1, -1, -1},
204 { -1, -1, -1, -1, -1},
205 { 16+3, 16+3, 16+3, 16+3, 16+3},
206 { 16+2, 16+2, 16+2, 16+2, 16+2},
207 { 16+1, 16+1, 16+1, 16+1, 16+1},
209 const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
214 takara_swizzle(
struct pci_dev *dev,
u8 *pinp)
218 unsigned int ctlreg =
inl(0x500);
219 unsigned int busslot;
226 if (dev->
bus->number != 0
228 && ((1<<(36-busslot)) & ctlreg)) {
230 pin += (20 - busslot);
233 "handle cards with INTA IRQ pin.\n");
238 "card-bridge behind builtin bridge yet.\n");
246 takara_init_pci(
void)
249 alpha_mv.pci_map_irq = takara_map_irq_srm;
268 .vector_name =
"Takara",
278 .device_interrupt = takara_device_interrupt,
281 .init_irq = takara_init_irq,
283 .init_pci = takara_init_pci,
285 .pci_map_irq = takara_map_irq,
286 .pci_swizzle = takara_swizzle,