|
@@ -49,8 +49,22 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
|
|
|
{
|
|
|
int err = 0;
|
|
|
|
|
|
- if (scsi_is_sdev_device(dev))
|
|
|
+ if (scsi_is_sdev_device(dev)) {
|
|
|
+ /*
|
|
|
+ * sd is the only high-level SCSI driver to implement runtime
|
|
|
+ * PM, and sd treats runtime suspend, system suspend, and
|
|
|
+ * system hibernate identically (but not system freeze).
|
|
|
+ */
|
|
|
+ if (pm_runtime_suspended(dev)) {
|
|
|
+ if (msg.event == PM_EVENT_SUSPEND ||
|
|
|
+ msg.event == PM_EVENT_HIBERNATE)
|
|
|
+ return 0; /* already suspended */
|
|
|
+
|
|
|
+ /* wake up device so that FREEZE will succeed */
|
|
|
+ pm_runtime_resume(dev);
|
|
|
+ }
|
|
|
err = scsi_dev_type_suspend(dev, msg);
|
|
|
+ }
|
|
|
return err;
|
|
|
}
|
|
|
|