summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libahci.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 16:20:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-24 16:20:33 -0400
commit0519359784328bfa92bf0931bf0cff3b58c16932 (patch)
tree71ab4638b4f0bf86c76eb2b12de01303f6b1f5bf /drivers/ata/libahci.c
parent596766102a3a37ba20c4d9a4130a8a4b42b34646 (diff)
parent2d17f460c5d79fa9fc794e813377f3276acf81ce (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.c27
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,
801 cmd |= PORT_CMD_ALPE; 801 cmd |= PORT_CMD_ALPE;
802 if (policy == ATA_LPM_MIN_POWER) 802 if (policy == ATA_LPM_MIN_POWER)
803 cmd |= PORT_CMD_ASP; 803 cmd |= PORT_CMD_ASP;
804 else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
805 cmd &= ~PORT_CMD_ASP;
804 806
805 /* write out new cmd value */ 807 /* write out new cmd value */
806 writel(cmd, port_mmio + PORT_CMD); 808 writel(cmd, port_mmio + PORT_CMD);
@@ -811,7 +813,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
811 if ((hpriv->cap2 & HOST_CAP2_SDS) && 813 if ((hpriv->cap2 & HOST_CAP2_SDS) &&
812 (hpriv->cap2 & HOST_CAP2_SADM) && 814 (hpriv->cap2 & HOST_CAP2_SADM) &&
813 (link->device->flags & ATA_DFLAG_DEVSLP)) { 815 (link->device->flags & ATA_DFLAG_DEVSLP)) {
814 if (policy == ATA_LPM_MIN_POWER) 816 if (policy == ATA_LPM_MIN_POWER ||
817 policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
815 ahci_set_aggressive_devslp(ap, true); 818 ahci_set_aggressive_devslp(ap, true);
816 else 819 else
817 ahci_set_aggressive_devslp(ap, false); 820 ahci_set_aggressive_devslp(ap, false);
@@ -2107,7 +2110,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2107 struct ahci_host_priv *hpriv = ap->host->private_data; 2110 struct ahci_host_priv *hpriv = ap->host->private_data;
2108 void __iomem *port_mmio = ahci_port_base(ap); 2111 void __iomem *port_mmio = ahci_port_base(ap);
2109 struct ata_device *dev = ap->link.device; 2112 struct ata_device *dev = ap->link.device;
2110 u32 devslp, dm, dito, mdat, deto; 2113 u32 devslp, dm, dito, mdat, deto, dito_conf;
2111 int rc; 2114 int rc;
2112 unsigned int err_mask; 2115 unsigned int err_mask;
2113 2116
@@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2131 return; 2134 return;
2132 } 2135 }
2133 2136
2134 /* device sleep was already enabled */ 2137 dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
2135 if (devslp & PORT_DEVSLP_ADSE) 2138 dito = devslp_idle_timeout / (dm + 1);
2139 if (dito > 0x3ff)
2140 dito = 0x3ff;
2141
2142 dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF;
2143
2144 /* device sleep was already enabled and same dito */
2145 if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito))
2136 return; 2146 return;
2137 2147
2138 /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ 2148 /* 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)
2140 if (rc) 2150 if (rc)
2141 return; 2151 return;
2142 2152
2143 dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
2144 dito = devslp_idle_timeout / (dm + 1);
2145 if (dito > 0x3ff)
2146 dito = 0x3ff;
2147
2148 /* Use the nominal value 10 ms if the read MDAT is zero, 2153 /* Use the nominal value 10 ms if the read MDAT is zero,
2149 * the nominal value of DETO is 20 ms. 2154 * the nominal value of DETO is 20 ms.
2150 */ 2155 */
@@ -2162,6 +2167,8 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2162 deto = 20; 2167 deto = 20;
2163 } 2168 }
2164 2169
2170 /* Make dito, mdat, deto bits to 0s */
2171 devslp &= ~GENMASK_ULL(24, 2);
2165 devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) | 2172 devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
2166 (mdat << PORT_DEVSLP_MDAT_OFFSET) | 2173 (mdat << PORT_DEVSLP_MDAT_OFFSET) |
2167 (deto << PORT_DEVSLP_DETO_OFFSET) | 2174 (deto << PORT_DEVSLP_DETO_OFFSET) |
@@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap)
2439 * re-enabling INTx. 2446 * re-enabling INTx.
2440 */ 2447 */
2441 writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT); 2448 writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
2449
2450 ahci_rpm_put_port(ap);
2442} 2451}
2443 2452
2444void ahci_print_info(struct ata_host *host, const char *scc_s) 2453void ahci_print_info(struct ata_host *host, const char *scc_s)