* [PATCH 1/4] ARM: vexpress: add support for multiple core tiles
2010-09-17 13:12 [PATCH 0/4] CPU hotplug support for Versatile platforms Will Deacon
@ 2010-09-17 13:12 ` Will Deacon
2010-09-17 13:12 ` [PATCH 2/4] ARM: realview: fix CPU hotplug support for SMP platforms Will Deacon
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2010-09-17 13:12 UTC (permalink / raw)
To: linux-arm-kernel
The current Versatile Express BSP defines the MACHINE_START macro
in the core tile code.
This patch moves this into the generic board code and introduces
a method for determining the current tile at runtime, allowing
the Kernel to have support for multiple tiles compiled in.
Tile-specific functions are executed via a descriptor struct containing
the correct implementations for the current tile.
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mach-vexpress/core.h | 5 --
arch/arm/mach-vexpress/ct-ca9x4.c | 36 ++++++++-----
arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 2 +
arch/arm/mach-vexpress/include/mach/motherboard.h | 21 +++++++
arch/arm/mach-vexpress/platsmp.c | 12 +----
arch/arm/mach-vexpress/v2m.c | 61 +++++++++++++++++----
6 files changed, 97 insertions(+), 40 deletions(-)
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 57dd95c..c55feff 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -18,9 +18,4 @@ struct amba_device name##_device = { \
/* .dma = DMA_##base,*/ \
}
-struct map_desc;
-
-void v2m_map_io(struct map_desc *tile, size_t num);
-extern struct sys_timer v2m_timer;
-
extern void __iomem *gic_cpu_base_addr;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 577df6c..a59ffa8 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -10,12 +10,11 @@
#include <linux/amba/clcd.h>
#include <asm/clkdev.h>
-#include <asm/pgtable.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
-#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/smp_scu.h>
#include <asm/smp_twd.h>
#include <mach/clkdev.h>
@@ -23,7 +22,6 @@
#include <plat/timer-sp.h>
-#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
@@ -55,7 +53,7 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = {
static void __init ct_ca9x4_map_io(void)
{
twd_base = MMIO_P2V(A9_MPCORE_TWD);
- v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+ iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
}
void __iomem *gic_cpu_base_addr;
@@ -238,16 +236,26 @@ static void ct_ca9x4_init(void)
platform_device_register(&pmu_device);
}
-MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
- .phys_io = V2M_UART0 & SECTION_MASK,
- .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x00000100,
+#ifdef CONFIG_SMP
+static unsigned int ct_ca9x4_get_core_count(void)
+{
+ return scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
+}
+
+static void ct_ca9x4_smp_enable(void)
+{
+ scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+}
+#endif
+
+struct ct_desc ct_ca9x4_desc = {
+ .id = V2M_CT_ID_CA9,
+ .name = "CA9x4",
.map_io = ct_ca9x4_map_io,
.init_irq = ct_ca9x4_init_irq,
-#if 0
- .timer = &ct_ca9x4_timer,
-#else
- .timer = &v2m_timer,
+ .init_tile = ct_ca9x4_init,
+#ifdef CONFIG_SMP
+ .get_core_count = ct_ca9x4_get_core_count,
+ .smp_enable = ct_ca9x4_smp_enable,
#endif
- .init_machine = ct_ca9x4_init,
-MACHINE_END
+};
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index f9e2f8d..a34d3d4 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -45,4 +45,6 @@
#define IRQ_CT_CA9X4_PMU_CPU2 94
#define IRQ_CT_CA9X4_PMU_CPU3 95
+extern struct ct_desc ct_ca9x4_desc;
+
#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 98a8ded..6433ae5 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -118,4 +118,25 @@
int v2m_cfg_write(u32 devfn, u32 data);
int v2m_cfg_read(u32 devfn, u32 *data);
+/*
+ * Core tile IDs
+ */
+#define V2M_CT_ID_CA9 0x0c000191
+#define V2M_CT_ID_UNSUPPORTED 0xff000191
+#define V2M_CT_ID_MASK 0xff000fff
+
+struct ct_desc {
+ u32 id;
+ const char *name;
+ void (*map_io)(void);
+ void (*init_irq)(void);
+ void (*init_tile)(void);
+#ifdef CONFIG_SMP
+ unsigned int (*get_core_count)(void);
+ void (*smp_enable)(void);
+#endif
+};
+
+extern struct ct_desc *ct_desc;
+
#endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 6709706..b2d1e29 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -18,10 +18,8 @@
#include <asm/cacheflush.h>
#include <asm/localtimer.h>
-#include <asm/smp_scu.h>
#include <asm/unified.h>
-#include <mach/ct-ca9x4.h>
#include <mach/motherboard.h>
#define V2M_PA_CS7 0x10000000
@@ -35,11 +33,6 @@ extern void vexpress_secondary_startup(void);
*/
volatile int __cpuinitdata pen_release = -1;
-static void __iomem *scu_base_addr(void)
-{
- return MMIO_P2V(A9_MPCORE_SCU);
-}
-
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -118,10 +111,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
*/
void __init smp_init_cpus(void)
{
- void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores;
- ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+ ncores = ct_desc->get_core_count();
/* sanity check */
if (ncores == 0) {
@@ -175,7 +167,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/
percpu_timer_setup();
- scu_enable(scu_base_addr());
+ ct_desc->smp_enable();
/*
* Write the address of secondary startup into the
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 817f0ad..376f50c 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -13,13 +13,17 @@
#include <linux/usb/isp1760.h>
#include <asm/clkdev.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
#include <asm/sizes.h>
+#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/hardware/arm_timer.h>
#include <mach/clkdev.h>
+#include <mach/ct-ca9x4.h>
#include <mach/motherboard.h>
#include <plat/timer-sp.h>
@@ -41,13 +45,6 @@ static struct map_desc v2m_io_desc[] __initdata = {
},
};
-void __init v2m_map_io(struct map_desc *tile, size_t num)
-{
- iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
- iotable_init(tile, num);
-}
-
-
static void v2m_timer_init(void)
{
writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
@@ -57,7 +54,7 @@ static void v2m_timer_init(void)
sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
}
-struct sys_timer v2m_timer = {
+static struct sys_timer v2m_timer = {
.init = v2m_timer_init,
};
@@ -343,7 +340,40 @@ static void v2m_restart(char str, const char *cmd)
printk(KERN_EMERG "Unable to reboot\n");
}
-static int __init v2m_init(void)
+struct ct_desc *ct_desc;
+
+static struct ct_desc *ct_descs[] __initdata = {
+ &ct_ca9x4_desc,
+};
+
+static void __init v2m_populate_ct_desc(void)
+{
+ int i;
+ u32 current_tile_id;
+
+ current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
+ for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
+ if (ct_descs[i]->id == current_tile_id)
+ ct_desc = ct_descs[i];
+
+ if (!ct_desc)
+ panic("Versatile Express: "
+ "failed to populate core tile description\n");
+}
+
+static void __init v2m_map_io(void)
+{
+ iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+ v2m_populate_ct_desc();
+ ct_desc->map_io();
+}
+
+static void __init v2m_init_irq(void)
+{
+ ct_desc->init_irq();
+}
+
+static void __init v2m_init(void)
{
int i;
@@ -361,6 +391,15 @@ static int __init v2m_init(void)
pm_power_off = v2m_power_off;
arm_pm_restart = v2m_restart;
- return 0;
+ ct_desc->init_tile();
}
-arch_initcall(v2m_init);
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express")
+ .phys_io = V2M_UART0 & SECTION_MASK,
+ .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x00000100,
+ .map_io = v2m_map_io,
+ .init_irq = v2m_init_irq,
+ .timer = &v2m_timer,
+ .init_machine = v2m_init,
+MACHINE_END
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 2/4] ARM: realview: fix CPU hotplug support for SMP platforms
2010-09-17 13:12 [PATCH 0/4] CPU hotplug support for Versatile platforms Will Deacon
2010-09-17 13:12 ` [PATCH 1/4] ARM: vexpress: add support for multiple core tiles Will Deacon
@ 2010-09-17 13:12 ` Will Deacon
2010-09-17 13:12 ` [PATCH 3/4] ARM: plat-versatile: factor out common hotplug code Will Deacon
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2010-09-17 13:12 UTC (permalink / raw)
To: linux-arm-kernel
The current CPU hotplug functions for RealView boards suffer from a number
of problems:
- The location of the SMP/AMP bit in the Auxiliary Control Register is
correct only for 11MPCore.
- The I-cache is not flushed when a core leaves lowpower mode
- The assembly routines for entering/leaving the lowpower state can
be made more readable by using macros for operations such as dsb().
This patch fixes these problems for the RealView boards and has been
tested successfully on the PB11MPCore board.
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mach-realview/hotplug.c | 41 ++++++++++++++++++++++++-------------
1 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index f95521a..b90c15a 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -8,11 +8,15 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
#include <linux/completion.h>
+#include <mach/board-eb.h>
+#include <mach/board-pbx.h>
+
#include <asm/cacheflush.h>
extern volatile int pen_release;
@@ -21,42 +25,52 @@ static DECLARE_COMPLETION(cpu_killed);
static inline void cpu_enter_lowpower(void)
{
- unsigned int v;
+ unsigned int v, smp_ctrl;
+
+ smp_ctrl = (core_tile_pbxa9mp() || core_tile_a9mp()) ? 0x40 : 0x20;
flush_cache_all();
+ dsb();
asm volatile(
- " mcr p15, 0, %1, c7, c5, 0\n"
- " mcr p15, 0, %1, c7, c10, 4\n"
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
- " bic %0, %0, #0x20\n"
+ " bic %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 1\n"
+ /* DSB */
+ " mcr p15, 0, %2, c7, c10, 4\n"
+ /* Disable D-cache */
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
- : "r" (0)
- : "cc");
+ : "r" (smp_ctrl), "r" (0)
+ : "memory");
+ isb();
}
static inline void cpu_leave_lowpower(void)
{
- unsigned int v;
+ unsigned int v, smp_ctrl;
+ smp_ctrl = (core_tile_pbxa9mp() || core_tile_a9mp()) ? 0x40 : 0x20;
+
+ flush_cache_all();
+ dsb();
asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
- " orr %0, %0, #0x20\n"
+ " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
- :
- : "cc");
+ : "r" (smp_ctrl)
+ : "memory");
+ isb();
}
-static inline void platform_do_lowpower(unsigned int cpu)
+static void __ref platform_do_lowpower(unsigned int cpu)
{
/*
* there is no power-control hardware on this platform, so all
@@ -67,10 +81,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
/*
* here's the WFI
*/
- asm(".word 0xe320f003\n"
- :
- :
- : "memory", "cc");
+ asm volatile("wfi" : : : "memory");
if (pen_release == cpu) {
/*
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 3/4] ARM: plat-versatile: factor out common hotplug code
2010-09-17 13:12 [PATCH 0/4] CPU hotplug support for Versatile platforms Will Deacon
2010-09-17 13:12 ` [PATCH 1/4] ARM: vexpress: add support for multiple core tiles Will Deacon
2010-09-17 13:12 ` [PATCH 2/4] ARM: realview: fix CPU hotplug support for SMP platforms Will Deacon
@ 2010-09-17 13:12 ` Will Deacon
2010-09-17 13:12 ` [PATCH 4/4] ARM: vexpress: add support for CPU hotplug to ct-ca9x4 tile Will Deacon
2010-09-17 21:21 ` [PATCH 0/4] CPU hotplug support for Versatile platforms Rob Herring
4 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2010-09-17 13:12 UTC (permalink / raw)
To: linux-arm-kernel
Common hotplug routines for the Versatile Platforms can be factored
out under plat-versatile leaving only the platform_do_lowpower function
to be implemented by the BSP code.
This patch factors out the hotplug code and changes the RealView hotplug
implementation to use the new framework.
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mach-realview/hotplug.c | 52 +--------------------
arch/arm/plat-versatile/Makefile | 1 +
arch/arm/plat-versatile/hotplug.c | 57 ++++++++++++++++++++++++
arch/arm/plat-versatile/include/plat/hotplug.h | 6 +++
4 files changed, 67 insertions(+), 49 deletions(-)
create mode 100644 arch/arm/plat-versatile/hotplug.c
create mode 100644 arch/arm/plat-versatile/include/plat/hotplug.h
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index b90c15a..3577590 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -16,13 +16,12 @@
#include <mach/board-eb.h>
#include <mach/board-pbx.h>
+#include <plat/hotplug.h>
#include <asm/cacheflush.h>
extern volatile int pen_release;
-static DECLARE_COMPLETION(cpu_killed);
-
static inline void cpu_enter_lowpower(void)
{
unsigned int v, smp_ctrl;
@@ -70,8 +69,9 @@ static inline void cpu_leave_lowpower(void)
isb();
}
-static void __ref platform_do_lowpower(unsigned int cpu)
+void __ref platform_do_lowpower(unsigned int cpu)
{
+ cpu_enter_lowpower();
/*
* there is no power-control hardware on this platform, so all
* we can do is put the core into WFI; this is safe as the calling
@@ -102,51 +102,5 @@ static void __ref platform_do_lowpower(unsigned int cpu)
printk("CPU%u: spurious wakeup call\n", cpu);
#endif
}
-}
-
-int platform_cpu_kill(unsigned int cpu)
-{
- return wait_for_completion_timeout(&cpu_killed, 5000);
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void platform_cpu_die(unsigned int cpu)
-{
-#ifdef DEBUG
- unsigned int this_cpu = hard_smp_processor_id();
-
- if (cpu != this_cpu) {
- printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
- this_cpu, cpu);
- BUG();
- }
-#endif
-
- printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
- complete(&cpu_killed);
-
- /*
- * we're ready for shutdown now, so do it
- */
- cpu_enter_lowpower();
- platform_do_lowpower(cpu);
-
- /*
- * bring this CPU back into the world of cache
- * coherency, and then restore interrupts
- */
cpu_leave_lowpower();
}
-
-int platform_cpu_disable(unsigned int cpu)
-{
- /*
- * we don't allow CPU 0 to be shutdown (it is still too special
- * e.g. clock tick interrupts)
- */
- return cpu == 0 ? -EPERM : 0;
-}
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 5cf88e8..e0fad33 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -6,3 +6,4 @@ ifeq ($(CONFIG_LEDS_CLASS),y)
obj-$(CONFIG_ARCH_REALVIEW) += leds.o
obj-$(CONFIG_ARCH_VERSATILE) += leds.o
endif
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/plat-versatile/hotplug.c b/arch/arm/plat-versatile/hotplug.c
new file mode 100644
index 0000000..15ed6bd
--- /dev/null
+++ b/arch/arm/plat-versatile/hotplug.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/arm/plat-versatile/hotplug.c
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <plat/hotplug.h>
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+ unsigned int this_cpu = hard_smp_processor_id();
+
+ if (cpu != this_cpu) {
+ printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
+ this_cpu, cpu);
+ BUG();
+ }
+#endif
+
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+ complete(&cpu_killed);
+
+ /*
+ * Call the CPU-specific low-power routine.
+ */
+ platform_do_lowpower(cpu);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/plat-versatile/include/plat/hotplug.h b/arch/arm/plat-versatile/include/plat/hotplug.h
new file mode 100644
index 0000000..f36df1c
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/hotplug.h
@@ -0,0 +1,6 @@
+#ifndef PLAT_HOTPLUG_H
+#define PLAT_HOTPLUG_H
+
+void platform_do_lowpower(unsigned int cpu);
+
+#endif
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 4/4] ARM: vexpress: add support for CPU hotplug to ct-ca9x4 tile
2010-09-17 13:12 [PATCH 0/4] CPU hotplug support for Versatile platforms Will Deacon
` (2 preceding siblings ...)
2010-09-17 13:12 ` [PATCH 3/4] ARM: plat-versatile: factor out common hotplug code Will Deacon
@ 2010-09-17 13:12 ` Will Deacon
2010-09-17 21:21 ` [PATCH 0/4] CPU hotplug support for Versatile platforms Rob Herring
4 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2010-09-17 13:12 UTC (permalink / raw)
To: linux-arm-kernel
The Versatile Express platform can support a quad-core Cortex-A9 tile running
SMP Linux.
This patch adds support for CPU hotplug when running in this configuration.
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mach-vexpress/Makefile | 1 +
arch/arm/mach-vexpress/ct-ca9x4.c | 55 +++++++++++++++++++++
arch/arm/mach-vexpress/hotplug.c | 39 +++++++++++++++
arch/arm/mach-vexpress/include/mach/motherboard.h | 5 ++
4 files changed, 100 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-vexpress/hotplug.c
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 1b71b77..15a34f0 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -6,3 +6,4 @@ obj-y := v2m.o
obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index a59ffa8..a8853fa 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -9,6 +9,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
+#include <asm/cacheflush.h>
#include <asm/clkdev.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
@@ -248,6 +249,55 @@ static void ct_ca9x4_smp_enable(void)
}
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+static void ct_ca9x4_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ dsb();
+ asm volatile(
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x40\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " dsb\n"
+ /* Disable D-cache */
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "memory");
+ isb();
+}
+
+static void ct_ca9x4_leave_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ dsb();
+ asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x40\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ :
+ : "memory");
+ isb();
+}
+
+static int ct_ca9x4_do_lowpower(void)
+{
+ return -ENODEV;
+}
+#endif
+
struct ct_desc ct_ca9x4_desc = {
.id = V2M_CT_ID_CA9,
.name = "CA9x4",
@@ -258,4 +308,9 @@ struct ct_desc ct_ca9x4_desc = {
.get_core_count = ct_ca9x4_get_core_count,
.smp_enable = ct_ca9x4_smp_enable,
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+ .enter_lowpower = ct_ca9x4_enter_lowpower,
+ .do_lowpower = ct_ca9x4_do_lowpower,
+ .leave_lowpower = ct_ca9x4_leave_lowpower,
+#endif
};
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 0000000..8c4d46e
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,39 @@
+/*
+ * linux/arch/arm/mach-vexpress/hotplug.c
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <mach/motherboard.h>
+
+#include <plat/hotplug.h>
+
+extern volatile int pen_release;
+
+void __ref platform_do_lowpower(unsigned int cpu)
+{
+ ct_desc->enter_lowpower();
+
+ for (;;) {
+ if (ct_desc->do_lowpower() == -ENODEV)
+ asm volatile("wfi" : : : "memory");
+
+ if (pen_release == cpu)
+ break;
+
+#ifdef DEBUG
+ printk("CPU%u: spurious wakeup call\n", cpu);
+#endif
+ }
+
+ ct_desc->leave_lowpower();
+}
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 6433ae5..2451947 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -135,6 +135,11 @@ struct ct_desc {
unsigned int (*get_core_count)(void);
void (*smp_enable)(void);
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+ void (*enter_lowpower)(void);
+ int (*do_lowpower)(void);
+ void (*leave_lowpower)(void);
+#endif
};
extern struct ct_desc *ct_desc;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 0/4] CPU hotplug support for Versatile platforms
2010-09-17 13:12 [PATCH 0/4] CPU hotplug support for Versatile platforms Will Deacon
` (3 preceding siblings ...)
2010-09-17 13:12 ` [PATCH 4/4] ARM: vexpress: add support for CPU hotplug to ct-ca9x4 tile Will Deacon
@ 2010-09-17 21:21 ` Rob Herring
2010-09-17 23:01 ` Russell King - ARM Linux
4 siblings, 1 reply; 9+ messages in thread
From: Rob Herring @ 2010-09-17 21:21 UTC (permalink / raw)
To: linux-arm-kernel
On 09/17/2010 08:12 AM, Will Deacon wrote:
> This patch series fixes some issues with the RealView CPU hotplug code and then
> factors out the common code into plat-versatile. Finally, support for multiple
> tiles is added to the Versatile Express BSP in order to decouple the
> tile-specific functions from the motherboard and hotplug support is
> added to the ct-ca9x4 tile using the new platform code.
>
> Taken against 2.6.35 and tested on RealView PB11MPCore and Versatile Express
> [ct-ca9x4] boards.
>
> Cc: Russell King - ARM Linux<linux@arm.linux.org.uk>
>
> Will Deacon (4):
> ARM: vexpress: add support for multiple core tiles
> ARM: realview: fix CPU hotplug support for SMP platforms
> ARM: plat-versatile: factor out common hotplug code
> ARM: vexpress: add support for CPU hotplug to ct-ca9x4 tile
>
> arch/arm/mach-realview/hotplug.c | 91 +++++++--------------
> arch/arm/mach-vexpress/Makefile | 1 +
> arch/arm/mach-vexpress/core.h | 5 -
> arch/arm/mach-vexpress/ct-ca9x4.c | 91 +++++++++++++++++---
> arch/arm/mach-vexpress/hotplug.c | 39 +++++++++
> arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 2 +
> arch/arm/mach-vexpress/include/mach/motherboard.h | 26 ++++++
> arch/arm/mach-vexpress/platsmp.c | 12 +---
> arch/arm/mach-vexpress/v2m.c | 61 +++++++++++---
> arch/arm/plat-versatile/Makefile | 1 +
> arch/arm/plat-versatile/hotplug.c | 57 +++++++++++++
> arch/arm/plat-versatile/include/plat/hotplug.h | 6 ++
> 12 files changed, 289 insertions(+), 103 deletions(-)
> create mode 100644 arch/arm/mach-vexpress/hotplug.c
> create mode 100644 arch/arm/plat-versatile/hotplug.c
> create mode 100644 arch/arm/plat-versatile/include/plat/hotplug.h
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
The platform specific SMP code is one area that prevents supporting a
single kernel image. All the functions in platsmp.c need to be converted
to function pointers and a lot of that code is pretty simliar across
platforms. What's needed is a common platsmp.c with something like
platform specific smp_ops like PowerPC. I think addressing that first
would simplify this restructuring as you are doing some of what's
needed, but you introducing new namespace problems like platform_cpu_*.
Rob
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 0/4] CPU hotplug support for Versatile platforms
2010-09-17 21:21 ` [PATCH 0/4] CPU hotplug support for Versatile platforms Rob Herring
@ 2010-09-17 23:01 ` Russell King - ARM Linux
2010-09-18 20:58 ` Rob Herring
0 siblings, 1 reply; 9+ messages in thread
From: Russell King - ARM Linux @ 2010-09-17 23:01 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Sep 17, 2010 at 04:21:42PM -0500, Rob Herring wrote:
> The platform specific SMP code is one area that prevents supporting a
> single kernel image. All the functions in platsmp.c need to be converted
> to function pointers and a lot of that code is pretty simliar across
> platforms. What's needed is a common platsmp.c with something like
> platform specific smp_ops like PowerPC. I think addressing that first
> would simplify this restructuring as you are doing some of what's
> needed, but you introducing new namespace problems like platform_cpu_*.
The split between smp.c and platsmp.c is there to allow different SMP
implementations from the standard ARM Ltd SMP implementation (and there
will be different implementations.)
Just because all the SMP implementations that are currently merged are
the standard ARM Ltd SMP implementation does not mean that we should
move stuff out of platsmp.c into the generic code.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/4] CPU hotplug support for Versatile platforms
2010-09-17 23:01 ` Russell King - ARM Linux
@ 2010-09-18 20:58 ` Rob Herring
2010-09-22 17:45 ` Will Deacon
0 siblings, 1 reply; 9+ messages in thread
From: Rob Herring @ 2010-09-18 20:58 UTC (permalink / raw)
To: linux-arm-kernel
On 09/17/2010 06:01 PM, Russell King - ARM Linux wrote:
> On Fri, Sep 17, 2010 at 04:21:42PM -0500, Rob Herring wrote:
>> The platform specific SMP code is one area that prevents supporting a
>> single kernel image. All the functions in platsmp.c need to be converted
>> to function pointers and a lot of that code is pretty simliar across
>> platforms. What's needed is a common platsmp.c with something like
>> platform specific smp_ops like PowerPC. I think addressing that first
>> would simplify this restructuring as you are doing some of what's
>> needed, but you introducing new namespace problems like platform_cpu_*.
>
> The split between smp.c and platsmp.c is there to allow different SMP
> implementations from the standard ARM Ltd SMP implementation (and there
> will be different implementations.)
>
> Just because all the SMP implementations that are currently merged are
> the standard ARM Ltd SMP implementation does not mean that we should
> move stuff out of platsmp.c into the generic code.
Agreed, but the interface between smp.c and platsmp.c does not allow for
more than one SMP platform in a single image. Granted, there are plenty
of other obstacles to multi-platform kernel binaries, but this one would
be good to address before there are a bunch of SMP platforns rather than
after. Ideally, platsmp.c could be common, but optional for platforms
that are significantly different.
The idea I have is add a smp_init function ptr to struct mdesc which
would fill in an smp_ops struct of function pointers and call
set_cpu_possible for each core. This would replace the direct
smp_init_cpus call.
Rob
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/4] CPU hotplug support for Versatile platforms
2010-09-18 20:58 ` Rob Herring
@ 2010-09-22 17:45 ` Will Deacon
0 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2010-09-22 17:45 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rob,
> On 09/17/2010 06:01 PM, Russell King - ARM Linux wrote:
> > On Fri, Sep 17, 2010 at 04:21:42PM -0500, Rob Herring wrote:
> >> The platform specific SMP code is one area that prevents supporting a
> >> single kernel image. All the functions in platsmp.c need to be converted
> >> to function pointers and a lot of that code is pretty simliar across
> >> platforms. What's needed is a common platsmp.c with something like
> >> platform specific smp_ops like PowerPC. I think addressing that first
> >> would simplify this restructuring as you are doing some of what's
> >> needed, but you introducing new namespace problems like platform_cpu_*.
> >
> > The split between smp.c and platsmp.c is there to allow different SMP
> > implementations from the standard ARM Ltd SMP implementation (and there
> > will be different implementations.)
> >
> > Just because all the SMP implementations that are currently merged are
> > the standard ARM Ltd SMP implementation does not mean that we should
> > move stuff out of platsmp.c into the generic code.
>
> Agreed, but the interface between smp.c and platsmp.c does not allow for
> more than one SMP platform in a single image. Granted, there are plenty
> of other obstacles to multi-platform kernel binaries, but this one would
> be good to address before there are a bunch of SMP platforns rather than
> after. Ideally, platsmp.c could be common, but optional for platforms
> that are significantly different.
>
> The idea I have is add a smp_init function ptr to struct mdesc which
> would fill in an smp_ops struct of function pointers and call
> set_cpu_possible for each core. This would replace the direct
> smp_init_cpus call.
I think this is a separate patch. Whilst this sort of stuff is in the
back of my mind when doing BSP stuff, it's not the primary concern of
these patches. The platform_cpu_* namespace exists in the kernel already
and is not something I have introduced [see mach-realview/hotplug.c].
The main aim of these patches is to allow multiple variants (core tiles)
to exist for the versatile express without having to have separate machine
IDs.
Cheers,
Will
^ permalink raw reply [flat|nested] 9+ messages in thread