aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMattias Nilsson <mattias.i.nilsson@stericsson.com>2011-06-09 13:35:02 +0200
committersaid m bagheri <ebgheri@steludxu2848.(none)>2011-06-29 10:30:26 +0200
commitd64b0f6a798e8dca1daf20d507430584f2a8c337 (patch)
tree05b7f59b9c4e460167f16d50db653160620aec10 /arch
parent43326d2c9a909cc43d887057d1793f0331f06c50 (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.c32
-rw-r--r--arch/arm/mach-ux500/prcmu-regs-db8500.h5
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