Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
[pandora-kernel.git] / arch / ia64 / kernel / iosapic.c
index 22c3840..b0f9afe 100644 (file)
@@ -257,7 +257,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
 }
 
 static void
-nop (unsigned int irq)
+nop (struct irq_data *data)
 {
        /* do nothing... */
 }
@@ -287,8 +287,9 @@ kexec_disable_iosapic(void)
 #endif
 
 static void
-mask_irq (unsigned int irq)
+mask_irq (struct irq_data *data)
 {
+       unsigned int irq = data->irq;
        u32 low32;
        int rte_index;
        struct iosapic_rte_info *rte;
@@ -305,8 +306,9 @@ mask_irq (unsigned int irq)
 }
 
 static void
-unmask_irq (unsigned int irq)
+unmask_irq (struct irq_data *data)
 {
+       unsigned int irq = data->irq;
        u32 low32;
        int rte_index;
        struct iosapic_rte_info *rte;
@@ -323,9 +325,11 @@ unmask_irq (unsigned int irq)
 
 
 static int
-iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
+iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+                    bool force)
 {
 #ifdef CONFIG_SMP
+       unsigned int irq = data->irq;
        u32 high32, low32;
        int cpu, dest, rte_index;
        int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
@@ -379,32 +383,33 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
  */
 
 static unsigned int
-iosapic_startup_level_irq (unsigned int irq)
+iosapic_startup_level_irq (struct irq_data *data)
 {
-       unmask_irq(irq);
+       unmask_irq(data);
        return 0;
 }
 
 static void
-iosapic_unmask_level_irq (unsigned int irq)
+iosapic_unmask_level_irq (struct irq_data *data)
 {
+       unsigned int irq = data->irq;
        ia64_vector vec = irq_to_vector(irq);
        struct iosapic_rte_info *rte;
        int do_unmask_irq = 0;
 
        irq_complete_move(irq);
-       if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+       if (unlikely(irqd_is_setaffinity_pending(data))) {
                do_unmask_irq = 1;
-               mask_irq(irq);
+               mask_irq(data);
        } else
-               unmask_irq(irq);
+               unmask_irq(data);
 
        list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
                iosapic_eoi(rte->iosapic->addr, vec);
 
        if (unlikely(do_unmask_irq)) {
-               move_masked_irq(irq);
-               unmask_irq(irq);
+               irq_move_masked_irq(data);
+               unmask_irq(data);
        }
 }
 
@@ -414,15 +419,15 @@ iosapic_unmask_level_irq (unsigned int irq)
 #define iosapic_ack_level_irq          nop
 
 static struct irq_chip irq_type_iosapic_level = {
-       .name =         "IO-SAPIC-level",
-       .startup =      iosapic_startup_level_irq,
-       .shutdown =     iosapic_shutdown_level_irq,
-       .enable =       iosapic_enable_level_irq,
-       .disable =      iosapic_disable_level_irq,
-       .ack =          iosapic_ack_level_irq,
-       .mask =         mask_irq,
-       .unmask =       iosapic_unmask_level_irq,
-       .set_affinity = iosapic_set_affinity
+       .name =                 "IO-SAPIC-level",
+       .irq_startup =          iosapic_startup_level_irq,
+       .irq_shutdown =         iosapic_shutdown_level_irq,
+       .irq_enable =           iosapic_enable_level_irq,
+       .irq_disable =          iosapic_disable_level_irq,
+       .irq_ack =              iosapic_ack_level_irq,
+       .irq_mask =             mask_irq,
+       .irq_unmask =           iosapic_unmask_level_irq,
+       .irq_set_affinity =     iosapic_set_affinity
 };
 
 /*
@@ -430,9 +435,9 @@ static struct irq_chip irq_type_iosapic_level = {
  */
 
 static unsigned int
-iosapic_startup_edge_irq (unsigned int irq)
+iosapic_startup_edge_irq (struct irq_data *data)
 {
-       unmask_irq(irq);
+       unmask_irq(data);
        /*
         * IOSAPIC simply drops interrupts pended while the
         * corresponding pin was masked, so we can't know if an
@@ -442,37 +447,25 @@ iosapic_startup_edge_irq (unsigned int irq)
 }
 
 static void
-iosapic_ack_edge_irq (unsigned int irq)
+iosapic_ack_edge_irq (struct irq_data *data)
 {
-       struct irq_desc *idesc = irq_desc + irq;
-
-       irq_complete_move(irq);
-       move_native_irq(irq);
-       /*
-        * Once we have recorded IRQ_PENDING already, we can mask the
-        * interrupt for real. This prevents IRQ storms from unhandled
-        * devices.
-        */
-       if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
-           (IRQ_PENDING|IRQ_DISABLED))
-               mask_irq(irq);
+       irq_complete_move(data->irq);
+       irq_move_irq(data);
 }
 
 #define iosapic_enable_edge_irq                unmask_irq
 #define iosapic_disable_edge_irq       nop
-#define iosapic_end_edge_irq           nop
 
 static struct irq_chip irq_type_iosapic_edge = {
-       .name =         "IO-SAPIC-edge",
-       .startup =      iosapic_startup_edge_irq,
-       .shutdown =     iosapic_disable_edge_irq,
-       .enable =       iosapic_enable_edge_irq,
-       .disable =      iosapic_disable_edge_irq,
-       .ack =          iosapic_ack_edge_irq,
-       .end =          iosapic_end_edge_irq,
-       .mask =         mask_irq,
-       .unmask =       unmask_irq,
-       .set_affinity = iosapic_set_affinity
+       .name =                 "IO-SAPIC-edge",
+       .irq_startup =          iosapic_startup_edge_irq,
+       .irq_shutdown =         iosapic_disable_edge_irq,
+       .irq_enable =           iosapic_enable_edge_irq,
+       .irq_disable =          iosapic_disable_edge_irq,
+       .irq_ack =              iosapic_ack_edge_irq,
+       .irq_mask =             mask_irq,
+       .irq_unmask =           unmask_irq,
+       .irq_set_affinity =     iosapic_set_affinity
 };
 
 static unsigned int
@@ -562,8 +555,7 @@ static int
 register_intr (unsigned int gsi, int irq, unsigned char delivery,
               unsigned long polarity, unsigned long trigger)
 {
-       struct irq_desc *idesc;
-       struct irq_chip *irq_type;
+       struct irq_chip *chip, *irq_type;
        int index;
        struct iosapic_rte_info *rte;
 
@@ -610,19 +602,18 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
 
        irq_type = iosapic_get_irq_chip(trigger);
 
-       idesc = irq_desc + irq;
-       if (irq_type != NULL && idesc->chip != irq_type) {
-               if (idesc->chip != &no_irq_chip)
+       chip = irq_get_chip(irq);
+       if (irq_type != NULL && chip != irq_type) {
+               if (chip != &no_irq_chip)
                        printk(KERN_WARNING
                               "%s: changing vector %d from %s to %s\n",
                               __func__, irq_to_vector(irq),
-                              idesc->chip->name, irq_type->name);
-               idesc->chip = irq_type;
+                              chip->name, irq_type->name);
+               chip = irq_type;
        }
-       if (trigger == IOSAPIC_EDGE)
-               __set_irq_handler_unlocked(irq, handle_edge_irq);
-       else
-               __set_irq_handler_unlocked(irq, handle_level_irq);
+       __irq_set_chip_handler_name_locked(irq, chip, trigger == IOSAPIC_EDGE ?
+                                          handle_edge_irq : handle_level_irq,
+                                          NULL);
        return 0;
 }
 
@@ -732,6 +723,7 @@ iosapic_register_intr (unsigned int gsi,
        struct iosapic_rte_info *rte;
        u32 low32;
        unsigned char dmode;
+       struct irq_desc *desc;
 
        /*
         * If this GSI has already been registered (i.e., it's a
@@ -759,12 +751,13 @@ iosapic_register_intr (unsigned int gsi,
                        goto unlock_iosapic_lock;
        }
 
-       raw_spin_lock(&irq_desc[irq].lock);
+       desc = irq_to_desc(irq);
+       raw_spin_lock(&desc->lock);
        dest = get_target_cpu(gsi, irq);
        dmode = choose_dmode();
        err = register_intr(gsi, irq, dmode, polarity, trigger);
        if (err < 0) {
-               raw_spin_unlock(&irq_desc[irq].lock);
+               raw_spin_unlock(&desc->lock);
                irq = err;
                goto unlock_iosapic_lock;
        }
@@ -783,7 +776,7 @@ iosapic_register_intr (unsigned int gsi,
               (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
               cpu_logical_id(dest), dest, irq_to_vector(irq));
 
-       raw_spin_unlock(&irq_desc[irq].lock);
+       raw_spin_unlock(&desc->lock);
  unlock_iosapic_lock:
        spin_unlock_irqrestore(&iosapic_lock, flags);
        return irq;
@@ -794,7 +787,6 @@ iosapic_unregister_intr (unsigned int gsi)
 {
        unsigned long flags;
        int irq, index;
-       struct irq_desc *idesc;
        u32 low32;
        unsigned long trigger, polarity;
        unsigned int dest;
@@ -824,7 +816,6 @@ iosapic_unregister_intr (unsigned int gsi)
        if (--rte->refcnt > 0)
                goto out;
 
-       idesc = irq_desc + irq;
        rte->refcnt = NO_REF_RTE;
 
        /* Mask the interrupt */
@@ -848,7 +839,7 @@ iosapic_unregister_intr (unsigned int gsi)
        if (iosapic_intr_info[irq].count == 0) {
 #ifdef CONFIG_SMP
                /* Clear affinity */
-               cpumask_setall(idesc->affinity);
+               cpumask_setall(irq_get_irq_data(irq)->affinity);
 #endif
                /* Clear the interrupt information */
                iosapic_intr_info[irq].dest = 0;