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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
@@ -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)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
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)
|
|||||||
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.
|
||||||
|
|||||||
@@ -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);
|
|||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user