>From c21ea993b28bec894f96c0c7b387f9688b01900f Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 20 Apr 2021 14:33:03 +0300 Subject: [PATCH 1/2] changes suggested since v20 Signed-off-by: Adrian Hunter --- drivers/scsi/ufs/ufshcd.c | 50 ++++++++++----------------------------- drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index eb36f753469d..5be5b2472db0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5844,7 +5844,7 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) { - return (!hba->is_powered || hba->shutting_down || + return (!hba->is_powered || hba->shutting_down || !hba->sdev_ufs_device || hba->ufshcd_state == UFSHCD_STATE_ERROR || (!(hba->saved_err || hba->saved_uic_err || hba->force_reset || ufshcd_is_link_broken(hba)))); @@ -9572,51 +9572,27 @@ void ufshcd_resume_complete(struct device *dev) { struct ufs_hba *hba = dev_get_drvdata(dev); - ufshcd_rpm_put(hba); + if (hba->complete_put) { + hba->complete_put = false; + ufshcd_rpm_put(hba); + } } EXPORT_SYMBOL_GPL(ufshcd_resume_complete); int ufshcd_suspend_prepare(struct device *dev) { struct ufs_hba *hba = dev_get_drvdata(dev); - struct device *ufs_dev = &hba->sdev_ufs_device->sdev_gendev; - enum ufs_dev_pwr_mode spm_pwr_mode; - enum uic_link_state spm_link_state; - unsigned long flags; - bool rpm_state_ok; - - /* - * SCSI assumes that runtime-pm and system-pm for scsi drivers - * are same. And it doesn't wake up the device for system-suspend - * if it's runtime suspended. But ufs doesn't follow that. - * The rpm-lvl and spm-lvl can be different in ufs. - * However, if the current_{pwr_mode, link_state} is same as the - * desired_{pwr_mode, link_state}, there's no need to rpm resume - * the device. - * Refer ufshcd_resume_complete() - */ - pm_runtime_get_noresume(ufs_dev); - - spin_lock_irqsave(&ufs_dev->power.lock, flags); - - spm_pwr_mode = ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl); - spm_link_state = ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl); - - rpm_state_ok = pm_runtime_suspended(ufs_dev) && - hba->curr_dev_pwr_mode == spm_pwr_mode && - hba->uic_link_state == spm_link_state && - !hba->dev_info.b_rpm_dev_flush_capable; - - spin_unlock_irqrestore(&ufs_dev->power.lock, flags); + int ret; - if (!rpm_state_ok) { - int ret = pm_runtime_resume(ufs_dev); + if (!hba->sdev_ufs_device) + return 0; - if (ret < 0 && ret != -EACCES) { - pm_runtime_put(ufs_dev); - return ret; - } + ret = ufshcd_rpm_get_sync(hba); + if (ret < 0 && ret != -EACCES) { + ufshcd_rpm_put(hba); + return ret; } + hba->complete_put = true; return 0; } EXPORT_SYMBOL_GPL(ufshcd_suspend_prepare); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 3a8dc0dfae05..fd5be083e168 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -850,6 +850,7 @@ struct ufs_hba { u32 debugfs_ee_rate_limit_ms; #endif u32 luns_avail; + bool complete_put; }; /* Returns true if clocks can be gated. Otherwise false */ -- 2.25.1