This source file includes following definitions.
- suspend_test_start
- suspend_test_finish
- test_wakealarm
- has_wakealarm
- setup_test_suspend
- test_suspend
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/init.h>
   9 #include <linux/rtc.h>
  10 
  11 #include "power.h"
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 #define TEST_SUSPEND_SECONDS    10
  22 
  23 static unsigned long suspend_test_start_time;
  24 static u32 test_repeat_count_max = 1;
  25 static u32 test_repeat_count_current;
  26 
  27 void suspend_test_start(void)
  28 {
  29         
  30 
  31 
  32 
  33         suspend_test_start_time = jiffies;
  34 }
  35 
  36 void suspend_test_finish(const char *label)
  37 {
  38         long nj = jiffies - suspend_test_start_time;
  39         unsigned msec;
  40 
  41         msec = jiffies_to_msecs(abs(nj));
  42         pr_info("PM: %s took %d.%03d seconds\n", label,
  43                         msec / 1000, msec % 1000);
  44 
  45         
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53         WARN(msec > (TEST_SUSPEND_SECONDS * 1000),
  54              "Component: %s, time: %u\n", label, msec);
  55 }
  56 
  57 
  58 
  59 
  60 
  61 
  62 static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
  63 {
  64         static char err_readtime[] __initdata =
  65                 KERN_ERR "PM: can't read %s time, err %d\n";
  66         static char err_wakealarm [] __initdata =
  67                 KERN_ERR "PM: can't set %s wakealarm, err %d\n";
  68         static char err_suspend[] __initdata =
  69                 KERN_ERR "PM: suspend test failed, error %d\n";
  70         static char info_test[] __initdata =
  71                 KERN_INFO "PM: test RTC wakeup from '%s' suspend\n";
  72 
  73         unsigned long           now;
  74         struct rtc_wkalrm       alm;
  75         int                     status;
  76 
  77         
  78 repeat:
  79         status = rtc_read_time(rtc, &alm.time);
  80         if (status < 0) {
  81                 printk(err_readtime, dev_name(&rtc->dev), status);
  82                 return;
  83         }
  84         rtc_tm_to_time(&alm.time, &now);
  85 
  86         memset(&alm, 0, sizeof alm);
  87         rtc_time_to_tm(now + TEST_SUSPEND_SECONDS, &alm.time);
  88         alm.enabled = true;
  89 
  90         status = rtc_set_alarm(rtc, &alm);
  91         if (status < 0) {
  92                 printk(err_wakealarm, dev_name(&rtc->dev), status);
  93                 return;
  94         }
  95 
  96         if (state == PM_SUSPEND_MEM) {
  97                 printk(info_test, pm_states[state]);
  98                 status = pm_suspend(state);
  99                 if (status == -ENODEV)
 100                         state = PM_SUSPEND_STANDBY;
 101         }
 102         if (state == PM_SUSPEND_STANDBY) {
 103                 printk(info_test, pm_states[state]);
 104                 status = pm_suspend(state);
 105                 if (status < 0)
 106                         state = PM_SUSPEND_TO_IDLE;
 107         }
 108         if (state == PM_SUSPEND_TO_IDLE) {
 109                 printk(info_test, pm_states[state]);
 110                 status = pm_suspend(state);
 111         }
 112 
 113         if (status < 0)
 114                 printk(err_suspend, status);
 115 
 116         test_repeat_count_current++;
 117         if (test_repeat_count_current < test_repeat_count_max)
 118                 goto repeat;
 119 
 120         
 121 
 122 
 123 
 124         alm.enabled = false;
 125         rtc_set_alarm(rtc, &alm);
 126 }
 127 
 128 static int __init has_wakealarm(struct device *dev, const void *data)
 129 {
 130         struct rtc_device *candidate = to_rtc_device(dev);
 131 
 132         if (!candidate->ops->set_alarm)
 133                 return 0;
 134         if (!device_may_wakeup(candidate->dev.parent))
 135                 return 0;
 136 
 137         return 1;
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 static const char *test_state_label __initdata;
 146 
 147 static char warn_bad_state[] __initdata =
 148         KERN_WARNING "PM: can't test '%s' suspend state\n";
 149 
 150 static int __init setup_test_suspend(char *value)
 151 {
 152         int i;
 153         char *repeat;
 154         char *suspend_type;
 155 
 156         
 157         value++;
 158         suspend_type = strsep(&value, ",");
 159         if (!suspend_type)
 160                 return 0;
 161 
 162         repeat = strsep(&value, ",");
 163         if (repeat) {
 164                 if (kstrtou32(repeat, 0, &test_repeat_count_max))
 165                         return 0;
 166         }
 167 
 168         for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
 169                 if (!strcmp(pm_labels[i], suspend_type)) {
 170                         test_state_label = pm_labels[i];
 171                         return 0;
 172                 }
 173 
 174         printk(warn_bad_state, suspend_type);
 175         return 0;
 176 }
 177 __setup("test_suspend", setup_test_suspend);
 178 
 179 static int __init test_suspend(void)
 180 {
 181         static char             warn_no_rtc[] __initdata =
 182                 KERN_WARNING "PM: no wakealarm-capable RTC driver is ready\n";
 183 
 184         struct rtc_device       *rtc = NULL;
 185         struct device           *dev;
 186         suspend_state_t test_state;
 187 
 188         
 189         if (!test_state_label)
 190                 return 0;
 191 
 192         for (test_state = PM_SUSPEND_MIN; test_state < PM_SUSPEND_MAX; test_state++) {
 193                 const char *state_label = pm_states[test_state];
 194 
 195                 if (state_label && !strcmp(test_state_label, state_label))
 196                         break;
 197         }
 198         if (test_state == PM_SUSPEND_MAX) {
 199                 printk(warn_bad_state, test_state_label);
 200                 return 0;
 201         }
 202 
 203         
 204         dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm);
 205         if (dev) {
 206                 rtc = rtc_class_open(dev_name(dev));
 207                 put_device(dev);
 208         }
 209         if (!rtc) {
 210                 printk(warn_no_rtc);
 211                 return 0;
 212         }
 213 
 214         
 215         test_wakealarm(rtc, test_state);
 216         rtc_class_close(rtc);
 217         return 0;
 218 }
 219 late_initcall(test_suspend);