ARM: OMAP5: Fix mpuss_early_init
authorTony Lindgren <tony@atomide.com>
Mon, 7 Nov 2016 23:50:11 +0000 (16:50 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 7 Nov 2016 23:51:58 +0000 (16:51 -0700)
We need to properly initialize mpuss also on omap5 like we do on omap4.
Otherwise we run into similar kexec problems like we had on omap4 when
trying to kexec from a kernel with PM initialized.

Fixes: 0573b957fc21 ("ARM: OMAP4+: Prevent CPU1 related hang with kexec")
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap4-sar-layout.h

index deed42e1dd9c903aba522d306416537eb26f7762..6dcca2957e23ef3ffc26ea56d9450734262c76d6 100644 (file)
@@ -262,8 +262,6 @@ extern void __iomem *omap4_get_sar_ram_base(void);
 extern void omap4_mpuss_early_init(void);
 extern void omap_do_wfi(void);
 
-extern void omap4_secondary_startup(void);
-extern void omap4460_secondary_startup(void);
 
 #ifdef CONFIG_SMP
 /* Needed for secondary core boot */
@@ -275,16 +273,11 @@ extern void omap4_cpu_die(unsigned int cpu);
 extern int omap4_cpu_kill(unsigned int cpu);
 
 extern const struct smp_operations omap4_smp_ops;
-
-extern void omap5_secondary_startup(void);
-extern void omap5_secondary_hyp_startup(void);
 #endif
 
 #if defined(CONFIG_SMP) && defined(CONFIG_PM)
 extern int omap4_mpuss_init(void);
 extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
-extern int omap4_finish_suspend(unsigned long cpu_state);
-extern void omap4_cpu_resume(void);
 extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
 #else
 static inline int omap4_enter_lowpower(unsigned int cpu,
@@ -305,14 +298,41 @@ static inline int omap4_mpuss_init(void)
        return 0;
 }
 
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void omap4_secondary_startup(void);
+void omap4460_secondary_startup(void);
+int omap4_finish_suspend(unsigned long cpu_state);
+void omap4_cpu_resume(void);
+#else
+static inline void omap4_secondary_startup(void)
+{
+}
+
+static inline void omap4460_secondary_startup(void)
+{
+}
 static inline int omap4_finish_suspend(unsigned long cpu_state)
 {
        return 0;
 }
-
 static inline void omap4_cpu_resume(void)
-{}
+{
+}
+#endif
 
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+void omap5_secondary_startup(void);
+void omap5_secondary_hyp_startup(void);
+#else
+static inline void omap5_secondary_startup(void)
+{
+}
+
+static inline void omap5_secondary_hyp_startup(void)
+{
+}
 #endif
 
 void pdata_quirks_init(const struct of_device_id *);
index 0e9acdd95d707d59a4727fe794379244543b3675..f0da5259762aa493098021cc7aaf9fda8ec63dd8 100644 (file)
@@ -717,10 +717,11 @@ void __init omap5_init_early(void)
                              OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
        omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
        omap2_control_base_init();
-       omap4_pm_init_early();
        omap2_prcm_base_init();
        omap5xxx_check_revision();
        omap4_sar_ram_init();
+       omap4_mpuss_early_init();
+       omap4_pm_init_early();
        omap54xx_voltagedomains_init();
        omap54xx_powerdomains_init();
        omap54xx_clockdomains_init();
index ad982465efd0d0faffbf3e1d812c8e0bd44ec313..94428b476d8fec2c3de6ef50a9baf67467317bf9 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/smp_scu.h>
 #include <asm/pgalloc.h>
 #include <asm/suspend.h>
+#include <asm/virt.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #include "soc.h"
@@ -371,8 +372,12 @@ int __init omap4_mpuss_init(void)
        pm_info = &per_cpu(omap4_pm_info, 0x0);
        if (sar_base) {
                pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
-               pm_info->wkup_sar_addr = sar_base +
-                                       CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+               if (cpu_is_omap44xx())
+                       pm_info->wkup_sar_addr = sar_base +
+                               CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+               else
+                       pm_info->wkup_sar_addr = sar_base +
+                               OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
                pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
        }
        pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
@@ -391,8 +396,12 @@ int __init omap4_mpuss_init(void)
        pm_info = &per_cpu(omap4_pm_info, 0x1);
        if (sar_base) {
                pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
-               pm_info->wkup_sar_addr = sar_base +
-                                       CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+               if (cpu_is_omap44xx())
+                       pm_info->wkup_sar_addr = sar_base +
+                               CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+               else
+                       pm_info->wkup_sar_addr = sar_base +
+                               OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
                pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
        }
 
@@ -453,15 +462,24 @@ void __init omap4_mpuss_early_init(void)
 {
        unsigned long startup_pa;
 
-       if (!cpu_is_omap44xx())
+       if (!(cpu_is_omap44xx() || soc_is_omap54xx()))
                return;
 
        sar_base = omap4_get_sar_ram_base();
 
        if (cpu_is_omap443x())
                startup_pa = virt_to_phys(omap4_secondary_startup);
-       else
+       else if (cpu_is_omap446x())
                startup_pa = virt_to_phys(omap4460_secondary_startup);
+       else if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
+               startup_pa = virt_to_phys(omap5_secondary_hyp_startup);
+       else
+               startup_pa = virt_to_phys(omap5_secondary_startup);
 
-       writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+       if (cpu_is_omap44xx())
+               writel_relaxed(startup_pa, sar_base +
+                              CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+       else
+               writel_relaxed(startup_pa, sar_base +
+                              OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
 }
index 792b1069f724ff6b121a406c077826ff916ed36a..5b2966a0f73308d2e552d7f768f45a107b05a7be 100644 (file)
@@ -31,6 +31,8 @@
 /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET          0xa04
 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET          0xa08
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET    0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET    0xe04
 
 #define SAR_BACKUP_STATUS_OFFSET               (SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET             (SAR_BANK3_OFFSET + 0x504)