[PATCH 11/12] MIPS: IP27: Update IRQ code to work with the new BRIDGE code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Joshua Kinard <kumba@xxxxxxxxxx>

Sparsely update just enough of the existing IP27 code so that the
machine will boot against the newer Xtalk/BRIDGE code.   A future
patch series will completely rewrite a majority of the existing IP27
code.

Signed-off-by: Joshua Kinard <kumba@xxxxxxxxxx>
---
 arch/mips/pci/pci-bridge.c        | 11 +++++
 arch/mips/sgi-ip27/ip27-irq-pci.c | 72 +++++++++++++++++------------
 arch/mips/sgi-ip27/ip27-irq.c     |  5 ++
 3 files changed, 58 insertions(+), 30 deletions(-)

diff --git a/arch/mips/pci/pci-bridge.c b/arch/mips/pci/pci-bridge.c
index 28b0eb5b844e..9df13ce313b5 100644
--- a/arch/mips/pci/pci-bridge.c
+++ b/arch/mips/pci/pci-bridge.c
@@ -274,6 +274,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 2a1c40784bd9..957b689b35f4 100644
--- a/arch/mips/sgi-ip27/ip27-irq-pci.c
+++ b/arch/mips/sgi-ip27/ip27-irq-pci.c
@@ -134,45 +134,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);
 
@@ -182,13 +193,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
@@ -197,8 +208,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 16ec4e12daa3..812b23c126ef 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -35,6 +35,11 @@
 #include <asm/sn/hub.h>
 #include <asm/sn/intr.h>
 
+/* XXX: Part of the IP27 "mega update" */
+#include <asm/mach-ip27/pcibr.h>
+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
-- 
2.11.1





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux