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, 1999 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>
29 #include <asm/hw_irq.h>
31 #include "machvec_impl.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 */
50 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
)
111 pld
&= 0x00000000ffffffffUL
;
114 * Now for every possible bit set, work through them and call
115 * the appropriate interrupt handler.
119 pld
&= pld
- 1; /* clear least bit set */
121 rx164_isa_device_interrupt(vector
, regs
);
123 handle_irq(16+i
, 16+i
, regs
);
133 STANDARD_INIT_IRQ_PROLOG
;
135 pcibios_write_config_dword(0, 0, 0x74, (~alpha_irq_mask
>> 16));
136 pcibios_read_config_dword(0, 0, 0x74, &temp
);
138 enable_irq(16 + 20); /* enable ISA interrupts */
139 enable_irq(2); /* enable cascade */
143 /* The RX164 changed its interrupt routing between pass1 and pass2...
147 * Slot IDSEL INTA INTB INTC INTD
155 * Slot IDSEL INTA INTB INTC INTD
166 * 5 32 bit PCI option slot 0
167 * 6 64 bit PCI option slot 1
169 * 7 64 bit PCI option slot 2
170 * 9 32 bit PCI option slot 3
176 rx164_map_irq(struct pci_dev
*dev
, u8 slot
, u8 pin
)
179 char irq_tab_pass1
[6][5] = {
180 /*INT INTA INTB INTC INTD */
181 { 16+3, 16+3, 16+8, 16+13, 16+18}, /* IdSel 5, slot 2 */
182 { 16+5, 16+5, 16+10, 16+15, 16+20}, /* IdSel 6, slot 0 */
183 { 16+4, 16+4, 16+9, 16+14, 16+19}, /* IdSel 7, slot 1 */
184 { -1, -1, -1, -1, -1}, /* IdSel 8, PCI/ISA bridge */
185 { 16+2, 16+2, 16+7, 16+12, 16+17}, /* IdSel 9, slot 3 */
186 { 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */
189 char irq_tab
[6][5] = {
190 /*INT INTA INTB INTC INTD */
191 { 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */
192 { 16+1, 16+1, 16+7, 16+12, 16+17}, /* IdSel 6, slot 1 */
193 { -1, -1, -1, -1, -1}, /* IdSel 7, PCI/ISA bridge */
194 { 16+2, 16+2, 16+8, 16+13, 16+18}, /* IdSel 8, slot 2 */
195 { 16+3, 16+3, 16+9, 16+14, 16+19}, /* IdSel 9, slot 3 */
196 { 16+4, 16+4, 16+10, 16+15, 16+5}, /* IdSel 10, PCI-PCI */
199 const long min_idsel
= 5, max_idsel
= 10, irqs_per_slot
= 5;
201 /* JRP - Need to figure out how to distinguish pass1 from pass2,
202 and use the correct table. */
203 return COMMON_TABLE_LOOKUP
;
211 struct alpha_machine_vector rx164_mv __initmv
= {
212 vector_name
: "RX164",
217 machine_check
: polaris_machine_check
,
218 max_dma_address
: ALPHA_MAX_DMA_ADDRESS
,
219 min_io_address
: DEFAULT_IO_BASE
,
220 min_mem_address
: DEFAULT_MEM_BASE
,
223 irq_probe_mask
: _PROBE_MASK(40),
224 update_irq_hw
: rx164_update_irq_hw
,
225 ack_irq
: common_ack_irq
,
226 device_interrupt
: rx164_device_interrupt
,
228 init_arch
: polaris_init_arch
,
229 init_irq
: rx164_init_irq
,
230 init_pit
: common_init_pit
,
231 init_pci
: common_init_pci
,
233 pci_map_irq
: rx164_map_irq
,
234 pci_swizzle
: common_swizzle
,