summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-07-27 10:40:13 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2018-10-02 05:37:34 -0400
commitc440a9d9d113b9b3cd99bb5096c4aa47d515e463 (patch)
treee95fc2542cf1be81d3ebaa7b7ad1362f37509626 /drivers/irqchip
parente1a2e2010ba9d3c765b2e37a7ae8b332564716f1 (diff)
irqchip/gic-v3-its: Allow use of pre-programmed LPI tables
In order to cope with kexec and GICv3, let's try and spot when we're booting with LPIs already enabled, and the tables already programmed into the redistributors. This code is currently guarded by a predicate that is always false, meaning this is not functionnal just yet. Reviewed-by: Julien Thierry <julien.thierry@arm.com> Tested-by: Jeremy Linton <jeremy.linton@arm.com> Tested-by: Bhupesh Sharma <bhsharma@redhat.com> Tested-by: Lei Zhang <zhang.lei@jp.fujitsu.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 9f26445eee4a..6a9066411cbc 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -52,6 +52,7 @@
52#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3) 52#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3)
53 53
54#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) 54#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
55#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
55 56
56static u32 lpi_id_bits; 57static u32 lpi_id_bits;
57 58
@@ -1628,18 +1629,32 @@ static void its_free_prop_table(struct page *prop_page)
1628 1629
1629static int __init its_setup_lpi_prop_table(void) 1630static int __init its_setup_lpi_prop_table(void)
1630{ 1631{
1631 struct page *page; 1632 if (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) {
1633 u64 val;
1632 1634
1633 lpi_id_bits = min_t(u32, GICD_TYPER_ID_BITS(gic_rdists->gicd_typer), 1635 val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
1634 ITS_MAX_LPI_NRBITS); 1636 lpi_id_bits = (val & GICR_PROPBASER_IDBITS_MASK) + 1;
1635 page = its_allocate_prop_table(GFP_NOWAIT);
1636 if (!page) {
1637 pr_err("Failed to allocate PROPBASE\n");
1638 return -ENOMEM;
1639 }
1640 1637
1641 gic_rdists->prop_table_pa = page_to_phys(page); 1638 gic_rdists->prop_table_pa = val & GENMASK_ULL(51, 12);
1642 gic_rdists->prop_table_va = page_address(page); 1639 gic_rdists->prop_table_va = memremap(gic_rdists->prop_table_pa,
1640 LPI_PROPBASE_SZ,
1641 MEMREMAP_WB);
1642 gic_reset_prop_table(gic_rdists->prop_table_va);
1643 } else {
1644 struct page *page;
1645
1646 lpi_id_bits = min_t(u32,
1647 GICD_TYPER_ID_BITS(gic_rdists->gicd_typer),
1648 ITS_MAX_LPI_NRBITS);
1649 page = its_allocate_prop_table(GFP_NOWAIT);
1650 if (!page) {
1651 pr_err("Failed to allocate PROPBASE\n");
1652 return -ENOMEM;
1653 }
1654
1655 gic_rdists->prop_table_pa = page_to_phys(page);
1656 gic_rdists->prop_table_va = page_address(page);
1657 }
1643 1658
1644 pr_info("GICv3: using LPI property table @%pa\n", 1659 pr_info("GICv3: using LPI property table @%pa\n",
1645 &gic_rdists->prop_table_pa); 1660 &gic_rdists->prop_table_pa);
@@ -1948,10 +1963,27 @@ static void its_free_pending_table(struct page *pt)
1948 free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ)); 1963 free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ));
1949} 1964}
1950 1965
1966static bool enabled_lpis_allowed(void)
1967{
1968 return false;
1969}
1970
1951static int __init allocate_lpi_tables(void) 1971static int __init allocate_lpi_tables(void)
1952{ 1972{
1973 u64 val;
1953 int err, cpu; 1974 int err, cpu;
1954 1975
1976 /*
1977 * If LPIs are enabled while we run this from the boot CPU,
1978 * flag the RD tables as pre-allocated if the stars do align.
1979 */
1980 val = readl_relaxed(gic_data_rdist_rd_base() + GICR_CTLR);
1981 if ((val & GICR_CTLR_ENABLE_LPIS) && enabled_lpis_allowed()) {
1982 gic_rdists->flags |= (RDIST_FLAGS_RD_TABLES_PREALLOCATED |
1983 RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING);
1984 pr_info("GICv3: Using preallocated redistributor tables\n");
1985 }
1986
1955 err = its_setup_lpi_prop_table(); 1987 err = its_setup_lpi_prop_table();
1956 if (err) 1988 if (err)
1957 return err; 1989 return err;
@@ -1986,6 +2018,18 @@ static void its_cpu_init_lpis(void)
1986 if (gic_data_rdist()->lpi_enabled) 2018 if (gic_data_rdist()->lpi_enabled)
1987 return; 2019 return;
1988 2020
2021 val = readl_relaxed(rbase + GICR_CTLR);
2022 if ((gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) &&
2023 (val & GICR_CTLR_ENABLE_LPIS)) {
2024 paddr = gicr_read_pendbaser(rbase + GICR_PENDBASER);
2025 paddr &= GENMASK_ULL(51, 16);
2026
2027 its_free_pending_table(gic_data_rdist()->pend_page);
2028 gic_data_rdist()->pend_page = NULL;
2029
2030 goto out;
2031 }
2032
1989 pend_page = gic_data_rdist()->pend_page; 2033 pend_page = gic_data_rdist()->pend_page;
1990 paddr = page_to_phys(pend_page); 2034 paddr = page_to_phys(pend_page);
1991 2035
@@ -2040,9 +2084,11 @@ static void its_cpu_init_lpis(void)
2040 2084
2041 /* Make sure the GIC has seen the above */ 2085 /* Make sure the GIC has seen the above */
2042 dsb(sy); 2086 dsb(sy);
2087out:
2043 gic_data_rdist()->lpi_enabled = true; 2088 gic_data_rdist()->lpi_enabled = true;
2044 pr_info("GICv3: CPU%d: using LPI pending table @%pa\n", 2089 pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
2045 smp_processor_id(), 2090 smp_processor_id(),
2091 gic_data_rdist()->pend_page ? "allocated" : "reserved",
2046 &paddr); 2092 &paddr);
2047} 2093}
2048 2094
@@ -3535,8 +3581,11 @@ static int redist_disable_lpis(void)
3535 * If coming via a CPU hotplug event, we don't need to disable 3581 * If coming via a CPU hotplug event, we don't need to disable
3536 * LPIs before trying to re-enable them. They are already 3582 * LPIs before trying to re-enable them. They are already
3537 * configured and all is well in the world. 3583 * configured and all is well in the world.
3584 *
3585 * If running with preallocated tables, there is nothing to do.
3538 */ 3586 */
3539 if (gic_data_rdist()->lpi_enabled) 3587 if (gic_data_rdist()->lpi_enabled ||
3588 (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED))
3540 return 0; 3589 return 0;
3541 3590
3542 /* 3591 /*