Merge branch 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
Linus Torvalds [Fri, 26 Mar 2010 22:09:06 +0000 (15:09 -0700)]
* 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  genirq: Move two IRQ functions from .init.text to .text
  genirq: Protect access to irq_desc->action in can_request_irq()
  genirq: Prevent oneshot irq thread race

1  2 
kernel/irq/chip.c

diff --combined kernel/irq/chip.c
@@@ -359,6 -359,23 +359,23 @@@ static inline void mask_ack_irq(struct 
                if (desc->chip->ack)
                        desc->chip->ack(irq);
        }
+       desc->status |= IRQ_MASKED;
+ }
+ static inline void mask_irq(struct irq_desc *desc, int irq)
+ {
+       if (desc->chip->mask) {
+               desc->chip->mask(irq);
+               desc->status |= IRQ_MASKED;
+       }
+ }
+ static inline void unmask_irq(struct irq_desc *desc, int irq)
+ {
+       if (desc->chip->unmask) {
+               desc->chip->unmask(irq);
+               desc->status &= ~IRQ_MASKED;
+       }
  }
  
  /*
@@@ -484,10 -501,8 +501,8 @@@ handle_level_irq(unsigned int irq, stru
        raw_spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
  
-       if (unlikely(desc->status & IRQ_ONESHOT))
-               desc->status |= IRQ_MASKED;
-       else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-               desc->chip->unmask(irq);
+       if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))
+               unmask_irq(desc, irq);
  out_unlock:
        raw_spin_unlock(&desc->lock);
  }
@@@ -524,8 -539,7 +539,7 @@@ handle_fasteoi_irq(unsigned int irq, st
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
                desc->status |= IRQ_PENDING;
-               if (desc->chip->mask)
-                       desc->chip->mask(irq);
+               mask_irq(desc, irq);
                goto out;
        }
  
@@@ -554,7 -568,7 +568,7 @@@ out
   *    signal. The occurence is latched into the irq controller hardware
   *    and must be acked in order to be reenabled. After the ack another
   *    interrupt can happen on the same source even before the first one
 - *    is handled by the assosiacted event handler. If this happens it
 + *    is handled by the associated event handler. If this happens it
   *    might be necessary to disable (mask) the interrupt depending on the
   *    controller hardware. This requires to reenable the interrupt inside
   *    of the loop which handles the interrupts which have arrived while
@@@ -593,7 -607,7 +607,7 @@@ handle_edge_irq(unsigned int irq, struc
                irqreturn_t action_ret;
  
                if (unlikely(!action)) {
-                       desc->chip->mask(irq);
+                       mask_irq(desc, irq);
                        goto out_unlock;
                }
  
                if (unlikely((desc->status &
                               (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
                              (IRQ_PENDING | IRQ_MASKED))) {
-                       desc->chip->unmask(irq);
-                       desc->status &= ~IRQ_MASKED;
+                       unmask_irq(desc, irq);
                }
  
                desc->status &= ~IRQ_PENDING;
@@@ -716,7 -729,7 +729,7 @@@ set_irq_chip_and_handler_name(unsigned 
        __set_irq_handler(irq, handle, 0, name);
  }
  
- void __init set_irq_noprobe(unsigned int irq)
+ void set_irq_noprobe(unsigned int irq)
  {
        struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
        raw_spin_unlock_irqrestore(&desc->lock, flags);
  }
  
- void __init set_irq_probe(unsigned int irq)
+ void set_irq_probe(unsigned int irq)
  {
        struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;