mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
irqchip/gic-v3: Add FW info retrieval support
Plug the new .get_fwspec_info() callback into the GICv3 core driver, using some of the existing PPI affinity handling infrastructure. Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Will Deacon <will@kernel.org> Link: https://patch.msgid.link/20251020122944.3074811-6-maz@kernel.org
This commit is contained in:
committed by
Thomas Gleixner
parent
0d5daa938c
commit
68905ea65c
@@ -69,6 +69,8 @@ struct gic_chip_data {
|
||||
bool has_rss;
|
||||
unsigned int ppi_nr;
|
||||
struct partition_desc **ppi_descs;
|
||||
struct partition_affinity *parts;
|
||||
unsigned int nr_parts;
|
||||
};
|
||||
|
||||
#define T241_CHIPS_MAX 4
|
||||
@@ -1797,11 +1799,58 @@ static int gic_irq_domain_select(struct irq_domain *d,
|
||||
return d == partition_get_domain(gic_data.ppi_descs[ppi_idx]);
|
||||
}
|
||||
|
||||
static int gic_irq_get_fwspec_info(struct irq_fwspec *fwspec, struct irq_fwspec_info *info)
|
||||
{
|
||||
const struct cpumask *mask = NULL;
|
||||
|
||||
info->flags = 0;
|
||||
info->affinity = NULL;
|
||||
|
||||
/* ACPI is not capable of describing PPI affinity -- yet */
|
||||
if (!is_of_node(fwspec->fwnode))
|
||||
return 0;
|
||||
|
||||
/* If the specifier provides an affinity, use it */
|
||||
if (fwspec->param_count == 4 && fwspec->param[3]) {
|
||||
struct fwnode_handle *fw;
|
||||
|
||||
switch (fwspec->param[0]) {
|
||||
case 1: /* PPI */
|
||||
case 3: /* EPPI */
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
fw = of_fwnode_handle(of_find_node_by_phandle(fwspec->param[3]));
|
||||
if (!fw)
|
||||
return -ENOENT;
|
||||
|
||||
for (int i = 0; i < gic_data.nr_parts; i++) {
|
||||
if (gic_data.parts[i].partition_id == fw) {
|
||||
mask = &gic_data.parts[i].mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mask)
|
||||
return -ENOENT;
|
||||
} else {
|
||||
mask = cpu_possible_mask;
|
||||
}
|
||||
|
||||
info->affinity = mask;
|
||||
info->flags = IRQ_FWSPEC_INFO_AFFINITY_VALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops gic_irq_domain_ops = {
|
||||
.translate = gic_irq_domain_translate,
|
||||
.alloc = gic_irq_domain_alloc,
|
||||
.free = gic_irq_domain_free,
|
||||
.select = gic_irq_domain_select,
|
||||
.get_fwspec_info = gic_irq_get_fwspec_info,
|
||||
};
|
||||
|
||||
static int partition_domain_translate(struct irq_domain *d,
|
||||
@@ -1840,6 +1889,7 @@ static int partition_domain_translate(struct irq_domain *d,
|
||||
static const struct irq_domain_ops partition_domain_ops = {
|
||||
.translate = partition_domain_translate,
|
||||
.select = gic_irq_domain_select,
|
||||
.get_fwspec_info = gic_irq_get_fwspec_info,
|
||||
};
|
||||
|
||||
static bool gic_enable_quirk_msm8996(void *data)
|
||||
@@ -2232,6 +2282,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
|
||||
part_idx++;
|
||||
}
|
||||
|
||||
gic_data.parts = parts;
|
||||
gic_data.nr_parts = nr_parts;
|
||||
|
||||
for (i = 0; i < gic_data.ppi_nr; i++) {
|
||||
unsigned int irq;
|
||||
struct partition_desc *desc;
|
||||
|
||||
Reference in New Issue
Block a user