|
@@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
|
|
|
return pcidev->irq;
|
|
|
}
|
|
|
|
|
|
+static struct iosapic_info *first_isi = NULL;
|
|
|
+
|
|
|
+#ifdef CONFIG_64BIT
|
|
|
+int iosapic_serial_irq(int num)
|
|
|
+{
|
|
|
+ struct iosapic_info *isi = first_isi;
|
|
|
+ struct irt_entry *irte = NULL; /* only used if PAT PDC */
|
|
|
+ struct vector_info *vi;
|
|
|
+ int isi_line; /* line used by device */
|
|
|
+
|
|
|
+ /* lookup IRT entry for isi/slot/pin set */
|
|
|
+ irte = &irt_cell[num];
|
|
|
+
|
|
|
+ DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
|
|
|
+ irte,
|
|
|
+ irte->entry_type,
|
|
|
+ irte->entry_length,
|
|
|
+ irte->polarity_trigger,
|
|
|
+ irte->src_bus_irq_devno,
|
|
|
+ irte->src_bus_id,
|
|
|
+ irte->src_seg_id,
|
|
|
+ irte->dest_iosapic_intin,
|
|
|
+ (u32) irte->dest_iosapic_addr);
|
|
|
+ isi_line = irte->dest_iosapic_intin;
|
|
|
+
|
|
|
+ /* get vector info for this input line */
|
|
|
+ vi = isi->isi_vector + isi_line;
|
|
|
+ DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi);
|
|
|
+
|
|
|
+ /* If this IRQ line has already been setup, skip it */
|
|
|
+ if (vi->irte)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ vi->irte = irte;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Allocate processor IRQ
|
|
|
+ *
|
|
|
+ * XXX/FIXME The txn_alloc_irq() code and related code should be
|
|
|
+ * moved to enable_irq(). That way we only allocate processor IRQ
|
|
|
+ * bits for devices that actually have drivers claiming them.
|
|
|
+ * Right now we assign an IRQ to every PCI device present,
|
|
|
+ * regardless of whether it's used or not.
|
|
|
+ */
|
|
|
+ vi->txn_irq = txn_alloc_irq(8);
|
|
|
+
|
|
|
+ if (vi->txn_irq < 0)
|
|
|
+ panic("I/O sapic: couldn't get TXN IRQ\n");
|
|
|
+
|
|
|
+ /* enable_irq() will use txn_* to program IRdT */
|
|
|
+ vi->txn_addr = txn_alloc_addr(vi->txn_irq);
|
|
|
+ vi->txn_data = txn_alloc_data(vi->txn_irq);
|
|
|
+
|
|
|
+ vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
|
|
|
+ vi->eoi_data = cpu_to_le32(vi->txn_data);
|
|
|
+
|
|
|
+ cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
|
|
|
+
|
|
|
+ out:
|
|
|
+
|
|
|
+ return vi->txn_irq;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
** squirrel away the I/O Sapic Version
|
|
@@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa)
|
|
|
vip->irqline = (unsigned char) cnt;
|
|
|
vip->iosapic = isi;
|
|
|
}
|
|
|
+ if (!first_isi)
|
|
|
+ first_isi = isi;
|
|
|
return isi;
|
|
|
}
|
|
|
|