ANDROID: power: wakeup_reason: refine wakeup logs

make sure that only one of the following wakeup reasons being captured:

  1. RESUME_IRQ: system has suspended successfully and wakeup by IRQs.
  2. RESUME_ABORT: wakeup sources are activated during suspend flow.
  3. RESUME_ABNORMAL: misconfigured IRQ being captured.

Bug: 160945565
Signed-off-by: claude.yen <claude.yen@mediatek.com>
Change-Id: I13756e4aa083e1f86ffc9030ff9506a3092d8933
This commit is contained in:
claude.yen 2020-07-10 16:57:50 +08:00 committed by Todd Kjos
parent 2488b4d45f
commit 8f61f09d3c

View File

@ -41,6 +41,13 @@ struct wakeup_irq_node {
const char *irq_name;
};
enum wakeup_reason_flag {
RESUME_NONE = 0,
RESUME_IRQ,
RESUME_ABORT,
RESUME_ABNORMAL,
};
static DEFINE_SPINLOCK(wakeup_reason_lock);
static LIST_HEAD(leaf_irqs); /* kept in ascending IRQ sorted order */
@ -53,8 +60,7 @@ static const char *default_irq_name = "(unnamed)";
static struct kobject *kobj;
static bool capture_reasons;
static bool suspend_abort;
static bool abnormal_wake;
static int wakeup_reason;
static char non_irq_wake_reason[MAX_SUSPEND_ABORT_LEN];
static ktime_t last_monotime; /* monotonic time before last suspend */
@ -147,6 +153,10 @@ void log_irq_wakeup_reason(int irq)
unsigned long flags;
spin_lock_irqsave(&wakeup_reason_lock, flags);
if (wakeup_reason == RESUME_ABNORMAL || wakeup_reason == RESUME_ABORT) {
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return;
}
if (!capture_reasons) {
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
@ -156,6 +166,7 @@ void log_irq_wakeup_reason(int irq)
if (find_node_in_list(&parent_irqs, irq) == NULL)
add_sibling_node_sorted(&leaf_irqs, irq);
wakeup_reason = RESUME_IRQ;
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
}
@ -176,6 +187,11 @@ void log_threaded_irq_wakeup_reason(int irq, int parent_irq)
spin_lock_irqsave(&wakeup_reason_lock, flags);
if (wakeup_reason == RESUME_ABNORMAL || wakeup_reason == RESUME_ABORT) {
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return;
}
if (!capture_reasons || (find_node_in_list(&leaf_irqs, irq) != NULL)) {
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return;
@ -205,13 +221,16 @@ static void __log_abort_or_abnormal_wake(bool abort, const char *fmt,
spin_lock_irqsave(&wakeup_reason_lock, flags);
/* Suspend abort or abnormal wake reason has already been logged. */
if (suspend_abort || abnormal_wake) {
if (wakeup_reason != RESUME_NONE) {
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return;
}
suspend_abort = abort;
abnormal_wake = !abort;
if (abort)
wakeup_reason = RESUME_ABORT;
else
wakeup_reason = RESUME_ABNORMAL;
vsnprintf(non_irq_wake_reason, MAX_SUSPEND_ABORT_LEN, fmt, args);
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
@ -243,8 +262,7 @@ void clear_wakeup_reasons(void)
delete_list(&leaf_irqs);
delete_list(&parent_irqs);
suspend_abort = false;
abnormal_wake = false;
wakeup_reason = RESUME_NONE;
capture_reasons = true;
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
@ -259,17 +277,17 @@ static void print_wakeup_sources(void)
capture_reasons = false;
if (suspend_abort) {
if (wakeup_reason == RESUME_ABORT) {
pr_info("Abort: %s\n", non_irq_wake_reason);
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return;
}
if (!list_empty(&leaf_irqs))
if (wakeup_reason == RESUME_IRQ && !list_empty(&leaf_irqs))
list_for_each_entry(n, &leaf_irqs, siblings)
pr_info("Resume caused by IRQ %d, %s\n", n->irq,
n->irq_name);
else if (abnormal_wake)
else if (wakeup_reason == RESUME_ABNORMAL)
pr_info("Resume caused by %s\n", non_irq_wake_reason);
else
pr_info("Resume cause unknown\n");
@ -286,19 +304,19 @@ static ssize_t last_resume_reason_show(struct kobject *kobj,
spin_lock_irqsave(&wakeup_reason_lock, flags);
if (suspend_abort) {
if (wakeup_reason == RESUME_ABORT) {
buf_offset = scnprintf(buf, PAGE_SIZE, "Abort: %s",
non_irq_wake_reason);
spin_unlock_irqrestore(&wakeup_reason_lock, flags);
return buf_offset;
}
if (!list_empty(&leaf_irqs))
if (wakeup_reason == RESUME_IRQ && !list_empty(&leaf_irqs))
list_for_each_entry(n, &leaf_irqs, siblings)
buf_offset += scnprintf(buf + buf_offset,
PAGE_SIZE - buf_offset,
"%d %s\n", n->irq, n->irq_name);
else if (abnormal_wake)
else if (wakeup_reason == RESUME_ABNORMAL)
buf_offset = scnprintf(buf, PAGE_SIZE, "-1 %s",
non_irq_wake_reason);