Allow device power supply to enter low-power mode if device will
do nothing to save more power.

Signed-off-by: Stanley Chu <[email protected]>
Reviewed-by: Pengshun Zhao <[email protected]>
---
 drivers/scsi/ufs/ufs-mediatek.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 3c85f5e97dea..5f41b7b7db8f 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/soc/mediatek/mtk_sip_svc.h>
 
 #include "ufshcd.h"
@@ -521,6 +522,19 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
        return 0;
 }
 
+static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
+{
+       if (!hba->vreg_info.vccq2)
+               return;
+
+       if (lpm & !hba->vreg_info.vcc->enabled)
+               regulator_set_mode(hba->vreg_info.vccq2->reg,
+                                  REGULATOR_MODE_IDLE);
+       else if (!lpm)
+               regulator_set_mode(hba->vreg_info.vccq2->reg,
+                                  REGULATOR_MODE_NORMAL);
+}
+
 static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
        int err;
@@ -537,6 +551,12 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
                        ufshcd_set_link_off(hba);
                        return -EAGAIN;
                }
+               /*
+                * Make sure no error will be returned to prevent
+                * ufshcd_suspend() re-enabling regulators while vreg is still
+                * in low-power mode.
+                */
+               ufs_mtk_vreg_set_lpm(hba, true);
        }
 
        if (!ufshcd_is_link_active(hba))
@@ -554,6 +574,7 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum 
ufs_pm_op pm_op)
                phy_power_on(host->mphy);
 
        if (ufshcd_is_link_hibern8(hba)) {
+               ufs_mtk_vreg_set_lpm(hba, false);
                err = ufs_mtk_link_set_hpm(hba);
                if (err) {
                        err = ufshcd_link_recovery(hba);
-- 
2.18.0

Reply via email to