forked from Minki/linux
351b7c4907
Commit3251885285
("ARM: OMAP4+: Reset CPU1 properly for kexec") started unconditionally resetting CPU1 because of a kexec boot issue I was seeing earlier on omap4 when doing kexec boot between two different kernel versions. This caused issues on some systems. We should only reset CPU1 as a last resort option, and try to avoid it where possible. Doing an unconditional CPU1 reset causes issues for example when booting a bootloader configured secure OS running on CPU1 as reported by Andrew F. Davis <afd@ti.com>. We can't completely remove the reset of CPU1 as it would break kexec booting from older kernels. But we can limit the CPU1 reset to cases where CPU1 is wrongly parked within the memory area used by the booting kernel. Then later on we can add support for parking CPU1 for kexec out of the SDRAM back to bootrom. So let's first fix the regression reported by Andrew by making CPU1 reset conditional. To do this, we need to: 1. Save configured AUX_CORE_BOOT_1 for later 2. Modify AUX_CORE_BOOT_0 reading code to for HS SoCs to return the whole register instead of the CPU mask 3. Check if CPU1 is wrongly parked into the booting kernel by the previous kernel and reset if needed Fixes:3251885285
("ARM: OMAP4+: Reset CPU1 properly for kexec") Reported-by: Andrew F. Davis <afd@ti.com> Cc: Andrew F. Davis <afd@ti.com> Cc: Keerthy <j-keerthy@ti.com> Cc: Russell King <rmk+kernel@armlinux.org.uk> Cc: Santosh Shilimkar <ssantosh@kernel.org> Cc: Tero Kristo <t-kristo@ti.com> Tested-by: Keerthy <j-keerthy@ti.com> Tested-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
73 lines
1.6 KiB
C
73 lines
1.6 KiB
C
/*
|
|
* OMAP4 SMP cpu-hotplug support
|
|
*
|
|
* Copyright (C) 2010 Texas Instruments, Inc.
|
|
* Author:
|
|
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
|
*
|
|
* Platform file needed for the OMAP4 SMP. This file is based on arm
|
|
* realview smp platform.
|
|
* Copyright (c) 2002 ARM Limited.
|
|
*
|
|
* 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/io.h>
|
|
|
|
#include "omap-wakeupgen.h"
|
|
#include "common.h"
|
|
#include "powerdomain.h"
|
|
|
|
/*
|
|
* platform-specific code to shutdown a CPU
|
|
* Called with IRQs disabled
|
|
*/
|
|
void omap4_cpu_die(unsigned int cpu)
|
|
{
|
|
unsigned int boot_cpu = 0;
|
|
void __iomem *base = omap_get_wakeupgen_base();
|
|
|
|
/*
|
|
* we're ready for shutdown now, so do it
|
|
*/
|
|
if (omap_secure_apis_support()) {
|
|
if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
|
|
pr_err("Secure clear status failed\n");
|
|
} else {
|
|
writel_relaxed(0, base + OMAP_AUX_CORE_BOOT_0);
|
|
}
|
|
|
|
|
|
for (;;) {
|
|
/*
|
|
* Enter into low power state
|
|
*/
|
|
omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
|
|
|
|
if (omap_secure_apis_support())
|
|
boot_cpu = omap_read_auxcoreboot0() >> 9;
|
|
else
|
|
boot_cpu =
|
|
readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5;
|
|
|
|
if (boot_cpu == smp_processor_id()) {
|
|
/*
|
|
* OK, proper wakeup, we're done
|
|
*/
|
|
break;
|
|
}
|
|
pr_debug("CPU%u: spurious wakeup call\n", cpu);
|
|
}
|
|
}
|
|
|
|
/* Needed by kexec and platform_can_cpu_hotplug() */
|
|
int omap4_cpu_kill(unsigned int cpu)
|
|
{
|
|
return 1;
|
|
}
|