snd_hdac_leave_pm(&codec->core);
 }
 
-static int hda_codec_runtime_suspend(struct device *dev)
+static int hda_codec_suspend(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
        unsigned int state;
        return 0;
 }
 
-static int hda_codec_runtime_resume(struct device *dev)
+static int hda_codec_resume(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
 
        pm_runtime_mark_last_busy(dev);
        return 0;
 }
+
+static int hda_codec_runtime_suspend(struct device *dev)
+{
+       return hda_codec_suspend(dev);
+}
+
+static int hda_codec_runtime_resume(struct device *dev)
+{
+       return hda_codec_resume(dev);
+}
+
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PM_SLEEP
-static int hda_codec_force_resume(struct device *dev)
+static int hda_codec_pm_prepare(struct device *dev)
+{
+       return pm_runtime_suspended(dev);
+}
+
+static void hda_codec_pm_complete(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
-       int ret;
 
-       ret = pm_runtime_force_resume(dev);
-       /* schedule jackpoll work for jack detection update */
-       if (codec->jackpoll_interval ||
-           (pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
-               schedule_delayed_work(&codec->jackpoll_work,
-                                     codec->jackpoll_interval);
-       return ret;
+       if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
+           hda_codec_need_resume(codec) || codec->forced_resume))
+               pm_request_resume(dev);
 }
 
 static int hda_codec_pm_suspend(struct device *dev)
 {
        dev->power.power_state = PMSG_SUSPEND;
-       return pm_runtime_force_suspend(dev);
+       return hda_codec_suspend(dev);
 }
 
 static int hda_codec_pm_resume(struct device *dev)
 {
        dev->power.power_state = PMSG_RESUME;
-       return hda_codec_force_resume(dev);
+       return hda_codec_resume(dev);
 }
 
 static int hda_codec_pm_freeze(struct device *dev)
 {
        dev->power.power_state = PMSG_FREEZE;
-       return pm_runtime_force_suspend(dev);
+       return hda_codec_suspend(dev);
 }
 
 static int hda_codec_pm_thaw(struct device *dev)
 {
        dev->power.power_state = PMSG_THAW;
-       return hda_codec_force_resume(dev);
+       return hda_codec_resume(dev);
 }
 
 static int hda_codec_pm_restore(struct device *dev)
 {
        dev->power.power_state = PMSG_RESTORE;
-       return hda_codec_force_resume(dev);
+       return hda_codec_resume(dev);
 }
 #endif /* CONFIG_PM_SLEEP */
 
 /* referred in hda_bind.c */
 const struct dev_pm_ops hda_codec_driver_pm = {
 #ifdef CONFIG_PM_SLEEP
+       .prepare = hda_codec_pm_prepare,
+       .complete = hda_codec_pm_complete,
        .suspend = hda_codec_pm_suspend,
        .resume = hda_codec_pm_resume,
        .freeze = hda_codec_pm_freeze,