OSDN Git Service

power: Add detailed suspend abort reason
authorMaggie White <maggiewhite@google.com>
Mon, 17 Apr 2017 18:32:46 +0000 (11:32 -0700)
committerArian <arian.kulmer@web.de>
Tue, 19 Nov 2019 14:43:39 +0000 (15:43 +0100)
Test: dumpsys batterystats
Bug: 30874086

(cherry picked from commit a9d6bead120dab67e00bfe5500a616f83b94cf44)

Change-Id: I9feae71693b4addd45550b19ecab7dfd7371c378
Signed-off-by: Maggie White <maggiewhite@google.com>
drivers/base/power/main.c
drivers/base/power/wakeup.c
kernel/irq/pm.c
kernel/power/process.c
kernel/power/suspend.c

index 4192e46..07d3de6 100644 (file)
@@ -1058,11 +1058,13 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
        }
 
        error = dpm_run_callback(callback, dev, state, info);
-       if (!error)
+       if (!error) {
                dev->power.is_noirq_suspended = true;
-       else
+       } else {
+               log_suspend_abort_reason("Callback failed on %s in %pF returned %d",
+                                        dev_name(dev), callback, error);
                async_error = error;
-
+       }
 Complete:
        complete_all(&dev->power.completion);
        TRACE_SUSPEND(error);
@@ -1205,10 +1207,13 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
        }
 
        error = dpm_run_callback(callback, dev, state, info);
-       if (!error)
+       if (!error) {
                dev->power.is_late_suspended = true;
-       else
+       } else {
+               log_suspend_abort_reason("Callback failed on %s in %pF returned %d",
+                                        dev_name(dev), callback, error);
                async_error = error;
+       }
 
 Complete:
        TRACE_SUSPEND(error);
@@ -1351,7 +1356,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        pm_callback_t callback = NULL;
        char *info = NULL;
        int error = 0;
-       char suspend_abort[MAX_SUSPEND_ABORT_LEN];
        DECLARE_DPM_WATCHDOG_ON_STACK(wd);
 
        TRACE_DEVICE(dev);
@@ -1374,9 +1378,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
                pm_wakeup_event(dev, 0);
 
        if (pm_wakeup_pending()) {
-               pm_get_active_wakeup_sources(suspend_abort,
-                       MAX_SUSPEND_ABORT_LEN);
-               log_suspend_abort_reason(suspend_abort);
                dev->power.direct_complete = false;
                async_error = -EBUSY;
                goto Complete;
@@ -1463,6 +1464,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
 
                        spin_unlock_irq(&parent->power.lock);
                }
+       } else {
+               log_suspend_abort_reason("Callback failed on %s in %pF returned %d",
+                                        dev_name(dev), callback, error);
        }
 
        device_unlock(dev);
@@ -1666,6 +1670,9 @@ int dpm_prepare(pm_message_t state)
                        printk(KERN_INFO "PM: Device %s not prepared "
                                "for power transition: code %d\n",
                                dev_name(dev), error);
+                       log_suspend_abort_reason("Device %s not prepared "
+                                                "for power transition: code %d",
+                                                dev_name(dev), error);
                        put_device(dev);
                        break;
                }
index 37658ff..5f3bd23 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_wakeirq.h>
 #include <linux/types.h>
+#include <linux/wakeup_reason.h>
 #include <trace/events/power.h>
 
 #include "power.h"
@@ -884,6 +885,7 @@ bool pm_wakeup_pending(void)
 {
        unsigned long flags;
        bool ret = false;
+       char suspend_abort[MAX_SUSPEND_ABORT_LEN];
 
        spin_lock_irqsave(&events_lock, flags);
        if (events_check_enabled) {
@@ -897,7 +899,10 @@ bool pm_wakeup_pending(void)
 
        if (ret) {
                pr_info("PM: Wakeup pending, aborting suspend\n");
-               pm_print_active_wakeup_sources();
+               pm_get_active_wakeup_sources(suspend_abort,
+                                            MAX_SUSPEND_ABORT_LEN);
+               log_suspend_abort_reason(suspend_abort);
+               pr_info("PM: %s\n", suspend_abort);
        }
 
        return ret || pm_abort_suspend;
index cea1de0..d62898c 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
-
+#include <linux/wakeup_reason.h>
 #include "internals.h"
 
 bool irq_pm_check_wakeup(struct irq_desc *desc)
@@ -21,6 +21,10 @@ bool irq_pm_check_wakeup(struct irq_desc *desc)
                desc->istate |= IRQS_SUSPENDED | IRQS_PENDING;
                desc->depth++;
                irq_disable(desc);
+               log_suspend_abort_reason("Wakeup IRQ %d %s pending",
+                                        desc->irq_data.irq,
+                                        (desc->action && desc->action->name) ?
+                                                desc->action->name : "");
                pm_system_irq_wakeup(irq_desc_get_irq(desc));
                return true;
        }
index cc17714..372de06 100644 (file)
@@ -37,9 +37,6 @@ static int try_to_freeze_tasks(bool user_only)
        unsigned int elapsed_msecs;
        bool wakeup = false;
        int sleep_usecs = USEC_PER_MSEC;
-#ifdef CONFIG_PM_SLEEP
-       char suspend_abort[MAX_SUSPEND_ABORT_LEN];
-#endif
 
        do_gettimeofday(&start);
 
@@ -69,11 +66,6 @@ static int try_to_freeze_tasks(bool user_only)
                        break;
 
                if (pm_wakeup_pending()) {
-#ifdef CONFIG_PM_SLEEP
-                       pm_get_active_wakeup_sources(suspend_abort,
-                               MAX_SUSPEND_ABORT_LEN);
-                       log_suspend_abort_reason(suspend_abort);
-#endif
                        wakeup = true;
                        break;
                }
index f3bec82..6e7832e 100644 (file)
@@ -287,6 +287,7 @@ static int suspend_prepare(suspend_state_t state)
        if (!error)
                return 0;
 
+       log_suspend_abort_reason("One or more tasks refusing to freeze");
        suspend_stats.failed_freeze++;
        dpm_save_failed_step(SUSPEND_FREEZE);
  Finish:
@@ -316,7 +317,6 @@ void __weak arch_suspend_enable_irqs(void)
  */
 static int suspend_enter(suspend_state_t state, bool *wakeup)
 {
-       char suspend_abort[MAX_SUSPEND_ABORT_LEN];
        int error, last_dev;
 
        error = platform_suspend_prepare(state);
@@ -385,9 +385,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
                                state, false);
                        events_check_enabled = false;
                } else if (*wakeup) {
-                       pm_get_active_wakeup_sources(suspend_abort,
-                               MAX_SUSPEND_ABORT_LEN);
-                       log_suspend_abort_reason(suspend_abort);
                        error = -EBUSY;
                }