diff options
author | Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 2011-06-09 13:35:02 +0200 |
---|---|---|
committer | said m bagheri <ebgheri@steludxu2848.(none)> | 2011-06-29 10:30:26 +0200 |
commit | d64b0f6a798e8dca1daf20d507430584f2a8c337 (patch) | |
tree | 05b7f59b9c4e460167f16d50db653160620aec10 /arch | |
parent | 43326d2c9a909cc43d887057d1793f0331f06c50 (diff) |
arm: ux500: prcmu_ac_wake_req workaround
This patch adds a check in prcmu_ac_wake_req that the modem is
awake (in terms of the value in the PRCM_MOD_AWAKE_STATUS
register) after the AC_WAKE_ACK has been received from the PRCMU
FW. If the check fails, a retry is made.
This seems to be necessary, since the modem can generate an
AC_WAKE_ACK, and then still go to sleep.
ST Ericsson ID: 340222
ST Ericsson FOSS-OUT ID: trivial
Change-Id: I01acbc72a376a995d5afd36ad88ecf70da911b63
Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/25132
Reviewed-by: Maxime COQUELIN <maxime.coquelin-nonst@stericsson.com>
Reviewed-by: Yann GAUTIER <yann.gautier@stericsson.com>
Reviewed-by: QATEST
Reviewed-by: Yvan FILLION <yvan.fillion@stericsson.com>
Tested-by: Yvan FILLION <yvan.fillion@stericsson.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-ux500/prcmu-db8500.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-ux500/prcmu-regs-db8500.h | 5 |
2 files changed, 33 insertions, 4 deletions
diff --git a/arch/arm/mach-ux500/prcmu-db8500.c b/arch/arm/mach-ux500/prcmu-db8500.c index d9c4e19785c..42b771c5ac2 100644 --- a/arch/arm/mach-ux500/prcmu-db8500.c +++ b/arch/arm/mach-ux500/prcmu-db8500.c @@ -1676,6 +1676,7 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) void prcmu_ac_wake_req(void) { u32 val; + u32 status; mutex_lock(&mb0_transfer.ac_wake_lock); @@ -1685,12 +1686,35 @@ void prcmu_ac_wake_req(void) atomic_set(&ac_wake_req_state, 1); +retry: writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + msecs_to_jiffies(5000))) { + panic("prcmu: %s timed out (5 s) waiting for a reply.\n", + __func__); + goto unlock_and_return; + } + + /* + * The modem can generate an AC_WAKE_ACK, and then still go to sleep. + * As a workaround, we wait, and then check that the modem is indeed + * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS + * register, which may not be the whole truth). + */ + udelay(400); + status = (readl(_PRCMU_BASE + PRCM_MOD_AWAKE_STATUS) & BITS(0, 2)); + if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE | + PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) { + pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n", + __func__, status); + udelay(1200); + writel(val, (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); + if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work, + msecs_to_jiffies(5000))) + goto retry; + panic("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n", __func__); } @@ -1715,8 +1739,8 @@ void prcmu_ac_sleep_req() (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, - msecs_to_jiffies(20000))) { - pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + msecs_to_jiffies(5000))) { + panic("prcmu: %s timed out (5 s) waiting for a reply.\n", __func__); } diff --git a/arch/arm/mach-ux500/prcmu-regs-db8500.h b/arch/arm/mach-ux500/prcmu-regs-db8500.h index 1014ea340cf..fa70144b42a 100644 --- a/arch/arm/mach-ux500/prcmu-regs-db8500.h +++ b/arch/arm/mach-ux500/prcmu-regs-db8500.h @@ -67,6 +67,11 @@ #define PRCM_ARM_IT1_CLR 0x48C #define PRCM_ARM_IT1_VAL 0x494 +#define PRCM_MOD_AWAKE_STATUS 0x4A0 +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE BIT(0) +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE BIT(1) +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_VMODEM_OFF_ISO BIT(2) + #define PRCM_ITSTATUS0 0x148 #define PRCM_ITSTATUS1 0x150 #define PRCM_ITSTATUS2 0x158 |