diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-24 13:20:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-24 13:20:33 -0700 |
commit | 0519359784328bfa92bf0931bf0cff3b58c16932 (patch) | |
tree | 71ab4638b4f0bf86c76eb2b12de01303f6b1f5bf /drivers/ata/libahci.c | |
parent | 596766102a3a37ba20c4d9a4130a8a4b42b34646 (diff) | |
parent | 2d17f460c5d79fa9fc794e813377f3276acf81ce (diff) |
Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata updates from Tejun Heo:
"Nothing too interesting. Mostly ahci and ahci_platform changes, many
around power management"
* 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (22 commits)
ata: ahci_platform: enable to get and control reset
ata: libahci_platform: add reset control support
ata: add an extra argument to ahci_platform_get_resources()
ata: sata_rcar: Add r8a77965 support
ata: sata_rcar: exclude setting of PHY registers in Gen3
ata: sata_rcar: really mask all interrupts on Gen2 and later
Revert "ata: ahci_platform: allow disabling of hotplug to save power"
ata: libahci: Allow reconfigure of DEVSLP register
ata: libahci: Correct setting of DEVSLP register
ata: ahci: Enable DEVSLP by default on x86 with SLP_S0
ata: ahci: Support state with min power but Partial low power state
Revert "ata: ahci_platform: convert kcalloc to devm_kcalloc"
ata: sata_rcar: Add rudimentary Runtime PM support
ata: sata_rcar: Provide a short-hand for &pdev->dev
ata: Only output sg element mapped number in verbose debug
ata: Guard ata_scsi_dump_cdb() by ATA_VERBOSE_DEBUG
ata: ahci_platform: convert kcalloc to devm_kcalloc
ata: ahci_platform: convert kzallloc to kcalloc
ata: ahci_platform: correct parameter documentation for ahci_platform_shutdown
libata: remove ata_sff_data_xfer_noirq()
...
Diffstat (limited to 'drivers/ata/libahci.c')
-rw-r--r-- | drivers/ata/libahci.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 09620c2ffa0f..b5f57c69c487 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -801,6 +801,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, cmd |= PORT_CMD_ALPE; if (policy == ATA_LPM_MIN_POWER) cmd |= PORT_CMD_ASP; + else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL) + cmd &= ~PORT_CMD_ASP; /* write out new cmd value */ writel(cmd, port_mmio + PORT_CMD); @@ -811,7 +813,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, if ((hpriv->cap2 & HOST_CAP2_SDS) && (hpriv->cap2 & HOST_CAP2_SADM) && (link->device->flags & ATA_DFLAG_DEVSLP)) { - if (policy == ATA_LPM_MIN_POWER) + if (policy == ATA_LPM_MIN_POWER || + policy == ATA_LPM_MIN_POWER_WITH_PARTIAL) ahci_set_aggressive_devslp(ap, true); else ahci_set_aggressive_devslp(ap, false); @@ -2107,7 +2110,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) struct ahci_host_priv *hpriv = ap->host->private_data; void __iomem *port_mmio = ahci_port_base(ap); struct ata_device *dev = ap->link.device; - u32 devslp, dm, dito, mdat, deto; + u32 devslp, dm, dito, mdat, deto, dito_conf; int rc; unsigned int err_mask; @@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) return; } - /* device sleep was already enabled */ - if (devslp & PORT_DEVSLP_ADSE) + dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET; + dito = devslp_idle_timeout / (dm + 1); + if (dito > 0x3ff) + dito = 0x3ff; + + dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF; + + /* device sleep was already enabled and same dito */ + if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito)) return; /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ @@ -2140,11 +2150,6 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) if (rc) return; - dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET; - dito = devslp_idle_timeout / (dm + 1); - if (dito > 0x3ff) - dito = 0x3ff; - /* Use the nominal value 10 ms if the read MDAT is zero, * the nominal value of DETO is 20 ms. */ @@ -2162,6 +2167,8 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) deto = 20; } + /* Make dito, mdat, deto bits to 0s */ + devslp &= ~GENMASK_ULL(24, 2); devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) | (mdat << PORT_DEVSLP_MDAT_OFFSET) | (deto << PORT_DEVSLP_DETO_OFFSET) | @@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap) * re-enabling INTx. */ writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT); + + ahci_rpm_put_port(ap); } void ahci_print_info(struct ata_host *host, const char *scc_s) |