Commit b127cdb8 authored by Achin Gupta's avatar Achin Gupta Committed by Dan Handley
Browse files

clear wakeup enable bit upon resuming from suspend

The FVP specific code that gets called after a cpu has been physically
powered on after having been turned off or suspended earlier does not
clear the PWRC.PWKUPR.WEN bit. Not doing so causes problems if: a cpu
is suspended, woken from suspend, powered down through a cpu_off call
& receives a spurious interrupt. Since the WEN bit is not cleared
after the cpu woke up from suspend, the spurious wakeup will power the
cpu on. Since the cpu_off call clears the jump address in the mailbox
this spurious wakeup will cause the cpu to crash.

This patch fixes this issue by clearing the WEN bit whenever a cpu is
powered up.

Change-Id: Ic91f5dffe1ed01d76bc7fc807acf0ecd3e38ce5b
parent 4a826dda
......@@ -45,6 +45,9 @@ Detailed changes since last release
instructions for how to contribute and update copyright text in all files to
acknowledge contributors.
* The wake up enable bit in the FVP power controller is cleared when a cpu is
physically powered up to prevent a spurious wake up from a subsequent cpu
off state.
ARM Trusted Firmware - version 0.2
==================================
......
......@@ -77,7 +77,7 @@ void fvp_pwrc_write_ppoffr(unsigned long mpidr)
bakery_lock_release(mpidr, &pwrc_lock);
}
void fvp_pwrc_write_pwkupr(unsigned long mpidr)
void fvp_pwrc_set_wen(unsigned long mpidr)
{
bakery_lock_get(mpidr, &pwrc_lock);
mmio_write_32(PWRC_BASE + PWKUPR_OFF,
......@@ -85,6 +85,14 @@ void fvp_pwrc_write_pwkupr(unsigned long mpidr)
bakery_lock_release(mpidr, &pwrc_lock);
}
void fvp_pwrc_clr_wen(unsigned long mpidr)
{
bakery_lock_get(mpidr, &pwrc_lock);
mmio_write_32(PWRC_BASE + PWKUPR_OFF,
(unsigned int) mpidr);
bakery_lock_release(mpidr, &pwrc_lock);
}
void fvp_pwrc_write_pcoffr(unsigned long mpidr)
{
bakery_lock_get(mpidr, &pwrc_lock);
......
......@@ -67,7 +67,8 @@ extern int fvp_pwrc_setup(void);
extern void fvp_pwrc_write_pcoffr(unsigned long);
extern void fvp_pwrc_write_ppoffr(unsigned long);
extern void fvp_pwrc_write_pponr(unsigned long);
extern void fvp_pwrc_write_pwkupr(unsigned long);
extern void fvp_pwrc_set_wen(unsigned long);
extern void fvp_pwrc_clr_wen(unsigned long);
extern unsigned int fvp_pwrc_read_psysr(unsigned long);
extern unsigned int fvp_pwrc_get_cpu_wkr(unsigned long);
......
......@@ -251,7 +251,7 @@ int fvp_affinst_suspend(unsigned long mpidr,
* Program the power controller to power this
* cpu off and enable wakeup interrupts.
*/
fvp_pwrc_write_pwkupr(mpidr);
fvp_pwrc_set_wen(mpidr);
fvp_pwrc_write_ppoffr(mpidr);
}
break;
......@@ -309,6 +309,12 @@ int fvp_affinst_on_finish(unsigned long mpidr,
write_cpuectlr(ectlr);
}
/*
* Clear PWKUPR.WEN bit to ensure interrupts do not interfere
* with a cpu power down unless the bit is set again
*/
fvp_pwrc_clr_wen(mpidr);
/* Zero the jump address in the mailbox for this cpu */
fvp_mboxes = (mailbox *) (TZDRAM_BASE + MBOX_OFF);
linear_id = platform_get_core_pos(mpidr);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment