genirq: Add irq disabled flag to irq_data state
Thomas Gleixner [Sun, 27 Mar 2011 09:02:49 +0000 (11:02 +0200)]
Some irq_chip implementation require to know the disabled state of the
interrupt in certain callbacks. Add a state flag and accessor to
irq_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

include/linux/irq.h
kernel/irq/chip.c
kernel/irq/irqdesc.c

index 5d876c9..8649b0f 100644 (file)
@@ -174,6 +174,8 @@ struct irq_data {
  *                               from suspend
  * IRDQ_MOVE_PCNTXT            - Interrupt can be moved in process
  *                               context
+ * IRQD_IRQ_DISABLED           - Some chip function need to know the
+ *                               disabled state.
  */
 enum {
        IRQD_TRIGGER_MASK               = 0xf,
@@ -184,6 +186,7 @@ enum {
        IRQD_LEVEL                      = (1 << 13),
        IRQD_WAKEUP_STATE               = (1 << 14),
        IRQD_MOVE_PCNTXT                = (1 << 15),
+       IRQD_IRQ_DISABLED               = (1 << 16),
 };
 
 static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
@@ -235,6 +238,11 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d)
        return d->state_use_accessors & IRQD_MOVE_PCNTXT;
 }
 
+static inline bool irqd_irq_disabled(struct irq_data *d)
+{
+       return d->state_use_accessors & IRQD_IRQ_DISABLED;
+}
+
 /**
  * struct irq_chip - hardware interrupt chip descriptor
  *
index c35d74c..0a890bd 100644 (file)
@@ -141,12 +141,14 @@ EXPORT_SYMBOL_GPL(irq_get_irq_data);
 static void irq_state_clr_disabled(struct irq_desc *desc)
 {
        desc->istate &= ~IRQS_DISABLED;
+       irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED);
        irq_compat_clr_disabled(desc);
 }
 
 static void irq_state_set_disabled(struct irq_desc *desc)
 {
        desc->istate |= IRQS_DISABLED;
+       irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
        irq_compat_set_disabled(desc);
 }
 
@@ -648,8 +650,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
        if (handle == handle_bad_irq) {
                if (desc->irq_data.chip != &no_irq_chip)
                        mask_ack_irq(desc);
-               irq_compat_set_disabled(desc);
-               desc->istate |= IRQS_DISABLED;
+               irq_state_set_disabled(desc);
                desc->depth = 1;
        }
        desc->handle_irq = handle;
index 6fb014f..96c3268 100644 (file)
@@ -80,6 +80,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
        desc->irq_data.handler_data = NULL;
        desc->irq_data.msi_desc = NULL;
        irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
+       irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
        desc->istate = IRQS_DISABLED;
        desc->handle_irq = handle_bad_irq;
        desc->depth = 1;