There is a variant of MT7621 which contains only one CPU core instead of 2. This is not reflected in the config register, so the kernel detects more physical cores, which leads to a hang on SMP bringup. Add a hack to detect missing cores. Signed-off-by: Felix Fietkau --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -43,6 +43,11 @@ static unsigned core_vpe_count(unsigned return mips_cps_numvps(cluster, core); } +bool __weak plat_cpu_core_present(int core) +{ + return true; +} + static void __init cps_smp_setup(void) { unsigned int nclusters, ncores, nvpes, core_vpes; @@ -60,6 +65,8 @@ static void __init cps_smp_setup(void) ncores = mips_cps_numcores(cl); for (c = 0; c < ncores; c++) { + if (!plat_cpu_core_present(c)) + continue; core_vpes = core_vpe_count(cl, c); if (c > 0) --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -160,6 +161,20 @@ void __init ralink_of_remap(void) panic("Failed to remap core resources"); } +bool plat_cpu_core_present(int core) +{ + struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); + + if (!core) + return true; + launch += core * 2; /* 2 VPEs per core */ + if (!(launch->flags & LAUNCH_FREADY)) + return false; + if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE)) + return false; + return true; +} + void prom_soc_init(struct ralink_soc_info *soc_info) { void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);