Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84a6a00b authored by claude.yen's avatar claude.yen Committed by Todd Kjos
Browse files

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: default avatarclaude.yen <claude.yen@mediatek.com>
Change-Id: I13756e4aa083e1f86ffc9030ff9506a3092d8933
(cherry picked from commit 8f61f09d3c9d6078e2832ef771c183cc6c07175d)
parent 7a9803c5
Loading
Loading
Loading
Loading
+31 −13
Original line number Diff line number Diff line
@@ -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;
@@ -204,13 +220,16 @@ void __log_abort_or_abnormal_wake(bool abort, const char *fmt, va_list args)
	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);
@@ -242,8 +261,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);
@@ -258,17 +276,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");
@@ -285,19 +303,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);