Commit 920181ce authored by Derek Basehore's avatar Derek Basehore Committed by Marc Zyngier

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: default avatarDerek Basehore <dbasehore@chromium.org>
Reviewed-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent dba0bc7b
...@@ -1942,15 +1942,9 @@ static void its_cpu_init_lpis(void) ...@@ -1942,15 +1942,9 @@ static void its_cpu_init_lpis(void)
dsb(sy); 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 = smp_processor_id();
int cpu;
spin_lock(&its_lock);
cpu = smp_processor_id();
list_for_each_entry(its, &its_nodes, entry) {
u64 target; u64 target;
/* avoid cross node collections and its mapping */ /* avoid cross node collections and its mapping */
...@@ -1960,7 +1954,7 @@ static void its_cpu_init_collection(void) ...@@ -1960,7 +1954,7 @@ static void its_cpu_init_collection(void)
cpu_node = of_get_cpu_node(cpu, NULL); cpu_node = of_get_cpu_node(cpu, NULL);
if (its->numa_node != NUMA_NO_NODE && if (its->numa_node != NUMA_NO_NODE &&
its->numa_node != of_node_to_nid(cpu_node)) its->numa_node != of_node_to_nid(cpu_node))
continue; return;
} }
/* /*
...@@ -1974,9 +1968,7 @@ static void its_cpu_init_collection(void) ...@@ -1974,9 +1968,7 @@ static void its_cpu_init_collection(void)
*/ */
target = gic_data_rdist()->phys_base; target = gic_data_rdist()->phys_base;
} else { } else {
/* /* This ITS wants a linear CPU number. */
* This ITS wants a linear CPU number.
*/
target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER); target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
target = GICR_TYPER_CPU_NUMBER(target) << 16; target = GICR_TYPER_CPU_NUMBER(target) << 16;
} }
...@@ -1987,7 +1979,16 @@ static void its_cpu_init_collection(void) ...@@ -1987,7 +1979,16 @@ static void its_cpu_init_collection(void)
its_send_mapc(its, &its->collections[cpu], 1); its_send_mapc(its, &its->collections[cpu], 1);
its_send_invall(its, &its->collections[cpu]); 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); spin_unlock(&its_lock);
} }
...@@ -3135,6 +3136,15 @@ static void its_restore_enable(void) ...@@ -3135,6 +3136,15 @@ static void its_restore_enable(void)
its_write_baser(its, baser, baser->val); its_write_baser(its, baser, baser->val);
} }
writel_relaxed(its->ctlr_save, base + GITS_CTLR); 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); spin_unlock(&its_lock);
} }
...@@ -3401,7 +3411,7 @@ int its_cpu_init(void) ...@@ -3401,7 +3411,7 @@ int its_cpu_init(void)
return -ENXIO; return -ENXIO;
} }
its_cpu_init_lpis(); its_cpu_init_lpis();
its_cpu_init_collection(); its_cpu_init_collections();
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment