Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20891d1b authored by Nitin Rawat's avatar Nitin Rawat
Browse files

scsi: ufs: Fix clock gating issue



commit <f0e7e5ba> ("Avoid potential lrb race caused by early
release of lrb_in_use") holds lrb_in_use till all operations
of lrbp is finished to avoid the potential race with
the next task which may use the same lrbp in some corner
case. As part of this change, clear_bit_unlock API
was moved down just before scsi_done call.

Due to which _ufshcd_release is called before we reset the bit
for particular request tag in hba->lrb_in_use flag.
Hence for the last request in completion handler, _ufshcd_release
is called with non zero value of hba->lrb_in_use and hence its
return without scheduling the hr timer to start the gate work.
Due to which clock are not getting turned off and it remains
on till runtime suspend kicks in. This is causing ufs
power consumption issue.

To fix this, move down __ufshcd_release and
__ufshcd_hibern8_release function after the clear_bit_unlock,
so that __ufshcd_release will be called with updated
value of hba->lrb_in_use flag .

Change-Id: I3b42bcd1f7bf12adb3e769154de221d700defa2c
Signed-off-by: default avatarNitin Rawat <nitirawa@codeaurora.org>
parent e39cf4ae
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -6502,8 +6502,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
			/* Mark completed command as NULL in LRB */
			lrbp->cmd = NULL;
			hba->ufs_stats.clk_rel.ctx = XFR_REQ_COMPL;
			__ufshcd_release(hba, false);
			__ufshcd_hibern8_release(hba, false);
			if (cmd->request) {
				/*
				 * As we are accessing the "request" structure,
@@ -6515,6 +6513,17 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
			}

			clear_bit_unlock(index, &hba->lrb_in_use);
			/*
			 *__ufshcd_release and __ufshcd_hibern8_release is
			 * called after clear_bit_unlock so that
			 * these function can be called with updated state of
			 * lrb_in_use flag so that for last transfer req
			 * completion, gate and hibernate work function would
			 * be called to gate the clock and put the link in
			 * hibern8 state.
			 */
			__ufshcd_release(hba, false);
			__ufshcd_hibern8_release(hba, false);

			/* Do not touch lrbp after scsi done */
			cmd->scsi_done(cmd);
@@ -6570,7 +6579,6 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result)
			update_req_stats(hba, lrbp);
			/* Mark completed command as NULL in LRB */
			lrbp->cmd = NULL;
			ufshcd_release_all(hba);
			if (cmd->request) {
				/*
				 * As we are accessing the "request" structure,
@@ -6581,6 +6589,17 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result)
					true);
			}
			clear_bit_unlock(index, &hba->lrb_in_use);

			/*
			 * ufshcd_release_all is called after clear_bit_unlock
			 * so that the function can be called with updated state
			 * of lrb_in_use flag so that for last abort req
			 * completion, gate and hibernate work function would
			 * be called to gate the clock and put the link in
			 * hibern8 state.
			 */
			 ufshcd_release_all(hba);

			/* Do not touch lrbp after scsi done */
			cmd->scsi_done(cmd);
		} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE) {