From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
To: linux-ia64@vger.kernel.org
Subject: [RFC][patch 7/10] Multiple vector domain support - IOSAPIC support
Date: Thu, 14 Jul 2005 09:33:05 +0000 [thread overview]
Message-ID: <42D63151.60005@jp.fujitsu.com> (raw)
This patch changes IOSAPIC code to support multiple vector domain.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
---
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;
_
reply other threads:[~2005-07-14 9:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42D63151.60005@jp.fujitsu.com \
--to=kaneshige.kenji@jp.fujitsu.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.