suspend_test.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * kernel/power/suspend_test.c - Suspend to RAM and standby test facility.
  4. *
  5. * Copyright (c) 2009 Pavel Machek <pavel@ucw.cz>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/rtc.h>
  9. #include "power.h"
  10. /*
  11. * We test the system suspend code by setting an RTC wakealarm a short
  12. * time in the future, then suspending. Suspending the devices won't
  13. * normally take long ... some systems only need a few milliseconds.
  14. *
  15. * The time it takes is system-specific though, so when we test this
  16. * during system bootup we allow a LOT of time.
  17. */
  18. #define TEST_SUSPEND_SECONDS 10
  19. static unsigned long suspend_test_start_time;
  20. static u32 test_repeat_count_max = 1;
  21. static u32 test_repeat_count_current;
  22. void suspend_test_start(void)
  23. {
  24. /* FIXME Use better timebase than "jiffies", ideally a clocksource.
  25. * What we want is a hardware counter that will work correctly even
  26. * during the irqs-are-off stages of the suspend/resume cycle...
  27. */
  28. suspend_test_start_time = jiffies;
  29. }
  30. void suspend_test_finish(const char *label)
  31. {
  32. long nj = jiffies - suspend_test_start_time;
  33. unsigned msec;
  34. msec = jiffies_to_msecs(abs(nj));
  35. pr_info("PM: %s took %d.%03d seconds\n", label,
  36. msec / 1000, msec % 1000);
  37. /* Warning on suspend means the RTC alarm period needs to be
  38. * larger -- the system was sooo slooowwww to suspend that the
  39. * alarm (should have) fired before the system went to sleep!
  40. *
  41. * Warning on either suspend or resume also means the system
  42. * has some performance issues. The stack dump of a WARN_ON
  43. * is more likely to get the right attention than a printk...
  44. */
  45. WARN(msec > (TEST_SUSPEND_SECONDS * 1000),
  46. "Component: %s, time: %u\n", label, msec);
  47. }
  48. /*
  49. * To test system suspend, we need a hands-off mechanism to resume the
  50. * system. RTCs wake alarms are a common self-contained mechanism.
  51. */
  52. static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
  53. {
  54. static char err_readtime[] __initdata =
  55. KERN_ERR "PM: can't read %s time, err %d\n";
  56. static char err_wakealarm [] __initdata =
  57. KERN_ERR "PM: can't set %s wakealarm, err %d\n";
  58. static char err_suspend[] __initdata =
  59. KERN_ERR "PM: suspend test failed, error %d\n";
  60. static char info_test[] __initdata =
  61. KERN_INFO "PM: test RTC wakeup from '%s' suspend\n";
  62. time64_t now;
  63. struct rtc_wkalrm alm;
  64. int status;
  65. /* this may fail if the RTC hasn't been initialized */
  66. repeat:
  67. status = rtc_read_time(rtc, &alm.time);
  68. if (status < 0) {
  69. printk(err_readtime, dev_name(&rtc->dev), status);
  70. return;
  71. }
  72. now = rtc_tm_to_time64(&alm.time);
  73. memset(&alm, 0, sizeof alm);
  74. rtc_time64_to_tm(now + TEST_SUSPEND_SECONDS, &alm.time);
  75. alm.enabled = true;
  76. status = rtc_set_alarm(rtc, &alm);
  77. if (status < 0) {
  78. printk(err_wakealarm, dev_name(&rtc->dev), status);
  79. return;
  80. }
  81. if (state == PM_SUSPEND_MEM) {
  82. printk(info_test, pm_states[state]);
  83. status = pm_suspend(state);
  84. if (status == -ENODEV)
  85. state = PM_SUSPEND_STANDBY;
  86. }
  87. if (state == PM_SUSPEND_STANDBY) {
  88. printk(info_test, pm_states[state]);
  89. status = pm_suspend(state);
  90. if (status < 0)
  91. state = PM_SUSPEND_TO_IDLE;
  92. }
  93. if (state == PM_SUSPEND_TO_IDLE) {
  94. printk(info_test, pm_states[state]);
  95. status = pm_suspend(state);
  96. }
  97. if (status < 0)
  98. printk(err_suspend, status);
  99. test_repeat_count_current++;
  100. if (test_repeat_count_current < test_repeat_count_max)
  101. goto repeat;
  102. /* Some platforms can't detect that the alarm triggered the
  103. * wakeup, or (accordingly) disable it after it afterwards.
  104. * It's supposed to give oneshot behavior; cope.
  105. */
  106. alm.enabled = false;
  107. rtc_set_alarm(rtc, &alm);
  108. }
  109. static int __init has_wakealarm(struct device *dev, const void *data)
  110. {
  111. struct rtc_device *candidate = to_rtc_device(dev);
  112. if (!candidate->ops->set_alarm)
  113. return 0;
  114. if (!device_may_wakeup(candidate->dev.parent))
  115. return 0;
  116. return 1;
  117. }
  118. /*
  119. * Kernel options like "test_suspend=mem" force suspend/resume sanity tests
  120. * at startup time. They're normally disabled, for faster boot and because
  121. * we can't know which states really work on this particular system.
  122. */
  123. static const char *test_state_label __initdata;
  124. static char warn_bad_state[] __initdata =
  125. KERN_WARNING "PM: can't test '%s' suspend state\n";
  126. static int __init setup_test_suspend(char *value)
  127. {
  128. int i;
  129. char *repeat;
  130. char *suspend_type;
  131. /* example : "=mem[,N]" ==> "mem[,N]" */
  132. value++;
  133. suspend_type = strsep(&value, ",");
  134. if (!suspend_type)
  135. return 1;
  136. repeat = strsep(&value, ",");
  137. if (repeat) {
  138. if (kstrtou32(repeat, 0, &test_repeat_count_max))
  139. return 1;
  140. }
  141. for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
  142. if (!strcmp(pm_labels[i], suspend_type)) {
  143. test_state_label = pm_labels[i];
  144. return 1;
  145. }
  146. printk(warn_bad_state, suspend_type);
  147. return 1;
  148. }
  149. __setup("test_suspend", setup_test_suspend);
  150. static int __init test_suspend(void)
  151. {
  152. static char warn_no_rtc[] __initdata =
  153. KERN_WARNING "PM: no wakealarm-capable RTC driver is ready\n";
  154. struct rtc_device *rtc = NULL;
  155. struct device *dev;
  156. suspend_state_t test_state;
  157. /* PM is initialized by now; is that state testable? */
  158. if (!test_state_label)
  159. return 0;
  160. for (test_state = PM_SUSPEND_MIN; test_state < PM_SUSPEND_MAX; test_state++) {
  161. const char *state_label = pm_states[test_state];
  162. if (state_label && !strcmp(test_state_label, state_label))
  163. break;
  164. }
  165. if (test_state == PM_SUSPEND_MAX) {
  166. printk(warn_bad_state, test_state_label);
  167. return 0;
  168. }
  169. /* RTCs have initialized by now too ... can we use one? */
  170. dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm);
  171. if (dev) {
  172. rtc = rtc_class_open(dev_name(dev));
  173. put_device(dev);
  174. }
  175. if (!rtc) {
  176. printk(warn_no_rtc);
  177. return 0;
  178. }
  179. /* go for it */
  180. test_wakealarm(rtc, test_state);
  181. rtc_class_close(rtc);
  182. return 0;
  183. }
  184. late_initcall(test_suspend);