提交 786f41fb 编写于 作者: R Rafael J. Wysocki

PM / core: Split dpm_suspend_noirq() and dpm_resume_noirq()

Put the device interrupts disabling and enabling as well as
cpuidle_pause() and cpuidle_resume() called during the "noirq"
stages of system suspend into separate functions to allow the
core suspend-to-idle code to be optimized (later).

The only functional difference this makes is that debug facilities
and diagnostic tools will not include the above operations into the
"noirq" device suspend/resume duration measurements.
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
上级 8e6bcd9f
...@@ -598,14 +598,7 @@ static void async_resume_noirq(void *data, async_cookie_t cookie) ...@@ -598,14 +598,7 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
put_device(dev); put_device(dev);
} }
/** void dpm_noirq_resume_devices(pm_message_t state)
* 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)
{ {
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) ...@@ -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) ...@@ -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);
} }
/** void dpm_noirq_begin(void)
* dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices. {
* @state: PM transition of the system being carried out. cpuidle_pause();
* device_wakeup_arm_wake_irqs();
* Prevent device drivers from receiving interrupts and call the "noirq" suspend suspend_device_irqs();
* handlers for all non-sysdev devices. }
*/
int dpm_suspend_noirq(pm_message_t state) 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) ...@@ -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) ...@@ -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.
......
...@@ -689,6 +689,8 @@ struct dev_pm_domain { ...@@ -689,6 +689,8 @@ struct dev_pm_domain {
extern void device_pm_lock(void); extern void device_pm_lock(void);
extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_start(pm_message_t state);
extern void dpm_resume_end(pm_message_t state); extern void dpm_resume_end(pm_message_t state);
extern void dpm_noirq_resume_devices(pm_message_t state);
extern void dpm_noirq_end(void);
extern void dpm_resume_noirq(pm_message_t state); extern void dpm_resume_noirq(pm_message_t state);
extern void dpm_resume_early(pm_message_t state); extern void dpm_resume_early(pm_message_t state);
extern void dpm_resume(pm_message_t state); extern void dpm_resume(pm_message_t state);
...@@ -697,6 +699,8 @@ extern void dpm_complete(pm_message_t state); ...@@ -697,6 +699,8 @@ extern void dpm_complete(pm_message_t state);
extern void device_pm_unlock(void); extern void device_pm_unlock(void);
extern int dpm_suspend_end(pm_message_t state); extern int dpm_suspend_end(pm_message_t state);
extern int dpm_suspend_start(pm_message_t state); extern int dpm_suspend_start(pm_message_t state);
extern void dpm_noirq_begin(void);
extern int dpm_noirq_suspend_devices(pm_message_t state);
extern int dpm_suspend_noirq(pm_message_t state); extern int dpm_suspend_noirq(pm_message_t state);
extern int dpm_suspend_late(pm_message_t state); extern int dpm_suspend_late(pm_message_t state);
extern int dpm_suspend(pm_message_t state); extern int dpm_suspend(pm_message_t state);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册