mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
ahci: don't enter slumber on power down
Some ATA/ATAPI devices act weirdly after the link is put into slumber mode. Some hang completely requiring physical power removal while others fail to wake up till the link is hardreset a couple of times. The addition of slumber on power down was never driven by real need. It just followed what ahci spec said literally. The spec itself seems faulty in that it doesn't consider devices (not controllers) which don't support link powersaving mode. Theory never matches reality when it comes to dark allys of cheap ATA/ATAPI world. It's just unrealistic to expect vendors to test rarely used link powersaving feature rigorously. This patch makes ahci more friendly to the coldness of reality. This shouldn't have any negative effect - when suspend operation succeeds, we power off the whole machine; otherwise, we wake up everything. I can't see any reason to be so elaborate with powering down the link in the first place. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
f740d1689d
commit
07c53dac49
@ -586,35 +586,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
|
||||
{
|
||||
u32 cmd, scontrol;
|
||||
|
||||
if (!(cap & HOST_CAP_SSS))
|
||||
return;
|
||||
|
||||
/* put device into listen mode, first set PxSCTL.DET to 0 */
|
||||
scontrol = readl(port_mmio + PORT_SCR_CTL);
|
||||
scontrol &= ~0xf;
|
||||
writel(scontrol, port_mmio + PORT_SCR_CTL);
|
||||
|
||||
/* then set PxCMD.SUD to 0 */
|
||||
cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
|
||||
|
||||
if (cap & HOST_CAP_SSC) {
|
||||
/* enable transitions to slumber mode */
|
||||
scontrol = readl(port_mmio + PORT_SCR_CTL);
|
||||
if ((scontrol & 0x0f00) > 0x100) {
|
||||
scontrol &= ~0xf00;
|
||||
writel(scontrol, port_mmio + PORT_SCR_CTL);
|
||||
}
|
||||
|
||||
/* put device into slumber mode */
|
||||
writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD);
|
||||
|
||||
/* wait for the transition to complete */
|
||||
ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER,
|
||||
PORT_CMD_ICC_SLUMBER, 1, 50);
|
||||
}
|
||||
|
||||
/* put device into listen mode */
|
||||
if (cap & HOST_CAP_SSS) {
|
||||
/* first set PxSCTL.DET to 0 */
|
||||
scontrol = readl(port_mmio + PORT_SCR_CTL);
|
||||
scontrol &= ~0xf;
|
||||
writel(scontrol, port_mmio + PORT_SCR_CTL);
|
||||
|
||||
/* then set PxCMD.SUD to 0 */
|
||||
cmd &= ~PORT_CMD_SPIN_UP;
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
}
|
||||
cmd &= ~PORT_CMD_SPIN_UP;
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
}
|
||||
|
||||
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
|
||||
|
Loading…
Reference in New Issue
Block a user