diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 4cf0348b3b82..dcb8dd2b6362 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5853,7 +5853,12 @@ static inline void ufshcd_schedule_eh_work(struct ufs_hba *hba) static void ufshcd_err_handling_prepare(struct ufs_hba *hba) { +#if defined(CONFIG_SCSI_UFSHCD_QTI) + if (!hba->abort_triggered_wlun) + pm_runtime_get_sync(hba->dev); +#else pm_runtime_get_sync(hba->dev); +#endif if (pm_runtime_suspended(hba->dev)) { /* * Don't assume anything of pm_runtime_get_sync(), if @@ -5885,7 +5890,13 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) ufshcd_release(hba); if (hba->clk_scaling.is_allowed) ufshcd_resume_clkscaling(hba); +#if defined(CONFIG_SCSI_UFSHCD_QTI) + if (!hba->abort_triggered_wlun) + pm_runtime_put(hba->dev); + hba->abort_triggered_wlun = false; +#else pm_runtime_put(hba->dev); +#endif } static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) @@ -6777,8 +6788,15 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) * To avoid these unnecessary/illegal step we skip to the last error * handling stage: reset and restore. */ +#if defined(CONFIG_SCSI_UFSHCD_QTI) + if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { + hba->abort_triggered_wlun = true; + return ufshcd_eh_host_reset_handler(cmd); + } +#else if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) return ufshcd_eh_host_reset_handler(cmd); +#endif ufshcd_hold(hba, false); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); @@ -8990,6 +9008,22 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) if (!ufshcd_is_ufs_dev_active(hba)) { ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE); +#if defined(CONFIG_SCSI_UFSHCD_QTI) + if (ret) { + if (ufshcd_is_ufs_dev_active(hba) && + ufshcd_is_link_active(hba)) { + ret = 0; + dev_err(hba->dev, "UFS device and link are Active\n"); + } else if ((work_pending(&hba->eh_work)) || + ufshcd_eh_in_progress(hba)) { + flush_work(&hba->eh_work); + ret = 0; + dev_err(hba->dev, "dev pwr mode=%d, UIC link state=%d\n", + hba->curr_dev_pwr_mode, + hba->uic_link_state); + } + } +#endif if (ret) goto set_old_link_state; } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index db44c7ca098e..d9003a0b12a4 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1032,6 +1032,11 @@ struct ufs_hba { ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); ANDROID_KABI_RESERVE(4); +#ifdef CONFIG_SCSI_UFSHCD_QTI + /* distinguish between resume and restore */ + bool restore; + bool abort_triggered_wlun; +#endif }; /* Returns true if clocks can be gated. Otherwise false */