diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-08-27 21:59:59 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-08-27 21:59:59 -0500 |
commit | 8ce7a9c159c8c4eb480f0a65c6af753dbf9a1a70 (patch) | |
tree | be59573c0af3617d0cd8a7d61f0ed119e58b1156 /kernel/irq/manage.c | |
parent | d2afb3ae04e36dbc6e9eb2d8bd54406ff7b6b3bd (diff) | |
parent | 01da5fd83d6b2c5e36b77539f6cbdd8f49849225 (diff) |
Merge ../linux-2.6
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 4e461438e48..92be519eff2 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -137,16 +137,40 @@ EXPORT_SYMBOL(enable_irq); * @irq: interrupt to control * @on: enable/disable power management wakeup * - * Enable/disable power management wakeup mode + * Enable/disable power management wakeup mode, which is + * disabled by default. Enables and disables must match, + * just as they match for non-wakeup mode support. + * + * Wakeup mode lets this IRQ wake the system from sleep + * states like "suspend to RAM". */ 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; + /* 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 (desc->chip->set_wake) + if (on) { + if (desc->wake_depth++ == 0) + desc->status |= IRQ_WAKEUP; + else + set_wake = NULL; + } 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; + } + if (set_wake) ret = desc->chip->set_wake(irq, on); spin_unlock_irqrestore(&desc->lock, flags); return ret; |