diff options
| -rw-r--r-- | kernel/irq/manage.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 77a51be36010..3cfc0fefb5ee 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -217,6 +217,17 @@ void enable_irq(unsigned int irq) | |||
| 217 | } | 217 | } |
| 218 | EXPORT_SYMBOL(enable_irq); | 218 | EXPORT_SYMBOL(enable_irq); |
| 219 | 219 | ||
| 220 | int set_irq_wake_real(unsigned int irq, unsigned int on) | ||
| 221 | { | ||
| 222 | struct irq_desc *desc = irq_desc + irq; | ||
| 223 | int ret = -ENXIO; | ||
| 224 | |||
| 225 | if (desc->chip->set_wake) | ||
| 226 | ret = desc->chip->set_wake(irq, on); | ||
| 227 | |||
| 228 | return ret; | ||
| 229 | } | ||
| 230 | |||
| 220 | /** | 231 | /** |
| 221 | * set_irq_wake - control irq power management wakeup | 232 | * set_irq_wake - control irq power management wakeup |
| 222 | * @irq: interrupt to control | 233 | * @irq: interrupt to control |
| @@ -233,30 +244,34 @@ int set_irq_wake(unsigned int irq, unsigned int on) | |||
| 233 | { | 244 | { |
| 234 | struct irq_desc *desc = irq_desc + irq; | 245 | struct irq_desc *desc = irq_desc + irq; |
| 235 | unsigned long flags; | 246 | unsigned long flags; |
| 236 | int ret = -ENXIO; | 247 | int ret = 0; |
| 237 | int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake; | ||
| 238 | 248 | ||
| 239 | /* wakeup-capable irqs can be shared between drivers that | 249 | /* wakeup-capable irqs can be shared between drivers that |
| 240 | * don't need to have the same sleep mode behaviors. | 250 | * don't need to have the same sleep mode behaviors. |
| 241 | */ | 251 | */ |
| 242 | spin_lock_irqsave(&desc->lock, flags); | 252 | spin_lock_irqsave(&desc->lock, flags); |
| 243 | if (on) { | 253 | if (on) { |
| 244 | if (desc->wake_depth++ == 0) | 254 | if (desc->wake_depth++ == 0) { |
| 245 | desc->status |= IRQ_WAKEUP; | 255 | ret = set_irq_wake_real(irq, on); |
| 246 | else | 256 | if (ret) |
| 247 | set_wake = NULL; | 257 | desc->wake_depth = 0; |
| 258 | else | ||
| 259 | desc->status |= IRQ_WAKEUP; | ||
| 260 | } | ||
| 248 | } else { | 261 | } else { |
| 249 | if (desc->wake_depth == 0) { | 262 | if (desc->wake_depth == 0) { |
| 250 | printk(KERN_WARNING "Unbalanced IRQ %d " | 263 | printk(KERN_WARNING "Unbalanced IRQ %d " |
| 251 | "wake disable\n", irq); | 264 | "wake disable\n", irq); |
| 252 | WARN_ON(1); | 265 | WARN_ON(1); |
| 253 | } else if (--desc->wake_depth == 0) | 266 | } else if (--desc->wake_depth == 0) { |
| 254 | desc->status &= ~IRQ_WAKEUP; | 267 | ret = set_irq_wake_real(irq, on); |
| 255 | else | 268 | if (ret) |
| 256 | set_wake = NULL; | 269 | desc->wake_depth = 1; |
| 270 | else | ||
| 271 | desc->status &= ~IRQ_WAKEUP; | ||
| 272 | } | ||
| 257 | } | 273 | } |
| 258 | if (set_wake) | 274 | |
| 259 | ret = desc->chip->set_wake(irq, on); | ||
| 260 | spin_unlock_irqrestore(&desc->lock, flags); | 275 | spin_unlock_irqrestore(&desc->lock, flags); |
| 261 | return ret; | 276 | return ret; |
| 262 | } | 277 | } |
