diff options
author | Prashant Gaikwad <pgaikwad@nvidia.com> | 2013-09-20 15:39:25 +0530 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2013-10-16 03:00:08 -0700 |
commit | ffa9f5edf19cf631f0cda153285d1b0976e50ff3 (patch) | |
tree | e2eae1ff0b09fa5958f737b300cb200d2186afdb /drivers/base | |
parent | 149256ef49e9be4709e56bba8fefea54e28d7e74 (diff) |
PM / Core: add save and restore syscore ops
Add ops to save and restore system context when entering deep
idle state.
Bug 1254633
Change-Id: Iea36ed98544827ce73b50fcb2bf201c233baf2ca
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Reviewed-on: http://git-master/r/299446
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/syscore.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index 0240f01714a1..64465edb5e53 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c @@ -109,6 +109,79 @@ void syscore_resume(void) } } EXPORT_SYMBOL_GPL(syscore_resume); + +/** + * syscore_save - Execute all the registered system core save callbacks. + * + * This function is executed when going into deep idle state to save system + * context. + */ +int syscore_save(void) +{ + struct syscore_ops *ops; + int ret = 0; + + pr_debug("Checking wakeup interrupts\n"); + + /* Return error code if there are any wakeup interrupts pending. */ + ret = check_wakeup_irqs(); + if (ret) + return ret; + + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled before system core suspend.\n"); + + list_for_each_entry_reverse(ops, &syscore_ops_list, node) + if (ops->save) { + if (initcall_debug) + pr_info("PM: Calling %pF\n", ops->save); + ret = ops->save(); + if (ret) + goto err_out; + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled after %pF\n", ops->save); + } + + return 0; + + err_out: + pr_err("PM: System core save callback %pF failed.\n", ops->save); + + list_for_each_entry_continue(ops, &syscore_ops_list, node) + if (ops->restore) + ops->restore(); + + return ret; +} +EXPORT_SYMBOL_GPL(syscore_save); + +/** + * syscore_restore - Execute all the registered system core restore callbacks. + * + * This function is executed after resuming from deep idle state to restore + * system context. + */ +void syscore_restore(void) +{ + struct syscore_ops *ops; + + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled before system core resume.\n"); + + list_for_each_entry(ops, &syscore_ops_list, node) + if (ops->restore) { + ops->restore(); + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled after %pF\n", ops->restore); + } + if (initcall_debug) { + list_for_each_entry(ops, &syscore_ops_list, node) + if (ops->restore) { + pr_info("PM: Called %pF\n", ops->restore); + } + } +} +EXPORT_SYMBOL_GPL(syscore_restore); #endif /* CONFIG_PM_SLEEP */ /** |