Skip to content

Commit 0d94ded

Browse files
author
Marc Zyngier
committed
irqchip/gic-v3: Add redistributor iterator
In order to discover the VLPI properties, we need to iterate over the redistributor regions. As we already have code that does this, let's factor it out and make it slightly more generic. Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent 0abce64 commit 0d94ded

File tree

1 file changed

+47
-22
lines changed

1 file changed

+47
-22
lines changed

drivers/irqchip/irq-gic-v3.c

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -421,24 +421,14 @@ static void __init gic_dist_init(void)
421421
gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
422422
}
423423

424-
static int gic_populate_rdist(void)
424+
static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
425425
{
426-
unsigned long mpidr = cpu_logical_map(smp_processor_id());
427-
u64 typer;
428-
u32 aff;
426+
int ret = -ENODEV;
429427
int i;
430428

431-
/*
432-
* Convert affinity to a 32bit value that can be matched to
433-
* GICR_TYPER bits [63:32].
434-
*/
435-
aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
436-
MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
437-
MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
438-
MPIDR_AFFINITY_LEVEL(mpidr, 0));
439-
440429
for (i = 0; i < gic_data.nr_redist_regions; i++) {
441430
void __iomem *ptr = gic_data.redist_regions[i].redist_base;
431+
u64 typer;
442432
u32 reg;
443433

444434
reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
@@ -450,15 +440,9 @@ static int gic_populate_rdist(void)
450440

451441
do {
452442
typer = gic_read_typer(ptr + GICR_TYPER);
453-
if ((typer >> 32) == aff) {
454-
u64 offset = ptr - gic_data.redist_regions[i].redist_base;
455-
gic_data_rdist_rd_base() = ptr;
456-
gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
457-
pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
458-
smp_processor_id(), mpidr, i,
459-
&gic_data_rdist()->phys_base);
443+
ret = fn(gic_data.redist_regions + i, ptr);
444+
if (!ret)
460445
return 0;
461-
}
462446

463447
if (gic_data.redist_regions[i].single_redist)
464448
break;
@@ -473,9 +457,50 @@ static int gic_populate_rdist(void)
473457
} while (!(typer & GICR_TYPER_LAST));
474458
}
475459

460+
return ret ? -ENODEV : 0;
461+
}
462+
463+
static int __gic_populate_rdist(struct redist_region *region, void __iomem *ptr)
464+
{
465+
unsigned long mpidr = cpu_logical_map(smp_processor_id());
466+
u64 typer;
467+
u32 aff;
468+
469+
/*
470+
* Convert affinity to a 32bit value that can be matched to
471+
* GICR_TYPER bits [63:32].
472+
*/
473+
aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
474+
MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
475+
MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
476+
MPIDR_AFFINITY_LEVEL(mpidr, 0));
477+
478+
typer = gic_read_typer(ptr + GICR_TYPER);
479+
if ((typer >> 32) == aff) {
480+
u64 offset = ptr - region->redist_base;
481+
gic_data_rdist_rd_base() = ptr;
482+
gic_data_rdist()->phys_base = region->phys_base + offset;
483+
484+
pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
485+
smp_processor_id(), mpidr,
486+
(int)(region - gic_data.redist_regions),
487+
&gic_data_rdist()->phys_base);
488+
return 0;
489+
}
490+
491+
/* Try next one */
492+
return 1;
493+
}
494+
495+
static int gic_populate_rdist(void)
496+
{
497+
if (gic_iterate_rdists(__gic_populate_rdist) == 0)
498+
return 0;
499+
476500
/* We couldn't even deal with ourselves... */
477501
WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n",
478-
smp_processor_id(), mpidr);
502+
smp_processor_id(),
503+
(unsigned long)cpu_logical_map(smp_processor_id()));
479504
return -ENODEV;
480505
}
481506

0 commit comments

Comments
 (0)