Avoid locking in the interrupt context to improve latency. Since we
don't lock in the interrupt context, it is possible that we now could
race with the DRV_CONTROL register that writes the enable register and
cleared by the interrupt handler. For fire-n-forget requests, the
interrupt may be raised as soon as the TCS is triggered and the IRQ
handler may clear the enable bit before the DRV_CONTROL is read back.

Use the non-sync variant when enabling the TCS register to avoid reading
back a value that may been cleared because the interrupt handler ran
immediately after triggering the TCS.

Signed-off-by: Lina Iyer <[email protected]>
---
 drivers/soc/qcom/rpmh-rsc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index 5ede8d6de3ad..694ba881624e 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -242,9 +242,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
                write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
                write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0);
                write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
-               spin_lock(&drv->lock);
                clear_bit(i, drv->tcs_in_use);
-               spin_unlock(&drv->lock);
                if (req)
                        rpmh_tx_done(req, err);
        }
@@ -304,7 +302,7 @@ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
        enable = TCS_AMC_MODE_ENABLE;
        write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
        enable |= TCS_AMC_MODE_TRIGGER;
-       write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
+       write_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, enable);
 }
 
 static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

Reply via email to