aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2011-12-22 01:50:49 -0500
committerJeff Garzik <jgarzik@redhat.com>2012-01-08 19:14:59 -0500
commit33574d68ae41ccbc6686cfabd965c685285c58a0 (patch)
tree617e26ada8d782869c5e0c0af1f11274a10947a3 /drivers/ata
parente90b1e5a6e04c8892007ff8db20ef6d4fbdb5402 (diff)
ata: add ata port hibernate callbacks
Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ba1ed9b3acc3..11c9aea4f4f7 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5281,12 +5281,24 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
5281 5281
5282#define to_ata_port(d) container_of(d, struct ata_port, tdev) 5282#define to_ata_port(d) container_of(d, struct ata_port, tdev)
5283 5283
5284static int ata_port_suspend_common(struct device *dev) 5284static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
5285{ 5285{
5286 struct ata_port *ap = to_ata_port(dev); 5286 struct ata_port *ap = to_ata_port(dev);
5287 unsigned int ehi_flags = ATA_EHI_QUIET;
5287 int rc; 5288 int rc;
5288 5289
5289 rc = ata_port_request_pm(ap, PMSG_SUSPEND, 0, ATA_EHI_QUIET, 1); 5290 /*
5291 * On some hardware, device fails to respond after spun down
5292 * for suspend. As the device won't be used before being
5293 * resumed, we don't need to touch the device. Ask EH to skip
5294 * the usual stuff and proceed directly to suspend.
5295 *
5296 * http://thread.gmane.org/gmane.linux.ide/46764
5297 */
5298 if (mesg.event == PM_EVENT_SUSPEND)
5299 ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
5300
5301 rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, 1);
5290 return rc; 5302 return rc;
5291} 5303}
5292 5304
@@ -5295,7 +5307,23 @@ static int ata_port_suspend(struct device *dev)
5295 if (pm_runtime_suspended(dev)) 5307 if (pm_runtime_suspended(dev))
5296 return 0; 5308 return 0;
5297 5309
5298 return ata_port_suspend_common(dev); 5310 return ata_port_suspend_common(dev, PMSG_SUSPEND);
5311}
5312
5313static int ata_port_do_freeze(struct device *dev)
5314{
5315 if (pm_runtime_suspended(dev))
5316 pm_runtime_resume(dev);
5317
5318 return ata_port_suspend_common(dev, PMSG_FREEZE);
5319}
5320
5321static int ata_port_poweroff(struct device *dev)
5322{
5323 if (pm_runtime_suspended(dev))
5324 return 0;
5325
5326 return ata_port_suspend_common(dev, PMSG_HIBERNATE);
5299} 5327}
5300 5328
5301static int ata_port_resume_common(struct device *dev) 5329static int ata_port_resume_common(struct device *dev)
@@ -5330,8 +5358,12 @@ static int ata_port_runtime_idle(struct device *dev)
5330static const struct dev_pm_ops ata_port_pm_ops = { 5358static const struct dev_pm_ops ata_port_pm_ops = {
5331 .suspend = ata_port_suspend, 5359 .suspend = ata_port_suspend,
5332 .resume = ata_port_resume, 5360 .resume = ata_port_resume,
5361 .freeze = ata_port_do_freeze,
5362 .thaw = ata_port_resume,
5363 .poweroff = ata_port_poweroff,
5364 .restore = ata_port_resume,
5333 5365
5334 .runtime_suspend = ata_port_suspend_common, 5366 .runtime_suspend = ata_port_suspend,
5335 .runtime_resume = ata_port_resume_common, 5367 .runtime_resume = ata_port_resume_common,
5336 .runtime_idle = ata_port_runtime_idle, 5368 .runtime_idle = ata_port_runtime_idle,
5337}; 5369};