}
int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
+{
+ return __setup_msi_irq(desc, msidesc,
+ msi_maskable_irq(msidesc) ? &pci_msi_maskable
+ : &pci_msi_nonmaskable);
+}
+
+int __setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc,
+ hw_irq_controller *handler)
{
struct msi_msg msg;
desc->msi_desc = msidesc;
- desc->handler = msi_maskable_irq(msidesc) ? &pci_msi_maskable
- : &pci_msi_nonmaskable;
+ desc->handler = handler;
msi_compose_msg(desc, &msg);
return write_msi_msg(msidesc, &msg);
}
static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
{
int irq, ret;
- struct irq_desc *desc;
+ hw_irq_controller *handler;
unsigned long flags;
u16 control;
return 0;
}
- desc = irq_to_desc(irq);
spin_lock_irqsave(&pcidevs_lock, flags);
iommu->msi.dev = pci_get_pdev(iommu->seg, PCI_BUS(iommu->bdf),
PCI_DEVFN2(iommu->bdf));
PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
return 0;
}
- desc->msi_desc = &iommu->msi;
control = pci_conf_read16(iommu->seg, PCI_BUS(iommu->bdf),
PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
iommu->msi.msi_attrib.pos + PCI_MSI_FLAGS);
iommu->msi.msi_attrib.maskbit = 1;
iommu->msi.msi.mpos = msi_mask_bits_reg(iommu->msi.msi_attrib.pos,
is_64bit_address(control));
- desc->handler = &iommu_maskable_msi_type;
+ handler = &iommu_maskable_msi_type;
}
else
- desc->handler = &iommu_msi_type;
- ret = request_irq(irq, iommu_interrupt_handler, 0, "amd_iommu", iommu);
+ handler = &iommu_msi_type;
+ ret = __setup_msi_irq(irq_to_desc(irq), &iommu->msi, handler);
+ if ( !ret )
+ ret = request_irq(irq, iommu_interrupt_handler, 0, "amd_iommu", iommu);
if ( ret )
{
- desc->handler = &no_irq_type;
destroy_irq(irq);
AMD_IOMMU_DEBUG("can't request irq\n");
return 0;
};
struct irq_desc;
+struct hw_interrupt_type;
struct msi_desc;
/* Helper functions */
extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
extern int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool_t off);
extern void pci_cleanup_msi(struct pci_dev *pdev);
extern int setup_msi_irq(struct irq_desc *, struct msi_desc *);
+extern int __setup_msi_irq(struct irq_desc *, struct msi_desc *,
+ const struct hw_interrupt_type *);
extern void teardown_msi_irq(int irq);
extern int msi_free_vector(struct msi_desc *entry);
extern int pci_restore_msi_state(struct pci_dev *pdev);