1
0
Fork 0

[PATCH] PM: Add pm_trace switch

Add the pm_trace attribute in /sys/power which has to be explicitly set to
one to really enable the "PM tracing" code compiled in when CONFIG_PM_TRACE
is set (which modifies the machine's CMOS clock in unpredictable ways).

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
hifive-unleashed-5.1
Rafael J. Wysocki 2006-09-25 23:32:58 -07:00 committed by Linus Torvalds
parent 7d145aa3ab
commit c5c6ba4e08
3 changed files with 59 additions and 10 deletions

View File

@ -52,3 +52,18 @@ suspend image will be as small as possible.
Reading from this file will display the current image size limit, which
is set to 500 MB by default.
/sys/power/pm_trace controls the code which saves the last PM event point in
the RTC across reboots, so that you can debug a machine that just hangs
during suspend (or more commonly, during resume). Namely, the RTC is only
used to save the last PM event point if this file contains '1'. Initially it
contains '0' which may be changed to '1' by writing a string representing a
nonzero integer into it.
To use this debugging feature you should attempt to suspend the machine, then
reboot it and run
dmesg -s 1000000 | grep 'hash matches'
CAUTION: Using it will cause your machine's real-time (CMOS) clock to be
set to a random invalid time after a resume.

View File

@ -3,21 +3,25 @@
#ifdef CONFIG_PM_TRACE
extern int pm_trace_enabled;
struct device;
extern void set_trace_device(struct device *);
extern void generate_resume_trace(void *tracedata, unsigned int user);
#define TRACE_DEVICE(dev) set_trace_device(dev)
#define TRACE_RESUME(user) do { \
void *tracedata; \
asm volatile("movl $1f,%0\n" \
".section .tracedata,\"a\"\n" \
"1:\t.word %c1\n" \
"\t.long %c2\n" \
".previous" \
:"=r" (tracedata) \
: "i" (__LINE__), "i" (__FILE__)); \
generate_resume_trace(tracedata, user); \
#define TRACE_RESUME(user) do { \
if (pm_trace_enabled) { \
void *tracedata; \
asm volatile("movl $1f,%0\n" \
".section .tracedata,\"a\"\n" \
"1:\t.word %c1\n" \
"\t.long %c2\n" \
".previous" \
:"=r" (tracedata) \
: "i" (__LINE__), "i" (__FILE__)); \
generate_resume_trace(tracedata, user); \
} \
} while (0)
#else

View File

@ -17,6 +17,7 @@
#include <linux/pm.h>
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/resume-trace.h>
#include "power.h"
@ -281,10 +282,39 @@ static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n
power_attr(state);
#ifdef CONFIG_PM_TRACE
int pm_trace_enabled;
static ssize_t pm_trace_show(struct subsystem * subsys, char * buf)
{
return sprintf(buf, "%d\n", pm_trace_enabled);
}
static ssize_t
pm_trace_store(struct subsystem * subsys, const char * buf, size_t n)
{
int val;
if (sscanf(buf, "%d", &val) == 1) {
pm_trace_enabled = !!val;
return n;
}
return -EINVAL;
}
power_attr(pm_trace);
static struct attribute * g[] = {
&state_attr.attr,
&pm_trace_attr.attr,
NULL,
};
#else
static struct attribute * g[] = {
&state_attr.attr,
NULL,
};
#endif /* CONFIG_PM_TRACE */
static struct attribute_group attr_group = {
.attrs = g,