diff options
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 4e461438e48b..92be519eff26 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -137,16 +137,40 @@ EXPORT_SYMBOL(enable_irq); | |||
| 137 | * @irq: interrupt to control | 137 | * @irq: interrupt to control |
| 138 | * @on: enable/disable power management wakeup | 138 | * @on: enable/disable power management wakeup |
| 139 | * | 139 | * |
| 140 | * Enable/disable power management wakeup mode | 140 | * Enable/disable power management wakeup mode, which is |
| 141 | * disabled by default. Enables and disables must match, | ||
| 142 | * just as they match for non-wakeup mode support. | ||
| 143 | * | ||
| 144 | * Wakeup mode lets this IRQ wake the system from sleep | ||
| 145 | * states like "suspend to RAM". | ||
| 141 | */ | 146 | */ |
| 142 | int set_irq_wake(unsigned int irq, unsigned int on) | 147 | int set_irq_wake(unsigned int irq, unsigned int on) |
| 143 | { | 148 | { |
| 144 | struct irq_desc *desc = irq_desc + irq; | 149 | struct irq_desc *desc = irq_desc + irq; |
| 145 | unsigned long flags; | 150 | unsigned long flags; |
| 146 | int ret = -ENXIO; | 151 | int ret = -ENXIO; |
| 152 | int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake; | ||
| 147 | 153 | ||
| 154 | /* wakeup-capable irqs can be shared between drivers that | ||
| 155 | * don't need to have the same sleep mode behaviors. | ||
| 156 | */ | ||
| 148 | spin_lock_irqsave(&desc->lock, flags); | 157 | spin_lock_irqsave(&desc->lock, flags); |
| 149 | if (desc->chip->set_wake) | 158 | if (on) { |
| 159 | if (desc->wake_depth++ == 0) | ||
| 160 | desc->status |= IRQ_WAKEUP; | ||
| 161 | else | ||
| 162 | set_wake = NULL; | ||
| 163 | } else { | ||
| 164 | if (desc->wake_depth == 0) { | ||
| 165 | printk(KERN_WARNING "Unbalanced IRQ %d " | ||
| 166 | "wake disable\n", irq); | ||
| 167 | WARN_ON(1); | ||
| 168 | } else if (--desc->wake_depth == 0) | ||
| 169 | desc->status &= ~IRQ_WAKEUP; | ||
| 170 | else | ||
| 171 | set_wake = NULL; | ||
| 172 | } | ||
| 173 | if (set_wake) | ||
| 150 | ret = desc->chip->set_wake(irq, on); | 174 | ret = desc->chip->set_wake(irq, on); |
| 151 | spin_unlock_irqrestore(&desc->lock, flags); | 175 | spin_unlock_irqrestore(&desc->lock, flags); |
| 152 | return ret; | 176 | return ret; |
