mfd: Update db8500-prmcu hostport_access enable
authorArun Murthy <arun.murthy@stericsson.com>
Mon, 21 May 2012 08:58:21 +0000 (14:28 +0530)
committerSamuel Ortiz <sameo@linux.intel.com>
Sun, 8 Jul 2012 22:16:10 +0000 (00:16 +0200)
Force the Modem wakeup by asserting the CaWakeReq signal before the
hostaccess_req/ack ping-pong sequence. The Awake_req signal is de-asserted
asserted at the same time than the hostaccess_req. Return error on failure
case so that the client using this can take appropiate steps.

Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/mfd/db8500-prcmu.c
drivers/mfd/dbx500-prcmu-regs.h
include/linux/mfd/db8500-prcmu.h
include/linux/mfd/dbx500-prcmu.h

index bf5a054a2b91e73ac80d1a6c3f69931c3288fc8e..f4adcabb2a51262c3c1d26807dde0576ad9f2172 100644 (file)
@@ -2269,10 +2269,10 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
 /**
  * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem
  */
-void prcmu_ac_wake_req(void)
+int prcmu_ac_wake_req(void)
 {
        u32 val;
-       u32 status;
+       int ret = 0;
 
        mutex_lock(&mb0_transfer.ac_wake_lock);
 
@@ -2282,39 +2282,32 @@ void prcmu_ac_wake_req(void)
 
        atomic_set(&ac_wake_req_state, 1);
 
-retry:
-       writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ);
+       /*
+        * Force Modem Wake-up before hostaccess_req ping-pong.
+        * It prevents Modem to enter in Sleep while acking the hostaccess
+        * request. The 31us delay has been calculated by HWI.
+        */
+       val |= PRCM_HOSTACCESS_REQ_WAKE_REQ;
+       writel(val, PRCM_HOSTACCESS_REQ);
+
+       udelay(31);
+
+       val |= PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ;
+       writel(val, PRCM_HOSTACCESS_REQ);
 
        if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
                        msecs_to_jiffies(5000))) {
+#if defined(CONFIG_DBX500_PRCMU_DEBUG)
+               db8500_prcmu_debug_dump(__func__, true, true);
+#endif
                pr_crit("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(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, PRCM_HOSTACCESS_REQ);
-               if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
-                               msecs_to_jiffies(5000)))
-                       goto retry;
-               pr_crit("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n",
-                       __func__);
+               ret = -EFAULT;
        }
 
 unlock_and_return:
        mutex_unlock(&mb0_transfer.ac_wake_lock);
+       return ret;
 }
 
 /**
index 3a0bf91d7780894a552f0f83d0cd9defb4637c63..23108a6e316782612eafda90cb2944b37a644e0e 100644 (file)
 
 #define PRCM_HOSTACCESS_REQ    (_PRCMU_BASE + 0x334)
 #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1
+#define PRCM_HOSTACCESS_REQ_WAKE_REQ   BIT(16)
 #define ARM_WAKEUP_MODEM       0x1
 
 #define PRCM_ARM_IT1_CLR       (_PRCMU_BASE + 0x48C)
index b3a43b1263fead2092a4bffd7b87d878e5c0cbb5..b82f6ee66a0bb21849777fddbdffdc3585ca03d1 100644 (file)
@@ -530,7 +530,7 @@ int db8500_prcmu_stop_temp_sense(void);
 int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
 int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
 
-void prcmu_ac_wake_req(void);
+int prcmu_ac_wake_req(void);
 void prcmu_ac_sleep_req(void);
 void db8500_prcmu_modem_reset(void);
 
@@ -680,7 +680,10 @@ static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
        return -ENOSYS;
 }
 
-static inline void prcmu_ac_wake_req(void) {}
+static inline int prcmu_ac_wake_req(void)
+{
+       return 0;
+}
 
 static inline void prcmu_ac_sleep_req(void) {}
 
index 5a13f93d8f1c97325ceb3d562ab0741c9ededdee..5b90e94399e1b2d8707885ee85be713b9288ab57 100644 (file)
@@ -345,7 +345,7 @@ static inline u16 prcmu_get_reset_code(void)
        return db8500_prcmu_get_reset_code();
 }
 
-void prcmu_ac_wake_req(void);
+int prcmu_ac_wake_req(void);
 void prcmu_ac_sleep_req(void);
 static inline void prcmu_modem_reset(void)
 {
@@ -533,7 +533,10 @@ static inline u16 prcmu_get_reset_code(void)
        return 0;
 }
 
-static inline void prcmu_ac_wake_req(void) {}
+static inline int prcmu_ac_wake_req(void)
+{
+       return 0;
+}
 
 static inline void prcmu_ac_sleep_req(void) {}