]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
PCI/xgene-msi: Convert to hotplug state machine
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Thu, 17 Nov 2016 18:35:28 +0000 (19:35 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 22 Nov 2016 22:34:40 +0000 (23:34 +0100)
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: linux-pci@vger.kernel.org
Cc: Duc Dang <dhdang@apm.com>
Cc: rt@linuxtronix.de
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/20161117183541.8588-8-bigeasy@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
drivers/pci/host/pci-xgene-msi.c
include/linux/cpuhotplug.h

index a6456b5782692a5d5559b9ef59226d2fbce99e3f..1f38d0836751af9f823d848218d7dc17d9dad43f 100644 (file)
@@ -360,16 +360,16 @@ static void xgene_msi_isr(struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
+static enum cpuhp_state pci_xgene_online;
+
 static int xgene_msi_remove(struct platform_device *pdev)
 {
-       int virq, i;
        struct xgene_msi *msi = platform_get_drvdata(pdev);
 
-       for (i = 0; i < NR_HW_IRQS; i++) {
-               virq = msi->msi_groups[i].gic_irq;
-               if (virq != 0)
-                       irq_set_chained_handler_and_data(virq, NULL, NULL);
-       }
+       if (pci_xgene_online)
+               cpuhp_remove_state(pci_xgene_online);
+       cpuhp_remove_state(CPUHP_PCI_XGENE_DEAD);
+
        kfree(msi->msi_groups);
 
        kfree(msi->bitmap);
@@ -427,7 +427,7 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)
        return 0;
 }
 
-static void xgene_msi_hwirq_free(unsigned int cpu)
+static int xgene_msi_hwirq_free(unsigned int cpu)
 {
        struct xgene_msi *msi = &xgene_msi_ctrl;
        struct xgene_msi_group *msi_group;
@@ -441,33 +441,9 @@ static void xgene_msi_hwirq_free(unsigned int cpu)
                irq_set_chained_handler_and_data(msi_group->gic_irq, NULL,
                                                 NULL);
        }
+       return 0;
 }
 
-static int xgene_msi_cpu_callback(struct notifier_block *nfb,
-                                 unsigned long action, void *hcpu)
-{
-       unsigned cpu = (unsigned long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               xgene_msi_hwirq_alloc(cpu);
-               break;
-       case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
-               xgene_msi_hwirq_free(cpu);
-               break;
-       default:
-               break;
-       }
-
-       return NOTIFY_OK;
-}
-
-static struct notifier_block xgene_msi_cpu_notifier = {
-       .notifier_call = xgene_msi_cpu_callback,
-};
-
 static const struct of_device_id xgene_msi_match_table[] = {
        {.compatible = "apm,xgene1-msi"},
        {},
@@ -478,7 +454,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
        struct resource *res;
        int rc, irq_index;
        struct xgene_msi *xgene_msi;
-       unsigned int cpu;
        int virt_msir;
        u32 msi_val, msi_idx;
 
@@ -540,28 +515,22 @@ static int xgene_msi_probe(struct platform_device *pdev)
                }
        }
 
-       cpu_notifier_register_begin();
-
-       for_each_online_cpu(cpu)
-               if (xgene_msi_hwirq_alloc(cpu)) {
-                       dev_err(&pdev->dev, "failed to register MSI handlers\n");
-                       cpu_notifier_register_done();
-                       goto error;
-               }
-
-       rc = __register_hotcpu_notifier(&xgene_msi_cpu_notifier);
-       if (rc) {
-               dev_err(&pdev->dev, "failed to add CPU MSI notifier\n");
-               cpu_notifier_register_done();
-               goto error;
-       }
-
-       cpu_notifier_register_done();
+       rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "pci/xgene:online",
+                              xgene_msi_hwirq_alloc, NULL);
+       if (rc)
+               goto err_cpuhp;
+       pci_xgene_online = rc;
+       rc = cpuhp_setup_state(CPUHP_PCI_XGENE_DEAD, "pci/xgene:dead", NULL,
+                              xgene_msi_hwirq_free);
+       if (rc)
+               goto err_cpuhp;
 
        dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n");
 
        return 0;
 
+err_cpuhp:
+       dev_err(&pdev->dev, "failed to add CPU MSI notifier\n");
 error:
        xgene_msi_remove(pdev);
        return rc;
index 79b96f647d643e1c715e90cd69d1160cd2f40452..94c6a189421f9731b21e4889081aa2e145e4bebe 100644 (file)
@@ -38,6 +38,7 @@ enum cpuhp_state {
        CPUHP_RADIX_DEAD,
        CPUHP_PAGE_ALLOC_DEAD,
        CPUHP_NET_DEV_DEAD,
+       CPUHP_PCI_XGENE_DEAD,
        CPUHP_WORKQUEUE_PREP,
        CPUHP_POWER_NUMA_PREPARE,
        CPUHP_HRTIMERS_PREPARE,