summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorPrashant Gaikwad <pgaikwad@nvidia.com>2013-09-20 15:39:25 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2013-10-16 03:00:08 -0700
commitffa9f5edf19cf631f0cda153285d1b0976e50ff3 (patch)
treee2eae1ff0b09fa5958f737b300cb200d2186afdb /drivers/base
parent149256ef49e9be4709e56bba8fefea54e28d7e74 (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.c73
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 */
/**