Commit 29707fab authored by Kiwoong Kim's avatar Kiwoong Kim Committed by Martin K. Petersen
Browse files

scsi: ufs: Change fDeviceInit busy wait

Currently, the UFS driver busy waits for fDeviceInit to be cleared. Provide
an upper bound and sleep between attempts instead of busy waiting.

Link: https://lore.kernel.org/r/1597053747-75171-1-git-send-email-kwmad.kim@samsung.com


Tested-by: default avatarKiwoong Kim <kwmad.kim@samsung.com>
Reviewed-by: default avatarAvri Altman <avri.altman@wdc.com>
Signed-off-by: default avatarKiwoong Kim <kwmad.kim@samsung.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b0008625
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -74,6 +74,9 @@
/* Default value of wait time before gating device ref clock */
#define UFSHCD_REF_CLK_GATING_WAIT_US 0xFF /* microsecs */

/* Polling time to wait for fDeviceInit */
#define FDEVICEINIT_COMPL_TIMEOUT 1500 /* millisecs */

#define ufshcd_toggle_vreg(_dev, _vreg, _on)				\
	({                                                              \
		int _ret;                                               \
@@ -4175,9 +4178,9 @@ EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode);
 */
static int ufshcd_complete_dev_init(struct ufs_hba *hba)
{
	int i;
	int err;
	bool flag_res = true;
	ktime_t timeout;

	err = ufshcd_query_flag_retry(hba, UPIU_QUERY_OPCODE_SET_FLAG,
		QUERY_FLAG_IDN_FDEVICEINIT, 0, NULL);
@@ -4188,20 +4191,26 @@ static int ufshcd_complete_dev_init(struct ufs_hba *hba)
		goto out;
	}

	/* poll for max. 1000 iterations for fDeviceInit flag to clear */
	for (i = 0; i < 1000 && !err && flag_res; i++)
		err = ufshcd_query_flag_retry(hba, UPIU_QUERY_OPCODE_READ_FLAG,
	/* Poll fDeviceInit flag to be cleared */
	timeout = ktime_add_ms(ktime_get(), FDEVICEINIT_COMPL_TIMEOUT);
	do {
		err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,
					QUERY_FLAG_IDN_FDEVICEINIT, 0, &flag_res);
		if (!flag_res)
			break;
		usleep_range(5000, 10000);
	} while (ktime_before(ktime_get(), timeout));

	if (err)
	if (err) {
		dev_err(hba->dev,
				"%s reading fDeviceInit flag failed with error %d\n",
				__func__, err);
	else if (flag_res)
	} else if (flag_res) {
		dev_err(hba->dev,
				"%s fDeviceInit was not cleared by the device\n",
				__func__);

		err = -EBUSY;
	}
out:
	return err;
}