From 4c835e22250b3af9c27766374c8da6da21314bcf Mon Sep 17 00:00:00 2001 From: Xin Hao Date: Thu, 22 Apr 2021 15:34:05 +0800 Subject: [PATCH 2914/2944] ck: irqchip:phytium-gic: Sync the latest code modify Here we keep the same codes of PHYTIUM ft2500 chip as Phytium Technology Co., Ltd. Signed-off-by: Xin Hao Reviewed-by: Baolin Wang --- .../gic_phytium_2500/irq-gic-phytium-2500-its.c | 86 ++++++++++++++-------- include/linux/irqchip/arm-gic-phytium-2500.h | 1 + 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/drivers/staging/gic_phytium_2500/irq-gic-phytium-2500-its.c b/drivers/staging/gic_phytium_2500/irq-gic-phytium-2500-its.c index 34647a4..d72bb95 100644 --- a/drivers/staging/gic_phytium_2500/irq-gic-phytium-2500-its.c +++ b/drivers/staging/gic_phytium_2500/irq-gic-phytium-2500-its.c @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include #include @@ -176,6 +175,7 @@ struct its_device { static DEFINE_IDA(its_vpeid_ida); #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) +#define gic_data_rdist_cpu(cpu) (per_cpu_ptr(gic_rdists->rdist, cpu)) #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K) @@ -451,6 +451,7 @@ static struct its_collection *its_build_mapti_cmd(struct its_node *its, col = dev_event_to_col(desc->its_mapti_cmd.dev, desc->its_mapti_cmd.event_id); + col->col_id = col->col_id % 64; its_encode_cmd(cmd, GITS_CMD_MAPTI); its_encode_devid(cmd, desc->its_mapti_cmd.dev->device_id); @@ -1658,7 +1659,7 @@ static void its_free_prop_table(struct page *prop_page) get_order(LPI_PROPBASE_SZ)); } -static int __init its_alloc_lpi_tables(void) +static int __init its_setup_lpi_prop_table(void) { phys_addr_t paddr; @@ -1981,30 +1982,47 @@ static void its_free_pending_table(struct page *pt) get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); } -static void its_cpu_init_lpis(void) +static int __init allocate_lpi_tables(void) { - void __iomem *rbase = gic_data_rdist_rd_base(); - struct page *pend_page; - u64 val, tmp; + int err, cpu; - /* If we didn't allocate the pending table yet, do it now */ - pend_page = gic_data_rdist()->pend_page; - if (!pend_page) { - phys_addr_t paddr; + err = its_setup_lpi_prop_table(); + if (err) + return err; + + /* + * We allocate all the pending tables anyway, as we may have a + * mix of RDs that have had LPIs enabled, and some that + * don't. We'll free the unused ones as each CPU comes online. + */ + for_each_possible_cpu(cpu) { + struct page *pend_page; pend_page = its_allocate_pending_table(GFP_NOWAIT); if (!pend_page) { - pr_err("Failed to allocate PENDBASE for CPU%d\n", - smp_processor_id()); - return; + pr_err("Failed to allocate PENDBASE for CPU%d\n", cpu); + return -ENOMEM; } - paddr = page_to_phys(pend_page); - pr_info("CPU%d: using LPI pending table @%pa\n", - smp_processor_id(), &paddr); - gic_data_rdist()->pend_page = pend_page; + gic_data_rdist_cpu(cpu)->pend_page = pend_page; } + return 0; +} + +static void its_cpu_init_lpis(void) +{ + void __iomem *rbase = gic_data_rdist_rd_base(); + struct page *pend_page; + phys_addr_t paddr; + u64 val, tmp; + + if (gic_data_rdist()->lpi_enabled) + return; + + pend_page = gic_data_rdist()->pend_page; + paddr = page_to_phys(pend_page); + /* set PROPBASE */ val = (page_to_phys(gic_rdists->prop_page) | GICR_PROPBASER_InnerShareable | @@ -2056,6 +2074,10 @@ static void its_cpu_init_lpis(void) /* Make sure the GIC has seen the above */ dsb(sy); + gic_data_rdist()->lpi_enabled = true; + pr_info("GICv3: CPU%d: using LPI pending table @%pa\n", + smp_processor_id(), + &paddr); } static void its_cpu_init_collection(struct its_node *its) @@ -2097,7 +2119,7 @@ static void its_cpu_init_collection(struct its_node *its) /* Perform collection mapping */ its->collections[cpu].target_address = target; - its->collections[cpu].col_id = cpu; + its->collections[cpu].col_id = cpu % 64; its_send_mapc(its, &its->collections[cpu], 1); its_send_invall(its, &its->collections[cpu]); @@ -2443,7 +2465,7 @@ static int its_cpumask_first(struct its_device *its_dev, skt = (cpu_logical_map(i) >> 16) & 0xff; if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) skt_cpu_cnt[skt]++; - else if (0xff != skt) + else if (skt != 0xff) pr_err("socket address: %d is out of range.", skt); } @@ -3567,16 +3589,6 @@ static int redist_disable_lpis(void) u64 timeout = USEC_PER_SEC; u64 val; - /* - * If coming via a CPU hotplug event, we don't need to disable - * LPIs before trying to re-enable them. They are already - * configured and all is well in the world. Detect this case - * by checking the allocation of the pending table for the - * current CPU. - */ - if (gic_data_rdist()->pend_page) - return 0; - if (!gic_rdists_supports_plpis()) { pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); return -ENXIO; @@ -3586,7 +3598,18 @@ static int redist_disable_lpis(void) if (!(val & GICR_CTLR_ENABLE_LPIS)) return 0; - pr_warn("CPU%d: Booted with LPIs enabled, memory probably corrupted\n", + /* + * If coming via a CPU hotplug event, we don't need to disable + * LPIs before trying to re-enable them. They are already + * configured and all is well in the world. + */ + if (gic_data_rdist()->lpi_enabled) + return 0; + + /* + * From that point on, we only try to do some damage control. + */ + pr_warn("GICv3: CPU%d: Booted with LPIs enabled, memory probably corrupted\n", smp_processor_id()); add_taint(TAINT_CRAP, LOCKDEP_STILL_OK); @@ -3842,7 +3865,8 @@ int __init phytium_its_init(struct fwnode_handle *handle, struct rdists *rdists, } gic_rdists = rdists; - err = its_alloc_lpi_tables(); + + err = allocate_lpi_tables(); if (err) return err; diff --git a/include/linux/irqchip/arm-gic-phytium-2500.h b/include/linux/irqchip/arm-gic-phytium-2500.h index 00f2178..17518fa 100644 --- a/include/linux/irqchip/arm-gic-phytium-2500.h +++ b/include/linux/irqchip/arm-gic-phytium-2500.h @@ -585,6 +585,7 @@ struct rdists { void __iomem *rd_base; struct page *pend_page; phys_addr_t phys_base; + bool lpi_enabled; } __percpu *rdist; struct page *prop_page; u64 flags; -- 1.8.3.1