Commit 23812b9d9e497580d38c62ebdc6f308733b0a32a

Authored by Ning Jiang
Committed by Thomas Gleixner
1 parent f9369910a6

genirq: Add IRQS_PENDING for nested and simple irq

Every interrupt which is an active wakeup source needs the ability to
abort suspend if there is a pending irq. Right now only edge and level
irqs can do that.

            |
       +---------+
       |   INTC  |
       +---------+
               | GPIO_IRQ
            +------------+
            |  gpio-exp  |
            +------------+
              |        |
         GPIO0_IRQ  GPIO1_IRQ

In the above diagram, gpio expander has irq number GPIO_IRQ, it is
connected with two sub GPIO pins, GPIO0 and GPIO1.

During suspend, we set IRQF_NO_SUSPEND for GPIO_IRQ so that gpio
expander driver can handle the sub irq GPIO0_IRQ and GPIO1_IRQ, and
these two irqs themselves can further be handled by simple or nested
irq in some drivers(typically gpio and mfd driver). If they are used
as wakeup sources during suspend, we want them to be able to abort
suspend too.

Setting IRQS_PENDING flag in handle_nested_irq() and handle_simple_irq()
when the irq is disabled allows check_wakeup_irqs() to identify such
irqs as source for aborting suspend.

Signed-off-by: Ning Jiang <ning.n.jiang@gmail.com>
Cc: rjw@sisk.pl
Link: http://lkml.kernel.org/r/CAH3Oq6T905%2B3fkF43NAMMFvJvq7dsk_so6T2vQ8ZJrA5xiU3YA@mail.gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Showing 1 changed file with 6 additions and 2 deletions Side-by-side Diff

... ... @@ -275,8 +275,10 @@
275 275 kstat_incr_irqs_this_cpu(irq, desc);
276 276  
277 277 action = desc->action;
278   - if (unlikely(!action || irqd_irq_disabled(&desc->irq_data)))
  278 + if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
  279 + desc->istate |= IRQS_PENDING;
279 280 goto out_unlock;
  281 + }
280 282  
281 283 irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
282 284 raw_spin_unlock_irq(&desc->lock);
283 285  
... ... @@ -324,8 +326,10 @@
324 326 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
325 327 kstat_incr_irqs_this_cpu(irq, desc);
326 328  
327   - if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
  329 + if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
  330 + desc->istate |= IRQS_PENDING;
328 331 goto out_unlock;
  332 + }
329 333  
330 334 handle_irq_event(desc);
331 335