Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 82371
b: refs/heads/master
c: 0e7d56e
h: refs/heads/master
i:
  82369: 413e64b
  82367: 681bc99
v: v3
  • Loading branch information
Rafael J. Wysocki authored and Len Brown committed Feb 1, 2008
1 parent f7c4e44 commit 1a1d829
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c3e94d899c864e558f938f9845ddb8c2e5d5ccd0
refs/heads/master: 0e7d56e3d9d7e37c79d0e05ffb3994e34beb3bbc
108 changes: 99 additions & 9 deletions trunk/kernel/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,79 @@ DEFINE_MUTEX(pm_mutex);
unsigned int pm_flags;
EXPORT_SYMBOL(pm_flags);

#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;

static int suspend_test(int level)
{
if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
mdelay(5000);
return 1;
}
return 0;
}

static const char * const pm_tests[__TEST_AFTER_LAST] = {
[TEST_NONE] = "none",
[TEST_CORE] = "core",
[TEST_CPUS] = "processors",
[TEST_PLATFORM] = "platform",
[TEST_DEVICES] = "devices",
[TEST_FREEZER] = "freezer",
};

static ssize_t pm_test_show(struct kset *kset, char *buf)
{
char *s = buf;
int level;

for (level = TEST_FIRST; level <= TEST_MAX; level++)
if (pm_tests[level]) {
if (level == pm_test_level)
s += sprintf(s, "[%s] ", pm_tests[level]);
else
s += sprintf(s, "%s ", pm_tests[level]);
}

if (s != buf)
/* convert the last space to a newline */
*(s-1) = '\n';

return (s - buf);
}

static ssize_t pm_test_store(struct kset *kset, const char *buf, size_t n)
{
const char * const *s;
int level;
char *p;
int len;
int error = -EINVAL;

p = memchr(buf, '\n', n);
len = p ? p - buf : n;

mutex_lock(&pm_mutex);

level = TEST_FIRST;
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
pm_test_level = level;
error = 0;
break;
}

mutex_unlock(&pm_mutex);

return error ? error : n;
}

power_attr(pm_test);
#else /* !CONFIG_PM_DEBUG */
static inline int suspend_test(int level) { return 0; }
#endif /* !CONFIG_PM_DEBUG */

#ifdef CONFIG_SUSPEND

/* This is just an arbitrary number */
Expand Down Expand Up @@ -136,7 +209,10 @@ static int suspend_enter(suspend_state_t state)
printk(KERN_ERR "Some devices failed to power down\n");
goto Done;
}
error = suspend_ops->enter(state);

if (!suspend_test(TEST_CORE))
error = suspend_ops->enter(state);

device_power_up();
Done:
arch_suspend_enable_irqs();
Expand Down Expand Up @@ -167,16 +243,25 @@ int suspend_devices_and_enter(suspend_state_t state)
printk(KERN_ERR "Some devices failed to suspend\n");
goto Resume_console;
}

if (suspend_test(TEST_DEVICES))
goto Resume_devices;

if (suspend_ops->prepare) {
error = suspend_ops->prepare();
if (error)
goto Resume_devices;
}

if (suspend_test(TEST_PLATFORM))
goto Finish;

error = disable_nonboot_cpus();
if (!error)
if (!error && !suspend_test(TEST_CPUS))
suspend_enter(state);

enable_nonboot_cpus();
Finish:
if (suspend_ops->finish)
suspend_ops->finish();
Resume_devices:
Expand Down Expand Up @@ -243,12 +328,17 @@ static int enter_state(suspend_state_t state)
printk("done.\n");

pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
if ((error = suspend_prepare()))
error = suspend_prepare();
if (error)
goto Unlock;

if (suspend_test(TEST_FREEZER))
goto Finish;

pr_debug("PM: Entering %s sleep\n", pm_states[state]);
error = suspend_devices_and_enter(state);

Finish:
pr_debug("PM: Finishing wakeup.\n");
suspend_finish();
Unlock:
Expand Down Expand Up @@ -369,18 +459,18 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
}

power_attr(pm_trace);
#endif /* CONFIG_PM_TRACE */

static struct attribute * g[] = {
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
&pm_trace_attr.attr,
#endif
#ifdef CONFIG_PM_DEBUG
&pm_test_attr.attr,
#endif
NULL,
};
#else
static struct attribute * g[] = {
&state_attr.attr,
NULL,
};
#endif /* CONFIG_PM_TRACE */

static struct attribute_group attr_group = {
.attrs = g,
Expand Down
18 changes: 18 additions & 0 deletions trunk/kernel/power/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,21 @@ int restore_highmem(void);
static inline unsigned int count_highmem_pages(void) { return 0; }
static inline int restore_highmem(void) { return 0; }
#endif

/*
* Suspend test levels
*/
enum {
/* keep first */
TEST_NONE,
TEST_CORE,
TEST_CPUS,
TEST_PLATFORM,
TEST_DEVICES,
TEST_FREEZER,
/* keep last */
__TEST_AFTER_LAST
};

#define TEST_FIRST TEST_NONE
#define TEST_MAX (__TEST_AFTER_LAST - 1)

0 comments on commit 1a1d829

Please sign in to comment.