This source file includes following definitions.
- register_syscore_ops
- unregister_syscore_ops
- syscore_suspend
- syscore_resume
- syscore_shutdown
   1 
   2 
   3 
   4 
   5 
   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 
  19 
  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 
  31 
  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 
  44 
  45 
  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         
  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 
  89 
  90 
  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 
 112 
 113 
 114 
 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 }