genirq: Add IRQF_FORCE_RESUME

Xen needs to reenable interrupts which are marked IRQF_NO_SUSPEND in the
resume path. Add a flag to force the reenabling in the resume code.

Tested-and-acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Thomas Gleixner 2011-02-04 13:19:20 +01:00
parent 100b33c8bd
commit dc5f219e88
3 changed files with 12 additions and 5 deletions

View file

@ -55,7 +55,7 @@
* Used by threaded interrupts which need to keep the * Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run. * irq line disabled until the threaded handler has been run.
* IRQF_NO_SUSPEND - Do not disable this IRQ during suspend * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
* * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
*/ */
#define IRQF_DISABLED 0x00000020 #define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040 #define IRQF_SAMPLE_RANDOM 0x00000040
@ -67,6 +67,7 @@
#define IRQF_IRQPOLL 0x00001000 #define IRQF_IRQPOLL 0x00001000
#define IRQF_ONESHOT 0x00002000 #define IRQF_ONESHOT 0x00002000
#define IRQF_NO_SUSPEND 0x00004000 #define IRQF_NO_SUSPEND 0x00004000
#define IRQF_FORCE_RESUME 0x00008000
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND) #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND)

View file

@ -282,8 +282,17 @@ EXPORT_SYMBOL(disable_irq);
void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume) void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
{ {
if (resume) if (resume) {
if (!(desc->status & IRQ_SUSPENDED)) {
if (!desc->action)
return;
if (!(desc->action->flags & IRQF_FORCE_RESUME))
return;
/* Pretend that it got disabled ! */
desc->depth++;
}
desc->status &= ~IRQ_SUSPENDED; desc->status &= ~IRQ_SUSPENDED;
}
switch (desc->depth) { switch (desc->depth) {
case 0: case 0:

View file

@ -53,9 +53,6 @@ void resume_device_irqs(void)
for_each_irq_desc(irq, desc) { for_each_irq_desc(irq, desc) {
unsigned long flags; unsigned long flags;
if (!(desc->status & IRQ_SUSPENDED))
continue;
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
__enable_irq(desc, irq, true); __enable_irq(desc, irq, true);
raw_spin_unlock_irqrestore(&desc->lock, flags); raw_spin_unlock_irqrestore(&desc->lock, flags);