diff options
| -rw-r--r-- | arch/arm/mach-imx/headsmp.S | 12 | ||||
| -rw-r--r-- | arch/arm/mach-imx/platsmp.c | 14 |
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index 67b9c48dcafe..627f16f0e9d1 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S | |||
| @@ -18,8 +18,20 @@ | |||
| 18 | .section ".text.head", "ax" | 18 | .section ".text.head", "ax" |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_SMP | 20 | #ifdef CONFIG_SMP |
| 21 | diag_reg_offset: | ||
| 22 | .word g_diag_reg - . | ||
| 23 | |||
| 24 | .macro set_diag_reg | ||
| 25 | adr r0, diag_reg_offset | ||
| 26 | ldr r1, [r0] | ||
| 27 | add r1, r1, r0 @ r1 = physical &g_diag_reg | ||
| 28 | ldr r0, [r1] | ||
| 29 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | ||
| 30 | .endm | ||
| 31 | |||
| 21 | ENTRY(v7_secondary_startup) | 32 | ENTRY(v7_secondary_startup) |
| 22 | bl v7_invalidate_l1 | 33 | bl v7_invalidate_l1 |
| 34 | set_diag_reg | ||
| 23 | b secondary_startup | 35 | b secondary_startup |
| 24 | ENDPROC(v7_secondary_startup) | 36 | ENDPROC(v7_secondary_startup) |
| 25 | #endif | 37 | #endif |
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 4a69305db65e..c6e1ab544882 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
| 15 | #include <asm/cacheflush.h> | ||
| 15 | #include <asm/page.h> | 16 | #include <asm/page.h> |
| 16 | #include <asm/smp_scu.h> | 17 | #include <asm/smp_scu.h> |
| 17 | #include <asm/mach/map.h> | 18 | #include <asm/mach/map.h> |
| @@ -21,6 +22,7 @@ | |||
| 21 | 22 | ||
| 22 | #define SCU_STANDBY_ENABLE (1 << 5) | 23 | #define SCU_STANDBY_ENABLE (1 << 5) |
| 23 | 24 | ||
| 25 | u32 g_diag_reg; | ||
| 24 | static void __iomem *scu_base; | 26 | static void __iomem *scu_base; |
| 25 | 27 | ||
| 26 | static struct map_desc scu_io_desc __initdata = { | 28 | static struct map_desc scu_io_desc __initdata = { |
| @@ -80,6 +82,18 @@ void imx_smp_prepare(void) | |||
| 80 | static void __init imx_smp_prepare_cpus(unsigned int max_cpus) | 82 | static void __init imx_smp_prepare_cpus(unsigned int max_cpus) |
| 81 | { | 83 | { |
| 82 | imx_smp_prepare(); | 84 | imx_smp_prepare(); |
| 85 | |||
| 86 | /* | ||
| 87 | * The diagnostic register holds the errata bits. Mostly bootloader | ||
| 88 | * does not bring up secondary cores, so that when errata bits are set | ||
| 89 | * in bootloader, they are set only for boot cpu. But on a SMP | ||
| 90 | * configuration, it should be equally done on every single core. | ||
| 91 | * Read the register from boot cpu here, and will replicate it into | ||
| 92 | * secondary cores when booting them. | ||
| 93 | */ | ||
| 94 | asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc"); | ||
| 95 | __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg)); | ||
| 96 | outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1)); | ||
| 83 | } | 97 | } |
| 84 | 98 | ||
| 85 | struct smp_operations imx_smp_ops __initdata = { | 99 | struct smp_operations imx_smp_ops __initdata = { |
