aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Basehore <dbasehore@chromium.org>2018-03-01 00:48:20 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2018-03-14 07:11:30 -0400
commit920181ce84692653094d9a3e04e05c06177edf5d (patch)
tree85db8dd675eff79c7e70886cb2798271a5cb2de5
parentdba0bc7b76dcf80f82f5a7542605d4abc52808f2 (diff)
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>
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c86
1 files changed, 48 insertions, 38 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 06682c33acba..2c9006726450 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1942,52 +1942,53 @@ static void its_cpu_init_lpis(void)
1942 dsb(sy); 1942 dsb(sy);
1943} 1943}
1944 1944
1945static void its_cpu_init_collection(void) 1945static void its_cpu_init_collection(struct its_node *its)
1946{ 1946{
1947 struct its_node *its; 1947 int cpu = smp_processor_id();
1948 int cpu; 1948 u64 target;
1949
1950 spin_lock(&its_lock);
1951 cpu = smp_processor_id();
1952
1953 list_for_each_entry(its, &its_nodes, entry) {
1954 u64 target;
1955 1949
1956 /* avoid cross node collections and its mapping */ 1950 /* avoid cross node collections and its mapping */
1957 if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) { 1951 if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
1958 struct device_node *cpu_node; 1952 struct device_node *cpu_node;
1959 1953
1960 cpu_node = of_get_cpu_node(cpu, NULL); 1954 cpu_node = of_get_cpu_node(cpu, NULL);
1961 if (its->numa_node != NUMA_NO_NODE && 1955 if (its->numa_node != NUMA_NO_NODE &&
1962 its->numa_node != of_node_to_nid(cpu_node)) 1956 its->numa_node != of_node_to_nid(cpu_node))
1963 continue; 1957 return;
1964 } 1958 }
1965 1959
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) {
1966 /* 1965 /*
1967 * We now have to bind each collection to its target 1966 * This ITS wants the physical address of the
1968 * redistributor. 1967 * redistributor.
1969 */ 1968 */
1970 if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) { 1969 target = gic_data_rdist()->phys_base;
1971 /* 1970 } else {
1972 * This ITS wants the physical address of the 1971 /* This ITS wants a linear CPU number. */
1973 * redistributor. 1972 target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
1974 */ 1973 target = GICR_TYPER_CPU_NUMBER(target) << 16;
1975 target = gic_data_rdist()->phys_base; 1974 }
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 }
1983 1975
1984 /* Perform collection mapping */ 1976 /* Perform collection mapping */
1985 its->collections[cpu].target_address = target; 1977 its->collections[cpu].target_address = target;
1986 its->collections[cpu].col_id = cpu; 1978 its->collections[cpu].col_id = cpu;
1987 1979
1988 its_send_mapc(its, &its->collections[cpu], 1); 1980 its_send_mapc(its, &its->collections[cpu], 1);
1989 its_send_invall(its, &its->collections[cpu]); 1981 its_send_invall(its, &its->collections[cpu]);
1990 } 1982}
1983
1984static 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);
1991 1992
1992 spin_unlock(&its_lock); 1993 spin_unlock(&its_lock);
1993} 1994}
@@ -3135,6 +3136,15 @@ static void its_restore_enable(void)
3135 its_write_baser(its, baser, baser->val); 3136 its_write_baser(its, baser, baser->val);
3136 } 3137 }
3137 writel_relaxed(its->ctlr_save, base + GITS_CTLR); 3138 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);
3138 } 3148 }
3139 spin_unlock(&its_lock); 3149 spin_unlock(&its_lock);
3140} 3150}
@@ -3401,7 +3411,7 @@ int its_cpu_init(void)
3401 return -ENXIO; 3411 return -ENXIO;
3402 } 3412 }
3403 its_cpu_init_lpis(); 3413 its_cpu_init_lpis();
3404 its_cpu_init_collection(); 3414 its_cpu_init_collections();
3405 } 3415 }
3406 3416
3407 return 0; 3417 return 0;