diff --git a/arch/mips/pci/pci-bridge.c b/arch/mips/pci/pci-bridge.c index a64ab146f30c..78524134d752 100644 --- a/arch/mips/pci/pci-bridge.c +++ b/arch/mips/pci/pci-bridge.c @@ -277,6 +277,17 @@ bridge_disable_swapping_dma(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, bridge_disable_swapping_dma); +#if 0 +/* + * XXX: Onyx2 systems have a RAD1 on their IO6-G board, but the RAD1 driver + * and corresponding defines are part of the IP30 patchset, so we need to + * make this part conditional for now until the IP30 patches are merged + * upstream. + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_RAD1, + bridge_disable_swapping_dma); +#endif + /* XXX: Temporarily defined here until the IP27 "mega update". */ #ifdef CONFIG_NUMA /** diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c index cd449e90b917..cbd75c08a38a 100644 --- a/arch/mips/sgi-ip27/ip27-irq-pci.c +++ b/arch/mips/sgi-ip27/ip27-irq-pci.c @@ -135,45 +135,56 @@ static int intr_disconnect_level(int cpu, int bit) /* Startup one of the (PCI ...) IRQs routes over a bridge. */ static unsigned int startup_bridge_irq(struct irq_data *d) { + u32 slot, reg; struct bridge_controller *bc; - bridgereg_t device; - bridge_t *bridge; - int pin, swlevel; + int swlevel; cpuid_t cpu; - pin = SLOT_FROM_PCI_IRQ(d->irq); + slot = SLOT_FROM_PCI_IRQ(d->irq); bc = IRQ_TO_BRIDGE(d->irq); - bridge = bc->base; - pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); + pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, slot); /* * "map" irq to a swlevel greater than 6 since the first 6 bits * of INT_PEND0 are taken */ swlevel = find_level(&cpu, d->irq); - bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); - bridge->b_int_enable |= (1 << pin); - bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ /* - * Enable sending of an interrupt clear packt to the hub on a high to - * low transition of the interrupt pin. + * Handle BRIDGE IRQs. * - * IRIX sets additional bits in the address which are documented as - * reserved in the bridge docs. - */ - bridge->b_int_mode |= (1UL << pin); - - /* - * We assume the bridge to have a 1:1 mapping between devices - * (slots) and intr pins. + * b_int_addr(slot) - Points to the HUB that this BRIDGE + * is assigned to, so that BRIDGE can frob the PI_INT_PEND_MOD + * register directly, without having to know which nasid the + * specific HUB is on. + * + * b_int_mode - Enable the sending of an interrupt clear + * packet to the HUB on a high-to-low transition of the + * interrupt pin. + * + * b_int_device - We assume the bridge to have a 1:1 mapping + * between devices (slots) and interrupt numbers. + * + * XXX: Replace the magic values with readable macros at some point. */ - device = bridge->b_int_device; - device &= ~(7 << (pin*3)); - device |= (pin << (pin*3)); - bridge->b_int_device = device; - - bridge->b_wid_tflush; + /* b_int_addr */ + bridge_write_reg((0x20000 | swlevel | (bc->nasid << 8)), bc, + b_int_addr(slot)); + /* b_int_enable */ + reg = bridge_read_reg(bc, b_int_enable); + bridge_write_reg((reg | BIT(slot) | 0x7ffffe00), bc, b_int_enable); + + /* b_int_mode */ + reg = bridge_read_reg(bc, b_int_mode); + bridge_write_reg((reg | BIT(slot)), bc, b_int_mode); + + /* b_int_device */ + reg = bridge_read_reg(bc, b_int_device); + reg &= ~BRIDGE_INT_DEV_MASK(slot); + reg |= BRIDGE_INT_DEV_SET(slot, slot); + bridge_write_reg(reg, bc, b_int_device); + /* flush */ + BRIDGE_FLUSH(bc); intr_connect_level(cpu, swlevel); @@ -183,13 +194,13 @@ static unsigned int startup_bridge_irq(struct irq_data *d) /* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ static void shutdown_bridge_irq(struct irq_data *d) { + u32 slot, reg; struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); - bridge_t *bridge = bc->base; - int pin, swlevel; + int swlevel; cpuid_t cpu; pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); - pin = SLOT_FROM_PCI_IRQ(d->irq); + slot = SLOT_FROM_PCI_IRQ(d->irq); /* * map irq to a swlevel greater than 6 since the first 6 bits @@ -198,8 +209,9 @@ static void shutdown_bridge_irq(struct irq_data *d) swlevel = find_level(&cpu, d->irq); intr_disconnect_level(cpu, swlevel); - bridge->b_int_enable &= ~(1 << pin); - bridge->b_wid_tflush; + reg = bridge_read_reg(bc, b_int_enable); + bridge_write_reg((reg & ~(BIT(slot))), bc, b_int_enable); + BRIDGE_FLUSH(bc); } static inline void enable_bridge_irq(struct irq_data *d) diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0dde6164a06f..23b4cd72de3e 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -36,6 +36,11 @@ #include #include +/* XXX: Part of the IP27 "mega update" */ +#include +struct bridge_controller *irq_to_bridge[PCIBR_MAX_BUS_X_DEV]; +u32 irq_to_slot[PCIBR_MAX_BUS_X_DEV]; + /* * Linux has a controller-independent x86 interrupt architecture. * every controller has a 'controller-template', that is used