Attempt to detect if the hardware is UP hardware, and use the optional UP specific processors functions in struct proc_info_list if available. Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx> --- arch/arm/include/asm/procinfo.h | 6 +++++ arch/arm/include/asm/smp_plat.h | 9 ++++++++ arch/arm/kernel/setup.c | 45 +++++++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 20 ++++++++++------- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/procinfo.h b/arch/arm/include/asm/procinfo.h index ca52e58..962d01e 100644 --- a/arch/arm/include/asm/procinfo.h +++ b/arch/arm/include/asm/procinfo.h @@ -40,6 +40,12 @@ struct proc_info_list { struct cpu_tlb_fns *tlb; struct cpu_user_fns *user; struct cpu_cache_fns *cache; + +#ifdef CONFIG_SMP_ON_UP + struct processor *proc_up; + struct cpu_tlb_fns *tlb_up; + struct cpu_cache_fns *cache_up; +#endif }; #else /* __KERNEL__ */ diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index e621530..1c2f587 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h @@ -18,4 +18,13 @@ static inline int cache_ops_need_broadcast(void) return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; } +#ifdef CONFIG_SMP_ON_UP +extern int smp_on_up(void); +#else +static inline int smp_on_up(void) +{ + return 0; +} +#endif + #endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d5231ae..5f3606c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -289,6 +289,50 @@ static void __init feat_v6_fixup(void) elf_hwcap &= ~HWCAP_TLS; } +#ifdef CONFIG_SMP_ON_UP + +static int _smp_on_up; + +int smp_on_up(void) +{ + return _smp_on_up; +} + +static void __init smp_on_up_fixup(struct proc_info_list *list) +{ + int id; + + id = read_cpuid_id() & 0xff0f0000; + if ((id == 0x41070000) || (id == 0x410f0000)) { + int mpidr; + + asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (mpidr)); + mpidr >>= 30; + + /* SMP hardware? */ + if (!((mpidr == 0) || (mpidr == 3))) + return; + } + + _smp_on_up = 1; + + pr_info("CPU: SMP kernel on UP hardware\n"); + + if (list->proc_up) + processor = *list->proc_up; + + if (list->tlb_up) + cpu_tlb = *list->tlb_up; + + if (list->cache_up) + cpu_cache = *list->cache_up; +} +#else +static inline void smp_on_up_fixup(struct proc_info_list *list) +{ +} +#endif + static void __init setup_processor(void) { struct proc_info_list *list; @@ -331,6 +375,7 @@ static void __init setup_processor(void) elf_hwcap &= ~HWCAP_THUMB; #endif + smp_on_up_fixup(list); feat_v6_fixup(); cacheid_init(); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6e1c4f6..f320901 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -430,15 +430,17 @@ static void __init build_mem_type_table(void) /* * Mark memory with the "shared" attribute for SMP systems */ - user_pgprot |= L_PTE_SHARED; - kern_pgprot |= L_PTE_SHARED; - vecs_pgprot |= L_PTE_SHARED; - mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; - mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; - mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; - mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; + if (!smp_on_up()) { + user_pgprot |= L_PTE_SHARED; + kern_pgprot |= L_PTE_SHARED; + vecs_pgprot |= L_PTE_SHARED; + mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; + mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; + } #endif } -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html