|
@@ -360,16 +360,16 @@ static void xgene_msi_isr(struct irq_desc *desc)
|
|
chained_irq_exit(chip, desc);
|
|
chained_irq_exit(chip, desc);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static enum cpuhp_state pci_xgene_online;
|
|
|
|
+
|
|
static int xgene_msi_remove(struct platform_device *pdev)
|
|
static int xgene_msi_remove(struct platform_device *pdev)
|
|
{
|
|
{
|
|
- int virq, i;
|
|
|
|
struct xgene_msi *msi = platform_get_drvdata(pdev);
|
|
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->msi_groups);
|
|
|
|
|
|
kfree(msi->bitmap);
|
|
kfree(msi->bitmap);
|
|
@@ -427,7 +427,7 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)
|
|
return 0;
|
|
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 *msi = &xgene_msi_ctrl;
|
|
struct xgene_msi_group *msi_group;
|
|
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,
|
|
irq_set_chained_handler_and_data(msi_group->gic_irq, NULL,
|
|
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[] = {
|
|
static const struct of_device_id xgene_msi_match_table[] = {
|
|
{.compatible = "apm,xgene1-msi"},
|
|
{.compatible = "apm,xgene1-msi"},
|
|
{},
|
|
{},
|
|
@@ -478,7 +454,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
|
|
struct resource *res;
|
|
struct resource *res;
|
|
int rc, irq_index;
|
|
int rc, irq_index;
|
|
struct xgene_msi *xgene_msi;
|
|
struct xgene_msi *xgene_msi;
|
|
- unsigned int cpu;
|
|
|
|
int virt_msir;
|
|
int virt_msir;
|
|
u32 msi_val, msi_idx;
|
|
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");
|
|
dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n");
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+err_cpuhp:
|
|
|
|
+ dev_err(&pdev->dev, "failed to add CPU MSI notifier\n");
|
|
error:
|
|
error:
|
|
xgene_msi_remove(pdev);
|
|
xgene_msi_remove(pdev);
|
|
return rc;
|
|
return rc;
|