Commit 96a7141d authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Martin K. Petersen

scsi: ufs: core: Add support for reinitializing the UFS device

Some platforms like Qcom, requires the UFS device to be reinitialized after
switching to maximum gear speed. So add support for that in UFS core by
introducing a new quirk (UFSHCD_CAP_REINIT_AFTER_MAX_GEAR_SWITCH) and doing
the reinitialization, if the quirk is enabled by the controller driver.
Suggested-by: default avatarCan Guo <quic_cang@quicinc.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # Qdrive3/sa8540p-ride
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c2c38c57
......@@ -8231,27 +8231,18 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
return ret;
}
/**
* ufshcd_probe_hba - probe hba to detect device and initialize it
* @hba: per-adapter instance
* @init_dev_params: whether or not to call ufshcd_device_params_init().
*
* Execute link-startup and verify device initialization
*/
static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params)
{
int ret;
unsigned long flags;
ktime_t start = ktime_get();
hba->ufshcd_state = UFSHCD_STATE_RESET;
ret = ufshcd_link_startup(hba);
if (ret)
goto out;
return ret;
if (hba->quirks & UFSHCD_QUIRK_SKIP_PH_CONFIGURATION)
goto out;
return ret;
/* Debug counters initialization */
ufshcd_clear_dbg_ufs_stats(hba);
......@@ -8262,12 +8253,12 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
/* Verify device initialization by sending NOP OUT UPIU */
ret = ufshcd_verify_dev_init(hba);
if (ret)
goto out;
return ret;
/* Initiate UFS initialization, and waiting until completion */
ret = ufshcd_complete_dev_init(hba);
if (ret)
goto out;
return ret;
/*
* Initialize UFS device parameters used by driver, these
......@@ -8276,7 +8267,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
if (init_dev_params) {
ret = ufshcd_device_params_init(hba);
if (ret)
goto out;
return ret;
}
ufshcd_tune_unipro_params(hba);
......@@ -8297,11 +8288,51 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
if (ret) {
dev_err(hba->dev, "%s: Failed setting power mode, err = %d\n",
__func__, ret);
return ret;
}
}
return 0;
}
/**
* ufshcd_probe_hba - probe hba to detect device and initialize it
* @hba: per-adapter instance
* @init_dev_params: whether or not to call ufshcd_device_params_init().
*
* Execute link-startup and verify device initialization
*/
static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params)
{
ktime_t start = ktime_get();
unsigned long flags;
int ret;
ret = ufshcd_device_init(hba, init_dev_params);
if (ret)
goto out;
if (hba->quirks & UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH) {
/* Reset the device and controller before doing reinit */
ufshcd_device_reset(hba);
ufshcd_hba_stop(hba);
ufshcd_vops_reinit_notify(hba);
ret = ufshcd_hba_enable(hba);
if (ret) {
dev_err(hba->dev, "Host controller enable failed\n");
ufshcd_print_evt_hist(hba);
ufshcd_print_host_state(hba);
goto out;
}
ufshcd_print_pwr_info(hba);
/* Reinit the device */
ret = ufshcd_device_init(hba, init_dev_params);
if (ret)
goto out;
}
ufshcd_print_pwr_info(hba);
/*
* bActiveICCLevel is volatile for UFS device (as per latest v2.1 spec)
* and for removable UFS card as well, hence always set the parameter.
......
......@@ -596,6 +596,12 @@ enum ufshcd_quirks {
* auto-hibernate capability but it's FASTAUTO only.
*/
UFSHCD_QUIRK_HIBERN_FASTAUTO = 1 << 18,
/*
* This quirk needs to be enabled if the host controller needs
* to reinit the device after switching to maximum gear.
*/
UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH = 1 << 19,
};
enum ufshcd_caps {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment