powerpc/pseries/pci: Add a domain_free_irqs() handler
authorCédric Le Goater <clg@kaod.org>
Thu, 1 Jul 2021 13:27:26 +0000 (15:27 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 10 Aug 2021 13:14:58 +0000 (23:14 +1000)
The RTAS firmware can not disable one MSI at a time. It's all or
nothing. We need a custom free IRQ handler for that.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210701132750.1475580-9-clg@kaod.org
arch/powerpc/platforms/pseries/msi.c

index 86c6809ebac2c70c6c86dff52357b163514b0d02..591cee9cbc9ed79943dbd9138655683baddcb2ee 100644 (file)
@@ -529,8 +529,24 @@ static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev
        return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
 }
 
+/*
+ * RTAS can not disable one MSI at a time. It's all or nothing. Do it
+ * at the end after all IRQs have been freed.
+ */
+static void pseries_msi_domain_free_irqs(struct irq_domain *domain,
+                                        struct device *dev)
+{
+       if (WARN_ON_ONCE(!dev_is_pci(dev)))
+               return;
+
+       __msi_domain_free_irqs(domain, dev);
+
+       rtas_disable_msi(to_pci_dev(dev));
+}
+
 static struct msi_domain_ops pseries_pci_msi_domain_ops = {
        .msi_prepare    = pseries_msi_ops_prepare,
+       .domain_free_irqs = pseries_msi_domain_free_irqs,
 };
 
 static void pseries_msi_shutdown(struct irq_data *d)