Skip to content

Commit 6aceb36

Browse files
Marc Zyngierbjorn-helgaas
authored andcommitted
PCI: xgene-msi: Restructure handler setup/teardown
Another utterly pointless aspect of the xgene-msi driver is that it is built around CPU hotplug. Which is quite amusing since this is one of the few arm64 platforms that, by construction, cannot do CPU hotplug in a supported way (no EL3, no PSCI, no luck). Drop the CPU hotplug nonsense and just setup the IRQs and handlers in a less overdesigned way, grouping things more logically in the process. Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent cd5ffaf commit 6aceb36

File tree

1 file changed

+37
-70
lines changed

1 file changed

+37
-70
lines changed

drivers/pci/controller/pci-xgene-msi.c

Lines changed: 37 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,6 @@ static int xgene_allocate_domains(struct device_node *node,
231231
return msi->inner_domain ? 0 : -ENOMEM;
232232
}
233233

234-
static void xgene_free_domains(struct xgene_msi *msi)
235-
{
236-
if (msi->inner_domain)
237-
irq_domain_remove(msi->inner_domain);
238-
}
239-
240234
static int xgene_msi_init_allocator(struct device *dev)
241235
{
242236
xgene_msi_ctrl->bitmap = devm_bitmap_zalloc(dev, NR_MSI_VEC, GFP_KERNEL);
@@ -283,34 +277,56 @@ static void xgene_msi_isr(struct irq_desc *desc)
283277
chained_irq_exit(chip, desc);
284278
}
285279

286-
static enum cpuhp_state pci_xgene_online;
287-
288280
static void xgene_msi_remove(struct platform_device *pdev)
289281
{
290-
struct xgene_msi *msi = platform_get_drvdata(pdev);
291-
292-
if (pci_xgene_online)
293-
cpuhp_remove_state(pci_xgene_online);
294-
cpuhp_remove_state(CPUHP_PCI_XGENE_DEAD);
282+
for (int i = 0; i < NR_HW_IRQS; i++) {
283+
unsigned int irq = xgene_msi_ctrl->gic_irq[i];
284+
if (!irq)
285+
continue;
286+
irq_set_chained_handler_and_data(irq, NULL, NULL);
287+
}
295288

296-
xgene_free_domains(msi);
289+
if (xgene_msi_ctrl->inner_domain)
290+
irq_domain_remove(xgene_msi_ctrl->inner_domain);
297291
}
298292

299-
static int xgene_msi_hwirq_alloc(unsigned int cpu)
293+
static int xgene_msi_handler_setup(struct platform_device *pdev)
300294
{
295+
struct xgene_msi *xgene_msi = xgene_msi_ctrl;
301296
int i;
302-
int err;
303297

304-
for (i = cpu; i < NR_HW_IRQS; i += num_possible_cpus()) {
305-
unsigned int irq = xgene_msi_ctrl->gic_irq[i];
298+
for (i = 0; i < NR_HW_IRQS; i++) {
299+
u32 msi_val;
300+
int irq, err;
301+
302+
/*
303+
* MSInIRx registers are read-to-clear; before registering
304+
* interrupt handlers, read all of them to clear spurious
305+
* interrupts that may occur before the driver is probed.
306+
*/
307+
for (int msi_idx = 0; msi_idx < IDX_PER_GROUP; msi_idx++)
308+
xgene_msi_ir_read(xgene_msi, i, msi_idx);
309+
310+
/* Read MSIINTn to confirm */
311+
msi_val = xgene_msi_int_read(xgene_msi, i);
312+
if (msi_val) {
313+
dev_err(&pdev->dev, "Failed to clear spurious IRQ\n");
314+
return EINVAL;
315+
}
316+
317+
irq = platform_get_irq(pdev, i);
318+
if (irq < 0)
319+
return irq;
320+
321+
xgene_msi->gic_irq[i] = irq;
306322

307323
/*
308324
* Statically allocate MSI GIC IRQs to each CPU core.
309325
* With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated
310326
* to each core.
311327
*/
312328
irq_set_status_flags(irq, IRQ_NO_BALANCING);
313-
err = irq_set_affinity(irq, cpumask_of(cpu));
329+
err = irq_set_affinity(irq, cpumask_of(i % num_possible_cpus()));
314330
if (err) {
315331
pr_err("failed to set affinity for GIC IRQ");
316332
return err;
@@ -323,17 +339,6 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)
323339
return 0;
324340
}
325341

326-
static int xgene_msi_hwirq_free(unsigned int cpu)
327-
{
328-
struct xgene_msi *msi = xgene_msi_ctrl;
329-
int i;
330-
331-
for (i = cpu; i < NR_HW_IRQS; i += num_possible_cpus())
332-
irq_set_chained_handler_and_data(msi->gic_irq[i], NULL, NULL);
333-
334-
return 0;
335-
}
336-
337342
static const struct of_device_id xgene_msi_match_table[] = {
338343
{.compatible = "apm,xgene1-msi"},
339344
{},
@@ -343,7 +348,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
343348
{
344349
struct resource *res;
345350
struct xgene_msi *xgene_msi;
346-
u32 msi_val, msi_idx;
347351
int rc;
348352

349353
xgene_msi_ctrl = devm_kzalloc(&pdev->dev, sizeof(*xgene_msi_ctrl),
@@ -353,8 +357,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
353357

354358
xgene_msi = xgene_msi_ctrl;
355359

356-
platform_set_drvdata(pdev, xgene_msi);
357-
358360
xgene_msi->msi_regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
359361
if (IS_ERR(xgene_msi->msi_regs)) {
360362
rc = PTR_ERR(xgene_msi->msi_regs);
@@ -374,48 +376,13 @@ static int xgene_msi_probe(struct platform_device *pdev)
374376
goto error;
375377
}
376378

377-
for (int irq_index = 0; irq_index < NR_HW_IRQS; irq_index++) {
378-
rc = platform_get_irq(pdev, irq_index);
379-
if (rc < 0)
380-
goto error;
381-
382-
xgene_msi->gic_irq[irq_index] = rc;
383-
}
384-
385-
/*
386-
* MSInIRx registers are read-to-clear; before registering
387-
* interrupt handlers, read all of them to clear spurious
388-
* interrupts that may occur before the driver is probed.
389-
*/
390-
for (int irq_index = 0; irq_index < NR_HW_IRQS; irq_index++) {
391-
for (msi_idx = 0; msi_idx < IDX_PER_GROUP; msi_idx++)
392-
xgene_msi_ir_read(xgene_msi, irq_index, msi_idx);
393-
394-
/* Read MSIINTn to confirm */
395-
msi_val = xgene_msi_int_read(xgene_msi, irq_index);
396-
if (msi_val) {
397-
dev_err(&pdev->dev, "Failed to clear spurious IRQ\n");
398-
rc = -EINVAL;
399-
goto error;
400-
}
401-
}
402-
403-
rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "pci/xgene:online",
404-
xgene_msi_hwirq_alloc, NULL);
405-
if (rc < 0)
406-
goto err_cpuhp;
407-
pci_xgene_online = rc;
408-
rc = cpuhp_setup_state(CPUHP_PCI_XGENE_DEAD, "pci/xgene:dead", NULL,
409-
xgene_msi_hwirq_free);
379+
rc = xgene_msi_handler_setup(pdev);
410380
if (rc)
411-
goto err_cpuhp;
381+
goto error;
412382

413383
dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n");
414384

415385
return 0;
416-
417-
err_cpuhp:
418-
dev_err(&pdev->dev, "failed to add CPU MSI notifier\n");
419386
error:
420387
xgene_msi_remove(pdev);
421388
return rc;

0 commit comments

Comments
 (0)