From c0114709ed85a5693eb74acdfa03d94f7f12e5b8 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 14 Jan 2013 18:05:37 +0000 Subject: irqchip: gic: Perform the gic_secondary_init() call via CPU notifier All the calls to gic_secondary_init() pass 0 as the first argument. Since this function is called on each CPU when starting, it can be done in a platform-independent way via a CPU notifier registered by the GIC code. Signed-off-by: Catalin Marinas Acked-by: Stephen Warren Acked-by: Viresh Kumar Acked-by: Santosh Shilimkar Acked-by: Rob Herring Acked-by: Simon Horman Tested-by: Simon Horman Acked-by: Srinidhi Kasagar Tested-by: Dinh Nguyen Acked-by: Nicolas Pitre Tested-by: Marc Zyngier Cc: Russell King Cc: Thomas Gleixner Cc: Kukjin Kim Cc: Sascha Hauer Cc: David Brown Cc: Bryan Huntsman Cc: Tony Lindgren Cc: Magnus Damm Cc: Shiraz Hashim Cc: Linus Walleij Cc: Will Deacon Cc: Kukjin Kim Cc: Barry Song --- arch/arm/mach-omap2/omap-smp.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/arm/mach-omap2/omap-smp.c') diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index d9727218dd0..e7a449758ab 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -66,13 +66,6 @@ static void __cpuinit omap4_secondary_init(unsigned int cpu) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); - /* - * If any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * Synchronise with the boot thread. */ -- cgit v1.2.3-70-g09d2 From 466caec026e38df1a3dda117ac90ccc82b8d3f14 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 10 Feb 2013 13:18:42 +0530 Subject: ARM: OMAP4+: Remove un-necessary cacheflush in secondary CPU boot path This was borrowed from ARM versatile code with pen_release mechanism but since OMAP uses hardware register based synchronisation, pen_release stuff was dropped. Unfortunately the cacheflush wasn't dropped along with it. Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap-smp.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/arm/mach-omap2/omap-smp.c') diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index d9727218dd0..5d8f2497017 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -21,7 +21,6 @@ #include #include -#include #include #include "omap-secure.h" @@ -103,9 +102,6 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * else __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); - flush_cache_all(); - smp_wmb(); - if (!cpu1_clkdm) cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); -- cgit v1.2.3-70-g09d2 From 2f82bd7814eeb553aaf63c202ba655e82350000a Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 10 Feb 2013 13:37:04 +0530 Subject: ARM: OMAP4+: Remove out of placed smp_wmb() in secondary wakeup code The smp_wmb() here is out of placed and redundant. So remove it. It is a left over of the pen_release cleanup mostly. Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap-smp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/mach-omap2/omap-smp.c') diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 5d8f2497017..1e14899dbbf 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -186,8 +186,6 @@ static void __init wakeup_secondary(void) __raw_writel(virt_to_phys(omap5_secondary_startup), base + OMAP_AUX_CORE_BOOT_1); - smp_wmb(); - /* * Send a 'sev' to wake the secondary core from WFE. * Drain the outstanding writes to memory -- cgit v1.2.3-70-g09d2 From b699ddd19bf3542d43ffe293c6148161e160b1bc Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 10 Feb 2013 13:54:00 +0530 Subject: ARM: OMAP4+: Move the CPU wakeup prepare code under smp_prepare_cpus() Move the secondary CPU wakeup prepare code under smp_prepare_cpus() where it belongs. It was remainder of the pen release code which was borrowed from ARM code initially. While at it drop the un-necessary sev() and barrier which was under prepare code. Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap-smp.c | 51 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) (limited to 'arch/arm/mach-omap2/omap-smp.c') diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 1e14899dbbf..0cbb677c4df 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -164,36 +164,6 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * return 0; } -static void __init wakeup_secondary(void) -{ - void *startup_addr = omap_secondary_startup; - void __iomem *base = omap_get_wakeupgen_base(); - - if (cpu_is_omap446x()) { - startup_addr = omap_secondary_startup_4460; - pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; - } - - /* - * Write the address of secondary startup routine into the - * AuxCoreBoot1 where ROM code will jump and start executing - * on secondary core once out of WFE - * A barrier is added to ensure that write buffer is drained - */ - if (omap_secure_apis_support()) - omap_auxcoreboot_addr(virt_to_phys(startup_addr)); - else - __raw_writel(virt_to_phys(omap5_secondary_startup), - base + OMAP_AUX_CORE_BOOT_1); - - /* - * Send a 'sev' to wake the secondary core from WFE. - * Drain the outstanding writes to memory - */ - dsb_sev(); - mb(); -} - /* * Initialise the CPU possible map early - this describes the CPUs * which may be present or become present in the system. @@ -229,6 +199,8 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { + void *startup_addr = omap_secondary_startup; + void __iomem *base = omap_get_wakeupgen_base(); /* * Initialise the SCU and wake up the secondary core using @@ -236,7 +208,24 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) */ if (scu_base) scu_enable(scu_base); - wakeup_secondary(); + + if (cpu_is_omap446x()) { + startup_addr = omap_secondary_startup_4460; + pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; + } + + /* + * Write the address of secondary startup routine into the + * AuxCoreBoot1 where ROM code will jump and start executing + * on secondary core once out of WFE + * A barrier is added to ensure that write buffer is drained + */ + if (omap_secure_apis_support()) + omap_auxcoreboot_addr(virt_to_phys(startup_addr)); + else + __raw_writel(virt_to_phys(omap5_secondary_startup), + base + OMAP_AUX_CORE_BOOT_1); + } struct smp_operations omap4_smp_ops __initdata = { -- cgit v1.2.3-70-g09d2 From b7806dc7cba840ea538706621486475d93a53c55 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 8 Feb 2013 22:50:58 +0530 Subject: ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method While waking up CPU from off state using clock domain force wakeup, restore the CPU power state to ON state before putting CPU clock domain under hardware control. Otherwise CPU wakeup might fail. The change is recommended for all OMAP4+ devices though the PRCM weakness was observed on OMAP5 devices first. As a result of weakness, lock-up is observed inside the hardware state machine of local CPU PRCM and results are UN-predictable as per designers. In software testing, we have seen hard-locks most of the time where system gets frozen. With power domain state restored, system behaves correctly. So update the code accordingly. Acked-by: Nishanth Menon Signed-off-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle44xx.c | 1 + arch/arm/mach-omap2/omap-smp.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2/omap-smp.c') diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 944e64aad7e..9de47a70628 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev, /* Wakeup CPU1 only if it is not offlined */ if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { clkdm_wakeup(cpu_clkdm[1]); + omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); clkdm_allow_idle(cpu_clkdm[1]); } diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 0cbb677c4df..e4441cc7aca 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * { static struct clockdomain *cpu1_clkdm; static bool booted; + static struct powerdomain *cpu1_pwrdm; void __iomem *base = omap_get_wakeupgen_base(); /* @@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * else __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); - if (!cpu1_clkdm) + if (!cpu1_clkdm && !cpu1_pwrdm) { cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); + cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm"); + } /* * The SGI(Software Generated Interrupts) are not wakeup capable @@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * * Section : * 4.3.4.2 Power States of CPU0 and CPU1 */ - if (booted) { + if (booted && cpu1_pwrdm && cpu1_clkdm) { /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure @@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * gic_dist_disable(); } + /* + * Ensure that CPU power state is set to ON to avoid CPU + * powerdomain transition on wfi + */ clkdm_wakeup(cpu1_clkdm); + omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON); clkdm_allow_idle(cpu1_clkdm); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { -- cgit v1.2.3-70-g09d2