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

Commit 4f0df17b authored by Subhash Jadavani's avatar Subhash Jadavani
Browse files

scsi: ufs: clear and apply dev_quirks on every device probe



We should clear the dev_quirks on every device probe to make sure
that we apply the quirks for newly detected UFS device. This is
particularly important with removable UFS devices.

Change-Id: I4632741c3a3b281c4c5a6c4a1887bad8fa18676b
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 23df2316
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1271,7 +1271,7 @@ static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
{
	int err = 0;

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
	if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
		err = ufs_qcom_quirk_host_pa_saveconfigtime(hba);

	return err;
+3 −0
Original line number Diff line number Diff line
@@ -515,6 +515,9 @@ struct ufs_dev_info {
	bool is_lu_power_on_wp;
	/* is Unit Attention Condition cleared on UFS Device LUN? */
	unsigned is_ufs_dev_wlun_ua_cleared:1;

	/* Device deviations from standard UFS device spec. */
	unsigned int quirks;
};

#endif /* End of Header */
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ void ufs_advertise_fixup_device(struct ufs_hba *hba)
		    (STR_PRFX_EQUAL(f->model, model) ||
		     !strcmp(f->model, UFS_ANY_MODEL)))
			/* update quirks */
			hba->dev_quirks |= f->quirk;
			hba->dev_info.quirks |= f->quirk;
	}
out:
	kfree(model);
+10 −9
Original line number Diff line number Diff line
@@ -638,7 +638,7 @@ static void ufshcd_print_host_state(struct ufs_hba *hba)
	dev_err(hba->dev, "Host capabilities=0x%x, caps=0x%x\n",
		hba->capabilities, hba->caps);
	dev_err(hba->dev, "quirks=0x%x, dev. quirks=0x%x\n", hba->quirks,
		hba->dev_quirks);
		hba->dev_info.quirks);
}

/**
@@ -4611,7 +4611,7 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
			goto out;
	}

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_BROKEN_LCC) {
	if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_BROKEN_LCC) {
		ret = ufshcd_disable_host_tx_lcc(hba);
		if (ret)
			goto out;
@@ -5638,7 +5638,8 @@ static void ufshcd_err_handler(struct work_struct *work)
	/* Complete requests that have door-bell cleared by h/w */
	ufshcd_complete_requests(hba);

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) {
	if (hba->dev_info.quirks &
	    UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) {
		bool ret;

		spin_unlock_irqrestore(hba->host->host_lock, flags);
@@ -5808,7 +5809,7 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba)

	if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) {
		hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR;
	} else if (hba->dev_quirks &
	} else if (hba->dev_info.quirks &
		   UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) {
		if (reg & UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED)
			hba->uic_error |=
@@ -6818,11 +6819,11 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
		ufshcd_tune_pa_hibern8time(hba);
	}

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE)
	if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE)
		/* set 1ms timeout for PA_TACTIVATE */
		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 10);

	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
	if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
		ufshcd_quirk_tune_host_pa_tactivate(hba);

	ufshcd_vops_apply_dev_quirks(hba);
@@ -6846,7 +6847,7 @@ static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)

static void ufshcd_apply_pm_quirks(struct ufs_hba *hba)
{
	if (hba->dev_quirks & UFS_DEVICE_QUIRK_NO_LINK_OFF) {
	if (hba->dev_info.quirks & UFS_DEVICE_QUIRK_NO_LINK_OFF) {
		if (ufs_get_pm_lvl_to_link_pwr_state(hba->rpm_lvl) ==
		    UIC_LINK_OFF_STATE) {
			hba->rpm_lvl =
@@ -6996,7 +6997,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)

	ufshcd_apply_pm_quirks(hba);
	ret = ufshcd_set_vccq_rail_unused(hba,
		(hba->dev_quirks & UFS_DEVICE_NO_VCCQ) ? true : false);
		(hba->dev_info.quirks & UFS_DEVICE_NO_VCCQ) ? true : false);
	if (ret)
		goto out;

@@ -8880,7 +8881,7 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
			/* scale down gear */
			new_pwr_info.gear_tx = scale_down_gear;
			new_pwr_info.gear_rx = scale_down_gear;
			if (!(hba->dev_quirks & UFS_DEVICE_NO_FASTAUTO)) {
			if (!(hba->dev_info.quirks & UFS_DEVICE_NO_FASTAUTO)) {
				new_pwr_info.pwr_tx = FASTAUTO_MODE;
				new_pwr_info.pwr_rx = FASTAUTO_MODE;
			}
+0 −3
Original line number Diff line number Diff line
@@ -774,9 +774,6 @@ struct ufs_hba {

	unsigned int quirks;	/* Deviations from standard UFSHCI spec. */

	/* Device deviations from standard UFS device spec. */
	unsigned int dev_quirks;

	wait_queue_head_t tm_wq;
	wait_queue_head_t tm_tag_wq;
	unsigned long tm_condition;