This patch changes IOSAPIC code to support multiple vector domain.

Signed-off-by: Kenji Kaneshige <[EMAIL PROTECTED]>

---

 linux-2.6.13-rc1-kanesige/arch/ia64/kernel/iosapic.c |  354 +++++++++++--------
 1 files changed, 220 insertions(+), 134 deletions(-)

diff -puN arch/ia64/kernel/iosapic.c~vector-domain-ia64-iosapic 
arch/ia64/kernel/iosapic.c
--- linux-2.6.13-rc1/arch/ia64/kernel/iosapic.c~vector-domain-ia64-iosapic      
2005-07-13 16:12:50.000000000 +0900
+++ linux-2.6.13-rc1-kanesige/arch/ia64/kernel/iosapic.c        2005-07-13 
16:12:50.000000000 +0900
@@ -123,7 +123,7 @@ static struct iosapic_intr_info {
        unsigned char   dmode   : 3;    /* delivery mode (see iosapic.h) */
        unsigned char   polarity: 1;    /* interrupt polarity (see iosapic.h) */
        unsigned char   trigger : 1;    /* trigger mode (see iosapic.h) */
-} iosapic_intr_info[IA64_NUM_VECTORS];
+} iosapic_intr_info[NR_GSVS];
 
 static struct iosapic {
        char __iomem    *addr;          /* base address of IOSAPIC */
@@ -157,12 +157,12 @@ find_iosapic (unsigned int gsi)
 }
 
 static inline int
-_gsi_to_vector (unsigned int gsi)
+gsi_to_gsv (unsigned int gsi)
 {
        struct iosapic_intr_info *info;
        struct iosapic_rte_info *rte;
 
-       for (info = iosapic_intr_info; info < iosapic_intr_info + 
IA64_NUM_VECTORS; ++info)
+       for (info = iosapic_intr_info; info < iosapic_intr_info + NR_GSVS; 
++info)
                list_for_each_entry(rte, &info->rtes, rte_list)
                        if (rte->gsi_base + rte->rte_index == gsi)
                                return info - iosapic_intr_info;
@@ -176,7 +176,7 @@ _gsi_to_vector (unsigned int gsi)
 inline int
 gsi_to_vector (unsigned int gsi)
 {
-       return _gsi_to_vector(gsi);
+       return gsv_to_vector(gsi_to_gsv(gsi));
 }
 
 int
@@ -184,31 +184,29 @@ gsi_to_irq (unsigned int gsi)
 {
        unsigned long flags;
        int irq;
-       /*
-        * XXX fix me: this assumes an identity mapping vetween IA-64 vector 
and Linux irq
-        * numbers...
-        */
+
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               irq = _gsi_to_vector(gsi);
+               irq = gsv_to_irq(gsi_to_gsv(gsi));
        }
        spin_unlock_irqrestore(&iosapic_lock, flags);
 
        return irq;
 }
 
-static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned 
int vec)
+static struct iosapic_rte_info *
+gsi_gsv_to_rte(unsigned int gsi, unsigned int gsv)
 {
        struct iosapic_rte_info *rte;
 
-       list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
+       list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, rte_list)
                if (rte->gsi_base + rte->rte_index == gsi)
                        return rte;
        return NULL;
 }
 
 static void
-set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
+set_rte (unsigned int gsi, unsigned int gsv, unsigned int dest, int mask)
 {
        unsigned long pol, trigger, dmode;
        u32 low32, high32;
@@ -216,30 +214,26 @@ set_rte (unsigned int gsi, unsigned int 
        int rte_index;
        char redir;
        struct iosapic_rte_info *rte;
+       unsigned int vector = gsv_to_vector(gsv);
 
        DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
 
-       rte = gsi_vector_to_rte(gsi, vector);
+       rte = gsi_gsv_to_rte(gsi, gsv);
        if (!rte)
                return;         /* not an IOSAPIC interrupt */
 
        rte_index = rte->rte_index;
        addr    = rte->addr;
-       pol     = iosapic_intr_info[vector].polarity;
-       trigger = iosapic_intr_info[vector].trigger;
-       dmode   = iosapic_intr_info[vector].dmode;
+       pol     = iosapic_intr_info[gsv].polarity;
+       trigger = iosapic_intr_info[gsv].trigger;
+       dmode   = iosapic_intr_info[gsv].dmode;
 
        redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
 
 #ifdef CONFIG_SMP
        {
-               unsigned int irq;
-
-               for (irq = 0; irq < NR_IRQS; ++irq)
-                       if (irq_to_vector(irq) == vector) {
-                               set_irq_affinity_info(irq, (int)(dest & 
0xffff), redir);
-                               break;
-                       }
+               unsigned int irq = gsv_to_irq(gsv);
+               set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
        }
 #endif
 
@@ -254,8 +248,8 @@ set_rte (unsigned int gsi, unsigned int 
 
        iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
        iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
-       iosapic_intr_info[vector].low32 = low32;
-       iosapic_intr_info[vector].dest = dest;
+       iosapic_intr_info[gsv].low32 = low32;
+       iosapic_intr_info[gsv].dest = dest;
 }
 
 static void
@@ -271,17 +265,17 @@ mask_irq (unsigned int irq)
        char __iomem *addr;
        u32 low32;
        int rte_index;
-       ia64_vector vec = irq_to_vector(irq);
+       unsigned int gsv = irq_to_gsv(irq);
        struct iosapic_rte_info *rte;
 
-       if (list_empty(&iosapic_intr_info[vec].rtes))
+       if (list_empty(&iosapic_intr_info[gsv].rtes))
                return;                 /* not an IOSAPIC interrupt! */
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
                /* set only the mask bit */
-               low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
-               list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, 
rte_list) {
+               low32 = iosapic_intr_info[gsv].low32 |= IOSAPIC_MASK;
+               list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, 
rte_list) {
                        addr = rte->addr;
                        rte_index = rte->rte_index;
                        iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -297,16 +291,16 @@ unmask_irq (unsigned int irq)
        char __iomem *addr;
        u32 low32;
        int rte_index;
-       ia64_vector vec = irq_to_vector(irq);
+       unsigned int gsv = irq_to_gsv(irq);
        struct iosapic_rte_info *rte;
 
-       if (list_empty(&iosapic_intr_info[vec].rtes))
+       if (list_empty(&iosapic_intr_info[gsv].rtes))
                return;                 /* not an IOSAPIC interrupt! */
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
-               list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, 
rte_list) {
+               low32 = iosapic_intr_info[gsv].low32 &= ~IOSAPIC_MASK;
+               list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, 
rte_list) {
                        addr = rte->addr;
                        rte_index = rte->rte_index;
                        iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -322,21 +316,27 @@ iosapic_set_affinity (unsigned int irq, 
 #ifdef CONFIG_SMP
        unsigned long flags;
        u32 high32, low32;
-       int dest, rte_index;
+       int cpu, dest, rte_index, gsv;
        char __iomem *addr;
        int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
-       ia64_vector vec;
        struct iosapic_rte_info *rte;
 
        irq &= (~IA64_IRQ_REDIRECTED);
-       vec = irq_to_vector(irq);
+       gsv = irq_to_gsv(irq);
 
        if (cpus_empty(mask))
                return;
 
-       dest = cpu_physical_id(first_cpu(mask));
+       cpu = first_cpu(mask);
+       dest = cpu_physical_id(cpu);
 
-       if (list_empty(&iosapic_intr_info[vec].rtes))
+       /*
+        * XXX - IRQ migration between different domains is not supported yet.
+        */
+       if (!cpu_isset(cpu, ia64_domain_to_cpumask(gsv_to_domain(gsv))))
+               return;
+
+       if (list_empty(&iosapic_intr_info[gsv].rtes))
                return;                 /* not an IOSAPIC interrupt */
 
        set_irq_affinity_info(irq, dest, redir);
@@ -346,7 +346,7 @@ iosapic_set_affinity (unsigned int irq, 
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               low32 = iosapic_intr_info[vec].low32 & ~(7 << 
IOSAPIC_DELIVERY_SHIFT);
+               low32 = iosapic_intr_info[gsv].low32 & ~(7 << 
IOSAPIC_DELIVERY_SHIFT);
 
                if (redir)
                        /* change delivery mode to lowest priority */
@@ -355,9 +355,9 @@ iosapic_set_affinity (unsigned int irq, 
                        /* change delivery mode to fixed */
                        low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
 
-               iosapic_intr_info[vec].low32 = low32;
-               iosapic_intr_info[vec].dest = dest;
-               list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, 
rte_list) {
+               iosapic_intr_info[gsv].low32 = low32;
+               iosapic_intr_info[gsv].dest = dest;
+               list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, 
rte_list) {
                        addr = rte->addr;
                        rte_index = rte->rte_index;
                        iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), 
high32);
@@ -382,11 +382,12 @@ iosapic_startup_level_irq (unsigned int 
 static void
 iosapic_end_level_irq (unsigned int irq)
 {
-       ia64_vector vec = irq_to_vector(irq);
+       unsigned int gsv = irq_to_gsv(irq);
+       ia64_vector vec = gsv_to_vector(gsv);
        struct iosapic_rte_info *rte;
 
        move_irq(irq);
-       list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
+       list_for_each_entry(rte, &iosapic_intr_info[gsv].rtes, rte_list)
                iosapic_eoi(rte->addr, vec);
 }
 
@@ -467,9 +468,10 @@ iosapic_version (char __iomem *addr)
        return iosapic_read(addr, IOSAPIC_VERSION);
 }
 
-static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long 
pol)
+static int
+__iosapic_find_sharable_gsv (unsigned long trigger, unsigned long pol, int 
domain)
 {
-       int i, vector = -1, min_count = -1;
+       int i, min_count = -1, gsv = -1;
        struct iosapic_intr_info *info;
 
        /*
@@ -479,20 +481,38 @@ static int iosapic_find_sharable_vector 
        if (trigger == IOSAPIC_EDGE)
                return -1;
 
-       for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) {
+       for (i = domain_vector_to_gsv(domain, IA64_FIRST_DEVICE_VECTOR);
+            i <= domain_vector_to_gsv(domain, IA64_LAST_DEVICE_VECTOR); i++) {
                info = &iosapic_intr_info[i];
                if (info->trigger == trigger && info->polarity == pol &&
                    (info->dmode == IOSAPIC_FIXED || info->dmode == 
IOSAPIC_LOWEST_PRIORITY)) {
                        if (min_count == -1 || info->count < min_count) {
-                               vector = i;
+                               gsv = i;
                                min_count = info->count;
                        }
                }
        }
-       if (vector < 0)
-               panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+       return gsv;
+}
+
+static int
+iosapic_find_sharable_gsv (unsigned long trigger, unsigned long pol, int 
domain)
+{
+       static int next_domain = 0;
+       int i, gsv;
 
-       return vector;
+       if (domain == AUTO_ASSIGN) {
+               for (i = 0; i < NR_VECTOR_DOMAINS; i++) {
+                       gsv = __iosapic_find_sharable_gsv(trigger, pol, 
next_domain++);
+                       if (next_domain >= NR_VECTOR_DOMAINS)
+                               next_domain = 0;
+                       if (gsv >= 0)
+                               break;
+               }
+               return gsv;
+       }
+       else
+               return __iosapic_find_sharable_gsv(trigger, pol, domain);
 }
 
 /*
@@ -500,20 +520,21 @@ static int iosapic_find_sharable_vector 
  *  assign a new vector for the other and make the vector available
  */
 static void __init
-iosapic_reassign_vector (int vector)
+iosapic_reassign_gsv (unsigned int gsv)
 {
-       int new_vector;
+       int new_gsv;
 
-       if (!list_empty(&iosapic_intr_info[vector].rtes)) {
-               new_vector = assign_irq_vector(AUTO_ASSIGN);
-               printk(KERN_INFO "Reassigning vector %d to %d\n", vector, 
new_vector);
-               memcpy(&iosapic_intr_info[new_vector], 
&iosapic_intr_info[vector],
+       if (!list_empty(&iosapic_intr_info[gsv].rtes)) {
+               new_gsv = assign_irq_gsv(AUTO_ASSIGN, gsv_to_domain(gsv));
+               printk(KERN_INFO "Reassigning vector %d to %d\n",
+                       gsv_to_vector(gsv), gsv_to_vector(new_gsv));
+               memcpy(&iosapic_intr_info[new_gsv], &iosapic_intr_info[gsv],
                       sizeof(struct iosapic_intr_info));
-               INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes);
-               list_move(iosapic_intr_info[vector].rtes.next, 
&iosapic_intr_info[new_vector].rtes);
-               memset(&iosapic_intr_info[vector], 0, sizeof(struct 
iosapic_intr_info));
-               iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
-               INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
+               INIT_LIST_HEAD(&iosapic_intr_info[new_gsv].rtes);
+               list_move(iosapic_intr_info[gsv].rtes.next, 
&iosapic_intr_info[new_gsv].rtes);
+               memset(&iosapic_intr_info[gsv], 0, sizeof(struct 
iosapic_intr_info));
+               iosapic_intr_info[gsv].low32 = IOSAPIC_MASK;
+               INIT_LIST_HEAD(&iosapic_intr_info[gsv].rtes);
        }
 }
 
@@ -556,13 +577,13 @@ static void iosapic_free_rte (struct ios
                kfree(rte);
 }
 
-static inline int vector_is_shared (int vector)
+static inline int gsv_is_shared (unsigned int gsv)
 {
-       return (iosapic_intr_info[vector].count > 1);
+       return (iosapic_intr_info[gsv].count > 1);
 }
 
 static void
-register_intr (unsigned int gsi, int vector, unsigned char delivery,
+register_intr (unsigned int gsi, unsigned int gsv, unsigned char delivery,
               unsigned long polarity, unsigned long trigger)
 {
        irq_desc_t *idesc;
@@ -582,7 +603,7 @@ register_intr (unsigned int gsi, int vec
        iosapic_address = iosapic_lists[index].addr;
        gsi_base = iosapic_lists[index].gsi_base;
 
-       rte = gsi_vector_to_rte(gsi, vector);
+       rte = gsi_gsv_to_rte(gsi, gsv);
        if (!rte) {
                rte = iosapic_alloc_rte();
                if (!rte) {
@@ -595,48 +616,99 @@ register_intr (unsigned int gsi, int vec
                rte->addr       = iosapic_address;
                rte->gsi_base   = gsi_base;
                rte->refcnt++;
-               list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
-               iosapic_intr_info[vector].count++;
+               list_add_tail(&rte->rte_list, &iosapic_intr_info[gsv].rtes);
+               iosapic_intr_info[gsv].count++;
                iosapic_lists[index].rtes_inuse++;
        }
-       else if (vector_is_shared(vector)) {
-               struct iosapic_intr_info *info = &iosapic_intr_info[vector];
+       else if (gsv_is_shared(gsv)) {
+               struct iosapic_intr_info *info = &iosapic_intr_info[gsv];
                if (info->trigger != trigger || info->polarity != polarity) {
                        printk (KERN_WARNING "%s: cannot override the 
interrupt\n", __FUNCTION__);
                        return;
                }
        }
 
-       iosapic_intr_info[vector].polarity = polarity;
-       iosapic_intr_info[vector].dmode    = delivery;
-       iosapic_intr_info[vector].trigger  = trigger;
+       iosapic_intr_info[gsv].polarity = polarity;
+       iosapic_intr_info[gsv].dmode    = delivery;
+       iosapic_intr_info[gsv].trigger  = trigger;
 
        if (trigger == IOSAPIC_EDGE)
                irq_type = &irq_type_iosapic_edge;
        else
                irq_type = &irq_type_iosapic_level;
 
-       idesc = irq_descp(vector);
+       idesc = irq_descp(gsv_to_irq(gsv));
        if (idesc->handler != irq_type) {
                if (idesc->handler != &no_irq_type)
                        printk(KERN_WARNING "%s: changing vector %d from %s to 
%s\n",
-                              __FUNCTION__, vector, idesc->handler->typename, 
irq_type->typename);
+                              __FUNCTION__, gsv_to_vector(gsv),
+                              idesc->handler->typename, irq_type->typename);
                idesc->handler = irq_type;
        }
 }
 
+int
+get_target_domain (unsigned int gsi)
+{
+#ifdef CONFIG_VECTOR_DOMAIN
+       /*
+        * Some interrupts (ACPI SCI, for instance) are registered
+        * before the BSP is marked as online.
+        */
+       if (!cpu_online(smp_processor_id()))
+               return ia64_cpu_to_domain(smp_processor_id());
+
+#ifdef CONFIG_NUMA
+       {
+               int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
+               cpumask_t cpu_mask;
+
+               iosapic_index = find_iosapic(gsi);
+               if (iosapic_index < 0 ||
+                   iosapic_lists[iosapic_index].node == MAX_NUMNODES)
+                       goto skip_numa_setup;
+
+               cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node);
+
+               for_each_cpu_mask(numa_cpu, cpu_mask) {
+                       if (!cpu_online(numa_cpu))
+                               cpu_clear(numa_cpu, cpu_mask);
+               }
+
+               num_cpus = cpus_weight(cpu_mask);
+
+               if (!num_cpus)
+                       goto skip_numa_setup;
+
+               /* Use vector assigment to distribute across cpus in node */
+               cpu_index = gsi % num_cpus;
+
+               for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
+                       numa_cpu = next_cpu(numa_cpu, cpu_mask);
+
+               if (numa_cpu != NR_CPUS)
+                       return ia64_cpu_to_domain(numa_cpu);
+       }
+skip_numa_setup:
+#endif
+
+#endif /* CONFIG_VECTOR_DOMAIN */
+       return AUTO_ASSIGN;
+}
+
 static unsigned int
-get_target_cpu (unsigned int gsi, int vector)
+get_target_cpu (unsigned int gsi, unsigned int gsv)
 {
 #ifdef CONFIG_SMP
        static int cpu = -1;
+       int domain;
 
        /*
         * In case of vector shared by multiple RTEs, all RTEs that
         * share the vector need to use the same destination CPU.
         */
-       if (!list_empty(&iosapic_intr_info[vector].rtes))
-               return iosapic_intr_info[vector].dest;
+       if (!list_empty(&iosapic_intr_info[gsv].rtes))
+               return iosapic_intr_info[gsv].dest;
 
        /*
         * If the platform supports redirection via XTP, let it
@@ -652,6 +724,8 @@ get_target_cpu (unsigned int gsi, int ve
        if (!cpu_online(smp_processor_id()))
                return cpu_physical_id(smp_processor_id());
 
+       domain = gsv_to_domain(gsv);
+
 #ifdef CONFIG_NUMA
        {
                int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
@@ -662,7 +736,9 @@ get_target_cpu (unsigned int gsi, int ve
                    iosapic_lists[iosapic_index].node == MAX_NUMNODES)
                        goto skip_numa_setup;
 
-               cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node);
+               cpus_and(cpu_mask,
+                        node_to_cpumask(iosapic_lists[iosapic_index].node),
+                        ia64_domain_to_cpumask(domain));
 
                for_each_cpu_mask(numa_cpu, cpu_mask) {
                        if (!cpu_online(numa_cpu))
@@ -675,7 +751,7 @@ get_target_cpu (unsigned int gsi, int ve
                        goto skip_numa_setup;
 
                /* Use vector assigment to distribute across cpus in node */
-               cpu_index = vector % num_cpus;
+               cpu_index = gsv % num_cpus;
 
                for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
                        numa_cpu = next_cpu(numa_cpu, cpu_mask);
@@ -693,7 +769,7 @@ skip_numa_setup:
        do {
                if (++cpu >= NR_CPUS)
                        cpu = 0;
-       } while (!cpu_online(cpu));
+       } while (!cpu_isset(cpu, ia64_domain_to_cpumask(domain)));
 
        return cpu_physical_id(cpu);
 #else
@@ -710,11 +786,12 @@ int
 iosapic_register_intr (unsigned int gsi,
                       unsigned long polarity, unsigned long trigger)
 {
-       int vector, mask = 1;
+       int mask = 1, domain, gsv;
        unsigned int dest;
        unsigned long flags;
        struct iosapic_rte_info *rte;
        u32 low32;
+       irq_desc_t *idesc;
 again:
        /*
         * If this GSI has already been registered (i.e., it's a
@@ -723,54 +800,59 @@ again:
         */
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               vector = gsi_to_vector(gsi);
-               if (vector > 0) {
-                       rte = gsi_vector_to_rte(gsi, vector);
+               gsv = gsi_to_gsv(gsi);
+               if (gsv > 0) {
+                       rte = gsi_gsv_to_rte(gsi, gsv);
                        rte->refcnt++;
                        spin_unlock_irqrestore(&iosapic_lock, flags);
-                       return vector;
+                       return gsv_to_irq(gsv);
                }
        }
        spin_unlock_irqrestore(&iosapic_lock, flags);
 
+       domain = get_target_domain(gsi);
        /* If vector is running out, we try to find a sharable vector */
-       vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
-       if (vector < 0)
-               vector = iosapic_find_sharable_vector(trigger, polarity);
+       gsv = assign_irq_gsv(AUTO_ASSIGN, domain);
+       if (gsv < 0) {
+               gsv = iosapic_find_sharable_gsv(trigger, polarity, domain);
+               if (gsv < 0)
+                       panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+       }
 
-       spin_lock_irqsave(&irq_descp(vector)->lock, flags);
+       idesc = irq_descp(gsv_to_irq(gsv));
+       spin_lock_irqsave(&idesc->lock, flags);
        spin_lock(&iosapic_lock);
        {
-               if (gsi_to_vector(gsi) > 0) {
-                       if (list_empty(&iosapic_intr_info[vector].rtes))
-                               free_irq_vector(vector);
+               if (gsi_to_gsv(gsi) > 0) {
+                       if (list_empty(&iosapic_intr_info[gsv].rtes))
+                               free_irq_gsv(gsv);
                        spin_unlock(&iosapic_lock);
-                       spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
+                       spin_unlock_irqrestore(&idesc->lock, flags);
                        goto again;
                }
 
-               dest = get_target_cpu(gsi, vector);
-               register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+               dest = get_target_cpu(gsi, gsv);
+               register_intr(gsi, gsv, IOSAPIC_LOWEST_PRIORITY,
                              polarity, trigger);
 
                /*
                 * If the vector is shared and already unmasked for
                 * other interrupt sources, don't mask it.
                 */
-               low32 = iosapic_intr_info[vector].low32;
-               if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK))
+               low32 = iosapic_intr_info[gsv].low32;
+               if (gsv_is_shared(gsv) && !(low32 & IOSAPIC_MASK))
                        mask = 0;
-               set_rte(gsi, vector, dest, mask);
+               set_rte(gsi, gsv, dest, mask);
        }
        spin_unlock(&iosapic_lock);
-       spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
+       spin_unlock_irqrestore(&idesc->lock, flags);
 
        printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
               gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
               (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              cpu_logical_id(dest), dest, vector);
+              cpu_logical_id(dest), dest, gsv_to_vector(gsv));
 
-       return vector;
+       return gsv_to_irq(gsv);
 }
 
 #ifdef CONFIG_ACPI_DEALLOCATE_IRQ
@@ -778,11 +860,11 @@ void
 iosapic_unregister_intr (unsigned int gsi)
 {
        unsigned long flags;
-       int irq, vector, index;
+       int irq, index;
        irq_desc_t *idesc;
        u32 low32;
        unsigned long trigger, polarity;
-       unsigned int dest;
+       unsigned int gsv, dest;
        struct iosapic_rte_info *rte;
 
        /*
@@ -796,13 +878,13 @@ iosapic_unregister_intr (unsigned int gs
                WARN_ON(1);
                return;
        }
-       vector = irq_to_vector(irq);
+       gsv = irq_to_gsv(irq);
 
        idesc = irq_descp(irq);
        spin_lock_irqsave(&idesc->lock, flags);
        spin_lock(&iosapic_lock);
        {
-               if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) {
+               if ((rte = gsi_gsv_to_rte(gsi, gsv)) == NULL) {
                        printk(KERN_ERR "iosapic_unregister_intr(%u) 
unbalanced\n", gsi);
                        WARN_ON(1);
                        goto out;
@@ -812,36 +894,36 @@ iosapic_unregister_intr (unsigned int gs
                        goto out;
 
                /* Mask the interrupt */
-               low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK;
+               low32 = iosapic_intr_info[gsv].low32 | IOSAPIC_MASK;
                iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), 
low32);
 
                /* Remove the rte entry from the list */
                list_del(&rte->rte_list);
-               iosapic_intr_info[vector].count--;
+               iosapic_intr_info[gsv].count--;
                iosapic_free_rte(rte);
                index = find_iosapic(gsi);
                iosapic_lists[index].rtes_inuse--;
                WARN_ON(iosapic_lists[index].rtes_inuse < 0);
 
-               trigger  = iosapic_intr_info[vector].trigger;
-               polarity = iosapic_intr_info[vector].polarity;
-               dest     = iosapic_intr_info[vector].dest;
+               trigger  = iosapic_intr_info[gsv].trigger;
+               polarity = iosapic_intr_info[gsv].polarity;
+               dest     = iosapic_intr_info[gsv].dest;
                printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d 
unregistered\n",
                       gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
                       (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-                      cpu_logical_id(dest), dest, vector);
+                      cpu_logical_id(dest), dest, gsv_to_vector(gsv));
 
-               if (list_empty(&iosapic_intr_info[vector].rtes)) {
+               if (list_empty(&iosapic_intr_info[gsv].rtes)) {
                        /* Sanity check */
-                       BUG_ON(iosapic_intr_info[vector].count);
+                       BUG_ON(iosapic_intr_info[gsv].count);
 
                        /* Clear the interrupt controller descriptor */
                        idesc->handler = &no_irq_type;
 
                        /* Clear the interrupt information */
-                       memset(&iosapic_intr_info[vector], 0, sizeof(struct 
iosapic_intr_info));
-                       iosapic_intr_info[vector].low32 |= IOSAPIC_MASK;
-                       INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
+                       memset(&iosapic_intr_info[gsv], 0, sizeof(struct 
iosapic_intr_info));
+                       iosapic_intr_info[gsv].low32 |= IOSAPIC_MASK;
+                       INIT_LIST_HEAD(&iosapic_intr_info[gsv].rtes);
 
                        if (idesc->action) {
                                printk(KERN_ERR "interrupt handlers still exist 
on IRQ %u\n", irq);
@@ -849,7 +931,7 @@ iosapic_unregister_intr (unsigned int gs
                        }
 
                        /* Free the interrupt vector */
-                       free_irq_vector(vector);
+                       free_irq_gsv(gsv);
                }
        }
  out:
@@ -869,25 +951,26 @@ iosapic_register_platform_intr (u32 int_
 {
        static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
        unsigned char delivery;
-       int vector, mask = 0;
-       unsigned int dest = ((id << 8) | eid) & 0xffff;
+       int mask = 0;
+       unsigned int gsv, dest = ((id << 8) | eid) & 0xffff;
+       int domain = ia64_cpu_to_domain(cpu_logical_id(dest));
 
        switch (int_type) {
              case ACPI_INTERRUPT_PMI:
-               vector = iosapic_vector;
+               gsv = domain_vector_to_gsv(domain, iosapic_vector);
                /*
                 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
                 * we need to make sure the vector is available
                 */
-               iosapic_reassign_vector(vector);
+               iosapic_reassign_gsv(gsv);
                delivery = IOSAPIC_PMI;
                break;
              case ACPI_INTERRUPT_INIT:
-               vector = assign_irq_vector(AUTO_ASSIGN);
+               gsv = assign_irq_gsv(AUTO_ASSIGN, domain);
                delivery = IOSAPIC_INIT;
                break;
              case ACPI_INTERRUPT_CPEI:
-               vector = IA64_CPE_VECTOR;
+               gsv = domain_vector_to_gsv(domain, IA64_CPE_VECTOR);
                delivery = IOSAPIC_LOWEST_PRIORITY;
                mask = 1;
                break;
@@ -896,16 +979,16 @@ iosapic_register_platform_intr (u32 int_
                return -1;
        }
 
-       register_intr(gsi, vector, delivery, polarity, trigger);
+       register_intr(gsi, gsv, delivery, polarity, trigger);
 
        printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d 
(0x%04x) vector %d\n",
               int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
               int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
               (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              cpu_logical_id(dest), dest, vector);
+              cpu_logical_id(dest), dest, gsv_to_vector(gsv));
 
-       set_rte(gsi, vector, dest, mask);
-       return vector;
+       set_rte(gsi, gsv, dest, mask);
+       return gsv_to_vector(gsv);
 }
 
 
@@ -919,28 +1002,31 @@ iosapic_override_isa_irq (unsigned int i
                          unsigned long trigger)
 {
        int vector;
+       unsigned int gsv;
        unsigned int dest = cpu_physical_id(smp_processor_id());
+       unsigned int domain = ia64_cpu_to_domain(smp_processor_id());
 
        vector = isa_irq_to_vector(isa_irq);
+       gsv = domain_vector_to_gsv(domain, vector);
 
-       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
+       register_intr(gsi, gsv, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
 
        DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
            isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
            polarity == IOSAPIC_POL_HIGH ? "high" : "low",
            cpu_logical_id(dest), dest, vector);
 
-       set_rte(gsi, vector, dest, 1);
+       set_rte(gsi, gsv, dest, 1);
 }
 
 void __init
 iosapic_system_init (int system_pcat_compat)
 {
-       int vector;
+       unsigned int gsv;
 
-       for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
-               iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
-               INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);        /* mark 
as unused */
+       for (gsv = 0; gsv < NR_GSVS; ++gsv) {
+               iosapic_intr_info[gsv].low32 = IOSAPIC_MASK;
+               INIT_LIST_HEAD(&iosapic_intr_info[gsv].rtes);   /* mark as 
unused */
        }
 
        pcat_compat = system_pcat_compat;

_


-
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to