[patch 3/4] genirq: Add IRQF_FORCE_RESUME

From: Thomas Gleixner
Date: Sat Feb 05 2011 - 15:09:37 EST


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.

Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
include/linux/interrupt.h | 3 ++-
include/linux/irq.h | 4 +++-
kernel/irq/manage.c | 11 ++++++++++-
kernel/irq/pm.c | 3 ---
4 files changed, 15 insertions(+), 6 deletions(-)

Index: linux-next/include/linux/interrupt.h
===================================================================
--- linux-next.orig/include/linux/interrupt.h
+++ linux-next/include/linux/interrupt.h
@@ -57,7 +57,7 @@
* Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run.
* 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_SAMPLE_RANDOM 0x00000040
@@ -69,6 +69,7 @@
#define IRQF_IRQPOLL 0x00001000
#define IRQF_ONESHOT 0x00002000
#define IRQF_NO_SUSPEND 0x00004000
+#define IRQF_FORCE_RESUME 0x00008000

#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND)

Index: linux-next/include/linux/irq.h
===================================================================
--- linux-next.orig/include/linux/irq.h
+++ linux-next/include/linux/irq.h
@@ -71,10 +71,12 @@ typedef void (*irq_flow_handler_t)(unsig
#define IRQ_SUSPENDED 0x04000000 /* IRQ has gone through suspend sequence */
#define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */
#define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */
+#define IRQ_FORCE_SUSPEND 0x20000000 /* Ignore IRQF_NO_SUSPEND */

#define IRQF_MODIFY_MASK \
(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
- IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
+ IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL \
+ IRQ_FORCE_SUSPEND)

#ifdef CONFIG_IRQ_PER_CPU
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
Index: linux-next/kernel/irq/manage.c
===================================================================
--- linux-next.orig/kernel/irq/manage.c
+++ linux-next/kernel/irq/manage.c
@@ -359,8 +359,17 @@ EXPORT_SYMBOL(disable_irq);

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;
+ }

switch (desc->depth) {
case 0:
Index: linux-next/kernel/irq/pm.c
===================================================================
--- linux-next.orig/kernel/irq/pm.c
+++ linux-next/kernel/irq/pm.c
@@ -53,9 +53,6 @@ void resume_device_irqs(void)
for_each_irq_desc(irq, desc) {
unsigned long flags;

- if (!(desc->status & IRQ_SUSPENDED))
- continue;
-
raw_spin_lock_irqsave(&desc->lock, flags);
__enable_irq(desc, irq, true);
raw_spin_unlock_irqrestore(&desc->lock, flags);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/