+static int ata_port_suspend(struct device *dev)
+{
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ return ata_port_suspend_common(dev, PMSG_SUSPEND);
+}
+
+static int ata_port_do_freeze(struct device *dev)
+{
+ if (pm_runtime_suspended(dev))
+ pm_runtime_resume(dev);
+
+ return ata_port_suspend_common(dev, PMSG_FREEZE);
+}
+
+static int ata_port_poweroff(struct device *dev)
+{
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ return ata_port_suspend_common(dev, PMSG_HIBERNATE);
+}
+
+static int ata_port_resume_common(struct device *dev)
+{
+ struct ata_port *ap = to_ata_port(dev);
+ int rc;
+
+ rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
+ ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
+ return rc;
+}
+
+static int ata_port_resume(struct device *dev)
+{
+ int rc;
+
+ rc = ata_port_resume_common(dev);
+ if (!rc) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return rc;
+}
+
+static int ata_port_runtime_idle(struct device *dev)
+{
+ return pm_runtime_suspend(dev);
+}
+
+static const struct dev_pm_ops ata_port_pm_ops = {
+ .suspend = ata_port_suspend,
+ .resume = ata_port_resume,
+ .freeze = ata_port_do_freeze,
+ .thaw = ata_port_resume,
+ .poweroff = ata_port_poweroff,
+ .restore = ata_port_resume,
+
+ .runtime_suspend = ata_port_suspend,
+ .runtime_resume = ata_port_resume_common,
+ .runtime_idle = ata_port_runtime_idle,
+};
+
+/**
+ * ata_host_suspend - suspend host
+ * @host: host to suspend
+ * @mesg: PM message
+ *
+ * Suspend @host. Actual operation is performed by port suspend.
+ */
+int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
+{
+ host->dev->power.power_state = mesg;
+ return 0;
+}
+