Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -532,9 +532,12 @@ struct dev_pm_info {
 	struct wakeup_source	*wakeup;
 	bool			wakeup_path:1;
 	bool			syscore:1;
+#ifdef CONFIG_PM_RUNTIME
+	bool			skip_resume:1;
+#endif
 #else
 	unsigned int		should_wakeup:1;
-#endif
+#endif /* CONFIG_PM_SLEEP */
 #ifdef CONFIG_PM_RUNTIME
 	struct timer_list	suspend_timer;
 	unsigned long		timer_expires;
@@ -561,7 +564,7 @@ struct dev_pm_info {
 	unsigned long		active_jiffies;
 	unsigned long		suspended_jiffies;
 	unsigned long		accounting_timestamp;
-#endif
+#endif /* CONFIG_PM_RUNTIME */
 	struct pm_subsys_data	*subsys_data;  /* Owned by the subsystem. */
 	struct dev_pm_qos	*qos;
 };
@@ -716,4 +719,10 @@ enum dpm_order {
 	DPM_ORDER_DEV_LAST,
 };
 
+#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_PM_SLEEP)
+void device_pm_skip_resume(struct device *dev, bool enable);
+#else
+static inline void device_pm_skip_resume(struct device *dev, bool enable) {}
+#endif /* CONFIG_PM_RUNTIME && CONFIG_PM_SLEEP */
+
 #endif /* _LINUX_PM_H */
Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -384,6 +384,29 @@ static int dpm_run_callback(pm_callback_
 	return error;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+void device_pm_skip_resume(struct device *dev, bool enable)
+{
+	device_pm_lock();
+
+	if (!dev->power.is_prepared)
+		dev->power.skip_resume = !!enable;
+
+	device_pm_unlock();
+}
+
+static inline bool skip_device_resume(struct device *dev, pm_message_t state)
+{
+	return dev->power.skip_resume && (state.event == PM_EVENT_RESUME
+		|| state.event == PM_EVENT_RESTORE);
+}
+#else
+static inline bool skip_device_resume(struct device *dev, pm_message_t state)
+{
+	return false;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
 /*------------------------- Resume routines -------------------------*/
 
 /**
@@ -446,21 +469,24 @@ static void dpm_resume_noirq(pm_message_
 	mutex_lock(&dpm_list_mtx);
 	while (!list_empty(&dpm_noirq_list)) {
 		struct device *dev = to_device(dpm_noirq_list.next);
-		int error;
 
 		get_device(dev);
 		list_move_tail(&dev->power.entry, &dpm_late_early_list);
-		mutex_unlock(&dpm_list_mtx);
+		if (!skip_device_resume(dev, state)) {
+			int error;
 
-		error = device_resume_noirq(dev, state);
-		if (error) {
-			suspend_stats.failed_resume_noirq++;
-			dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
-			dpm_save_failed_dev(dev_name(dev));
-			pm_dev_err(dev, state, " noirq", error);
-		}
+			mutex_unlock(&dpm_list_mtx);
+
+			error = device_resume_noirq(dev, state);
+			if (error) {
+				suspend_stats.failed_resume_noirq++;
+				dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
+				dpm_save_failed_dev(dev_name(dev));
+				pm_dev_err(dev, state, " noirq", error);
+			}
 
-		mutex_lock(&dpm_list_mtx);
+			mutex_lock(&dpm_list_mtx);
+		}
 		put_device(dev);
 	}
 	mutex_unlock(&dpm_list_mtx);
@@ -527,21 +553,39 @@ static void dpm_resume_early(pm_message_
 	mutex_lock(&dpm_list_mtx);
 	while (!list_empty(&dpm_late_early_list)) {
 		struct device *dev = to_device(dpm_late_early_list.next);
-		int error;
 
 		get_device(dev);
 		list_move_tail(&dev->power.entry, &dpm_suspended_list);
-		mutex_unlock(&dpm_list_mtx);
+		if (skip_device_resume(dev, state)) {
+			pm_runtime_set_suspended(dev);
+			pm_runtime_enable(dev);
+			/*
+			 * Balance the pm_runtime_get_noresume() in
+			 * device_prepare().
+			 */
+			pm_runtime_put_noidle(dev);
+			/*
+			 * The device might have been powered up by the platform
+			 * firmware already, so make it resume and then possibly
+			 * suspend again to avoid leaving powered up devices as
+			 * "suspended" for too long.
+			 */
+			pm_request_resume(dev);
+		} else {
+			int error;
 
-		error = device_resume_early(dev, state);
-		if (error) {
-			suspend_stats.failed_resume_early++;
-			dpm_save_failed_step(SUSPEND_RESUME_EARLY);
-			dpm_save_failed_dev(dev_name(dev));
-			pm_dev_err(dev, state, " early", error);
-		}
+			mutex_unlock(&dpm_list_mtx);
+
+			error = device_resume_early(dev, state);
+			if (error) {
+				suspend_stats.failed_resume_early++;
+				dpm_save_failed_step(SUSPEND_RESUME_EARLY);
+				dpm_save_failed_dev(dev_name(dev));
+				pm_dev_err(dev, state, " early", error);
+			}
 
-		mutex_lock(&dpm_list_mtx);
+			mutex_lock(&dpm_list_mtx);
+		}
 		put_device(dev);
 	}
 	mutex_unlock(&dpm_list_mtx);
@@ -682,6 +726,10 @@ void dpm_resume(pm_message_t state)
 
 	list_for_each_entry(dev, &dpm_suspended_list, power.entry) {
 		INIT_COMPLETION(dev->power.completion);
+		if (skip_device_resume(dev, state)) {
+			complete(&dev->power.completion);
+			continue;
+		}
 		if (is_async(dev)) {
 			get_device(dev);
 			async_schedule(async_resume, dev);
@@ -691,7 +739,7 @@ void dpm_resume(pm_message_t state)
 	while (!list_empty(&dpm_suspended_list)) {
 		dev = to_device(dpm_suspended_list.next);
 		get_device(dev);
-		if (!is_async(dev)) {
+		if (!is_async(dev) && !skip_device_resume(dev, state)) {
 			int error;
 
 			mutex_unlock(&dpm_list_mtx);
@@ -780,11 +828,13 @@ void dpm_complete(pm_message_t state)
 		get_device(dev);
 		dev->power.is_prepared = false;
 		list_move(&dev->power.entry, &list);
-		mutex_unlock(&dpm_list_mtx);
+		if (!skip_device_resume(dev, state)) {
+			mutex_unlock(&dpm_list_mtx);
 
-		device_complete(dev, state);
+			device_complete(dev, state);
 
-		mutex_lock(&dpm_list_mtx);
+			mutex_lock(&dpm_list_mtx);
+		}
 		put_device(dev);
 	}
 	list_splice(&list, &dpm_list);
