main.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * kernel/power/main.c - PM subsystem core functionality.
  3. *
  4. * Copyright (c) 2003 Patrick Mochel
  5. * Copyright (c) 2003 Open Source Development Lab
  6. *
  7. * This file is released under the GPLv2
  8. *
  9. */
  10. #include <linux/kobject.h>
  11. #include <linux/string.h>
  12. #include <linux/resume-trace.h>
  13. #include <linux/workqueue.h>
  14. #include "power.h"
  15. DEFINE_MUTEX(pm_mutex);
  16. #ifdef CONFIG_PM_SLEEP
  17. /* Routines for PM-transition notifications */
  18. static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
  19. int register_pm_notifier(struct notifier_block *nb)
  20. {
  21. return blocking_notifier_chain_register(&pm_chain_head, nb);
  22. }
  23. EXPORT_SYMBOL_GPL(register_pm_notifier);
  24. int unregister_pm_notifier(struct notifier_block *nb)
  25. {
  26. return blocking_notifier_chain_unregister(&pm_chain_head, nb);
  27. }
  28. EXPORT_SYMBOL_GPL(unregister_pm_notifier);
  29. int pm_notifier_call_chain(unsigned long val)
  30. {
  31. int ret = blocking_notifier_call_chain(&pm_chain_head, val, NULL);
  32. return notifier_to_errno(ret);
  33. }
  34. /* If set, devices may be suspended and resumed asynchronously. */
  35. int pm_async_enabled = 1;
  36. static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
  37. char *buf)
  38. {
  39. return sprintf(buf, "%d\n", pm_async_enabled);
  40. }
  41. static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
  42. const char *buf, size_t n)
  43. {
  44. unsigned long val;
  45. if (strict_strtoul(buf, 10, &val))
  46. return -EINVAL;
  47. if (val > 1)
  48. return -EINVAL;
  49. pm_async_enabled = val;
  50. return n;
  51. }
  52. power_attr(pm_async);
  53. #ifdef CONFIG_PM_DEBUG
  54. int pm_test_level = TEST_NONE;
  55. static const char * const pm_tests[__TEST_AFTER_LAST] = {
  56. [TEST_NONE] = "none",
  57. [TEST_CORE] = "core",
  58. [TEST_CPUS] = "processors",
  59. [TEST_PLATFORM] = "platform",
  60. [TEST_DEVICES] = "devices",
  61. [TEST_FREEZER] = "freezer",
  62. };
  63. static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
  64. char *buf)
  65. {
  66. char *s = buf;
  67. int level;
  68. for (level = TEST_FIRST; level <= TEST_MAX; level++)
  69. if (pm_tests[level]) {
  70. if (level == pm_test_level)
  71. s += sprintf(s, "[%s] ", pm_tests[level]);
  72. else
  73. s += sprintf(s, "%s ", pm_tests[level]);
  74. }
  75. if (s != buf)
  76. /* convert the last space to a newline */
  77. *(s-1) = '\n';
  78. return (s - buf);
  79. }
  80. static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
  81. const char *buf, size_t n)
  82. {
  83. const char * const *s;
  84. int level;
  85. char *p;
  86. int len;
  87. int error = -EINVAL;
  88. p = memchr(buf, '\n', n);
  89. len = p ? p - buf : n;
  90. mutex_lock(&pm_mutex);
  91. level = TEST_FIRST;
  92. for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
  93. if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
  94. pm_test_level = level;
  95. error = 0;
  96. break;
  97. }
  98. mutex_unlock(&pm_mutex);
  99. return error ? error : n;
  100. }
  101. power_attr(pm_test);
  102. #endif /* CONFIG_PM_DEBUG */
  103. #endif /* CONFIG_PM_SLEEP */
  104. struct kobject *power_kobj;
  105. /**
  106. * state - control system power state.
  107. *
  108. * show() returns what states are supported, which is hard-coded to
  109. * 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and
  110. * 'disk' (Suspend-to-Disk).
  111. *
  112. * store() accepts one of those strings, translates it into the
  113. * proper enumerated value, and initiates a suspend transition.
  114. */
  115. static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
  116. char *buf)
  117. {
  118. char *s = buf;
  119. #ifdef CONFIG_SUSPEND
  120. int i;
  121. for (i = 0; i < PM_SUSPEND_MAX; i++) {
  122. if (pm_states[i] && valid_state(i))
  123. s += sprintf(s,"%s ", pm_states[i]);
  124. }
  125. #endif
  126. #ifdef CONFIG_HIBERNATION
  127. s += sprintf(s, "%s\n", "disk");
  128. #else
  129. if (s != buf)
  130. /* convert the last space to a newline */
  131. *(s-1) = '\n';
  132. #endif
  133. return (s - buf);
  134. }
  135. static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
  136. const char *buf, size_t n)
  137. {
  138. #ifdef CONFIG_SUSPEND
  139. suspend_state_t state = PM_SUSPEND_STANDBY;
  140. const char * const *s;
  141. #endif
  142. char *p;
  143. int len;
  144. int error = -EINVAL;
  145. p = memchr(buf, '\n', n);
  146. len = p ? p - buf : n;
  147. /* First, check if we are requested to hibernate */
  148. if (len == 4 && !strncmp(buf, "disk", len)) {
  149. error = hibernate();
  150. goto Exit;
  151. }
  152. #ifdef CONFIG_SUSPEND
  153. for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {
  154. if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
  155. break;
  156. }
  157. if (state < PM_SUSPEND_MAX && *s)
  158. error = enter_state(state);
  159. #endif
  160. Exit:
  161. return error ? error : n;
  162. }
  163. power_attr(state);
  164. #ifdef CONFIG_PM_SLEEP
  165. /*
  166. * The 'wakeup_count' attribute, along with the functions defined in
  167. * drivers/base/power/wakeup.c, provides a means by which wakeup events can be
  168. * handled in a non-racy way.
  169. *
  170. * If a wakeup event occurs when the system is in a sleep state, it simply is
  171. * woken up. In turn, if an event that would wake the system up from a sleep
  172. * state occurs when it is undergoing a transition to that sleep state, the
  173. * transition should be aborted. Moreover, if such an event occurs when the
  174. * system is in the working state, an attempt to start a transition to the
  175. * given sleep state should fail during certain period after the detection of
  176. * the event. Using the 'state' attribute alone is not sufficient to satisfy
  177. * these requirements, because a wakeup event may occur exactly when 'state'
  178. * is being written to and may be delivered to user space right before it is
  179. * frozen, so the event will remain only partially processed until the system is
  180. * woken up by another event. In particular, it won't cause the transition to
  181. * a sleep state to be aborted.
  182. *
  183. * This difficulty may be overcome if user space uses 'wakeup_count' before
  184. * writing to 'state'. It first should read from 'wakeup_count' and store
  185. * the read value. Then, after carrying out its own preparations for the system
  186. * transition to a sleep state, it should write the stored value to
  187. * 'wakeup_count'. If that fails, at least one wakeup event has occurred since
  188. * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it
  189. * is allowed to write to 'state', but the transition will be aborted if there
  190. * are any wakeup events detected after 'wakeup_count' was written to.
  191. */
  192. static ssize_t wakeup_count_show(struct kobject *kobj,
  193. struct kobj_attribute *attr,
  194. char *buf)
  195. {
  196. unsigned int val;
  197. return pm_get_wakeup_count(&val) ? sprintf(buf, "%u\n", val) : -EINTR;
  198. }
  199. static ssize_t wakeup_count_store(struct kobject *kobj,
  200. struct kobj_attribute *attr,
  201. const char *buf, size_t n)
  202. {
  203. unsigned int val;
  204. if (sscanf(buf, "%u", &val) == 1) {
  205. if (pm_save_wakeup_count(val))
  206. return n;
  207. }
  208. return -EINVAL;
  209. }
  210. power_attr(wakeup_count);
  211. #endif /* CONFIG_PM_SLEEP */
  212. #ifdef CONFIG_PM_TRACE
  213. int pm_trace_enabled;
  214. static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
  215. char *buf)
  216. {
  217. return sprintf(buf, "%d\n", pm_trace_enabled);
  218. }
  219. static ssize_t
  220. pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
  221. const char *buf, size_t n)
  222. {
  223. int val;
  224. if (sscanf(buf, "%d", &val) == 1) {
  225. pm_trace_enabled = !!val;
  226. return n;
  227. }
  228. return -EINVAL;
  229. }
  230. power_attr(pm_trace);
  231. static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
  232. struct kobj_attribute *attr,
  233. char *buf)
  234. {
  235. return show_trace_dev_match(buf, PAGE_SIZE);
  236. }
  237. static ssize_t
  238. pm_trace_dev_match_store(struct kobject *kobj, struct kobj_attribute *attr,
  239. const char *buf, size_t n)
  240. {
  241. return -EINVAL;
  242. }
  243. power_attr(pm_trace_dev_match);
  244. #endif /* CONFIG_PM_TRACE */
  245. static struct attribute * g[] = {
  246. &state_attr.attr,
  247. #ifdef CONFIG_PM_TRACE
  248. &pm_trace_attr.attr,
  249. &pm_trace_dev_match_attr.attr,
  250. #endif
  251. #ifdef CONFIG_PM_SLEEP
  252. &pm_async_attr.attr,
  253. &wakeup_count_attr.attr,
  254. #ifdef CONFIG_PM_DEBUG
  255. &pm_test_attr.attr,
  256. #endif
  257. #endif
  258. NULL,
  259. };
  260. static struct attribute_group attr_group = {
  261. .attrs = g,
  262. };
  263. #ifdef CONFIG_PM_RUNTIME
  264. struct workqueue_struct *pm_wq;
  265. EXPORT_SYMBOL_GPL(pm_wq);
  266. static int __init pm_start_workqueue(void)
  267. {
  268. pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
  269. return pm_wq ? 0 : -ENOMEM;
  270. }
  271. #else
  272. static inline int pm_start_workqueue(void) { return 0; }
  273. #endif
  274. static int __init pm_init(void)
  275. {
  276. int error = pm_start_workqueue();
  277. if (error)
  278. return error;
  279. hibernate_image_size_init();
  280. hibernate_reserved_size_init();
  281. power_kobj = kobject_create_and_add("power", NULL);
  282. if (!power_kobj)
  283. return -ENOMEM;
  284. return sysfs_create_group(power_kobj, &attr_group);
  285. }
  286. core_initcall(pm_init);