summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorGabriele Mazzotta <gabriele.mzt@gmail.com>2015-04-25 19:52:37 +0200
committerLuis Henriques <luis.henriques@canonical.com>2015-05-28 09:59:58 +0100
commit578267ded59cebc351e9b7920f0e6e4cc18ee42b (patch)
tree25820c1a9a185c076a96f1e49b93c65c461f4c5a /drivers/ata
parent9a47bdd057fa2c1c677d0208ce5c693be4169084 (diff)
downloadlinux-stable-578267ded59cebc351e9b7920f0e6e4cc18ee42b.tar.gz
linux-stable-578267ded59cebc351e9b7920f0e6e4cc18ee42b.tar.bz2
linux-stable-578267ded59cebc351e9b7920f0e6e4cc18ee42b.zip
libata: Ignore spurious PHY event on LPM policy change
commit 09c5b4803a80a5451d950d6a539d2eb311dc0fb1 upstream. When the LPM policy is set to ATA_LPM_MAX_POWER, the device might generate a spurious PHY event that cuases errors on the link. Ignore this event if it occured within 10s after the policy change. The timeout was chosen observing that on a Dell XPS13 9333 these spurious events can occur up to roughly 6s after the policy change. Link: http://lkml.kernel.org/g/3352987.ugV1Ipy7Z5@xps13 Signed-off-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c15
-rw-r--r--drivers/ata/libata-eh.c3
2 files changed, 17 insertions, 1 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c89f10fbf169..52ddc0afcaf6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6827,8 +6827,21 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
*/
bool sata_lpm_ignore_phy_events(struct ata_link *link)
{
+ unsigned long lpm_timeout = link->last_lpm_change +
+ msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY);
+
/* if LPM is enabled, PHYRDY doesn't mean anything */
- return !!(link->lpm_policy > ATA_LPM_MAX_POWER);
+ if (link->lpm_policy > ATA_LPM_MAX_POWER)
+ return true;
+
+ /* ignore the first PHY event after the LPM policy changed
+ * as it is might be spurious
+ */
+ if ((link->flags & ATA_LFLAG_CHANGED) &&
+ time_before(jiffies, lpm_timeout))
+ return true;
+
+ return false;
}
EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dad83df555c4..4ec95b76f6a1 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3490,6 +3490,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
}
}
+ link->last_lpm_change = jiffies;
+ link->flags |= ATA_LFLAG_CHANGED;
+
return 0;
fail: