|
@@ -598,14 +598,7 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
|
|
put_device(dev);
|
|
put_device(dev);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices.
|
|
|
|
- * @state: PM transition of the system being carried out.
|
|
|
|
- *
|
|
|
|
- * Call the "noirq" resume handlers for all devices in dpm_noirq_list and
|
|
|
|
- * enable device drivers to receive interrupts.
|
|
|
|
- */
|
|
|
|
-void dpm_resume_noirq(pm_message_t state)
|
|
|
|
|
|
+void dpm_noirq_resume_devices(pm_message_t state)
|
|
{
|
|
{
|
|
struct device *dev;
|
|
struct device *dev;
|
|
ktime_t starttime = ktime_get();
|
|
ktime_t starttime = ktime_get();
|
|
@@ -651,10 +644,27 @@ void dpm_resume_noirq(pm_message_t state)
|
|
mutex_unlock(&dpm_list_mtx);
|
|
mutex_unlock(&dpm_list_mtx);
|
|
async_synchronize_full();
|
|
async_synchronize_full();
|
|
dpm_show_time(starttime, state, "noirq");
|
|
dpm_show_time(starttime, state, "noirq");
|
|
|
|
+ trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void dpm_noirq_end(void)
|
|
|
|
+{
|
|
resume_device_irqs();
|
|
resume_device_irqs();
|
|
device_wakeup_disarm_wake_irqs();
|
|
device_wakeup_disarm_wake_irqs();
|
|
cpuidle_resume();
|
|
cpuidle_resume();
|
|
- trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false);
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices.
|
|
|
|
+ * @state: PM transition of the system being carried out.
|
|
|
|
+ *
|
|
|
|
+ * Invoke the "noirq" resume callbacks for all devices in dpm_noirq_list and
|
|
|
|
+ * allow device drivers' interrupt handlers to be called.
|
|
|
|
+ */
|
|
|
|
+void dpm_resume_noirq(pm_message_t state)
|
|
|
|
+{
|
|
|
|
+ dpm_noirq_resume_devices(state);
|
|
|
|
+ dpm_noirq_end();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1154,22 +1164,19 @@ static int device_suspend_noirq(struct device *dev)
|
|
return __device_suspend_noirq(dev, pm_transition, false);
|
|
return __device_suspend_noirq(dev, pm_transition, false);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices.
|
|
|
|
- * @state: PM transition of the system being carried out.
|
|
|
|
- *
|
|
|
|
- * Prevent device drivers from receiving interrupts and call the "noirq" suspend
|
|
|
|
- * handlers for all non-sysdev devices.
|
|
|
|
- */
|
|
|
|
-int dpm_suspend_noirq(pm_message_t state)
|
|
|
|
|
|
+void dpm_noirq_begin(void)
|
|
|
|
+{
|
|
|
|
+ cpuidle_pause();
|
|
|
|
+ device_wakeup_arm_wake_irqs();
|
|
|
|
+ suspend_device_irqs();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int dpm_noirq_suspend_devices(pm_message_t state)
|
|
{
|
|
{
|
|
ktime_t starttime = ktime_get();
|
|
ktime_t starttime = ktime_get();
|
|
int error = 0;
|
|
int error = 0;
|
|
|
|
|
|
trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
|
|
trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
|
|
- cpuidle_pause();
|
|
|
|
- device_wakeup_arm_wake_irqs();
|
|
|
|
- suspend_device_irqs();
|
|
|
|
mutex_lock(&dpm_list_mtx);
|
|
mutex_lock(&dpm_list_mtx);
|
|
pm_transition = state;
|
|
pm_transition = state;
|
|
async_error = 0;
|
|
async_error = 0;
|
|
@@ -1204,7 +1211,6 @@ int dpm_suspend_noirq(pm_message_t state)
|
|
if (error) {
|
|
if (error) {
|
|
suspend_stats.failed_suspend_noirq++;
|
|
suspend_stats.failed_suspend_noirq++;
|
|
dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
|
|
dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
|
|
- dpm_resume_noirq(resume_event(state));
|
|
|
|
} else {
|
|
} else {
|
|
dpm_show_time(starttime, state, "noirq");
|
|
dpm_show_time(starttime, state, "noirq");
|
|
}
|
|
}
|
|
@@ -1212,6 +1218,25 @@ int dpm_suspend_noirq(pm_message_t state)
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices.
|
|
|
|
+ * @state: PM transition of the system being carried out.
|
|
|
|
+ *
|
|
|
|
+ * Prevent device drivers' interrupt handlers from being called and invoke
|
|
|
|
+ * "noirq" suspend callbacks for all non-sysdev devices.
|
|
|
|
+ */
|
|
|
|
+int dpm_suspend_noirq(pm_message_t state)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ dpm_noirq_begin();
|
|
|
|
+ ret = dpm_noirq_suspend_devices(state);
|
|
|
|
+ if (ret)
|
|
|
|
+ dpm_resume_noirq(resume_event(state));
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* device_suspend_late - Execute a "late suspend" callback for given device.
|
|
* device_suspend_late - Execute a "late suspend" callback for given device.
|
|
* @dev: Device to handle.
|
|
* @dev: Device to handle.
|