Skip to content

Commit

Permalink
irqchip/apple-aic: Parse FIQ affinities from device-tree
Browse files Browse the repository at this point in the history
In order to be able to tell the core IRQ code about the affinity
of the PMU interrupt in later patches, parse the affinities kindly
provided in the device-tree.

Signed-off-by: Marc Zyngier <maz@kernel.org>
  • Loading branch information
Marc Zyngier committed Feb 7, 2022
1 parent dba07ad commit a5e8801
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions drivers/irqchip/irq-apple-aic.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ struct aic_irq_chip {
void __iomem *base;
struct irq_domain *hw_domain;
struct irq_domain *ipi_domain;
struct {
cpumask_t aff;
} *fiq_aff[AIC_NR_FIQ];
int nr_hw;
};

Expand Down Expand Up @@ -793,12 +796,50 @@ static struct gic_kvm_info vgic_info __initdata = {
.no_hw_deactivation = true,
};

static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff)
{
int i, n;
u32 fiq;

if (of_property_read_u32(aff, "apple,fiq-index", &fiq) ||
WARN_ON(fiq >= AIC_NR_FIQ) || ic->fiq_aff[fiq])
return;

n = of_property_count_elems_of_size(aff, "cpus", sizeof(u32));
if (WARN_ON(n < 0))
return;

ic->fiq_aff[fiq] = kzalloc(sizeof(ic->fiq_aff[fiq]), GFP_KERNEL);
if (!ic->fiq_aff[fiq])
return;

for (i = 0; i < n; i++) {
struct device_node *cpu_node;
u32 cpu_phandle;
int cpu;

if (of_property_read_u32_index(aff, "cpus", i, &cpu_phandle))
continue;

cpu_node = of_find_node_by_phandle(cpu_phandle);
if (WARN_ON(!cpu_node))
continue;

cpu = of_cpu_node_to_id(cpu_node);
if (WARN_ON(cpu < 0))
continue;

cpumask_set_cpu(cpu, &ic->fiq_aff[fiq]->aff);
}
}

static int __init aic_of_ic_init(struct device_node *node, struct device_node *parent)
{
int i;
void __iomem *regs;
u32 info;
struct aic_irq_chip *irqc;
struct device_node *affs;

regs = of_iomap(node, 0);
if (WARN_ON(!regs))
Expand Down Expand Up @@ -832,6 +873,14 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
return -ENODEV;
}

affs = of_get_child_by_name(node, "affinities");
if (affs) {
struct device_node *chld;

for_each_child_of_node(affs, chld)
build_fiq_affinity(irqc, chld);
}

set_handle_irq(aic_handle_irq);
set_handle_fiq(aic_handle_fiq);

Expand Down

0 comments on commit a5e8801

Please sign in to comment.