diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-22 23:49:01 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-22 23:49:01 +0000 |
commit | d221c44b7afefd8f77f8595af468dfacb3b21cc2 (patch) | |
tree | ef1c7aa4fe157c9f63be777cc6809f292da1f5d5 /arch/alpha/kernel/sys_takara.c | |
parent | 51d3b7814cdccef9188240fe0cbd8d97ff2c7470 (diff) |
Merge with Linux 2.3.8.
Diffstat (limited to 'arch/alpha/kernel/sys_takara.c')
-rw-r--r-- | arch/alpha/kernel/sys_takara.c | 90 |
1 files changed, 70 insertions, 20 deletions
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 95adc3b39..c554a9fa1 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -3,7 +3,7 @@ * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996 Jay A Estabrook - * Copyright (C) 1998 Richard Henderson + * Copyright (C) 1998, 1999 Richard Henderson * * Code supporting the TAKARA. */ @@ -30,11 +30,21 @@ #include "machvec.h" -/* - * WARNING WARNING WARNING - * - * This port is missing an update_irq_hw implementation. - */ +static void +takara_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) +{ + unsigned int regaddr; + + if (irq <= 15) { + if (irq <= 7) + outb(mask, 0x21); /* ISA PIC1 */ + else + outb(mask >> 8, 0xA1); /* ISA PIC2 */ + } else if (irq <= 31) { + regaddr = 0x510 + ((irq - 16) & 0x0c); + outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr); + } +} static void takara_device_interrupt(unsigned long vector, struct pt_regs *regs) @@ -68,28 +78,45 @@ takara_device_interrupt(unsigned long vector, struct pt_regs *regs) if (intstatus & 4) handle_irq(16+2, 16+2, regs); if (intstatus & 2) handle_irq(16+1, 16+1, regs); if (intstatus & 1) handle_irq(16+0, 16+0, regs); - } else + } else { isa_device_interrupt (vector, regs); + } +} + +static void +takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + int irq = (vector - 0x800) >> 4; + + if (irq > 15) + irq = ((vector - 0x800) >> 6) + 12; + + handle_irq(irq, irq, regs); } static void __init takara_init_irq(void) { - unsigned int ctlreg; - STANDARD_INIT_IRQ_PROLOG; - ctlreg = inl(0x500); - ctlreg &= ~0x8000; /* return to non-accelerated mode */ - outw(ctlreg >> 16, 0x502); - outw(ctlreg & 0xFFFF, 0x500); - ctlreg = 0x05107c00; /* enable the PCI interrupt register */ - outw(ctlreg >> 16, 0x502); - outw(ctlreg & 0xFFFF, 0x500); + if (alpha_using_srm) + alpha_mv.device_interrupt = takara_srm_device_interrupt; + + if (!alpha_using_srm) { + unsigned int ctlreg = inl(0x500); + + /* Return to non-accelerated mode. */ + ctlreg &= ~0x8000; + outl(ctlreg, 0x500); + + /* Enable the PCI interrupt register. */ + ctlreg = 0x05107c00; + outl(ctlreg, 0x500); + } + enable_irq(2); } - /* * The Takara has PCI devices 1, 2, and 3 configured to slots 20, * 19, and 18 respectively, in the default configuration. They can @@ -123,12 +150,35 @@ takara_map_irq(struct pci_dev *dev, int slot, int pin) return COMMON_TABLE_LOOKUP; } +static int __init +takara_swizzle(struct pci_dev *dev, int *pinp) +{ + int slot = PCI_SLOT(dev->devfn); + int pin = *pinp; + unsigned int ctlreg = inl(0x500); + unsigned int busslot = PCI_SLOT(dev->bus->self->devfn); + + /* Check first for built-in bridges. */ + if (busslot > 16 && ((1<<(36-busslot)) & ctlreg)) { + if (pin == 1) + pin += (20 - busslot); + else { + /* Must be a card-based bridge. */ + printk(KERN_WARNING "takara_swizzle: cannot handle " + "card-bridge behind builtin bridge yet.\n"); + } + } + + *pinp = pin; + return slot; +} + static void __init takara_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); - common_pci_fixup(takara_map_irq, common_swizzle); - enable_ide(0x26e); + common_pci_fixup(takara_map_irq, takara_swizzle); + /* enable_ide(0x26e); */ } @@ -147,7 +197,7 @@ struct alpha_machine_vector takara_mv __initmv = { nr_irqs: 20, irq_probe_mask: _PROBE_MASK(20), - update_irq_hw: NULL, + update_irq_hw: takara_update_irq_hw, ack_irq: generic_ack_irq, device_interrupt: takara_device_interrupt, |