From c3646075c203bb2e47a600b4e3f24627b4c1f8d7 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 24 Feb 2017 11:22:03 -0800 Subject: [PATCH] msm: ipa3: fix a race condition on clock vote from suspend There is a potential race condition where suspend interrupt handling might be running from two different context in parallel. Add a mutex to ensure mutual exclusion when voting for IPA clocks. CRs-Fixed: 2037199 Change-Id: I7f14866696b6c9f5e239f3de2c4bad6991097ecb Acked-by: Ady Abraham Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v2/ipa.c | 2 ++ drivers/platform/msm/ipa/ipa_v3/ipa.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index f01743d04e84..0629d6bca49a 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -3685,6 +3685,7 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, * pipe will be unsuspended as part of * enabling IPA clocks */ + mutex_lock(&ipa_ctx->sps_pm.sps_pm_lock); if (!atomic_read( &ipa_ctx->sps_pm.dec_clients) ) { @@ -3697,6 +3698,7 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, 1); ipa_sps_process_irq_schedule_rel(); } + mutex_unlock(&ipa_ctx->sps_pm.sps_pm_lock); } else { resource = ipa2_get_rm_resource_from_ep(i); res = ipa_rm_request_resource_with_timer( diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 5ee6e5d2d9e3..5a7a0e5000b9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -3614,6 +3614,8 @@ void ipa3_suspend_handler(enum ipa_irq_type interrupt, * pipe will be unsuspended as part of * enabling IPA clocks */ + mutex_lock(&ipa3_ctx->transport_pm. + transport_pm_mutex); if (!atomic_read( &ipa3_ctx->transport_pm.dec_clients) ) { @@ -3626,6 +3628,8 @@ void ipa3_suspend_handler(enum ipa_irq_type interrupt, 1); ipa3_sps_process_irq_schedule_rel(); } + mutex_unlock(&ipa3_ctx->transport_pm. + transport_pm_mutex); } else { resource = ipa3_get_rm_resource_from_ep(i); res =