summaryrefslogtreecommitdiffstats
path: root/kernel/arch/powerpc/sysdev/fsl_msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/arch/powerpc/sysdev/fsl_msi.c')
-rw-r--r--kernel/arch/powerpc/sysdev/fsl_msi.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/kernel/arch/powerpc/sysdev/fsl_msi.c b/kernel/arch/powerpc/sysdev/fsl_msi.c
index f086c6f22..3a2be3676 100644
--- a/kernel/arch/powerpc/sysdev/fsl_msi.c
+++ b/kernel/arch/powerpc/sysdev/fsl_msi.c
@@ -110,7 +110,7 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
int rc, hwirq;
rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS_MAX,
- msi_data->irqhost->of_node);
+ irq_domain_get_of_node(msi_data->irqhost));
if (rc)
return rc;
@@ -128,15 +128,16 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
struct fsl_msi *msi_data;
+ irq_hw_number_t hwirq;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
+ hwirq = virq_to_hw(entry->irq);
msi_data = irq_get_chip_data(entry->irq);
irq_set_msi_desc(entry->irq, NULL);
- msi_bitmap_free_hwirqs(&msi_data->bitmap,
- virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
+ msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
}
return;
@@ -219,7 +220,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
}
}
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/*
* Loop over all the MSI devices until we find one that has an
* available interrupt.
@@ -405,6 +406,7 @@ static int fsl_of_msi_probe(struct platform_device *dev)
const struct fsl_msi_feature *features;
int len;
u32 offset;
+ struct pci_controller *phb;
match = of_match_device(fsl_of_msi_ids, &dev->dev);
if (!match)
@@ -541,14 +543,20 @@ static int fsl_of_msi_probe(struct platform_device *dev)
list_add_tail(&msi->list, &msi_head);
- /* The multiple setting ppc_md.setup_msi_irqs will not harm things */
- if (!ppc_md.setup_msi_irqs) {
- ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
- } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
- dev_err(&dev->dev, "Different MSI driver already installed!\n");
- err = -ENODEV;
- goto error_out;
+ /*
+ * Apply the MSI ops to all the controllers.
+ * It doesn't hurt to reassign the same ops,
+ * but bail out if we find another MSI driver.
+ */
+ list_for_each_entry(phb, &hose_list, list_node) {
+ if (!phb->controller_ops.setup_msi_irqs) {
+ phb->controller_ops.setup_msi_irqs = fsl_setup_msi_irqs;
+ phb->controller_ops.teardown_msi_irqs = fsl_teardown_msi_irqs;
+ } else if (phb->controller_ops.setup_msi_irqs != fsl_setup_msi_irqs) {
+ dev_err(&dev->dev, "Different MSI driver already installed!\n");
+ err = -ENODEV;
+ goto error_out;
+ }
}
return 0;
error_out: