diff --git a/drivers/platform/tegra/dce/dce-worker.c b/drivers/platform/tegra/dce/dce-worker.c index 338a1433..0299c192 100644 --- a/drivers/platform/tegra/dce/dce-worker.c +++ b/drivers/platform/tegra/dce/dce-worker.c @@ -36,14 +36,23 @@ int dce_wait_interruptible(struct tegra_dce *d, u32 msg_id) } wait = &d->ipc_waits[msg_id]; - atomic_set(&wait->complete, 0); + /* + * It is possible that we received the ACK from DCE even before we + * start waiting. But that should not be an issue as wait->complete + * Will be "1" and we immediately exit from the wait. + */ DCE_COND_WAIT_INTERRUPTIBLE(&wait->cond_wait, atomic_read(&wait->complete) == 1); if (atomic_read(&wait->complete) != 1) return -EINTR; + /* + * Clear wait->complete as soon as we exit from wait (consume the wake call) + * So that when the next dce_wait_interruptible is called, it doesn't see old + * wait->complete state. + */ atomic_set(&wait->complete, 0); return 0; } @@ -67,6 +76,11 @@ void dce_wakeup_interruptible(struct tegra_dce *d, u32 msg_id) wait = &d->ipc_waits[msg_id]; + /* + * Set wait->complete to "1", so if the wait is called even after + * "dce_cond_signal_interruptible", it'll see the complete variable + * as "1" and exit the wait immediately. + */ atomic_set(&wait->complete, 1); dce_cond_signal_interruptible(&wait->cond_wait); }