};
/* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are
-@@ -788,6 +790,7 @@ struct ata_link {
- struct ata_eh_context eh_context;
-
+@@ -800,6 +800,7 @@ struct ata_link {
struct ata_device device[ATA_MAX_DEVICES];
+
+ unsigned long last_lpm_change; /* when last LPM change happened */
+ u8 init_lpm; /* initial lpm configuration */
};
#define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag)
struct ahci_port_priv *pp = ap->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
-@@ -701,9 +702,9 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+@@ -701,10 +702,10 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
if (hpriv->cap & HOST_CAP_ALPM) {
u32 cmd = readl(port_mmio + PORT_CMD);
-+ cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
++ if (!(hints & ATA_LPM_WAKE_ONLY))
++ cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) {
-- cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
+- if (!(hints & ATA_LPM_WAKE_ONLY))
+- cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
cmd |= PORT_CMD_ICC_ACTIVE;
writel(cmd, port_mmio + PORT_CMD);
@@ -711,6 +712,13 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
- /* wait 10ms to be sure we've come out of LPM state */
- ata_msleep(ap, 10);
+ if (hints & ATA_LPM_WAKE_ONLY)
+ return 0;
+ } else if (policy == ATA_LPM_FIRMWARE_DEFAULTS) {
+ if (ppriv->init_alpe)
+ cmd |= PORT_CMD_ALPE;