From 8694f78edc8e279cdf59e6e805b67568180de313 Mon Sep 17 00:00:00 2001 From: "Bao D. Nguyen" Date: Fri, 19 Jun 2020 16:14:37 -0700 Subject: [PATCH] scsi: ufs: Support query the spm/rpm level from device tree Add support to query the system suspend and runtime suspend pm levels from the device tree. Note if the pm level is set to power down, the device's vcc will be turned off during system suspend, and the host will do full device power up sequence during system resume. This may have some impact on the system resume latency and UFS device life time. Change-Id: I9f1aaeb14e7947f0a5e474ebb3ea5981e5e502a7 Signed-off-by: Bao D. Nguyen --- drivers/scsi/ufs/ufs-qcom.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 5c18c9efba11..2dad1133ae77 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1598,6 +1598,28 @@ out: return err; } +static inline bool +ufshcd_is_valid_pm_lvl(enum ufs_pm_level lvl) +{ + return lvl >= 0 && lvl < UFS_PM_LVL_MAX; +} + +static void ufshcd_parse_pm_levels(struct ufs_hba *hba) +{ + struct device *dev = hba->dev; + struct device_node *np = dev->of_node; + enum ufs_pm_level rpm_lvl = UFS_PM_LVL_MAX, spm_lvl = UFS_PM_LVL_MAX; + + if (!np) + return; + if (!of_property_read_u32(np, "rpm-level", &rpm_lvl) && + ufshcd_is_valid_pm_lvl(rpm_lvl)) + hba->rpm_lvl = rpm_lvl; + if (!of_property_read_u32(np, "spm-level", &spm_lvl) && + ufshcd_is_valid_pm_lvl(spm_lvl)) + hba->spm_lvl = spm_lvl; +} + static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba) { unsigned long flags; @@ -1619,6 +1641,8 @@ static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba) if (hba->dev_info.wmanufacturerid == UFS_VENDOR_WDC) hba->dev_quirks |= UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE; + ufshcd_parse_pm_levels(hba); + return err; }