aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/setup.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8a16ee5d8a95..84db893dedc2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -393,19 +393,34 @@ static void __init cpuid_init_hwcaps(void)
393 elf_hwcap |= HWCAP_LPAE; 393 elf_hwcap |= HWCAP_LPAE;
394} 394}
395 395
396static void __init feat_v6_fixup(void) 396static void __init elf_hwcap_fixup(void)
397{ 397{
398 int id = read_cpuid_id(); 398 unsigned id = read_cpuid_id();
399 399 unsigned sync_prim;
400 if ((id & 0xff0f0000) != 0x41070000)
401 return;
402 400
403 /* 401 /*
404 * HWCAP_TLS is available only on 1136 r1p0 and later, 402 * HWCAP_TLS is available only on 1136 r1p0 and later,
405 * see also kuser_get_tls_init. 403 * see also kuser_get_tls_init.
406 */ 404 */
407 if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) 405 if (read_cpuid_part() == ARM_CPU_PART_ARM1136 &&
406 ((id >> 20) & 3) == 0) {
408 elf_hwcap &= ~HWCAP_TLS; 407 elf_hwcap &= ~HWCAP_TLS;
408 return;
409 }
410
411 /* Verify if CPUID scheme is implemented */
412 if ((id & 0x000f0000) != 0x000f0000)
413 return;
414
415 /*
416 * If the CPU supports LDREX/STREX and LDREXB/STREXB,
417 * avoid advertising SWP; it may not be atomic with
418 * multiprocessing cores.
419 */
420 sync_prim = ((read_cpuid_ext(CPUID_EXT_ISAR3) >> 8) & 0xf0) |
421 ((read_cpuid_ext(CPUID_EXT_ISAR4) >> 20) & 0x0f);
422 if (sync_prim >= 0x13)
423 elf_hwcap &= ~HWCAP_SWP;
409} 424}
410 425
411/* 426/*
@@ -609,7 +624,7 @@ static void __init setup_processor(void)
609#endif 624#endif
610 erratum_a15_798181_init(); 625 erratum_a15_798181_init();
611 626
612 feat_v6_fixup(); 627 elf_hwcap_fixup();
613 628
614 cacheid_init(); 629 cacheid_init();
615 cpu_init(); 630 cpu_init();