diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 3ed853b8a8c8..0f9d6c598c51 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -48,6 +48,9 @@ enum sbi_ext_base_fid { SBI_EXT_BASE_GET_MVENDORID, SBI_EXT_BASE_GET_MARCHID, SBI_EXT_BASE_GET_MIMPID, +#if defined(CONFIG_SOC_SPACEMIT_K1PRO) || defined(CONFIG_SOC_SPACEMIT_K1X) + SBI_EXT_BASE_FLUSH_CACHE_ALL, +#endif }; enum sbi_ext_time_fid { diff --git a/arch/riscv/kernel/cpu-hotplug.c b/arch/riscv/kernel/cpu-hotplug.c index 6b710ef9d9ae..3fccf16f2b82 100644 --- a/arch/riscv/kernel/cpu-hotplug.c +++ b/arch/riscv/kernel/cpu-hotplug.c @@ -75,8 +75,14 @@ void __noreturn arch_cpu_idle_dead(void) { idle_task_exit(); +#if defined(CONFIG_SOC_SPACEMIT_K1PRO) || defined(CONFIG_SOC_SPACEMIT_K1X) + sbi_flush_local_dcache_all(); +#endif cpuhp_ap_report_dead(); +#if defined(CONFIG_SOC_SPACEMIT_K1PRO) || defined(CONFIG_SOC_SPACEMIT_K1X) + sbi_flush_local_dcache_all(); +#endif cpu_ops[smp_processor_id()]->cpu_stop(); /* It should never reach here */ BUG(); diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 5a62ed1da453..dfe569767ad0 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -460,6 +460,15 @@ int sbi_remote_hfence_vvma(const struct cpumask *cpu_mask, } EXPORT_SYMBOL(sbi_remote_hfence_vvma); +#if defined(CONFIG_SOC_SPACEMIT_K1PRO) || defined(CONFIG_SOC_SPACEMIT_K1X) +void sbi_flush_local_dcache_all(void) +{ + sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_FLUSH_CACHE_ALL, 0, + 0, 0, 0, 0, 0); +} +EXPORT_SYMBOL(sbi_flush_local_dcache_all); +#endif + /** * sbi_remote_hfence_vvma_asid() - Execute HFENCE.VVMA instructions on given * remote harts for current guest virtual address range belonging to a specific diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index da3071b387eb..7830061f5d32 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -144,6 +144,13 @@ static int __init riscv_timer_init_common(void) return -ENODEV; } +#ifdef CONFIG_SOC_SPACEMIT + if (riscv_isa_extension_available(NULL, SSTC)) { + pr_info("Timer interrupt in S-mode is available via sstc extension\n"); + static_branch_enable(&riscv_sstc_available); + } +#endif + error = clocksource_register_hz(&riscv_clocksource, riscv_timebase); if (error) { pr_err("RISCV timer registration failed [%d]\n", error); @@ -160,10 +167,12 @@ static int __init riscv_timer_init_common(void) return error; } +#ifndef CONFIG_SOC_SPACEMIT if (riscv_isa_extension_available(NULL, SSTC)) { pr_info("Timer interrupt in S-mode is available via sstc extension\n"); static_branch_enable(&riscv_sstc_available); } +#endif error = cpuhp_setup_state(CPUHP_AP_RISCV_TIMER_STARTING, "clockevents/riscv/timer:starting",