summaryrefslogtreecommitdiff
path: root/kernel/power/wakeup_reason.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/wakeup_reason.c')
-rw-r--r--kernel/power/wakeup_reason.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/kernel/power/wakeup_reason.c b/kernel/power/wakeup_reason.c
index 187e4e9105fb..2aacc34ef17c 100644
--- a/kernel/power/wakeup_reason.c
+++ b/kernel/power/wakeup_reason.c
@@ -31,6 +31,8 @@
#define MAX_WAKEUP_REASON_IRQS 32
static int irq_list[MAX_WAKEUP_REASON_IRQS];
static int irqcount;
+static bool suspend_abort;
+static char abort_reason[MAX_SUSPEND_ABORT_LEN];
static struct kobject *wakeup_reason;
static spinlock_t resume_reason_lock;
@@ -40,14 +42,18 @@ static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribu
int irq_no, buf_offset = 0;
struct irq_desc *desc;
spin_lock(&resume_reason_lock);
- for (irq_no = 0; irq_no < irqcount; irq_no++) {
- desc = irq_to_desc(irq_list[irq_no]);
- if (desc && desc->action && desc->action->name)
- buf_offset += sprintf(buf + buf_offset, "%d %s\n",
- irq_list[irq_no], desc->action->name);
- else
- buf_offset += sprintf(buf + buf_offset, "%d\n",
- irq_list[irq_no]);
+ if (suspend_abort) {
+ buf_offset = sprintf(buf, "Abort: %s", abort_reason);
+ } else {
+ for (irq_no = 0; irq_no < irqcount; irq_no++) {
+ desc = irq_to_desc(irq_list[irq_no]);
+ if (desc && desc->action && desc->action->name)
+ buf_offset += sprintf(buf + buf_offset, "%d %s\n",
+ irq_list[irq_no], desc->action->name);
+ else
+ buf_offset += sprintf(buf + buf_offset, "%d\n",
+ irq_list[irq_no]);
+ }
}
spin_unlock(&resume_reason_lock);
return buf_offset;
@@ -89,6 +95,25 @@ void log_wakeup_reason(int irq)
spin_unlock(&resume_reason_lock);
}
+void log_suspend_abort_reason(const char *fmt, ...)
+{
+ va_list args;
+
+ spin_lock(&resume_reason_lock);
+
+ //Suspend abort reason has already been logged.
+ if (suspend_abort) {
+ spin_unlock(&resume_reason_lock);
+ return;
+ }
+
+ suspend_abort = true;
+ va_start(args, fmt);
+ snprintf(abort_reason, MAX_SUSPEND_ABORT_LEN, fmt, args);
+ va_end(args);
+ spin_unlock(&resume_reason_lock);
+}
+
/* Detects a suspend and clears all the previous wake up reasons*/
static int wakeup_reason_pm_event(struct notifier_block *notifier,
unsigned long pm_event, void *unused)
@@ -97,6 +122,7 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
case PM_SUSPEND_PREPARE:
spin_lock(&resume_reason_lock);
irqcount = 0;
+ suspend_abort = false;
spin_unlock(&resume_reason_lock);
break;
default: