summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-05-15 23:50:59 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-05-15 23:50:59 +0000
commit04c69d60ac52d3bc4beed02e944c0036d9bb2b8a (patch)
treeb9a852f5a5959a71a7d8cc93f32dfb9f2babe8f3
parentc71b3ce4c33d1cdc0c03b4cb0dc977830536a905 (diff)
Move the intercpu intr irq numbers to the lowest possible. Assign
all PCI irqs above that. Fix pci_map_irq to not just have 2 bits for slot number, else irq numbers will not be unique. Include the bus number as part of the irq for now, so that scsi controllers on various PCI busses get unique irq numbers.
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c71
-rw-r--r--arch/mips64/sgi-ip27/ip27-pci.c42
-rw-r--r--include/asm-mips64/sn/sn0/ip27.h13
3 files changed, 57 insertions, 69 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 50feeed72..20dc3245d 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -81,9 +81,10 @@ unsigned long spurious_count = 0;
* use these macros to get the encoded nasid, widget id, and real irq
* from the irq value
*/
-#define NASID_FROM_IRQ(i) ((i >> 16)&(0xff))
-#define WID_FROM_IRQ(i) ((i >> 8)&(0xff))
-#define IRQ_FROM_IRQ(i) ((i)&(0xff))
+#define NASID_FROM_PCI_IRQ(i) (((i - BASE_PCI_IRQ) >> 16) & (0xff))
+#define WID_FROM_PCI_IRQ(i) (((i - BASE_PCI_IRQ) >> 8) & (0xff))
+#define SLOT_FROM_PCI_IRQ(i) ((i - BASE_PCI_IRQ) & 7)
+#define IRQ_FROM_IRQ(i) ((i) & (0xff))
void disable_irq(unsigned int irq_nr)
{
@@ -220,27 +221,15 @@ static unsigned int bridge_startup(unsigned int irq)
int pin, swlevel;
int real_irq = IRQ_FROM_IRQ(irq);
- DBG("bridge_startup(): irq= 0x%x real_irq= %d\n", irq, real_irq);
- bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_IRQ(irq), WID_FROM_IRQ(irq));
-
- /* FIIIIIXME ... Temporary kludge. This knows how interrupts are
- setup in _my_ Origin. */
-
- if (irq != real_irq) /* pci device interrupt */
- switch (real_irq) {
- case IRQ_FROM_IRQ(IOC3_ETH_INT): pin = 2; break;
- default: pin = real_irq; break;
- }
- else
- switch (real_irq) {
- case CPU_RESCHED_A_IRQ:
- case CPU_RESCHED_B_IRQ:
- case CPU_CALL_A_IRQ:
- case CPU_CALL_B_IRQ:
- return 0;
- default: panic("bridge_startup: whoops? %d\n", irq);
- }
+ bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq),
+ WID_FROM_PCI_IRQ(irq));
+ if (real_irq == IRQ_FROM_IRQ(IOC3_ETH_INT))
+ pin = 2;
+ else
+ pin = SLOT_FROM_PCI_IRQ(irq);
+
+ DBG("bridge_startup(): irq= 0x%x real_irq= %d pin=%d\n", irq, real_irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
@@ -253,7 +242,7 @@ static unsigned int bridge_startup(unsigned int irq)
/* set more stuff in int_enable reg */
bridge->b_int_enable |= 0x7ffffe00;
- if (real_irq < 2 || real_irq==4 || real_irq==5) {
+ if (real_irq != IRQ_FROM_IRQ(IOC3_ETH_INT)) {
bridgereg_t device;
#if 0
/*
@@ -268,9 +257,9 @@ static unsigned int bridge_startup(unsigned int irq)
bridge->b_even_resp = 0xcc88; /* breaks eth0 */
#endif
/* Turn on bridge swapping */
- device = bridge->b_device[real_irq].reg;
+ device = bridge->b_device[pin].reg;
device |= BRIDGE_DEV_SWAP_DIR;
- bridge->b_device[real_irq].reg = device;
+ bridge->b_device[pin].reg = device;
/*
* Associate interrupt pin with device
* XXX This only works if b_int_device is initialized to 0!
@@ -292,25 +281,13 @@ static unsigned int bridge_shutdown(unsigned int irq)
int real_irq = IRQ_FROM_IRQ(irq);
struct irqaction **p;
- bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_IRQ(irq), WID_FROM_IRQ(irq));
+ bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq),
+ WID_FROM_PCI_IRQ(irq));
DBG("bridge_shutdown: irq 0x%x\n", irq);
- /* FIIIIIXME ... Temporary kludge. This knows how interrupts are
- setup in _my_ Origin. */
-
- if (irq != real_irq) /* pci device interrupt */
- switch (real_irq) {
- case IRQ_FROM_IRQ(IOC3_ETH_INT): pin = 2; break;
- default: pin = real_irq; break;
- }
- else
- switch (real_irq) {
- case CPU_RESCHED_A_IRQ:
- case CPU_RESCHED_B_IRQ:
- case CPU_CALL_A_IRQ:
- case CPU_CALL_B_IRQ:
- return 0;
- default: panic("bridge_startup: whoops?");
- }
+ if (real_irq == IRQ_FROM_IRQ(IOC3_ETH_INT))
+ pin = 2;
+ else
+ pin = SLOT_FROM_PCI_IRQ(irq);
/*
* map irq to a swlevel greater than 6 since the first 6 bits
@@ -392,7 +369,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
*p = new;
- if (!shared) {
+ if ((!shared) && (irq >= BASE_PCI_IRQ)) {
bridge_startup(irq);
}
restore_flags(flags);
@@ -408,8 +385,6 @@ int request_irq(unsigned int irq,
struct irqaction *action;
DBG("request_irq(): irq= 0x%x\n", irq);
- if (IRQ_FROM_IRQ(irq) > 9)
- return -EINVAL;
if (!handler)
return -EINVAL;
@@ -448,7 +423,7 @@ void free_irq(unsigned int irq, void *dev_id)
/* Found it - now free it */
save_and_cli(flags);
*p = action->next;
- if (!irq[irq_action])
+ if ((!irq[irq_action]) && (irq >= BASE_PCI_IRQ))
bridge_shutdown(irq);
restore_flags(flags);
kfree(action);
diff --git a/arch/mips64/sgi-ip27/ip27-pci.c b/arch/mips64/sgi-ip27/ip27-pci.c
index 75d966d9d..bd068d289 100644
--- a/arch/mips64/sgi-ip27/ip27-pci.c
+++ b/arch/mips64/sgi-ip27/ip27-pci.c
@@ -154,14 +154,32 @@ pci_swizzle(struct pci_dev *dev, u8 *pinp)
return PCI_SLOT(dev->devfn);
}
-/* XXX This should include the node ID into the final interrupt number. */
+/*
+ * All observed requests have pin == 1. We could have a global here, that
+ * gets incremented and returned every time - unfortunately, pci_map_irq
+ * may be called on the same device over and over, and need to return the
+ * same value. On o2000, pin can be 0 or 1, and PCI slots can be [0..3].
+ * The format of the returned irq is:
+ * NASID WID BUS PIN SLOT
+ * 8 8 4 1 3
+ * Just to make sure the interpcu intrs do not collide with any irq's
+ * assigned this way, we keep the intercpu intrs at a low value, and
+ * add in the offset. IOC3_ETH_INT does not collide with other pci irqs
+ * as it has a pin = 0 in the interpreted irq value.
+ */
static int __init
pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int rv;
- rv = (slot + (((pin-1) & 1) << 2)) & 7;
+
+ if ((dev->bus->number > 16) || (slot > 7) || (pin > 1)) {
+ printk("PCI_MAP_IRQ: Time to change IRQ format %d, %d, %d\n", dev->bus->number, slot, pin);
+ while(0);
+ }
+ rv = (dev->bus->number << 4) + (slot + (((pin-1) & 1) << 3));
rv |= (bus_to_wid[dev->bus->number] << 8);
rv |= (bus_to_nid[dev->bus->number] << 16);
+ rv += BASE_PCI_IRQ;
return rv;
}
@@ -251,20 +269,18 @@ pci_fixup_isp1020(struct pci_dev *d)
/* Configure device to allow bus mastering, i/o and memory mapping.
* Older qlogicisp driver expects to have the IO space enable
- * bit set. Things stop working if we program the controllers as not having
- * PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
+ * bit set. Things stop working if we program the controllers as not
+ * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
*/
- /* only turn on scsi's on main bus */
- if (d->bus->number == 0) {
- pci_set_master(d);
- pci_read_config_word(d, PCI_COMMAND, &command);
- command |= PCI_COMMAND_MEMORY;
- command |= PCI_COMMAND_IO;
- pci_write_config_word(d, PCI_COMMAND, command);
- d->resource[1].flags |= 1;
- }
+ pci_set_master(d);
+ pci_read_config_word(d, PCI_COMMAND, &command);
+ command |= PCI_COMMAND_MEMORY;
+ command |= PCI_COMMAND_IO;
+ pci_write_config_word(d, PCI_COMMAND, command);
+ d->resource[1].flags |= 1;
}
+
static void __init
pci_fixup_isp2x00(struct pci_dev *d)
{
diff --git a/include/asm-mips64/sn/sn0/ip27.h b/include/asm-mips64/sn/sn0/ip27.h
index 206c043fa..d595830a5 100644
--- a/include/asm-mips64/sn/sn0/ip27.h
+++ b/include/asm-mips64/sn/sn0/ip27.h
@@ -85,14 +85,11 @@
/* Sanity hazzard ... Below all the Origin hacks are following. */
-#define SCSI0_INT 0
-#define SCSI1_INT 1
-#define CPU_RESCHED_A_IRQ 3
-#define CPU_RESCHED_B_IRQ 4
-#define QLOGICFC_SLOT5 5
-#define CPU_CALL_A_IRQ 6
-#define CPU_CALL_B_IRQ 7
-#define IOC3_SERIAL_INT 8
+#define CPU_RESCHED_A_IRQ 0
+#define CPU_RESCHED_B_IRQ 1
+#define CPU_CALL_A_IRQ 2
+#define CPU_CALL_B_IRQ 3
+#define BASE_PCI_IRQ 4
/*#define IOC3_ETH_INT 9*/
#define IOC3_ETH_INT 0x0809 /* nasid 0, wid 0x8 */