linux/kernel/power/main.c
<<
>>
Prefs
   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
  11#include <linux/export.h>
  12#include <linux/kobject.h>
  13#include <linux/string.h>
  14#include <linux/pm-trace.h>
  15#include <linux/workqueue.h>
  16#include <linux/debugfs.h>
  17#include <linux/seq_file.h>
  18
  19#include "power.h"
  20
  21DEFINE_MUTEX(pm_mutex);
  22
  23#ifdef CONFIG_PM_SLEEP
  24
  25/* Routines for PM-transition notifications */
  26
  27static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
  28
  29int register_pm_notifier(struct notifier_block *nb)
  30{
  31        return blocking_notifier_chain_register(&pm_chain_head, nb);
  32}
  33EXPORT_SYMBOL_GPL(register_pm_notifier);
  34
  35int unregister_pm_notifier(struct notifier_block *nb)
  36{
  37        return blocking_notifier_chain_unregister(&pm_chain_head, nb);
  38}
  39EXPORT_SYMBOL_GPL(unregister_pm_notifier);
  40
  41int __pm_notifier_call_chain(unsigned long val, int nr_to_call, int *nr_calls)
  42{
  43        int ret;
  44
  45        ret = __blocking_notifier_call_chain(&pm_chain_head, val, NULL,
  46                                                nr_to_call, nr_calls);
  47
  48        return notifier_to_errno(ret);
  49}
  50int pm_notifier_call_chain(unsigned long val)
  51{
  52        return __pm_notifier_call_chain(val, -1, NULL);
  53}
  54
  55/* If set, devices may be suspended and resumed asynchronously. */
  56int pm_async_enabled = 1;
  57
  58static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
  59                             char *buf)
  60{
  61        return sprintf(buf, "%d\n", pm_async_enabled);
  62}
  63
  64static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
  65                              const char *buf, size_t n)
  66{
  67        unsigned long val;
  68
  69        if (kstrtoul(buf, 10, &val))
  70                return -EINVAL;
  71
  72        if (val > 1)
  73                return -EINVAL;
  74
  75        pm_async_enabled = val;
  76        return n;
  77}
  78
  79power_attr(pm_async);
  80
  81#ifdef CONFIG_SUSPEND
  82static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
  83                              char *buf)
  84{
  85        char *s = buf;
  86        suspend_state_t i;
  87
  88        for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
  89                if (mem_sleep_states[i]) {
  90                        const char *label = mem_sleep_states[i];
  91
  92                        if (mem_sleep_current == i)
  93                                s += sprintf(s, "[%s] ", label);
  94                        else
  95                                s += sprintf(s, "%s ", label);
  96                }
  97
  98        /* Convert the last space to a newline if needed. */
  99        if (s != buf)
 100                *(s-1) = '\n';
 101
 102        return (s - buf);
 103}
 104
 105static suspend_state_t decode_suspend_state(const char *buf, size_t n)
 106{
 107        suspend_state_t state;
 108        char *p;
 109        int len;
 110
 111        p = memchr(buf, '\n', n);
 112        len = p ? p - buf : n;
 113
 114        for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
 115                const char *label = mem_sleep_states[state];
 116
 117                if (label && len == strlen(label) && !strncmp(buf, label, len))
 118                        return state;
 119        }
 120
 121        return PM_SUSPEND_ON;
 122}
 123
 124static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
 125                               const char *buf, size_t n)
 126{
 127        suspend_state_t state;
 128        int error;
 129
 130        error = pm_autosleep_lock();
 131        if (error)
 132                return error;
 133
 134        if (pm_autosleep_state() > PM_SUSPEND_ON) {
 135                error = -EBUSY;
 136                goto out;
 137        }
 138
 139        state = decode_suspend_state(buf, n);
 140        if (state < PM_SUSPEND_MAX && state > PM_SUSPEND_ON)
 141                mem_sleep_current = state;
 142        else
 143                error = -EINVAL;
 144
 145 out:
 146        pm_autosleep_unlock();
 147        return error ? error : n;
 148}
 149
 150power_attr(mem_sleep);
 151#endif /* CONFIG_SUSPEND */
 152
 153#ifdef CONFIG_PM_SLEEP_DEBUG
 154int pm_test_level = TEST_NONE;
 155
 156static const char * const pm_tests[__TEST_AFTER_LAST] = {
 157        [TEST_NONE] = "none",
 158        [TEST_CORE] = "core",
 159        [TEST_CPUS] = "processors",
 160        [TEST_PLATFORM] = "platform",
 161        [TEST_DEVICES] = "devices",
 162        [TEST_FREEZER] = "freezer",
 163};
 164
 165static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
 166                                char *buf)
 167{
 168        char *s = buf;
 169        int level;
 170
 171        for (level = TEST_FIRST; level <= TEST_MAX; level++)
 172                if (pm_tests[level]) {
 173                        if (level == pm_test_level)
 174                                s += sprintf(s, "[%s] ", pm_tests[level]);
 175                        else
 176                                s += sprintf(s, "%s ", pm_tests[level]);
 177                }
 178
 179        if (s != buf)
 180                /* convert the last space to a newline */
 181                *(s-1) = '\n';
 182
 183        return (s - buf);
 184}
 185
 186static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
 187                                const char *buf, size_t n)
 188{
 189        const char * const *s;
 190        int level;
 191        char *p;
 192        int len;
 193        int error = -EINVAL;
 194
 195        p = memchr(buf, '\n', n);
 196        len = p ? p - buf : n;
 197
 198        lock_system_sleep();
 199
 200        level = TEST_FIRST;
 201        for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
 202                if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
 203                        pm_test_level = level;
 204                        error = 0;
 205                        break;
 206                }
 207
 208        unlock_system_sleep();
 209
 210        return error ? error : n;
 211}
 212
 213power_attr(pm_test);
 214#endif /* CONFIG_PM_SLEEP_DEBUG */
 215
 216#ifdef CONFIG_DEBUG_FS
 217static char *suspend_step_name(enum suspend_stat_step step)
 218{
 219        switch (step) {
 220        case SUSPEND_FREEZE:
 221                return "freeze";
 222        case SUSPEND_PREPARE:
 223                return "prepare";
 224        case SUSPEND_SUSPEND:
 225                return "suspend";
 226        case SUSPEND_SUSPEND_NOIRQ:
 227                return "suspend_noirq";
 228        case SUSPEND_RESUME_NOIRQ:
 229                return "resume_noirq";
 230        case SUSPEND_RESUME:
 231                return "resume";
 232        default:
 233                return "";
 234        }
 235}
 236
 237static int suspend_stats_show(struct seq_file *s, void *unused)
 238{
 239        int i, index, last_dev, last_errno, last_step;
 240
 241        last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
 242        last_dev %= REC_FAILED_NUM;
 243        last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
 244        last_errno %= REC_FAILED_NUM;
 245        last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
 246        last_step %= REC_FAILED_NUM;
 247        seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
 248                        "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
 249                        "success", suspend_stats.success,
 250                        "fail", suspend_stats.fail,
 251                        "failed_freeze", suspend_stats.failed_freeze,
 252                        "failed_prepare", suspend_stats.failed_prepare,
 253                        "failed_suspend", suspend_stats.failed_suspend,
 254                        "failed_suspend_late",
 255                                suspend_stats.failed_suspend_late,
 256                        "failed_suspend_noirq",
 257                                suspend_stats.failed_suspend_noirq,
 258                        "failed_resume", suspend_stats.failed_resume,
 259                        "failed_resume_early",
 260                                suspend_stats.failed_resume_early,
 261                        "failed_resume_noirq",
 262                                suspend_stats.failed_resume_noirq);
 263        seq_printf(s,   "failures:\n  last_failed_dev:\t%-s\n",
 264                        suspend_stats.failed_devs[last_dev]);
 265        for (i = 1; i < REC_FAILED_NUM; i++) {
 266                index = last_dev + REC_FAILED_NUM - i;
 267                index %= REC_FAILED_NUM;
 268                seq_printf(s, "\t\t\t%-s\n",
 269                        suspend_stats.failed_devs[index]);
 270        }
 271        seq_printf(s,   "  last_failed_errno:\t%-d\n",
 272                        suspend_stats.errno[last_errno]);
 273        for (i = 1; i < REC_FAILED_NUM; i++) {
 274                index = last_errno + REC_FAILED_NUM - i;
 275                index %= REC_FAILED_NUM;
 276                seq_printf(s, "\t\t\t%-d\n",
 277                        suspend_stats.errno[index]);
 278        }
 279        seq_printf(s,   "  last_failed_step:\t%-s\n",
 280                        suspend_step_name(
 281                                suspend_stats.failed_steps[last_step]));
 282        for (i = 1; i < REC_FAILED_NUM; i++) {
 283                index = last_step + REC_FAILED_NUM - i;
 284                index %= REC_FAILED_NUM;
 285                seq_printf(s, "\t\t\t%-s\n",
 286                        suspend_step_name(
 287                                suspend_stats.failed_steps[index]));
 288        }
 289
 290        return 0;
 291}
 292
 293static int suspend_stats_open(struct inode *inode, struct file *file)
 294{
 295        return single_open(file, suspend_stats_show, NULL);
 296}
 297
 298static const struct file_operations suspend_stats_operations = {
 299        .open           = suspend_stats_open,
 300        .read           = seq_read,
 301        .llseek         = seq_lseek,
 302        .release        = single_release,
 303};
 304
 305static int __init pm_debugfs_init(void)
 306{
 307        debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
 308                        NULL, NULL, &suspend_stats_operations);
 309        return 0;
 310}
 311
 312late_initcall(pm_debugfs_init);
 313#endif /* CONFIG_DEBUG_FS */
 314
 315#endif /* CONFIG_PM_SLEEP */
 316
 317#ifdef CONFIG_PM_SLEEP_DEBUG
 318/*
 319 * pm_print_times: print time taken by devices to suspend and resume.
 320 *
 321 * show() returns whether printing of suspend and resume times is enabled.
 322 * store() accepts 0 or 1.  0 disables printing and 1 enables it.
 323 */
 324bool pm_print_times_enabled;
 325
 326static ssize_t pm_print_times_show(struct kobject *kobj,
 327                                   struct kobj_attribute *attr, char *buf)
 328{
 329        return sprintf(buf, "%d\n", pm_print_times_enabled);
 330}
 331
 332static ssize_t pm_print_times_store(struct kobject *kobj,
 333                                    struct kobj_attribute *attr,
 334                                    const char *buf, size_t n)
 335{
 336        unsigned long val;
 337
 338        if (kstrtoul(buf, 10, &val))
 339                return -EINVAL;
 340
 341        if (val > 1)
 342                return -EINVAL;
 343
 344        pm_print_times_enabled = !!val;
 345        return n;
 346}
 347
 348power_attr(pm_print_times);
 349
 350static inline void pm_print_times_init(void)
 351{
 352        pm_print_times_enabled = !!initcall_debug;
 353}
 354
 355static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
 356                                        struct kobj_attribute *attr,
 357                                        char *buf)
 358{
 359        return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
 360}
 361
 362power_attr_ro(pm_wakeup_irq);
 363
 364bool pm_debug_messages_on __read_mostly;
 365
 366static ssize_t pm_debug_messages_show(struct kobject *kobj,
 367                                      struct kobj_attribute *attr, char *buf)
 368{
 369        return sprintf(buf, "%d\n", pm_debug_messages_on);
 370}
 371
 372static ssize_t pm_debug_messages_store(struct kobject *kobj,
 373                                       struct kobj_attribute *attr,
 374                                       const char *buf, size_t n)
 375{
 376        unsigned long val;
 377
 378        if (kstrtoul(buf, 10, &val))
 379                return -EINVAL;
 380
 381        if (val > 1)
 382                return -EINVAL;
 383
 384        pm_debug_messages_on = !!val;
 385        return n;
 386}
 387
 388power_attr(pm_debug_messages);
 389
 390/**
 391 * __pm_pr_dbg - Print a suspend debug message to the kernel log.
 392 * @defer: Whether or not to use printk_deferred() to print the message.
 393 * @fmt: Message format.
 394 *
 395 * The message will be emitted if enabled through the pm_debug_messages
 396 * sysfs attribute.
 397 */
 398void __pm_pr_dbg(bool defer, const char *fmt, ...)
 399{
 400        struct va_format vaf;
 401        va_list args;
 402
 403        if (!pm_debug_messages_on)
 404                return;
 405
 406        va_start(args, fmt);
 407
 408        vaf.fmt = fmt;
 409        vaf.va = &args;
 410
 411        if (defer)
 412                printk_deferred(KERN_DEBUG "PM: %pV", &vaf);
 413        else
 414                printk(KERN_DEBUG "PM: %pV", &vaf);
 415
 416        va_end(args);
 417}
 418
 419#else /* !CONFIG_PM_SLEEP_DEBUG */
 420static inline void pm_print_times_init(void) {}
 421#endif /* CONFIG_PM_SLEEP_DEBUG */
 422
 423struct kobject *power_kobj;
 424
 425/**
 426 * state - control system sleep states.
 427 *
 428 * show() returns available sleep state labels, which may be "mem", "standby",
 429 * "freeze" and "disk" (hibernation).  See Documentation/power/states.txt for a
 430 * description of what they mean.
 431 *
 432 * store() accepts one of those strings, translates it into the proper
 433 * enumerated value, and initiates a suspend transition.
 434 */
 435static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
 436                          char *buf)
 437{
 438        char *s = buf;
 439#ifdef CONFIG_SUSPEND
 440        suspend_state_t i;
 441
 442        for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
 443                if (pm_states[i])
 444                        s += sprintf(s,"%s ", pm_states[i]);
 445
 446#endif
 447        if (hibernation_available())
 448                s += sprintf(s, "disk ");
 449        if (s != buf)
 450                /* convert the last space to a newline */
 451                *(s-1) = '\n';
 452        return (s - buf);
 453}
 454
 455static suspend_state_t decode_state(const char *buf, size_t n)
 456{
 457#ifdef CONFIG_SUSPEND
 458        suspend_state_t state;
 459#endif
 460        char *p;
 461        int len;
 462
 463        p = memchr(buf, '\n', n);
 464        len = p ? p - buf : n;
 465
 466        /* Check hibernation first. */
 467        if (len == 4 && !strncmp(buf, "disk", len))
 468                return PM_SUSPEND_MAX;
 469
 470#ifdef CONFIG_SUSPEND
 471        for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) {
 472                const char *label = pm_states[state];
 473
 474                if (label && len == strlen(label) && !strncmp(buf, label, len))
 475                        return state;
 476        }
 477#endif
 478
 479        return PM_SUSPEND_ON;
 480}
 481
 482static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
 483                           const char *buf, size_t n)
 484{
 485        suspend_state_t state;
 486        int error;
 487
 488        error = pm_autosleep_lock();
 489        if (error)
 490                return error;
 491
 492        if (pm_autosleep_state() > PM_SUSPEND_ON) {
 493                error = -EBUSY;
 494                goto out;
 495        }
 496
 497        state = decode_state(buf, n);
 498        if (state < PM_SUSPEND_MAX) {
 499                if (state == PM_SUSPEND_MEM)
 500                        state = mem_sleep_current;
 501
 502                error = pm_suspend(state);
 503        } else if (state == PM_SUSPEND_MAX) {
 504                error = hibernate();
 505        } else {
 506                error = -EINVAL;
 507        }
 508
 509 out:
 510        pm_autosleep_unlock();
 511        return error ? error : n;
 512}
 513
 514power_attr(state);
 515
 516#ifdef CONFIG_PM_SLEEP
 517/*
 518 * The 'wakeup_count' attribute, along with the functions defined in
 519 * drivers/base/power/wakeup.c, provides a means by which wakeup events can be
 520 * handled in a non-racy way.
 521 *
 522 * If a wakeup event occurs when the system is in a sleep state, it simply is
 523 * woken up.  In turn, if an event that would wake the system up from a sleep
 524 * state occurs when it is undergoing a transition to that sleep state, the
 525 * transition should be aborted.  Moreover, if such an event occurs when the
 526 * system is in the working state, an attempt to start a transition to the
 527 * given sleep state should fail during certain period after the detection of
 528 * the event.  Using the 'state' attribute alone is not sufficient to satisfy
 529 * these requirements, because a wakeup event may occur exactly when 'state'
 530 * is being written to and may be delivered to user space right before it is
 531 * frozen, so the event will remain only partially processed until the system is
 532 * woken up by another event.  In particular, it won't cause the transition to
 533 * a sleep state to be aborted.
 534 *
 535 * This difficulty may be overcome if user space uses 'wakeup_count' before
 536 * writing to 'state'.  It first should read from 'wakeup_count' and store
 537 * the read value.  Then, after carrying out its own preparations for the system
 538 * transition to a sleep state, it should write the stored value to
 539 * 'wakeup_count'.  If that fails, at least one wakeup event has occurred since
 540 * 'wakeup_count' was read and 'state' should not be written to.  Otherwise, it
 541 * is allowed to write to 'state', but the transition will be aborted if there
 542 * are any wakeup events detected after 'wakeup_count' was written to.
 543 */
 544
 545static ssize_t wakeup_count_show(struct kobject *kobj,
 546                                struct kobj_attribute *attr,
 547                                char *buf)
 548{
 549        unsigned int val;
 550
 551        return pm_get_wakeup_count(&val, true) ?
 552                sprintf(buf, "%u\n", val) : -EINTR;
 553}
 554
 555static ssize_t wakeup_count_store(struct kobject *kobj,
 556                                struct kobj_attribute *attr,
 557                                const char *buf, size_t n)
 558{
 559        unsigned int val;
 560        int error;
 561
 562        error = pm_autosleep_lock();
 563        if (error)
 564                return error;
 565
 566        if (pm_autosleep_state() > PM_SUSPEND_ON) {
 567                error = -EBUSY;
 568                goto out;
 569        }
 570
 571        error = -EINVAL;
 572        if (sscanf(buf, "%u", &val) == 1) {
 573                if (pm_save_wakeup_count(val))
 574                        error = n;
 575                else
 576                        pm_print_active_wakeup_sources();
 577        }
 578
 579 out:
 580        pm_autosleep_unlock();
 581        return error;
 582}
 583
 584power_attr(wakeup_count);
 585
 586#ifdef CONFIG_PM_AUTOSLEEP
 587static ssize_t autosleep_show(struct kobject *kobj,
 588                              struct kobj_attribute *attr,
 589                              char *buf)
 590{
 591        suspend_state_t state = pm_autosleep_state();
 592
 593        if (state == PM_SUSPEND_ON)
 594                return sprintf(buf, "off\n");
 595
 596#ifdef CONFIG_SUSPEND
 597        if (state < PM_SUSPEND_MAX)
 598                return sprintf(buf, "%s\n", pm_states[state] ?
 599                                        pm_states[state] : "error");
 600#endif
 601#ifdef CONFIG_HIBERNATION
 602        return sprintf(buf, "disk\n");
 603#else
 604        return sprintf(buf, "error");
 605#endif
 606}
 607
 608static ssize_t autosleep_store(struct kobject *kobj,
 609                               struct kobj_attribute *attr,
 610                               const char *buf, size_t n)
 611{
 612        suspend_state_t state = decode_state(buf, n);
 613        int error;
 614
 615        if (state == PM_SUSPEND_ON
 616            && strcmp(buf, "off") && strcmp(buf, "off\n"))
 617                return -EINVAL;
 618
 619        if (state == PM_SUSPEND_MEM)
 620                state = mem_sleep_current;
 621
 622        error = pm_autosleep_set_state(state);
 623        return error ? error : n;
 624}
 625
 626power_attr(autosleep);
 627#endif /* CONFIG_PM_AUTOSLEEP */
 628
 629#ifdef CONFIG_PM_WAKELOCKS
 630static ssize_t wake_lock_show(struct kobject *kobj,
 631                              struct kobj_attribute *attr,
 632                              char *buf)
 633{
 634        return pm_show_wakelocks(buf, true);
 635}
 636
 637static ssize_t wake_lock_store(struct kobject *kobj,
 638                               struct kobj_attribute *attr,
 639                               const char *buf, size_t n)
 640{
 641        int error = pm_wake_lock(buf);
 642        return error ? error : n;
 643}
 644
 645power_attr(wake_lock);
 646
 647static ssize_t wake_unlock_show(struct kobject *kobj,
 648                                struct kobj_attribute *attr,
 649                                char *buf)
 650{
 651        return pm_show_wakelocks(buf, false);
 652}
 653
 654static ssize_t wake_unlock_store(struct kobject *kobj,
 655                                 struct kobj_attribute *attr,
 656                                 const char *buf, size_t n)
 657{
 658        int error = pm_wake_unlock(buf);
 659        return error ? error : n;
 660}
 661
 662power_attr(wake_unlock);
 663
 664#endif /* CONFIG_PM_WAKELOCKS */
 665#endif /* CONFIG_PM_SLEEP */
 666
 667#ifdef CONFIG_PM_TRACE
 668int pm_trace_enabled;
 669
 670static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
 671                             char *buf)
 672{
 673        return sprintf(buf, "%d\n", pm_trace_enabled);
 674}
 675
 676static ssize_t
 677pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
 678               const char *buf, size_t n)
 679{
 680        int val;
 681
 682        if (sscanf(buf, "%d", &val) == 1) {
 683                pm_trace_enabled = !!val;
 684                if (pm_trace_enabled) {
 685                        pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
 686                                "PM: Correct system time has to be restored manually after resume.\n");
 687                }
 688                return n;
 689        }
 690        return -EINVAL;
 691}
 692
 693power_attr(pm_trace);
 694
 695static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
 696                                       struct kobj_attribute *attr,
 697                                       char *buf)
 698{
 699        return show_trace_dev_match(buf, PAGE_SIZE);
 700}
 701
 702power_attr_ro(pm_trace_dev_match);
 703
 704#endif /* CONFIG_PM_TRACE */
 705
 706#ifdef CONFIG_FREEZER
 707static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
 708                                      struct kobj_attribute *attr, char *buf)
 709{
 710        return sprintf(buf, "%u\n", freeze_timeout_msecs);
 711}
 712
 713static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
 714                                       struct kobj_attribute *attr,
 715                                       const char *buf, size_t n)
 716{
 717        unsigned long val;
 718
 719        if (kstrtoul(buf, 10, &val))
 720                return -EINVAL;
 721
 722        freeze_timeout_msecs = val;
 723        return n;
 724}
 725
 726power_attr(pm_freeze_timeout);
 727
 728#endif  /* CONFIG_FREEZER*/
 729
 730static struct attribute * g[] = {
 731        &state_attr.attr,
 732#ifdef CONFIG_PM_TRACE
 733        &pm_trace_attr.attr,
 734        &pm_trace_dev_match_attr.attr,
 735#endif
 736#ifdef CONFIG_PM_SLEEP
 737        &pm_async_attr.attr,
 738        &wakeup_count_attr.attr,
 739#ifdef CONFIG_SUSPEND
 740        &mem_sleep_attr.attr,
 741#endif
 742#ifdef CONFIG_PM_AUTOSLEEP
 743        &autosleep_attr.attr,
 744#endif
 745#ifdef CONFIG_PM_WAKELOCKS
 746        &wake_lock_attr.attr,
 747        &wake_unlock_attr.attr,
 748#endif
 749#ifdef CONFIG_PM_SLEEP_DEBUG
 750        &pm_test_attr.attr,
 751        &pm_print_times_attr.attr,
 752        &pm_wakeup_irq_attr.attr,
 753        &pm_debug_messages_attr.attr,
 754#endif
 755#endif
 756#ifdef CONFIG_FREEZER
 757        &pm_freeze_timeout_attr.attr,
 758#endif
 759        NULL,
 760};
 761
 762static const struct attribute_group attr_group = {
 763        .attrs = g,
 764};
 765
 766struct workqueue_struct *pm_wq;
 767EXPORT_SYMBOL_GPL(pm_wq);
 768
 769static int __init pm_start_workqueue(void)
 770{
 771        pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
 772
 773        return pm_wq ? 0 : -ENOMEM;
 774}
 775
 776static int __init pm_init(void)
 777{
 778        int error = pm_start_workqueue();
 779        if (error)
 780                return error;
 781        hibernate_image_size_init();
 782        hibernate_reserved_size_init();
 783        pm_states_init();
 784        power_kobj = kobject_create_and_add("power", NULL);
 785        if (!power_kobj)
 786                return -ENOMEM;
 787        error = sysfs_create_group(power_kobj, &attr_group);
 788        if (error)
 789                return error;
 790        pm_print_times_init();
 791        return pm_autosleep_init();
 792}
 793
 794core_initcall(pm_init);
 795