2 * linux/arch/alpha/kernel/sys_rx164.c
4 * Copyright (C) 1995 David A Rusling
5 * Copyright (C) 1996 Jay A Estabrook
6 * Copyright (C) 1998 Richard Henderson
8 * Code supporting the RX164 (PCA56+POLARIS).
11 #include <linux/kernel.h>
12 #include <linux/types.h>
14 #include <linux/sched.h>
15 #include <linux/pci.h>
16 #include <linux/init.h>
18 #include <asm/ptrace.h>
19 #include <asm/system.h>
22 #include <asm/bitops.h>
23 #include <asm/mmu_context.h>
25 #include <asm/pgtable.h>
26 #include <asm/core_polaris.h>
35 rx164_update_irq_hw(unsigned long irq
, unsigned long mask
, int unmask_p
)
39 pcibios_write_config_dword(0, 0, 0x74, ~mask
>> 16);
40 pcibios_read_config_dword(0, 0, 0x74, &temp
);
43 outb(mask
>> 8, 0xA1); /* ISA PIC2 */
45 outb(mask
, 0x21); /* ISA PIC1 */
49 rx164_srm_update_irq_hw(unsigned long irq
, unsigned long mask
, int unmask_p
)
59 outb(mask
>> 8, 0xA1); /* ISA PIC2 */
61 outb(mask
, 0x21); /* ISA PIC1 */
66 rx164_isa_device_interrupt(unsigned long vector
, struct pt_regs
* regs
)
71 * It seems to me that the probability of two or more *device*
72 * interrupts occurring at almost exactly the same time is
73 * pretty low. So why pay the price of checking for
74 * additional interrupts here if the common case can be
75 * handled so much easier?
78 * The first read of the PIC gives you *all* interrupting lines.
79 * Therefore, read the mask register and and out those lines
80 * not enabled. Note that some documentation has 21 and a1
81 * write only. This is not true.
83 pic
= inb(0x20) | (inb(0xA0) << 8); /* read isr */
84 pic
&= ~alpha_irq_mask
; /* apply mask */
85 pic
&= 0xFFFB; /* mask out cascade & hibits */
90 handle_irq(j
, j
, regs
);
95 rx164_device_interrupt(unsigned long vector
, struct pt_regs
*regs
)
100 /* Read the interrupt summary register. On Polaris,
101 * this is the DIRR register in PCI config space (offset 0x84)
104 pcibios_read_config_dword(0, 0, 0x84, (unsigned int *)&pld
);
107 printk("PLD 0x%lx\n", pld
);
110 if (pld
& 0xffffffff00000000UL
) pld
&= 0x00000000ffffffffUL
;
113 * Now for every possible bit set, work through them and call
114 * the appropriate interrupt handler.
118 pld
&= pld
- 1; /* clear least bit set */
120 rx164_isa_device_interrupt(vector
, regs
);
122 handle_irq(16+i
, 16+i
, regs
);
132 STANDARD_INIT_IRQ_PROLOG
;
134 pcibios_write_config_dword(0, 0, 0x74, (~alpha_irq_mask
>> 16));
135 pcibios_read_config_dword(0, 0, 0x74, &temp
);
137 enable_irq(16 + 20); /* enable ISA interrupts */
138 enable_irq(2); /* enable cascade */
140 /* The RX164 changed its interrupt routing between pass1 and pass2...
144 * Slot IDSEL INTA INTB INTC INTD
152 * Slot IDSEL INTA INTB INTC INTD
163 * 5 32 bit PCI option slot 0
164 * 6 64 bit PCI option slot 1
166 * 7 64 bit PCI option slot 2
167 * 9 32 bit PCI option slot 3
173 rx164_map_irq(struct pci_dev
*dev
, int slot
, int pin
)
176 char irq_tab_pass1
[6][5] = {
177 /*INT INTA INTB INTC INTD */
178 { 16+3, 16+3, 16+8, 16+13, 16+18}, /* IdSel 5, slot 2 */
179 { 16+5, 16+5, 16+10, 16+15, 16+20}, /* IdSel 6, slot 0 */
180 { 16+4, 16+4, 16+9, 16+14, 16+19}, /* IdSel 7, slot 1 */
181 { -1, -1, -1, -1, -1}, /* IdSel 8, PCI/ISA bridge */
182 { 16+2, 16+2, 16+7, 16+12, 16+17}, /* IdSel 9, slot 3 */
183 { 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */
186 char irq_tab
[6][5] = {
187 /*INT INTA INTB INTC INTD */
188 { 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */
189 { 16+1, 16+1, 16+7, 16+12, 16+17}, /* IdSel 6, slot 1 */
190 { -1, -1, -1, -1, -1}, /* IdSel 7, PCI/ISA bridge */
191 { 16+2, 16+2, 16+8, 16+13, 16+18}, /* IdSel 8, slot 2 */
192 { 16+3, 16+3, 16+9, 16+14, 16+19}, /* IdSel 9, slot 3 */
193 { 16+4, 16+4, 16+10, 16+15, 16+5}, /* IdSel 10, PCI-PCI */
195 const long min_idsel
= 5, max_idsel
= 10, irqs_per_slot
= 5;
196 /* JRP - Need to figure out how to distinguish pass1 from pass2,
197 * and use the correct table...
199 return COMMON_TABLE_LOOKUP
;
203 rx164_pci_fixup(void)
205 layout_all_busses(DEFAULT_IO_BASE
, DEFAULT_MEM_BASE
);
206 common_pci_fixup(rx164_map_irq
, common_swizzle
);
214 struct alpha_machine_vector rx164_mv __initmv
= {
215 vector_name
: "RX164",
220 machine_check
: polaris_machine_check
,
221 max_dma_address
: ALPHA_MAX_DMA_ADDRESS
,
224 irq_probe_mask
: _PROBE_MASK(40),
225 update_irq_hw
: rx164_update_irq_hw
,
226 ack_irq
: generic_ack_irq
,
227 device_interrupt
: rx164_device_interrupt
,
229 init_arch
: polaris_init_arch
,
230 init_irq
: rx164_init_irq
,
231 init_pit
: generic_init_pit
,
232 pci_fixup
: rx164_pci_fixup
,
233 kill_arch
: generic_kill_arch
,