mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
set_irq_wake: fix return code and wake status tracking
Since 15a647eba9
set_irq_wake returned -ENXIO
if another device had it already enabled. Zero is the right value to
return in this case. Moreover the change to desc->status was not reverted
if desc->chip->set_wake returned an error.
Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1bad879a07
commit
2db873211b
@ -217,6 +217,17 @@ void enable_irq(unsigned int irq)
|
||||
}
|
||||
EXPORT_SYMBOL(enable_irq);
|
||||
|
||||
int set_irq_wake_real(unsigned int irq, unsigned int on)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
int ret = -ENXIO;
|
||||
|
||||
if (desc->chip->set_wake)
|
||||
ret = desc->chip->set_wake(irq, on);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_irq_wake - control irq power management wakeup
|
||||
* @irq: interrupt to control
|
||||
@ -233,30 +244,34 @@ int set_irq_wake(unsigned int irq, unsigned int on)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
unsigned long flags;
|
||||
int ret = -ENXIO;
|
||||
int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
|
||||
int ret = 0;
|
||||
|
||||
/* wakeup-capable irqs can be shared between drivers that
|
||||
* don't need to have the same sleep mode behaviors.
|
||||
*/
|
||||
spin_lock_irqsave(&desc->lock, flags);
|
||||
if (on) {
|
||||
if (desc->wake_depth++ == 0)
|
||||
desc->status |= IRQ_WAKEUP;
|
||||
else
|
||||
set_wake = NULL;
|
||||
if (desc->wake_depth++ == 0) {
|
||||
ret = set_irq_wake_real(irq, on);
|
||||
if (ret)
|
||||
desc->wake_depth = 0;
|
||||
else
|
||||
desc->status |= IRQ_WAKEUP;
|
||||
}
|
||||
} else {
|
||||
if (desc->wake_depth == 0) {
|
||||
printk(KERN_WARNING "Unbalanced IRQ %d "
|
||||
"wake disable\n", irq);
|
||||
WARN_ON(1);
|
||||
} else if (--desc->wake_depth == 0)
|
||||
desc->status &= ~IRQ_WAKEUP;
|
||||
else
|
||||
set_wake = NULL;
|
||||
} else if (--desc->wake_depth == 0) {
|
||||
ret = set_irq_wake_real(irq, on);
|
||||
if (ret)
|
||||
desc->wake_depth = 1;
|
||||
else
|
||||
desc->status &= ~IRQ_WAKEUP;
|
||||
}
|
||||
}
|
||||
if (set_wake)
|
||||
ret = desc->chip->set_wake(irq, on);
|
||||
|
||||
spin_unlock_irqrestore(&desc->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user