diff options
author | Ben Dooks <ben.dooks@codethink.co.uk> | 2016-06-21 06:20:24 -0400 |
---|---|---|
committer | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2016-06-21 07:25:58 -0400 |
commit | 458ad21df1c38d229aaa4c494199168d742302ab (patch) | |
tree | 738f776820ef323c479a9741cbb70a16dee07b2a | |
parent | f4c24f36c3e457cb727f9f548f146d805739e8e0 (diff) |
ARM: EXYNOS: Fixups for big-endian operation
If the kernel is built big endian, then using the __raw read and write IO
accessors is not going to work as they end up writing big-endian data to
little-endian IO registers. Fix this by using the readl and writel relaxed
versions which ensure little endian IO.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
-rw-r--r-- | arch/arm/mach-exynos/firmware.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-exynos/headsmp.S | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 4 |
3 files changed, 14 insertions, 11 deletions
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index 1bfd1b0bd9dc..fd6da5419b51 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c | |||
@@ -41,9 +41,9 @@ static int exynos_do_idle(unsigned long mode) | |||
41 | case FW_DO_IDLE_AFTR: | 41 | case FW_DO_IDLE_AFTR: |
42 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | 42 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) |
43 | exynos_save_cp15(); | 43 | exynos_save_cp15(); |
44 | __raw_writel(virt_to_phys(exynos_cpu_resume_ns), | 44 | writel_relaxed(virt_to_phys(exynos_cpu_resume_ns), |
45 | sysram_ns_base_addr + 0x24); | 45 | sysram_ns_base_addr + 0x24); |
46 | __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); | 46 | writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); |
47 | if (soc_is_exynos3250()) { | 47 | if (soc_is_exynos3250()) { |
48 | flush_cache_all(); | 48 | flush_cache_all(); |
49 | exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE, | 49 | exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE, |
@@ -97,7 +97,7 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) | |||
97 | if (soc_is_exynos4412()) | 97 | if (soc_is_exynos4412()) |
98 | boot_reg += 4 * cpu; | 98 | boot_reg += 4 * cpu; |
99 | 99 | ||
100 | __raw_writel(boot_addr, boot_reg); | 100 | writel_relaxed(boot_addr, boot_reg); |
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
@@ -113,7 +113,7 @@ static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr) | |||
113 | if (soc_is_exynos4412()) | 113 | if (soc_is_exynos4412()) |
114 | boot_reg += 4 * cpu; | 114 | boot_reg += 4 * cpu; |
115 | 115 | ||
116 | *boot_addr = __raw_readl(boot_reg); | 116 | *boot_addr = readl_relaxed(boot_reg); |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
@@ -234,20 +234,20 @@ void exynos_set_boot_flag(unsigned int cpu, unsigned int mode) | |||
234 | { | 234 | { |
235 | unsigned int tmp; | 235 | unsigned int tmp; |
236 | 236 | ||
237 | tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4); | 237 | tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4); |
238 | 238 | ||
239 | if (mode & BOOT_MODE_MASK) | 239 | if (mode & BOOT_MODE_MASK) |
240 | tmp &= ~BOOT_MODE_MASK; | 240 | tmp &= ~BOOT_MODE_MASK; |
241 | 241 | ||
242 | tmp |= mode; | 242 | tmp |= mode; |
243 | __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4); | 243 | writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4); |
244 | } | 244 | } |
245 | 245 | ||
246 | void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode) | 246 | void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode) |
247 | { | 247 | { |
248 | unsigned int tmp; | 248 | unsigned int tmp; |
249 | 249 | ||
250 | tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4); | 250 | tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4); |
251 | tmp &= ~mode; | 251 | tmp &= ~mode; |
252 | __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4); | 252 | writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4); |
253 | } | 253 | } |
diff --git a/arch/arm/mach-exynos/headsmp.S b/arch/arm/mach-exynos/headsmp.S index b54f9701e421..d3d24ab351ae 100644 --- a/arch/arm/mach-exynos/headsmp.S +++ b/arch/arm/mach-exynos/headsmp.S | |||
@@ -12,12 +12,15 @@ | |||
12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | 14 | ||
15 | #include <asm/assembler.h> | ||
16 | |||
15 | /* | 17 | /* |
16 | * exynos4 specific entry point for secondary CPUs. This provides | 18 | * exynos4 specific entry point for secondary CPUs. This provides |
17 | * a "holding pen" into which all secondary cores are held until we're | 19 | * a "holding pen" into which all secondary cores are held until we're |
18 | * ready for them to initialise. | 20 | * ready for them to initialise. |
19 | */ | 21 | */ |
20 | ENTRY(exynos4_secondary_startup) | 22 | ENTRY(exynos4_secondary_startup) |
23 | ARM_BE8(setend be) | ||
21 | mrc p15, 0, r0, c0, c0, 5 | 24 | mrc p15, 0, r0, c0, c0, 5 |
22 | and r0, r0, #15 | 25 | and r0, r0, #15 |
23 | adr r4, 1f | 26 | adr r4, 1f |
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 85c3be63d644..98ffe1e62ad5 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
@@ -264,7 +264,7 @@ int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) | |||
264 | ret = PTR_ERR(boot_reg); | 264 | ret = PTR_ERR(boot_reg); |
265 | goto fail; | 265 | goto fail; |
266 | } | 266 | } |
267 | __raw_writel(boot_addr, boot_reg); | 267 | writel_relaxed(boot_addr, boot_reg); |
268 | ret = 0; | 268 | ret = 0; |
269 | } | 269 | } |
270 | fail: | 270 | fail: |
@@ -289,7 +289,7 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr) | |||
289 | ret = PTR_ERR(boot_reg); | 289 | ret = PTR_ERR(boot_reg); |
290 | goto fail; | 290 | goto fail; |
291 | } | 291 | } |
292 | *boot_addr = __raw_readl(boot_reg); | 292 | *boot_addr = readl_relaxed(boot_reg); |
293 | ret = 0; | 293 | ret = 0; |
294 | } | 294 | } |
295 | fail: | 295 | fail: |