diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ebb2bfd4ab0a22ad090d593d15069ea2d967ffcb..8ed2f42b85fd3482fb9b54f5461ec19ef770a1a2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1855,6 +1855,17 @@ 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 (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + 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 ccc80ff57eb2018adf9657aaa284a5aa3b1e52a4..e4e0e6d94741ea76a62056b227d88d3ac5392d8f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3448,6 +3448,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, struct ata_device **r_failed_dev) { struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; + struct device *device = ap->host->dev; + struct pci_dev *pdev = (!device || !dev_is_pci(device)) ? NULL : to_pci_dev(device); struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; enum ata_lpm_policy old_policy = link->lpm_policy; @@ -3456,6 +3458,11 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, unsigned int err_mask; int rc; + /* if controller does not support lpm, then sets no LPM flags */ + if ((pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) && + !(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 ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) return 0; diff --git a/include/linux/libata.h b/include/linux/libata.h index dc164b7ebbb06095e7928d6eacc42c7fcc46dfa6..1cec68e5b104c98eef92292381930b640d8afa15 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -276,6 +276,9 @@ enum { ATA_HOST_STARTED = (1 << 1), /* Host started */ 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 */