Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
[linux-block.git] / drivers / ata / ahci.c
index b2b9eba1d214765723165f1d3d7c1bda64720207..021ce46e2e57343b181976a980abef2e16e798d5 100644 (file)
@@ -610,7 +610,7 @@ static int marvell_enable = 1;
 module_param(marvell_enable, int, 0644);
 MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
 
-static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+static int mobile_lpm_policy = -1;
 module_param(mobile_lpm_policy, int, 0644);
 MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
 
@@ -1604,6 +1604,37 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
        return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
 }
 
+static void ahci_update_initial_lpm_policy(struct ata_port *ap,
+                                          struct ahci_host_priv *hpriv)
+{
+       int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+
+
+       /* Ignore processing for non mobile platforms */
+       if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
+               return;
+
+       /* user modified policy via module param */
+       if (mobile_lpm_policy != -1) {
+               policy = mobile_lpm_policy;
+               goto update_policy;
+       }
+
+#ifdef CONFIG_ACPI
+       if (policy > ATA_LPM_MED_POWER &&
+           (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
+               if (hpriv->cap & HOST_CAP_PART)
+                       policy = ATA_LPM_MIN_POWER_WITH_PARTIAL;
+               else if (hpriv->cap & HOST_CAP_SSC)
+                       policy = ATA_LPM_MIN_POWER;
+       }
+#endif
+
+update_policy:
+       if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER)
+               ap->target_lpm_policy = policy;
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        unsigned int board_id = ent->driver_data;
@@ -1807,10 +1838,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                if (ap->flags & ATA_FLAG_EM)
                        ap->em_message_type = hpriv->em_msg_type;
 
-               if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
-                   mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
-                   mobile_lpm_policy <= ATA_LPM_MIN_POWER)
-                       ap->target_lpm_policy = mobile_lpm_policy;
+               ahci_update_initial_lpm_policy(ap, hpriv);
 
                /* disabled/not-implemented port */
                if (!(hpriv->port_map & (1 << i)))