diff options
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r-- | drivers/scsi/ufs/ufs-hisi.c | 15 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs-mediatek.c | 4 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs-sysfs.c | 12 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 12 |
4 files changed, 28 insertions, 15 deletions
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 0aa58131e791..d0626773eb38 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -467,21 +467,24 @@ static int ufs_hisi_init_common(struct ufs_hba *hba) host->hba = hba; ufshcd_set_variant(hba, host); - host->rst = devm_reset_control_get(dev, "rst"); + host->rst = devm_reset_control_get(dev, "rst"); if (IS_ERR(host->rst)) { dev_err(dev, "%s: failed to get reset control\n", __func__); - return PTR_ERR(host->rst); + err = PTR_ERR(host->rst); + goto error; } ufs_hisi_set_pm_lvl(hba); err = ufs_hisi_get_resource(host); - if (err) { - ufshcd_set_variant(hba, NULL); - return err; - } + if (err) + goto error; return 0; + +error: + ufshcd_set_variant(hba, NULL); + return err; } static int ufs_hi3660_init(struct ufs_hba *hba) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index a981f261b304..aee3cfc7142a 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -922,6 +922,7 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm) static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) { int err; + struct arm_smccc_res res; if (ufshcd_is_link_hibern8(hba)) { err = ufs_mtk_link_set_lpm(hba); @@ -941,6 +942,9 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) goto fail; } + if (ufshcd_is_link_off(hba)) + ufs_mtk_device_reset_ctrl(0, res); + return 0; fail: /* diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index d7c3cff9662f..5d0e98a05ada 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -9,7 +9,7 @@ #include "ufs.h" #include "ufs-sysfs.h" -static const char *ufschd_uic_link_state_to_string( +static const char *ufshcd_uic_link_state_to_string( enum uic_link_state state) { switch (state) { @@ -21,7 +21,7 @@ static const char *ufschd_uic_link_state_to_string( } } -static const char *ufschd_ufs_dev_pwr_mode_to_string( +static const char *ufshcd_ufs_dev_pwr_mode_to_string( enum ufs_dev_pwr_mode state) { switch (state) { @@ -81,7 +81,7 @@ static ssize_t rpm_target_dev_state_show(struct device *dev, { struct ufs_hba *hba = dev_get_drvdata(dev); - return sysfs_emit(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( + return sysfs_emit(buf, "%s\n", ufshcd_ufs_dev_pwr_mode_to_string( ufs_pm_lvl_states[hba->rpm_lvl].dev_state)); } @@ -90,7 +90,7 @@ static ssize_t rpm_target_link_state_show(struct device *dev, { struct ufs_hba *hba = dev_get_drvdata(dev); - return sysfs_emit(buf, "%s\n", ufschd_uic_link_state_to_string( + return sysfs_emit(buf, "%s\n", ufshcd_uic_link_state_to_string( ufs_pm_lvl_states[hba->rpm_lvl].link_state)); } @@ -113,7 +113,7 @@ static ssize_t spm_target_dev_state_show(struct device *dev, { struct ufs_hba *hba = dev_get_drvdata(dev); - return sysfs_emit(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( + return sysfs_emit(buf, "%s\n", ufshcd_ufs_dev_pwr_mode_to_string( ufs_pm_lvl_states[hba->spm_lvl].dev_state)); } @@ -122,7 +122,7 @@ static ssize_t spm_target_link_state_show(struct device *dev, { struct ufs_hba *hba = dev_get_drvdata(dev); - return sysfs_emit(buf, "%s\n", ufschd_uic_link_state_to_string( + return sysfs_emit(buf, "%s\n", ufshcd_uic_link_state_to_string( ufs_pm_lvl_states[hba->spm_lvl].link_state)); } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0625da7a42ee..72fd41bfbd54 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2842,7 +2842,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, * ufshcd_exec_dev_cmd - API for sending device management requests * @hba: UFS hba * @cmd_type: specifies the type (NOP, Query...) - * @timeout: time in seconds + * @timeout: timeout in milliseconds * * NOTE: Since there is only one available tag for device management commands, * it is expected you hold the hba->dev_cmd.lock mutex. @@ -2872,6 +2872,9 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, } tag = req->tag; WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + /* Set the timeout such that the SCSI error handler is not activated. */ + req->timeout = msecs_to_jiffies(2 * timeout); + blk_mq_start_request(req); init_completion(&wait); lrbp = &hba->lrb[tag]; @@ -8593,7 +8596,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) } else if (!ufshcd_is_ufs_dev_active(hba)) { ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false); vcc_off = true; - if (!ufshcd_is_link_active(hba)) { + if (ufshcd_is_link_hibern8(hba) || ufshcd_is_link_off(hba)) { ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq); ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2); } @@ -8615,7 +8618,7 @@ static int ufshcd_vreg_set_hpm(struct ufs_hba *hba) !hba->dev_info.is_lu_power_on_wp) { ret = ufshcd_setup_vreg(hba, true); } else if (!ufshcd_is_ufs_dev_active(hba)) { - if (!ret && !ufshcd_is_link_active(hba)) { + if (!ufshcd_is_link_active(hba)) { ret = ufshcd_config_vreg_hpm(hba, hba->vreg_info.vccq); if (ret) goto vcc_disable; @@ -8975,10 +8978,13 @@ int ufshcd_system_suspend(struct ufs_hba *hba) if (!hba->is_powered) return 0; + cancel_delayed_work_sync(&hba->rpm_dev_flush_recheck_work); + if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) == hba->curr_dev_pwr_mode) && (ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) == hba->uic_link_state) && + pm_runtime_suspended(hba->dev) && !hba->dev_info.b_rpm_dev_flush_capable) goto out; |