diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci-ioda.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3d4e9588a69..3f88c51cb95 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -31,6 +31,7 @@ #include <asm/opal.h> #include <asm/iommu.h> #include <asm/tce.h> +#include <asm/xics.h> #include "powernv.h" #include "pci.h" @@ -589,11 +590,27 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb) } #ifdef CONFIG_PCI_MSI +static void pnv_ioda2_msi_eoi(struct irq_data *d) +{ + unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); + struct irq_chip *chip = irq_data_get_irq_chip(d); + struct pnv_phb *phb = container_of(chip, struct pnv_phb, + ioda.irq_chip); + int64_t rc; + + rc = opal_pci_msi_eoi(phb->opal_id, hw_irq); + WARN_ON_ONCE(rc); + + icp_native_eoi(d); +} + static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int is_64, - struct msi_msg *msg) + unsigned int hwirq, unsigned int virq, + unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); + struct irq_data *idata; + struct irq_chip *ichip; unsigned int xive_num = hwirq - phb->msi_base; uint64_t addr64; uint32_t addr32, data; @@ -638,6 +655,23 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, } msg->data = data; + /* + * Change the IRQ chip for the MSI interrupts on PHB3. + * The corresponding IRQ chip should be populated for + * the first time. + */ + if (phb->type == PNV_PHB_IODA2) { + if (!phb->ioda.irq_chip_init) { + idata = irq_get_irq_data(virq); + ichip = irq_data_get_irq_chip(idata); + phb->ioda.irq_chip_init = 1; + phb->ioda.irq_chip = *ichip; + phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; + } + + irq_set_chip(virq, &phb->ioda.irq_chip); + } + pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," " address=%x_%08x data=%x PE# %d\n", pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, |