[PATCH v2] arm: mvebu: don't hardcode a physical address in headsmp.S
Thomas Petazzoni
thomas.petazzoni at free-electrons.com
Thu Jun 6 06:24:28 EDT 2013
Now that the coherency_init() function is called a bit earlier, we can
actually read the physical address of the coherency unit registers
from the Device Tree, and communicate that to the headsmp.S code,
which avoids hardcoding a physical address.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
---
Changes from v1 to v2:
* Simplified the code in headsmp.S to compute the physical address of
the coherency unit base address. Suggested by Nicolas Pitre.
* Added a sync_cache_w() call to ensure the physical address of the
coherency unit stored in the coherency_phys_base is visible by the
other CPUs. The other CPUs are reading this before they join the
coherency fabric, so we need to make some manual cache coherency
here. Noticed by Will Deacon.
arch/arm/mach-mvebu/coherency.c | 12 ++++++++++++
arch/arm/mach-mvebu/headsmp.S | 16 ++++++++--------
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index d74794a..32fcf69 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -25,8 +25,10 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/smp_plat.h>
+#include <asm/cacheflush.h>
#include "armada-370-xp.h"
+unsigned long __cpuinitdata coherency_phys_base;
static void __iomem *coherency_base;
static void __iomem *coherency_cpu_base;
@@ -124,7 +126,17 @@ int __init coherency_init(void)
np = of_find_matching_node(NULL, of_coherency_table);
if (np) {
+ struct resource res;
pr_info("Initializing Coherency fabric\n");
+ of_address_to_resource(np, 0, &res);
+ coherency_phys_base = res.start;
+ /*
+ * Ensure secondary CPUs will see the updated value,
+ * which they read before they join the coherency
+ * fabric, and therefore before they are coherent with
+ * the boot CPU cache.
+ */
+ sync_cache_w(&coherency_phys_base);
coherency_base = of_iomap(np, 0);
coherency_cpu_base = of_iomap(np, 1);
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index a06e0ed..7147300 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -21,12 +21,6 @@
#include <linux/linkage.h>
#include <linux/init.h>
-/*
- * At this stage the secondary CPUs don't have acces yet to the MMU, so
- * we have to provide physical addresses
- */
-#define ARMADA_XP_CFB_BASE 0xD0020200
-
__CPUINIT
/*
@@ -35,15 +29,21 @@
* startup
*/
ENTRY(armada_xp_secondary_startup)
+ /* Get coherency fabric base physical address */
+ adr r0, 1f
+ ldr r1, [r0]
+ ldr r0, [r0, r1]
/* Read CPU id */
mrc p15, 0, r1, c0, c0, 5
and r1, r1, #0xF
/* Add CPU to coherency fabric */
- ldr r0, =ARMADA_XP_CFB_BASE
-
bl ll_set_cpu_coherent
b secondary_startup
ENDPROC(armada_xp_secondary_startup)
+
+ .align 2
+1:
+ .long coherency_phys_base - .
--
1.8.1.2
More information about the linux-arm-kernel
mailing list