--- /dev/null
+Index: linux-4.4.74/arch/mips/include/asm/smp.h
+===================================================================
+--- linux-4.4.74.orig/arch/mips/include/asm/smp.h
++++ linux-4.4.74/arch/mips/include/asm/smp.h
+@@ -16,12 +16,14 @@
+ #include <linux/smp.h>
+ #include <linux/threads.h>
+ #include <linux/cpumask.h>
++#include <linux/cache.h>
+
+ #include <linux/atomic.h>
+ #include <asm/smp-ops.h>
++#include <asm/percpu.h>
+
+ extern int smp_num_siblings;
+-extern cpumask_t cpu_sibling_map[];
++DECLARE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
+ extern cpumask_t cpu_core_map[];
+ extern cpumask_t cpu_foreign_map;
+
+Index: linux-4.4.74/arch/mips/kernel/proc.c
+===================================================================
+--- linux-4.4.74.orig/arch/mips/kernel/proc.c
++++ linux-4.4.74/arch/mips/kernel/proc.c
+@@ -134,6 +134,14 @@ static int show_cpuinfo(struct seq_file
+ seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
+ seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
+
++#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
++ if (cpu_has_mipsmt) {
++ seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
++#if defined(CONFIG_MIPS_MT_SMTC)
++ seq_printf(m, "TC\t\t\t: %d\n", cpu_data[n].tc_id);
++#endif
++ }
++#endif
+ sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+ cpu_has_vce ? "%u" : "not available");
+ seq_printf(m, fmt, 'D', vced_count);
+Index: linux-4.4.74/arch/mips/kernel/smp-cmp.c
+===================================================================
+--- linux-4.4.74.orig/arch/mips/kernel/smp-cmp.c
++++ linux-4.4.74/arch/mips/kernel/smp-cmp.c
+@@ -43,9 +43,19 @@ static void cmp_init_secondary(void)
+ {
+ struct cpuinfo_mips *c __maybe_unused = ¤t_cpu_data;
+
++#ifdef CONFIG_SOC_MT7621
++ if(cpu_has_veic) {
++ change_c0_status(ST0_IM, 0);
++ } else {
++ change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
++ }
++#else
+ /* Assume GIC is present */
+ change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 |
+ STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
++#endif
++
++ c->core = (read_c0_ebase() & 0x3ff) >> (fls(smp_num_siblings)-1);
+
+ /* Enable per-cpu interrupts: platform specific */
+
+Index: linux-4.4.74/arch/mips/kernel/smp.c
+===================================================================
+--- linux-4.4.74.orig/arch/mips/kernel/smp.c
++++ linux-4.4.74/arch/mips/kernel/smp.c
+@@ -57,8 +57,8 @@ int smp_num_siblings = 1;
+ EXPORT_SYMBOL(smp_num_siblings);
+
+ /* representing the TCs (or siblings in Intel speak) of each logical CPU */
+-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
+-EXPORT_SYMBOL(cpu_sibling_map);
++DEFINE_PER_CPU_SHARED_ALIGNED(struct cpumask, cpu_sibling_map);
++EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
+
+ /* representing the core map of multi-core chips of each logical CPU */
+ cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
+@@ -89,12 +89,13 @@ static inline void set_cpu_sibling_map(i
+ for_each_cpu(i, &cpu_sibling_setup_map) {
+ if (cpu_data[cpu].package == cpu_data[i].package &&
+ cpu_data[cpu].core == cpu_data[i].core) {
+- cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
+- cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
++ cpumask_set_cpu(i, &per_cpu(cpu_sibling_map, cpu));
++ cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_map, i));
++
+ }
+ }
+ } else
+- cpumask_set_cpu(cpu, &cpu_sibling_map[cpu]);
++ cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_map, cpu));
+ }
+
+ static inline void set_cpu_core_map(int cpu)
+Index: linux-4.4.74/arch/mips/ralink/mt7621.c
+===================================================================
+--- linux-4.4.74.orig/arch/mips/ralink/mt7621.c
++++ linux-4.4.74/arch/mips/ralink/mt7621.c
+@@ -21,6 +21,7 @@
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/mt7621.h>
+ #include <asm/mips-boards/launch.h>
++#include <asm/delay.h>
+
+ #include <pinmux.h>
+
+@@ -178,6 +179,58 @@ bool plat_cpu_core_present(int core)
+ return true;
+ }
+
++#define LPS_PREC 8
++/*
++* Re-calibration lpj(loop-per-jiffy).
++* (derived from kernel/calibrate.c)
++*/
++static int udelay_recal(void)
++{
++ unsigned int i, lpj = 0;
++ unsigned long ticks, loopbit;
++ int lps_precision = LPS_PREC;
++
++ lpj = (1<<12);
++
++ while ((lpj <<= 1) != 0) {
++ /* wait for "start of" clock tick */
++ ticks = jiffies;
++ while (ticks == jiffies)
++ /* nothing */;
++
++ /* Go .. */
++ ticks = jiffies;
++ __delay(lpj);
++ ticks = jiffies - ticks;
++ if (ticks)
++ break;
++ }
++
++ /*
++ * Do a binary approximation to get lpj set to
++ * equal one clock (up to lps_precision bits)
++ */
++ lpj >>= 1;
++ loopbit = lpj;
++ while (lps_precision-- && (loopbit >>= 1)) {
++ lpj |= loopbit;
++ ticks = jiffies;
++ while (ticks == jiffies)
++ /* nothing */;
++ ticks = jiffies;
++ __delay(lpj);
++ if (jiffies != ticks) /* longer than 1 tick */
++ lpj &= ~loopbit;
++ }
++ printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj);
++
++ for(i=0; i< NR_CPUS; i++)
++ cpu_data[i].udelay_val = lpj;
++
++ return 0;
++}
++device_initcall(udelay_recal);
++
+ void prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+Index: linux-4.4.74/arch/mips/include/asm/topology.h
+===================================================================
+--- linux-4.4.74.orig/arch/mips/include/asm/topology.h
++++ linux-4.4.74/arch/mips/include/asm/topology.h
+@@ -15,7 +15,7 @@
+ #define topology_physical_package_id(cpu) (cpu_data[cpu].package)
+ #define topology_core_id(cpu) (cpu_data[cpu].core)
+ #define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
+-#define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu])
++#define topology_sibling_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
+ #endif
+
+ #endif /* __ASM_TOPOLOGY_H */
+Index: linux-4.4.74/arch/mips/mm/c-r4k.c
+===================================================================
+--- linux-4.4.74.orig/arch/mips/mm/c-r4k.c
++++ linux-4.4.74/arch/mips/mm/c-r4k.c
+@@ -103,7 +103,7 @@ static inline void r4k_on_each_cpu(unsig
+
+ /* exclude sibling CPUs */
+ cpumask_andnot(&mask, &cpu_foreign_map,
+- &cpu_sibling_map[smp_processor_id()]);
++ &per_cpu(cpu_sibling_map, smp_processor_id()));
+ smp_call_function_many(&mask, func, info, 1);
+ }
+ #endif