root/drivers/base/syscore.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. register_syscore_ops
  2. unregister_syscore_ops
  3. syscore_suspend
  4. syscore_resume
  5. syscore_shutdown

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  syscore.c - Execution of system core operations.
   4  *
   5  *  Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
   6  */
   7 
   8 #include <linux/syscore_ops.h>
   9 #include <linux/mutex.h>
  10 #include <linux/module.h>
  11 #include <linux/suspend.h>
  12 #include <trace/events/power.h>
  13 
  14 static LIST_HEAD(syscore_ops_list);
  15 static DEFINE_MUTEX(syscore_ops_lock);
  16 
  17 /**
  18  * register_syscore_ops - Register a set of system core operations.
  19  * @ops: System core operations to register.
  20  */
  21 void register_syscore_ops(struct syscore_ops *ops)
  22 {
  23         mutex_lock(&syscore_ops_lock);
  24         list_add_tail(&ops->node, &syscore_ops_list);
  25         mutex_unlock(&syscore_ops_lock);
  26 }
  27 EXPORT_SYMBOL_GPL(register_syscore_ops);
  28 
  29 /**
  30  * unregister_syscore_ops - Unregister a set of system core operations.
  31  * @ops: System core operations to unregister.
  32  */
  33 void unregister_syscore_ops(struct syscore_ops *ops)
  34 {
  35         mutex_lock(&syscore_ops_lock);
  36         list_del(&ops->node);
  37         mutex_unlock(&syscore_ops_lock);
  38 }
  39 EXPORT_SYMBOL_GPL(unregister_syscore_ops);
  40 
  41 #ifdef CONFIG_PM_SLEEP
  42 /**
  43  * syscore_suspend - Execute all the registered system core suspend callbacks.
  44  *
  45  * This function is executed with one CPU on-line and disabled interrupts.
  46  */
  47 int syscore_suspend(void)
  48 {
  49         struct syscore_ops *ops;
  50         int ret = 0;
  51 
  52         trace_suspend_resume(TPS("syscore_suspend"), 0, true);
  53         pr_debug("Checking wakeup interrupts\n");
  54 
  55         /* Return error code if there are any wakeup interrupts pending. */
  56         if (pm_wakeup_pending())
  57                 return -EBUSY;
  58 
  59         WARN_ONCE(!irqs_disabled(),
  60                 "Interrupts enabled before system core suspend.\n");
  61 
  62         list_for_each_entry_reverse(ops, &syscore_ops_list, node)
  63                 if (ops->suspend) {
  64                         if (initcall_debug)
  65                                 pr_info("PM: Calling %pS\n", ops->suspend);
  66                         ret = ops->suspend();
  67                         if (ret)
  68                                 goto err_out;
  69                         WARN_ONCE(!irqs_disabled(),
  70                                 "Interrupts enabled after %pS\n", ops->suspend);
  71                 }
  72 
  73         trace_suspend_resume(TPS("syscore_suspend"), 0, false);
  74         return 0;
  75 
  76  err_out:
  77         pr_err("PM: System core suspend callback %pS failed.\n", ops->suspend);
  78 
  79         list_for_each_entry_continue(ops, &syscore_ops_list, node)
  80                 if (ops->resume)
  81                         ops->resume();
  82 
  83         return ret;
  84 }
  85 EXPORT_SYMBOL_GPL(syscore_suspend);
  86 
  87 /**
  88  * syscore_resume - Execute all the registered system core resume callbacks.
  89  *
  90  * This function is executed with one CPU on-line and disabled interrupts.
  91  */
  92 void syscore_resume(void)
  93 {
  94         struct syscore_ops *ops;
  95 
  96         trace_suspend_resume(TPS("syscore_resume"), 0, true);
  97         WARN_ONCE(!irqs_disabled(),
  98                 "Interrupts enabled before system core resume.\n");
  99 
 100         list_for_each_entry(ops, &syscore_ops_list, node)
 101                 if (ops->resume) {
 102                         if (initcall_debug)
 103                                 pr_info("PM: Calling %pS\n", ops->resume);
 104                         ops->resume();
 105                         WARN_ONCE(!irqs_disabled(),
 106                                 "Interrupts enabled after %pS\n", ops->resume);
 107                 }
 108         trace_suspend_resume(TPS("syscore_resume"), 0, false);
 109 }
 110 EXPORT_SYMBOL_GPL(syscore_resume);
 111 #endif /* CONFIG_PM_SLEEP */
 112 
 113 /**
 114  * syscore_shutdown - Execute all the registered system core shutdown callbacks.
 115  */
 116 void syscore_shutdown(void)
 117 {
 118         struct syscore_ops *ops;
 119 
 120         mutex_lock(&syscore_ops_lock);
 121 
 122         list_for_each_entry_reverse(ops, &syscore_ops_list, node)
 123                 if (ops->shutdown) {
 124                         if (initcall_debug)
 125                                 pr_info("PM: Calling %pS\n", ops->shutdown);
 126                         ops->shutdown();
 127                 }
 128 
 129         mutex_unlock(&syscore_ops_lock);
 130 }

/* [<][>][^][v][top][bottom][index][help] */