| From 1d53864c3617f5235f891ca0fbe9347c4cd35d46 Mon Sep 17 00:00:00 2001 |
| From: Stanley Chu <stanley.chu@mediatek.com> |
| Date: Tue, 22 Dec 2020 15:29:04 +0800 |
| Subject: scsi: ufs: Fix possible power drain during system suspend |
| |
| From: Stanley Chu <stanley.chu@mediatek.com> |
| |
| commit 1d53864c3617f5235f891ca0fbe9347c4cd35d46 upstream. |
| |
| Currently if device needs to do flush or BKOP operations, the device VCC |
| power is kept during runtime-suspend period. |
| |
| However, if system suspend is happening while device is runtime-suspended, |
| such power may not be disabled successfully. |
| |
| The reasons may be, |
| |
| 1. If current PM level is the same as SPM level, device will keep |
| runtime-suspended by ufshcd_system_suspend(). |
| |
| 2. Flush recheck work may not be scheduled successfully during system |
| suspend period. If it can wake up the system, this is also not the |
| intention of the recheck work. |
| |
| To fix this issue, simply runtime-resume the device if the flush is allowed |
| during runtime suspend period. Flush capability will be disabled while |
| leaving runtime suspend, and also not be allowed in system suspend period. |
| |
| Link: https://lore.kernel.org/r/20201222072905.32221-2-stanley.chu@mediatek.com |
| Fixes: 51dd905bd2f6 ("scsi: ufs: Fix WriteBooster flush during runtime suspend") |
| Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com> |
| Reviewed-by: Can Guo <cang@codeaurora.org> |
| Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/scsi/ufs/ufshcd.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/scsi/ufs/ufshcd.c |
| +++ b/drivers/scsi/ufs/ufshcd.c |
| @@ -8818,7 +8818,8 @@ int ufshcd_system_suspend(struct ufs_hba |
| 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)) |
| + hba->uic_link_state) && |
| + !hba->dev_info.b_rpm_dev_flush_capable) |
| goto out; |
| |
| if (pm_runtime_suspended(hba->dev)) { |