Skip to content

Commit 920181c

Browse files
dbasehoreMarc Zyngier
authored andcommitted
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>
1 parent dba0bc7 commit 920181c

File tree

1 file changed

+48
-38
lines changed

1 file changed

+48
-38
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,52 +1942,53 @@ static void its_cpu_init_lpis(void)
19421942
dsb(sy);
19431943
}
19441944

1945-
static void its_cpu_init_collection(void)
1945+
static void its_cpu_init_collection(struct its_node *its)
19461946
{
1947-
struct its_node *its;
1948-
int cpu;
1949-
1950-
spin_lock(&its_lock);
1951-
cpu = smp_processor_id();
1952-
1953-
list_for_each_entry(its, &its_nodes, entry) {
1954-
u64 target;
1947+
int cpu = smp_processor_id();
1948+
u64 target;
19551949

1956-
/* avoid cross node collections and its mapping */
1957-
if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
1958-
struct device_node *cpu_node;
1950+
/* avoid cross node collections and its mapping */
1951+
if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
1952+
struct device_node *cpu_node;
19591953

1960-
cpu_node = of_get_cpu_node(cpu, NULL);
1961-
if (its->numa_node != NUMA_NO_NODE &&
1962-
its->numa_node != of_node_to_nid(cpu_node))
1963-
continue;
1964-
}
1954+
cpu_node = of_get_cpu_node(cpu, NULL);
1955+
if (its->numa_node != NUMA_NO_NODE &&
1956+
its->numa_node != of_node_to_nid(cpu_node))
1957+
return;
1958+
}
19651959

1960+
/*
1961+
* We now have to bind each collection to its target
1962+
* redistributor.
1963+
*/
1964+
if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
19661965
/*
1967-
* We now have to bind each collection to its target
1966+
* This ITS wants the physical address of the
19681967
* redistributor.
19691968
*/
1970-
if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
1971-
/*
1972-
* This ITS wants the physical address of the
1973-
* redistributor.
1974-
*/
1975-
target = gic_data_rdist()->phys_base;
1976-
} else {
1977-
/*
1978-
* This ITS wants a linear CPU number.
1979-
*/
1980-
target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
1981-
target = GICR_TYPER_CPU_NUMBER(target) << 16;
1982-
}
1969+
target = gic_data_rdist()->phys_base;
1970+
} else {
1971+
/* This ITS wants a linear CPU number. */
1972+
target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
1973+
target = GICR_TYPER_CPU_NUMBER(target) << 16;
1974+
}
19831975

1984-
/* Perform collection mapping */
1985-
its->collections[cpu].target_address = target;
1986-
its->collections[cpu].col_id = cpu;
1976+
/* Perform collection mapping */
1977+
its->collections[cpu].target_address = target;
1978+
its->collections[cpu].col_id = cpu;
19871979

1988-
its_send_mapc(its, &its->collections[cpu], 1);
1989-
its_send_invall(its, &its->collections[cpu]);
1990-
}
1980+
its_send_mapc(its, &its->collections[cpu], 1);
1981+
its_send_invall(its, &its->collections[cpu]);
1982+
}
1983+
1984+
static void its_cpu_init_collections(void)
1985+
{
1986+
struct its_node *its;
1987+
1988+
spin_lock(&its_lock);
1989+
1990+
list_for_each_entry(its, &its_nodes, entry)
1991+
its_cpu_init_collection(its);
19911992

19921993
spin_unlock(&its_lock);
19931994
}
@@ -3135,6 +3136,15 @@ static void its_restore_enable(void)
31353136
its_write_baser(its, baser, baser->val);
31363137
}
31373138
writel_relaxed(its->ctlr_save, base + GITS_CTLR);
3139+
3140+
/*
3141+
* Reinit the collection if it's stored in the ITS. This is
3142+
* indicated by the col_id being less than the HCC field.
3143+
* CID < HCC as specified in the GIC v3 Documentation.
3144+
*/
3145+
if (its->collections[smp_processor_id()].col_id <
3146+
GITS_TYPER_HCC(gic_read_typer(base + GITS_TYPER)))
3147+
its_cpu_init_collection(its);
31383148
}
31393149
spin_unlock(&its_lock);
31403150
}
@@ -3401,7 +3411,7 @@ int its_cpu_init(void)
34013411
return -ENXIO;
34023412
}
34033413
its_cpu_init_lpis();
3404-
its_cpu_init_collection();
3414+
its_cpu_init_collections();
34053415
}
34063416

34073417
return 0;

0 commit comments

Comments
 (0)