scsi: ufs-pci: Ensure UFS device is in PowerDown mode for suspend-to-disk ->poweroff()
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 7 Dec 2020 08:31:18 +0000 (10:31 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 9 Dec 2020 16:34:20 +0000 (11:34 -0500)
The expectation for suspend-to-disk is that devices will be powered-off, so
the UFS device should be put in PowerDown mode. If spm_lvl is not 5, then
that will not happen. Change the pm callbacks to force spm_lvl 5 for
suspend-to-disk poweroff.

Link: https://lore.kernel.org/r/20201207083120.26732-3-adrian.hunter@intel.com
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufshcd-pci.c

index 360c25f..5d33c39 100644 (file)
@@ -227,6 +227,30 @@ static int ufshcd_pci_resume(struct device *dev)
 {
        return ufshcd_system_resume(dev_get_drvdata(dev));
 }
+
+/**
+ * ufshcd_pci_poweroff - suspend-to-disk poweroff function
+ * @dev: pointer to PCI device handle
+ *
+ * Returns 0 if successful
+ * Returns non-zero otherwise
+ */
+static int ufshcd_pci_poweroff(struct device *dev)
+{
+       struct ufs_hba *hba = dev_get_drvdata(dev);
+       int spm_lvl = hba->spm_lvl;
+       int ret;
+
+       /*
+        * For poweroff we need to set the UFS device to PowerDown mode.
+        * Force spm_lvl to ensure that.
+        */
+       hba->spm_lvl = 5;
+       ret = ufshcd_system_suspend(hba);
+       hba->spm_lvl = spm_lvl;
+       return ret;
+}
+
 #endif /* !CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PM
@@ -322,8 +346,14 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct dev_pm_ops ufshcd_pci_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend,
-                               ufshcd_pci_resume)
+#ifdef CONFIG_PM_SLEEP
+       .suspend        = ufshcd_pci_suspend,
+       .resume         = ufshcd_pci_resume,
+       .freeze         = ufshcd_pci_suspend,
+       .thaw           = ufshcd_pci_resume,
+       .poweroff       = ufshcd_pci_poweroff,
+       .restore        = ufshcd_pci_resume,
+#endif
        SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend,
                           ufshcd_pci_runtime_resume,
                           ufshcd_pci_runtime_idle)