diff options
author | Rebecca Schultz Zavin <rebecca@android.com> | 2011-01-28 21:58:22 -0800 |
---|---|---|
committer | Rebecca Schultz Zavin <rebecca@android.com> | 2011-01-28 21:58:22 -0800 |
commit | bfb8b878f3e4b004eae71ad55ad3f3baca57452a (patch) | |
tree | 6c3192a7486e53b138d2620c99ef62103e46ea57 | |
parent | 8f47f22d81d514a3c947d161b2fcd4a51351a5da (diff) | |
parent | 6f0193721acf50368b585e3fad8c206049e2e07a (diff) |
Merge remote branch 'common/android-2.6.36' into android-tegra-2.6.36
-rw-r--r-- | drivers/base/power/main.c | 50 | ||||
-rw-r--r-- | kernel/irq/pm.c | 6 |
2 files changed, 25 insertions, 31 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 33f9aafb47fb..4ff491f49ee4 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -47,11 +47,10 @@ static DEFINE_MUTEX(dpm_list_mtx); 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 dpm_drv_wd_data { struct device *dev; struct task_struct *tsk; -} dpm_drv_wd_data; +}; /* * Set once the preparation of devices for a PM transition has started, reset @@ -605,8 +604,9 @@ static bool is_async(struct device *dev) */ static void dpm_drv_timeout(unsigned long data) { - struct device *dev = dpm_drv_wd_data.dev; - struct task_struct *tsk = dpm_drv_wd_data.tsk; + struct dpm_drv_wd_data *wd_data = (void *)data; + struct device *dev = wd_data->dev; + struct task_struct *tsk = wd_data->tsk; printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev), (dev->driver ? dev->driver->name : "no driver")); @@ -618,29 +618,6 @@ static void dpm_drv_timeout(unsigned long data) } /** - * dpm_drv_wdset - Sets up driver suspend/resume watchdog timer. - * @dev: struct device which we're guarding. - * - */ -static void dpm_drv_wdset(struct device *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)); -} - -/** - * dpm_drv_wdclr - clears driver suspend/resume watchdog timer. - * @dev: struct device which we're no longer guarding. - * - */ -static void dpm_drv_wdclr(struct device *dev) -{ - del_timer_sync(&dpm_drv_wd); -} - -/** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. * @@ -896,8 +873,19 @@ static int async_error; static int __device_suspend(struct device *dev, pm_message_t state, bool async) { int error = 0; + struct timer_list timer; + struct dpm_drv_wd_data data; dpm_wait_for_children(dev, async); + + data.dev = dev; + data.tsk = get_current(); + init_timer_on_stack(&timer); + timer.expires = jiffies + HZ * 3; + timer.function = dpm_drv_timeout; + timer.data = (unsigned long)&data; + add_timer(&timer); + device_lock(dev); if (async_error) @@ -939,6 +927,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) End: device_unlock(dev); + + del_timer_sync(&timer); + destroy_timer_on_stack(&timer); + complete_all(&dev->power.completion); return error; @@ -991,9 +983,7 @@ static int dpm_suspend(pm_message_t state) get_device(dev); mutex_unlock(&dpm_list_mtx); - dpm_drv_wdset(dev); error = device_suspend(dev); - dpm_drv_wdclr(dev); mutex_lock(&dpm_list_mtx); if (error) { diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index 0d4005d85b03..1df62ef4713b 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -72,8 +72,12 @@ int check_wakeup_irqs(void) int irq; for_each_irq_desc(irq, desc) - if ((desc->status & IRQ_WAKEUP) && (desc->status & IRQ_PENDING)) + if ((desc->status & IRQ_WAKEUP) && + (desc->status & IRQ_PENDING)) { + pr_info("Wakeup IRQ %d %s pending, suspend aborted\n", + irq, desc->name ? desc->name : ""); return -EBUSY; + } return 0; } |