summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/main.c25
-rw-r--r--drivers/base/power/wakeup.c7
-rw-r--r--kernel/irq/pm.c6
-rw-r--r--kernel/power/process.c8
-rw-r--r--kernel/power/suspend.c5
5 files changed, 28 insertions, 23 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 4192e46eda37..07d3de65e990 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -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;
}
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 37658ff761ed..5f3bd234c4be 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -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;
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index cea1de0161f1..d62898ccebed 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -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;
}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index cc177142a08f..372de061dda2 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -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;
}
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index f3bec829aae5..6e7832ee6d74 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -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;
}