summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-03-16 09:42:34 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-03-16 09:54:46 +0800
commit4b5cdefdbcb3eb0c01efc714e2b7fe6d8fb5ca21 (patch)
tree63fa92f684fa43a7975fa70c5855c43b0d316ac0 /include
parent779beac355abcaffdefc958feec5b0a2992d850d (diff)
ENGR00175844 irq: enable IRQF_EARLY_RESUME irq when dpm_suspend_noirq failed
The dpm_suspend_noirq routing calls suspend_device_irqs() first to disable all the irq no matter what flags it has. Then it enumerates the device driver on dpm_suspend_list to call their suspend_noirq pm callback. If any dev suspend failed, it will call dpm_resume_noirq to re-enable all the irq without IRQF_EARLY_RESUME, and return failed. If dpm_suspend_noirq() return failed, then no syscore_resume() can be called, that means the irq with flag IRQF_EARLY_RESUME, can not be re-enabled on this case. error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { .. goto Platform_finish; } .... error = syscore_suspend(); if (!error) { ... syscore_resume(); } ... dpm_resume_noirq(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); So we must enable all the irqs no matter it's IRQF_EARLY_RESUME or not. Otherwise the GPIO power key who's irq has flag of IRQF_EARLY_RESUME will be disabled forever when some device failed to suspend. Signed-off-by: Xinyu Chen <xinyu.chen@freescale.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/interrupt.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index b9490bf39399..61ace3b6f482 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -216,6 +216,7 @@ extern void enable_irq(unsigned int irq);
#ifdef CONFIG_GENERIC_HARDIRQS
extern void suspend_device_irqs(void);
extern void resume_device_irqs(void);
+extern void resume_irqs(bool);
#ifdef CONFIG_PM_SLEEP
extern int check_wakeup_irqs(void);
#else
@@ -224,6 +225,7 @@ static inline int check_wakeup_irqs(void) { return 0; }
#else
static inline void suspend_device_irqs(void) { };
static inline void resume_device_irqs(void) { };
+extern inline void resume_irqs(bool) { };
static inline int check_wakeup_irqs(void) { return 0; }
#endif