irqchip/gic-v3-its: Add ability to resend MAPC on resume
This adds functionality to resend the MAPC command to an ITS node on resume. If the ITS is powered down during suspend and the collections are not backed by memory, the ITS will lose that state. This just sets up the known state for the collections after the ITS is restored. Signed-off-by: Derek Basehore <dbasehore@chromium.org> Reviewed-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
Родитель
dba0bc7b76
Коммит
920181ce84
|
@ -1942,53 +1942,54 @@ static void its_cpu_init_lpis(void)
|
|||
dsb(sy);
|
||||
}
|
||||
|
||||
static void its_cpu_init_collection(void)
|
||||
static void its_cpu_init_collection(struct its_node *its)
|
||||
{
|
||||
struct its_node *its;
|
||||
int cpu;
|
||||
int cpu = smp_processor_id();
|
||||
u64 target;
|
||||
|
||||
spin_lock(&its_lock);
|
||||
cpu = smp_processor_id();
|
||||
/* avoid cross node collections and its mapping */
|
||||
if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
|
||||
struct device_node *cpu_node;
|
||||
|
||||
list_for_each_entry(its, &its_nodes, entry) {
|
||||
u64 target;
|
||||
|
||||
/* avoid cross node collections and its mapping */
|
||||
if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
|
||||
struct device_node *cpu_node;
|
||||
|
||||
cpu_node = of_get_cpu_node(cpu, NULL);
|
||||
if (its->numa_node != NUMA_NO_NODE &&
|
||||
its->numa_node != of_node_to_nid(cpu_node))
|
||||
continue;
|
||||
}
|
||||
cpu_node = of_get_cpu_node(cpu, NULL);
|
||||
if (its->numa_node != NUMA_NO_NODE &&
|
||||
its->numa_node != of_node_to_nid(cpu_node))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We now have to bind each collection to its target
|
||||
* redistributor.
|
||||
*/
|
||||
if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
|
||||
/*
|
||||
* We now have to bind each collection to its target
|
||||
* This ITS wants the physical address of the
|
||||
* redistributor.
|
||||
*/
|
||||
if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
|
||||
/*
|
||||
* This ITS wants the physical address of the
|
||||
* redistributor.
|
||||
*/
|
||||
target = gic_data_rdist()->phys_base;
|
||||
} else {
|
||||
/*
|
||||
* This ITS wants a linear CPU number.
|
||||
*/
|
||||
target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
|
||||
target = GICR_TYPER_CPU_NUMBER(target) << 16;
|
||||
}
|
||||
|
||||
/* Perform collection mapping */
|
||||
its->collections[cpu].target_address = target;
|
||||
its->collections[cpu].col_id = cpu;
|
||||
|
||||
its_send_mapc(its, &its->collections[cpu], 1);
|
||||
its_send_invall(its, &its->collections[cpu]);
|
||||
target = gic_data_rdist()->phys_base;
|
||||
} else {
|
||||
/* This ITS wants a linear CPU number. */
|
||||
target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
|
||||
target = GICR_TYPER_CPU_NUMBER(target) << 16;
|
||||
}
|
||||
|
||||
/* Perform collection mapping */
|
||||
its->collections[cpu].target_address = target;
|
||||
its->collections[cpu].col_id = cpu;
|
||||
|
||||
its_send_mapc(its, &its->collections[cpu], 1);
|
||||
its_send_invall(its, &its->collections[cpu]);
|
||||
}
|
||||
|
||||
static void its_cpu_init_collections(void)
|
||||
{
|
||||
struct its_node *its;
|
||||
|
||||
spin_lock(&its_lock);
|
||||
|
||||
list_for_each_entry(its, &its_nodes, entry)
|
||||
its_cpu_init_collection(its);
|
||||
|
||||
spin_unlock(&its_lock);
|
||||
}
|
||||
|
||||
|
@ -3135,6 +3136,15 @@ static void its_restore_enable(void)
|
|||
its_write_baser(its, baser, baser->val);
|
||||
}
|
||||
writel_relaxed(its->ctlr_save, base + GITS_CTLR);
|
||||
|
||||
/*
|
||||
* Reinit the collection if it's stored in the ITS. This is
|
||||
* indicated by the col_id being less than the HCC field.
|
||||
* CID < HCC as specified in the GIC v3 Documentation.
|
||||
*/
|
||||
if (its->collections[smp_processor_id()].col_id <
|
||||
GITS_TYPER_HCC(gic_read_typer(base + GITS_TYPER)))
|
||||
its_cpu_init_collection(its);
|
||||
}
|
||||
spin_unlock(&its_lock);
|
||||
}
|
||||
|
@ -3401,7 +3411,7 @@ int its_cpu_init(void)
|
|||
return -ENXIO;
|
||||
}
|
||||
its_cpu_init_lpis();
|
||||
its_cpu_init_collection();
|
||||
its_cpu_init_collections();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче