summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2011-12-13 01:23:42 +0800
committerAndy Green <andy.green@linaro.org>2011-12-26 16:42:38 +0800
commit486b7b9361fc2d0f0c648b1998e14bb5a3f14b20 (patch)
tree567cc8451aaf472577e5dcb5349c84af2c23414f /drivers
parent3407969a038600d9a43635d6ecea49a5ffc7240c (diff)
PM: Dump suspend thread stack on dpm suspend timeout
When a driver takes more than 3 seconds to suspend, dump the suspend thread stack since BUG() might only dump the idle thread stack. Change-Id: If854db355fdcf3b773ea20b1b5e031def6d4b114 Signed-off-by: Benoit Goby <benoit@android.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/main.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index c7fa3c6412c..4e365ce9ed0 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -54,6 +54,10 @@ static pm_message_t pm_transition;
static void dpm_drv_timeout(unsigned long data);
static DEFINE_TIMER(dpm_drv_wd, dpm_drv_timeout, 0, 0);
+static struct {
+ struct device *dev;
+ struct task_struct *tsk;
+} dpm_drv_wd_data;
static int async_error;
@@ -615,10 +619,15 @@ static bool is_async(struct device *dev)
*/
static void dpm_drv_timeout(unsigned long data)
{
- struct device *dev = (struct device *) data;
+ struct device *dev = dpm_drv_wd_data.dev;
+ struct task_struct *tsk = dpm_drv_wd_data.tsk;
printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev),
(dev->driver ? dev->driver->name : "no driver"));
+
+ printk(KERN_EMERG "dpm suspend stack:\n");
+ show_stack(tsk, NULL);
+
BUG();
}
@@ -629,7 +638,9 @@ static void dpm_drv_timeout(unsigned long data)
*/
static void dpm_drv_wdset(struct device *dev)
{
- dpm_drv_wd.data = (unsigned long) dev;
+ dpm_drv_wd_data.dev = dev;
+ dpm_drv_wd_data.tsk = get_current();
+ dpm_drv_wd.data = (unsigned long) &dpm_drv_wd_data;
mod_timer(&dpm_drv_wd, jiffies + (HZ * 3));
}