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

Commit facc9df1 authored by Subhash Jadavani's avatar Subhash Jadavani
Browse files

scsi: ufs: fix deadlock during runtime resume



Commit e21cdd59 (scsi: ufs: Change power
mode at run-time via debug-fs) has introduced bug where
pm_runtime_get_sync() might get called in UFS driver's runtime resume
callback context which will cause the deadlock as pm_runtime_get_sync()
waits for the runtime resume callback to finish.

This change fixes the above bug by moving pm_runtime_get_sync() call out
of runtime resume callback context.

Change-Id: I1efa68510eb2545fc043dfa4d8bfe6f6c36ef6a8
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 0c694e68
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -693,7 +693,9 @@ static ssize_t ufsdbg_power_mode_write(struct file *file,
		__func__, pwr_mode.gear_rx, pwr_mode.gear_tx, pwr_mode.lane_rx,
		pwr_mode.lane_tx, pwr_mode.pwr_rx, pwr_mode.pwr_tx);

	pm_runtime_get_sync(hba->dev);
	ret = ufshcd_config_pwr_mode(hba, &pwr_mode);
	pm_runtime_put_sync(hba->dev);
	if (ret == -EBUSY)
		dev_err(hba->dev,
			"%s: ufshcd_config_pwr_mode failed: system is busy, try again\n",
+0 −4
Original line number Diff line number Diff line
@@ -1248,7 +1248,6 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
	unsigned long flags;

	ufshcd_hold(hba, false);
	pm_runtime_get_sync(hba->dev);
	mutex_lock(&hba->uic_cmd_mutex);
	spin_lock_irqsave(hba->host->host_lock, flags);
	ret = __ufshcd_send_uic_cmd(hba, uic_cmd);
@@ -1257,7 +1256,6 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
		ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd);

	mutex_unlock(&hba->uic_cmd_mutex);
	pm_runtime_put_sync(hba->dev);
	ufshcd_release(hba);
	return ret;
}
@@ -2598,7 +2596,6 @@ int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
	int retries = POWER_MODE_RETRIES;

	ufshcd_hold(hba, false);
	pm_runtime_get_sync(hba->dev);
	mutex_lock(&hba->uic_cmd_mutex);
	init_completion(&uic_async_done);

@@ -2667,7 +2664,6 @@ out:
	hba->uic_async_done = NULL;
	spin_unlock_irqrestore(hba->host->host_lock, flags);
	mutex_unlock(&hba->uic_cmd_mutex);
	pm_runtime_put_sync(hba->dev);
	ufshcd_release(hba);
	return ret;
}