xive-specific data is stored in handler_data. This creates a mess, as xive
has to rely on child interrupt controller drivers to clean up this data, as
was done by 9a014f45688 ("powerpc/pseries/pci: Add a msi_free() handler to
clear XIVE data").

Instead, store xive-specific data in chip_data and untangle the child
drivers.

Signed-off-by: Nam Cao <nam...@linutronix.de>
---
 arch/powerpc/include/asm/xive.h           |  1 -
 arch/powerpc/platforms/powernv/pci-ioda.c | 21 +-------
 arch/powerpc/platforms/pseries/msi.c      | 18 +------
 arch/powerpc/sysdev/xive/common.c         | 63 +++++++++++------------
 4 files changed, 33 insertions(+), 70 deletions(-)

diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index 92930b0b5d0e1..efb0f5effcc69 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -111,7 +111,6 @@ void xive_native_free_vp_block(u32 vp_base);
 int xive_native_populate_irq_data(u32 hw_irq,
                                  struct xive_irq_data *data);
 void xive_cleanup_irq_data(struct xive_irq_data *xd);
-void xive_irq_free_data(unsigned int virq);
 void xive_native_free_irq(u32 irq);
 int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index d8ccf2c9b98ad..fb37098d4d58c 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -37,7 +37,6 @@
 #include <asm/firmware.h>
 #include <asm/pnv-pci.h>
 #include <asm/mmzone.h>
-#include <asm/xive.h>
 
 #include "powernv.h"
 #include "pci.h"
@@ -1707,23 +1706,6 @@ static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, 
struct pci_dev *dev,
        return 0;
 }
 
-/*
- * The msi_free() op is called before irq_domain_free_irqs_top() when
- * the handler data is still available. Use that to clear the XIVE
- * controller.
- */
-static void pnv_msi_ops_msi_free(struct irq_domain *domain,
-                                struct msi_domain_info *info,
-                                unsigned int irq)
-{
-       if (xive_enabled())
-               xive_irq_free_data(irq);
-}
-
-static struct msi_domain_ops pnv_pci_msi_domain_ops = {
-       .msi_free       = pnv_msi_ops_msi_free,
-};
-
 static void pnv_msi_shutdown(struct irq_data *d)
 {
        d = d->parent_data;
@@ -1754,7 +1736,6 @@ static struct irq_chip pnv_pci_msi_irq_chip = {
 static struct msi_domain_info pnv_msi_domain_info = {
        .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
                  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
-       .ops   = &pnv_pci_msi_domain_ops,
        .chip  = &pnv_pci_msi_irq_chip,
 };
 
@@ -1870,7 +1851,7 @@ static void pnv_irq_domain_free(struct irq_domain 
*domain, unsigned int virq,
                 virq, d->hwirq, nr_irqs);
 
        msi_bitmap_free_hwirqs(&phb->msi_bmp, d->hwirq, nr_irqs);
-       /* XIVE domain is cleared through ->msi_free() */
+       irq_domain_free_irqs_parent(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops pnv_irq_domain_ops = {
diff --git a/arch/powerpc/platforms/pseries/msi.c 
b/arch/powerpc/platforms/pseries/msi.c
index ee1c8c6898a3c..10712477938e4 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -15,7 +15,6 @@
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
 #include <asm/machdep.h>
-#include <asm/xive.h>
 
 #include "pseries.h"
 
@@ -436,19 +435,6 @@ static int pseries_msi_ops_prepare(struct irq_domain 
*domain, struct device *dev
        return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
 }
 
-/*
- * ->msi_free() is called before irq_domain_free_irqs_top() when the
- * handler data is still available. Use that to clear the XIVE
- * controller data.
- */
-static void pseries_msi_ops_msi_free(struct irq_domain *domain,
-                                    struct msi_domain_info *info,
-                                    unsigned int irq)
-{
-       if (xive_enabled())
-               xive_irq_free_data(irq);
-}
-
 /*
  * 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.
@@ -463,7 +449,6 @@ static void pseries_msi_post_free(struct irq_domain 
*domain, struct device *dev)
 
 static struct msi_domain_ops pseries_pci_msi_domain_ops = {
        .msi_prepare    = pseries_msi_ops_prepare,
-       .msi_free       = pseries_msi_ops_msi_free,
        .msi_post_free  = pseries_msi_post_free,
 };
 
@@ -604,8 +589,7 @@ static void pseries_irq_domain_free(struct irq_domain 
*domain, unsigned int virq
        struct pci_controller *phb = irq_data_get_irq_chip_data(d);
 
        pr_debug("%s bridge %pOF %d #%d\n", __func__, phb->dn, virq, nr_irqs);
-
-       /* XIVE domain data is cleared through ->msi_free() */
+       irq_domain_free_irqs_parent(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops pseries_irq_domain_ops = {
diff --git a/arch/powerpc/sysdev/xive/common.c 
b/arch/powerpc/sysdev/xive/common.c
index f105924050247..625361a15424e 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -317,7 +317,7 @@ int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d)
        if (d) {
                char buffer[128];
 
-               xive_irq_data_dump(irq_data_get_irq_handler_data(d),
+               xive_irq_data_dump(irq_data_get_irq_chip_data(d),
                                   buffer, sizeof(buffer));
                xmon_printf("%s", buffer);
        }
@@ -437,7 +437,7 @@ static void xive_do_source_eoi(struct xive_irq_data *xd)
 /* irq_chip eoi callback, called with irq descriptor lock held */
 static void xive_irq_eoi(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        struct xive_cpu *xc = __this_cpu_read(xive_cpu);
 
        DBG_VERBOSE("eoi_irq: irq=%d [0x%lx] pending=%02x\n",
@@ -595,7 +595,7 @@ static int xive_pick_irq_target(struct irq_data *d,
                                const struct cpumask *affinity)
 {
        static unsigned int fuzz;
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        cpumask_var_t mask;
        int cpu = -1;
 
@@ -628,7 +628,7 @@ static int xive_pick_irq_target(struct irq_data *d,
 
 static unsigned int xive_irq_startup(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
        int target, rc;
 
@@ -673,7 +673,7 @@ static unsigned int xive_irq_startup(struct irq_data *d)
 /* called with irq descriptor lock held */
 static void xive_irq_shutdown(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
 
        pr_debug("%s: irq %d [0x%x] data @%p\n", __func__, d->irq, hw_irq, d);
@@ -698,7 +698,7 @@ static void xive_irq_shutdown(struct irq_data *d)
 
 static void xive_irq_unmask(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
 
        pr_debug("%s: irq %d data @%p\n", __func__, d->irq, xd);
 
@@ -707,7 +707,7 @@ static void xive_irq_unmask(struct irq_data *d)
 
 static void xive_irq_mask(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
 
        pr_debug("%s: irq %d data @%p\n", __func__, d->irq, xd);
 
@@ -718,7 +718,7 @@ static int xive_irq_set_affinity(struct irq_data *d,
                                 const struct cpumask *cpumask,
                                 bool force)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
        u32 target, old_target;
        int rc = 0;
@@ -776,7 +776,7 @@ static int xive_irq_set_affinity(struct irq_data *d,
 
 static int xive_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
 
        /*
         * We only support these. This has really no effect other than setting
@@ -815,7 +815,7 @@ static int xive_irq_set_type(struct irq_data *d, unsigned 
int flow_type)
 
 static int xive_irq_retrigger(struct irq_data *d)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
 
        /* This should be only for MSIs */
        if (WARN_ON(xd->flags & XIVE_IRQ_FLAG_LSI))
@@ -837,7 +837,7 @@ static int xive_irq_retrigger(struct irq_data *d)
  */
 static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(d);
        unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
        int rc;
        u8 pq;
@@ -951,7 +951,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, 
void *state)
 static int xive_get_irqchip_state(struct irq_data *data,
                                  enum irqchip_irq_state which, bool *state)
 {
-       struct xive_irq_data *xd = irq_data_get_irq_handler_data(data);
+       struct xive_irq_data *xd = irq_data_get_irq_chip_data(data);
        u8 pq;
 
        switch (which) {
@@ -1011,21 +1011,20 @@ void xive_cleanup_irq_data(struct xive_irq_data *xd)
 }
 EXPORT_SYMBOL_GPL(xive_cleanup_irq_data);
 
-static int xive_irq_alloc_data(unsigned int virq, irq_hw_number_t hw)
+static struct xive_irq_data *xive_irq_alloc_data(unsigned int virq, 
irq_hw_number_t hw)
 {
        struct xive_irq_data *xd;
        int rc;
 
        xd = kzalloc(sizeof(struct xive_irq_data), GFP_KERNEL);
        if (!xd)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        rc = xive_ops->populate_irq_data(hw, xd);
        if (rc) {
                kfree(xd);
-               return rc;
+               return ERR_PTR(rc);
        }
        xd->target = XIVE_INVALID_TARGET;
-       irq_set_handler_data(virq, xd);
 
        /*
         * Turn OFF by default the interrupt being mapped. A side
@@ -1036,20 +1035,19 @@ static int xive_irq_alloc_data(unsigned int virq, 
irq_hw_number_t hw)
         */
        xive_esb_read(xd, XIVE_ESB_SET_PQ_01);
 
-       return 0;
+       return xd;
 }
 
-void xive_irq_free_data(unsigned int virq)
+static void xive_irq_free_data(unsigned int virq)
 {
-       struct xive_irq_data *xd = irq_get_handler_data(virq);
+       struct xive_irq_data *xd = irq_get_chip_data(virq);
 
        if (!xd)
                return;
-       irq_set_handler_data(virq, NULL);
+       irq_set_chip_data(virq, NULL);
        xive_cleanup_irq_data(xd);
        kfree(xd);
 }
-EXPORT_SYMBOL_GPL(xive_irq_free_data);
 
 #ifdef CONFIG_SMP
 
@@ -1286,7 +1284,7 @@ void __init xive_smp_probe(void)
 static int xive_irq_domain_map(struct irq_domain *h, unsigned int virq,
                               irq_hw_number_t hw)
 {
-       int rc;
+       struct xive_irq_data *xd;
 
        /*
         * Mark interrupts as edge sensitive by default so that resend
@@ -1294,11 +1292,12 @@ static int xive_irq_domain_map(struct irq_domain *h, 
unsigned int virq,
         */
        irq_clear_status_flags(virq, IRQ_LEVEL);
 
-       rc = xive_irq_alloc_data(virq, hw);
-       if (rc)
-               return rc;
+       xd = xive_irq_alloc_data(virq, hw);
+       if (IS_ERR(xd))
+               return PTR_ERR(xd);
 
        irq_set_chip_and_handler(virq, &xive_irq_chip, handle_fasteoi_irq);
+       irq_set_chip_data(virq, xd);
 
        return 0;
 }
@@ -1366,7 +1365,7 @@ static void xive_irq_domain_debug_show(struct seq_file 
*m, struct irq_domain *d,
        seq_printf(m, "%*sXIVE:\n", ind, "");
        ind++;
 
-       xd = irq_data_get_irq_handler_data(irqd);
+       xd = irq_data_get_irq_chip_data(irqd);
        if (!xd) {
                seq_printf(m, "%*snot assigned\n", ind, "");
                return;
@@ -1403,6 +1402,7 @@ static int xive_irq_domain_alloc(struct irq_domain 
*domain, unsigned int virq,
                                 unsigned int nr_irqs, void *arg)
 {
        struct irq_fwspec *fwspec = arg;
+       struct xive_irq_data *xd;
        irq_hw_number_t hwirq;
        unsigned int type = IRQ_TYPE_NONE;
        int i, rc;
@@ -1423,12 +1423,11 @@ static int xive_irq_domain_alloc(struct irq_domain 
*domain, unsigned int virq,
                irq_clear_status_flags(virq, IRQ_LEVEL);
 
                /* allocates and sets handler data */
-               rc = xive_irq_alloc_data(virq + i, hwirq + i);
-               if (rc)
-                       return rc;
+               xd = xive_irq_alloc_data(virq + i, hwirq + i);
+               if (IS_ERR(xd))
+                       return PTR_ERR(xd);
 
-               irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
-                                             &xive_irq_chip, 
domain->host_data);
+               irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, 
&xive_irq_chip, xd);
                irq_set_handler(virq + i, handle_fasteoi_irq);
        }
 
@@ -1764,7 +1763,7 @@ static void xive_debug_show_irq(struct seq_file *m, 
struct irq_data *d)
        seq_printf(m, "IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ",
                   hw_irq, target, prio, lirq);
 
-       xive_irq_data_dump(irq_data_get_irq_handler_data(d), buffer, 
sizeof(buffer));
+       xive_irq_data_dump(irq_data_get_irq_chip_data(d), buffer, 
sizeof(buffer));
        seq_puts(m, buffer);
        seq_puts(m, "\n");
 }
-- 
2.39.5


Reply via email to