diff options
| author | Markus Stockhausen | 2025-05-28 17:41:32 +0000 |
|---|---|---|
| committer | Robert Marko | 2025-06-11 20:27:22 +0000 |
| commit | e124859587143bff28440a1fbedef623c6b22735 (patch) | |
| tree | 7f9182a36bf9d36e9165e83e6866cd3acdf52d3f | |
| parent | 09440d9858762cb40f40a839926344ef7f1aab47 (diff) | |
| download | openwrt-e124859587143bff28440a1fbedef623c6b22735.tar.gz | |
realtek: 6.12: relocate R4K deactivation to late CPU init
To avoid unneeded interrupts the R4K timer is deactivated during
secondary cpu initialization. This is currently done during
phase init_secondary(). With the upgrade to 6.12 the kernel runs
a primary/secondary cpu timer/counter synchronization to verify the
proper setup in synchronise_count_slave(). That runs at a later
point in time and expects the secondary counter to be fully
functional. Finding a deactivated counter results in the following
messages:
WARNING: CPU: 1 PID: 0 at arch/mips/kernel/sync-r4k.c:99 check_counter_warp+0x220/0x254
Warning: zero counter calibration delta: 0 [max: 6500000]
Counter synchronization [CPU#0 -> CPU#1]:
Measured 278760029 cycles counter warp between CPUs
Relocate the deactivation to smp_finsh() at the end of the cpu
startup sequence. Additionally polish the startup code and remove
all unneeded parts.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
| -rw-r--r-- | target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c | 84 |
1 files changed, 43 insertions, 41 deletions
diff --git a/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c b/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c index f98fb5e93f..c2c4b09d1d 100644 --- a/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c +++ b/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c @@ -9,66 +9,69 @@ * */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/of_fdt.h> -#include <linux/libfdt.h> -#include <asm/bootinfo.h> -#include <asm/addrspace.h> -#include <asm/page.h> -#include <asm/cpu.h> #include <asm/fw/fw.h> +#include <asm/mips-cps.h> #include <asm/prom.h> #include <asm/smp-ops.h> -#include <asm/mips-cps.h> #include <mach-rtl83xx.h> -extern char arcs_cmdline[]; - struct rtl83xx_soc_info soc_info; const void *fdt; #ifdef CONFIG_MIPS_MT_SMP + extern const struct plat_smp_ops vsmp_smp_ops; -static struct plat_smp_ops rtl_smp_ops; +static struct plat_smp_ops rtlops; -static void rtl_init_secondary(void) +static void rtlsmp_init_secondary(void) { -#ifndef CONFIG_CEVT_R4K -/* - * These devices are low on resources. There might be the chance that CEVT_R4K - * is not enabled in kernel build. Nevertheless the timer and interrupt 7 might - * be active by default after startup of secondary VPE. With no registered - * handler that leads to continuous unhandeled interrupts. In this case disable - * counting (DC) in the core and confirm a pending interrupt. - */ - write_c0_cause(read_c0_cause() | CAUSEF_DC); - write_c0_compare(0); -#endif /* CONFIG_CEVT_R4K */ -/* - * Enable all CPU interrupts, as everything is managed by the external - * controller. TODO: Standard vsmp_init_secondary() has special treatment for - * Malta if external GIC is available. Maybe we need this too. - */ + /* + * Enable all CPU interrupts, as everything is managed by the external controller. + * TODO: Standard vsmp_init_secondary() has special treatment for Malta if external + * GIC is available. Maybe we need this too. + */ if (mips_gic_present()) pr_warn("%s: GIC present. Maybe interrupt enabling required.\n", __func__); else set_c0_status(ST0_IM); } -#endif /* CONFIG_MIPS_MT_SMP */ -const char *get_system_type(void) +static void rtlsmp_finish(void) { - return soc_info.name; + /* These devices are low on resources. There might be the chance that CEVT_R4K is + * not enabled in kernel build. Nevertheless the timer and interrupt 7 might be + * active by default after startup of secondary VPE. With no registered handler + * that leads to continuous unhandeled interrupts. In this case disable counting + * (DC) in the core and confirm a pending interrupt. + */ + if (!IS_ENABLED(CONFIG_CEVT_R4K)) { + write_c0_cause(read_c0_cause() | CAUSEF_DC); + write_c0_compare(0); + } + + local_irq_enable(); } -void __init prom_free_prom_memory(void) +static int rtlsmp_register(void) { + if (!cpu_has_mipsmt) + return 1; + + rtlops = vsmp_smp_ops; + rtlops.init_secondary = rtlsmp_init_secondary; + rtlops.smp_finish = rtlsmp_finish; + register_smp_ops(&rtlops); + return 0; } +#else /* !CONFIG_MIPS_MT_SMP */ + +#define rtlsmp_register() (1) + +#endif + void __init device_tree_init(void) { if (!fdt_check_header(&__appended_dtb)) { @@ -84,18 +87,17 @@ void __init device_tree_init(void) if (!register_cps_smp_ops()) return; -#ifdef CONFIG_MIPS_MT_SMP - if (cpu_has_mipsmt) { - rtl_smp_ops = vsmp_smp_ops; - rtl_smp_ops.init_secondary = rtl_init_secondary; - register_smp_ops(&rtl_smp_ops); + if (!rtlsmp_register()) return; - } -#endif register_up_smp_ops(); } +const char *get_system_type(void) +{ + return soc_info.name; +} + static void __init identify_rtl9302(void) { switch (sw_r32(RTL93XX_MODEL_NAME_INFO) & 0xfffffff0) { |