From b09c22c040d134cc316048e95be617199d4da7ec Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena Date: Tue, 7 Mar 2017 16:53:38 +0530 Subject: msm: ipa: Fix incorrect wakelock handling For every __pm_stay_awake call, there must be a __pm_relax call to ensure there is no stale wakelock is held. with the current logic __pm_stay_awake is called whenever wakelock ref cnt is non-zero and released only when it is 0. This leads to wakelock being held even when it is not required. Make a change to acquire wakelock only when it is not held previously. Change-Id: I8c61c184506c705fd5866de8a606f642c5de3d5b Acked-by: Chaitanya Pratapa Signed-off-by: Utkarsh Saxena --- drivers/platform/msm/ipa/ipa_v2/ipa.c | 12 +++++++++--- drivers/platform/msm/ipa/ipa_v2/ipa_i.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index d4b0dd9910e1..553480660722 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -3418,11 +3418,14 @@ void ipa_inc_acquire_wakelock(enum ipa_wakelock_ref_client ref_client) return; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); if (ipa_ctx->wakelock_ref_cnt.cnt & (1 << ref_client)) - IPAERR("client enum %d mask already set. ref cnt = %d\n", + IPADBG("client enum %d mask already set. ref cnt = %d\n", ref_client, ipa_ctx->wakelock_ref_cnt.cnt); ipa_ctx->wakelock_ref_cnt.cnt |= (1 << ref_client); - if (ipa_ctx->wakelock_ref_cnt.cnt) + if (ipa_ctx->wakelock_ref_cnt.cnt && + !ipa_ctx->wakelock_ref_cnt.wakelock_acquired) { __pm_stay_awake(&ipa_ctx->w_lock); + ipa_ctx->wakelock_ref_cnt.wakelock_acquired = true; + } IPADBG_LOW("active wakelock ref cnt = %d client enum %d\n", ipa_ctx->wakelock_ref_cnt.cnt, ref_client); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); @@ -3446,8 +3449,11 @@ void ipa_dec_release_wakelock(enum ipa_wakelock_ref_client ref_client) ipa_ctx->wakelock_ref_cnt.cnt &= ~(1 << ref_client); IPADBG_LOW("active wakelock ref cnt = %d client enum %d\n", ipa_ctx->wakelock_ref_cnt.cnt, ref_client); - if (ipa_ctx->wakelock_ref_cnt.cnt == 0) + if (ipa_ctx->wakelock_ref_cnt.cnt == 0 && + ipa_ctx->wakelock_ref_cnt.wakelock_acquired) { __pm_relax(&ipa_ctx->w_lock); + ipa_ctx->wakelock_ref_cnt.wakelock_acquired = false; + } spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index 94d76db6f993..a14d1fee9c35 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -841,6 +841,7 @@ struct ipa_active_clients { struct ipa_wakelock_ref_cnt { spinlock_t spinlock; u32 cnt; + bool wakelock_acquired; }; struct ipa_tag_completion { -- cgit v1.2.3