diff --git a/docs/change-log.md b/docs/change-log.md index 841def96ad5241d5a2e3bfbc63e376ca381b0f0b..3ae5fabe953a929744d08f548f9de2999ee9e3bb 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -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 ================================== diff --git a/drivers/power/fvp_pwrc.c b/drivers/power/fvp_pwrc.c index 2b98b054d2f6dcad730462900f344117e3b74e50..cbaaa3d4a5164f384a6582f55759ac12b2f22d7a 100644 --- a/drivers/power/fvp_pwrc.c +++ b/drivers/power/fvp_pwrc.c @@ -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); diff --git a/drivers/power/fvp_pwrc.h b/drivers/power/fvp_pwrc.h index 050c33b64ba60b4a5d2d1d1005de62abb6bd771d..73d36df7a027855738d3dfc9cb4e2f5555e3ce23 100644 --- a/drivers/power/fvp_pwrc.h +++ b/drivers/power/fvp_pwrc.h @@ -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); diff --git a/plat/fvp/fvp_pm.c b/plat/fvp/fvp_pm.c index fd92526d5bc7562922450057794f157b4626fdfd..658a28594110ec9c30c2a3ef7086004b01b6f887 100644 --- a/plat/fvp/fvp_pm.c +++ b/plat/fvp/fvp_pm.c @@ -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);