@@ -31,6 +31,12 @@
/* Time out Values in uSeconds*/
#define TIHELEN_ACKTIMEOUT 10000
+/*
+ * Time out for power state transition (in msecs), due to system
+ * latencies and HZ resolution this timer can vary.
+ */
+#define PWRSTST_TIMEOUT 200
+
/* Time delay for HOM->SAM transition. */
#define WAIT_SAM 1000000 /* in usec (1000 millisec) */
@@ -110,7 +110,7 @@ DSP_STATUS handle_hibernation_fromDSP(struct WMD_DEV_CONTEXT *pDevContext)
{
DSP_STATUS status = DSP_SOK;
#ifdef CONFIG_PM
- u16 usCount = TIHELEN_ACKTIMEOUT;
+ u16 usCount = PWRSTST_TIMEOUT / 10;
struct CFG_HOSTRES resources;
enum HW_PwrState_t pwrState;
#ifdef CONFIG_BRIDGE_DVFS
@@ -127,10 +127,12 @@ DSP_STATUS handle_hibernation_fromDSP(struct WMD_DEV_CONTEXT *pDevContext)
HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP,
&pwrState);
- /* Wait for DSP to move into Off state, how much time should
- * we wait? */
+ /* Wait for DSP to move into OFF state */
while ((pwrState != HW_PWR_STATE_OFF) && --usCount) {
- udelay(500);
+ if (msleep_interruptible(10)) {
+ pr_err("Waiting for DSP OFF mode interrupted\n");
+ return DSP_EFAIL;
+ }
HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP,
&pwrState);
}
@@ -195,7 +197,7 @@ DSP_STATUS SleepDSP(struct WMD_DEV_CONTEXT *pDevContext, IN u32 dwCmd,
#ifdef CONFIG_BRIDGE_NTFY_PWRERR
struct DEH_MGR *hDehMgr;
#endif /* CONFIG_BRIDGE_NTFY_PWRERR */
- u16 usCount = TIHELEN_ACKTIMEOUT;
+ u16 usCount = PWRSTST_TIMEOUT / 10;
enum HW_PwrState_t pwrState, targetPwrState;
DBG_Trace(DBG_LEVEL7, "SleepDSP- Enter function \n");
@@ -256,12 +258,12 @@ DSP_STATUS SleepDSP(struct WMD_DEV_CONTEXT *pDevContext, IN u32 dwCmd,
HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP,
&pwrState);
- /*
- * Wait for DSP to move into Standby state, how much time
- * should we wait?
- */
- while ((pwrState != targetPwrState) && --usCount) {
- udelay(500);
+ /* Wait for DSP to move into target power state */
+ while ((pwrState != targetPwrState) && usCount--) {
+ if (msleep_interruptible(10)) {
+ pr_err("Waiting for DSP to Suspend interrupted\n");
+ return DSP_EFAIL;
+ }
HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP,
&pwrState);
}