In AHCI spec, PhyRdy Change Interrupt cannot coexist with Link Power Management (LPM). While LPM driver would disable PhyRdy Change interrupt without checking whether HBA supports LPM or not before enabling it. Therefore, if enabling LPM from LPM driver by default, we can not disable it from BIOS without influence Hotplug out capability.
Signed-off-by: LeoLiu-oc LeoLiu-oc@zhaoxin.com --- drivers/ata/ahci.c | 9 +++++++++ drivers/ata/libata-eh.c | 4 ++++ include/linux/libata.h | 4 ++++ 3 files changed, 17 insertions(+)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f8059eed3..2d1ac1b5b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1883,6 +1883,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) else dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n");
+ if (hpriv->cap & HOST_CAP_PART) + host->flags |= ATA_HOST_PART; + + if (hpriv->cap & HOST_CAP_SSC) + host->flags |= ATA_HOST_SSC; + + if (hpriv->cap2 & HOST_CAP2_SDS) + host->flags |= ATA_HOST_DEVSLP; + if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index b6f92050e..ff6e660d6 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3237,6 +3237,10 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, unsigned int err_mask; int rc;
+ /* if Host does not support lpm, then sets no LPM flags*/ + if (!(ap->host->flags & (ATA_HOST_PART | ATA_HOST_SSC | ATA_HOST_DEVSLP))) + link->flags |= ATA_LFLAG_NO_LPM; + /* if the link or host doesn't do LPM, noop */ if (!IS_ENABLED(CONFIG_SATA_HOST) || (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) diff --git a/include/linux/libata.h b/include/linux/libata.h index 5f550eb27..81124ddc2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -260,6 +260,10 @@ enum { ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */
+ ATA_HOST_PART = (1 << 4), /* Host support partial.*/ + ATA_HOST_SSC = (1 << 5), /* Host support slumber.*/ + ATA_HOST_DEVSLP = (1 << 6), /* Host support devslp.*/ + /* bits 24:31 of host->flags are reserved for LLD specific flags */
/* various lengths of time */