All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] x86/irq
@ 2010-03-22  1:36 Yinghai Lu
  2010-03-22  1:36   ` Yinghai Lu
                   ` (9 more replies)
  0 siblings, 10 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

only irq related...

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
  2010-03-22  1:36   ` Yinghai Lu
@ 2010-03-22  1:36   ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 03/10] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi Yinghai Lu
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Ian Campbell,
	Paul Mundt, linux-sh, x86, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Yinghai Lu

From: Ian Campbell <ian.campbell@citrix.com>

Move arch_init_copy_chip_data and arch_free_chip_data into function
pointers in struct irq_chip since they operate on irq_desc->chip_data.

arch_init_chip_data cannot be moved into struct irq_chip because
irq_desc->chip is not known at the time the irq_desc is setup. Instead
rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
only other user, whose usage better matches the new name.

To replace the x86 arch_init_chip_data functionality
irq_to_desc_alloc_node now takes a pointer to a function to allocate
the chip data. This is necessary to ensure the allocation happens
under the correct locking at the core level. On PowerPC and SH
architectures (the other users of irq_to_desc_alloc_node) pass in NULL
which retains existing chip_data behaviour.

I've retained the chip_data behaviour for uv_irq although it isn't
clear to me if these interrupt types support migration or how closely
related to the APIC modes they really are. If it weren't for this the
x86_{init,copy,free}_chip_data functions could be static to
io_apic.c.

I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
and 32 bit without, but it's not clear to me what actions I need to
take to actually exercise some of these code paths.

-v4: yinghai add irq_to_desc_alloc_node_x...
     so could leave default path not changed...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Michael Ellerman <michael@ellerman.id.au> [PowerPC rename portion]
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: x86@kernel.org
Cc: linuxppc-dev@ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: lguest@ozlabs.org
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: linux-sh@vger.kernel.org
---
 arch/powerpc/kernel/irq.c      |    2 +-
 arch/x86/include/asm/hw_irq.h  |    7 +++++-
 arch/x86/kernel/apic/io_apic.c |   49 ++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/uv_irq.c       |    3 ++
 drivers/xen/events.c           |    7 +++++-
 include/linux/interrupt.h      |    1 -
 include/linux/irq.h            |   21 +++++++++++++----
 kernel/irq/chip.c              |    7 +++++
 kernel/irq/handle.c            |   13 ++++++----
 kernel/irq/numa_migrate.c      |   12 ++++++++-
 kernel/softirq.c               |    5 ----
 11 files changed, 102 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 46c0fe0..767d3f8 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -20,9 +20,9 @@
 #include <linux/percpu.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
+#include <linux/irq.h>
 
 #include <asm/atomic.h>
-#include <asm/irq.h>
 #include <asm/sections.h>
 
 /* Interrupt handlers registered during init_IRQ */
@@ -61,6 +61,11 @@ extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
 extern void disable_IO_APIC(void);
 
+extern void x86_copy_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc, int node);
+extern void x86_free_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc);
+
 struct io_apic_irq_attr {
 	int ioapic;
 	int ioapic_pin;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 463de9a..a917fdf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -211,7 +211,7 @@ static struct irq_cfg *get_one_free_irq_cfg(int node)
 	return cfg;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+static int x86_init_chip_data(struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 
@@ -287,8 +287,8 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
 	old_cfg->irq_2_pin = NULL;
 }
 
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int node)
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 	struct irq_cfg *old_cfg;
@@ -312,7 +312,7 @@ static void free_irq_cfg(struct irq_cfg *old_cfg)
 	kfree(old_cfg);
 }
 
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	struct irq_cfg *old_cfg, *cfg;
 
@@ -329,6 +329,14 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 	}
 }
 /* end for move_irq_desc */
+int arch_init_irq_desc(struct irq_desc *desc, int node,
+			 init_chip_data_fn init_chip_data)
+{
+	if (!init_chip_data)
+		return x86_init_chip_data(desc, node);
+
+	return init_chip_data(desc, node);
+}
 
 #else
 struct irq_cfg *irq_cfg(unsigned int irq)
@@ -336,6 +344,15 @@ struct irq_cfg *irq_cfg(unsigned int irq)
 	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
 
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
+{
+}
+
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+{
+}
+
 #endif
 
 struct io_apic {
@@ -2747,6 +2764,9 @@ static struct irq_chip ioapic_chip __read_mostly = {
 	.set_affinity	= set_ioapic_affinity_irq,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
@@ -2762,6 +2782,9 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -3474,6 +3497,9 @@ static struct irq_chip msi_chip = {
 	.set_affinity	= set_msi_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip msi_ir_chip = {
@@ -3487,6 +3513,9 @@ static struct irq_chip msi_ir_chip = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
@@ -3646,6 +3675,9 @@ static struct irq_chip dmar_msi_type = {
 	.set_affinity = dmar_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_dmar_msi(unsigned int irq)
@@ -3703,6 +3735,9 @@ static struct irq_chip ir_hpet_msi_type = {
 #endif
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip hpet_msi_type = {
@@ -3714,6 +3749,9 @@ static struct irq_chip hpet_msi_type = {
 	.set_affinity = hpet_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
@@ -3800,6 +3838,9 @@ static struct irq_chip ht_irq_chip = {
 	.set_affinity	= set_ht_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index ece73d8..4c61f1b 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -55,6 +55,9 @@ struct irq_chip uv_irq_chip = {
 	.eoi		= uv_ack_apic,
 	.end		= uv_noop,
 	.set_affinity	= uv_set_irq_affinity,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2f84137..64cbbe4 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -329,6 +329,11 @@ static void unmask_evtchn(int port)
 	put_cpu();
 }
 
+static int xen_init_chip_data(struct irq_desc *desc, int node)
+{
+	return 0;
+}
+
 static int find_unbound_irq(void)
 {
 	int irq;
@@ -341,7 +346,7 @@ static int find_unbound_irq(void)
 	if (irq = nr_irqs)
 		panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-	desc = irq_to_desc_alloc_node(irq, 0);
+	desc = irq_to_desc_alloc_node_x(irq, 0, xen_init_chip_data);
 	if (WARN_ON(desc = NULL))
 		return -1;
 
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 75f3f00..0b0d679 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -611,6 +611,5 @@ struct irq_desc;
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
 extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int node);
 
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 707ab12..60f3368 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -140,6 +140,13 @@ struct irq_chip {
 	 * Will disappear.
 	 */
 	const char	*typename;
+
+	/* for move_irq_desc */
+	void		(*copy_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc, int node);
+	void		(*free_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc);
+
 };
 
 struct timer_rand_state;
@@ -208,10 +215,6 @@ struct irq_desc {
 	const char		*name;
 } ____cacheline_internodealigned_in_smp;
 
-extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-					struct irq_desc *desc, int node);
-extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
-
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
@@ -225,7 +228,15 @@ static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 }
 #endif
 
-extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
+typedef int (*init_chip_data_fn)(struct irq_desc *, int node);
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn);
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn fn);
+static inline struct irq_desc *irq_to_desc_alloc_node(unsigned int irq,
+							 int node)
+{
+	return irq_to_desc_alloc_node_x(irq, node, NULL);
+}
 
 /*
  * Pick up the arch-dependent methods:
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index bbba585..3dcdd2f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -758,3 +758,10 @@ void __init set_irq_probe(unsigned int irq)
 	desc->status &= ~IRQ_NOPROBE;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
+
+int __weak arch_init_irq_desc(struct irq_desc *desc, int node,
+				 init_chip_data_fn init_chip_data)
+{
+	return 0;
+}
+
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 76d5a67..f30c9c7 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -100,7 +100,8 @@ void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 	}
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node,
+			      init_chip_data_fn init_chip_data)
 {
 	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
 
@@ -120,7 +121,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
 		BUG_ON(1);
 	}
 	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
+	arch_init_irq_desc(desc, node, init_chip_data);
 }
 
 /*
@@ -198,7 +199,8 @@ int __init early_irq_init(void)
 	return arch_early_irq_init();
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc * __ref irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn init_chip_data)
 {
 	struct irq_desc *desc;
 	unsigned long flags;
@@ -227,7 +229,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
 		printk(KERN_ERR "can not alloc irq_desc\n");
 		BUG_ON(1);
 	}
-	init_one_irq_desc(irq, desc, node);
+	init_one_irq_desc(irq, desc, node, init_chip_data);
 
 	set_irq_desc(irq, desc);
 
@@ -277,7 +279,8 @@ struct irq_desc *irq_to_desc(unsigned int irq)
 	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					init_chip_data_fn init_chip_data)
 {
 	return irq_to_desc(irq);
 }
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 963559d..9ea09c9 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -47,7 +47,8 @@ static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
 	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
 	init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
 	init_copy_desc_masks(old_desc, desc);
-	arch_init_copy_chip_data(old_desc, desc, node);
+	if (desc->chip->copy_chip_data)
+		desc->chip->copy_chip_data(old_desc, desc, node);
 	return true;
 }
 
@@ -55,7 +56,8 @@ static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	free_kstat_irqs(old_desc, desc);
 	free_desc_masks(old_desc, desc);
-	arch_free_chip_data(old_desc, desc);
+	if (desc->chip->free_chip_data)
+		desc->chip->free_chip_data(old_desc, desc);
 }
 
 static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
@@ -107,9 +109,15 @@ out_unlock:
 
 struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 {
+
 	/* those static or target node is -1, do not move them */
 	if (desc->irq < NR_IRQS_LEGACY || node = -1)
 		return desc;
+	/* IRQ chip does not support movement */
+	if (desc->chip_data &&
+	    (desc->chip->copy_chip_data = NULL ||
+	     desc->chip->free_chip_data = NULL))
+		return desc;
 
 	if (desc->node != node)
 		desc = __real_move_irq_desc(desc, node);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 7c1a67e..7df0209 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -895,8 +895,3 @@ int __init __weak arch_early_irq_init(void)
 {
 	return 0;
 }
-
-int __weak arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	return 0;
-}
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  1:36   ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Ian Campbell, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, Eric W. Biederman, Yinghai Lu,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

From: Ian Campbell <ian.campbell@citrix.com>

Move arch_init_copy_chip_data and arch_free_chip_data into function
pointers in struct irq_chip since they operate on irq_desc->chip_data.

arch_init_chip_data cannot be moved into struct irq_chip because
irq_desc->chip is not known at the time the irq_desc is setup. Instead
rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
only other user, whose usage better matches the new name.

To replace the x86 arch_init_chip_data functionality
irq_to_desc_alloc_node now takes a pointer to a function to allocate
the chip data. This is necessary to ensure the allocation happens
under the correct locking at the core level. On PowerPC and SH
architectures (the other users of irq_to_desc_alloc_node) pass in NULL
which retains existing chip_data behaviour.

I've retained the chip_data behaviour for uv_irq although it isn't
clear to me if these interrupt types support migration or how closely
related to the APIC modes they really are. If it weren't for this the
x86_{init,copy,free}_chip_data functions could be static to
io_apic.c.

I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
and 32 bit without, but it's not clear to me what actions I need to
take to actually exercise some of these code paths.

-v4: yinghai add irq_to_desc_alloc_node_x...
     so could leave default path not changed...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Michael Ellerman <michael@ellerman.id.au> [PowerPC rename portion]
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: x86@kernel.org
Cc: linuxppc-dev@ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: lguest@ozlabs.org
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: linux-sh@vger.kernel.org
---
 arch/powerpc/kernel/irq.c      |    2 +-
 arch/x86/include/asm/hw_irq.h  |    7 +++++-
 arch/x86/kernel/apic/io_apic.c |   49 ++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/uv_irq.c       |    3 ++
 drivers/xen/events.c           |    7 +++++-
 include/linux/interrupt.h      |    1 -
 include/linux/irq.h            |   21 +++++++++++++----
 kernel/irq/chip.c              |    7 +++++
 kernel/irq/handle.c            |   13 ++++++----
 kernel/irq/numa_migrate.c      |   12 ++++++++-
 kernel/softirq.c               |    5 ----
 11 files changed, 102 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 46c0fe0..767d3f8 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -20,9 +20,9 @@
 #include <linux/percpu.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
+#include <linux/irq.h>
 
 #include <asm/atomic.h>
-#include <asm/irq.h>
 #include <asm/sections.h>
 
 /* Interrupt handlers registered during init_IRQ */
@@ -61,6 +61,11 @@ extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
 extern void disable_IO_APIC(void);
 
+extern void x86_copy_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc, int node);
+extern void x86_free_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc);
+
 struct io_apic_irq_attr {
 	int ioapic;
 	int ioapic_pin;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 463de9a..a917fdf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -211,7 +211,7 @@ static struct irq_cfg *get_one_free_irq_cfg(int node)
 	return cfg;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+static int x86_init_chip_data(struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 
@@ -287,8 +287,8 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
 	old_cfg->irq_2_pin = NULL;
 }
 
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int node)
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 	struct irq_cfg *old_cfg;
@@ -312,7 +312,7 @@ static void free_irq_cfg(struct irq_cfg *old_cfg)
 	kfree(old_cfg);
 }
 
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	struct irq_cfg *old_cfg, *cfg;
 
@@ -329,6 +329,14 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 	}
 }
 /* end for move_irq_desc */
+int arch_init_irq_desc(struct irq_desc *desc, int node,
+			 init_chip_data_fn init_chip_data)
+{
+	if (!init_chip_data)
+		return x86_init_chip_data(desc, node);
+
+	return init_chip_data(desc, node);
+}
 
 #else
 struct irq_cfg *irq_cfg(unsigned int irq)
@@ -336,6 +344,15 @@ struct irq_cfg *irq_cfg(unsigned int irq)
 	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
 
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
+{
+}
+
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+{
+}
+
 #endif
 
 struct io_apic {
@@ -2747,6 +2764,9 @@ static struct irq_chip ioapic_chip __read_mostly = {
 	.set_affinity	= set_ioapic_affinity_irq,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
@@ -2762,6 +2782,9 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -3474,6 +3497,9 @@ static struct irq_chip msi_chip = {
 	.set_affinity	= set_msi_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip msi_ir_chip = {
@@ -3487,6 +3513,9 @@ static struct irq_chip msi_ir_chip = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
@@ -3646,6 +3675,9 @@ static struct irq_chip dmar_msi_type = {
 	.set_affinity = dmar_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_dmar_msi(unsigned int irq)
@@ -3703,6 +3735,9 @@ static struct irq_chip ir_hpet_msi_type = {
 #endif
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip hpet_msi_type = {
@@ -3714,6 +3749,9 @@ static struct irq_chip hpet_msi_type = {
 	.set_affinity = hpet_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
@@ -3800,6 +3838,9 @@ static struct irq_chip ht_irq_chip = {
 	.set_affinity	= set_ht_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index ece73d8..4c61f1b 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -55,6 +55,9 @@ struct irq_chip uv_irq_chip = {
 	.eoi		= uv_ack_apic,
 	.end		= uv_noop,
 	.set_affinity	= uv_set_irq_affinity,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2f84137..64cbbe4 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -329,6 +329,11 @@ static void unmask_evtchn(int port)
 	put_cpu();
 }
 
+static int xen_init_chip_data(struct irq_desc *desc, int node)
+{
+	return 0;
+}
+
 static int find_unbound_irq(void)
 {
 	int irq;
@@ -341,7 +346,7 @@ static int find_unbound_irq(void)
 	if (irq == nr_irqs)
 		panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-	desc = irq_to_desc_alloc_node(irq, 0);
+	desc = irq_to_desc_alloc_node_x(irq, 0, xen_init_chip_data);
 	if (WARN_ON(desc == NULL))
 		return -1;
 
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 75f3f00..0b0d679 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -611,6 +611,5 @@ struct irq_desc;
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
 extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int node);
 
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 707ab12..60f3368 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -140,6 +140,13 @@ struct irq_chip {
 	 * Will disappear.
 	 */
 	const char	*typename;
+
+	/* for move_irq_desc */
+	void		(*copy_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc, int node);
+	void		(*free_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc);
+
 };
 
 struct timer_rand_state;
@@ -208,10 +215,6 @@ struct irq_desc {
 	const char		*name;
 } ____cacheline_internodealigned_in_smp;
 
-extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-					struct irq_desc *desc, int node);
-extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
-
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
@@ -225,7 +228,15 @@ static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 }
 #endif
 
-extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
+typedef int (*init_chip_data_fn)(struct irq_desc *, int node);
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn);
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn fn);
+static inline struct irq_desc *irq_to_desc_alloc_node(unsigned int irq,
+							 int node)
+{
+	return irq_to_desc_alloc_node_x(irq, node, NULL);
+}
 
 /*
  * Pick up the arch-dependent methods:
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index bbba585..3dcdd2f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -758,3 +758,10 @@ void __init set_irq_probe(unsigned int irq)
 	desc->status &= ~IRQ_NOPROBE;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
+
+int __weak arch_init_irq_desc(struct irq_desc *desc, int node,
+				 init_chip_data_fn init_chip_data)
+{
+	return 0;
+}
+
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 76d5a67..f30c9c7 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -100,7 +100,8 @@ void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 	}
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node,
+			      init_chip_data_fn init_chip_data)
 {
 	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
 
@@ -120,7 +121,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
 		BUG_ON(1);
 	}
 	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
+	arch_init_irq_desc(desc, node, init_chip_data);
 }
 
 /*
@@ -198,7 +199,8 @@ int __init early_irq_init(void)
 	return arch_early_irq_init();
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc * __ref irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn init_chip_data)
 {
 	struct irq_desc *desc;
 	unsigned long flags;
@@ -227,7 +229,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
 		printk(KERN_ERR "can not alloc irq_desc\n");
 		BUG_ON(1);
 	}
-	init_one_irq_desc(irq, desc, node);
+	init_one_irq_desc(irq, desc, node, init_chip_data);
 
 	set_irq_desc(irq, desc);
 
@@ -277,7 +279,8 @@ struct irq_desc *irq_to_desc(unsigned int irq)
 	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					init_chip_data_fn init_chip_data)
 {
 	return irq_to_desc(irq);
 }
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 963559d..9ea09c9 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -47,7 +47,8 @@ static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
 	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
 	init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
 	init_copy_desc_masks(old_desc, desc);
-	arch_init_copy_chip_data(old_desc, desc, node);
+	if (desc->chip->copy_chip_data)
+		desc->chip->copy_chip_data(old_desc, desc, node);
 	return true;
 }
 
@@ -55,7 +56,8 @@ static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	free_kstat_irqs(old_desc, desc);
 	free_desc_masks(old_desc, desc);
-	arch_free_chip_data(old_desc, desc);
+	if (desc->chip->free_chip_data)
+		desc->chip->free_chip_data(old_desc, desc);
 }
 
 static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
@@ -107,9 +109,15 @@ out_unlock:
 
 struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 {
+
 	/* those static or target node is -1, do not move them */
 	if (desc->irq < NR_IRQS_LEGACY || node == -1)
 		return desc;
+	/* IRQ chip does not support movement */
+	if (desc->chip_data &&
+	    (desc->chip->copy_chip_data == NULL ||
+	     desc->chip->free_chip_data == NULL))
+		return desc;
 
 	if (desc->node != node)
 		desc = __real_move_irq_desc(desc, node);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 7c1a67e..7df0209 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -895,8 +895,3 @@ int __init __weak arch_early_irq_init(void)
 {
 	return 0;
 }
-
-int __weak arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	return 0;
-}
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  1:36   ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Ian Campbell,
	Paul Mundt, linux-sh, x86, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Thomas Gleixner, Yinghai Lu

From: Ian Campbell <ian.campbell@citrix.com>

Move arch_init_copy_chip_data and arch_free_chip_data into function
pointers in struct irq_chip since they operate on irq_desc->chip_data.

arch_init_chip_data cannot be moved into struct irq_chip because
irq_desc->chip is not known at the time the irq_desc is setup. Instead
rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
only other user, whose usage better matches the new name.

To replace the x86 arch_init_chip_data functionality
irq_to_desc_alloc_node now takes a pointer to a function to allocate
the chip data. This is necessary to ensure the allocation happens
under the correct locking at the core level. On PowerPC and SH
architectures (the other users of irq_to_desc_alloc_node) pass in NULL
which retains existing chip_data behaviour.

I've retained the chip_data behaviour for uv_irq although it isn't
clear to me if these interrupt types support migration or how closely
related to the APIC modes they really are. If it weren't for this the
x86_{init,copy,free}_chip_data functions could be static to
io_apic.c.

I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
and 32 bit without, but it's not clear to me what actions I need to
take to actually exercise some of these code paths.

-v4: yinghai add irq_to_desc_alloc_node_x...
     so could leave default path not changed...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Michael Ellerman <michael@ellerman.id.au> [PowerPC rename portion]
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: x86@kernel.org
Cc: linuxppc-dev@ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: lguest@ozlabs.org
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: linux-sh@vger.kernel.org
---
 arch/powerpc/kernel/irq.c      |    2 +-
 arch/x86/include/asm/hw_irq.h  |    7 +++++-
 arch/x86/kernel/apic/io_apic.c |   49 ++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/uv_irq.c       |    3 ++
 drivers/xen/events.c           |    7 +++++-
 include/linux/interrupt.h      |    1 -
 include/linux/irq.h            |   21 +++++++++++++----
 kernel/irq/chip.c              |    7 +++++
 kernel/irq/handle.c            |   13 ++++++----
 kernel/irq/numa_migrate.c      |   12 ++++++++-
 kernel/softirq.c               |    5 ----
 11 files changed, 102 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 46c0fe0..767d3f8 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -20,9 +20,9 @@
 #include <linux/percpu.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
+#include <linux/irq.h>
 
 #include <asm/atomic.h>
-#include <asm/irq.h>
 #include <asm/sections.h>
 
 /* Interrupt handlers registered during init_IRQ */
@@ -61,6 +61,11 @@ extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
 extern void disable_IO_APIC(void);
 
+extern void x86_copy_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc, int node);
+extern void x86_free_chip_data(struct irq_desc *old_desc,
+				  struct irq_desc *desc);
+
 struct io_apic_irq_attr {
 	int ioapic;
 	int ioapic_pin;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 463de9a..a917fdf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -211,7 +211,7 @@ static struct irq_cfg *get_one_free_irq_cfg(int node)
 	return cfg;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+static int x86_init_chip_data(struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 
@@ -287,8 +287,8 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
 	old_cfg->irq_2_pin = NULL;
 }
 
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int node)
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
 {
 	struct irq_cfg *cfg;
 	struct irq_cfg *old_cfg;
@@ -312,7 +312,7 @@ static void free_irq_cfg(struct irq_cfg *old_cfg)
 	kfree(old_cfg);
 }
 
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	struct irq_cfg *old_cfg, *cfg;
 
@@ -329,6 +329,14 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
 	}
 }
 /* end for move_irq_desc */
+int arch_init_irq_desc(struct irq_desc *desc, int node,
+			 init_chip_data_fn init_chip_data)
+{
+	if (!init_chip_data)
+		return x86_init_chip_data(desc, node);
+
+	return init_chip_data(desc, node);
+}
 
 #else
 struct irq_cfg *irq_cfg(unsigned int irq)
@@ -336,6 +344,15 @@ struct irq_cfg *irq_cfg(unsigned int irq)
 	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
 
+void x86_copy_chip_data(struct irq_desc *old_desc,
+			   struct irq_desc *desc, int node)
+{
+}
+
+void x86_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+{
+}
+
 #endif
 
 struct io_apic {
@@ -2747,6 +2764,9 @@ static struct irq_chip ioapic_chip __read_mostly = {
 	.set_affinity	= set_ioapic_affinity_irq,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip ir_ioapic_chip __read_mostly = {
@@ -2762,6 +2782,9 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -3474,6 +3497,9 @@ static struct irq_chip msi_chip = {
 	.set_affinity	= set_msi_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip msi_ir_chip = {
@@ -3487,6 +3513,9 @@ static struct irq_chip msi_ir_chip = {
 #endif
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
@@ -3646,6 +3675,9 @@ static struct irq_chip dmar_msi_type = {
 	.set_affinity = dmar_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_dmar_msi(unsigned int irq)
@@ -3703,6 +3735,9 @@ static struct irq_chip ir_hpet_msi_type = {
 #endif
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 static struct irq_chip hpet_msi_type = {
@@ -3714,6 +3749,9 @@ static struct irq_chip hpet_msi_type = {
 	.set_affinity = hpet_msi_set_affinity,
 #endif
 	.retrigger = ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
@@ -3800,6 +3838,9 @@ static struct irq_chip ht_irq_chip = {
 	.set_affinity	= set_ht_irq_affinity,
 #endif
 	.retrigger	= ioapic_retrigger_irq,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index ece73d8..4c61f1b 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -55,6 +55,9 @@ struct irq_chip uv_irq_chip = {
 	.eoi		= uv_ack_apic,
 	.end		= uv_noop,
 	.set_affinity	= uv_set_irq_affinity,
+
+	.copy_chip_data = x86_copy_chip_data,
+	.free_chip_data = x86_free_chip_data,
 };
 
 /*
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2f84137..64cbbe4 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -329,6 +329,11 @@ static void unmask_evtchn(int port)
 	put_cpu();
 }
 
+static int xen_init_chip_data(struct irq_desc *desc, int node)
+{
+	return 0;
+}
+
 static int find_unbound_irq(void)
 {
 	int irq;
@@ -341,7 +346,7 @@ static int find_unbound_irq(void)
 	if (irq == nr_irqs)
 		panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-	desc = irq_to_desc_alloc_node(irq, 0);
+	desc = irq_to_desc_alloc_node_x(irq, 0, xen_init_chip_data);
 	if (WARN_ON(desc == NULL))
 		return -1;
 
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 75f3f00..0b0d679 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -611,6 +611,5 @@ struct irq_desc;
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
 extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int node);
 
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 707ab12..60f3368 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -140,6 +140,13 @@ struct irq_chip {
 	 * Will disappear.
 	 */
 	const char	*typename;
+
+	/* for move_irq_desc */
+	void		(*copy_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc, int node);
+	void		(*free_chip_data)(struct irq_desc *old_desc,
+					  struct irq_desc *desc);
+
 };
 
 struct timer_rand_state;
@@ -208,10 +215,6 @@ struct irq_desc {
 	const char		*name;
 } ____cacheline_internodealigned_in_smp;
 
-extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-					struct irq_desc *desc, int node);
-extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
-
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
@@ -225,7 +228,15 @@ static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 }
 #endif
 
-extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
+typedef int (*init_chip_data_fn)(struct irq_desc *, int node);
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn);
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn fn);
+static inline struct irq_desc *irq_to_desc_alloc_node(unsigned int irq,
+							 int node)
+{
+	return irq_to_desc_alloc_node_x(irq, node, NULL);
+}
 
 /*
  * Pick up the arch-dependent methods:
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index bbba585..3dcdd2f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -758,3 +758,10 @@ void __init set_irq_probe(unsigned int irq)
 	desc->status &= ~IRQ_NOPROBE;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
+
+int __weak arch_init_irq_desc(struct irq_desc *desc, int node,
+				 init_chip_data_fn init_chip_data)
+{
+	return 0;
+}
+
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 76d5a67..f30c9c7 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -100,7 +100,8 @@ void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 	}
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node,
+			      init_chip_data_fn init_chip_data)
 {
 	memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
 
@@ -120,7 +121,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
 		BUG_ON(1);
 	}
 	init_desc_masks(desc);
-	arch_init_chip_data(desc, node);
+	arch_init_irq_desc(desc, node, init_chip_data);
 }
 
 /*
@@ -198,7 +199,8 @@ int __init early_irq_init(void)
 	return arch_early_irq_init();
 }
 
-struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc * __ref irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					       init_chip_data_fn init_chip_data)
 {
 	struct irq_desc *desc;
 	unsigned long flags;
@@ -227,7 +229,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
 		printk(KERN_ERR "can not alloc irq_desc\n");
 		BUG_ON(1);
 	}
-	init_one_irq_desc(irq, desc, node);
+	init_one_irq_desc(irq, desc, node, init_chip_data);
 
 	set_irq_desc(irq, desc);
 
@@ -277,7 +279,8 @@ struct irq_desc *irq_to_desc(unsigned int irq)
 	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc *irq_to_desc_alloc_node_x(unsigned int irq, int node,
+					init_chip_data_fn init_chip_data)
 {
 	return irq_to_desc(irq);
 }
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 963559d..9ea09c9 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -47,7 +47,8 @@ static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
 	lockdep_set_class(&desc->lock, &irq_desc_lock_class);
 	init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
 	init_copy_desc_masks(old_desc, desc);
-	arch_init_copy_chip_data(old_desc, desc, node);
+	if (desc->chip->copy_chip_data)
+		desc->chip->copy_chip_data(old_desc, desc, node);
 	return true;
 }
 
@@ -55,7 +56,8 @@ static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
 {
 	free_kstat_irqs(old_desc, desc);
 	free_desc_masks(old_desc, desc);
-	arch_free_chip_data(old_desc, desc);
+	if (desc->chip->free_chip_data)
+		desc->chip->free_chip_data(old_desc, desc);
 }
 
 static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
@@ -107,9 +109,15 @@ out_unlock:
 
 struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 {
+
 	/* those static or target node is -1, do not move them */
 	if (desc->irq < NR_IRQS_LEGACY || node == -1)
 		return desc;
+	/* IRQ chip does not support movement */
+	if (desc->chip_data &&
+	    (desc->chip->copy_chip_data == NULL ||
+	     desc->chip->free_chip_data == NULL))
+		return desc;
 
 	if (desc->node != node)
 		desc = __real_move_irq_desc(desc, node);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 7c1a67e..7df0209 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -895,8 +895,3 @@ int __init __weak arch_early_irq_init(void)
 {
 	return 0;
 }
-
-int __weak arch_init_chip_data(struct irq_desc *desc, int node)
-{
-	return 0;
-}
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 02/10] x86: fix out of order of gsi - full
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
  2010-03-22  1:36   ` Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22 11:14   ` Thomas Gleixner
  2010-03-22  1:36 ` [PATCH 03/10] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi Yinghai Lu
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu, Thomas Renninger, Eric W. Biederman,
	Suresh Siddha, len.brown

Iranna D Ankad reported that IBM x3950 systems have boot problems
after this commit:

 |
 | commit b9c61b70075c87a8612624736faf4a2de5b1ed30
 |
 |    x86/pci: update pirq_enable_irq() to setup io apic routing
 |
  ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
  IOAPIC[0]: apic_id 16, version 0, address 0xfecff000, GSI 0-2
  ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
  IOAPIC[1]: apic_id 15, version 0, address 0xfec00000, GSI 3-38
  ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
  IOAPIC[2]: apic_id 14, version 0, address 0xfec01000, GSI 39-74

  As explained in the previous patch ("x86: Fix out of order gsi)

  need to remap those gsis

  This patch adds boot_ioapic_idx and gsi_to_irq/irq_to_gsi
  So we could make sure for those kind of system will have
        irq: 0 - 15 for legacy irq
        irq:  16 after will be gsi + 16

 -v13: move gsi_to_irq/irq_to_gsi to acpi/boot.c

Reported-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
Bisected-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
Tested-by: Gary Hade <garyhade@us.ibm.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Thomas Renninger <trenn@suse.de>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: len.brown@intel.com
---
 arch/x86/include/asm/io_apic.h |    2 +-
 arch/x86/include/asm/mpspec.h  |   14 ++++++++
 arch/x86/kernel/acpi/boot.c    |   64 +++++++++++++++++++++++++++++------
 arch/x86/kernel/apic/io_apic.c |   72 +++++++++++++++++++++++++++++----------
 drivers/pnp/pnpacpi/rsparser.c |    4 ++
 5 files changed, 125 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..c4683b9 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -158,7 +158,7 @@ extern int io_apic_get_redir_entries(int ioapic);
 struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
-void setup_IO_APIC_irq_extra(u32 gsi);
+void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *irq);
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..1a221e0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -109,6 +109,9 @@ extern int acpi_probe_gsi(void);
 #ifdef CONFIG_X86_IO_APIC
 extern int mp_find_ioapic(int gsi);
 extern int mp_find_ioapic_pin(int ioapic, int gsi);
+extern int gsi_delta;
+int gsi_to_irq(unsigned int gsi);
+unsigned int irq_to_gsi(int irq);
 #endif
 #else /* !CONFIG_ACPI: */
 static inline int acpi_probe_gsi(void)
@@ -117,6 +120,17 @@ static inline int acpi_probe_gsi(void)
 }
 #endif /* CONFIG_ACPI */
 
+#if !defined(CONFIG_ACPI) || !defined(CONFIG_X86_IO_APIC)
+static inline int gsi_to_irq(unsigned int gsi)
+{
+	return gsi;
+}
+static inline unsigned int irq_to_gsi(int irq)
+{
+	return irq;
+}
+#endif
+
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
 
 struct physid_mask {
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 37de00f..2450c95 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -311,7 +311,8 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init
+acpi_sci_ioapic_setup(u8 bus_irq, u32 gsi, u16 polarity, u16 trigger)
 {
 	if (trigger == 0)	/* compatible SCI trigger is level */
 		trigger = 3;
@@ -331,7 +332,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
 	 * If GSI is < 16, this will update its flags,
 	 * else it will create a new mp_irqs[] entry.
 	 */
-	mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
 	/*
 	 * stash over-ride to indicate we've been here
@@ -355,7 +356,8 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-		acpi_sci_ioapic_setup(intsrc->global_irq,
+		acpi_sci_ioapic_setup(intsrc->source_irq,
+				      intsrc->global_irq,
 				      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
 				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
 		return 0;
@@ -446,11 +448,11 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	*irq = gsi;
+	*irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
-		setup_IO_APIC_irq_extra(gsi);
+		setup_IO_APIC_irq_extra(gsi, irq);
 #endif
 
 	return 0;
@@ -914,6 +916,40 @@ static void save_mp_irq(struct mpc_intsrc *m)
 		panic("Max # of irq sources exceeded!!\n");
 }
 
+/* By default isa irqs are identity mapped to gsis */
+static unsigned int isa_irq_to_gsi[NR_IRQS_LEGACY] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+int gsi_delta;
+int gsi_to_irq(unsigned int gsi)
+{
+	unsigned int irq = gsi;
+	unsigned int i;
+
+	irq += gsi_delta;
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		if (isa_irq_to_gsi[i] == gsi) {
+			irq = i;
+			break;
+		}
+	}
+
+	return irq;
+}
+
+unsigned int irq_to_gsi(int irq)
+{
+	unsigned int gsi;
+
+	if (irq < NR_IRQS_LEGACY)
+		gsi = isa_irq_to_gsi[irq];
+	else
+		gsi = irq - gsi_delta;
+
+	return gsi;
+}
+
 void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 {
 	int ioapic;
@@ -945,6 +981,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 	mp_irq.dstirq = pin;	/* INTIN# */
 
 	save_mp_irq(&mp_irq);
+
+	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
@@ -974,7 +1012,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 	/*
 	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
 	 */
-	ioapic = mp_find_ioapic(0);
+	ioapic = mp_find_ioapic(irq_to_gsi(0));
 	if (ioapic < 0)
 		return;
 	dstapic = mp_ioapics[ioapic].apicid;
@@ -1057,6 +1095,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 {
 	int ioapic;
 	int ioapic_pin;
+	int irq;
 	struct io_apic_irq_attr irq_attr;
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
@@ -1079,11 +1118,12 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 		gsi = ioapic_renumber_irq(ioapic, gsi);
 #endif
 
+	irq = gsi_to_irq(gsi);
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 		       "%d-%d\n", mp_ioapics[ioapic].apicid,
 		       ioapic_pin);
-		return gsi;
+		return irq;
 	}
 
 	if (enable_update_mptable)
@@ -1092,9 +1132,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	io_apic_set_pci_routing(dev, gsi, &irq_attr);
+	io_apic_set_pci_routing(dev, irq, &irq_attr);
 
-	return gsi;
+	return irq;
 }
 
 /*
@@ -1151,8 +1191,10 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	 * If BIOS did not supply an INT_SRC_OVR for the SCI
 	 * pretend we got one so we can set the SCI flags.
 	 */
-	if (!acpi_sci_override_gsi)
-		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+	if (!acpi_sci_override_gsi) {
+		int irq = gsi_to_irq(acpi_gbl_FADT.sci_interrupt);
+		acpi_sci_ioapic_setup(irq, acpi_gbl_FADT.sci_interrupt, 0, 0);
+	}
 
 	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a917fdf..61b59ef 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -97,6 +97,8 @@ int mp_irq_entries;
 /* GSI interrupts */
 static int nr_irqs_gsi = NR_IRQS_LEGACY;
 
+static int boot_ioapic_idx;
+
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
 int mp_bus_id_to_type[MAX_MP_BUSSES];
 #endif
@@ -1032,7 +1034,7 @@ static inline int irq_trigger(int idx)
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-	int irq, i;
+	int irq;
 	int bus = mp_irqs[idx].srcbus;
 
 	/*
@@ -1044,18 +1046,28 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
+		unsigned int gsi;
+		if (!acpi_ioapic) {
+			int i;
+			/*
+			 * PCI IRQs are mapped in order
+			 */
+			i = gsi = 0;
+			while (i < apic)
+				gsi += nr_ioapic_registers[i++];
+			gsi += pin;
+		} else
+			gsi = pin + mp_gsi_routing[apic].gsi_base;
+
+#ifdef CONFIG_X86_32
 		/*
                  * For MPS mode, so far only needed by ES7000 platform
                  */
 		if (ioapic_renumber_irq)
-			irq = ioapic_renumber_irq(apic, irq);
+			gsi = ioapic_renumber_irq(apic, gsi);
+#endif
+
+		irq = gsi_to_irq(gsi);
 	}
 
 #ifdef CONFIG_X86_32
@@ -1505,9 +1517,10 @@ static void __init setup_IO_APIC_irqs(void)
 	struct irq_cfg *cfg;
 	int node = cpu_to_node(boot_cpu_id);
 
+	apic_id = boot_ioapic_idx;
+
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-	for (apic_id = 0; apic_id < nr_ioapics; apic_id++)
 	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
 		idx = find_irq_entry(apic_id, pin, mp_INT);
 		if (idx == -1) {
@@ -1529,9 +1542,6 @@ static void __init setup_IO_APIC_irqs(void)
 
 		irq = pin_2_irq(idx, apic_id, pin);
 
-		if ((apic_id > 0) && (irq > 16))
-			continue;
-
 		/*
 		 * Skip the timer IRQ if there's a quirk handler
 		 * installed and if it returns 1:
@@ -1565,7 +1575,7 @@ static void __init setup_IO_APIC_irqs(void)
  * but could not use acpi_register_gsi()
  * like some special sci in IBM x3330
  */
-void setup_IO_APIC_irq_extra(u32 gsi)
+void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *pirq)
 {
 	int apic_id = 0, pin, idx, irq;
 	int node = cpu_to_node(boot_cpu_id);
@@ -1585,6 +1595,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 		return;
 
 	irq = pin_2_irq(idx, apic_id, pin);
+	*pirq = irq;
 #ifdef CONFIG_SPARSE_IRQ
 	desc = irq_to_desc(irq);
 	if (desc)
@@ -2028,6 +2039,30 @@ void __init enable_IO_APIC(void)
 	clear_IO_APIC();
 }
 
+static void __init probe_ioapic_i8259(void)
+{
+	/* probe boot ioapic idx */
+	boot_ioapic_idx = ioapic_i8259.apic;
+	if (boot_ioapic_idx < 0)
+		boot_ioapic_idx = find_isa_irq_apic(0, mp_INT);
+#ifdef CONFIG_ACPI
+	if (!acpi_disabled && acpi_ioapic && boot_ioapic_idx < 0)
+		boot_ioapic_idx = mp_find_ioapic(irq_to_gsi(0));
+#endif
+	if (boot_ioapic_idx < 0)
+		boot_ioapic_idx = 0;
+
+#ifdef CONFIG_ACPI
+	if (mp_gsi_routing[boot_ioapic_idx].gsi_base) {
+		gsi_delta = NR_IRQS_LEGACY;
+		nr_irqs_gsi += NR_IRQS_LEGACY;
+		printk(KERN_DEBUG "new nr_irqs_gsi: %d\n", nr_irqs_gsi);
+	}
+#endif
+
+	printk(KERN_INFO "boot_ioapic_idx: %d\n", boot_ioapic_idx);
+}
+
 /*
  * Not an __init, needed by the reboot code
  */
@@ -3045,7 +3080,7 @@ static inline void __init check_timer(void)
 				legacy_pic->chip->unmask(0);
 			}
 			if (disable_timer_pin_1 > 0)
-				clear_IO_APIC_pin(0, pin1);
+				clear_IO_APIC_pin(apic1, pin1);
 			goto out;
 		}
 		if (intr_remapping_enabled)
@@ -3165,6 +3200,7 @@ void __init setup_IO_APIC(void)
 	x86_init.mpparse.setup_ioapic_ids();
 
 	sync_Arb_IDs();
+	probe_ioapic_i8259();
 	setup_IO_APIC_irqs();
 	init_IO_APIC_traps();
 	if (legacy_pic->nr_legacy_irqs)
@@ -4156,16 +4192,14 @@ void __init setup_ioapic_dest(void)
 	if (skip_ioapic_setup == 1)
 		return;
 
-	for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
+	ioapic = boot_ioapic_idx;
+
 	for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
 		irq_entry = find_irq_entry(ioapic, pin, mp_INT);
 		if (irq_entry == -1)
 			continue;
 		irq = pin_2_irq(irq_entry, ioapic, pin);
 
-		if ((ioapic > 0) && (irq > 16))
-			continue;
-
 		desc = irq_to_desc(irq);
 
 		/*
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 54514aa..1dcf64d 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -123,6 +123,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
 	}
 
 	flags = irq_flags(triggering, polarity, shareable);
+#ifdef CONFIG_X86
+	/* bus_irq or gsi ? */
+	gsi = irq_to_gsi(gsi);
+#endif
 	irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
 	if (irq >= 0)
 		pcibios_penalize_isa_irq(irq, 1);
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 03/10] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
  2010-03-22  1:36   ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 02/10] x86: fix out of order of gsi - full Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 04/10] x86: kill smpboot_hooks.h Yinghai Lu
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

don't clear that in arch_early_irq_init

probe_nr_irqs_gsi is always called when ioapic is selected in config.

so even for mrst, print out from probe_nr_irqs_gsi is report correct
nr_irqs_gsi

-v2: remove io_apic_irqs assignement, setup_IO_APIC will do that.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/kernel/apic/io_apic.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 61b59ef..ba469f8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -153,11 +153,6 @@ int __init arch_early_irq_init(void)
 	int node;
 	int i;
 
-	if (!legacy_pic->nr_legacy_irqs) {
-		nr_irqs_gsi = 0;
-		io_apic_irqs = ~0UL;
-	}
-
 	cfg = irq_cfgx;
 	count = ARRAY_SIZE(irq_cfgx);
 	node= cpu_to_node(boot_cpu_id);
@@ -3938,6 +3933,8 @@ void __init probe_nr_irqs_gsi(void)
 {
 	int nr = 0;
 
+	nr_irqs_gsi = legacy_pic->nr_legacy_irqs;
+
 	nr = acpi_probe_gsi();
 	if (nr > nr_irqs_gsi) {
 		nr_irqs_gsi = nr;
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 04/10] x86: kill smpboot_hooks.h
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (2 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 03/10] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22 13:34   ` Thomas Gleixner
  2010-03-22  1:36 ` [PATCH 05/10] x86: use vector_desc instead of vector_irq Yinghai Lu
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

only one user, move it back to smpboot.c

remove smpboot_clear_io_apic, and only keep smpboot_clear_io_apic_irqs.

and check nr_legacy_irqs before clear it.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/smpboot_hooks.h |   61 ----------------------------------
 arch/x86/kernel/smpboot.c            |   57 ++++++++++++++++++++++++++++++--
 2 files changed, 54 insertions(+), 64 deletions(-)
 delete mode 100644 arch/x86/include/asm/smpboot_hooks.h

diff --git a/arch/x86/include/asm/smpboot_hooks.h b/arch/x86/include/asm/smpboot_hooks.h
deleted file mode 100644
index 1def601..0000000
--- a/arch/x86/include/asm/smpboot_hooks.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
- * which needs to alter them. */
-
-static inline void smpboot_clear_io_apic_irqs(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	io_apic_irqs = 0;
-#endif
-}
-
-static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
-{
-	CMOS_WRITE(0xa, 0xf);
-	local_flush_tlb();
-	pr_debug("1.\n");
-	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) =
-								 start_eip >> 4;
-	pr_debug("2.\n");
-	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_low)) =
-							 start_eip & 0xf;
-	pr_debug("3.\n");
-}
-
-static inline void smpboot_restore_warm_reset_vector(void)
-{
-	/*
-	 * Install writable page 0 entry to set BIOS data area.
-	 */
-	local_flush_tlb();
-
-	/*
-	 * Paranoid:  Set warm reset code and vector here back
-	 * to default values.
-	 */
-	CMOS_WRITE(0, 0xf);
-
-	*((volatile long *)phys_to_virt(apic->trampoline_phys_low)) = 0;
-}
-
-static inline void __init smpboot_setup_io_apic(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	/*
-	 * Here we can be sure that there is an IO-APIC in the system. Let's
-	 * go and set it up:
-	 */
-	if (!skip_ioapic_setup && nr_ioapics)
-		setup_IO_APIC();
-	else {
-		nr_ioapics = 0;
-		localise_nmi_watchdog();
-	}
-#endif
-}
-
-static inline void smpboot_clear_io_apic(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	nr_ioapics = 0;
-#endif
-}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 06d98ae..ba43b3b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -67,7 +67,6 @@
 #include <asm/uv/uv.h>
 #include <linux/mc146818rtc.h>
 
-#include <asm/smpboot_hooks.h>
 #include <asm/i8259.h>
 
 #ifdef CONFIG_X86_32
@@ -701,6 +700,35 @@ static void __cpuinit announce_cpu(int cpu, int apicid)
 			node, cpu, apicid);
 }
 
+static void smpboot_setup_warm_reset_vector(unsigned long start_eip)
+{
+	CMOS_WRITE(0xa, 0xf);
+	local_flush_tlb();
+	pr_debug("1.\n");
+	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) =
+								 start_eip >> 4;
+	pr_debug("2.\n");
+	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_low)) =
+							 start_eip & 0xf;
+	pr_debug("3.\n");
+}
+
+static void smpboot_restore_warm_reset_vector(void)
+{
+	/*
+	 * Install writable page 0 entry to set BIOS data area.
+	 */
+	local_flush_tlb();
+
+	/*
+	 * Paranoid:  Set warm reset code and vector here back
+	 * to default values.
+	 */
+	CMOS_WRITE(0, 0xf);
+
+	*((volatile long *)phys_to_virt(apic->trampoline_phys_low)) = 0;
+}
+
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -928,6 +956,13 @@ int __cpuinit native_cpu_up(unsigned int cpu)
 	return 0;
 }
 
+static void smpboot_clear_io_apic_irqs(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	if (legacy_pic->nr_legacy_irqs)
+		io_apic_irqs = 0;
+#endif
+}
 /*
  * Fall back to non SMP mode after errors.
  *
@@ -1027,7 +1062,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
 			pr_err("... forcing use of dummy APIC emulation."
 				"(tell your hw vendor)\n");
 		}
-		smpboot_clear_io_apic();
+		smpboot_clear_io_apic_irqs();
 		arch_disable_smp_support();
 		return -1;
 	}
@@ -1039,7 +1074,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
 	 */
 	if (!max_cpus) {
 		printk(KERN_INFO "SMP mode deactivated.\n");
-		smpboot_clear_io_apic();
+		smpboot_clear_io_apic_irqs();
 
 		localise_nmi_watchdog();
 
@@ -1064,6 +1099,22 @@ static void __init smp_cpu_index_default(void)
 	}
 }
 
+static void __init smpboot_setup_io_apic(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	/*
+	 * Here we can be sure that there is an IO-APIC in the system. Let's
+	 * go and set it up:
+	 */
+	if (!skip_ioapic_setup && nr_ioapics)
+		setup_IO_APIC();
+	else {
+		nr_ioapics = 0;
+		localise_nmi_watchdog();
+	}
+#endif
+}
+
 /*
  * Prepare for SMP bootup.  The MP table or ACPI has been read
  * earlier.  Just do some sanity checking here and enable APIC mode.
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 05/10] x86: use vector_desc instead of vector_irq
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (3 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 04/10] x86: kill smpboot_hooks.h Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22 13:58   ` Thomas Gleixner
  2010-03-22  1:36 ` [PATCH 06/10] irq: Start the transition of irq_chip methods taking a desc Yinghai Lu
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

Eric pointed out that radix tree version of irq_to_desc will magnify delay on
the path of handle_irq.

use vector_desc to reduce the calling of irq_to_desc.

next step: need to change all ack, mask, umask, eoi for all irq_chip to take irq_desc

-v2: irq should be unsigned in 32bit handle_irq according to Eric
     also reset vector_desc for lguest in setup_irq
-v3: keep irq in x+execute_on_irq_stack() ...
-v4: update after legacy_pic

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/x86/include/asm/desc.h    |    2 +-
 arch/x86/include/asm/hw_irq.h  |   13 ++++---
 arch/x86/include/asm/irq.h     |    3 +-
 arch/x86/kernel/apic/io_apic.c |   77 +++++++++++++++++++++-------------------
 arch/x86/kernel/irq.c          |   15 ++++----
 arch/x86/kernel/irq_32.c       |   13 ++++---
 arch/x86/kernel/irq_64.c       |    7 +---
 arch/x86/kernel/irqinit.c      |   14 +++----
 arch/x86/kernel/smpboot.c      |    2 +-
 arch/x86/kernel/uv_irq.c       |    2 +-
 arch/x86/kernel/vmiclock_32.c  |    2 +-
 arch/x86/lguest/boot.c         |    7 +++-
 12 files changed, 82 insertions(+), 75 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 617bd56..25c5635 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -334,7 +334,7 @@ static inline void set_intr_gate(unsigned int n, void *addr)
 }
 
 extern int first_system_vector;
-/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
+/* used_vectors is BITMAP for irq is not managed by percpu vector_desc */
 extern unsigned long used_vectors[];
 
 static inline void alloc_system_vector(int vector)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 767d3f8..d23cf94 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -97,7 +97,8 @@ struct irq_cfg {
 };
 
 extern struct irq_cfg *irq_cfg(unsigned int);
-extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
+int assign_irq_vector(struct irq_desc *, struct irq_cfg *,
+			 const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
 
 struct irq_desc;
@@ -136,18 +137,18 @@ extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
 
 extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
 
-typedef int vector_irq_t[NR_VECTORS];
-DECLARE_PER_CPU(vector_irq_t, vector_irq);
-extern void setup_vector_irq(int cpu);
+typedef struct irq_desc *vector_desc_t[NR_VECTORS];
+DECLARE_PER_CPU(vector_desc_t, vector_desc);
+extern void setup_vector_desc(int cpu);
 
 #ifdef CONFIG_X86_IO_APIC
 extern void lock_vector_lock(void);
 extern void unlock_vector_lock(void);
-extern void __setup_vector_irq(int cpu);
+extern void __setup_vector_desc(int cpu);
 #else
 static inline void lock_vector_lock(void) {}
 static inline void unlock_vector_lock(void) {}
-static inline void __setup_vector_irq(int cpu) {}
+static inline void __setup_vector_desc(int cpu) {}
 #endif
 
 #endif /* !ASSEMBLY_ */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 5458380..64c5f6f 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -39,7 +39,8 @@ extern void irq_force_complete_move(int);
 
 extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
-extern bool handle_irq(unsigned irq, struct pt_regs *regs);
+struct irq_desc;
+extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
 
 extern unsigned int do_IRQ(struct pt_regs *regs);
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index ba469f8..cd2f193 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1159,7 +1159,8 @@ void unlock_vector_lock(void)
 }
 
 static int
-__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+__assign_irq_vector(struct irq_desc *desc, struct irq_cfg *cfg,
+			 const struct cpumask *mask)
 {
 	/*
 	 * NOTE! The local APIC isn't very good at handling
@@ -1218,7 +1219,7 @@ next:
 			goto next;
 
 		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
-			if (per_cpu(vector_irq, new_cpu)[vector] != -1)
+			if (per_cpu(vector_desc, new_cpu)[vector] != NULL)
 				goto next;
 		/* Found one! */
 		current_vector = vector;
@@ -1228,7 +1229,7 @@ next:
 			cpumask_copy(cfg->old_domain, cfg->domain);
 		}
 		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
-			per_cpu(vector_irq, new_cpu)[vector] = irq;
+			per_cpu(vector_desc, new_cpu)[vector] = desc;
 		cfg->vector = vector;
 		cpumask_copy(cfg->domain, tmp_mask);
 		err = 0;
@@ -1238,18 +1239,19 @@ next:
 	return err;
 }
 
-int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+int assign_irq_vector(struct irq_desc *desc, struct irq_cfg *cfg,
+			 const struct cpumask *mask)
 {
 	int err;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&vector_lock, flags);
-	err = __assign_irq_vector(irq, cfg, mask);
+	err = __assign_irq_vector(desc, cfg, mask);
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
 	return err;
 }
 
-static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
+static void __clear_irq_vector(struct irq_desc *desc, struct irq_cfg *cfg)
 {
 	int cpu, vector;
 
@@ -1257,7 +1259,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
 
 	vector = cfg->vector;
 	for_each_cpu_and(cpu, cfg->domain, cpu_online_mask)
-		per_cpu(vector_irq, cpu)[vector] = -1;
+		per_cpu(vector_desc, cpu)[vector] = NULL;
 
 	cfg->vector = 0;
 	cpumask_clear(cfg->domain);
@@ -1267,18 +1269,18 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
 	for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
 		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
 								vector++) {
-			if (per_cpu(vector_irq, cpu)[vector] != irq)
+			if (per_cpu(vector_desc, cpu)[vector] != desc)
 				continue;
-			per_cpu(vector_irq, cpu)[vector] = -1;
+			per_cpu(vector_desc, cpu)[vector] = NULL;
 			break;
 		}
 	}
 	cfg->move_in_progress = 0;
 }
 
-void __setup_vector_irq(int cpu)
+void __setup_vector_desc(int cpu)
 {
-	/* Initialize vector_irq on a new cpu */
+	/* Initialize vector_desc on a new cpu */
 	int irq, vector;
 	struct irq_cfg *cfg;
 	struct irq_desc *desc;
@@ -1303,17 +1305,17 @@ void __setup_vector_irq(int cpu)
 		if (!cpumask_test_cpu(cpu, cfg->domain))
 			continue;
 		vector = cfg->vector;
-		per_cpu(vector_irq, cpu)[vector] = irq;
+		per_cpu(vector_desc, cpu)[vector] = desc;
 	}
 	/* Mark the free vectors */
 	for (vector = 0; vector < NR_VECTORS; ++vector) {
-		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq < 0)
+		desc = per_cpu(vector_desc, cpu)[vector];
+		if (!desc)
 			continue;
 
-		cfg = irq_cfg(irq);
+		cfg = desc->chip_data;
 		if (!cpumask_test_cpu(cpu, cfg->domain))
-			per_cpu(vector_irq, cpu)[vector] = -1;
+			per_cpu(vector_desc, cpu)[vector] = NULL;
 	}
 	raw_spin_unlock(&vector_lock);
 }
@@ -1473,7 +1475,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
 	if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain))
 		apic->vector_allocation_domain(0, cfg->domain);
 
-	if (assign_irq_vector(irq, cfg, apic->target_cpus()))
+	if (assign_irq_vector(desc, cfg, apic->target_cpus()))
 		return;
 
 	dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
@@ -1489,7 +1491,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
 			       dest, trigger, polarity, cfg->vector, pin)) {
 		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
 		       mp_ioapics[apic_id].apicid, pin);
-		__clear_irq_vector(irq, cfg);
+		__clear_irq_vector(desc, cfg);
 		return;
 	}
 
@@ -2386,14 +2388,12 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
 		  unsigned int *dest_id)
 {
 	struct irq_cfg *cfg;
-	unsigned int irq;
 
 	if (!cpumask_intersects(mask, cpu_online_mask))
 		return -1;
 
-	irq = desc->irq;
 	cfg = desc->chip_data;
-	if (assign_irq_vector(irq, cfg, mask))
+	if (assign_irq_vector(desc, cfg, mask))
 		return -1;
 
 	cpumask_copy(desc->affinity, mask);
@@ -2466,7 +2466,7 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 		return ret;
 
 	cfg = desc->chip_data;
-	if (assign_irq_vector(irq, cfg, mask))
+	if (assign_irq_vector(desc, cfg, mask))
 		return ret;
 
 	dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
@@ -2520,20 +2520,15 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
 
 	me = smp_processor_id();
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		unsigned int irq;
 		unsigned int irr;
 		struct irq_desc *desc;
 		struct irq_cfg *cfg;
-		irq = __get_cpu_var(vector_irq)[vector];
-
-		if (irq == -1)
-			continue;
+		desc = __get_cpu_var(vector_desc)[vector];
 
-		desc = irq_to_desc(irq);
 		if (!desc)
 			continue;
 
-		cfg = irq_cfg(irq);
+		cfg = desc->chip_data;
 		raw_spin_lock(&desc->lock);
 
 		/*
@@ -2558,7 +2553,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
 			apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
 			goto unlock;
 		}
-		__get_cpu_var(vector_irq)[vector] = -1;
+		__get_cpu_var(vector_desc)[vector] = NULL;
 unlock:
 		raw_spin_unlock(&desc->lock);
 	}
@@ -3001,7 +2996,7 @@ static inline void __init check_timer(void)
 	 * get/set the timer IRQ vector:
 	 */
 	legacy_pic->chip->mask(0);
-	assign_irq_vector(0, cfg, apic->target_cpus());
+	assign_irq_vector(desc, cfg, apic->target_cpus());
 
 	/*
 	 * As IRQ0 is to be enabled in the 8259A, the virtual
@@ -3331,7 +3326,7 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
 		desc_new = move_irq_desc(desc_new, node);
 		cfg_new = desc_new->chip_data;
 
-		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
+		if (__assign_irq_vector(desc_new, cfg_new, apic->target_cpus()) == 0)
 			irq = new;
 		break;
 	}
@@ -3361,12 +3356,16 @@ int create_irq(void)
 void destroy_irq(unsigned int irq)
 {
 	unsigned long flags;
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
 
 	dynamic_irq_cleanup_keep_chip_data(irq);
 
 	free_irte(irq);
 	raw_spin_lock_irqsave(&vector_lock, flags);
-	__clear_irq_vector(irq, get_irq_chip_data(irq));
+	desc = irq_to_desc(irq);
+	cfg = desc->chip_data;
+	__clear_irq_vector(desc, cfg);
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
 }
 
@@ -3377,6 +3376,7 @@ void destroy_irq(unsigned int irq)
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
 			   struct msi_msg *msg, u8 hpet_id)
 {
+	struct irq_desc *desc;
 	struct irq_cfg *cfg;
 	int err;
 	unsigned dest;
@@ -3384,8 +3384,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
 	if (disable_apic)
 		return -ENXIO;
 
-	cfg = irq_cfg(irq);
-	err = assign_irq_vector(irq, cfg, apic->target_cpus());
+	desc = irq_to_desc(irq);
+	cfg = desc->chip_data;
+	err = assign_irq_vector(desc, cfg, apic->target_cpus());
 	if (err)
 		return err;
 
@@ -3876,14 +3877,16 @@ static struct irq_chip ht_irq_chip = {
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 {
+	struct irq_desc *desc;
 	struct irq_cfg *cfg;
 	int err;
 
 	if (disable_apic)
 		return -ENXIO;
 
-	cfg = irq_cfg(irq);
-	err = assign_irq_vector(irq, cfg, apic->target_cpus());
+	desc = irq_to_desc(irq);
+	cfg = desc->chip_data;
+	err = assign_irq_vector(desc, cfg, apic->target_cpus());
 	if (!err) {
 		struct ht_irq_msg msg;
 		unsigned dest;
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 91fd0c7..f71625c 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -229,19 +229,19 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
 
 	/* high bit used in ret_from_ code  */
 	unsigned vector = ~regs->orig_ax;
-	unsigned irq;
+	struct irq_desc *desc;
 
 	exit_idle();
 	irq_enter();
 
-	irq = __get_cpu_var(vector_irq)[vector];
+	desc = __get_cpu_var(vector_desc)[vector];
 
-	if (!handle_irq(irq, regs)) {
+	if (!handle_irq(desc, regs)) {
 		ack_APIC_irq();
 
 		if (printk_ratelimit())
-			pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
-				__func__, smp_processor_id(), vector, irq);
+			pr_emerg("%s: %d.%d No irq handler for vector\n",
+				__func__, smp_processor_id(), vector);
 	}
 
 	irq_exit();
@@ -348,14 +348,13 @@ void fixup_irqs(void)
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
 		unsigned int irr;
 
-		if (__get_cpu_var(vector_irq)[vector] < 0)
+		if (__get_cpu_var(vector_desc)[vector] == NULL)
 			continue;
 
 		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
 		if (irr  & (1 << (vector % 32))) {
-			irq = __get_cpu_var(vector_irq)[vector];
+			desc = __get_cpu_var(vector_desc)[vector];
 
-			desc = irq_to_desc(irq);
 			raw_spin_lock(&desc->lock);
 			if (desc->chip->retrigger)
 				desc->chip->retrigger(irq);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 10709f2..f5daa3d 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -76,7 +76,7 @@ static void call_on_stack(void *func, void *stack)
 }
 
 static inline int
-execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq)
+execute_on_irq_stack(int overflow, struct irq_desc *desc, unsigned int irq)
 {
 	union irq_ctx *curctx, *irqctx;
 	u32 *isp, arg1, arg2;
@@ -189,20 +189,23 @@ asmlinkage void do_softirq(void)
 
 #else
 static inline int
-execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { return 0; }
+execute_on_irq_stack(int overflow, struct irq_desc *desc, unsigned int irq)
+{
+	 return 0;
+}
 #endif
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
 	int overflow;
+	unsigned int irq;
 
 	overflow = check_stack_overflow();
 
-	desc = irq_to_desc(irq);
 	if (unlikely(!desc))
 		return false;
 
+	irq = desc->irq;
 	if (!execute_on_irq_stack(overflow, desc, irq)) {
 		if (unlikely(overflow))
 			print_stack_overflow();
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index acf8fbf..5e6e493 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -48,17 +48,14 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 #endif
 }
 
-bool handle_irq(unsigned irq, struct pt_regs *regs)
+bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
 {
-	struct irq_desc *desc;
-
 	stack_overflow_check(regs);
 
-	desc = irq_to_desc(irq);
 	if (unlikely(!desc))
 		return false;
 
-	generic_handle_irq_desc(irq, desc);
+	generic_handle_irq_desc(desc->irq, desc);
 	return true;
 }
 
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index f01d390..7b77458 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -83,16 +83,14 @@ static struct irqaction irq2 = {
 	.name = "cascade",
 };
 
-DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
-	[0 ... NR_VECTORS - 1] = -1,
-};
+DEFINE_PER_CPU(vector_desc_t, vector_desc);
 
 int vector_used_by_percpu_irq(unsigned int vector)
 {
 	int cpu;
 
 	for_each_online_cpu(cpu) {
-		if (per_cpu(vector_irq, cpu)[vector] != -1)
+		if (per_cpu(vector_desc, cpu)[vector] != NULL)
 			return 1;
 	}
 
@@ -136,7 +134,7 @@ void __init init_IRQ(void)
 	 * irq's migrate etc.
 	 */
 	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
-		per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
+		per_cpu(vector_desc, 0)[IRQ0_VECTOR + i] = irq_to_desc(i);
 
 	x86_init.irqs.intr_init();
 }
@@ -144,7 +142,7 @@ void __init init_IRQ(void)
 /*
  * Setup the vector to irq mappings.
  */
-void setup_vector_irq(int cpu)
+void setup_vector_desc(int cpu)
 {
 #ifndef CONFIG_X86_IO_APIC
 	int irq;
@@ -157,10 +155,10 @@ void setup_vector_irq(int cpu)
 	 * legacy vector to irq mapping:
 	 */
 	for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
-		per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+		per_cpu(vector_desc, cpu)[IRQ0_VECTOR + irq] = irq_to_desc(irq);
 #endif
 
-	__setup_vector_irq(cpu);
+	__setup_vector_desc(cpu);
 }
 
 static void __init smp_intr_init(void)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ba43b3b..a1483ac 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -246,7 +246,7 @@ static void __cpuinit smp_callin(void)
 	/*
 	 * Need to setup vector mappings before we enable interrupts.
 	 */
-	setup_vector_irq(smp_processor_id());
+	setup_vector_desc(smp_processor_id());
 	/*
 	 * Get our bogomips.
 	 *
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index 4c61f1b..44c430d 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -158,7 +158,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
 
 	cfg = irq_cfg(irq);
 
-	err = assign_irq_vector(irq, cfg, eligible_cpu);
+	err = assign_irq_vector(desc, cfg, eligible_cpu);
 	if (err != 0)
 		return err;
 
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 5e1ff66..fb65235 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -236,7 +236,7 @@ void __init vmi_time_init(void)
 	vmi_time_init_clockevent();
 	setup_irq(0, &vmi_clock_action);
 	for_each_possible_cpu(cpu)
-		per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
+		per_cpu(vector_desc, cpu)[vmi_get_timer_vector()] = irq_to_desc(0);
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 8eb9eed..e0f6b26 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -819,7 +819,7 @@ static void __init lguest_init_IRQ(void)
 
 	for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
 		/* Some systems map "vectors" to interrupts weirdly.  Not us! */
-		__get_cpu_var(vector_irq)[i] = i - FIRST_EXTERNAL_VECTOR;
+		__get_cpu_var(vector_desc)[i] = irq_to_desc(i - FIRST_EXTERNAL_VECTOR);
 		if (i != SYSCALL_VECTOR)
 			set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
 	}
@@ -842,6 +842,11 @@ static void __init lguest_init_IRQ(void)
 void lguest_setup_irq(unsigned int irq)
 {
 	irq_to_desc_alloc_node(irq, 0);
+	/*
+	 *  for sparseirq, we could get new desc other than legacy irq,
+	 *  so set vector_desc again for that irq
+	 */
+	__get_cpu_var(vector_desc)[irq + FIRST_EXTERNAL_VECTOR] = irq_to_desc(irq);
 	set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
 				      handle_level_irq, "level");
 }
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 06/10] irq: Start the transition of irq_chip methods taking a desc
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (4 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 05/10] x86: use vector_desc instead of vector_irq Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 07/10] x86/irq: use irq_desc *desc with irq_chip Yinghai Lu
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

With SPARSE_IRQ irq_to_desc becomes an unnecessary lookup operation on
the fast path of dispatching irqs to their handlers.  We can avoid
this cost by passing an irq_desc pointer instead of using an integer
irq token to the irq_chip methods.

A single patch to convert all of the architectures is an unreviewable
2000+ line patch.  A gradual transition scenario with two sets of
irq_chip methods in irq_chip is an unmanageable mess in kernel/irq.

So instead I define some macros so the generic irq code in kernel/irq/
can compile either way based on a boolean Kconfig variable
CONFIG_CHIP_PARAM_DESC.  This allows us to convert one architecture at
a time, reducing the follow on patches to manageable proportions.  It
is a little bit ugly but it is much better than the alternatives, and
as soon as we finish the transition we can kill the macros.

I introduce the macros CHIP_ARG, CHIP_VAR, and CHIP_PARAM where
appropriate.  I change a few declarations of irq as int to unsigned
int.  I normalize the variables names in the functions that call
chip methods to ensure that I have the variables irq and desc present
allowing CHIP_ARG to work properly.  Most importantly none of the irq
logic changes with this patch.

-v2: add CHIP_VAR_IRQ

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/Kconfig           |    3 ++
 include/linux/irq.h    |   60 ++++++++++++++++++++++++++++-------------------
 kernel/irq/autoprobe.c |   39 ++++++++++++++++---------------
 kernel/irq/chip.c      |   40 ++++++++++++++++----------------
 kernel/irq/handle.c    |   18 +++++++-------
 kernel/irq/internals.h |    4 +-
 kernel/irq/manage.c    |   22 ++++++++--------
 kernel/irq/migration.c |   10 ++++----
 kernel/irq/pm.c        |    6 ++--
 kernel/irq/resend.c    |    5 ++-
 kernel/irq/spurious.c  |    4 +-
 11 files changed, 114 insertions(+), 97 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index f06010f..7331bbb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -2,6 +2,9 @@
 # General architecture dependent options
 #
 
+config CHIP_PARAM_DESC
+       def_bool n
+
 config OPROFILE
 	tristate "OProfile system profiling"
 	depends on PROFILING
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 60f3368..5a110a4 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -83,6 +83,18 @@ typedef	void (*irq_flow_handler_t)(unsigned int irq,
 struct proc_dir_entry;
 struct msi_desc;
 
+#ifdef CONFIG_CHIP_PARAM_DESC
+#define CHIP_PARAM struct irq_desc *desc
+#define CHIP_VAR
+#define CHIP_VAR_IRQ unsigned int irq = desc->irq;
+#define CHIP_ARG   desc
+#else
+#define CHIP_PARAM unsigned int irq
+#define CHIP_VAR   struct irq_desc *desc = irq_to_desc(irq);
+#define CHIP_VAR_IRQ
+#define CHIP_ARG   irq
+#endif
+
 /**
  * struct irq_chip - hardware interrupt chip descriptor
  *
@@ -110,30 +122,30 @@ struct msi_desc;
  */
 struct irq_chip {
 	const char	*name;
-	unsigned int	(*startup)(unsigned int irq);
-	void		(*shutdown)(unsigned int irq);
-	void		(*enable)(unsigned int irq);
-	void		(*disable)(unsigned int irq);
-
-	void		(*ack)(unsigned int irq);
-	void		(*mask)(unsigned int irq);
-	void		(*mask_ack)(unsigned int irq);
-	void		(*unmask)(unsigned int irq);
-	void		(*eoi)(unsigned int irq);
-
-	void		(*end)(unsigned int irq);
-	int		(*set_affinity)(unsigned int irq,
+	unsigned int	(*startup)(CHIP_PARAM);
+	void		(*shutdown)(CHIP_PARAM);
+	void		(*enable)(CHIP_PARAM);
+	void		(*disable)(CHIP_PARAM);
+
+	void		(*ack)(CHIP_PARAM);
+	void		(*mask)(CHIP_PARAM);
+	void		(*mask_ack)(CHIP_PARAM);
+	void		(*unmask)(CHIP_PARAM);
+	void		(*eoi)(CHIP_PARAM);
+
+	void		(*end)(CHIP_PARAM);
+	int		(*set_affinity)(CHIP_PARAM,
 					const struct cpumask *dest);
-	int		(*retrigger)(unsigned int irq);
-	int		(*set_type)(unsigned int irq, unsigned int flow_type);
-	int		(*set_wake)(unsigned int irq, unsigned int on);
+	int		(*retrigger)(CHIP_PARAM);
+	int		(*set_type)(CHIP_PARAM, unsigned int flow_type);
+	int		(*set_wake)(CHIP_PARAM, unsigned int on);
 
-	void		(*bus_lock)(unsigned int irq);
-	void		(*bus_sync_unlock)(unsigned int irq);
+	void		(*bus_lock)(CHIP_PARAM);
+	void		(*bus_sync_unlock)(CHIP_PARAM);
 
 	/* Currently used only by UML, might disappear one day.*/
 #ifdef CONFIG_IRQ_RELEASE_METHOD
-	void		(*release)(unsigned int irq, void *dev_id);
+	void		(*release)(CHIP_PARAM, void *dev_id);
 #endif
 	/*
 	 * For compatibility, ->typename is copied into ->name.
@@ -252,20 +264,20 @@ extern void remove_irq(unsigned int irq, struct irqaction *act);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 
-void move_native_irq(int irq);
-void move_masked_irq(int irq);
+void move_native_irq(unsigned int irq);
+void move_masked_irq(unsigned int irq);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ */
 
-static inline void move_irq(int irq)
+static inline void move_irq(unsigned int irq)
 {
 }
 
-static inline void move_native_irq(int irq)
+static inline void move_native_irq(unsigned int irq)
 {
 }
 
-static inline void move_masked_irq(int irq)
+static inline void move_masked_irq(unsigned int irq)
 {
 }
 
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 2295a31..2a8702f 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -33,7 +33,7 @@ unsigned long probe_irq_on(void)
 	struct irq_desc *desc;
 	unsigned long mask = 0;
 	unsigned int status;
-	int i;
+	unsigned int irq;
 
 	/*
 	 * quiesce the kernel, or at least the asynchronous portion
@@ -44,7 +44,7 @@ unsigned long probe_irq_on(void)
 	 * something may have generated an irq long ago and we want to
 	 * flush such a longstanding irq before considering it as spurious.
 	 */
-	for_each_irq_desc_reverse(i, desc) {
+	for_each_irq_desc_reverse(irq, desc) {
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
 			/*
@@ -58,8 +58,8 @@ unsigned long probe_irq_on(void)
 			 * progress:
 			 */
 			if (desc->chip->set_type)
-				desc->chip->set_type(i, IRQ_TYPE_PROBE);
-			desc->chip->startup(i);
+				desc->chip->set_type(CHIP_ARG, IRQ_TYPE_PROBE);
+			desc->chip->startup(CHIP_ARG);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -72,11 +72,11 @@ unsigned long probe_irq_on(void)
 	 * (we must startup again here because if a longstanding irq
 	 * happened in the previous stage, it may have masked itself)
 	 */
-	for_each_irq_desc_reverse(i, desc) {
+	for_each_irq_desc_reverse(irq, desc) {
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
 			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->chip->startup(i))
+			if (desc->chip->startup(CHIP_ARG))
 				desc->status |= IRQ_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
@@ -90,7 +90,7 @@ unsigned long probe_irq_on(void)
 	/*
 	 * Now filter out any obviously spurious interrupts
 	 */
-	for_each_irq_desc(i, desc) {
+	for_each_irq_desc(irq, desc) {
 		raw_spin_lock_irq(&desc->lock);
 		status = desc->status;
 
@@ -98,10 +98,10 @@ unsigned long probe_irq_on(void)
 			/* It triggered already - consider it spurious. */
 			if (!(status & IRQ_WAITING)) {
 				desc->status = status & ~IRQ_AUTODETECT;
-				desc->chip->shutdown(i);
+				desc->chip->shutdown(CHIP_ARG);
 			} else
-				if (i < 32)
-					mask |= 1 << i;
+				if (irq < 32)
+					mask |= 1 << irq;
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -126,18 +126,18 @@ unsigned int probe_irq_mask(unsigned long val)
 {
 	unsigned int status, mask = 0;
 	struct irq_desc *desc;
-	int i;
+	unsigned int irq;
 
-	for_each_irq_desc(i, desc) {
+	for_each_irq_desc(irq, desc) {
 		raw_spin_lock_irq(&desc->lock);
 		status = desc->status;
 
 		if (status & IRQ_AUTODETECT) {
-			if (i < 16 && !(status & IRQ_WAITING))
-				mask |= 1 << i;
+			if (irq < 16 && !(status & IRQ_WAITING))
+				mask |= 1 << irq;
 
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(CHIP_ARG);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -166,22 +166,23 @@ EXPORT_SYMBOL(probe_irq_mask);
  */
 int probe_irq_off(unsigned long val)
 {
-	int i, irq_found = 0, nr_of_irqs = 0;
+	int irq_found = 0, nr_of_irqs = 0;
 	struct irq_desc *desc;
 	unsigned int status;
+	unsigned int irq;
 
-	for_each_irq_desc(i, desc) {
+	for_each_irq_desc(irq, desc) {
 		raw_spin_lock_irq(&desc->lock);
 		status = desc->status;
 
 		if (status & IRQ_AUTODETECT) {
 			if (!(status & IRQ_WAITING)) {
 				if (!nr_of_irqs)
-					irq_found = i;
+					irq_found = irq;
 				nr_of_irqs++;
 			}
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(CHIP_ARG);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3dcdd2f..190360d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -287,40 +287,40 @@ EXPORT_SYMBOL_GPL(set_irq_nested_thread);
 /*
  * default enable function
  */
-static void default_enable(unsigned int irq)
+static void default_enable(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(CHIP_ARG);
 	desc->status &= ~IRQ_MASKED;
 }
 
 /*
  * default disable function
  */
-static void default_disable(unsigned int irq)
+static void default_disable(CHIP_PARAM)
 {
 }
 
 /*
  * default startup function
  */
-static unsigned int default_startup(unsigned int irq)
+static unsigned int default_startup(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR;
 
-	desc->chip->enable(irq);
+	desc->chip->enable(CHIP_ARG);
 	return 0;
 }
 
 /*
  * default shutdown function
  */
-static void default_shutdown(unsigned int irq)
+static void default_shutdown(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(CHIP_ARG);
 	desc->status |= IRQ_MASKED;
 }
 
@@ -353,11 +353,11 @@ void irq_chip_set_defaults(struct irq_chip *chip)
 static inline void mask_ack_irq(struct irq_desc *desc, int irq)
 {
 	if (desc->chip->mask_ack)
-		desc->chip->mask_ack(irq);
+		desc->chip->mask_ack(CHIP_ARG);
 	else {
-		desc->chip->mask(irq);
+		desc->chip->mask(CHIP_ARG);
 		if (desc->chip->ack)
-			desc->chip->ack(irq);
+			desc->chip->ack(CHIP_ARG);
 	}
 	desc->status |= IRQ_MASKED;
 }
@@ -365,7 +365,7 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
 static inline void mask_irq(struct irq_desc *desc, int irq)
 {
 	if (desc->chip->mask) {
-		desc->chip->mask(irq);
+		desc->chip->mask(CHIP_ARG);
 		desc->status |= IRQ_MASKED;
 	}
 }
@@ -373,7 +373,7 @@ static inline void mask_irq(struct irq_desc *desc, int irq)
 static inline void unmask_irq(struct irq_desc *desc, int irq)
 {
 	if (desc->chip->unmask) {
-		desc->chip->unmask(irq);
+		desc->chip->unmask(CHIP_ARG);
 		desc->status &= ~IRQ_MASKED;
 	}
 }
@@ -554,7 +554,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
 	raw_spin_lock(&desc->lock);
 	desc->status &= ~IRQ_INPROGRESS;
 out:
-	desc->chip->eoi(irq);
+	desc->chip->eoi(CHIP_ARG);
 
 	raw_spin_unlock(&desc->lock);
 }
@@ -597,7 +597,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 
 	/* Start handling the irq */
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(CHIP_ARG);
 
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
@@ -651,14 +651,14 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
 	kstat_incr_irqs_this_cpu(irq, desc);
 
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(CHIP_ARG);
 
 	action_ret = handle_IRQ_event(irq, desc->action);
 	if (!noirqdebug)
 		note_interrupt(irq, desc, action_ret);
 
 	if (desc->chip->eoi)
-		desc->chip->eoi(irq);
+		desc->chip->eoi(CHIP_ARG);
 }
 
 void
@@ -706,7 +706,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 		desc->status &= ~IRQ_DISABLED;
 		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
 		desc->depth = 0;
-		desc->chip->startup(irq);
+		desc->chip->startup(CHIP_ARG);
 	}
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	chip_bus_sync_unlock(irq, desc);
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index f30c9c7..9e4a0a0 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -295,22 +295,22 @@ void clear_kstat_irqs(struct irq_desc *desc)
  * What should we do if we get a hw irq event on an illegal vector?
  * Each architecture has to answer this themself.
  */
-static void ack_bad(unsigned int irq)
+static void ack_bad(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR;
 
-	print_irq_desc(irq, desc);
-	ack_bad_irq(irq);
+	print_irq_desc(desc->irq, desc);
+	ack_bad_irq(desc->irq);
 }
 
 /*
  * NOP functions
  */
-static void noop(unsigned int irq)
+static void noop(CHIP_PARAM)
 {
 }
 
-static unsigned int noop_ret(unsigned int irq)
+static unsigned int noop_ret(CHIP_PARAM)
 {
 	return 0;
 }
@@ -470,13 +470,13 @@ unsigned int __do_IRQ(unsigned int irq)
 			if (!noirqdebug)
 				note_interrupt(irq, desc, action_ret);
 		}
-		desc->chip->end(irq);
+		desc->chip->end(CHIP_ARG);
 		return 1;
 	}
 
 	raw_spin_lock(&desc->lock);
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(CHIP_ARG);
 	/*
 	 * REPLAY is when Linux resends an IRQ that was dropped earlier
 	 * WAITING is used by probe to mark irqs that are being tested
@@ -536,7 +536,7 @@ out:
 	 * The ->end() handler has to deal with interrupts which got
 	 * disabled while the handler was running.
 	 */
-	desc->chip->end(irq);
+	desc->chip->end(CHIP_ARG);
 	raw_spin_unlock(&desc->lock);
 
 	return 1;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index c63f3bc..2a9ec5e 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -44,13 +44,13 @@ extern void irq_set_thread_affinity(struct irq_desc *desc);
 static inline void chip_bus_lock(unsigned int irq, struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_lock))
-		desc->chip->bus_lock(irq);
+		desc->chip->bus_lock(CHIP_ARG);
 }
 
 static inline void chip_bus_sync_unlock(unsigned int irq, struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_sync_unlock))
-		desc->chip->bus_sync_unlock(irq);
+		desc->chip->bus_sync_unlock(CHIP_ARG);
 }
 
 /*
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 69a3d7b..706b320 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -118,7 +118,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 	if (desc->status & IRQ_MOVE_PCNTXT) {
-		if (!desc->chip->set_affinity(irq, cpumask)) {
+		if (!desc->chip->set_affinity(CHIP_ARG, cpumask)) {
 			cpumask_copy(desc->affinity, cpumask);
 			irq_set_thread_affinity(desc);
 		}
@@ -128,7 +128,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 		cpumask_copy(desc->pending_mask, cpumask);
 	}
 #else
-	if (!desc->chip->set_affinity(irq, cpumask)) {
+	if (!desc->chip->set_affinity(CHIP_ARG, cpumask)) {
 		cpumask_copy(desc->affinity, cpumask);
 		irq_set_thread_affinity(desc);
 	}
@@ -161,7 +161,7 @@ static int setup_affinity(unsigned int irq, struct irq_desc *desc)
 
 	cpumask_and(desc->affinity, cpu_online_mask, irq_default_affinity);
 set_affinity:
-	desc->chip->set_affinity(irq, desc->affinity);
+	desc->chip->set_affinity(CHIP_ARG, desc->affinity);
 
 	return 0;
 }
@@ -207,7 +207,7 @@ void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
 
 	if (!desc->depth++) {
 		desc->status |= IRQ_DISABLED;
-		desc->chip->disable(irq);
+		desc->chip->disable(CHIP_ARG);
 	}
 }
 
@@ -321,7 +321,7 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
 	int ret = -ENXIO;
 
 	if (desc->chip->set_wake)
-		ret = desc->chip->set_wake(irq, on);
+		ret = desc->chip->set_wake(CHIP_ARG, on);
 
 	return ret;
 }
@@ -425,7 +425,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 	}
 
 	/* caller masked out all except trigger mode flags */
-	ret = chip->set_type(irq, flags);
+	ret = chip->set_type(CHIP_ARG, flags);
 
 	if (ret)
 		pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
@@ -505,7 +505,7 @@ again:
 
 	if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
 		desc->status &= ~IRQ_MASKED;
-		desc->chip->unmask(irq);
+		desc->chip->unmask(CHIP_ARG);
 	}
 	raw_spin_unlock_irq(&desc->lock);
 	chip_bus_sync_unlock(irq, desc);
@@ -756,7 +756,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		if (!(desc->status & IRQ_NOAUTOEN)) {
 			desc->depth = 0;
 			desc->status &= ~IRQ_DISABLED;
-			desc->chip->startup(irq);
+			desc->chip->startup(CHIP_ARG);
 		} else
 			/* Undo nested disables: */
 			desc->depth = 1;
@@ -890,16 +890,16 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	/* Currently used only by UML, might disappear one day: */
 #ifdef CONFIG_IRQ_RELEASE_METHOD
 	if (desc->chip->release)
-		desc->chip->release(irq, dev_id);
+		desc->chip->release(CHIP_ARG, dev_id);
 #endif
 
 	/* If this was the last handler, shut down the IRQ line: */
 	if (!desc->action) {
 		desc->status |= IRQ_DISABLED;
 		if (desc->chip->shutdown)
-			desc->chip->shutdown(irq);
+			desc->chip->shutdown(CHIP_ARG);
 		else
-			desc->chip->disable(irq);
+			desc->chip->disable(CHIP_ARG);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 2419622..5821159 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -4,7 +4,7 @@
 
 #include "internals.h"
 
-void move_masked_irq(int irq)
+void move_masked_irq(unsigned int irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 
@@ -43,7 +43,7 @@ void move_masked_irq(int irq)
 	 */
 	if (likely(cpumask_any_and(desc->pending_mask, cpu_online_mask)
 		   < nr_cpu_ids))
-		if (!desc->chip->set_affinity(irq, desc->pending_mask)) {
+		if (!desc->chip->set_affinity(CHIP_ARG, desc->pending_mask)) {
 			cpumask_copy(desc->affinity, desc->pending_mask);
 			irq_set_thread_affinity(desc);
 		}
@@ -51,7 +51,7 @@ void move_masked_irq(int irq)
 	cpumask_clear(desc->pending_mask);
 }
 
-void move_native_irq(int irq)
+void move_native_irq(unsigned int irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 
@@ -61,8 +61,8 @@ void move_native_irq(int irq)
 	if (unlikely(desc->status & IRQ_DISABLED))
 		return;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(CHIP_ARG);
 	move_masked_irq(irq);
-	desc->chip->unmask(irq);
+	desc->chip->unmask(CHIP_ARG);
 }
 
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index 0d4005d..94767d1 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -23,7 +23,7 @@
 void suspend_device_irqs(void)
 {
 	struct irq_desc *desc;
-	int irq;
+	unsigned int irq;
 
 	for_each_irq_desc(irq, desc) {
 		unsigned long flags;
@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(suspend_device_irqs);
 void resume_device_irqs(void)
 {
 	struct irq_desc *desc;
-	int irq;
+	unsigned int irq;
 
 	for_each_irq_desc(irq, desc) {
 		unsigned long flags;
@@ -69,7 +69,7 @@ EXPORT_SYMBOL_GPL(resume_device_irqs);
 int check_wakeup_irqs(void)
 {
 	struct irq_desc *desc;
-	int irq;
+	unsigned int irq;
 
 	for_each_irq_desc(irq, desc)
 		if ((desc->status & IRQ_WAKEUP) && (desc->status & IRQ_PENDING))
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 090c376..dc9dff8 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -60,7 +60,7 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
 	/*
 	 * Make sure the interrupt is enabled, before resending it:
 	 */
-	desc->chip->enable(irq);
+	desc->chip->enable(CHIP_ARG);
 
 	/*
 	 * We do not resend level type interrupts. Level type
@@ -70,7 +70,8 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
 	if ((status & (IRQ_LEVEL | IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
 		desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY;
 
-		if (!desc->chip->retrigger || !desc->chip->retrigger(irq)) {
+		if (!desc->chip->retrigger ||
+		    !desc->chip->retrigger(CHIP_ARG)) {
 #ifdef CONFIG_HARDIRQS_SW_RESEND
 			/* Set it pending and activate the softirq: */
 			set_bit(irq, irqs_resend);
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 89fb90a..6cc2cb9 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -79,7 +79,7 @@ static int try_one_irq(int irq, struct irq_desc *desc)
 	 * IRQ controller clean up too
 	 */
 	if (work && desc->chip && desc->chip->end)
-		desc->chip->end(irq);
+		desc->chip->end(CHIP_ARG);
 	raw_spin_unlock(&desc->lock);
 
 	return ok;
@@ -254,7 +254,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
 		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
 		desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
 		desc->depth++;
-		desc->chip->disable(irq);
+		desc->chip->disable(CHIP_ARG);
 
 		mod_timer(&poll_spurious_irq_timer,
 			  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 07/10] x86/irq: use irq_desc *desc with irq_chip
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (5 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 06/10] irq: Start the transition of irq_chip methods taking a desc Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 08/10] genericirq: add set_irq_desc_chip/data Yinghai Lu
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

need to apply after eric's CHIP_PARAM_DESC patch

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/Kconfig                            |    1 +
 arch/x86/include/asm/hardirq.h              |    2 +-
 arch/x86/include/asm/hpet.h                 |    8 +-
 arch/x86/include/asm/hw_irq.h               |    1 -
 arch/x86/include/asm/i8259.h                |    2 +-
 arch/x86/kernel/apic/io_apic.c              |  153 +++++++++++----------------
 arch/x86/kernel/hpet.c                      |   16 ++--
 arch/x86/kernel/i8259.c                     |   31 +++---
 arch/x86/kernel/irq.c                       |   12 +-
 arch/x86/kernel/uv_irq.c                    |   15 ++--
 arch/x86/kernel/visws_quirks.c              |   29 +++---
 arch/x86/kernel/vmiclock_32.c               |    8 +-
 arch/x86/lguest/boot.c                      |    8 +-
 drivers/gpio/langwell_gpio.c                |   11 +-
 drivers/gpio/pca953x.c                      |   23 +++--
 drivers/gpio/timbgpio.c                     |   17 ++--
 drivers/infiniband/hw/ipath/ipath_iba6110.c |    2 +-
 drivers/mfd/ezx-pcap.c                      |   12 ++-
 drivers/mfd/twl4030-irq.c                   |   16 ++--
 drivers/mfd/wm831x-irq.c                    |   18 ++--
 drivers/misc/sgi-gru/grufile.c              |    2 +-
 drivers/pci/dmar.c                          |   20 ++--
 drivers/pci/htirq.c                         |   22 ++--
 drivers/pci/msi.c                           |   48 ++++-----
 drivers/xen/events.c                        |   22 ++--
 include/asm-generic/hardirq.h               |    4 +-
 include/linux/dmar.h                        |    8 +-
 include/linux/htirq.h                       |   11 +-
 include/linux/irq.h                         |    7 +-
 include/linux/msi.h                         |   13 +--
 kernel/irq/handle.c                         |    8 +-
 kernel/irq/internals.h                      |    7 +-
 kernel/irq/migration.c                      |   10 +-
 33 files changed, 279 insertions(+), 288 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 6a80bce..1b47c54 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -58,6 +58,7 @@ config X86
 	select ANON_INODES
 	select HAVE_ARCH_KMEMCHECK
 	select HAVE_USER_RETURN_NOTIFIER
+	select CHIP_PARAM_DESC
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 0f85764..9b4b8f3 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -44,7 +44,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 #define set_softirq_pending(x)	percpu_write(irq_stat.__softirq_pending, (x))
 #define or_softirq_pending(x)	percpu_or(irq_stat.__softirq_pending, (x))
 
-extern void ack_bad_irq(unsigned int irq);
+extern void ack_bad_irq(struct irq_desc *desc);
 
 extern u64 arch_irq_stat_cpu(unsigned int cpu);
 #define arch_irq_stat_cpu	arch_irq_stat_cpu
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 1d5c08a..16c2257 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -74,10 +74,10 @@ extern void hpet_disable(void);
 extern unsigned int hpet_readl(unsigned int a);
 extern void force_hpet_resume(void);
 
-extern void hpet_msi_unmask(unsigned int irq);
-extern void hpet_msi_mask(unsigned int irq);
-extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
-extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+extern void hpet_msi_unmask(struct irq_desc *);
+extern void hpet_msi_mask(struct irq_desc *);
+extern void hpet_msi_write(struct irq_desc *desc, struct msi_msg *msg);
+extern void hpet_msi_read(struct irq_desc *desc, struct msi_msg *msg);
 
 #ifdef CONFIG_PCI_MSI
 extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index d23cf94..2417e29 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -96,7 +96,6 @@ struct irq_cfg {
 	u8			move_in_progress : 1;
 };
 
-extern struct irq_cfg *irq_cfg(unsigned int);
 int assign_irq_vector(struct irq_desc *, struct irq_cfg *,
 			 const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 1655147..0b2ad6f 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -58,7 +58,7 @@ struct legacy_pic {
 	void (*mask_all)(void);
 	void (*restore_mask)(void);
 	void (*init)(int auto_eoi);
-	int (*irq_pending)(unsigned int irq);
+	int (*irq_pending)(struct irq_desc *desc);
 	void (*make_irq)(unsigned int irq);
 };
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index cd2f193..f908af5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -176,18 +176,6 @@ int __init arch_early_irq_init(void)
 }
 
 #ifdef CONFIG_SPARSE_IRQ
-struct irq_cfg *irq_cfg(unsigned int irq)
-{
-	struct irq_cfg *cfg = NULL;
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		cfg = desc->chip_data;
-
-	return cfg;
-}
-
 static struct irq_cfg *get_one_free_irq_cfg(int node)
 {
 	struct irq_cfg *cfg;
@@ -336,10 +324,6 @@ int arch_init_irq_desc(struct irq_desc *desc, int node,
 }
 
 #else
-struct irq_cfg *irq_cfg(unsigned int irq)
-{
-	return irq < nr_irqs ? irq_cfgx + irq : NULL;
-}
 
 void x86_copy_chip_data(struct irq_desc *old_desc,
 			   struct irq_desc *desc, int node)
@@ -619,16 +603,12 @@ static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void mask_IO_APIC_irq(unsigned int irq)
+static void mask_IO_APIC_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	mask_IO_APIC_irq_desc(desc);
 }
-static void unmask_IO_APIC_irq(unsigned int irq)
+static void unmask_IO_APIC_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	unmask_IO_APIC_irq_desc(desc);
 }
 
@@ -1497,7 +1477,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
 
 	ioapic_register_intr(irq, desc, trigger);
 	if (irq < legacy_pic->nr_legacy_irqs)
-		legacy_pic->chip->mask(irq);
+		legacy_pic->chip->mask(desc);
 
 	ioapic_write_entry(apic_id, pin, entry);
 }
@@ -2296,29 +2276,29 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(struct irq_desc *desc)
 {
 	int was_pending = 0;
 	unsigned long flags;
 	struct irq_cfg *cfg;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	if (irq < legacy_pic->nr_legacy_irqs) {
-		legacy_pic->chip->mask(irq);
-		if (legacy_pic->irq_pending(irq))
+	if (desc->irq < legacy_pic->nr_legacy_irqs) {
+		legacy_pic->chip->mask(desc);
+		if (legacy_pic->irq_pending(desc))
 			was_pending = 1;
 	}
-	cfg = irq_cfg(irq);
+	cfg = desc->chip_data;
 	__unmask_IO_APIC_irq(cfg);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return was_pending;
 }
 
-static int ioapic_retrigger_irq(unsigned int irq)
+static int ioapic_retrigger_irq(struct irq_desc *desc)
 {
 
-	struct irq_cfg *cfg = irq_cfg(irq);
+	struct irq_cfg *cfg = desc->chip_data;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&vector_lock, flags);
@@ -2427,12 +2407,8 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 }
 
 static int
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
+set_ioapic_affinity_irq(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-
 	return set_ioapic_affinity_irq_desc(desc, mask);
 }
 
@@ -2495,11 +2471,9 @@ static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
 {
 	return migrate_ioapic_irq_desc(desc, mask);
 }
-static int set_ir_ioapic_affinity_irq(unsigned int irq,
+static int set_ir_ioapic_affinity_irq(struct irq_desc *desc,
 				       const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	return set_ir_ioapic_affinity_irq_desc(desc, mask);
 }
 #else
@@ -2592,12 +2566,10 @@ void irq_force_complete_move(int irq)
 static inline void irq_complete_move(struct irq_desc **descp) {}
 #endif
 
-static void ack_apic_edge(unsigned int irq)
+static void ack_apic_edge(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	irq_complete_move(&desc);
-	move_native_irq(irq);
+	move_native_irq(desc);
 	ack_APIC_irq();
 }
 
@@ -2656,9 +2628,8 @@ static void eoi_ioapic_irq(struct irq_desc *desc)
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void ack_apic_level(unsigned int irq)
+static void ack_apic_level(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long v;
 	int i;
 	struct irq_cfg *cfg;
@@ -2758,21 +2729,19 @@ static void ack_apic_level(unsigned int irq)
 		 */
 		cfg = desc->chip_data;
 		if (!io_apic_level_ack_pending(cfg))
-			move_masked_irq(irq);
+			move_masked_irq(desc);
 		unmask_IO_APIC_irq_desc(desc);
 	}
 }
 
 #ifdef CONFIG_INTR_REMAP
-static void ir_ack_apic_edge(unsigned int irq)
+static void ir_ack_apic_edge(struct irq_desc *desc)
 {
 	ack_APIC_irq();
 }
 
-static void ir_ack_apic_level(unsigned int irq)
+static void ir_ack_apic_level(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	ack_APIC_irq();
 	eoi_ioapic_irq(desc);
 }
@@ -2850,7 +2819,7 @@ static inline void init_IO_APIC_traps(void)
  * The local APIC irq-chip implementation:
  */
 
-static void mask_lapic_irq(unsigned int irq)
+static void mask_lapic_irq(struct irq_desc *desc)
 {
 	unsigned long v;
 
@@ -2858,7 +2827,7 @@ static void mask_lapic_irq(unsigned int irq)
 	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
-static void unmask_lapic_irq(unsigned int irq)
+static void unmask_lapic_irq(struct irq_desc *desc)
 {
 	unsigned long v;
 
@@ -2866,7 +2835,7 @@ static void unmask_lapic_irq(unsigned int irq)
 	apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
-static void ack_lapic_irq(unsigned int irq)
+static void ack_lapic_irq(struct irq_desc *desc)
 {
 	ack_APIC_irq();
 }
@@ -2995,7 +2964,7 @@ static inline void __init check_timer(void)
 	/*
 	 * get/set the timer IRQ vector:
 	 */
-	legacy_pic->chip->mask(0);
+	legacy_pic->chip->mask(desc);
 	assign_irq_vector(desc, cfg, apic->target_cpus());
 
 	/*
@@ -3067,7 +3036,7 @@ static inline void __init check_timer(void)
 		if (timer_irq_works()) {
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->chip->unmask(desc);
 			}
 			if (disable_timer_pin_1 > 0)
 				clear_IO_APIC_pin(apic1, pin1);
@@ -3090,14 +3059,14 @@ static inline void __init check_timer(void)
 		 */
 		replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
 		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
-		legacy_pic->chip->unmask(0);
+		legacy_pic->chip->unmask(desc);
 		if (timer_irq_works()) {
 			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
 			timer_through_8259 = 1;
 			if (nmi_watchdog == NMI_IO_APIC) {
-				legacy_pic->chip->mask(0);
+				legacy_pic->chip->mask(desc);
 				setup_nmi();
-				legacy_pic->chip->unmask(0);
+				legacy_pic->chip->unmask(desc);
 			}
 			goto out;
 		}
@@ -3105,7 +3074,7 @@ static inline void __init check_timer(void)
 		 * Cleanup, just in case ...
 		 */
 		local_irq_disable();
-		legacy_pic->chip->mask(0);
+		legacy_pic->chip->mask(desc);
 		clear_IO_APIC_pin(apic2, pin2);
 		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
 	}
@@ -3124,14 +3093,14 @@ static inline void __init check_timer(void)
 
 	lapic_register_intr(0, desc);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
-	legacy_pic->chip->unmask(0);
+	legacy_pic->chip->unmask(desc);
 
 	if (timer_irq_works()) {
 		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
 		goto out;
 	}
 	local_irq_disable();
-	legacy_pic->chip->mask(0);
+	legacy_pic->chip->mask(desc);
 	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
 	apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
 
@@ -3373,10 +3342,10 @@ void destroy_irq(unsigned int irq)
  * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
+static int msi_compose_msg(struct pci_dev *pdev, struct irq_desc *desc,
 			   struct msi_msg *msg, u8 hpet_id)
 {
-	struct irq_desc *desc;
+	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg;
 	int err;
 	unsigned dest;
@@ -3384,7 +3353,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
 	if (disable_apic)
 		return -ENXIO;
 
-	desc = irq_to_desc(irq);
 	cfg = desc->chip_data;
 	err = assign_irq_vector(desc, cfg, apic->target_cpus());
 	if (err)
@@ -3452,9 +3420,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
 }
 
 #ifdef CONFIG_SMP
-static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_cfg *cfg;
 	struct msi_msg msg;
 	unsigned int dest;
@@ -3464,14 +3432,14 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
 
 	cfg = desc->chip_data;
 
-	read_msi_msg_desc(desc, &msg);
+	read_msi_msg(desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	write_msi_msg_desc(desc, &msg);
+	write_msi_msg(desc, &msg);
 
 	return 0;
 }
@@ -3481,9 +3449,9 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
  * done in the process context using interrupt-remapping hardware.
  */
 static int
-ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+ir_set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg = desc->chip_data;
 	unsigned int dest;
 	struct irte irte;
@@ -3581,16 +3549,16 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 {
 	int ret;
 	struct msi_msg msg;
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	ret = msi_compose_msg(dev, irq, &msg, -1);
+	ret = msi_compose_msg(dev, desc, &msg, -1);
 	if (ret < 0)
 		return ret;
 
 	set_irq_msi(irq, msidesc);
-	write_msi_msg(irq, &msg);
+	write_msi_msg(desc, &msg);
 
 	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
 		/*
 		 * irq migration in process context
 		 */
@@ -3672,9 +3640,9 @@ void arch_teardown_msi_irq(unsigned int irq)
 
 #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
 #ifdef CONFIG_SMP
-static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+dmar_msi_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_cfg *cfg;
 	struct msi_msg msg;
 	unsigned int dest;
@@ -3684,14 +3652,14 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 	cfg = desc->chip_data;
 
-	dmar_msi_read(irq, &msg);
+	dmar_msi_read(desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	dmar_msi_write(irq, &msg);
+	dmar_msi_write(desc, &msg);
 
 	return 0;
 }
@@ -3716,11 +3684,12 @@ int arch_setup_dmar_msi(unsigned int irq)
 {
 	int ret;
 	struct msi_msg msg;
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	ret = msi_compose_msg(NULL, irq, &msg, -1);
+	ret = msi_compose_msg(NULL, desc, &msg, -1);
 	if (ret < 0)
 		return ret;
-	dmar_msi_write(irq, &msg);
+	dmar_msi_write(desc, &msg);
 	set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
 		"edge");
 	return 0;
@@ -3730,9 +3699,9 @@ int arch_setup_dmar_msi(unsigned int irq)
 #ifdef CONFIG_HPET_TIMER
 
 #ifdef CONFIG_SMP
-static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+hpet_msi_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_cfg *cfg;
 	struct msi_msg msg;
 	unsigned int dest;
@@ -3742,14 +3711,14 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 	cfg = desc->chip_data;
 
-	hpet_msi_read(irq, &msg);
+	hpet_msi_read(desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
-	hpet_msi_write(irq, &msg);
+	hpet_msi_write(desc, &msg);
 
 	return 0;
 }
@@ -3804,11 +3773,11 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 			return -1;
 	}
 
-	ret = msi_compose_msg(NULL, irq, &msg, id);
+	ret = msi_compose_msg(NULL, desc, &msg, id);
 	if (ret < 0)
 		return ret;
 
-	hpet_msi_write(irq, &msg);
+	hpet_msi_write(desc, &msg);
 	desc->status |= IRQ_MOVE_PCNTXT;
 	if (irq_remapped(irq))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
@@ -3829,10 +3798,10 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 
 #ifdef CONFIG_SMP
 
-static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
+static void target_ht_irq(struct irq_desc *desc, unsigned int dest, u8 vector)
 {
 	struct ht_irq_msg msg;
-	fetch_ht_irq_msg(irq, &msg);
+	fetch_ht_irq_msg(desc, &msg);
 
 	msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
 	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
@@ -3840,12 +3809,12 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
 	msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
 	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
 
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(desc, &msg);
 }
 
-static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+set_ht_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_cfg *cfg;
 	unsigned int dest;
 
@@ -3854,7 +3823,7 @@ static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
 
 	cfg = desc->chip_data;
 
-	target_ht_irq(irq, dest, cfg->vector);
+	target_ht_irq(desc, dest, cfg->vector);
 
 	return 0;
 }
@@ -3909,7 +3878,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 				HT_IRQ_LOW_MT_ARBITRATED) |
 			HT_IRQ_LOW_IRQ_MASKED;
 
-		write_ht_irq_msg(irq, &msg);
+		write_ht_irq_msg(desc, &msg);
 
 		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
 					      handle_edge_irq, "edge");
@@ -4399,7 +4368,7 @@ void __init pre_init_apic_IRQ0(void)
 
 	setup_local_APIC();
 
-	cfg = irq_cfg(0);
+	cfg = desc->chip_data;
 	add_pin_to_irq_node(cfg, 0, 0, 0);
 	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ee4fa1b..3355b99 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -426,9 +426,9 @@ static int hpet_legacy_next_event(unsigned long delta,
 static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
 static struct hpet_dev	*hpet_devs;
 
-void hpet_msi_unmask(unsigned int irq)
+void hpet_msi_unmask(struct irq_desc *desc)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = get_irq_desc_data(desc);
 	unsigned int cfg;
 
 	/* unmask it */
@@ -437,10 +437,10 @@ void hpet_msi_unmask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_mask(unsigned int irq)
+void hpet_msi_mask(struct irq_desc *desc)
 {
 	unsigned int cfg;
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = get_irq_desc_data(desc);
 
 	/* mask it */
 	cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -448,17 +448,17 @@ void hpet_msi_mask(unsigned int irq)
 	hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
 }
 
-void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_write(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = get_irq_desc_data(desc);
 
 	hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
 	hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
 }
 
-void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+void hpet_msi_read(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct hpet_dev *hdev = get_irq_data(irq);
+	struct hpet_dev *hdev = get_irq_desc_data(desc);
 
 	msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
 	msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index fb725ee..b248555 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -33,13 +33,13 @@
 
 static int i8259A_auto_eoi;
 DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void mask_and_ack_8259A(unsigned int);
+static void mask_and_ack_8259A(struct irq_desc *desc);
 static void mask_8259A(void);
 static void unmask_8259A(void);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
+static void disable_8259A_irq(struct irq_desc *desc);
+static void enable_8259A_irq(struct irq_desc *desc);
 static void init_8259A(int auto_eoi);
-static int i8259A_irq_pending(unsigned int irq);
+static int i8259A_irq_pending(struct irq_desc *desc);
 
 struct irq_chip i8259A_chip = {
 	.name		= "XT-PIC",
@@ -69,8 +69,9 @@ unsigned int cached_irq_mask = 0xffff;
  */
 unsigned long io_apic_irqs;
 
-static void disable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
 
@@ -83,8 +84,9 @@ static void disable_8259A_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static void enable_8259A_irq(unsigned int irq)
+static void enable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
 
@@ -97,8 +99,9 @@ static void enable_8259A_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-static int i8259A_irq_pending(unsigned int irq)
+static int i8259A_irq_pending(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1<<irq;
 	unsigned long flags;
 	int ret;
@@ -151,8 +154,9 @@ static inline int i8259A_irq_real(unsigned int irq)
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static void mask_and_ack_8259A(unsigned int irq)
+static void mask_and_ack_8259A(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irqmask = 1 << irq;
 	unsigned long flags;
 
@@ -372,17 +376,18 @@ static void init_8259A(int auto_eoi)
  */
 
 static void legacy_pic_noop(void) { };
+static void legacy_pic_desc_noop(struct irq_desc *desc) { };
 static void legacy_pic_uint_noop(unsigned int unused) { };
 static void legacy_pic_int_noop(int unused) { };
 
 static struct irq_chip dummy_pic_chip  = {
 	.name = "dummy pic",
-	.mask = legacy_pic_uint_noop,
-	.unmask = legacy_pic_uint_noop,
-	.disable = legacy_pic_uint_noop,
-	.mask_ack = legacy_pic_uint_noop,
+	.mask = legacy_pic_desc_noop,
+	.unmask = legacy_pic_desc_noop,
+	.disable = legacy_pic_desc_noop,
+	.mask_ack = legacy_pic_desc_noop,
 };
-static int legacy_pic_irq_pending_noop(unsigned int irq)
+static int legacy_pic_irq_pending_noop(struct irq_desc *desc)
 {
 	return 0;
 }
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index f71625c..ae70844 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -24,10 +24,10 @@ void (*x86_platform_ipi_callback)(void) = NULL;
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
  */
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	if (printk_ratelimit())
-		pr_err("unexpected IRQ trap at vector %02x\n", irq);
+		pr_err("unexpected IRQ trap at irq %02x\n", desc->irq);
 
 	/*
 	 * Currently unexpected vectors happen only on SMP and APIC.
@@ -316,15 +316,15 @@ void fixup_irqs(void)
 		}
 
 		if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->mask)
-			desc->chip->mask(irq);
+			desc->chip->mask(desc);
 
 		if (desc->chip->set_affinity)
-			desc->chip->set_affinity(irq, affinity);
+			desc->chip->set_affinity(desc, affinity);
 		else if (!(warned++))
 			set_affinity = 0;
 
 		if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask)
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 
 		raw_spin_unlock(&desc->lock);
 
@@ -357,7 +357,7 @@ void fixup_irqs(void)
 
 			raw_spin_lock(&desc->lock);
 			if (desc->chip->retrigger)
-				desc->chip->retrigger(irq);
+				desc->chip->retrigger(desc);
 			raw_spin_unlock(&desc->lock);
 		}
 	}
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index 44c430d..ed4ce50 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -27,18 +27,18 @@ struct uv_irq_2_mmr_pnode{
 static spinlock_t		uv_irq_lock;
 static struct rb_root		uv_irq_root;
 
-static int uv_set_irq_affinity(unsigned int, const struct cpumask *);
+static int uv_set_irq_affinity(struct irq_desc *desc, const struct cpumask *);
 
-static void uv_noop(unsigned int irq)
+static void uv_noop(struct irq_desc *desc)
 {
 }
 
-static unsigned int uv_noop_ret(unsigned int irq)
+static unsigned int uv_noop_ret(struct irq_desc *desc)
 {
 	return 0;
 }
 
-static void uv_ack_apic(unsigned int irq)
+static void uv_ack_apic(struct irq_desc *desc)
 {
 	ack_APIC_irq();
 }
@@ -156,7 +156,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
 	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
 			sizeof(unsigned long));
 
-	cfg = irq_cfg(irq);
+	cfg = desc->chip_data;
 
 	err = assign_irq_vector(desc, cfg, eligible_cpu);
 	if (err != 0)
@@ -208,9 +208,10 @@ static void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset)
 	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
 }
 
-static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int
+uv_set_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg = desc->chip_data;
 	unsigned int dest;
 	unsigned long mmr_value;
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index e680ea5..8bd5075 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -430,14 +430,15 @@ static int is_co_apic(unsigned int irq)
  * This is the SGI Cobalt (IO-)APIC:
  */
 
-static void enable_cobalt_irq(unsigned int irq)
+static void enable_cobalt_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	co_apic_set(is_co_apic(irq), irq);
 }
 
-static void disable_cobalt_irq(unsigned int irq)
+static void disable_cobalt_irq(struct irq_desc *desc)
 {
-	int entry = is_co_apic(irq);
+	int entry = is_co_apic(desc->irq);
 
 	co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
 	co_apic_read(CO_APIC_LO(entry));
@@ -448,37 +449,35 @@ static void disable_cobalt_irq(unsigned int irq)
  * map this to the Cobalt APIC entry where it's physically wired.
  * This is called via request_irq -> setup_irq -> irq_desc->startup()
  */
-static unsigned int startup_cobalt_irq(unsigned int irq)
+static unsigned int startup_cobalt_irq(struct irq_desc *desc)
 {
 	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
 
 	spin_lock_irqsave(&cobalt_lock, flags);
 	if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
 		desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
-	enable_cobalt_irq(irq);
+	enable_cobalt_irq(desc);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 	return 0;
 }
 
-static void ack_cobalt_irq(unsigned int irq)
+static void ack_cobalt_irq(struct irq_desc *desc)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	disable_cobalt_irq(irq);
+	disable_cobalt_irq(desc);
 	apic_write(APIC_EOI, APIC_EIO_ACK);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static void end_cobalt_irq(unsigned int irq)
+static void end_cobalt_irq(struct irq_desc *desc)
 {
 	unsigned long flags;
-	struct irq_desc *desc = irq_to_desc(irq);
 
 	spin_lock_irqsave(&cobalt_lock, flags);
 	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_cobalt_irq(irq);
+		enable_cobalt_irq(desc);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
@@ -503,19 +502,19 @@ static struct irq_chip cobalt_irq_type = {
  * interrupt controller type, and through a special virtual interrupt-
  * controller. Device drivers only see the virtual interrupt sources.
  */
-static unsigned int startup_piix4_master_irq(unsigned int irq)
+static unsigned int startup_piix4_master_irq(struct irq_desc *desc)
 {
 	legacy_pic->init(0);
 
-	return startup_cobalt_irq(irq);
+	return startup_cobalt_irq(desc);
 }
 
-static void end_piix4_master_irq(unsigned int irq)
+static void end_piix4_master_irq(struct irq_desc *desc)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&cobalt_lock, flags);
-	enable_cobalt_irq(irq);
+	enable_cobalt_irq(desc);
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index fb65235..41257f6 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -84,7 +84,7 @@ static inline unsigned int vmi_get_timer_vector(void)
 
 /** vmi clockchip */
 #ifdef CONFIG_X86_LOCAL_APIC
-static unsigned int startup_timer_irq(unsigned int irq)
+static unsigned int startup_timer_irq(struct irq_desc *desc)
 {
 	unsigned long val = apic_read(APIC_LVTT);
 	apic_write(APIC_LVTT, vmi_get_timer_vector());
@@ -92,19 +92,19 @@ static unsigned int startup_timer_irq(unsigned int irq)
 	return (val & APIC_SEND_PENDING);
 }
 
-static void mask_timer_irq(unsigned int irq)
+static void mask_timer_irq(struct irq_desc *desc)
 {
 	unsigned long val = apic_read(APIC_LVTT);
 	apic_write(APIC_LVTT, val | APIC_LVT_MASKED);
 }
 
-static void unmask_timer_irq(unsigned int irq)
+static void unmask_timer_irq(struct irq_desc *desc)
 {
 	unsigned long val = apic_read(APIC_LVTT);
 	apic_write(APIC_LVTT, val & ~APIC_LVT_MASKED);
 }
 
-static void ack_timer_irq(unsigned int irq)
+static void ack_timer_irq(struct irq_desc *desc)
 {
 	ack_APIC_irq();
 }
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index e0f6b26..be7a653 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -789,14 +789,14 @@ static void lguest_flush_tlb_kernel(void)
  * simple as setting a bit.  We don't actually "ack" interrupts as such, we
  * just mask and unmask them.  I wonder if we should be cleverer?
  */
-static void disable_lguest_irq(unsigned int irq)
+static void disable_lguest_irq(struct irq_desc *desc)
 {
-	set_bit(irq, lguest_data.blocked_interrupts);
+	set_bit(desc->irq, lguest_data.blocked_interrupts);
 }
 
-static void enable_lguest_irq(unsigned int irq)
+static void enable_lguest_irq(struct irq_desc *desc)
 {
-	clear_bit(irq, lguest_data.blocked_interrupts);
+	clear_bit(desc->irq, lguest_data.blocked_interrupts);
 }
 
 /* This structure describes the lguest IRQ controller. */
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 6c0ebbd..9283da1 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -113,9 +113,10 @@ static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 	return lnw->irq_base + offset;
 }
 
-static int lnw_irq_type(unsigned irq, unsigned type)
+static int lnw_irq_type(CHIP_PARAM, unsigned type)
 {
-	struct lnw_gpio *lnw = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct lnw_gpio *lnw = get_irq_desc_chip_data(desc);
 	u32 gpio = irq - lnw->irq_base;
 	u8 reg = gpio / 32;
 	unsigned long flags;
@@ -142,11 +143,11 @@ static int lnw_irq_type(unsigned irq, unsigned type)
 	return 0;
 };
 
-static void lnw_irq_unmask(unsigned irq)
+static void lnw_irq_unmask(CHIP_PARAM)
 {
 };
 
-static void lnw_irq_mask(unsigned irq)
+static void lnw_irq_mask(CHIP_PARAM)
 {
 };
 
@@ -184,7 +185,7 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
 		/* clear the edge detect status bit */
 		writel(gedr_v, gedr);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(CHIP_ARG);
 }
 
 static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index ab5daab..ed615c0 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -227,37 +227,40 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
 	return chip->irq_base + off;
 }
 
-static void pca953x_irq_mask(unsigned int irq)
+static void pca953x_irq_mask(struct irq_desc *desc)
 {
-	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct pca953x_chip *chip = get_irq_desc_chip_data(desc);
 
 	chip->irq_mask &= ~(1 << (irq - chip->irq_base));
 }
 
-static void pca953x_irq_unmask(unsigned int irq)
+static void pca953x_irq_unmask(struct irq_desc *desc)
 {
-	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct pca953x_chip *chip = get_irq_desc_chip_data(desc);
 
 	chip->irq_mask |= 1 << (irq - chip->irq_base);
 }
 
-static void pca953x_irq_bus_lock(unsigned int irq)
+static void pca953x_irq_bus_lock(struct irq_desc *desc)
 {
-	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	CHIP_VAR struct pca953x_chip *chip = get_irq_desc_chip_data(desc);
 
 	mutex_lock(&chip->irq_lock);
 }
 
-static void pca953x_irq_bus_sync_unlock(unsigned int irq)
+static void pca953x_irq_bus_sync_unlock(struct irq_desc *desc)
 {
-	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	CHIP_VAR struct pca953x_chip *chip = get_irq_desc_chip_data(desc);
 
 	mutex_unlock(&chip->irq_lock);
 }
 
-static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
+static int pca953x_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
-	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct pca953x_chip *chip = get_irq_desc_chip_data(desc);
 	uint16_t level = irq - chip->irq_base;
 	uint16_t mask = 1 << level;
 
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index d4295fa..83160dc 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -107,25 +107,28 @@ static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
 /*
  * GPIO IRQ
  */
-static void timbgpio_irq_disable(unsigned irq)
+static void timbgpio_irq_disable(CHIP_PARAM)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct timbgpio *tgpio = get_irq_desc_chip_data(desc);
 	int offset = irq - tgpio->irq_base;
 
 	timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 0);
 }
 
-static void timbgpio_irq_enable(unsigned irq)
+static void timbgpio_irq_enable(struct irq_desc *desc)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct timbgpio *tgpio = get_irq_desc_chip_data(desc);
 	int offset = irq - tgpio->irq_base;
 
 	timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 1);
 }
 
-static int timbgpio_irq_type(unsigned irq, unsigned trigger)
+static int timbgpio_irq_type(CHIP_PARAM, unsigned trigger)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct timbgpio *tgpio = get_irq_desc_chip_data(desc);
 	int offset = irq - tgpio->irq_base;
 	unsigned long flags;
 	u32 lvr, flr, bflr = 0;
@@ -185,7 +188,7 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
 	unsigned long ipr;
 	int offset;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(CHIP_ARG);
 	ipr = ioread32(tgpio->membase + TGPIO_IPR);
 	iowrite32(ipr, tgpio->membase + TGPIO_ICR);
 
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 37d12e5..4cbae45 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -986,7 +986,7 @@ static int ipath_ht_intconfig(struct ipath_devdata *dd)
 	return ret;
 }
 
-static void ipath_ht_irq_update(struct pci_dev *dev, int irq,
+static void ipath_ht_irq_update(struct pci_dev *dev, struct irq_desc *desc,
 				struct ht_irq_msg *msg)
 {
 	struct ipath_devdata *dd = pci_get_drvdata(dev);
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index df405af..f63bb23 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -143,17 +143,19 @@ int pcap_to_irq(struct pcap_chip *pcap, int irq)
 }
 EXPORT_SYMBOL_GPL(pcap_to_irq);
 
-static void pcap_mask_irq(unsigned int irq)
+static void pcap_mask_irq(CHIP_PARAM)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct pcap_chip *pcap = get_irq_desc_chip_data(desc);
 
 	pcap->msr |= 1 << irq_to_pcap(pcap, irq);
 	queue_work(pcap->workqueue, &pcap->msr_work);
 }
 
-static void pcap_unmask_irq(unsigned int irq)
+static void pcap_unmask_irq(CHIP_PARAM)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct pcap_chip *pcap = get_irq_desc_chip_data(desc);
 
 	pcap->msr &= ~(1 << irq_to_pcap(pcap, irq));
 	queue_work(pcap->workqueue, &pcap->msr_work);
@@ -217,7 +219,7 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	struct pcap_chip *pcap = get_irq_data(irq);
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 	queue_work(pcap->workqueue, &pcap->isr_work);
 	return;
 }
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 9df9a5a..3e69ad3 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -595,9 +595,10 @@ static void twl4030_sih_do_edge(struct work_struct *work)
  * completion, potentially including some re-ordering, of these requests.
  */
 
-static void twl4030_sih_mask(unsigned irq)
+static void twl4030_sih_mask(CHIP_PARAM)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct sih_agent *sih = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&sih_agent_lock, flags);
@@ -607,9 +608,10 @@ static void twl4030_sih_mask(unsigned irq)
 	spin_unlock_irqrestore(&sih_agent_lock, flags);
 }
 
-static void twl4030_sih_unmask(unsigned irq)
+static void twl4030_sih_unmask(CHIP_PARAM)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct sih_agent *sih = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&sih_agent_lock, flags);
@@ -619,10 +621,10 @@ static void twl4030_sih_unmask(unsigned irq)
 	spin_unlock_irqrestore(&sih_agent_lock, flags);
 }
 
-static int twl4030_sih_set_type(unsigned irq, unsigned trigger)
+static int twl4030_sih_set_type(CHIP_PARAM, unsigned trigger)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct sih_agent *sih = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	if (!desc) {
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 3013276..eac701e 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -346,16 +346,16 @@ static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
 	return &wm831x_irqs[irq - wm831x->irq_base];
 }
 
-static void wm831x_irq_lock(unsigned int irq)
+static void wm831x_irq_lock(CHIP_PARAM)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	CHIP_VAR struct wm831x *wm831x = get_irq_desc_chip_data(desc);
 
 	mutex_lock(&wm831x->irq_lock);
 }
 
-static void wm831x_irq_sync_unlock(unsigned int irq)
+static void wm831x_irq_sync_unlock(CHIP_PARAM
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	CHIP_VAR struct wm831x *wm831x = get_irq_desc_chip_data(desc);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
@@ -372,17 +372,19 @@ static void wm831x_irq_sync_unlock(unsigned int irq)
 	mutex_unlock(&wm831x->irq_lock);
 }
 
-static void wm831x_irq_unmask(unsigned int irq)
+static void wm831x_irq_unmask(CHIP_PARAM)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct wm831x *wm831x = get_irq_desc_chip_data(desc);
 	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
 	wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
 }
 
-static void wm831x_irq_mask(unsigned int irq)
+static void wm831x_irq_mask(CHIP_PARAM)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	CHIP_VAR_IRQ
+	CHIP_VAR struct wm831x *wm831x = get_irq_desc_chip_data(desc);
 	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
 	wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index cb3b4d2..71aed9f 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -348,7 +348,7 @@ static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep)
 
 static int gru_irq_count[GRU_CHIPLETS_PER_BLADE];
 
-static void gru_noop(unsigned int irq)
+static void gru_noop(CHIP_PARAM)
 {
 }
 
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 83aae47..00b6aee 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1230,9 +1230,10 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
 	}
 }
 
-void dmar_msi_unmask(unsigned int irq)
+void dmar_msi_unmask(CHIP_PARAM)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	CHIP_VAR
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	/* unmask it */
@@ -1243,10 +1244,11 @@ void dmar_msi_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
-void dmar_msi_mask(unsigned int irq)
+void dmar_msi_mask(CHIP_PARAM)
 {
+	CHIP_VAR
 	unsigned long flag;
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 
 	/* mask it */
 	spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1256,9 +1258,10 @@ void dmar_msi_mask(unsigned int irq)
 	spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
-void dmar_msi_write(int irq, struct msi_msg *msg)
+void dmar_msi_write(CHIP_PARAM, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	CHIP_VAR
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1268,9 +1271,10 @@ void dmar_msi_write(int irq, struct msi_msg *msg)
 	spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
-void dmar_msi_read(int irq, struct msi_msg *msg)
+void dmar_msi_read(CHIP_PARAM, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	CHIP_VAR
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	spin_lock_irqsave(&iommu->register_lock, flag);
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 737a1c4..d9c5f0d 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -33,9 +33,9 @@ struct ht_irq_cfg {
 };
 
 
-void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
+void write_ht_irq_msg(struct irq_desc *desc, struct ht_irq_msg *msg)
 {
-	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = get_irq_desc_data(desc);
 	unsigned long flags;
 	spin_lock_irqsave(&ht_irq_lock, flags);
 	if (cfg->msg.address_lo != msg->address_lo) {
@@ -47,39 +47,39 @@ void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
 		pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi);
 	}
 	if (cfg->update)
-		cfg->update(cfg->dev, irq, msg);
+		cfg->update(cfg->dev, desc, msg);
 	spin_unlock_irqrestore(&ht_irq_lock, flags);
 	cfg->msg = *msg;
 }
 
-void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
+void fetch_ht_irq_msg(struct irq_desc *desc, struct ht_irq_msg *msg)
 {
-	struct ht_irq_cfg *cfg = get_irq_data(irq);
+	struct ht_irq_cfg *cfg = get_irq_desc_data(desc);
 	*msg = cfg->msg;
 }
 
-void mask_ht_irq(unsigned int irq)
+void mask_ht_irq(struct irq_desc *desc)
 {
 	struct ht_irq_cfg *cfg;
 	struct ht_irq_msg msg;
 
-	cfg = get_irq_data(irq);
+	cfg = get_irq_desc_data(desc);
 
 	msg = cfg->msg;
 	msg.address_lo |= 1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(desc, &msg);
 }
 
-void unmask_ht_irq(unsigned int irq)
+void unmask_ht_irq(struct irq_desc *desc)
 {
 	struct ht_irq_cfg *cfg;
 	struct ht_irq_msg msg;
 
-	cfg = get_irq_data(irq);
+	cfg = get_irq_desc_data(desc);
 
 	msg = cfg->msg;
 	msg.address_lo &= ~1;
-	write_ht_irq_msg(irq, &msg);
+	write_ht_irq_msg(desc, &msg);
 }
 
 /**
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f9cf317..98ac7a6 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -169,9 +169,10 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag)
 	desc->masked = __msix_mask_irq(desc, flag);
 }
 
-static void msi_set_mask_bit(unsigned irq, u32 flag)
+static void msi_set_mask_bit(struct irq_desc *descx, u32 flag)
 {
-	struct msi_desc *desc = get_irq_msi(irq);
+	unsigned int irq = descx->irq;
+	struct msi_desc *desc = get_irq_desc_msi(descx);
 
 	if (desc->msi_attrib.is_msix) {
 		msix_mask_irq(desc, flag);
@@ -182,18 +183,21 @@ static void msi_set_mask_bit(unsigned irq, u32 flag)
 	}
 }
 
-void mask_msi_irq(unsigned int irq)
+void mask_msi_irq(CHIP_PARAM)
 {
-	msi_set_mask_bit(irq, 1);
+	CHIP_VAR;
+	msi_set_mask_bit(desc, 1);
 }
 
-void unmask_msi_irq(unsigned int irq)
+void unmask_msi_irq(CHIP_PARAM)
 {
-	msi_set_mask_bit(irq, 0);
+	CHIP_VAR;
+	msi_set_mask_bit(desc, 0);
 }
 
-void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+void read_msi_msg(CHIP_PARAM, struct msi_msg *msg)
 {
+	CHIP_VAR
 	struct msi_desc *entry = get_irq_desc_msi(desc);
 	if (entry->msi_attrib.is_msix) {
 		void __iomem *base = entry->mask_base +
@@ -221,15 +225,9 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 	}
 }
 
-void read_msi_msg(unsigned int irq, struct msi_msg *msg)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	read_msi_msg_desc(desc, msg);
-}
-
-void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
+void write_msi_msg(CHIP_PARAM, struct msi_msg *msg)
 {
+	CHIP_VAR
 	struct msi_desc *entry = get_irq_desc_msi(desc);
 	if (entry->msi_attrib.is_msix) {
 		void __iomem *base;
@@ -264,13 +262,6 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 	entry->msg = *msg;
 }
 
-void write_msi_msg(unsigned int irq, struct msi_msg *msg)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	write_msi_msg_desc(desc, msg);
-}
-
 static void free_msi_irqs(struct pci_dev *dev)
 {
 	struct msi_desc *entry, *tmp;
@@ -319,16 +310,19 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
 	int pos;
 	u16 control;
 	struct msi_desc *entry;
+	unsigned int irq = dev->irq;
+	struct irq_desc *desc;
 
 	if (!dev->msi_enabled)
 		return;
 
-	entry = get_irq_msi(dev->irq);
+	desc = irq_to_desc(irq);
+	entry = get_irq_desc_msi(desc);
 	pos = entry->msi_attrib.pos;
 
 	pci_intx_for_msi(dev, 0);
 	msi_set_enable(dev, pos, 0);
-	write_msi_msg(dev->irq, &entry->msg);
+	write_msi_msg(CHIP_ARG, &entry->msg);
 
 	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
 	msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
@@ -356,7 +350,11 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
 	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		write_msi_msg(entry->irq, &entry->msg);
+		unsigned int irq = entry->irq;
+#ifdef CONFIG_CHIP_PARAM_DESC
+		struct irq_desc *desc = irq_to_desc(irq);
+#endif
+		write_msi_msg(CHIP_ARG, &entry->msg);
 		msix_mask_irq(entry, entry->masked);
 	}
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 64cbbe4..65372ad 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -730,11 +730,11 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 	return 0;
 }
 
-static int set_affinity_irq(unsigned irq, const struct cpumask *dest)
+static int set_affinity_irq(CHIP_PARAM, const struct cpumask *dest)
 {
 	unsigned tcpu = cpumask_first(dest);
 
-	return rebind_irq_to_cpu(irq, tcpu);
+	CHIP_VAR_IRQ return rebind_irq_to_cpu(irq, tcpu);
 }
 
 int resend_irq_on_evtchn(unsigned int irq)
@@ -753,35 +753,35 @@ int resend_irq_on_evtchn(unsigned int irq)
 	return 1;
 }
 
-static void enable_dynirq(unsigned int irq)
+static void enable_dynirq(CHIP_PARAM)
 {
-	int evtchn = evtchn_from_irq(irq);
+	CHIP_VAR_IRQ int evtchn = evtchn_from_irq(irq);
 
 	if (VALID_EVTCHN(evtchn))
 		unmask_evtchn(evtchn);
 }
 
-static void disable_dynirq(unsigned int irq)
+static void disable_dynirq(CHIP_PARAM)
 {
-	int evtchn = evtchn_from_irq(irq);
+	CHIP_VAR_IRQ int evtchn = evtchn_from_irq(irq);
 
 	if (VALID_EVTCHN(evtchn))
 		mask_evtchn(evtchn);
 }
 
-static void ack_dynirq(unsigned int irq)
+static void ack_dynirq(CHIP_PARAM)
 {
-	int evtchn = evtchn_from_irq(irq);
+	CHIP_VAR_IRQ int evtchn = evtchn_from_irq(irq);
 
-	move_native_irq(irq);
+	move_native_irq(CHIP_ARG);
 
 	if (VALID_EVTCHN(evtchn))
 		clear_evtchn(evtchn);
 }
 
-static int retrigger_dynirq(unsigned int irq)
+static int retrigger_dynirq(CHIP_PARAM)
 {
-	int evtchn = evtchn_from_irq(irq);
+	CHIP_VAR_IRQ int evtchn = evtchn_from_irq(irq);
 	struct shared_info *sh = HYPERVISOR_shared_info;
 	int ret = 0;
 
diff --git a/include/asm-generic/hardirq.h b/include/asm-generic/hardirq.h
index 62f5908..23b0724 100644
--- a/include/asm-generic/hardirq.h
+++ b/include/asm-generic/hardirq.h
@@ -12,8 +12,10 @@ typedef struct {
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
 #ifndef ack_bad_irq
-static inline void ack_bad_irq(unsigned int irq)
+static inline void ack_bad_irq(CHIP_PARAM)
 {
+	CHIP_VAR_IRQ
+
 	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
 }
 #endif
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 659a765..425c38a 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -187,10 +187,10 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
 /* Can't use the common MSI interrupt functions
  * since DMAR is not a pci device
  */
-extern void dmar_msi_unmask(unsigned int irq);
-extern void dmar_msi_mask(unsigned int irq);
-extern void dmar_msi_read(int irq, struct msi_msg *msg);
-extern void dmar_msi_write(int irq, struct msi_msg *msg);
+extern void dmar_msi_unmask(CHIP_PARAM);
+extern void dmar_msi_mask(CHIP_PARAM);
+extern void dmar_msi_read(CHIP_PARAM, struct msi_msg *msg);
+extern void dmar_msi_write(CHIP_PARAM, struct msi_msg *msg);
 extern int dmar_set_interrupt(struct intel_iommu *iommu);
 extern irqreturn_t dmar_fault(int irq, void *dev_id);
 extern int arch_setup_dmar_msi(unsigned int irq);
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
index c96ea46..91cf055 100644
--- a/include/linux/htirq.h
+++ b/include/linux/htirq.h
@@ -7,16 +7,17 @@ struct ht_irq_msg {
 };
 
 /* Helper functions.. */
-void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
-void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
-void mask_ht_irq(unsigned int irq);
-void unmask_ht_irq(unsigned int irq);
+struct irq_desc;
+void fetch_ht_irq_msg(struct irq_desc *desc, struct ht_irq_msg *msg);
+void write_ht_irq_msg(struct irq_desc *desc, struct ht_irq_msg *msg);
+void mask_ht_irq(struct irq_desc *);
+void unmask_ht_irq(struct irq_desc *);
 
 /* The arch hook for getting things started */
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
 
 /* For drivers of buggy hardware */
-typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq,
+typedef void (ht_irq_update_t)(struct pci_dev *dev, struct irq_desc *desc,
 			       struct ht_irq_msg *msg);
 int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update);
 
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 5a110a4..36ea6ac 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -264,8 +264,8 @@ extern void remove_irq(unsigned int irq, struct irqaction *act);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 
-void move_native_irq(unsigned int irq);
-void move_masked_irq(unsigned int irq);
+void move_native_irq(CHIP_PARAM);
+void move_masked_irq(CHIP_PARAM);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ */
 
@@ -349,9 +349,6 @@ static inline void generic_handle_irq(unsigned int irq)
 extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
 			   irqreturn_t action_ret);
 
-/* Resending of interrupts :*/
-void check_irq_resend(struct irq_desc *desc, unsigned int irq);
-
 /* Enable/disable irq debugging output: */
 extern int noirqdebug_setup(char *str);
 
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 6991ab5..2ab1cd3 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -3,6 +3,8 @@
 
 #include <linux/list.h>
 
+#include <linux/irq.h>
+
 struct msi_msg {
 	u32	address_lo;	/* low 32 bits of msi message address */
 	u32	address_hi;	/* high 32 bits of msi message address */
@@ -10,13 +12,10 @@ struct msi_msg {
 };
 
 /* Helper functions */
-struct irq_desc;
-extern void mask_msi_irq(unsigned int irq);
-extern void unmask_msi_irq(unsigned int irq);
-extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
-extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg);
-extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
-extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+extern void mask_msi_irq(CHIP_PARAM);
+extern void unmask_msi_irq(CHIP_PARAM);
+extern void read_msi_msg(CHIP_PARAM, struct msi_msg *msg);
+extern void write_msi_msg(CHIP_PARAM, struct msi_msg *msg);
 
 struct msi_desc {
 	struct {
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 9e4a0a0..1c1d465 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -38,9 +38,9 @@ struct lock_class_key irq_desc_lock_class;
  */
 void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 {
-	print_irq_desc(irq, desc);
+	print_irq_desc(desc);
 	kstat_incr_irqs_this_cpu(irq, desc);
-	ack_bad_irq(irq);
+	ack_bad_irq(CHIP_ARG);
 }
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
@@ -299,8 +299,8 @@ static void ack_bad(CHIP_PARAM)
 {
 	CHIP_VAR;
 
-	print_irq_desc(desc->irq, desc);
-	ack_bad_irq(desc->irq);
+	print_irq_desc(desc);
+	ack_bad_irq(CHIP_ARG);
 }
 
 /*
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 2a9ec5e..dca36c4 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -14,6 +14,8 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 		unsigned long flags);
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
+/* Resending of interrupts :*/
+void check_irq_resend(struct irq_desc *desc, unsigned int irq);
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
@@ -61,10 +63,11 @@ static inline void chip_bus_sync_unlock(unsigned int irq, struct irq_desc *desc)
 
 #define P(f) if (desc->status & f) printk("%14s set\n", #f)
 
-static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
+static inline void print_irq_desc(struct irq_desc *desc)
 {
 	printk("irq %d, desc: %p, depth: %d, count: %d, unhandled: %d\n",
-		irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled);
+		desc->irq, desc, desc->depth, desc->irq_count,
+		desc->irqs_unhandled);
 	printk("->handle_irq():  %p, ", desc->handle_irq);
 	print_symbol("%s\n", (unsigned long)desc->handle_irq);
 	printk("->chip(): %p, ", desc->chip);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 5821159..849b3d0 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -4,9 +4,9 @@
 
 #include "internals.h"
 
-void move_masked_irq(unsigned int irq)
+void move_masked_irq(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR
 
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
@@ -51,9 +51,9 @@ void move_masked_irq(unsigned int irq)
 	cpumask_clear(desc->pending_mask);
 }
 
-void move_native_irq(unsigned int irq)
+void move_native_irq(CHIP_PARAM)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	CHIP_VAR
 
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
@@ -62,7 +62,7 @@ void move_native_irq(unsigned int irq)
 		return;
 
 	desc->chip->mask(CHIP_ARG);
-	move_masked_irq(irq);
+	move_masked_irq(CHIP_ARG);
 	desc->chip->unmask(CHIP_ARG);
 }
 
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 08/10] genericirq: add set_irq_desc_chip/data ...
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (6 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 07/10] x86/irq: use irq_desc *desc with irq_chip Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 09/10] x86/iommu/dmar: update iommu/inter_remapping to use desc Yinghai Lu
  2010-03-22  1:36 ` [PATCH 10/10] x86: remove arch_probe_nr_irqs Yinghai Lu
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

with set_irq_chip/data...

to take desc instead of irq

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/kernel/apic/io_apic.c |    4 +-
 include/linux/irq.h            |   10 +++-
 include/linux/irqnr.h          |    1 +
 kernel/irq/chip.c              |  127 +++++++++++++++++++++++-----------------
 4 files changed, 85 insertions(+), 57 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f908af5..432bea1 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3302,7 +3302,7 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
 	if (irq > 0)
-		dynamic_irq_init_keep_chip_data(irq);
+		dynamic_irq_init_keep_chip_data(irq_to_desc(irq));
 
 	return irq;
 }
@@ -3328,7 +3328,7 @@ void destroy_irq(unsigned int irq)
 	struct irq_desc *desc;
 	struct irq_cfg *cfg;
 
-	dynamic_irq_cleanup_keep_chip_data(irq);
+	dynamic_irq_cleanup_keep_chip_data(irq_to_desc(irq));
 
 	free_irte(irq);
 	raw_spin_lock_irqsave(&vector_lock, flags);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 36ea6ac..1f5d112 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -420,9 +420,9 @@ static inline int irq_has_action(unsigned int irq)
 
 /* Dynamic irq helper functions */
 extern void dynamic_irq_init(unsigned int irq);
-void dynamic_irq_init_keep_chip_data(unsigned int irq);
+void dynamic_irq_init_keep_chip_data(struct irq_desc *desc);
 extern void dynamic_irq_cleanup(unsigned int irq);
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq);
+void dynamic_irq_cleanup_keep_chip_data(struct irq_desc *desc);
 
 /* Set/get chip/data for an IRQ: */
 extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
@@ -431,6 +431,12 @@ extern int set_irq_chip_data(unsigned int irq, void *data);
 extern int set_irq_type(unsigned int irq, unsigned int type);
 extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
 
+int set_irq_desc_chip(struct irq_desc *desc, struct irq_chip *chip);
+int set_irq_desc_data(struct irq_desc *desc, void *data);
+int set_irq_desc_chip_data(struct irq_desc *desc, void *data);
+int set_irq_desc_type(struct irq_desc *desc, unsigned int type);
+int set_irq_desc_msi(struct irq_desc *desc, struct msi_desc *entry);
+
 #define get_irq_chip(irq)	(irq_to_desc(irq)->chip)
 #define get_irq_chip_data(irq)	(irq_to_desc(irq)->chip_data)
 #define get_irq_data(irq)	(irq_to_desc(irq)->handler_data)
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 7bf89bc..dee8f2b 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -43,6 +43,7 @@ extern struct irq_desc *irq_to_desc(unsigned int irq);
 
 #ifdef CONFIG_SMP
 #define irq_node(irq)	(irq_to_desc(irq)->node)
+#define irq_desc_node(desc) ((desc)->node)
 #else
 #define irq_node(irq)	0
 #endif
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 190360d..6725334 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -18,17 +18,10 @@
 
 #include "internals.h"
 
-static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
+static void dynamic_irq_init_x(struct irq_desc *desc, bool keep_chip_data)
 {
-	struct irq_desc *desc;
 	unsigned long flags;
 
-	desc = irq_to_desc(irq);
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
-		return;
-	}
-
 	/* Ensure we don't have left over values from a previous use of this irq */
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	desc->status = IRQ_DISABLED;
@@ -57,7 +50,15 @@ static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data)
  */
 void dynamic_irq_init(unsigned int irq)
 {
-	dynamic_irq_init_x(irq, false);
+	struct irq_desc *desc;
+
+	desc = irq_to_desc(irq);
+	if (!desc) {
+		WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
+		return;
+	}
+
+	dynamic_irq_init_x(desc, false);
 }
 
 /**
@@ -66,26 +67,20 @@ void dynamic_irq_init(unsigned int irq)
  *
  *	does not set irq_to_desc(irq)->chip_data to NULL
  */
-void dynamic_irq_init_keep_chip_data(unsigned int irq)
+void dynamic_irq_init_keep_chip_data(struct irq_desc *desc)
 {
-	dynamic_irq_init_x(irq, true);
+	dynamic_irq_init_x(desc, true);
 }
 
-static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
+static void dynamic_irq_cleanup_x(struct irq_desc *desc, bool keep_chip_data)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
-	if (!desc) {
-		WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
-		return;
-	}
-
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	if (desc->action) {
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 		WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n",
-			irq);
+			desc->irq);
 		return;
 	}
 	desc->msi_desc = NULL;
@@ -105,7 +100,14 @@ static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data)
  */
 void dynamic_irq_cleanup(unsigned int irq)
 {
-	dynamic_irq_cleanup_x(irq, false);
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (!desc) {
+		WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
+		return;
+	}
+
+	dynamic_irq_cleanup_x(desc, false);
 }
 
 /**
@@ -114,9 +116,9 @@ void dynamic_irq_cleanup(unsigned int irq)
  *
  *	does not set irq_to_desc(irq)->chip_data to NULL
  */
-void dynamic_irq_cleanup_keep_chip_data(unsigned int irq)
+void dynamic_irq_cleanup_keep_chip_data(struct irq_desc *desc)
 {
-	dynamic_irq_cleanup_x(irq, true);
+	dynamic_irq_cleanup_x(desc, true);
 }
 
 
@@ -152,26 +154,31 @@ EXPORT_SYMBOL(set_irq_chip);
  *	@irq:	irq number
  *	@type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
  */
-int set_irq_type(unsigned int irq, unsigned int type)
+int set_irq_desc_type(struct irq_desc *desc, unsigned int type)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 	int ret = -ENXIO;
 
-	if (!desc) {
-		printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
-		return -ENODEV;
-	}
-
 	type &= IRQ_TYPE_SENSE_MASK;
 	if (type == IRQ_TYPE_NONE)
 		return 0;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	ret = __irq_set_trigger(desc, irq, type);
+	ret = __irq_set_trigger(desc, desc->irq, type);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return ret;
 }
+int set_irq_type(unsigned int irq, unsigned int type)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (!desc) {
+		printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
+		return -ENODEV;
+	}
+
+	return set_irq_desc_type(desc, type);
+}
 EXPORT_SYMBOL(set_irq_type);
 
 /**
@@ -181,10 +188,18 @@ EXPORT_SYMBOL(set_irq_type);
  *
  *	Set the hardware irq controller data for an irq
  */
+int set_irq_desc_data(struct irq_desc *desc, void *data)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+	desc->handler_data = data;
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+	return 0;
+}
 int set_irq_data(unsigned int irq, void *data)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
-	unsigned long flags;
 
 	if (!desc) {
 		printk(KERN_ERR
@@ -192,10 +207,7 @@ int set_irq_data(unsigned int irq, void *data)
 		return -EINVAL;
 	}
 
-	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc->handler_data = data;
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	return 0;
+	return set_irq_desc_data(desc, data);
 }
 EXPORT_SYMBOL(set_irq_data);
 
@@ -206,24 +218,28 @@ EXPORT_SYMBOL(set_irq_data);
  *
  *	Set the MSI descriptor entry for an irq
  */
-int set_irq_msi(unsigned int irq, struct msi_desc *entry)
+int set_irq_desc_msi(struct irq_desc *desc, struct msi_desc *entry)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
-	if (!desc) {
-		printk(KERN_ERR
-		       "Trying to install msi data for IRQ%d\n", irq);
-		return -EINVAL;
-	}
-
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	desc->msi_desc = entry;
 	if (entry)
-		entry->irq = irq;
+		entry->irq = desc->irq;
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return 0;
 }
+int set_irq_msi(unsigned int irq, struct msi_desc *entry)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	if (!desc) {
+		printk(KERN_ERR
+		       "Trying to install msi data for IRQ%d\n", desc->irq);
+		return -EINVAL;
+	}
+
+	return set_irq_desc_msi(desc, entry);
+}
 
 /**
  *	set_irq_chip_data - set irq chip data for an irq
@@ -232,19 +248,12 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
  *
  *	Set the hardware irq chip data for an irq
  */
-int set_irq_chip_data(unsigned int irq, void *data)
+int set_irq_desc_chip_data(struct irq_desc *desc, void *data)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
 
-	if (!desc) {
-		printk(KERN_ERR
-		       "Trying to install chip data for IRQ%d\n", irq);
-		return -EINVAL;
-	}
-
 	if (!desc->chip) {
-		printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
+		printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", desc->irq);
 		return -EINVAL;
 	}
 
@@ -254,6 +263,18 @@ int set_irq_chip_data(unsigned int irq, void *data)
 
 	return 0;
 }
+int set_irq_chip_data(unsigned int irq, void *data)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (!desc) {
+		printk(KERN_ERR
+		       "Trying to install chip data for IRQ%d\n", irq);
+		return -EINVAL;
+	}
+
+	return set_irq_desc_chip_data(desc, data);
+}
 EXPORT_SYMBOL(set_irq_chip_data);
 
 /**
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 09/10] x86/iommu/dmar: update iommu/inter_remapping to use desc
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (7 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 08/10] genericirq: add set_irq_desc_chip/data Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  2010-03-22  1:36 ` [PATCH 10/10] x86: remove arch_probe_nr_irqs Yinghai Lu
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

to make irq_remapped() not going to call irq_to_desc() ....

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/io_apic.h |    4 --
 arch/x86/kernel/apic/io_apic.c |   78 +++++++++++++++++++---------------------
 drivers/pci/intr_remapping.c   |   69 +++++++++++++++--------------------
 include/linux/dmar.h           |   36 ++++++++++---------
 4 files changed, 85 insertions(+), 102 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index c4683b9..d249186 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -171,10 +171,6 @@ extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
 
 extern void probe_nr_irqs_gsi(void);
 
-extern int setup_ioapic_entry(int apic, int irq,
-			      struct IO_APIC_route_entry *entry,
-			      unsigned int destination, int trigger,
-			      int polarity, int vector, int pin);
 extern void ioapic_write_entry(int apic, int pin,
 			       struct IO_APIC_route_entry e);
 extern void setup_ioapic_ids_from_mpc(void);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 432bea1..ce93428 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1340,7 +1340,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
 	else
 		desc->status &= ~IRQ_LEVEL;
 
-	if (irq_remapped(irq)) {
+	if (irq_remapped(desc)) {
 		desc->status |= IRQ_MOVE_PCNTXT;
 		if (trigger)
 			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
@@ -1362,7 +1362,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
 					      handle_edge_irq, "edge");
 }
 
-int setup_ioapic_entry(int apic_id, int irq,
+static int setup_ioapic_entry(int apic_id, struct irq_desc *desc,
 		       struct IO_APIC_route_entry *entry,
 		       unsigned int destination, int trigger,
 		       int polarity, int vector, int pin)
@@ -1382,7 +1382,7 @@ int setup_ioapic_entry(int apic_id, int irq,
 		if (!iommu)
 			panic("No mapping iommu for ioapic %d\n", apic_id);
 
-		index = alloc_irte(iommu, irq, 1);
+		index = alloc_irte(iommu, desc, 1);
 		if (index < 0)
 			panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
 
@@ -1405,7 +1405,7 @@ int setup_ioapic_entry(int apic_id, int irq,
 		/* Set source-id of interrupt request */
 		set_ioapic_sid(&irte, apic_id);
 
-		modify_irte(irq, &irte);
+		modify_irte(desc, &irte);
 
 		ir_entry->index2 = (index >> 15) & 0x1;
 		ir_entry->zero = 0;
@@ -1467,7 +1467,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
 		    irq, trigger, polarity);
 
 
-	if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry,
+	if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, desc, &entry,
 			       dest, trigger, polarity, cfg->vector, pin)) {
 		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
 		       mp_ioapics[apic_id].apicid, pin);
@@ -2334,7 +2334,7 @@ void send_cleanup_vector(struct irq_cfg *cfg)
 	cfg->move_in_progress = 0;
 }
 
-static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
+static void __target_IO_APIC_irq(struct irq_desc *desc, unsigned int dest, struct irq_cfg *cfg)
 {
 	int apic, pin;
 	struct irq_pin_list *entry;
@@ -2349,7 +2349,7 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
 		 * With interrupt-remapping, destination information comes
 		 * from interrupt-remapping table entry.
 		 */
-		if (!irq_remapped(irq))
+		if (!irq_remapped(desc))
 			io_apic_write(apic, 0x11 + pin*2, dest);
 		reg = io_apic_read(apic, 0x10 + pin*2);
 		reg &= ~IO_APIC_REDIR_VECTOR_MASK;
@@ -2388,10 +2388,8 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 	struct irq_cfg *cfg;
 	unsigned long flags;
 	unsigned int dest;
-	unsigned int irq;
 	int ret = -1;
 
-	irq = desc->irq;
 	cfg = desc->chip_data;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
@@ -2399,7 +2397,7 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 	if (!ret) {
 		/* Only the high 8 bits are valid. */
 		dest = SET_APIC_LOGICAL_ID(dest);
-		__target_IO_APIC_irq(irq, dest, cfg);
+		__target_IO_APIC_irq(desc, dest, cfg);
 	}
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -2431,14 +2429,12 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 	struct irq_cfg *cfg;
 	struct irte irte;
 	unsigned int dest;
-	unsigned int irq;
 	int ret = -1;
 
 	if (!cpumask_intersects(mask, cpu_online_mask))
 		return ret;
 
-	irq = desc->irq;
-	if (get_irte(irq, &irte))
+	if (get_irte(desc, &irte))
 		return ret;
 
 	cfg = desc->chip_data;
@@ -2453,7 +2449,7 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 	/*
 	 * Modified the IRTE and flushes the Interrupt entry cache.
 	 */
-	modify_irte(irq, &irte);
+	modify_irte(desc, &irte);
 
 	if (cfg->move_in_progress)
 		send_cleanup_vector(cfg);
@@ -2591,7 +2587,7 @@ atomic_t irq_mis_count;
  * Otherwise, we simulate the EOI message manually by changing the trigger
  * mode to edge and then back to level, with RTE being masked during this.
 */
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+static void __eoi_ioapic_irq(struct irq_desc *desc, struct irq_cfg *cfg)
 {
 	struct irq_pin_list *entry;
 
@@ -2603,7 +2599,7 @@ static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
 			 * intr-remapping table entry. Hence for the io-apic
 			 * EOI we use the pin number.
 			 */
-			if (irq_remapped(irq))
+			if (irq_remapped(desc))
 				io_apic_eoi(entry->apic, entry->pin);
 			else
 				io_apic_eoi(entry->apic, cfg->vector);
@@ -2618,13 +2614,11 @@ static void eoi_ioapic_irq(struct irq_desc *desc)
 {
 	struct irq_cfg *cfg;
 	unsigned long flags;
-	unsigned int irq;
 
-	irq = desc->irq;
 	cfg = desc->chip_data;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
-	__eoi_ioapic_irq(irq, cfg);
+	__eoi_ioapic_irq(desc, cfg);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -3328,11 +3322,11 @@ void destroy_irq(unsigned int irq)
 	struct irq_desc *desc;
 	struct irq_cfg *cfg;
 
-	dynamic_irq_cleanup_keep_chip_data(irq_to_desc(irq));
+	desc = irq_to_desc(irq);
+	dynamic_irq_cleanup_keep_chip_data(desc);
 
-	free_irte(irq);
+	free_irte(desc);
 	raw_spin_lock_irqsave(&vector_lock, flags);
-	desc = irq_to_desc(irq);
 	cfg = desc->chip_data;
 	__clear_irq_vector(desc, cfg);
 	raw_spin_unlock_irqrestore(&vector_lock, flags);
@@ -3345,7 +3339,6 @@ void destroy_irq(unsigned int irq)
 static int msi_compose_msg(struct pci_dev *pdev, struct irq_desc *desc,
 			   struct msi_msg *msg, u8 hpet_id)
 {
-	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg;
 	int err;
 	unsigned dest;
@@ -3360,15 +3353,15 @@ static int msi_compose_msg(struct pci_dev *pdev, struct irq_desc *desc,
 
 	dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
 
-	if (irq_remapped(irq)) {
+	if (irq_remapped(desc)) {
 		struct irte irte;
 		int ir_index;
 		u16 sub_handle;
 
-		ir_index = map_irq_to_irte_handle(irq, &sub_handle);
+		ir_index = map_irq_to_irte_handle(desc, &sub_handle);
 		BUG_ON(ir_index == -1);
 
-		memset (&irte, 0, sizeof(irte));
+		memset(&irte, 0, sizeof(irte));
 
 		irte.present = 1;
 		irte.dst_mode = apic->irq_dest_mode;
@@ -3383,7 +3376,7 @@ static int msi_compose_msg(struct pci_dev *pdev, struct irq_desc *desc,
 		else
 			set_hpet_sid(&irte, hpet_id);
 
-		modify_irte(irq, &irte);
+		modify_irte(desc, &irte);
 
 		msg->address_hi = MSI_ADDR_BASE_HI;
 		msg->data = sub_handle;
@@ -3451,12 +3444,11 @@ set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 static int
 ir_set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg = desc->chip_data;
 	unsigned int dest;
 	struct irte irte;
 
-	if (get_irte(irq, &irte))
+	if (get_irte(desc, &irte))
 		return -1;
 
 	if (set_desc_affinity(desc, mask, &dest))
@@ -3468,7 +3460,7 @@ ir_set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mask)
 	/*
 	 * atomically update the IRTE with the new destination and vector.
 	 */
-	modify_irte(irq, &irte);
+	modify_irte(desc, &irte);
 
 	/*
 	 * After this point, all the interrupts will start arriving
@@ -3523,7 +3515,7 @@ static struct irq_chip msi_ir_chip = {
  * and allocate 'nvec' consecutive interrupt-remapping table entries
  * in it.
  */
-static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
+static int msi_alloc_irte(struct pci_dev *dev, struct irq_desc *desc, int nvec)
 {
 	struct intel_iommu *iommu;
 	int index;
@@ -3535,7 +3527,7 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
 		return -ENOENT;
 	}
 
-	index = alloc_irte(iommu, irq, nvec);
+	index = alloc_irte(iommu, desc, nvec);
 	if (index < 0) {
 		printk(KERN_ERR
 		       "Unable to allocate %d IRTE for PCI %s\n", nvec,
@@ -3545,20 +3537,22 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
 	return index;
 }
 
-static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
+static int
+setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, struct irq_desc *desc)
 {
 	int ret;
 	struct msi_msg msg;
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq;
 
 	ret = msi_compose_msg(dev, desc, &msg, -1);
 	if (ret < 0)
 		return ret;
 
-	set_irq_msi(irq, msidesc);
+	set_irq_desc_msi(desc, msidesc);
 	write_msi_msg(desc, &msg);
 
-	if (irq_remapped(irq)) {
+	irq = desc->irq;
+	if (irq_remapped(desc)) {
 		/*
 		 * irq migration in process context
 		 */
@@ -3575,6 +3569,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
 	unsigned int irq;
+	struct irq_desc *desc;
 	int ret, sub_handle;
 	struct msi_desc *msidesc;
 	unsigned int irq_want;
@@ -3594,6 +3589,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 		if (irq == 0)
 			return -1;
 		irq_want = irq + 1;
+		desc = irq_to_desc(irq);
 		if (!intr_remapping_enabled)
 			goto no_ir;
 
@@ -3602,7 +3598,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 			 * allocate the consecutive block of IRTE's
 			 * for 'nvec'
 			 */
-			index = msi_alloc_irte(dev, irq, nvec);
+			index = msi_alloc_irte(dev, desc, nvec);
 			if (index < 0) {
 				ret = index;
 				goto error;
@@ -3618,10 +3614,10 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 			 * base index, the sub_handle pointing to the
 			 * appropriate interrupt remap table entry.
 			 */
-			set_irte_irq(irq, iommu, index, sub_handle);
+			set_irte_irq(desc, iommu, index, sub_handle);
 		}
 no_ir:
-		ret = setup_msi_irq(dev, msidesc, irq);
+		ret = setup_msi_irq(dev, msidesc, desc);
 		if (ret < 0)
 			goto error;
 		sub_handle++;
@@ -3768,7 +3764,7 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 		if (!iommu)
 			return -1;
 
-		index = alloc_irte(iommu, irq, 1);
+		index = alloc_irte(iommu, desc, 1);
 		if (index < 0)
 			return -1;
 	}
@@ -3779,7 +3775,7 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 
 	hpet_msi_write(desc, &msg);
 	desc->status |= IRQ_MOVE_PCNTXT;
-	if (irq_remapped(irq))
+	if (irq_remapped(desc))
 		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
 					      handle_edge_irq, "edge");
 	else
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 95b8491..1c03bc7 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -45,33 +45,27 @@ static struct irq_2_iommu *get_one_free_irq_2_iommu(int node)
 	return iommu;
 }
 
-static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
+static struct irq_2_iommu *irq_2_iommu(struct irq_desc *desc)
 {
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-
 	if (WARN_ON_ONCE(!desc))
 		return NULL;
 
 	return desc->irq_2_iommu;
 }
 
-static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
+static struct irq_2_iommu *irq_2_iommu_alloc(struct irq_desc *desc)
 {
-	struct irq_desc *desc;
 	struct irq_2_iommu *irq_iommu;
 
-	desc = irq_to_desc(irq);
 	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+		printk(KERN_INFO "can not get irq_desc\n");
 		return NULL;
 	}
 
 	irq_iommu = desc->irq_2_iommu;
 
 	if (!irq_iommu)
-		desc->irq_2_iommu = get_one_free_irq_2_iommu(irq_node(irq));
+		desc->irq_2_iommu = get_one_free_irq_2_iommu(irq_desc_node(desc));
 
 	return desc->irq_2_iommu;
 }
@@ -80,26 +74,27 @@ static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
 
 static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
 
-static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
+static struct irq_2_iommu *irq_2_iommu(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq < nr_irqs)
 		return &irq_2_iommuX[irq];
 
 	return NULL;
 }
-static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
+static struct irq_2_iommu *irq_2_iommu_alloc(struct irq_desc *desc)
 {
-	return irq_2_iommu(irq);
+	return irq_2_iommu(desc);
 }
 #endif
 
 static DEFINE_SPINLOCK(irq_2_ir_lock);
 
-static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
+static struct irq_2_iommu *valid_irq_2_iommu(struct irq_desc *desc)
 {
 	struct irq_2_iommu *irq_iommu;
 
-	irq_iommu = irq_2_iommu(irq);
+	irq_iommu = irq_2_iommu(desc);
 
 	if (!irq_iommu)
 		return NULL;
@@ -110,12 +105,12 @@ static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
 	return irq_iommu;
 }
 
-int irq_remapped(int irq)
+int irq_remapped(struct irq_desc *desc)
 {
-	return valid_irq_2_iommu(irq) != NULL;
+	return valid_irq_2_iommu(desc) != NULL;
 }
 
-int get_irte(int irq, struct irte *entry)
+int get_irte(struct irq_desc *desc, struct irte *entry)
 {
 	int index;
 	struct irq_2_iommu *irq_iommu;
@@ -125,7 +120,7 @@ int get_irte(int irq, struct irte *entry)
 		return -1;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
@@ -138,7 +133,7 @@ int get_irte(int irq, struct irte *entry)
 	return 0;
 }
 
-int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
+int alloc_irte(struct intel_iommu *iommu, struct irq_desc *desc, u16 count)
 {
 	struct ir_table *table = iommu->ir_table;
 	struct irq_2_iommu *irq_iommu;
@@ -150,12 +145,6 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
 	if (!count)
 		return -1;
 
-#ifndef CONFIG_SPARSE_IRQ
-	/* protect irq_2_iommu_alloc later */
-	if (irq >= nr_irqs)
-		return -1;
-#endif
-
 	/*
 	 * start the IRTE search from index 0.
 	 */
@@ -195,7 +184,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
 	for (i = index; i < index + count; i++)
 		table->base[i].present = 1;
 
-	irq_iommu = irq_2_iommu_alloc(irq);
+	irq_iommu = irq_2_iommu_alloc(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		printk(KERN_ERR "can't allocate irq_2_iommu\n");
@@ -223,14 +212,14 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
 	return qi_submit_sync(&desc, iommu);
 }
 
-int map_irq_to_irte_handle(int irq, u16 *sub_handle)
+int map_irq_to_irte_handle(struct irq_desc *desc, u16 *sub_handle)
 {
 	int index;
 	struct irq_2_iommu *irq_iommu;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
@@ -242,14 +231,14 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
 	return index;
 }
 
-int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
+int set_irte_irq(struct irq_desc *desc, struct intel_iommu *iommu, u16 index, u16 subhandle)
 {
 	struct irq_2_iommu *irq_iommu;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
 
-	irq_iommu = irq_2_iommu_alloc(irq);
+	irq_iommu = irq_2_iommu_alloc(desc);
 
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
@@ -267,13 +256,13 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
 	return 0;
 }
 
-int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
+int clear_irte_irq(struct irq_desc *desc, struct intel_iommu *iommu, u16 index)
 {
 	struct irq_2_iommu *irq_iommu;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
@@ -282,14 +271,14 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
 	irq_iommu->iommu = NULL;
 	irq_iommu->irte_index = 0;
 	irq_iommu->sub_handle = 0;
-	irq_2_iommu(irq)->irte_mask = 0;
+	irq_2_iommu(desc)->irte_mask = 0;
 
 	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return 0;
 }
 
-int modify_irte(int irq, struct irte *irte_modified)
+int modify_irte(struct irq_desc *desc, struct irte *irte_modified)
 {
 	int rc;
 	int index;
@@ -299,7 +288,7 @@ int modify_irte(int irq, struct irte *irte_modified)
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
@@ -320,7 +309,7 @@ int modify_irte(int irq, struct irte *irte_modified)
 	return rc;
 }
 
-int flush_irte(int irq)
+int flush_irte(struct irq_desc *desc)
 {
 	int rc;
 	int index;
@@ -329,7 +318,7 @@ int flush_irte(int irq)
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
@@ -399,14 +388,14 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
 	return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
 }
 
-int free_irte(int irq)
+int free_irte(struct irq_desc *desc)
 {
 	int rc = 0;
 	struct irq_2_iommu *irq_iommu;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_2_ir_lock, flags);
-	irq_iommu = valid_irq_2_iommu(irq);
+	irq_iommu = valid_irq_2_iommu(desc);
 	if (!irq_iommu) {
 		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 425c38a..8b0e4f5 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -113,17 +113,17 @@ extern int enable_intr_remapping(int);
 extern void disable_intr_remapping(void);
 extern int reenable_intr_remapping(int);
 
-extern int get_irte(int irq, struct irte *entry);
-extern int modify_irte(int irq, struct irte *irte_modified);
-extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count);
-extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
-   			u16 sub_handle);
-extern int map_irq_to_irte_handle(int irq, u16 *sub_handle);
-extern int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index);
-extern int flush_irte(int irq);
-extern int free_irte(int irq);
-
-extern int irq_remapped(int irq);
+int get_irte(struct irq_desc *desc, struct irte *entry);
+int modify_irte(struct irq_desc *desc, struct irte *irte_modified);
+int alloc_irte(struct intel_iommu *iommu, struct irq_desc *desc, u16 count);
+int set_irte_irq(struct irq_desc *desc, struct intel_iommu *iommu, u16 index,
+			u16 sub_handle);
+int map_irq_to_irte_handle(struct irq_desc *desc, u16 *sub_handle);
+int clear_irte_irq(struct irq_desc *desc, struct intel_iommu *iommu, u16 index);
+int flush_irte(struct irq_desc *desc);
+int free_irte(struct irq_desc *desc);
+
+extern int irq_remapped(struct irq_desc *desc);
 extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev);
 extern struct intel_iommu *map_ioapic_to_ir(int apic);
 extern struct intel_iommu *map_hpet_to_ir(u8 id);
@@ -131,23 +131,25 @@ extern int set_ioapic_sid(struct irte *irte, int apic);
 extern int set_hpet_sid(struct irte *irte, u8 id);
 extern int set_msi_sid(struct irte *irte, struct pci_dev *dev);
 #else
-static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
+static inline int
+alloc_irte(struct intel_iommu *iommu, struct irq_desc *desc, u16 count)
 {
 	return -1;
 }
-static inline int modify_irte(int irq, struct irte *irte_modified)
+static inline int modify_irte(struct irq_desc *desc, struct irte *irte_modified)
 {
 	return -1;
 }
-static inline int free_irte(int irq)
+static inline int free_irte(struct irq_desc *desc)
 {
 	return -1;
 }
-static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle)
+static inline int map_irq_to_irte_handle(struct irq_desc *desc, u16 *sub_handle)
 {
 	return -1;
 }
-static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
+static inline int
+set_irte_irq(struct irq_desc *desc, struct intel_iommu *iommu, u16 index,
 			       u16 sub_handle)
 {
 	return -1;
@@ -177,7 +179,7 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
 	return 0;
 }
 
-#define irq_remapped(irq)		(0)
+#define irq_remapped(desc)		(0)
 #define enable_intr_remapping(mode)	(-1)
 #define disable_intr_remapping()	(0)
 #define reenable_intr_remapping(mode)	(0)
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 10/10] x86: remove arch_probe_nr_irqs
  2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
                   ` (8 preceding siblings ...)
  2010-03-22  1:36 ` [PATCH 09/10] x86/iommu/dmar: update iommu/inter_remapping to use desc Yinghai Lu
@ 2010-03-22  1:36 ` Yinghai Lu
  9 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  1:36 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes
  Cc: linux-kernel, Yinghai Lu

so keep nr_irqs == NR_IRQS

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/kernel/apic/io_apic.c |   22 ----------------------
 1 files changed, 0 insertions(+), 22 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index ce93428..b9c4749 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3921,28 +3921,6 @@ void __init probe_nr_irqs_gsi(void)
 	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
 
-#ifdef CONFIG_SPARSE_IRQ
-int __init arch_probe_nr_irqs(void)
-{
-	int nr;
-
-	if (nr_irqs > (NR_VECTORS * nr_cpu_ids))
-		nr_irqs = NR_VECTORS * nr_cpu_ids;
-
-	nr = nr_irqs_gsi + 8 * nr_cpu_ids;
-#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ)
-	/*
-	 * for MSI and HT dyn irq
-	 */
-	nr += nr_irqs_gsi * 16;
-#endif
-	if (nr < nr_irqs)
-		nr_irqs = nr;
-
-	return 0;
-}
-#endif
-
 static int __io_apic_set_pci_routing(struct device *dev, int irq,
 				struct io_apic_irq_attr *irq_attr)
 {
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-22  1:36   ` Yinghai Lu
  (?)
@ 2010-03-22  1:56     ` Michael Ellerman
  -1 siblings, 0 replies; 115+ messages in thread
From: Michael Ellerman @ 2010-03-22  1:56 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Paul Mundt, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Ingo Molnar, Thomas Gleixner, Ian Campbell

[-- Attachment #1: Type: text/plain, Size: 1716 bytes --]

On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
...
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH
> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
...
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...
>      so could leave default path not changed...

Apologies for not noticing this sooner, but ..

> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;

This is a bit feral, that is the init_chip_data_fn.

It seems like it only exists to support the following on x86:

> +int arch_init_irq_desc(struct irq_desc *desc, int node,
> +			 init_chip_data_fn init_chip_data)
> +{
> +	if (!init_chip_data)
> +		return x86_init_chip_data(desc, node);
> +
> +	return init_chip_data(desc, node);
> +}

Which is really just a hack to avoid an if (xen) check isn't it?

It looks to me like this should just be done via a current machine
vector or platform routine, in the same way as powerpc and (I think)
ia64, ie:

> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> +{
> +	return current_machine->init_chip_data(desc, node);
> +}

cheers


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  1:56     ` Michael Ellerman
  0 siblings, 0 replies; 115+ messages in thread
From: Michael Ellerman @ 2010-03-22  1:56 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, lguest, Jeremy Fitzhardinge,
	Rusty Russell, Ian Campbell, Paul Mundt, linux-sh, x86,
	linux-kernel, linuxppc-dev, Ingo Molnar, Paul Mackerras

[-- Attachment #1: Type: text/plain, Size: 1716 bytes --]

On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
...
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH
> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
...
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...
>      so could leave default path not changed...

Apologies for not noticing this sooner, but ..

> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;

This is a bit feral, that is the init_chip_data_fn.

It seems like it only exists to support the following on x86:

> +int arch_init_irq_desc(struct irq_desc *desc, int node,
> +			 init_chip_data_fn init_chip_data)
> +{
> +	if (!init_chip_data)
> +		return x86_init_chip_data(desc, node);
> +
> +	return init_chip_data(desc, node);
> +}

Which is really just a hack to avoid an if (xen) check isn't it?

It looks to me like this should just be done via a current machine
vector or platform routine, in the same way as powerpc and (I think)
ia64, ie:

> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> +{
> +	return current_machine->init_chip_data(desc, node);
> +}

cheers


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  1:56     ` Michael Ellerman
  0 siblings, 0 replies; 115+ messages in thread
From: Michael Ellerman @ 2010-03-22  1:56 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Paul Mundt, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Ingo Molnar, Thomas Gleixner, Ian Campbell

[-- Attachment #1: Type: text/plain, Size: 1716 bytes --]

On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
...
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH
> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
...
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...
>      so could leave default path not changed...

Apologies for not noticing this sooner, but ..

> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;

This is a bit feral, that is the init_chip_data_fn.

It seems like it only exists to support the following on x86:

> +int arch_init_irq_desc(struct irq_desc *desc, int node,
> +			 init_chip_data_fn init_chip_data)
> +{
> +	if (!init_chip_data)
> +		return x86_init_chip_data(desc, node);
> +
> +	return init_chip_data(desc, node);
> +}

Which is really just a hack to avoid an if (xen) check isn't it?

It looks to me like this should just be done via a current machine
vector or platform routine, in the same way as powerpc and (I think)
ia64, ie:

> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> +{
> +	return current_machine->init_chip_data(desc, node);
> +}

cheers


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-22  1:56     ` Michael Ellerman
  (?)
@ 2010-03-22  3:32       ` Yinghai Lu
  -1 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  3:32 UTC (permalink / raw)
  To: michael
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Paul Mundt, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Ingo Molnar, Thomas Gleixner, Ian Campbell

On 03/21/2010 06:56 PM, Michael Ellerman wrote:
> On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
>> From: Ian Campbell <ian.campbell@citrix.com>
> ...
>> To replace the x86 arch_init_chip_data functionality
>> irq_to_desc_alloc_node now takes a pointer to a function to allocate
>> the chip data. This is necessary to ensure the allocation happens
>> under the correct locking at the core level. On PowerPC and SH
>> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
>> which retains existing chip_data behaviour.
> ...
>>
>> -v4: yinghai add irq_to_desc_alloc_node_x...
>>      so could leave default path not changed...
> 
> Apologies for not noticing this sooner, but ..
> 
>> --- a/arch/powerpc/kernel/irq.c
>> +++ b/arch/powerpc/kernel/irq.c
>> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>>  	return 0;
>>  }
>>  
>> -int arch_init_chip_data(struct irq_desc *desc, int node)
>> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>>  {
>>  	desc->status |= IRQ_NOREQUEST;
>>  	return 0;
> 
> This is a bit feral, that is the init_chip_data_fn.
> 
> It seems like it only exists to support the following on x86:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node,
>> +			 init_chip_data_fn init_chip_data)
>> +{
>> +	if (!init_chip_data)
>> +		return x86_init_chip_data(desc, node);
>> +
>> +	return init_chip_data(desc, node);
>> +}
> 
> Which is really just a hack to avoid an if (xen) check isn't it?

 arch/powerpc/kernel/irq.c      |    2 +-

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;

so this patch only change one line with powerpc code. 
> 
> It looks to me like this should just be done via a current machine
> vector or platform routine, in the same way as powerpc and (I think)
> ia64, ie:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node)
>> +{
>> +	return current_machine->init_chip_data(desc, node);
>> +}
> 
looks like xen in same run time, some irqs need x86_init_chip_data,
and some may need xen_init_chip_data later.

Thanks

Yinghai

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  3:32       ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  3:32 UTC (permalink / raw)
  To: michael
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, lguest, Jeremy Fitzhardinge,
	Rusty Russell, Ian Campbell, Paul Mundt, linux-sh, x86,
	linux-kernel, linuxppc-dev, Ingo Molnar, Paul Mackerras

On 03/21/2010 06:56 PM, Michael Ellerman wrote:
> On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
>> From: Ian Campbell <ian.campbell@citrix.com>
> ...
>> To replace the x86 arch_init_chip_data functionality
>> irq_to_desc_alloc_node now takes a pointer to a function to allocate
>> the chip data. This is necessary to ensure the allocation happens
>> under the correct locking at the core level. On PowerPC and SH
>> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
>> which retains existing chip_data behaviour.
> ...
>>
>> -v4: yinghai add irq_to_desc_alloc_node_x...
>>      so could leave default path not changed...
> 
> Apologies for not noticing this sooner, but ..
> 
>> --- a/arch/powerpc/kernel/irq.c
>> +++ b/arch/powerpc/kernel/irq.c
>> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>>  	return 0;
>>  }
>>  
>> -int arch_init_chip_data(struct irq_desc *desc, int node)
>> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>>  {
>>  	desc->status |= IRQ_NOREQUEST;
>>  	return 0;
> 
> This is a bit feral, that is the init_chip_data_fn.
> 
> It seems like it only exists to support the following on x86:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node,
>> +			 init_chip_data_fn init_chip_data)
>> +{
>> +	if (!init_chip_data)
>> +		return x86_init_chip_data(desc, node);
>> +
>> +	return init_chip_data(desc, node);
>> +}
> 
> Which is really just a hack to avoid an if (xen) check isn't it?

 arch/powerpc/kernel/irq.c      |    2 +-

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;

so this patch only change one line with powerpc code. 
> 
> It looks to me like this should just be done via a current machine
> vector or platform routine, in the same way as powerpc and (I think)
> ia64, ie:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node)
>> +{
>> +	return current_machine->init_chip_data(desc, node);
>> +}
> 
looks like xen in same run time, some irqs need x86_init_chip_data,
and some may need xen_init_chip_data later.

Thanks

Yinghai

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22  3:32       ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22  3:32 UTC (permalink / raw)
  To: michael
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Paul Mundt, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Ingo Molnar, Thomas Gleixner, Ian Campbell

On 03/21/2010 06:56 PM, Michael Ellerman wrote:
> On Sun, 2010-03-21 at 18:36 -0700, Yinghai Lu wrote:
>> From: Ian Campbell <ian.campbell@citrix.com>
> ...
>> To replace the x86 arch_init_chip_data functionality
>> irq_to_desc_alloc_node now takes a pointer to a function to allocate
>> the chip data. This is necessary to ensure the allocation happens
>> under the correct locking at the core level. On PowerPC and SH
>> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
>> which retains existing chip_data behaviour.
> ...
>>
>> -v4: yinghai add irq_to_desc_alloc_node_x...
>>      so could leave default path not changed...
> 
> Apologies for not noticing this sooner, but ..
> 
>> --- a/arch/powerpc/kernel/irq.c
>> +++ b/arch/powerpc/kernel/irq.c
>> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>>  	return 0;
>>  }
>>  
>> -int arch_init_chip_data(struct irq_desc *desc, int node)
>> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>>  {
>>  	desc->status |= IRQ_NOREQUEST;
>>  	return 0;
> 
> This is a bit feral, that is the init_chip_data_fn.
> 
> It seems like it only exists to support the following on x86:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node,
>> +			 init_chip_data_fn init_chip_data)
>> +{
>> +	if (!init_chip_data)
>> +		return x86_init_chip_data(desc, node);
>> +
>> +	return init_chip_data(desc, node);
>> +}
> 
> Which is really just a hack to avoid an if (xen) check isn't it?

 arch/powerpc/kernel/irq.c      |    2 +-

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 64f6f20..cafd378 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
 	return 0;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int node)
+int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
 {
 	desc->status |= IRQ_NOREQUEST;
 	return 0;

so this patch only change one line with powerpc code. 
> 
> It looks to me like this should just be done via a current machine
> vector or platform routine, in the same way as powerpc and (I think)
> ia64, ie:
> 
>> +int arch_init_irq_desc(struct irq_desc *desc, int node)
>> +{
>> +	return current_machine->init_chip_data(desc, node);
>> +}
> 
looks like xen in same run time, some irqs need x86_init_chip_data,
and some may need xen_init_chip_data later.

Thanks

Yinghai

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-22  1:36   ` Yinghai Lu
  (?)
@ 2010-03-22 10:19     ` Thomas Gleixner
  -1 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 10:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Ian Campbell,
	Paul Mundt, linux-sh, x86, linux-kernel, Jesse Barnes,
	linuxppc-dev, Ingo Molnar, Paul Mackerras, Eric W. Biederman,
	H. Peter Anvin, Ingo Molnar, Andrew Morton

On Sun, 21 Mar 2010, Yinghai Lu wrote:

> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Move arch_init_copy_chip_data and arch_free_chip_data into function
> pointers in struct irq_chip since they operate on irq_desc->chip_data.

Not sure about that. These functions are solely used by x86 and there
is really no need to generalize them. The problem you try to solve is
x86/xen specific and can be solved by x86_platform_ops as well w/o
adding extra function pointers to irq_chip.

> arch_init_chip_data cannot be moved into struct irq_chip because
> irq_desc->chip is not known at the time the irq_desc is setup. Instead
> rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
> only other user, whose usage better matches the new name.
> 
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH

Err, that argument is totally bogus. The calling convention of
irq_to_desc_alloc_node and arch_init_chip_data/arch_init_irq_desc is
still the same. It does not explain why the heck we need that function
pointer at all.

AFAICT the function pointer to irq_to_desc_alloc_node is completely
pointless. It just solves a Xen/x86 specific problem which can be
solved by using x86_platform_ops and keeps the churn x86 internal.

> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
 
> I've retained the chip_data behaviour for uv_irq although it isn't
> clear to me if these interrupt types support migration or how closely
> related to the APIC modes they really are. If it weren't for this the
> x86_{init,copy,free}_chip_data functions could be static to
> io_apic.c.
> 
> I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
> and 32 bit without, but it's not clear to me what actions I need to
> take to actually exercise some of these code paths.
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...

Aside of the general objection against this, please use descriptive
function names and do not distinguish functions by adding random
characters which tell us absolutely nothing about the purpose.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22 10:19     ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 10:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, H. Peter Anvin, Andrew Morton, Eric W. Biederman,
	Jesse Barnes, linux-kernel, Ian Campbell, Ingo Molnar,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

On Sun, 21 Mar 2010, Yinghai Lu wrote:

> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Move arch_init_copy_chip_data and arch_free_chip_data into function
> pointers in struct irq_chip since they operate on irq_desc->chip_data.

Not sure about that. These functions are solely used by x86 and there
is really no need to generalize them. The problem you try to solve is
x86/xen specific and can be solved by x86_platform_ops as well w/o
adding extra function pointers to irq_chip.

> arch_init_chip_data cannot be moved into struct irq_chip because
> irq_desc->chip is not known at the time the irq_desc is setup. Instead
> rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
> only other user, whose usage better matches the new name.
> 
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH

Err, that argument is totally bogus. The calling convention of
irq_to_desc_alloc_node and arch_init_chip_data/arch_init_irq_desc is
still the same. It does not explain why the heck we need that function
pointer at all.

AFAICT the function pointer to irq_to_desc_alloc_node is completely
pointless. It just solves a Xen/x86 specific problem which can be
solved by using x86_platform_ops and keeps the churn x86 internal.

> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
 
> I've retained the chip_data behaviour for uv_irq although it isn't
> clear to me if these interrupt types support migration or how closely
> related to the APIC modes they really are. If it weren't for this the
> x86_{init,copy,free}_chip_data functions could be static to
> io_apic.c.
> 
> I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
> and 32 bit without, but it's not clear to me what actions I need to
> take to actually exercise some of these code paths.
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...

Aside of the general objection against this, please use descriptive
function names and do not distinguish functions by adding random
characters which tell us absolutely nothing about the purpose.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-22 10:19     ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 10:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Ian Campbell,
	Paul Mundt, linux-sh, x86, linux-kernel, Jesse Barnes,
	linuxppc-dev, Ingo Molnar, Paul Mackerras, Eric W. Biederman,
	H. Peter Anvin, Ingo Molnar, Andrew Morton

On Sun, 21 Mar 2010, Yinghai Lu wrote:

> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Move arch_init_copy_chip_data and arch_free_chip_data into function
> pointers in struct irq_chip since they operate on irq_desc->chip_data.

Not sure about that. These functions are solely used by x86 and there
is really no need to generalize them. The problem you try to solve is
x86/xen specific and can be solved by x86_platform_ops as well w/o
adding extra function pointers to irq_chip.

> arch_init_chip_data cannot be moved into struct irq_chip because
> irq_desc->chip is not known at the time the irq_desc is setup. Instead
> rename arch_init_chip_data to arch_init_irq_desc for PowerPC, the
> only other user, whose usage better matches the new name.
> 
> To replace the x86 arch_init_chip_data functionality
> irq_to_desc_alloc_node now takes a pointer to a function to allocate
> the chip data. This is necessary to ensure the allocation happens
> under the correct locking at the core level. On PowerPC and SH

Err, that argument is totally bogus. The calling convention of
irq_to_desc_alloc_node and arch_init_chip_data/arch_init_irq_desc is
still the same. It does not explain why the heck we need that function
pointer at all.

AFAICT the function pointer to irq_to_desc_alloc_node is completely
pointless. It just solves a Xen/x86 specific problem which can be
solved by using x86_platform_ops and keeps the churn x86 internal.

> architectures (the other users of irq_to_desc_alloc_node) pass in NULL
> which retains existing chip_data behaviour.
 
> I've retained the chip_data behaviour for uv_irq although it isn't
> clear to me if these interrupt types support migration or how closely
> related to the APIC modes they really are. If it weren't for this the
> x86_{init,copy,free}_chip_data functions could be static to
> io_apic.c.
> 
> I've tested by booting on an 64 bit x86 system with sparse IRQ enabled
> and 32 bit without, but it's not clear to me what actions I need to
> take to actually exercise some of these code paths.
> 
> -v4: yinghai add irq_to_desc_alloc_node_x...

Aside of the general objection against this, please use descriptive
function names and do not distinguish functions by adding random
characters which tell us absolutely nothing about the purpose.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 02/10] x86: fix out of order of gsi - full
  2010-03-22  1:36 ` [PATCH 02/10] x86: fix out of order of gsi - full Yinghai Lu
@ 2010-03-22 11:14   ` Thomas Gleixner
  2010-03-22 19:45     ` Yinghai Lu
  2010-03-29 13:40     ` Eric W. Biederman
  0 siblings, 2 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 11:14 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, H. Peter Anvin, Andrew Morton, Eric W. Biederman,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown

On Sun, 21 Mar 2010, Yinghai Lu wrote:
> +extern int gsi_delta;

  Is this really necessary ? See below.

> +int gsi_to_irq(unsigned int gsi);

  unsigned int please

> +unsigned int irq_to_gsi(int irq);

  Ditto

> @@ -446,11 +448,11 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
>  
>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>  {
> -	*irq = gsi;
> +	*irq = gsi_to_irq(gsi);
>  
>  #ifdef CONFIG_X86_IO_APIC
>  	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
> -		setup_IO_APIC_irq_extra(gsi);
> +		setup_IO_APIC_irq_extra(gsi, irq);

  Please do not propagate that pointer.

    	 *irq = setup_IO_APIC_irq_extra(gsi);

  Also these changes have a total lack of comments. Why do we modify
  *irq here depending on the setup_IO_APIC_irq_extra() results ?

>  #endif
>  
>  	return 0;
> @@ -914,6 +916,40 @@ static void save_mp_irq(struct mpc_intsrc *m)
>  		panic("Max # of irq sources exceeded!!\n");
>  }
>  
> +/* By default isa irqs are identity mapped to gsis */
> +static unsigned int isa_irq_to_gsi[NR_IRQS_LEGACY] = {
> +	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
> +};
> +
> +int gsi_delta;

  Please make this static and provide a function to modify it from
  probe_ioapic_i8259().

  Also the variable name is horrible. What's the delta here ? It's an
  offset, right ?

> +int gsi_to_irq(unsigned int gsi)

unsigned int

> +{
> +	unsigned int irq = gsi;
> +	unsigned int i;
> +
> +	irq += gsi_delta;

  Please make that:

  	 unsigned int i, irq = gsi + gsi_delta;

> +	for (i = 0; i < NR_IRQS_LEGACY; i++) {
> +		if (isa_irq_to_gsi[i] == gsi) {
> +			irq = i;
> +			break;
> +		}
> +	}
> +
> +	return irq;
> +}
> +
> +unsigned int irq_to_gsi(int irq)

  unsigned int please

> +{
> +	unsigned int gsi;
> +
> +	if (irq < NR_IRQS_LEGACY)
> +		gsi = isa_irq_to_gsi[irq];
> +	else
> +		gsi = irq - gsi_delta;
> +
> +	return gsi;
> +}
> +
>  void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
>  {
>  	int ioapic;
> @@ -945,6 +981,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
>  	mp_irq.dstirq = pin;	/* INTIN# */
>  
>  	save_mp_irq(&mp_irq);
> +
> +	isa_irq_to_gsi[bus_irq] = gsi;

>  }
>  
>  void __init mp_config_acpi_legacy_irqs(void)
> @@ -974,7 +1012,7 @@ void __init mp_config_acpi_legacy_irqs(void)
>  	/*
>  	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
>  	 */
> -	ioapic = mp_find_ioapic(0);
> +	ioapic = mp_find_ioapic(irq_to_gsi(0));
>  	if (ioapic < 0)
>  		return;
>  	dstapic = mp_ioapics[ioapic].apicid;
> @@ -1057,6 +1095,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)

  Why is mp_register_gsi global ? It's only used in
  arch/x86/kernel/acpi/boot.c

>  {
>  	int ioapic;
>  	int ioapic_pin;
> +	int irq;

  irq is unsigned int.

>  	struct io_apic_irq_attr irq_attr;
>  
>  	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
> @@ -1079,11 +1118,12 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>  		gsi = ioapic_renumber_irq(ioapic, gsi);
>  #endif
>  
> +	irq = gsi_to_irq(gsi);
>  	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
>  		printk(KERN_ERR "Invalid reference to IOAPIC pin "
>  		       "%d-%d\n", mp_ioapics[ioapic].apicid,
>  		       ioapic_pin);
> -		return gsi;
> +		return irq;
>  	}
>  
>  	if (enable_update_mptable)
> @@ -1092,9 +1132,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>  	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
>  			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
>  			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
> -	io_apic_set_pci_routing(dev, gsi, &irq_attr);
> +	io_apic_set_pci_routing(dev, irq, &irq_attr);
>  
> -	return gsi;
> +	return irq;
>  }
>  
>  /*
> @@ -1151,8 +1191,10 @@ static int __init acpi_parse_madt_ioapic_entries(void)
>  	 * If BIOS did not supply an INT_SRC_OVR for the SCI
>  	 * pretend we got one so we can set the SCI flags.
>  	 */
> -	if (!acpi_sci_override_gsi)
> -		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
> +	if (!acpi_sci_override_gsi) {
> +		int irq = gsi_to_irq(acpi_gbl_FADT.sci_interrupt);

  unsigned int. New line between variable declaration and code.

> +		acpi_sci_ioapic_setup(irq, acpi_gbl_FADT.sci_interrupt, 0, 0);
> +	}
>  
>  	/* Fill in identity legacy mappings where no override */
>  	mp_config_acpi_legacy_irqs();
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index a917fdf..61b59ef 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -97,6 +97,8 @@ int mp_irq_entries;
>  /* GSI interrupts */
>  static int nr_irqs_gsi = NR_IRQS_LEGACY;
>  
> +static int boot_ioapic_idx;
> +
>  #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
>  int mp_bus_id_to_type[MAX_MP_BUSSES];
>  #endif
> @@ -1032,7 +1034,7 @@ static inline int irq_trigger(int idx)
>  int (*ioapic_renumber_irq)(int ioapic, int irq);
>  static int pin_2_irq(int idx, int apic, int pin)
>  {
> -	int irq, i;
> +	int irq;

  Can we please do a cleanup of irq variables to use unsigned
  int. That should be done as a separate patch.

>  	int bus = mp_irqs[idx].srcbus;
>  
>  	/*
> @@ -1044,18 +1046,28 @@ static int pin_2_irq(int idx, int apic, int pin)
>  	if (test_bit(bus, mp_bus_not_pci)) {
>  		irq = mp_irqs[idx].srcbusirq;

  Can we simply return mp_irqs[idx].srcbusirq here and get rid of the
  else path ident level ?

>  	} else {
> -		/*
> -		 * PCI IRQs are mapped in order
> -		 */
> -		i = irq = 0;
> -		while (i < apic)
> -			irq += nr_ioapic_registers[i++];
> -		irq += pin;
> +		unsigned int gsi;

  New line please

> +		if (!acpi_ioapic) {
> +			int i;

  

> +			/*
> +			 * PCI IRQs are mapped in order
> +			 */
> +			i = gsi = 0;
> +			while (i < apic)
> +				gsi += nr_ioapic_registers[i++];
> +			gsi += pin;
> +		} else
> +			gsi = pin + mp_gsi_routing[apic].gsi_base;
> +
> +#ifdef CONFIG_X86_32
>  		/*
>                   * For MPS mode, so far only needed by ES7000 platform
>                   */
>  		if (ioapic_renumber_irq)
> -			irq = ioapic_renumber_irq(apic, irq);
> +			gsi = ioapic_renumber_irq(apic, gsi);
> +#endif
> +
> +		irq = gsi_to_irq(gsi);
>  	}
>  
>  #ifdef CONFIG_X86_32
> @@ -1505,9 +1517,10 @@ static void __init setup_IO_APIC_irqs(void)
>  	struct irq_cfg *cfg;
>  	int node = cpu_to_node(boot_cpu_id);
>  
> +	apic_id = boot_ioapic_idx;
> +
>  	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
>  
> -	for (apic_id = 0; apic_id < nr_ioapics; apic_id++)
>  	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
>  		idx = find_irq_entry(apic_id, pin, mp_INT);
>  		if (idx == -1) {
> @@ -1529,9 +1542,6 @@ static void __init setup_IO_APIC_irqs(void)
>  
>  		irq = pin_2_irq(idx, apic_id, pin);
>  
> -		if ((apic_id > 0) && (irq > 16))
> -			continue;
> -
>  		/*
>  		 * Skip the timer IRQ if there's a quirk handler
>  		 * installed and if it returns 1:
> @@ -1565,7 +1575,7 @@ static void __init setup_IO_APIC_irqs(void)
>   * but could not use acpi_register_gsi()
>   * like some special sci in IBM x3330
>   */
> -void setup_IO_APIC_irq_extra(u32 gsi)
> +void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *pirq)
>  {
>  	int apic_id = 0, pin, idx, irq;
>  	int node = cpu_to_node(boot_cpu_id);
> @@ -1585,6 +1595,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
>  		return;
>  
>  	irq = pin_2_irq(idx, apic_id, pin);
> +	*pirq = irq;
>  #ifdef CONFIG_SPARSE_IRQ
>  	desc = irq_to_desc(irq);
>  	if (desc)
> @@ -2028,6 +2039,30 @@ void __init enable_IO_APIC(void)
>  	clear_IO_APIC();
>  }
>  
> +static void __init probe_ioapic_i8259(void)
> +{
> +	/* probe boot ioapic idx */
> +	boot_ioapic_idx = ioapic_i8259.apic;

  boot_ioapic_idx is an apic id. Why is the variable name suggesting
  it's an index ?

> +	if (boot_ioapic_idx < 0)
> +		boot_ioapic_idx = find_isa_irq_apic(0, mp_INT);
> +#ifdef CONFIG_ACPI
> +	if (!acpi_disabled && acpi_ioapic && boot_ioapic_idx < 0)
> +		boot_ioapic_idx = mp_find_ioapic(irq_to_gsi(0));
> +#endif
> +	if (boot_ioapic_idx < 0)
> +		boot_ioapic_idx = 0;
> +
> +#ifdef CONFIG_ACPI
> +	if (mp_gsi_routing[boot_ioapic_idx].gsi_base) {
> +		gsi_delta = NR_IRQS_LEGACY;
> +		nr_irqs_gsi += NR_IRQS_LEGACY;
> +		printk(KERN_DEBUG "new nr_irqs_gsi: %d\n", nr_irqs_gsi);
> +	}
> +#endif
> +
> +	printk(KERN_INFO "boot_ioapic_idx: %d\n", boot_ioapic_idx);
> +}
> +
>  /*
>   * Not an __init, needed by the reboot code
>   */
> @@ -3045,7 +3080,7 @@ static inline void __init check_timer(void)
>  				legacy_pic->chip->unmask(0);
>  			}
>  			if (disable_timer_pin_1 > 0)
> -				clear_IO_APIC_pin(0, pin1);
> +				clear_IO_APIC_pin(apic1, pin1);

  How is this change related to this patch ? It looks more like an
  independent fix.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 04/10] x86: kill smpboot_hooks.h
  2010-03-22  1:36 ` [PATCH 04/10] x86: kill smpboot_hooks.h Yinghai Lu
@ 2010-03-22 13:34   ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 13:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, H. Peter Anvin, Andrew Morton, Eric W. Biederman,
	Jesse Barnes, linux-kernel

On Sun, 21 Mar 2010, Yinghai Lu wrote:

> only one user, move it back to smpboot.c
> 
> remove smpboot_clear_io_apic, and only keep smpboot_clear_io_apic_irqs.
> 
> and check nr_legacy_irqs before clear it.

This is not the way how we do that. We move code in one patch and then
do modification in the follow up patch. Doing both makes it harder
than necessary to follow the code change.

As a side note, that changelog for the removal of
smpboot_clear_io_apic is not telling anything why that change is
functional equivivalent to the original code. And I doubt that it's
correct.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 05/10] x86: use vector_desc instead of vector_irq
  2010-03-22  1:36 ` [PATCH 05/10] x86: use vector_desc instead of vector_irq Yinghai Lu
@ 2010-03-22 13:58   ` Thomas Gleixner
  2010-03-22 14:04     ` Eric W. Biederman
  0 siblings, 1 reply; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 13:58 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, H. Peter Anvin, Andrew Morton, Eric W. Biederman,
	Jesse Barnes, linux-kernel

On Sun, 21 Mar 2010, Yinghai Lu wrote:

> Eric pointed out that radix tree version of irq_to_desc will magnify delay on
> the path of handle_irq.
> 
> use vector_desc to reduce the calling of irq_to_desc.
> 
> next step: need to change all ack, mask, umask, eoi for all irq_chip to take irq_desc

That's not relevant for this change.
 
>  
> -typedef int vector_irq_t[NR_VECTORS];
> -DECLARE_PER_CPU(vector_irq_t, vector_irq);
> -extern void setup_vector_irq(int cpu);
> +typedef struct irq_desc *vector_desc_t[NR_VECTORS];

  Why do we need that typedef ? Please use plain struct irq_desc *

> +DECLARE_PER_CPU(vector_desc_t, vector_desc);
> +extern void setup_vector_desc(int cpu);
...
>  void destroy_irq(unsigned int irq)
>  {
>  	unsigned long flags;
> +	struct irq_desc *desc;
> +	struct irq_cfg *cfg;
>  
>  	dynamic_irq_cleanup_keep_chip_data(irq);
>  
>  	free_irte(irq);
>  	raw_spin_lock_irqsave(&vector_lock, flags);
> -	__clear_irq_vector(irq, get_irq_chip_data(irq));
> +	desc = irq_to_desc(irq);
> +	cfg = desc->chip_data;
> +	__clear_irq_vector(desc, cfg);

	__clear_irq_vector(desc, desc->chip_data);

 should be sufficient, right ?

>  	raw_spin_unlock_irqrestore(&vector_lock, flags);
>  }
>  
> @@ -3377,6 +3376,7 @@ void destroy_irq(unsigned int irq)
>  static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
>  			   struct msi_msg *msg, u8 hpet_id)
>  {
> +	struct irq_desc *desc;
>  	struct irq_cfg *cfg;
>  	int err;
>  	unsigned dest;
> @@ -3384,8 +3384,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
>  	if (disable_apic)
>  		return -ENXIO;
>  
> -	cfg = irq_cfg(irq);
> -	err = assign_irq_vector(irq, cfg, apic->target_cpus());
> +	desc = irq_to_desc(irq);
> +	cfg = desc->chip_data;
> +	err = assign_irq_vector(desc, cfg, apic->target_cpus());

  Ditto

>  	if (err)
>  		return err;
>  
> @@ -3876,14 +3877,16 @@ static struct irq_chip ht_irq_chip = {
>  
>  int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
>  {
> +	struct irq_desc *desc;
>  	struct irq_cfg *cfg;
>  	int err;
>  
>  	if (disable_apic)
>  		return -ENXIO;
>  
> -	cfg = irq_cfg(irq);
> -	err = assign_irq_vector(irq, cfg, apic->target_cpus());
> +	desc = irq_to_desc(irq);
> +	cfg = desc->chip_data;
> +	err = assign_irq_vector(desc, cfg, apic->target_cpus());

  Ditto

>  	if (!err) {
>  		struct ht_irq_msg msg;
>  		unsigned dest;
> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
> index 91fd0c7..f71625c 100644
> --- a/arch/x86/kernel/irq.c
> +++ b/arch/x86/kernel/irq.c
> @@ -229,19 +229,19 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
>  
>  	/* high bit used in ret_from_ code  */
>  	unsigned vector = ~regs->orig_ax;
> -	unsigned irq;
> +	struct irq_desc *desc;
>  
>  	exit_idle();
>  	irq_enter();
>  
> -	irq = __get_cpu_var(vector_irq)[vector];
> +	desc = __get_cpu_var(vector_desc)[vector];
>  
> -	if (!handle_irq(irq, regs)) {
> +	if (!handle_irq(desc, regs)) {
>  		ack_APIC_irq();
>  
>  		if (printk_ratelimit())
> -			pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
> -				__func__, smp_processor_id(), vector, irq);
> +			pr_emerg("%s: %d.%d No irq handler for vector\n",

  That printk is confusing. It's not lacking an irq handler. The
  vector is simply not assigned.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 05/10] x86: use vector_desc instead of vector_irq
  2010-03-22 13:58   ` Thomas Gleixner
@ 2010-03-22 14:04     ` Eric W. Biederman
  2010-03-22 14:16       ` Thomas Gleixner
  0 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-22 14:04 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Jesse Barnes, linux-kernel

Thomas Gleixner <tglx@linutronix.de> writes:

> On Sun, 21 Mar 2010, Yinghai Lu wrote:
>
>> Eric pointed out that radix tree version of irq_to_desc will magnify delay on
>> the path of handle_irq.
>> 
>> use vector_desc to reduce the calling of irq_to_desc.
>> 
>> next step: need to change all ack, mask, umask, eoi for all irq_chip to take irq_desc
>
> That's not relevant for this change.
>  
>>  
>> -typedef int vector_irq_t[NR_VECTORS];
>> -DECLARE_PER_CPU(vector_irq_t, vector_irq);
>> -extern void setup_vector_irq(int cpu);
>> +typedef struct irq_desc *vector_desc_t[NR_VECTORS];
>
>   Why do we need that typedef ? Please use plain struct irq_desc *

Well at least originally DECLARE_PER_CPU chocked when given a complex
type. Does:
DECLARE_PER_CPU(struct irq_desc *[NR_VECTORS], vector_desc);
work?


>> +DECLARE_PER_CPU(vector_desc_t, vector_desc);
>> +extern void setup_vector_desc(int cpu);
> ...
>>  void destroy_irq(unsigned int irq)
>>  {
>>  	unsigned long flags;
>> +	struct irq_desc *desc;
>> +	struct irq_cfg *cfg;
>>  
>>  	dynamic_irq_cleanup_keep_chip_data(irq);
>>  
>>  	free_irte(irq);
>>  	raw_spin_lock_irqsave(&vector_lock, flags);
>> -	__clear_irq_vector(irq, get_irq_chip_data(irq));
>> +	desc = irq_to_desc(irq);
>> +	cfg = desc->chip_data;
>> +	__clear_irq_vector(desc, cfg);
>
> 	__clear_irq_vector(desc, desc->chip_data);
>
>  should be sufficient, right ?

You want to deliberately loose a modicum of type safety?


>
>>  	raw_spin_unlock_irqrestore(&vector_lock, flags);
>>  }
>>  
>> @@ -3377,6 +3376,7 @@ void destroy_irq(unsigned int irq)
>>  static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
>>  			   struct msi_msg *msg, u8 hpet_id)
>>  {
>> +	struct irq_desc *desc;
>>  	struct irq_cfg *cfg;
>>  	int err;
>>  	unsigned dest;
>> @@ -3384,8 +3384,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
>>  	if (disable_apic)
>>  		return -ENXIO;
>>  
>> -	cfg = irq_cfg(irq);
>> -	err = assign_irq_vector(irq, cfg, apic->target_cpus());
>> +	desc = irq_to_desc(irq);
>> +	cfg = desc->chip_data;
>> +	err = assign_irq_vector(desc, cfg, apic->target_cpus());
>
>   Ditto
>
>>  	if (err)
>>  		return err;
>>  
>> @@ -3876,14 +3877,16 @@ static struct irq_chip ht_irq_chip = {
>>  
>>  int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
>>  {
>> +	struct irq_desc *desc;
>>  	struct irq_cfg *cfg;
>>  	int err;
>>  
>>  	if (disable_apic)
>>  		return -ENXIO;
>>  
>> -	cfg = irq_cfg(irq);
>> -	err = assign_irq_vector(irq, cfg, apic->target_cpus());
>> +	desc = irq_to_desc(irq);
>> +	cfg = desc->chip_data;
>> +	err = assign_irq_vector(desc, cfg, apic->target_cpus());
>
>   Ditto
>
>>  	if (!err) {
>>  		struct ht_irq_msg msg;
>>  		unsigned dest;
>> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
>> index 91fd0c7..f71625c 100644
>> --- a/arch/x86/kernel/irq.c
>> +++ b/arch/x86/kernel/irq.c
>> @@ -229,19 +229,19 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
>>  
>>  	/* high bit used in ret_from_ code  */
>>  	unsigned vector = ~regs->orig_ax;
>> -	unsigned irq;
>> +	struct irq_desc *desc;
>>  
>>  	exit_idle();
>>  	irq_enter();
>>  
>> -	irq = __get_cpu_var(vector_irq)[vector];
>> +	desc = __get_cpu_var(vector_desc)[vector];
>>  
>> -	if (!handle_irq(irq, regs)) {
>> +	if (!handle_irq(desc, regs)) {
>>  		ack_APIC_irq();
>>  
>>  		if (printk_ratelimit())
>> -			pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
>> -				__func__, smp_processor_id(), vector, irq);
>> +			pr_emerg("%s: %d.%d No irq handler for vector\n",
>
>   That printk is confusing. It's not lacking an irq handler. The
>   vector is simply not assigned.

Long evolution.  Do you have a suggestion of better wording?

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 05/10] x86: use vector_desc instead of vector_irq
  2010-03-22 14:04     ` Eric W. Biederman
@ 2010-03-22 14:16       ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-22 14:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Jesse Barnes, linux-kernel

> >> -typedef int vector_irq_t[NR_VECTORS];
> >> -DECLARE_PER_CPU(vector_irq_t, vector_irq);
> >> -extern void setup_vector_irq(int cpu);
> >> +typedef struct irq_desc *vector_desc_t[NR_VECTORS];
> >
> >   Why do we need that typedef ? Please use plain struct irq_desc *
> 
> Well at least originally DECLARE_PER_CPU chocked when given a complex
> type. Does:
> DECLARE_PER_CPU(struct irq_desc *[NR_VECTORS], vector_desc);
> work?

Hmm, I thought that was fixed, but I might be wrong as usual.
 
> 
> >> +DECLARE_PER_CPU(vector_desc_t, vector_desc);
> >> +extern void setup_vector_desc(int cpu);
> > ...
> >>  void destroy_irq(unsigned int irq)
> >>  {
> >>  	unsigned long flags;
> >> +	struct irq_desc *desc;
> >> +	struct irq_cfg *cfg;
> >>  
> >>  	dynamic_irq_cleanup_keep_chip_data(irq);
> >>  
> >>  	free_irte(irq);
> >>  	raw_spin_lock_irqsave(&vector_lock, flags);
> >> -	__clear_irq_vector(irq, get_irq_chip_data(irq));
> >> +	desc = irq_to_desc(irq);
> >> +	cfg = desc->chip_data;
> >> +	__clear_irq_vector(desc, cfg);
> >
> > 	__clear_irq_vector(desc, desc->chip_data);
> >
> >  should be sufficient, right ?
> 
> You want to deliberately loose a modicum of type safety?

I really have a hard time to see how assigning a void pointer to a
struct irq_cfg pointer is anymore type safe than using the void
pointer as for the function argument right away. 

> >>  		if (printk_ratelimit())
> >> -			pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
> >> -				__func__, smp_processor_id(), vector, irq);
> >> +			pr_emerg("%s: %d.%d No irq handler for vector\n",
> >
> >   That printk is confusing. It's not lacking an irq handler. The
> >   vector is simply not assigned.
> 
> Long evolution.  Do you have a suggestion of better wording?

You mean hysterical raisins. Ok, how about:

    pr_emerg("irq: %d.d irq vector not assigned\n", ...);

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 02/10] x86: fix out of order of gsi - full
  2010-03-22 11:14   ` Thomas Gleixner
@ 2010-03-22 19:45     ` Yinghai Lu
  2010-03-29 13:40     ` Eric W. Biederman
  1 sibling, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-22 19:45 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, H. Peter Anvin, Andrew Morton, Eric W. Biederman,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown

On 03/22/2010 04:14 AM, Thomas Gleixner wrote:
> On Sun, 21 Mar 2010, Yinghai Lu wrote:
>> +extern int gsi_delta;
> 
>   Is this really necessary ? See below.
> 
>> +int gsi_to_irq(unsigned int gsi);
> 
>   unsigned int please
> 
>> +unsigned int irq_to_gsi(int irq);
> 
>   Ditto

ok

> 
>> @@ -446,11 +448,11 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
>>  
>>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>>  {
>> -	*irq = gsi;
>> +	*irq = gsi_to_irq(gsi);
>>  
>>  #ifdef CONFIG_X86_IO_APIC
>>  	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
>> -		setup_IO_APIC_irq_extra(gsi);
>> +		setup_IO_APIC_irq_extra(gsi, irq);
> 
>   Please do not propagate that pointer.
> 
>     	 *irq = setup_IO_APIC_irq_extra(gsi);
> 
>   Also these changes have a total lack of comments. Why do we modify
>   *irq here depending on the setup_IO_APIC_irq_extra() results ?
> 
looks *irq = gsi_to_irq(gsi) should already do the work for us.
>>  #endif
>>  
>>  	return 0;
>> @@ -914,6 +916,40 @@ static void save_mp_irq(struct mpc_intsrc *m)
>>  		panic("Max # of irq sources exceeded!!\n");
>>  }
>>  
>> +/* By default isa irqs are identity mapped to gsis */
>> +static unsigned int isa_irq_to_gsi[NR_IRQS_LEGACY] = {
>> +	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
>> +};
>> +
>> +int gsi_delta;
> 
>   Please make this static and provide a function to modify it from
>   probe_ioapic_i8259().
> 
>   Also the variable name is horrible. What's the delta here ? It's an
>   offset, right ?

yes. offset for non legacy irq.

> 
>> +int gsi_to_irq(unsigned int gsi)
> 
> unsigned int
> 
>> +{
>> +	unsigned int irq = gsi;
>> +	unsigned int i;
>> +
>> +	irq += gsi_delta;
> 
>   Please make that:
> 
>   	 unsigned int i, irq = gsi + gsi_delta;

ok

> 
>> +	for (i = 0; i < NR_IRQS_LEGACY; i++) {
>> +		if (isa_irq_to_gsi[i] == gsi) {
>> +			irq = i;
>> +			break;
>> +		}
>> +	}
>> +
>> +	return irq;
>> +}
>> +
>> +unsigned int irq_to_gsi(int irq)
> 
>   unsigned int please

ok

> 
>> +{
>> +	unsigned int gsi;
>> +
>> +	if (irq < NR_IRQS_LEGACY)
>> +		gsi = isa_irq_to_gsi[irq];
>> +	else
>> +		gsi = irq - gsi_delta;
>> +
>> +	return gsi;
>> +}
>> +
>>  void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
>>  {
>>  	int ioapic;
>> @@ -945,6 +981,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
>>  	mp_irq.dstirq = pin;	/* INTIN# */
>>  
>>  	save_mp_irq(&mp_irq);
>> +
>> +	isa_irq_to_gsi[bus_irq] = gsi;
> 
>>  }
>>  
>>  void __init mp_config_acpi_legacy_irqs(void)
>> @@ -974,7 +1012,7 @@ void __init mp_config_acpi_legacy_irqs(void)
>>  	/*
>>  	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
>>  	 */
>> -	ioapic = mp_find_ioapic(0);
>> +	ioapic = mp_find_ioapic(irq_to_gsi(0));
>>  	if (ioapic < 0)
>>  		return;
>>  	dstapic = mp_ioapics[ioapic].apicid;
>> @@ -1057,6 +1095,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
> 
>   Why is mp_register_gsi global ? It's only used in
>   arch/x86/kernel/acpi/boot.c

yes.

should adjust that function position.

arch/x86/kernel/acpi/boot.c:            plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
arch/x86/kernel/acpi/boot.c:int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)


> 
>>  {
>>  	int ioapic;
>>  	int ioapic_pin;
>> +	int irq;
> 
>   irq is unsigned int.
> 
>>  	struct io_apic_irq_attr irq_attr;
>>  
>>  	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
>> @@ -1079,11 +1118,12 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>>  		gsi = ioapic_renumber_irq(ioapic, gsi);
>>  #endif
>>  
>> +	irq = gsi_to_irq(gsi);
>>  	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
>>  		printk(KERN_ERR "Invalid reference to IOAPIC pin "
>>  		       "%d-%d\n", mp_ioapics[ioapic].apicid,
>>  		       ioapic_pin);
>> -		return gsi;
>> +		return irq;
>>  	}
>>  
>>  	if (enable_update_mptable)
>> @@ -1092,9 +1132,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>>  	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
>>  			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
>>  			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
>> -	io_apic_set_pci_routing(dev, gsi, &irq_attr);
>> +	io_apic_set_pci_routing(dev, irq, &irq_attr);
>>  
>> -	return gsi;
>> +	return irq;
>>  }
>>  
>>  /*
>> @@ -1151,8 +1191,10 @@ static int __init acpi_parse_madt_ioapic_entries(void)
>>  	 * If BIOS did not supply an INT_SRC_OVR for the SCI
>>  	 * pretend we got one so we can set the SCI flags.
>>  	 */
>> -	if (!acpi_sci_override_gsi)
>> -		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
>> +	if (!acpi_sci_override_gsi) {
>> +		int irq = gsi_to_irq(acpi_gbl_FADT.sci_interrupt);
> 
>   unsigned int. New line between variable declaration and code.
> 
>> +		acpi_sci_ioapic_setup(irq, acpi_gbl_FADT.sci_interrupt, 0, 0);
>> +	}
>>  
>>  	/* Fill in identity legacy mappings where no override */
>>  	mp_config_acpi_legacy_irqs();
>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index a917fdf..61b59ef 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -97,6 +97,8 @@ int mp_irq_entries;
>>  /* GSI interrupts */
>>  static int nr_irqs_gsi = NR_IRQS_LEGACY;
>>  
>> +static int boot_ioapic_idx;
>> +
>>  #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
>>  int mp_bus_id_to_type[MAX_MP_BUSSES];
>>  #endif
>> @@ -1032,7 +1034,7 @@ static inline int irq_trigger(int idx)
>>  int (*ioapic_renumber_irq)(int ioapic, int irq);
>>  static int pin_2_irq(int idx, int apic, int pin)
>>  {
>> -	int irq, i;
>> +	int irq;
> 
>   Can we please do a cleanup of irq variables to use unsigned
>   int. That should be done as a separate patch.

ok

> 
>>  	int bus = mp_irqs[idx].srcbus;
>>  
>>  	/*
>> @@ -1044,18 +1046,28 @@ static int pin_2_irq(int idx, int apic, int pin)
>>  	if (test_bit(bus, mp_bus_not_pci)) {
>>  		irq = mp_irqs[idx].srcbusirq;
> 
>   Can we simply return mp_irqs[idx].srcbusirq here and get rid of the
>   else path ident level ?
> 
>>  	} else {
>> -		/*
>> -		 * PCI IRQs are mapped in order
>> -		 */
>> -		i = irq = 0;
>> -		while (i < apic)
>> -			irq += nr_ioapic_registers[i++];
>> -		irq += pin;
>> +		unsigned int gsi;
> 
>   New line please
> 
>> +		if (!acpi_ioapic) {
>> +			int i;
> 
>   
> 
>> +			/*
>> +			 * PCI IRQs are mapped in order
>> +			 */
>> +			i = gsi = 0;
>> +			while (i < apic)
>> +				gsi += nr_ioapic_registers[i++];
>> +			gsi += pin;
>> +		} else
>> +			gsi = pin + mp_gsi_routing[apic].gsi_base;
>> +
>> +#ifdef CONFIG_X86_32
>>  		/*
>>                   * For MPS mode, so far only needed by ES7000 platform
>>                   */
>>  		if (ioapic_renumber_irq)
>> -			irq = ioapic_renumber_irq(apic, irq);
>> +			gsi = ioapic_renumber_irq(apic, gsi);
>> +#endif
>> +
>> +		irq = gsi_to_irq(gsi);
>>  	}
>>  
>>  #ifdef CONFIG_X86_32
>> @@ -1505,9 +1517,10 @@ static void __init setup_IO_APIC_irqs(void)
>>  	struct irq_cfg *cfg;
>>  	int node = cpu_to_node(boot_cpu_id);
>>  
>> +	apic_id = boot_ioapic_idx;
>> +
>>  	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
>>  
>> -	for (apic_id = 0; apic_id < nr_ioapics; apic_id++)
>>  	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
>>  		idx = find_irq_entry(apic_id, pin, mp_INT);
>>  		if (idx == -1) {
>> @@ -1529,9 +1542,6 @@ static void __init setup_IO_APIC_irqs(void)
>>  
>>  		irq = pin_2_irq(idx, apic_id, pin);
>>  
>> -		if ((apic_id > 0) && (irq > 16))
>> -			continue;
>> -
>>  		/*
>>  		 * Skip the timer IRQ if there's a quirk handler
>>  		 * installed and if it returns 1:
>> @@ -1565,7 +1575,7 @@ static void __init setup_IO_APIC_irqs(void)
>>   * but could not use acpi_register_gsi()
>>   * like some special sci in IBM x3330
>>   */
>> -void setup_IO_APIC_irq_extra(u32 gsi)
>> +void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *pirq)
>>  {
>>  	int apic_id = 0, pin, idx, irq;
>>  	int node = cpu_to_node(boot_cpu_id);
>> @@ -1585,6 +1595,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
>>  		return;
>>  
>>  	irq = pin_2_irq(idx, apic_id, pin);
>> +	*pirq = irq;
>>  #ifdef CONFIG_SPARSE_IRQ
>>  	desc = irq_to_desc(irq);
>>  	if (desc)
>> @@ -2028,6 +2039,30 @@ void __init enable_IO_APIC(void)
>>  	clear_IO_APIC();
>>  }
>>  
>> +static void __init probe_ioapic_i8259(void)
>> +{
>> +	/* probe boot ioapic idx */
>> +	boot_ioapic_idx = ioapic_i8259.apic;
> 
>   boot_ioapic_idx is an apic id. Why is the variable name suggesting
>   it's an index ?

it is an index.

> 
>> +	if (boot_ioapic_idx < 0)
>> +		boot_ioapic_idx = find_isa_irq_apic(0, mp_INT);
>> +#ifdef CONFIG_ACPI
>> +	if (!acpi_disabled && acpi_ioapic && boot_ioapic_idx < 0)
>> +		boot_ioapic_idx = mp_find_ioapic(irq_to_gsi(0));
>> +#endif
>> +	if (boot_ioapic_idx < 0)
>> +		boot_ioapic_idx = 0;
>> +
>> +#ifdef CONFIG_ACPI
>> +	if (mp_gsi_routing[boot_ioapic_idx].gsi_base) {
>> +		gsi_delta = NR_IRQS_LEGACY;
>> +		nr_irqs_gsi += NR_IRQS_LEGACY;
>> +		printk(KERN_DEBUG "new nr_irqs_gsi: %d\n", nr_irqs_gsi);
>> +	}
>> +#endif
>> +
>> +	printk(KERN_INFO "boot_ioapic_idx: %d\n", boot_ioapic_idx);
>> +}
>> +
>>  /*
>>   * Not an __init, needed by the reboot code
>>   */
>> @@ -3045,7 +3080,7 @@ static inline void __init check_timer(void)
>>  				legacy_pic->chip->unmask(0);
>>  			}
>>  			if (disable_timer_pin_1 > 0)
>> -				clear_IO_APIC_pin(0, pin1);
>> +				clear_IO_APIC_pin(apic1, pin1);
> 
>   How is this change related to this patch ? It looks more like an
>   independent fix.

ok another patch.

YH

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
  2010-03-22  3:32       ` Yinghai Lu
  (?)
@ 2010-03-23  7:10         ` Paul Mundt
  -1 siblings, 0 replies; 115+ messages in thread
From: Paul Mundt @ 2010-03-23  7:10 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Thomas Gleixner, Ian Campbell

On Sun, Mar 21, 2010 at 08:32:33PM -0700, Yinghai Lu wrote:
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 64f6f20..cafd378 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;
> 
> so this patch only change one line with powerpc code. 

This API seems to be going from bad to worse. Initially we had
arch_init_chip_data(), which had precisely nothing to do with chip_data
and only concerned itself with irq_desc, and now you're renaming it to
something sensible but also trying to bolt on some ad-hoc chip_data
relation at the same time thereby nullifying any benefit obtained from
renaming the function in the first place.

Renaming to xxx_irq_desc() while preserving the existing prototypes would
make sense, even if it's ultimately just unecessary churn.

> > It looks to me like this should just be done via a current machine
> > vector or platform routine, in the same way as powerpc and (I think)
> > ia64, ie:
> > 
> >> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> >> +{
> >> +	return current_machine->init_chip_data(desc, node);
> >> +}
> > 
> looks like xen in same run time, some irqs need x86_init_chip_data,
> and some may need xen_init_chip_data later.
> 
I'm afraid I am unable to grasp the meaning of this sentence, or what
precisely this has to do with not being able to utilize platform ops to
get this sorted out on x86.

You're effectively trying to have the hardirq code pass around a function
pointer for you that ultimately only serves to bail out on certain code
paths if you're running under xen, which is a concern for how the
platform chooses to initialize the irq desc, none of this has any value
or relevance to the hardirq code outside of that. The fact that the
hardirq code doesn't do anything with this information other than pass it
around for your platform should already be a clear indicator that this is
the wrong way to go.

From a cursory look at the x86 code, this looks like precisely the sort
of thing that arch/x86/include/asm/x86_init.h is well suited for, and
indeed you already have a x86_init_irqs to expand on as needed.

The function pointer thing itself is also a bit unorthodox to say the
least. You're introducing and passing around an opaque type just so you
can get to a 'return 0' in the xen case as far as I can tell, so you
could also just make arch_init_chip_data() a weak symbol and clobber it
in the xen case, no?

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-23  7:10         ` Paul Mundt
  0 siblings, 0 replies; 115+ messages in thread
From: Paul Mundt @ 2010-03-23  7:10 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: michael, Ingo Molnar, Thomas Gleixner, H. Peter Anvin,
	Andrew Morton, Eric W. Biederman, Jesse Barnes, lguest,
	Jeremy Fitzhardinge, Rusty Russell, Ian Campbell, linux-sh, x86,
	linux-kernel, linuxppc-dev, Ingo Molnar, Paul Mackerras

On Sun, Mar 21, 2010 at 08:32:33PM -0700, Yinghai Lu wrote:
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 64f6f20..cafd378 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;
> 
> so this patch only change one line with powerpc code. 

This API seems to be going from bad to worse. Initially we had
arch_init_chip_data(), which had precisely nothing to do with chip_data
and only concerned itself with irq_desc, and now you're renaming it to
something sensible but also trying to bolt on some ad-hoc chip_data
relation at the same time thereby nullifying any benefit obtained from
renaming the function in the first place.

Renaming to xxx_irq_desc() while preserving the existing prototypes would
make sense, even if it's ultimately just unecessary churn.

> > It looks to me like this should just be done via a current machine
> > vector or platform routine, in the same way as powerpc and (I think)
> > ia64, ie:
> > 
> >> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> >> +{
> >> +	return current_machine->init_chip_data(desc, node);
> >> +}
> > 
> looks like xen in same run time, some irqs need x86_init_chip_data,
> and some may need xen_init_chip_data later.
> 
I'm afraid I am unable to grasp the meaning of this sentence, or what
precisely this has to do with not being able to utilize platform ops to
get this sorted out on x86.

You're effectively trying to have the hardirq code pass around a function
pointer for you that ultimately only serves to bail out on certain code
paths if you're running under xen, which is a concern for how the
platform chooses to initialize the irq desc, none of this has any value
or relevance to the hardirq code outside of that. The fact that the
hardirq code doesn't do anything with this information other than pass it
around for your platform should already be a clear indicator that this is
the wrong way to go.

>From a cursory look at the x86 code, this looks like precisely the sort
of thing that arch/x86/include/asm/x86_init.h is well suited for, and
indeed you already have a x86_init_irqs to expand on as needed.

The function pointer thing itself is also a bit unorthodox to say the
least. You're introducing and passing around an opaque type just so you
can get to a 'return 0' in the xen case as far as I can tell, so you
could also just make arch_init_chip_data() a weak symbol and clobber it
in the xen case, no?

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-23  7:10         ` Paul Mundt
  0 siblings, 0 replies; 115+ messages in thread
From: Paul Mundt @ 2010-03-23  7:10 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Thomas Gleixner, Ian Campbell

On Sun, Mar 21, 2010 at 08:32:33PM -0700, Yinghai Lu wrote:
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 64f6f20..cafd378 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -1088,7 +1088,7 @@ int arch_early_irq_init(void)
>  	return 0;
>  }
>  
> -int arch_init_chip_data(struct irq_desc *desc, int node)
> +int arch_init_irq_desc(struct irq_desc *desc, int node, init_chip_data_fn fn)
>  {
>  	desc->status |= IRQ_NOREQUEST;
>  	return 0;
> 
> so this patch only change one line with powerpc code. 

This API seems to be going from bad to worse. Initially we had
arch_init_chip_data(), which had precisely nothing to do with chip_data
and only concerned itself with irq_desc, and now you're renaming it to
something sensible but also trying to bolt on some ad-hoc chip_data
relation at the same time thereby nullifying any benefit obtained from
renaming the function in the first place.

Renaming to xxx_irq_desc() while preserving the existing prototypes would
make sense, even if it's ultimately just unecessary churn.

> > It looks to me like this should just be done via a current machine
> > vector or platform routine, in the same way as powerpc and (I think)
> > ia64, ie:
> > 
> >> +int arch_init_irq_desc(struct irq_desc *desc, int node)
> >> +{
> >> +	return current_machine->init_chip_data(desc, node);
> >> +}
> > 
> looks like xen in same run time, some irqs need x86_init_chip_data,
> and some may need xen_init_chip_data later.
> 
I'm afraid I am unable to grasp the meaning of this sentence, or what
precisely this has to do with not being able to utilize platform ops to
get this sorted out on x86.

You're effectively trying to have the hardirq code pass around a function
pointer for you that ultimately only serves to bail out on certain code
paths if you're running under xen, which is a concern for how the
platform chooses to initialize the irq desc, none of this has any value
or relevance to the hardirq code outside of that. The fact that the
hardirq code doesn't do anything with this information other than pass it
around for your platform should already be a clear indicator that this is
the wrong way to go.

>From a cursory look at the x86 code, this looks like precisely the sort
of thing that arch/x86/include/asm/x86_init.h is well suited for, and
indeed you already have a x86_init_irqs to expand on as needed.

The function pointer thing itself is also a bit unorthodox to say the
least. You're introducing and passing around an opaque type just so you
can get to a 'return 0' in the xen case as far as I can tell, so you
could also just make arch_init_chip_data() a weak symbol and clobber it
in the xen case, no?

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-22 10:19     ` Thomas Gleixner
  (?)
@ 2010-03-24 13:32       ` Ian Campbell
  -1 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> On Sun, 21 Mar 2010, Yinghai Lu wrote:
> 
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> 
> Not sure about that. These functions are solely used by x86 and there
> is really no need to generalize them.

I thought the idea of struct irq_chip was to allow the potential for
multiple IRQ controllers in a system? Given that it seems that struct
irq_desc->chip_data ought to be available for use by whichever struct
irq_chip is managing a given interrupt. At the moment this is not
possible because we step around the abstraction using these arch_*
methods.

Although this might be unusual on x86 I think it is not uncommon in the
embedded world to have an architectural interrupt controller cascading
through to various different IRQ controllers/multiplexors, from random
FPGA based things, to GPIO controllers and things like superio chips
etc.

Currently the set of architectures which typically have this sort of
thing are disjoint from the ones which make use of struct
irq_desc->chip_data but with the growing use of embedded-x86 is this not
something worth considering? (Genuine question, I've been out of the
embedded space for a while now so maybe my experiences are out of date
or I'm overestimating the role of embedded-x86 etc).

Xen is a bit more of a specialised case than the above since it would
like to replace the architectural interrupt handling but I think the
broad requirements on the irq_chip interface are the same. Going forward
it is possible/likely that we would like to be able to make Xen event
channels available via a cascade model as well -- demultiplexing one (or
more?) x86 architectural interrupts into event channels would be part of
running PV Xen drivers on a fully-virtualised (i.e. native) kernel.

>  The problem you try to solve is
> x86/xen specific and can be solved by x86_platform_ops as well w/o
> adding extra function pointers to irq_chip.
[...]
> AFAICT the function pointer to irq_to_desc_alloc_node is completely
> pointless. It just solves a Xen/x86 specific problem which can be
> solved by using x86_platform_ops and keeps the churn x86 internal.

I have no problem with that if that is the x86/irq maintainer's
preference, I just thought it would be nicer to solve what I saw as an
oddity in the existing abstraction generically in the core.

> Aside of the general objection against this, please use descriptive
> function names and do not distinguish functions by adding random
> characters which tell us absolutely nothing about the purpose.

I agree on this one. More generally I would say that the number of
existing users of this interface is small enough that _if_ we decide we
need to modify it then we should just bite the bullet and do that
instead of building compatibility layers around stuff. For this reason I
think my original patch was preferable to this version (general
objections not withstanding).

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 13:32       ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, linux-kernel, Ingo Molnar,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> On Sun, 21 Mar 2010, Yinghai Lu wrote:
> 
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> 
> Not sure about that. These functions are solely used by x86 and there
> is really no need to generalize them.

I thought the idea of struct irq_chip was to allow the potential for
multiple IRQ controllers in a system? Given that it seems that struct
irq_desc->chip_data ought to be available for use by whichever struct
irq_chip is managing a given interrupt. At the moment this is not
possible because we step around the abstraction using these arch_*
methods.

Although this might be unusual on x86 I think it is not uncommon in the
embedded world to have an architectural interrupt controller cascading
through to various different IRQ controllers/multiplexors, from random
FPGA based things, to GPIO controllers and things like superio chips
etc.

Currently the set of architectures which typically have this sort of
thing are disjoint from the ones which make use of struct
irq_desc->chip_data but with the growing use of embedded-x86 is this not
something worth considering? (Genuine question, I've been out of the
embedded space for a while now so maybe my experiences are out of date
or I'm overestimating the role of embedded-x86 etc).

Xen is a bit more of a specialised case than the above since it would
like to replace the architectural interrupt handling but I think the
broad requirements on the irq_chip interface are the same. Going forward
it is possible/likely that we would like to be able to make Xen event
channels available via a cascade model as well -- demultiplexing one (or
more?) x86 architectural interrupts into event channels would be part of
running PV Xen drivers on a fully-virtualised (i.e. native) kernel.

>  The problem you try to solve is
> x86/xen specific and can be solved by x86_platform_ops as well w/o
> adding extra function pointers to irq_chip.
[...]
> AFAICT the function pointer to irq_to_desc_alloc_node is completely
> pointless. It just solves a Xen/x86 specific problem which can be
> solved by using x86_platform_ops and keeps the churn x86 internal.

I have no problem with that if that is the x86/irq maintainer's
preference, I just thought it would be nicer to solve what I saw as an
oddity in the existing abstraction generically in the core.

> Aside of the general objection against this, please use descriptive
> function names and do not distinguish functions by adding random
> characters which tell us absolutely nothing about the purpose.

I agree on this one. More generally I would say that the number of
existing users of this interface is small enough that _if_ we decide we
need to modify it then we should just bite the bullet and do that
instead of building compatibility layers around stuff. For this reason I
think my original patch was preferable to this version (general
objections not withstanding).

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 13:32       ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:32 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> On Sun, 21 Mar 2010, Yinghai Lu wrote:
> 
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> 
> Not sure about that. These functions are solely used by x86 and there
> is really no need to generalize them.

I thought the idea of struct irq_chip was to allow the potential for
multiple IRQ controllers in a system? Given that it seems that struct
irq_desc->chip_data ought to be available for use by whichever struct
irq_chip is managing a given interrupt. At the moment this is not
possible because we step around the abstraction using these arch_*
methods.

Although this might be unusual on x86 I think it is not uncommon in the
embedded world to have an architectural interrupt controller cascading
through to various different IRQ controllers/multiplexors, from random
FPGA based things, to GPIO controllers and things like superio chips
etc.

Currently the set of architectures which typically have this sort of
thing are disjoint from the ones which make use of struct
irq_desc->chip_data but with the growing use of embedded-x86 is this not
something worth considering? (Genuine question, I've been out of the
embedded space for a while now so maybe my experiences are out of date
or I'm overestimating the role of embedded-x86 etc).

Xen is a bit more of a specialised case than the above since it would
like to replace the architectural interrupt handling but I think the
broad requirements on the irq_chip interface are the same. Going forward
it is possible/likely that we would like to be able to make Xen event
channels available via a cascade model as well -- demultiplexing one (or
more?) x86 architectural interrupts into event channels would be part of
running PV Xen drivers on a fully-virtualised (i.e. native) kernel.

>  The problem you try to solve is
> x86/xen specific and can be solved by x86_platform_ops as well w/o
> adding extra function pointers to irq_chip.
[...]
> AFAICT the function pointer to irq_to_desc_alloc_node is completely
> pointless. It just solves a Xen/x86 specific problem which can be
> solved by using x86_platform_ops and keeps the churn x86 internal.

I have no problem with that if that is the x86/irq maintainer's
preference, I just thought it would be nicer to solve what I saw as an
oddity in the existing abstraction generically in the core.

> Aside of the general objection against this, please use descriptive
> function names and do not distinguish functions by adding random
> characters which tell us absolutely nothing about the purpose.

I agree on this one. More generally I would say that the number of
existing users of this interface is small enough that _if_ we decide we
need to modify it then we should just bite the bullet and do that
instead of building compatibility layers around stuff. For this reason I
think my original patch was preferable to this version (general
objections not withstanding).

Ian.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-23  7:10         ` Paul Mundt
  (?)
@ 2010-03-24 13:33           ` Ian Campbell
  -1 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:33 UTC (permalink / raw)
  To: Paul Mundt
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Yinghai Lu, Thomas Gleixner

On Tue, 2010-03-23 at 07:10 +0000, Paul Mundt wrote:

> The function pointer thing itself is also a bit unorthodox to say the
> least. You're introducing and passing around an opaque type just so you
> can get to a 'return 0' in the xen case as far as I can tell,

The ultimate aim is to have Xen use the chip data to store the event
channel information relating to each IRQ instead of keeping it in a
static NR_IRQs array, the new function only returns 0 as a placeholder
until this can be put in place (which depends on these changes), it
could as well have been left out for the time being (e.g. passing NULL
function pointer in the Xen case or whatever).

> so you
> could also just make arch_init_chip_data() a weak symbol and clobber it
> in the xen case, no?

A single kernel is able to boot native or Xen so a weak symbol doesn't
really work, having the function pointer at the arch level is one
similar option, I've replied to Thomas' similar suggestion.

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 13:33           ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:33 UTC (permalink / raw)
  To: Paul Mundt
  Cc: Yinghai Lu, michael, Ingo Molnar, Thomas Gleixner,
	H. Peter Anvin, Andrew Morton, Eric W. Biederman, Jesse Barnes,
	lguest, Jeremy Fitzhardinge, Rusty Russell, linux-sh, x86,
	linux-kernel, linuxppc-dev, Ingo Molnar, Paul Mackerras

On Tue, 2010-03-23 at 07:10 +0000, Paul Mundt wrote:

> The function pointer thing itself is also a bit unorthodox to say the
> least. You're introducing and passing around an opaque type just so you
> can get to a 'return 0' in the xen case as far as I can tell,

The ultimate aim is to have Xen use the chip data to store the event
channel information relating to each IRQ instead of keeping it in a
static NR_IRQs array, the new function only returns 0 as a placeholder
until this can be put in place (which depends on these changes), it
could as well have been left out for the time being (e.g. passing NULL
function pointer in the Xen case or whatever).

> so you
> could also just make arch_init_chip_data() a weak symbol and clobber it
> in the xen case, no?

A single kernel is able to boot native or Xen so a weak symbol doesn't
really work, having the function pointer at the arch level is one
similar option, I've replied to Thomas' similar suggestion.

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 13:33           ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 13:33 UTC (permalink / raw)
  To: Paul Mundt
  Cc: lguest, x86, Andrew Morton, linux-sh, Rusty Russell,
	Jeremy Fitzhardinge, Jesse Barnes, linux-kernel, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Eric W. Biederman, H. Peter Anvin,
	Ingo Molnar, Yinghai Lu, Thomas Gleixner

On Tue, 2010-03-23 at 07:10 +0000, Paul Mundt wrote:

> The function pointer thing itself is also a bit unorthodox to say the
> least. You're introducing and passing around an opaque type just so you
> can get to a 'return 0' in the xen case as far as I can tell,

The ultimate aim is to have Xen use the chip data to store the event
channel information relating to each IRQ instead of keeping it in a
static NR_IRQs array, the new function only returns 0 as a placeholder
until this can be put in place (which depends on these changes), it
could as well have been left out for the time being (e.g. passing NULL
function pointer in the Xen case or whatever).

> so you
> could also just make arch_init_chip_data() a weak symbol and clobber it
> in the xen case, no?

A single kernel is able to boot native or Xen so a weak symbol doesn't
really work, having the function pointer at the arch level is one
similar option, I've replied to Thomas' similar suggestion.

Ian.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-24 13:32       ` Ian Campbell
  (?)
@ 2010-03-24 17:44         ` Thomas Gleixner
  -1 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 17:44 UTC (permalink / raw)
  To: Ian Campbell
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 24 Mar 2010, Ian Campbell wrote:

> On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > 
> > > From: Ian Campbell <ian.campbell@citrix.com>
> > > 
> > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > 
> > Not sure about that. These functions are solely used by x86 and there
> > is really no need to generalize them.
> 
> I thought the idea of struct irq_chip was to allow the potential for
> multiple IRQ controllers in a system? Given that it seems that struct
> irq_desc->chip_data ought to be available for use by whichever struct
> irq_chip is managing a given interrupt. At the moment this is not
> possible because we step around the abstraction using these arch_*
> methods.

Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
but that same irq_chip can be associated to several irq_descs. So
irq_desc->data is there to provide data for the irq_chip functions
depending on what irq they handle (e.g. base_address ...). 

irq_desc->chip_data is set when the irq_chip is assigned to the
irq_desc.

So there is no point in having functions in irq_chip to set
irq_desc->chip_data.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 17:44         ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 17:44 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, linux-kernel, Ingo Molnar,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

On Wed, 24 Mar 2010, Ian Campbell wrote:

> On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > 
> > > From: Ian Campbell <ian.campbell@citrix.com>
> > > 
> > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > 
> > Not sure about that. These functions are solely used by x86 and there
> > is really no need to generalize them.
> 
> I thought the idea of struct irq_chip was to allow the potential for
> multiple IRQ controllers in a system? Given that it seems that struct
> irq_desc->chip_data ought to be available for use by whichever struct
> irq_chip is managing a given interrupt. At the moment this is not
> possible because we step around the abstraction using these arch_*
> methods.

Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
but that same irq_chip can be associated to several irq_descs. So
irq_desc->data is there to provide data for the irq_chip functions
depending on what irq they handle (e.g. base_address ...). 

irq_desc->chip_data is set when the irq_chip is assigned to the
irq_desc.

So there is no point in having functions in irq_chip to set
irq_desc->chip_data.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 17:44         ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 17:44 UTC (permalink / raw)
  To: Ian Campbell
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 24 Mar 2010, Ian Campbell wrote:

> On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > 
> > > From: Ian Campbell <ian.campbell@citrix.com>
> > > 
> > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > 
> > Not sure about that. These functions are solely used by x86 and there
> > is really no need to generalize them.
> 
> I thought the idea of struct irq_chip was to allow the potential for
> multiple IRQ controllers in a system? Given that it seems that struct
> irq_desc->chip_data ought to be available for use by whichever struct
> irq_chip is managing a given interrupt. At the moment this is not
> possible because we step around the abstraction using these arch_*
> methods.

Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
but that same irq_chip can be associated to several irq_descs. So
irq_desc->data is there to provide data for the irq_chip functions
depending on what irq they handle (e.g. base_address ...). 

irq_desc->chip_data is set when the irq_chip is assigned to the
irq_desc.

So there is no point in having functions in irq_chip to set
irq_desc->chip_data.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-24 17:44         ` Thomas Gleixner
  (?)
@ 2010-03-24 19:16           ` Ian Campbell
  -1 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 19:16 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> On Wed, 24 Mar 2010, Ian Campbell wrote:
> 
> > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > 
> > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > 
> > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > 
> > > Not sure about that. These functions are solely used by x86 and there
> > > is really no need to generalize them.
> > 
> > I thought the idea of struct irq_chip was to allow the potential for
> > multiple IRQ controllers in a system? Given that it seems that struct
> > irq_desc->chip_data ought to be available for use by whichever struct
> > irq_chip is managing a given interrupt. At the moment this is not
> > possible because we step around the abstraction using these arch_*
> > methods.
> 
> Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> but that same irq_chip can be associated to several irq_descs. So
> irq_desc->data is there to provide data for the irq_chip functions
> depending on what irq they handle (e.g. base_address ...). 
> 
> irq_desc->chip_data is set when the irq_chip is assigned to the
> irq_desc.
> 
> So there is no point in having functions in irq_chip to set
> irq_desc->chip_data.

So how do you know which is the appropriate irq_chip specific function
to call given an irq_desc that you want to copy/free/migrate? The
contents of the chip_data pointer will take different forms for
different irq_chips. The way the generic code is currently structured it
appears you can't (or at least don't) just do a shallow copy by copying
the irq_desc->chip_data pointer itself -- you need to do a deep copy
using a function which understands that type of chip_data.

How is this operation different to having pointers in irq_chip for
enabling/disabling/masking interrupts for each irq_chip?

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 19:16           ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 19:16 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, linux-kernel, Ingo Molnar,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> On Wed, 24 Mar 2010, Ian Campbell wrote:
> 
> > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > 
> > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > 
> > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > 
> > > Not sure about that. These functions are solely used by x86 and there
> > > is really no need to generalize them.
> > 
> > I thought the idea of struct irq_chip was to allow the potential for
> > multiple IRQ controllers in a system? Given that it seems that struct
> > irq_desc->chip_data ought to be available for use by whichever struct
> > irq_chip is managing a given interrupt. At the moment this is not
> > possible because we step around the abstraction using these arch_*
> > methods.
> 
> Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> but that same irq_chip can be associated to several irq_descs. So
> irq_desc->data is there to provide data for the irq_chip functions
> depending on what irq they handle (e.g. base_address ...). 
> 
> irq_desc->chip_data is set when the irq_chip is assigned to the
> irq_desc.
> 
> So there is no point in having functions in irq_chip to set
> irq_desc->chip_data.

So how do you know which is the appropriate irq_chip specific function
to call given an irq_desc that you want to copy/free/migrate? The
contents of the chip_data pointer will take different forms for
different irq_chips. The way the generic code is currently structured it
appears you can't (or at least don't) just do a shallow copy by copying
the irq_desc->chip_data pointer itself -- you need to do a deep copy
using a function which understands that type of chip_data.

How is this operation different to having pointers in irq_chip for
enabling/disabling/masking interrupts for each irq_chip?

Ian.


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 19:16           ` Ian Campbell
  0 siblings, 0 replies; 115+ messages in thread
From: Ian Campbell @ 2010-03-24 19:16 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> On Wed, 24 Mar 2010, Ian Campbell wrote:
> 
> > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > 
> > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > 
> > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > 
> > > Not sure about that. These functions are solely used by x86 and there
> > > is really no need to generalize them.
> > 
> > I thought the idea of struct irq_chip was to allow the potential for
> > multiple IRQ controllers in a system? Given that it seems that struct
> > irq_desc->chip_data ought to be available for use by whichever struct
> > irq_chip is managing a given interrupt. At the moment this is not
> > possible because we step around the abstraction using these arch_*
> > methods.
> 
> Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> but that same irq_chip can be associated to several irq_descs. So
> irq_desc->data is there to provide data for the irq_chip functions
> depending on what irq they handle (e.g. base_address ...). 
> 
> irq_desc->chip_data is set when the irq_chip is assigned to the
> irq_desc.
> 
> So there is no point in having functions in irq_chip to set
> irq_desc->chip_data.

So how do you know which is the appropriate irq_chip specific function
to call given an irq_desc that you want to copy/free/migrate? The
contents of the chip_data pointer will take different forms for
different irq_chips. The way the generic code is currently structured it
appears you can't (or at least don't) just do a shallow copy by copying
the irq_desc->chip_data pointer itself -- you need to do a deep copy
using a function which understands that type of chip_data.

How is this operation different to having pointers in irq_chip for
enabling/disabling/masking interrupts for each irq_chip?

Ian.

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into
  2010-03-24 19:16           ` Ian Campbell
  (?)
@ 2010-03-24 21:25             ` Thomas Gleixner
  -1 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 21:25 UTC (permalink / raw)
  To: Ian Campbell
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 24 Mar 2010, Ian Campbell wrote:
> On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> > On Wed, 24 Mar 2010, Ian Campbell wrote:
> > 
> > > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > > 
> > > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > > 
> > > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > > 
> > > > Not sure about that. These functions are solely used by x86 and there
> > > > is really no need to generalize them.
> > > 
> > > I thought the idea of struct irq_chip was to allow the potential for
> > > multiple IRQ controllers in a system? Given that it seems that struct
> > > irq_desc->chip_data ought to be available for use by whichever struct
> > > irq_chip is managing a given interrupt. At the moment this is not
> > > possible because we step around the abstraction using these arch_*
> > > methods.
> > 
> > Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> > but that same irq_chip can be associated to several irq_descs. So
> > irq_desc->data is there to provide data for the irq_chip functions
> > depending on what irq they handle (e.g. base_address ...). 
> > 
> > irq_desc->chip_data is set when the irq_chip is assigned to the
> > irq_desc.
> > 
> > So there is no point in having functions in irq_chip to set
> > irq_desc->chip_data.
> 
> So how do you know which is the appropriate irq_chip specific function
> to call given an irq_desc that you want to copy/free/migrate? The
> contents of the chip_data pointer will take different forms for
> different irq_chips. The way the generic code is currently structured it
> appears you can't (or at least don't) just do a shallow copy by copying
> the irq_desc->chip_data pointer itself -- you need to do a deep copy
> using a function which understands that type of chip_data.

The design of sparse_irq or to be honest the lack of design grew that
crap and it's not only this detail which is a nightmare. That pointer
should probably be simply copied. Either that or if the chip data
require to be node bound we need something along the line:

struct sparse_irq_chip_data {
       void *data;
       void (*copy)(...);
       void (*free)(...);
};

and a corresponding field in irq_desc.

I'm looking into sparse_irq right now anyway because it has other way
more serious short comings.

> How is this operation different to having pointers in irq_chip for
> enabling/disabling/masking interrupts for each irq_chip?

Because that's the purpose of the irq_chip perhaps ?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 21:25             ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 21:25 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Eric W. Biederman, Jesse Barnes, linux-kernel, Ingo Molnar,
	Jeremy Fitzhardinge, Benjamin Herrenschmidt, Paul Mackerras, x86,
	linuxppc-dev, Rusty Russell, lguest, Paul Mundt, linux-sh

On Wed, 24 Mar 2010, Ian Campbell wrote:
> On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> > On Wed, 24 Mar 2010, Ian Campbell wrote:
> > 
> > > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > > 
> > > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > > 
> > > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > > 
> > > > Not sure about that. These functions are solely used by x86 and there
> > > > is really no need to generalize them.
> > > 
> > > I thought the idea of struct irq_chip was to allow the potential for
> > > multiple IRQ controllers in a system? Given that it seems that struct
> > > irq_desc->chip_data ought to be available for use by whichever struct
> > > irq_chip is managing a given interrupt. At the moment this is not
> > > possible because we step around the abstraction using these arch_*
> > > methods.
> > 
> > Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> > but that same irq_chip can be associated to several irq_descs. So
> > irq_desc->data is there to provide data for the irq_chip functions
> > depending on what irq they handle (e.g. base_address ...). 
> > 
> > irq_desc->chip_data is set when the irq_chip is assigned to the
> > irq_desc.
> > 
> > So there is no point in having functions in irq_chip to set
> > irq_desc->chip_data.
> 
> So how do you know which is the appropriate irq_chip specific function
> to call given an irq_desc that you want to copy/free/migrate? The
> contents of the chip_data pointer will take different forms for
> different irq_chips. The way the generic code is currently structured it
> appears you can't (or at least don't) just do a shallow copy by copying
> the irq_desc->chip_data pointer itself -- you need to do a deep copy
> using a function which understands that type of chip_data.

The design of sparse_irq or to be honest the lack of design grew that
crap and it's not only this detail which is a nightmare. That pointer
should probably be simply copied. Either that or if the chip data
require to be node bound we need something along the line:

struct sparse_irq_chip_data {
       void *data;
       void (*copy)(...);
       void (*free)(...);
};

and a corresponding field in irq_desc.

I'm looking into sparse_irq right now anyway because it has other way
more serious short comings.

> How is this operation different to having pointers in irq_chip for
> enabling/disabling/masking interrupts for each irq_chip?

Because that's the purpose of the irq_chip perhaps ?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-24 21:25             ` Thomas Gleixner
  0 siblings, 0 replies; 115+ messages in thread
From: Thomas Gleixner @ 2010-03-24 21:25 UTC (permalink / raw)
  To: Ian Campbell
  Cc: lguest, Jeremy Fitzhardinge, Rusty Russell, Paul Mundt, linux-sh,
	x86, linux-kernel, Jesse Barnes, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Eric W. Biederman, H. Peter Anvin, Ingo Molnar,
	Yinghai Lu, Andrew Morton

On Wed, 24 Mar 2010, Ian Campbell wrote:
> On Wed, 2010-03-24 at 17:44 +0000, Thomas Gleixner wrote: 
> > On Wed, 24 Mar 2010, Ian Campbell wrote:
> > 
> > > On Mon, 2010-03-22 at 10:19 +0000, Thomas Gleixner wrote:
> > > > On Sun, 21 Mar 2010, Yinghai Lu wrote:
> > > > 
> > > > > From: Ian Campbell <ian.campbell@citrix.com>
> > > > > 
> > > > > Move arch_init_copy_chip_data and arch_free_chip_data into function
> > > > > pointers in struct irq_chip since they operate on irq_desc->chip_data.
> > > > 
> > > > Not sure about that. These functions are solely used by x86 and there
> > > > is really no need to generalize them.
> > > 
> > > I thought the idea of struct irq_chip was to allow the potential for
> > > multiple IRQ controllers in a system? Given that it seems that struct
> > > irq_desc->chip_data ought to be available for use by whichever struct
> > > irq_chip is managing a given interrupt. At the moment this is not
> > > possible because we step around the abstraction using these arch_*
> > > methods.
> > 
> > Right, but you have exactly _ONE_ irq_chip associated to an irq_desc,
> > but that same irq_chip can be associated to several irq_descs. So
> > irq_desc->data is there to provide data for the irq_chip functions
> > depending on what irq they handle (e.g. base_address ...). 
> > 
> > irq_desc->chip_data is set when the irq_chip is assigned to the
> > irq_desc.
> > 
> > So there is no point in having functions in irq_chip to set
> > irq_desc->chip_data.
> 
> So how do you know which is the appropriate irq_chip specific function
> to call given an irq_desc that you want to copy/free/migrate? The
> contents of the chip_data pointer will take different forms for
> different irq_chips. The way the generic code is currently structured it
> appears you can't (or at least don't) just do a shallow copy by copying
> the irq_desc->chip_data pointer itself -- you need to do a deep copy
> using a function which understands that type of chip_data.

The design of sparse_irq or to be honest the lack of design grew that
crap and it's not only this detail which is a nightmare. That pointer
should probably be simply copied. Either that or if the chip data
require to be node bound we need something along the line:

struct sparse_irq_chip_data {
       void *data;
       void (*copy)(...);
       void (*free)(...);
};

and a corresponding field in irq_desc.

I'm looking into sparse_irq right now anyway because it has other way
more serious short comings.

> How is this operation different to having pointers in irq_chip for
> enabling/disabling/masking interrupts for each irq_chip?

Because that's the purpose of the irq_chip perhaps ?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 02/10] x86: fix out of order of gsi - full
  2010-03-22 11:14   ` Thomas Gleixner
  2010-03-22 19:45     ` Yinghai Lu
@ 2010-03-29 13:40     ` Eric W. Biederman
  2010-03-29 17:57       ` H. Peter Anvin
  1 sibling, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 13:40 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Yinghai Lu, Ingo Molnar, H. Peter Anvin, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown


I have played with this a bit and I have a cleaner patchset that
addresses this issue.  I plan to sleep on it, and then go through it
again before I send it.

Thomas is the procedure for working on this stuff write clean patches
and send them, and they will land in an x86 topic branch?

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 02/10] x86: fix out of order of gsi - full
  2010-03-29 13:40     ` Eric W. Biederman
@ 2010-03-29 17:57       ` H. Peter Anvin
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
  0 siblings, 1 reply; 115+ messages in thread
From: H. Peter Anvin @ 2010-03-29 17:57 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown

On 03/29/2010 06:40 AM, Eric W. Biederman wrote:
> 
> I have played with this a bit and I have a cleaner patchset that
> addresses this issue.  I plan to sleep on it, and then go through it
> again before I send it.
> 
> Thomas is the procedure for working on this stuff write clean patches
> and send them, and they will land in an x86 topic branch?
> 

Pretty much, yes.

	-hpa

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
  2010-03-29 17:57       ` H. Peter Anvin
@ 2010-03-29 23:19         ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
                             ` (15 more replies)
  0 siblings, 16 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:19 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich


It appears there are a few systems in the wild that use acpi
interrupt source overrides to report a gsi > 16 is an isa irq.

This breaks all kinds of assumptions I figure any BIOS doing that
probably should be shot as that is very much not a conservative position.

That said acpi appears to allow this insanity and on the basis of being
liberal in what we accept we should try to do something reasonable, and
keep our notions of gsi, isa irq, and linux irq as straight as we can.

To that end this patchset slightly modifies the gsi to linux irq
mapping.  Making it a 1 to 1 identity mapping except for the first 16
gsis.  If those gsis are isa irqs (the typical and default acpi
configuration) they will be mapped into the first 16 irqs.  If those
first 16 gsis are not isa irqs they will be given a linux irq number
just past the last gsi.  Allowing us the chance to use them.

This patchset is my attempt to straighten out our understanding of which
kind of irq name is used where and the cleanups used to get there.

Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
this and finding that there is a real world problem here.  This patchset
is inspired by his work, but little of it remains the same.

This patchset lies in the weird world between the acpi and x86 and ia64.
Since most of the changes are x86 related I think it makes most sense
to go via the x86 tree.


Eric W. Biederman (14):
      x86 acpi/irq: Introduce apci_isa_irq_to_gsi
      x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
      x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
      x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
      x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
      x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
      x86 ioapic: Fix the types of gsi values
      x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
      x86 ioapic: In mpparse use mp_register_ioapic
      x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
      x86 ioapic: Optimize pin_2_irq
      x86 ioapic: Simplify probe_nr_irqs_gsi.
      x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
      x86 irq: Kill io_apic_renumber_irq

 arch/ia64/kernel/acpi.c          |    8 ++
 arch/x86/include/asm/io_apic.h   |   12 ++--
 arch/x86/include/asm/mpspec.h    |   10 ---
 arch/x86/kernel/acpi/boot.c      |  133 ++++++++++++++++++++++++--------------
 arch/x86/kernel/apic/es7000_32.c |   19 ------
 arch/x86/kernel/apic/io_apic.c   |   93 +++++++++++---------------
 arch/x86/kernel/mpparse.c        |   25 +-------
 arch/x86/kernel/sfi.c            |    4 +-
 drivers/acpi/pci_irq.c           |    8 ++-
 include/linux/acpi.h             |    5 +-
 10 files changed, 149 insertions(+), 168 deletions(-)

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
                             ` (14 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

There are a number of cases where the current code makes the assumption
that isa irqs identity map to the first 16 acpi global system intereupts.
In most instances that assumption is correct as that is the required
behaviour in dual i8259 mode and the default behavior in ioapic mode.

However there are some systems out there that take advantage of acpis
interrupt remapping  for the isa irqs to have a completely different
mapping of isa_irq to gsi.

Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the
code that needs it.  Initially this will be just the current assumed
identity mapping to ensure it's introduction does not cause regressions.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/ia64/kernel/acpi.c     |    8 ++++++++
 arch/x86/kernel/acpi/boot.c |    8 ++++++++
 include/linux/acpi.h        |    1 +
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index f1c9f70..16921bd 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -784,6 +784,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  *  ACPI based hotplug CPU support
  */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0061ea2..f96060d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -457,6 +457,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b926afe..7a937da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags;
 
 int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
                             ` (13 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

In perverse acpi implementations the isa irqs are not identity mapped
to the first 16 gsi.  Furthermore at least the extended interrupt
resource capability may return gsi's and not isa irqs.  So since
what we get from acpi is a gsi teach acpi_get_overrride_irq to
operate on a gsi instead of an isa_irq.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   23 ++++++++++++++---------
 include/linux/acpi.h           |    4 ++--
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..54ba1f7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4073,22 +4073,27 @@ int __init io_apic_get_version(int ioapic)
 	return reg_01.bits.version;
 }
 
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
 {
-	int i;
+	int ioapic, pin, idx;
 
 	if (skip_ioapic_setup)
 		return -1;
 
-	for (i = 0; i < mp_irq_entries; i++)
-		if (mp_irqs[i].irqtype == mp_INT &&
-		    mp_irqs[i].srcbusirq == bus_irq)
-			break;
-	if (i >= mp_irq_entries)
+	ioapic = mp_find_ioapic(gsi);
+	if (ioapic < 0)
+		return -1;
+
+	pin = mp_find_ioapic_pin(ioapic, gsi);
+	if (pin < 0)
+		return -1;
+
+	idx = find_irq_entry(ioapic, pin, mp_INT);
+	if (idx < 0)
 		return -1;
 
-	*trigger = irq_trigger(i);
-	*polarity = irq_polarity(i);
+	*trigger = irq_trigger(idx);
+	*polarity = irq_polarity(idx);
 	return 0;
 }
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a937da..3da73f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 #else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
 #endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
                             ` (12 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Strictly speaking on x86 (where acpi is used) dev->irq must be
a dual i8259 irq input aka an isa irq.  Therefore we should translate
that isa irq into a gsi before passing it to a function that
takes a gsi.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 drivers/acpi/pci_irq.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699e..703541d 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -400,11 +400,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * driver reported one, then use it. Exit in any case.
 	 */
 	if (gsi < 0) {
+		u32 dev_gsi;
 		dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq > 0 && (dev->irq <= 0xF)) {
-			printk(" - using IRQ %d\n", dev->irq);
-			acpi_register_gsi(&dev->dev, dev->irq,
+		if (dev->irq > 0 && (dev->irq <= 0xF) &&
+		    (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+			printk(" - using ISA IRQ %d\n", dev->irq);
+			acpi_register_gsi(&dev->dev, dev_gsi,
 					  ACPI_LEVEL_SENSITIVE,
 					  ACPI_ACTIVE_LOW);
 			return 0;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (2 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
                             ` (11 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with
bus_irq == gsi, which is wrong if we are comming from an override
Instead pass the bus_irq into acpi_sci_ioapic_setup.

This fix was inspired by a similar fix from:
Yinghai Lu <yinghai@kernel.org>

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index f96060d..1742888 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -312,7 +312,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
 {
 	if (trigger == 0)	/* compatible SCI trigger is level */
 		trigger = 3;
@@ -332,7 +332,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
 	 * If GSI is < 16, this will update its flags,
 	 * else it will create a new mp_irqs[] entry.
 	 */
-	mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
 	/*
 	 * stash over-ride to indicate we've been here
@@ -356,9 +356,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-		acpi_sci_ioapic_setup(intsrc->global_irq,
+		acpi_sci_ioapic_setup(intsrc->source_irq,
 				      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
-				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+				      intsrc->global_irq);
 		return 0;
 	}
 
@@ -1161,7 +1162,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	 * pretend we got one so we can set the SCI flags.
 	 */
 	if (!acpi_sci_override_gsi)
-		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+				      acpi_gbl_FADT.sci_interrupt);
 
 	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (3 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
                             ` (10 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Remove the assumption that there is not an override for isa irq 0.
Instead lookup the gsi and from that lookup the ioapic and pin of each
isa irq indivdually.

In general this should not have any behavioural affect but in
perverse cases this gets all of the details correct, instead of
doing something weird.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 1742888..9c48e99 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -960,8 +960,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 void __init mp_config_acpi_legacy_irqs(void)
 {
 	int i;
-	int ioapic;
-	unsigned int dstapic;
 	struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -982,19 +980,27 @@ void __init mp_config_acpi_legacy_irqs(void)
 #endif
 
 	/*
-	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
-	 */
-	ioapic = mp_find_ioapic(0);
-	if (ioapic < 0)
-		return;
-	dstapic = mp_ioapics[ioapic].apicid;
-
-	/*
 	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overridden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int ioapic, pin;
+		unsigned int dstapic;
 		int idx;
+		u32 gsi;
+
+		/* Locate the gsi that irq i maps to. */
+		if (acpi_isa_irq_to_gsi(i, &gsi))
+			continue;
+
+		/*
+		 * Locate the IOAPIC that manages the ISA IRQ.
+		 */
+		ioapic = mp_find_ioapic(gsi);
+		if (ioapic < 0)
+			continue;
+		pin = mp_find_ioapic_pin(ioapic, gsi);
+		dstapic = mp_ioapics[ioapic].apicid;
 
 		for (idx = 0; idx < mp_irq_entries; idx++) {
 			struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1004,7 +1010,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 				break;
 
 			/* Do we already have a mapping for this IOAPIC pin */
-			if (irq->dstapic == dstapic && irq->dstirq == i)
+			if (irq->dstapic == dstapic && irq->dstirq == pin)
 				break;
 		}
 
@@ -1019,7 +1025,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 		mp_irq.dstapic = dstapic;
 		mp_irq.irqtype = mp_INT;
 		mp_irq.srcbusirq = i; /* Identity mapped */
-		mp_irq.dstirq = i;
+		mp_irq.dstirq = pin;
 
 		save_mp_irq(&mp_irq);
 	}
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (4 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
                             ` (9 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Multiple declarations of the same function in different headers
is a pain to maintain.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/mpspec.h |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..29994f0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -106,10 +106,6 @@ struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
 extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
 #else /* !CONFIG_ACPI: */
 static inline int acpi_probe_gsi(void)
 {
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 07/14] x86 ioapic: Fix the types of gsi values
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (5 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
                             ` (8 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

This patches fixes the types of gsi_base and gsi_end values in
struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic
and mp_find_ioapic_pin

A gsi is cannonically a u32, not an int.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h |   10 +++++-----
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..feeaf0d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
 extern void setup_ioapic_ids_from_mpc(void);
 
 struct mp_ioapic_gsi{
-	int gsi_base;
-	int gsi_end;
+	u32 gsi_base;
+	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -197,7 +197,7 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 54ba1f7..32cea57 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4234,7 +4234,7 @@ void __init ioapic_insert_resources(void)
 	}
 }
 
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
 {
 	int i = 0;
 
@@ -4249,7 +4249,7 @@ int mp_find_ioapic(int gsi)
 	return -1;
 }
 
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
 	if (WARN_ON(ioapic == -1))
 		return -1;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (6 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
                             ` (7 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Add the global variable gsi_end and teach mp_register_ioapic
to keep it uptodate as we add more ioapics into the system.

ioapics can only be added early in boot so the code that
runs later can treat gsi_end as a constant.

Remove the have hacks in sfi.c to second guess mp_register_ioapic
by keeping t's own running total of how many gsi's have been seen,
and instead use the gsi_end.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h |    1 +
 arch/x86/kernel/apic/io_apic.c |    6 ++++++
 arch/x86/kernel/sfi.c          |    4 +---
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index feeaf0d..37b0f2b 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,7 @@ struct mp_ioapic_gsi{
 	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
+extern u32 gsi_end;
 int mp_find_ioapic(u32 gsi);
 int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 32cea57..a979a00 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -88,6 +88,9 @@ int nr_ioapics;
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
 
+/* One past the last gsi number used */
+u32 gsi_end;
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
@@ -4299,6 +4302,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	mp_gsi_routing[idx].gsi_end = gsi_base +
 	    io_apic_get_redir_entries(idx);
 
+	if (mp_gsi_routing[idx].gsi_end > gsi_end)
+		gsi_end = mp_gsi_routing[idx].gsi_end;
+
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
 	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index 34e0993..7ef6df2 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 	pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
 	for (i = 0; i < num; i++) {
-		mp_register_ioapic(i, pentry->phys_addr, gsi_base);
-		gsi_base += io_apic_get_redir_entries(i);
+		mp_register_ioapic(i, pentry->phys_addr, gsi_end);
 		pentry++;
 	}
 
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (7 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
                             ` (6 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Long ago MP_ioapic_info was the primary way of setting up our
ioapic data structures and mp_register_ioapic was a compatibility
shim for acpi code.  Now the situation is reversed and
and mp_register_ioapic is the primary way of setting up our
ioapic data structures.

Keep the setting up of ioapic data structures uniform by
having mp_register_ioapic call mp_register_ioapic.

This changes a few fields:

- type: is now hardset to MP_IOAPIC but type had to
  bey MP_IOAPIC or MP_ioapic_info would not have been called.

- flags: is now hard coded to MPC_APIC_USABLE.
  We require flags to contain at least MPC_APIC_USEBLE in
  MP_ioapic_info and we don't ever examine flags so dropping
  a few flags that might possibly exist that we have never
  used is harmless.

- apicaddr: Unchanged

- apicver: Read from the ioapic instead of using the cached
  hardware value in the MP table.  The real hardware value
  will be more accurate.

- apicid: Now verified to be unique and changed if it is not.
  If the BIOS got this right this is a noop.  If the BIOS did
  not fixing things appears to be the better solution.

This adds gsi_base and gsi_end values to our ioapics defined with
the mpatable, which will make our lives simpler later since
we can always assume gsi_base and gsi_end are valid.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/mpparse.c |   25 +------------------------
 1 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a2c1edd..c0de938 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
-static int bad_ioapic(unsigned long address)
-{
-	if (nr_ioapics >= MAX_IO_APICS) {
-		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-		       "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-	}
-	if (!address) {
-		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-		       " found in table, skipping!\n");
-		return 1;
-	}
-	return 0;
-}
-
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
 	if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
 	printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
 	       m->apicid, m->apicver, m->apicaddr);
 
-	if (bad_ioapic(m->apicaddr))
-		return;
-
-	mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
-	mp_ioapics[nr_ioapics].apicid = m->apicid;
-	mp_ioapics[nr_ioapics].type = m->type;
-	mp_ioapics[nr_ioapics].apicver = m->apicver;
-	mp_ioapics[nr_ioapics].flags = m->flags;
-	nr_ioapics++;
+	mp_register_ioapic(m->apicid, m->apicaddr, gsi_end);
 }
 
 static void print_MP_intsrc_info(struct mpc_intsrc *m)
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (8 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
                             ` (5 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that all ioapic registration happens in mp_register_ioapic we can
move the calculation of nr_ioapic_registers there from enable_IO_APIC.
The number of ioapic registers is already calucated in mp_register_ioapic
so all that really needs to be done is to save the caluclated value
in nr_ioapic_registers.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a979a00..0515f26 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1944,20 +1944,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 void __init enable_IO_APIC(void)
 {
-	union IO_APIC_reg_01 reg_01;
 	int i8259_apic, i8259_pin;
 	int apic;
-	unsigned long flags;
-
-	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		raw_spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(apic, 1);
-		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-	}
 
 	if (!legacy_pic->nr_legacy_irqs)
 		return;
@@ -4280,6 +4268,7 @@ static int bad_ioapic(unsigned long address)
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
 	int idx = 0;
+	int entries;
 
 	if (bad_ioapic(address))
 		return;
@@ -4298,9 +4287,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
+	entries = io_apic_get_redir_entries(idx);
 	mp_gsi_routing[idx].gsi_base = gsi_base;
-	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx);
+	mp_gsi_routing[idx].gsi_end = gsi_base + entries;
+
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	nr_ioapic_registers[idx] = entries;
 
 	if (mp_gsi_routing[idx].gsi_end > gsi_end)
 		gsi_end = mp_gsi_routing[idx].gsi_end;
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 11/14] x86 ioapic: Optimize pin_2_irq
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (9 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
                             ` (4 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that all ioapics have valid gsi_base values use this to
accellerate pin_2_irq.  In the case of acpi this also ensures
that pin_2_irq will compute the same irq value for an ioapic
pin as acpi will.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0515f26..996cf8f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1018,7 +1018,7 @@ static inline int irq_trigger(int idx)
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-	int irq, i;
+	int irq;
 	int bus = mp_irqs[idx].srcbus;
 
 	/*
@@ -1030,18 +1030,13 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
+		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
 		/*
                  * For MPS mode, so far only needed by ES7000 platform
                  */
 		if (ioapic_renumber_irq)
-			irq = ioapic_renumber_irq(apic, irq);
+			gsi = ioapic_renumber_irq(apic, gsi);
+		irq = gsi;
 	}
 
 #ifdef CONFIG_X86_32
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (10 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-30  2:16               ` Yinghai Lu
  2010-03-29 23:20           ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
                             ` (3 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Use the global gsi_end value now that all ioapics have
valid gsi numbers instead of a combination of acpi_probe_gsi
and walking all of the ioapics and couting their number of
entries by hand if acpi_probe_gsi gave us an answer we did
not like.

This fixes a small bug in probe_nr_irqs_gsi.  Previously
acpi_probe_gsi unnecessarily added 1 to the maximum
gsi_end value.  gsi_end is already one past the end of
the number of gsi's so the additional increment was
superfluous.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/mpspec.h  |    6 ------
 arch/x86/kernel/acpi/boot.c    |   23 -----------------------
 arch/x86/kernel/apic/io_apic.c |   17 +++--------------
 3 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 29994f0..c82868e 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
-extern int acpi_probe_gsi(void);
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
-	return 0;
-}
 #endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9c48e99..0e514a1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-int __init acpi_probe_gsi(void)
-{
-	int idx;
-	int gsi;
-	int max_gsi = 0;
-
-	if (acpi_disabled)
-		return 0;
-
-	if (!acpi_ioapic)
-		return 0;
-
-	max_gsi = 0;
-	for (idx = 0; idx < nr_ioapics; idx++) {
-		gsi = mp_gsi_routing[idx].gsi_end;
-
-		if (gsi > max_gsi)
-			max_gsi = gsi;
-	}
-
-	return max_gsi + 1;
-}
-
 static void assign_to_mp_irq(struct mpc_intsrc *m,
 				    struct mpc_intsrc *mp_irq)
 {
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 996cf8f..b57b7a3 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
 
 void __init probe_nr_irqs_gsi(void)
 {
-	int nr = 0;
+	int nr;
 
-	nr = acpi_probe_gsi();
-	if (nr > nr_irqs_gsi) {
+	nr = gsi_end;
+	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
-	} else {
-		/* for acpi=off or acpi is not compiled in */
-		int idx;
-
-		nr = 0;
-		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx) + 1;
-
-		if (nr > nr_irqs_gsi)
-			nr_irqs_gsi = nr;
-	}
 
 	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (11 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-29 23:20           ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
                             ` (2 subsequent siblings)
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

ACPI irq source overrides are allowed for the 16 isa irqs and are
allowed to map any gsi to any isa irq.  A few motherboards have been
seen to take advantage of this and put the isa irqs on the 2nd or
3rd ioapic.  This causes some problems, most notably the fact
that we can not use any gsi < 16.

To correct this move the gsis that are not isa irqs and have
a gsi number < 16 into the linux irq space just past gsi_end.
This is what the es7000 platform is doing today.  Moving only the
low 16 gsis above the rest of the gsi's only penalizes weird
platforms, leaving sane acpi implementations with a 1-1 mapping
of gsis and irqs.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c    |   57 +++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/apic/io_apic.c |    8 ++++-
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0e514a1..b372aba 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -92,6 +92,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
 
+/* 
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+	unsigned int irq = gsi + NR_IRQS_LEGACY;
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		if (isa_irq_to_gsi[i] == gsi) {
+			return i;
+		}
+	}
+
+	/* Provide an identity mapping of gsi == irq
+	 * except on truly weird platforms that have
+	 * non isa irqs in the first 16 gsis.
+	 */
+	if (gsi >= NR_IRQS_LEGACY)
+		irq = gsi;
+	else
+		irq = gsi_end + gsi;
+
+	return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+	unsigned int gsi;
+
+	if (irq < NR_IRQS_LEGACY)
+		gsi = isa_irq_to_gsi[irq];
+	else if (irq < gsi_end)
+		gsi = irq;
+	else if (irq < (gsi_end + NR_IRQS_LEGACY))
+		gsi = irq - gsi_end;
+	else
+		gsi = 0xffffffff;
+
+	return gsi;
+}
+
 /*
  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
@@ -448,7 +495,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	*irq = gsi;
+	*irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -462,7 +509,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 {
 	if (isa_irq >= 16)
 		return -1;
-	*gsi = isa_irq;
+	*gsi = irq_to_gsi(isa_irq);
 	return 0;
 }
 
@@ -490,7 +537,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
 	}
 #endif
-	irq = plat_gsi;
+	irq = gsi_to_irq(plat_gsi);
 
 	return irq;
 }
@@ -932,6 +979,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 	mp_irq.dstirq = pin;	/* INTIN# */
 
 	save_mp_irq(&mp_irq);
+
+	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
@@ -1085,7 +1134,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	io_apic_set_pci_routing(dev, gsi, &irq_attr);
+	io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 
 	return gsi;
 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index b57b7a3..f2c26d2 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1036,7 +1036,11 @@ static int pin_2_irq(int idx, int apic, int pin)
                  */
 		if (ioapic_renumber_irq)
 			gsi = ioapic_renumber_irq(apic, gsi);
-		irq = gsi;
+
+		if (gsi >= NR_IRQS_LEGACY)
+			irq = gsi;
+		else
+			irq = gsi_end + gsi;
 	}
 
 #ifdef CONFIG_X86_32
@@ -3839,7 +3843,7 @@ void __init probe_nr_irqs_gsi(void)
 {
 	int nr;
 
-	nr = gsi_end;
+	nr = gsi_end + NR_IRQS_LEGACY;
 	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
 
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (12 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-03-29 23:20           ` Eric W. Biederman
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
  2010-04-01  2:02           ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that the generic irq layer is performing the exact same remapping as
io_apic_renumber_irq we can kill this weird  es7000 specific function.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h   |    1 -
 arch/x86/kernel/acpi/boot.c      |    5 -----
 arch/x86/kernel/apic/es7000_32.c |   19 -------------------
 arch/x86/kernel/apic/io_apic.c   |    6 ------
 4 files changed, 0 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 37b0f2b..9da192a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
 void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
 
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index b372aba..a48dfa9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1116,11 +1116,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
 	ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
-#ifdef CONFIG_X86_32
-	if (ioapic_renumber_irq)
-		gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 		       "%d-%d\n", mp_ioapics[ioapic].apicid,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index dd2b5f2..7a63d47 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -130,24 +130,6 @@ int					es7000_plat;
 
 static unsigned int			base;
 
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-	if (es7000_plat == ES7000_ZORRO)
-		return gsi;
-
-	if (!base) {
-		int i;
-		for (i = 0; i < nr_ioapics; i++)
-			base += nr_ioapic_registers[i];
-	}
-
-	if (!ioapic && (gsi < 16))
-		gsi += base;
-
-	return gsi;
-}
-
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
 	unsigned long vect = 0, psaival = 0;
@@ -189,7 +171,6 @@ static void setup_unisys(void)
 		es7000_plat = ES7000_ZORRO;
 	else
 		es7000_plat = ES7000_CLASSIC;
-	ioapic_renumber_irq = es7000_rename_gsi;
 }
 
 /*
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f2c26d2..df7dcb3 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1015,7 +1015,6 @@ static inline int irq_trigger(int idx)
 	return MPBIOS_trigger(idx);
 }
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq;
@@ -1031,11 +1030,6 @@ static int pin_2_irq(int idx, int apic, int pin)
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
 		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
-		/*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-		if (ioapic_renumber_irq)
-			gsi = ioapic_renumber_irq(apic, gsi);
 
 		if (gsi >= NR_IRQS_LEGACY)
 			irq = gsi;
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-29 23:20           ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-30  2:16               ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-30  2:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> From: Eric W. Biederman <ebiederm@xmission.com>
>
> Use the global gsi_end value now that all ioapics have
> valid gsi numbers instead of a combination of acpi_probe_gsi
> and walking all of the ioapics and couting their number of
> entries by hand if acpi_probe_gsi gave us an answer we did
> not like.
>
> This fixes a small bug in probe_nr_irqs_gsi.  Previously
> acpi_probe_gsi unnecessarily added 1 to the maximum
> gsi_end value.  gsi_end is already one past the end of
> the number of gsi's so the additional increment was
> superfluous.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
>  arch/x86/include/asm/mpspec.h  |    6 ------
>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>  3 files changed, 3 insertions(+), 43 deletions(-)
>
> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
> index 29994f0..c82868e 100644
> --- a/arch/x86/include/asm/mpspec.h
> +++ b/arch/x86/include/asm/mpspec.h
> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>  struct device;
>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>                                 int active_high_low);
> -extern int acpi_probe_gsi(void);
> -#else /* !CONFIG_ACPI: */
> -static inline int acpi_probe_gsi(void)
> -{
> -       return 0;
> -}
>  #endif /* CONFIG_ACPI */
>
>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 9c48e99..0e514a1 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>  extern int es7000_plat;
>  #endif
>
> -int __init acpi_probe_gsi(void)
> -{
> -       int idx;
> -       int gsi;
> -       int max_gsi = 0;
> -
> -       if (acpi_disabled)
> -               return 0;
> -
> -       if (!acpi_ioapic)
> -               return 0;
> -
> -       max_gsi = 0;
> -       for (idx = 0; idx < nr_ioapics; idx++) {
> -               gsi = mp_gsi_routing[idx].gsi_end;
> -
> -               if (gsi > max_gsi)
> -                       max_gsi = gsi;
> -       }
> -
> -       return max_gsi + 1;
> -}
> -
>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>                                    struct mpc_intsrc *mp_irq)
>  {
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index 996cf8f..b57b7a3 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>
>  void __init probe_nr_irqs_gsi(void)
>  {
> -       int nr = 0;
> +       int nr;
>
> -       nr = acpi_probe_gsi();
> -       if (nr > nr_irqs_gsi) {
> +       nr = gsi_end;

you may need +1 here

YH

> +       if (nr > nr_irqs_gsi)
>                nr_irqs_gsi = nr;
> -       } else {
> -               /* for acpi=off or acpi is not compiled in */
> -               int idx;
> -
> -               nr = 0;
> -               for (idx = 0; idx < nr_ioapics; idx++)
> -                       nr += io_apic_get_redir_entries(idx) + 1;
> -
> -               if (nr > nr_irqs_gsi)
> -                       nr_irqs_gsi = nr;
> -       }
>
>        printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
>  }
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
@ 2010-03-30  2:16               ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-03-30  2:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> From: Eric W. Biederman <ebiederm@xmission.com>
>
> Use the global gsi_end value now that all ioapics have
> valid gsi numbers instead of a combination of acpi_probe_gsi
> and walking all of the ioapics and couting their number of
> entries by hand if acpi_probe_gsi gave us an answer we did
> not like.
>
> This fixes a small bug in probe_nr_irqs_gsi.  Previously
> acpi_probe_gsi unnecessarily added 1 to the maximum
> gsi_end value.  gsi_end is already one past the end of
> the number of gsi's so the additional increment was
> superfluous.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
>  arch/x86/include/asm/mpspec.h  |    6 ------
>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>  3 files changed, 3 insertions(+), 43 deletions(-)
>
> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
> index 29994f0..c82868e 100644
> --- a/arch/x86/include/asm/mpspec.h
> +++ b/arch/x86/include/asm/mpspec.h
> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>  struct device;
>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>                                 int active_high_low);
> -extern int acpi_probe_gsi(void);
> -#else /* !CONFIG_ACPI: */
> -static inline int acpi_probe_gsi(void)
> -{
> -       return 0;
> -}
>  #endif /* CONFIG_ACPI */
>
>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 9c48e99..0e514a1 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>  extern int es7000_plat;
>  #endif
>
> -int __init acpi_probe_gsi(void)
> -{
> -       int idx;
> -       int gsi;
> -       int max_gsi = 0;
> -
> -       if (acpi_disabled)
> -               return 0;
> -
> -       if (!acpi_ioapic)
> -               return 0;
> -
> -       max_gsi = 0;
> -       for (idx = 0; idx < nr_ioapics; idx++) {
> -               gsi = mp_gsi_routing[idx].gsi_end;
> -
> -               if (gsi > max_gsi)
> -                       max_gsi = gsi;
> -       }
> -
> -       return max_gsi + 1;
> -}
> -
>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>                                    struct mpc_intsrc *mp_irq)
>  {
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index 996cf8f..b57b7a3 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>
>  void __init probe_nr_irqs_gsi(void)
>  {
> -       int nr = 0;
> +       int nr;
>
> -       nr = acpi_probe_gsi();
> -       if (nr > nr_irqs_gsi) {
> +       nr = gsi_end;

you may need +1 here

YH

> +       if (nr > nr_irqs_gsi)
>                nr_irqs_gsi = nr;
> -       } else {
> -               /* for acpi=off or acpi is not compiled in */
> -               int idx;
> -
> -               nr = 0;
> -               for (idx = 0; idx < nr_ioapics; idx++)
> -                       nr += io_apic_get_redir_entries(idx) + 1;
> -
> -               if (nr > nr_irqs_gsi)
> -                       nr_irqs_gsi = nr;
> -       }
>
>        printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
>  }

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-30  2:16               ` Yinghai Lu
@ 2010-03-30  4:43                 ` Eric W. Biederman
  -1 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  4:43 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

Yinghai Lu <yinghai@kernel.org> writes:

> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>> From: Eric W. Biederman <ebiederm@xmission.com>
>>
>> Use the global gsi_end value now that all ioapics have
>> valid gsi numbers instead of a combination of acpi_probe_gsi
>> and walking all of the ioapics and couting their number of
>> entries by hand if acpi_probe_gsi gave us an answer we did
>> not like.
>>
>> This fixes a small bug in probe_nr_irqs_gsi.  Previously
>> acpi_probe_gsi unnecessarily added 1 to the maximum
>> gsi_end value.  gsi_end is already one past the end of
>> the number of gsi's so the additional increment was
>> superfluous.
>>
>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>> ---
>>  arch/x86/include/asm/mpspec.h  |    6 ------
>>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>>  3 files changed, 3 insertions(+), 43 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>> index 29994f0..c82868e 100644
>> --- a/arch/x86/include/asm/mpspec.h
>> +++ b/arch/x86/include/asm/mpspec.h
>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>  struct device;
>>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>                                 int active_high_low);
>> -extern int acpi_probe_gsi(void);
>> -#else /* !CONFIG_ACPI: */
>> -static inline int acpi_probe_gsi(void)
>> -{
>> -       return 0;
>> -}
>>  #endif /* CONFIG_ACPI */
>>
>>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>> index 9c48e99..0e514a1 100644
>> --- a/arch/x86/kernel/acpi/boot.c
>> +++ b/arch/x86/kernel/acpi/boot.c
>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>  extern int es7000_plat;
>>  #endif
>>
>> -int __init acpi_probe_gsi(void)
>> -{
>> -       int idx;
>> -       int gsi;
>> -       int max_gsi = 0;
>> -
>> -       if (acpi_disabled)
>> -               return 0;
>> -
>> -       if (!acpi_ioapic)
>> -               return 0;
>> -
>> -       max_gsi = 0;
>> -       for (idx = 0; idx < nr_ioapics; idx++) {
>> -               gsi = mp_gsi_routing[idx].gsi_end;
>> -
>> -               if (gsi > max_gsi)
>> -                       max_gsi = gsi;
>> -       }
>> -
>> -       return max_gsi + 1;
>> -}
>> -
>>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>>                                    struct mpc_intsrc *mp_irq)
>>  {
>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index 996cf8f..b57b7a3 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>
>>  void __init probe_nr_irqs_gsi(void)
>>  {
>> -       int nr = 0;
>> +       int nr;
>>
>> -       nr = acpi_probe_gsi();
>> -       if (nr > nr_irqs_gsi) {
>> +       nr = gsi_end;
>
> you may need +1 here

As documented in my comment that extra +1 has every appearance of a
bug.  Nothing is at gsi_end.  gsi_end is already at 1 past the last in
use gsi.  Therefore an extra +1 puts us two past the end for no
apparent reason.

Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
@ 2010-03-30  4:43                 ` Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  4:43 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

Yinghai Lu <yinghai@kernel.org> writes:

> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>> From: Eric W. Biederman <ebiederm@xmission.com>
>>
>> Use the global gsi_end value now that all ioapics have
>> valid gsi numbers instead of a combination of acpi_probe_gsi
>> and walking all of the ioapics and couting their number of
>> entries by hand if acpi_probe_gsi gave us an answer we did
>> not like.
>>
>> This fixes a small bug in probe_nr_irqs_gsi.  Previously
>> acpi_probe_gsi unnecessarily added 1 to the maximum
>> gsi_end value.  gsi_end is already one past the end of
>> the number of gsi's so the additional increment was
>> superfluous.
>>
>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>> ---
>>  arch/x86/include/asm/mpspec.h  |    6 ------
>>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>>  3 files changed, 3 insertions(+), 43 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>> index 29994f0..c82868e 100644
>> --- a/arch/x86/include/asm/mpspec.h
>> +++ b/arch/x86/include/asm/mpspec.h
>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>  struct device;
>>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>                                 int active_high_low);
>> -extern int acpi_probe_gsi(void);
>> -#else /* !CONFIG_ACPI: */
>> -static inline int acpi_probe_gsi(void)
>> -{
>> -       return 0;
>> -}
>>  #endif /* CONFIG_ACPI */
>>
>>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>> index 9c48e99..0e514a1 100644
>> --- a/arch/x86/kernel/acpi/boot.c
>> +++ b/arch/x86/kernel/acpi/boot.c
>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>  extern int es7000_plat;
>>  #endif
>>
>> -int __init acpi_probe_gsi(void)
>> -{
>> -       int idx;
>> -       int gsi;
>> -       int max_gsi = 0;
>> -
>> -       if (acpi_disabled)
>> -               return 0;
>> -
>> -       if (!acpi_ioapic)
>> -               return 0;
>> -
>> -       max_gsi = 0;
>> -       for (idx = 0; idx < nr_ioapics; idx++) {
>> -               gsi = mp_gsi_routing[idx].gsi_end;
>> -
>> -               if (gsi > max_gsi)
>> -                       max_gsi = gsi;
>> -       }
>> -
>> -       return max_gsi + 1;
>> -}
>> -
>>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>>                                    struct mpc_intsrc *mp_irq)
>>  {
>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index 996cf8f..b57b7a3 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>
>>  void __init probe_nr_irqs_gsi(void)
>>  {
>> -       int nr = 0;
>> +       int nr;
>>
>> -       nr = acpi_probe_gsi();
>> -       if (nr > nr_irqs_gsi) {
>> +       nr = gsi_end;
>
> you may need +1 here

As documented in my comment that extra +1 has every appearance of a
bug.  Nothing is at gsi_end.  gsi_end is already at 1 past the last in
use gsi.  Therefore an extra +1 puts us two past the end for no
apparent reason.

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-30  4:43                 ` Eric W. Biederman
  (?)
@ 2010-03-30  4:55                 ` Yinghai Lu
  2010-03-30  5:41                   ` Eric W. Biederman
  -1 siblings, 1 reply; 115+ messages in thread
From: Yinghai Lu @ 2010-03-30  4:55 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

On 03/29/2010 09:43 PM, Eric W. Biederman wrote:
> Yinghai Lu <yinghai@kernel.org> writes:
> 
>> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
>> <ebiederm@xmission.com> wrote:
>>> From: Eric W. Biederman <ebiederm@xmission.com>
>>>
>>> Use the global gsi_end value now that all ioapics have
>>> valid gsi numbers instead of a combination of acpi_probe_gsi
>>> and walking all of the ioapics and couting their number of
>>> entries by hand if acpi_probe_gsi gave us an answer we did
>>> not like.
>>>
>>> This fixes a small bug in probe_nr_irqs_gsi.  Previously
>>> acpi_probe_gsi unnecessarily added 1 to the maximum
>>> gsi_end value.  gsi_end is already one past the end of
>>> the number of gsi's so the additional increment was
>>> superfluous.
>>>
>>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>>> ---
>>>  arch/x86/include/asm/mpspec.h  |    6 ------
>>>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>>>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>>>  3 files changed, 3 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>>> index 29994f0..c82868e 100644
>>> --- a/arch/x86/include/asm/mpspec.h
>>> +++ b/arch/x86/include/asm/mpspec.h
>>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>>  struct device;
>>>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>>                                 int active_high_low);
>>> -extern int acpi_probe_gsi(void);
>>> -#else /* !CONFIG_ACPI: */
>>> -static inline int acpi_probe_gsi(void)
>>> -{
>>> -       return 0;
>>> -}
>>>  #endif /* CONFIG_ACPI */
>>>
>>>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
>>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>>> index 9c48e99..0e514a1 100644
>>> --- a/arch/x86/kernel/acpi/boot.c
>>> +++ b/arch/x86/kernel/acpi/boot.c
>>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>>  extern int es7000_plat;
>>>  #endif
>>>
>>> -int __init acpi_probe_gsi(void)
>>> -{
>>> -       int idx;
>>> -       int gsi;
>>> -       int max_gsi = 0;
>>> -
>>> -       if (acpi_disabled)
>>> -               return 0;
>>> -
>>> -       if (!acpi_ioapic)
>>> -               return 0;
>>> -
>>> -       max_gsi = 0;
>>> -       for (idx = 0; idx < nr_ioapics; idx++) {
>>> -               gsi = mp_gsi_routing[idx].gsi_end;
>>> -
>>> -               if (gsi > max_gsi)
>>> -                       max_gsi = gsi;
>>> -       }
>>> -
>>> -       return max_gsi + 1;
>>> -}
>>> -
>>>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>>>                                    struct mpc_intsrc *mp_irq)
>>>  {
>>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>>> index 996cf8f..b57b7a3 100644
>>> --- a/arch/x86/kernel/apic/io_apic.c
>>> +++ b/arch/x86/kernel/apic/io_apic.c
>>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>>
>>>  void __init probe_nr_irqs_gsi(void)
>>>  {
>>> -       int nr = 0;
>>> +       int nr;
>>>
>>> -       nr = acpi_probe_gsi();
>>> -       if (nr > nr_irqs_gsi) {
>>> +       nr = gsi_end;
>>
>> you may need +1 here
> 
> As documented in my comment that extra +1 has every appearance of a
> bug.  Nothing is at gsi_end.  gsi_end is already at 1 past the last in
> use gsi.  Therefore an extra +1 puts us two past the end for no
> apparent reason.

io_apic_get_redir_entries(), and io apic register readingout will return 23 if the total entries is 24.

[    0.000000] ACPI: IOAPIC (id[0x08] address[0xfec00000] gsi_base[0])
[    0.000000] IOAPIC[0]: apic_id 8, version 32, address 0xfec00000, GSI 0-23
[    0.000000] ACPI: IOAPIC (id[0x09] address[0xfec02000] gsi_base[24])
[    0.000000] IOAPIC[1]: apic_id 9, version 32, address 0xfec02000, GSI 24-47
[    0.000000] ACPI: IOAPIC (id[0x0a] address[0xfec04000] gsi_base[48])
[    0.000000] IOAPIC[2]: apic_id 10, version 32, address 0xfec04000, GSI 48-71
[    0.000000] ACPI: IOAPIC (id[0x0b] address[0xfec08000] gsi_base[72])
[    0.000000] IOAPIC[3]: apic_id 11, version 32, address 0xfec08000, GSI 72-95
[    0.000000] ACPI: IOAPIC (id[0x0c] address[0xfec0c000] gsi_base[96])
[    0.000000] IOAPIC[4]: apic_id 12, version 32, address 0xfec0c000, GSI 96-119

        mp_gsi_routing[idx].gsi_end = gsi_base +
            io_apic_get_redir_entries(idx);

        printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
               "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
               mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
               mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);

YH

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-30  4:55                 ` Yinghai Lu
@ 2010-03-30  5:41                   ` Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  5:41 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

Yinghai Lu <yinghai@kernel.org> writes:

> On 03/29/2010 09:43 PM, Eric W. Biederman wrote:
>> Yinghai Lu <yinghai@kernel.org> writes:
>> 
>>> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
>>> <ebiederm@xmission.com> wrote:
>>>> From: Eric W. Biederman <ebiederm@xmission.com>
>>>>
>>>> Use the global gsi_end value now that all ioapics have
>>>> valid gsi numbers instead of a combination of acpi_probe_gsi
>>>> and walking all of the ioapics and couting their number of
>>>> entries by hand if acpi_probe_gsi gave us an answer we did
>>>> not like.
>>>>
>>>> This fixes a small bug in probe_nr_irqs_gsi.  Previously
>>>> acpi_probe_gsi unnecessarily added 1 to the maximum
>>>> gsi_end value.  gsi_end is already one past the end of
>>>> the number of gsi's so the additional increment was
>>>> superfluous.
>>>>
>>>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>>>> ---
>>>>  arch/x86/include/asm/mpspec.h  |    6 ------
>>>>  arch/x86/kernel/acpi/boot.c    |   23 -----------------------
>>>>  arch/x86/kernel/apic/io_apic.c |   17 +++--------------
>>>>  3 files changed, 3 insertions(+), 43 deletions(-)
>>>>
>>>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>>>> index 29994f0..c82868e 100644
>>>> --- a/arch/x86/include/asm/mpspec.h
>>>> +++ b/arch/x86/include/asm/mpspec.h
>>>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>>>  struct device;
>>>>  extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>>>                                 int active_high_low);
>>>> -extern int acpi_probe_gsi(void);
>>>> -#else /* !CONFIG_ACPI: */
>>>> -static inline int acpi_probe_gsi(void)
>>>> -{
>>>> -       return 0;
>>>> -}
>>>>  #endif /* CONFIG_ACPI */
>>>>
>>>>  #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
>>>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>>>> index 9c48e99..0e514a1 100644
>>>> --- a/arch/x86/kernel/acpi/boot.c
>>>> +++ b/arch/x86/kernel/acpi/boot.c
>>>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>>>  extern int es7000_plat;
>>>>  #endif
>>>>
>>>> -int __init acpi_probe_gsi(void)
>>>> -{
>>>> -       int idx;
>>>> -       int gsi;
>>>> -       int max_gsi = 0;
>>>> -
>>>> -       if (acpi_disabled)
>>>> -               return 0;
>>>> -
>>>> -       if (!acpi_ioapic)
>>>> -               return 0;
>>>> -
>>>> -       max_gsi = 0;
>>>> -       for (idx = 0; idx < nr_ioapics; idx++) {
>>>> -               gsi = mp_gsi_routing[idx].gsi_end;
>>>> -
>>>> -               if (gsi > max_gsi)
>>>> -                       max_gsi = gsi;
>>>> -       }
>>>> -
>>>> -       return max_gsi + 1;
>>>> -}
>>>> -
>>>>  static void assign_to_mp_irq(struct mpc_intsrc *m,
>>>>                                    struct mpc_intsrc *mp_irq)
>>>>  {
>>>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>>>> index 996cf8f..b57b7a3 100644
>>>> --- a/arch/x86/kernel/apic/io_apic.c
>>>> +++ b/arch/x86/kernel/apic/io_apic.c
>>>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>>>
>>>>  void __init probe_nr_irqs_gsi(void)
>>>>  {
>>>> -       int nr = 0;
>>>> +       int nr;
>>>>
>>>> -       nr = acpi_probe_gsi();
>>>> -       if (nr > nr_irqs_gsi) {
>>>> +       nr = gsi_end;
>>>
>>> you may need +1 here
>> 
>> As documented in my comment that extra +1 has every appearance of a
>> bug.  Nothing is at gsi_end.  gsi_end is already at 1 past the last in
>> use gsi.  Therefore an extra +1 puts us two past the end for no
>> apparent reason.
>
> io_apic_get_redir_entries(), and io apic register readingout will return 23 if the total entries is 24.

Good catch.  I don't know if I have ever seen a function with a name to function
correspondence.  Apparently sfi.c also got this wrong when it was written.
and I missed the +1 in other places.

I guess this calls for another patch way at the beginning of my series that fixes
this brain damage.

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (13 preceding siblings ...)
  2010-03-29 23:20           ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
@ 2010-03-30  8:06           ` Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
                               ` (15 more replies)
  2010-04-01  2:02           ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
  15 siblings, 16 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:06 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich


It appears there are a few systems in the wild that use acpi
interrupt source overrides to report a gsi > 16 is an isa irq.

This breaks all kinds of assumptions I figure any BIOS doing that
probably should be shot as that is very much not a conservative position.

That said acpi appears to allow this insanity and on the basis of being
liberal in what we accept we should try to do something reasonable, and
keep our notions of gsi, isa irq, and linux irq as straight as we can.

To that end this patchset slightly modifies the gsi to linux irq
mapping.  Making it a 1 to 1 identity mapping except for the first 16
gsis.  If those gsis are isa irqs (the typical and default acpi
configuration) they will be mapped into the first 16 irqs.  If those
first 16 gsis are not isa irqs they will be given a linux irq number
just past the last gsi.  Allowing us the chance to use them.

This patchset is my attempt to straighten out our understanding of which
kind of irq name is used where and the cleanups used to get there.

Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
this and finding that there is a real world problem here.  This patchset
is inspired by his work, but little of it remains the same.

This patchset lies in the weird world between the acpi and x86 and ia64.
Since most of the changes are x86 related I think it makes most sense
to go via the x86 tree.

v2: Recognize that gsi_end is last gsi for an ioapic not one past the end.
    Since I use gsi_end widely in my patchset a respin of many of the patches
    made sense.

Eric W. Biederman (15):
      x86 acpi/irq: Introduce apci_isa_irq_to_gsi
      x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
      x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
      x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
      x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
      x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
      x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
      x86 ioapic: Fix the types of gsi values
      x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
      x86 ioapic: In mpparse use mp_register_ioapic
      x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
      x86 ioapic: Optimize pin_2_irq
      x86 ioapic: Simplify probe_nr_irqs_gsi.
      x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
      x86 irq: Kill io_apic_renumber_irq

 arch/ia64/kernel/acpi.c          |    8 ++
 arch/x86/include/asm/io_apic.h   |   12 ++--
 arch/x86/include/asm/mpspec.h    |   10 ---
 arch/x86/kernel/acpi/boot.c      |  133 ++++++++++++++++++++++++--------------
 arch/x86/kernel/apic/es7000_32.c |   19 ------
 arch/x86/kernel/apic/io_apic.c   |   99 +++++++++++++---------------
 arch/x86/kernel/mpparse.c        |   25 +-------
 arch/x86/kernel/sfi.c            |    4 +-
 drivers/acpi/pci_irq.c           |    8 ++-
 include/linux/acpi.h             |    5 +-
 10 files changed, 154 insertions(+), 169 deletions(-)

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:06               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
                               ` (14 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

There are a number of cases where the current code makes the assumption
that isa irqs identity map to the first 16 acpi global system intereupts.
In most instances that assumption is correct as that is the required
behaviour in dual i8259 mode and the default behavior in ioapic mode.

However there are some systems out there that take advantage of acpis
interrupt remapping  for the isa irqs to have a completely different
mapping of isa_irq to gsi.

Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the
code that needs it.  Initially this will be just the current assumed
identity mapping to ensure it's introduction does not cause regressions.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/ia64/kernel/acpi.c     |    8 ++++++++
 arch/x86/kernel/acpi/boot.c |    8 ++++++++
 include/linux/acpi.h        |    1 +
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index f1c9f70..16921bd 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -784,6 +784,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  *  ACPI based hotplug CPU support
  */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0061ea2..f96060d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -457,6 +457,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b926afe..7a937da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags;
 
 int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
                               ` (13 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

In perverse acpi implementations the isa irqs are not identity mapped
to the first 16 gsi.  Furthermore at least the extended interrupt
resource capability may return gsi's and not isa irqs.  So since
what we get from acpi is a gsi teach acpi_get_overrride_irq to
operate on a gsi instead of an isa_irq.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   23 ++++++++++++++---------
 include/linux/acpi.h           |    4 ++--
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..54ba1f7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4073,22 +4073,27 @@ int __init io_apic_get_version(int ioapic)
 	return reg_01.bits.version;
 }
 
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
 {
-	int i;
+	int ioapic, pin, idx;
 
 	if (skip_ioapic_setup)
 		return -1;
 
-	for (i = 0; i < mp_irq_entries; i++)
-		if (mp_irqs[i].irqtype == mp_INT &&
-		    mp_irqs[i].srcbusirq == bus_irq)
-			break;
-	if (i >= mp_irq_entries)
+	ioapic = mp_find_ioapic(gsi);
+	if (ioapic < 0)
+		return -1;
+
+	pin = mp_find_ioapic_pin(ioapic, gsi);
+	if (pin < 0)
+		return -1;
+
+	idx = find_irq_entry(ioapic, pin, mp_INT);
+	if (idx < 0)
 		return -1;
 
-	*trigger = irq_trigger(i);
-	*polarity = irq_polarity(i);
+	*trigger = irq_trigger(idx);
+	*polarity = irq_polarity(idx);
 	return 0;
 }
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a937da..3da73f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 #else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
 #endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
                               ` (12 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Strictly speaking on x86 (where acpi is used) dev->irq must be
a dual i8259 irq input aka an isa irq.  Therefore we should translate
that isa irq into a gsi before passing it to a function that
takes a gsi.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 drivers/acpi/pci_irq.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699e..703541d 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -400,11 +400,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * driver reported one, then use it. Exit in any case.
 	 */
 	if (gsi < 0) {
+		u32 dev_gsi;
 		dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq > 0 && (dev->irq <= 0xF)) {
-			printk(" - using IRQ %d\n", dev->irq);
-			acpi_register_gsi(&dev->dev, dev->irq,
+		if (dev->irq > 0 && (dev->irq <= 0xF) &&
+		    (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+			printk(" - using ISA IRQ %d\n", dev->irq);
+			acpi_register_gsi(&dev->dev, dev_gsi,
 					  ACPI_LEVEL_SENSITIVE,
 					  ACPI_ACTIVE_LOW);
 			return 0;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (2 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
                               ` (11 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with
bus_irq == gsi, which is wrong if we are comming from an override
Instead pass the bus_irq into acpi_sci_ioapic_setup.

This fix was inspired by a similar fix from:
Yinghai Lu <yinghai@kernel.org>

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index f96060d..1742888 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -312,7 +312,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
 {
 	if (trigger == 0)	/* compatible SCI trigger is level */
 		trigger = 3;
@@ -332,7 +332,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
 	 * If GSI is < 16, this will update its flags,
 	 * else it will create a new mp_irqs[] entry.
 	 */
-	mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
 	/*
 	 * stash over-ride to indicate we've been here
@@ -356,9 +356,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-		acpi_sci_ioapic_setup(intsrc->global_irq,
+		acpi_sci_ioapic_setup(intsrc->source_irq,
 				      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
-				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+				      intsrc->global_irq);
 		return 0;
 	}
 
@@ -1161,7 +1162,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	 * pretend we got one so we can set the SCI flags.
 	 */
 	if (!acpi_sci_override_gsi)
-		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+				      acpi_gbl_FADT.sci_interrupt);
 
 	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (3 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
                               ` (10 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Remove the assumption that there is not an override for isa irq 0.
Instead lookup the gsi and from that lookup the ioapic and pin of each
isa irq indivdually.

In general this should not have any behavioural affect but in
perverse cases this gets all of the details correct, instead of
doing something weird.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 1742888..9c48e99 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -960,8 +960,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 void __init mp_config_acpi_legacy_irqs(void)
 {
 	int i;
-	int ioapic;
-	unsigned int dstapic;
 	struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -982,19 +980,27 @@ void __init mp_config_acpi_legacy_irqs(void)
 #endif
 
 	/*
-	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
-	 */
-	ioapic = mp_find_ioapic(0);
-	if (ioapic < 0)
-		return;
-	dstapic = mp_ioapics[ioapic].apicid;
-
-	/*
 	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overridden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int ioapic, pin;
+		unsigned int dstapic;
 		int idx;
+		u32 gsi;
+
+		/* Locate the gsi that irq i maps to. */
+		if (acpi_isa_irq_to_gsi(i, &gsi))
+			continue;
+
+		/*
+		 * Locate the IOAPIC that manages the ISA IRQ.
+		 */
+		ioapic = mp_find_ioapic(gsi);
+		if (ioapic < 0)
+			continue;
+		pin = mp_find_ioapic_pin(ioapic, gsi);
+		dstapic = mp_ioapics[ioapic].apicid;
 
 		for (idx = 0; idx < mp_irq_entries; idx++) {
 			struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1004,7 +1010,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 				break;
 
 			/* Do we already have a mapping for this IOAPIC pin */
-			if (irq->dstapic == dstapic && irq->dstirq == i)
+			if (irq->dstapic == dstapic && irq->dstirq == pin)
 				break;
 		}
 
@@ -1019,7 +1025,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 		mp_irq.dstapic = dstapic;
 		mp_irq.irqtype = mp_INT;
 		mp_irq.srcbusirq = i; /* Identity mapped */
-		mp_irq.dstirq = i;
+		mp_irq.dstirq = pin;
 
 		save_mp_irq(&mp_irq);
 	}
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (4 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
                               ` (9 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Multiple declarations of the same function in different headers
is a pain to maintain.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/mpspec.h |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..29994f0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -106,10 +106,6 @@ struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
 extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
 #else /* !CONFIG_ACPI: */
 static inline int acpi_probe_gsi(void)
 {
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (5 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
                               ` (8 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

io_apic_redir_entries has a huge conceptual bug.  It returns the maximum
redirection entry not the number of redirection entries.  Which simply
does not match what the name of the function.  This just caught me
and it caught  Feng Tang, and  Len Brown when they wrote sfi_parse_ioapic.

Modify io_apic_redir_entries to actually return the number of redirection
entries, and fix the callers so that they properly handle receiving the
number of the number of redirection table entries, instead of the
number of redirection table entries less one.

While the usage in sfi.c does not show up in this patch it is fixed
by virtue of the fact that io_apic_redir_entries now has the semantics
sfi_parse_ioapic most reasonably expects.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 54ba1f7..7e139bb 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3846,7 +3846,11 @@ int __init io_apic_get_redir_entries (int ioapic)
 	reg_01.raw = io_apic_read(ioapic, 1);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
-	return reg_01.bits.entries;
+	/* The register returns the maximum index redir index
+	 * supported, which is one less than the total number of redir
+	 * entries.
+	 */
+	return reg_01.bits.entries + 1;
 }
 
 void __init probe_nr_irqs_gsi(void)
@@ -3862,7 +3866,7 @@ void __init probe_nr_irqs_gsi(void)
 
 		nr = 0;
 		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx) + 1;
+			nr += io_apic_get_redir_entries(idx);
 
 		if (nr > nr_irqs_gsi)
 			nr_irqs_gsi = nr;
@@ -4297,7 +4301,7 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 */
 	mp_gsi_routing[idx].gsi_base = gsi_base;
 	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx);
+	    io_apic_get_redir_entries(idx) - 1;
 
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 08/15] x86 ioapic: Fix the types of gsi values
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (6 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
                               ` (7 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

This patches fixes the types of gsi_base and gsi_end values in
struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic
and mp_find_ioapic_pin

A gsi is cannonically a u32, not an int.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h |   10 +++++-----
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..feeaf0d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
 extern void setup_ioapic_ids_from_mpc(void);
 
 struct mp_ioapic_gsi{
-	int gsi_base;
-	int gsi_end;
+	u32 gsi_base;
+	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -197,7 +197,7 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7e139bb..4611c43 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4238,7 +4238,7 @@ void __init ioapic_insert_resources(void)
 	}
 }
 
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
 {
 	int i = 0;
 
@@ -4253,7 +4253,7 @@ int mp_find_ioapic(int gsi)
 	return -1;
 }
 
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
 	if (WARN_ON(ioapic == -1))
 		return -1;
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (7 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
                               ` (6 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Add the global variable gsi_end and teach mp_register_ioapic
to keep it uptodate as we add more ioapics into the system.

ioapics can only be added early in boot so the code that
runs later can treat gsi_end as a constant.

Remove the have hacks in sfi.c to second guess mp_register_ioapic
by keeping t's own running total of how many gsi's have been seen,
and instead use the gsi_end.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h |    1 +
 arch/x86/kernel/apic/io_apic.c |    6 ++++++
 arch/x86/kernel/sfi.c          |    4 +---
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index feeaf0d..37b0f2b 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,7 @@ struct mp_ioapic_gsi{
 	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
+extern u32 gsi_end;
 int mp_find_ioapic(u32 gsi);
 int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4611c43..71988c5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -88,6 +88,9 @@ int nr_ioapics;
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
 
+/* The last gsi number used */
+u32 gsi_end;
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
@@ -4303,6 +4306,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	mp_gsi_routing[idx].gsi_end = gsi_base +
 	    io_apic_get_redir_entries(idx) - 1;
 
+	if (mp_gsi_routing[idx].gsi_end > gsi_end)
+		gsi_end = mp_gsi_routing[idx].gsi_end;
+
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
 	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index 34e0993..7ded578 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 	pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
 	for (i = 0; i < num; i++) {
-		mp_register_ioapic(i, pentry->phys_addr, gsi_base);
-		gsi_base += io_apic_get_redir_entries(i);
+		mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
 		pentry++;
 	}
 
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (8 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
                               ` (5 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Long ago MP_ioapic_info was the primary way of setting up our
ioapic data structures and mp_register_ioapic was a compatibility
shim for acpi code.  Now the situation is reversed and
and mp_register_ioapic is the primary way of setting up our
ioapic data structures.

Keep the setting up of ioapic data structures uniform by
having mp_register_ioapic call mp_register_ioapic.

This changes a few fields:

- type: is now hardset to MP_IOAPIC but type had to
  bey MP_IOAPIC or MP_ioapic_info would not have been called.

- flags: is now hard coded to MPC_APIC_USABLE.
  We require flags to contain at least MPC_APIC_USEBLE in
  MP_ioapic_info and we don't ever examine flags so dropping
  a few flags that might possibly exist that we have never
  used is harmless.

- apicaddr: Unchanged

- apicver: Read from the ioapic instead of using the cached
  hardware value in the MP table.  The real hardware value
  will be more accurate.

- apicid: Now verified to be unique and changed if it is not.
  If the BIOS got this right this is a noop.  If the BIOS did
  not fixing things appears to be the better solution.

This adds gsi_base and gsi_end values to our ioapics defined with
the mpatable, which will make our lives simpler later since
we can always assume gsi_base and gsi_end are valid.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/mpparse.c |   25 +------------------------
 1 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a2c1edd..22ba4f3 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
-static int bad_ioapic(unsigned long address)
-{
-	if (nr_ioapics >= MAX_IO_APICS) {
-		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-		       "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-	}
-	if (!address) {
-		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-		       " found in table, skipping!\n");
-		return 1;
-	}
-	return 0;
-}
-
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
 	if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
 	printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
 	       m->apicid, m->apicver, m->apicaddr);
 
-	if (bad_ioapic(m->apicaddr))
-		return;
-
-	mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
-	mp_ioapics[nr_ioapics].apicid = m->apicid;
-	mp_ioapics[nr_ioapics].type = m->type;
-	mp_ioapics[nr_ioapics].apicver = m->apicver;
-	mp_ioapics[nr_ioapics].flags = m->flags;
-	nr_ioapics++;
+	mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
 }
 
 static void print_MP_intsrc_info(struct mpc_intsrc *m)
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (9 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
                               ` (4 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that all ioapic registration happens in mp_register_ioapic we can
move the calculation of nr_ioapic_registers there from enable_IO_APIC.
The number of ioapic registers is already calucated in mp_register_ioapic
so all that really needs to be done is to save the caluclated value
in nr_ioapic_registers.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 71988c5..c505fe0 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1944,20 +1944,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 void __init enable_IO_APIC(void)
 {
-	union IO_APIC_reg_01 reg_01;
 	int i8259_apic, i8259_pin;
 	int apic;
-	unsigned long flags;
-
-	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		raw_spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(apic, 1);
-		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-	}
 
 	if (!legacy_pic->nr_legacy_irqs)
 		return;
@@ -4284,6 +4272,7 @@ static int bad_ioapic(unsigned long address)
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
 	int idx = 0;
+	int entries;
 
 	if (bad_ioapic(address))
 		return;
@@ -4302,9 +4291,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
+	entries = io_apic_get_redir_entries(idx);
 	mp_gsi_routing[idx].gsi_base = gsi_base;
-	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx) - 1;
+	mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	nr_ioapic_registers[idx] = entries;
 
 	if (mp_gsi_routing[idx].gsi_end > gsi_end)
 		gsi_end = mp_gsi_routing[idx].gsi_end;
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 12/15] x86 ioapic: Optimize pin_2_irq
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (10 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
                               ` (3 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that all ioapics have valid gsi_base values use this to
accellerate pin_2_irq.  In the case of acpi this also ensures
that pin_2_irq will compute the same irq value for an ioapic
pin as acpi will.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/apic/io_apic.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c505fe0..764c74c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1018,7 +1018,7 @@ static inline int irq_trigger(int idx)
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-	int irq, i;
+	int irq;
 	int bus = mp_irqs[idx].srcbus;
 
 	/*
@@ -1030,18 +1030,13 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
+		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
 		/*
                  * For MPS mode, so far only needed by ES7000 platform
                  */
 		if (ioapic_renumber_irq)
-			irq = ioapic_renumber_irq(apic, irq);
+			gsi = ioapic_renumber_irq(apic, gsi);
+		irq = gsi;
 	}
 
 #ifdef CONFIG_X86_32
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (11 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
                               ` (2 subsequent siblings)
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Use the global gsi_end value now that all ioapics have
valid gsi numbers instead of a combination of acpi_probe_gsi
and walking all of the ioapics and couting their number of
entries by hand if acpi_probe_gsi gave us an answer we did
not like.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/mpspec.h  |    6 ------
 arch/x86/kernel/acpi/boot.c    |   23 -----------------------
 arch/x86/kernel/apic/io_apic.c |   17 +++--------------
 3 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 29994f0..c82868e 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
-extern int acpi_probe_gsi(void);
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
-	return 0;
-}
 #endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9c48e99..0e514a1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-int __init acpi_probe_gsi(void)
-{
-	int idx;
-	int gsi;
-	int max_gsi = 0;
-
-	if (acpi_disabled)
-		return 0;
-
-	if (!acpi_ioapic)
-		return 0;
-
-	max_gsi = 0;
-	for (idx = 0; idx < nr_ioapics; idx++) {
-		gsi = mp_gsi_routing[idx].gsi_end;
-
-		if (gsi > max_gsi)
-			max_gsi = gsi;
-	}
-
-	return max_gsi + 1;
-}
-
 static void assign_to_mp_irq(struct mpc_intsrc *m,
 				    struct mpc_intsrc *mp_irq)
 {
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 764c74c..6d6def8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3841,22 +3841,11 @@ int __init io_apic_get_redir_entries (int ioapic)
 
 void __init probe_nr_irqs_gsi(void)
 {
-	int nr = 0;
+	int nr;
 
-	nr = acpi_probe_gsi();
-	if (nr > nr_irqs_gsi) {
+	nr = gsi_end + 1;
+	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
-	} else {
-		/* for acpi=off or acpi is not compiled in */
-		int idx;
-
-		nr = 0;
-		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx);
-
-		if (nr > nr_irqs_gsi)
-			nr_irqs_gsi = nr;
-	}
 
 	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (12 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-03-30  8:07             ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
  2010-05-03 23:21             ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

ACPI irq source overrides are allowed for the 16 isa irqs and are
allowed to map any gsi to any isa irq.  A few motherboards have been
seen to take advantage of this and put the isa irqs on the 2nd or
3rd ioapic.  This causes some problems, most notably the fact
that we can not use any gsi < 16.

To correct this move the gsis that are not isa irqs and have
a gsi number < 16 into the linux irq space just past gsi_end.
This is what the es7000 platform is doing today.  Moving only the
low 16 gsis above the rest of the gsi's only penalizes weird
platforms, leaving sane acpi implementations with a 1-1 mapping
of gsis and irqs.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c    |   57 +++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/apic/io_apic.c |    8 ++++-
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0e514a1..c4b4bd9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -92,6 +92,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
 
+/* 
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+	unsigned int irq = gsi + NR_IRQS_LEGACY;
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		if (isa_irq_to_gsi[i] == gsi) {
+			return i;
+		}
+	}
+
+	/* Provide an identity mapping of gsi == irq
+	 * except on truly weird platforms that have
+	 * non isa irqs in the first 16 gsis.
+	 */
+	if (gsi >= NR_IRQS_LEGACY)
+		irq = gsi;
+	else
+		irq = gsi_end + 1 + gsi;
+
+	return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+	unsigned int gsi;
+
+	if (irq < NR_IRQS_LEGACY)
+		gsi = isa_irq_to_gsi[irq];
+	else if (irq <= gsi_end)
+		gsi = irq;
+	else if (irq <= (gsi_end + NR_IRQS_LEGACY))
+		gsi = irq - gsi_end;
+	else
+		gsi = 0xffffffff;
+
+	return gsi;
+}
+
 /*
  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
@@ -448,7 +495,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	*irq = gsi;
+	*irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -462,7 +509,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 {
 	if (isa_irq >= 16)
 		return -1;
-	*gsi = isa_irq;
+	*gsi = irq_to_gsi(isa_irq);
 	return 0;
 }
 
@@ -490,7 +537,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
 	}
 #endif
-	irq = plat_gsi;
+	irq = gsi_to_irq(plat_gsi);
 
 	return irq;
 }
@@ -932,6 +979,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 	mp_irq.dstirq = pin;	/* INTIN# */
 
 	save_mp_irq(&mp_irq);
+
+	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
@@ -1085,7 +1134,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	io_apic_set_pci_routing(dev, gsi, &irq_attr);
+	io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 
 	return gsi;
 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6d6def8..0ac368a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1036,7 +1036,11 @@ static int pin_2_irq(int idx, int apic, int pin)
                  */
 		if (ioapic_renumber_irq)
 			gsi = ioapic_renumber_irq(apic, gsi);
-		irq = gsi;
+
+		if (gsi >= NR_IRQS_LEGACY)
+			irq = gsi;
+		else
+			irq = gsi_end + 1 + gsi;
 	}
 
 #ifdef CONFIG_X86_32
@@ -3843,7 +3847,7 @@ void __init probe_nr_irqs_gsi(void)
 {
 	int nr;
 
-	nr = gsi_end + 1;
+	nr = gsi_end + 1 + NR_IRQS_LEGACY;
 	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
 
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (13 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-03-30  8:07             ` Eric W. Biederman
  2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-05-03 23:21             ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
  15 siblings, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-03-30  8:07 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
	linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
	Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
	Natalie Protasevich, Eric W. Biederman

From: Eric W. Biederman <ebiederm@xmission.com>

Now that the generic irq layer is performing the exact same remapping as
io_apic_renumber_irq we can kill this weird  es7000 specific function.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h   |    1 -
 arch/x86/kernel/acpi/boot.c      |    5 -----
 arch/x86/kernel/apic/es7000_32.c |   19 -------------------
 arch/x86/kernel/apic/io_apic.c   |    6 ------
 4 files changed, 0 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 37b0f2b..9da192a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
 void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
 
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c4b4bd9..614f3a7 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1116,11 +1116,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
 	ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
-#ifdef CONFIG_X86_32
-	if (ioapic_renumber_irq)
-		gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 		       "%d-%d\n", mp_ioapics[ioapic].apicid,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index dd2b5f2..7a63d47 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -130,24 +130,6 @@ int					es7000_plat;
 
 static unsigned int			base;
 
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-	if (es7000_plat == ES7000_ZORRO)
-		return gsi;
-
-	if (!base) {
-		int i;
-		for (i = 0; i < nr_ioapics; i++)
-			base += nr_ioapic_registers[i];
-	}
-
-	if (!ioapic && (gsi < 16))
-		gsi += base;
-
-	return gsi;
-}
-
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
 	unsigned long vect = 0, psaival = 0;
@@ -189,7 +171,6 @@ static void setup_unisys(void)
 		es7000_plat = ES7000_ZORRO;
 	else
 		es7000_plat = ES7000_CLASSIC;
-	ioapic_renumber_irq = es7000_rename_gsi;
 }
 
 /*
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0ac368a..d23002d 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1015,7 +1015,6 @@ static inline int irq_trigger(int idx)
 	return MPBIOS_trigger(idx);
 }
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq;
@@ -1031,11 +1030,6 @@ static int pin_2_irq(int idx, int apic, int pin)
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
 		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
-		/*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-		if (ioapic_renumber_irq)
-			gsi = ioapic_renumber_irq(apic, gsi);
 
 		if (gsi >= NR_IRQS_LEGACY)
 			irq = gsi;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
  2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
                             ` (14 preceding siblings ...)
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
@ 2010-04-01  2:02           ` Len Brown
  2010-04-01  3:31             ` Eric W. Biederman
  15 siblings, 1 reply; 115+ messages in thread
From: Len Brown @ 2010-04-01  2:02 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: H. Peter Anvin, Thomas Gleixner, Yinghai Lu, Ingo Molnar,
	Andrew Morton, Jesse Barnes, linux-kernel, Thomas Renninger,
	Suresh Siddha, len.brown, Tony Luck, Fenghua Yu, linux-acpi,
	Iranna D Ankad, Gary Hade, Natalie Protasevich

> It appears there are a few systems in the wild that use acpi
> interrupt source overrides to report a gsi > 16 is an isa irq.
> 
> This breaks all kinds of assumptions I figure any BIOS doing that
> probably should be shot as that is very much not a conservative position.

You might run into trouble here on the ES7000 -- though I don't know
if anybody is booting a modern kernel on one of those these days.

IIR, ES7000 treated the bottom 16 as a special case.
When there was an irq shortage, I think they used overrides
to map higher PCI irqs into the empty spots below 16,
but I think to make room for them they may have mapped
some of the ISA irqs to high numbers.  Fuzzy memory
on this at the moment...

cheers,
Len Brown, Intel Open Source Technology Center


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
  2010-04-01  2:02           ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
@ 2010-04-01  3:31             ` Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-04-01  3:31 UTC (permalink / raw)
  To: Len Brown
  Cc: H. Peter Anvin, Thomas Gleixner, Yinghai Lu, Ingo Molnar,
	Andrew Morton, Jesse Barnes, linux-kernel, Thomas Renninger,
	Suresh Siddha, len.brown, Tony Luck, Fenghua Yu, linux-acpi,
	Iranna D Ankad, Gary Hade, Natalie Protasevich

Len Brown <lenb@kernel.org> writes:

>> It appears there are a few systems in the wild that use acpi
>> interrupt source overrides to report a gsi > 16 is an isa irq.
>> 
>> This breaks all kinds of assumptions I figure any BIOS doing that
>> probably should be shot as that is very much not a conservative position.
>
> You might run into trouble here on the ES7000 -- though I don't know
> if anybody is booting a modern kernel on one of those these days.
>
> IIR, ES7000 treated the bottom 16 as a special case.
> When there was an irq shortage, I think they used overrides
> to map higher PCI irqs into the empty spots below 16,
> but I think to make room for them they may have mapped
> some of the ISA irqs to high numbers.  Fuzzy memory
> on this at the moment...

A couple of things.

The ES7000 change is trivially safe because despite differences in how
the numbers are computed I have made that transform that the es7000
does always apply.

I also talked to Natalie about this.  I can't be certain about this
but from your description, from Natalies memories and from looking
at the code.  I believe the problem on the ES7000 is exactly what
I am fixing in the code.  Natalie has threatened to test this on
an ES7000.

The case of interest is this:
Weird but valid platforms where
GSI 0-15 are not ISA irqs.

Some high numbered GSIs are ISA irqs and use interrupt source
overrides to describe them.

That is the case on the IBM platform that regressed a bit ago
and Iranna D Ankad bisected a failure on. On that IBM platform
GSI 0-15 (because the are not ISA irqs) are unusable today.

Everything points to this problem I an fixing being the problem with
early ES7000 machines, including the memory of their boot firmware
developers complaint that they were in spec.

Eric


^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2
  2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
                               ` (14 preceding siblings ...)
  2010-03-30  8:07             ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
@ 2010-05-03 23:21             ` Eric W. Biederman
  15 siblings, 0 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-05-03 23:21 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
	Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
	len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
	Gary Hade, Natalie Protasevich

ebiederm@xmission.com (Eric W. Biederman) writes:

> It appears there are a few systems in the wild that use acpi
> interrupt source overrides to report a gsi > 16 is an isa irq.
>
> This breaks all kinds of assumptions I figure any BIOS doing that
> probably should be shot as that is very much not a conservative position.
>
> That said acpi appears to allow this insanity and on the basis of being
> liberal in what we accept we should try to do something reasonable, and
> keep our notions of gsi, isa irq, and linux irq as straight as we can.
>
> To that end this patchset slightly modifies the gsi to linux irq
> mapping.  Making it a 1 to 1 identity mapping except for the first 16
> gsis.  If those gsis are isa irqs (the typical and default acpi
> configuration) they will be mapped into the first 16 irqs.  If those
> first 16 gsis are not isa irqs they will be given a linux irq number
> just past the last gsi.  Allowing us the chance to use them.
>
> This patchset is my attempt to straighten out our understanding of which
> kind of irq name is used where and the cleanups used to get there.
>
> Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
> this and finding that there is a real world problem here.  This patchset
> is inspired by his work, but little of it remains the same.
>
> This patchset lies in the weird world between the acpi and x86 and ia64.
> Since most of the changes are x86 related I think it makes most sense
> to go via the x86 tree.
>
> v2: Recognize that gsi_end is last gsi for an ioapic not one past the end.
>     Since I use gsi_end widely in my patchset a respin of many of the patches
>     made sense.
>
> Eric W. Biederman (15):
>       x86 acpi/irq: Introduce apci_isa_irq_to_gsi
>       x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
>       x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
>       x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
>       x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
>       x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
>       x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
>       x86 ioapic: Fix the types of gsi values
>       x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
>       x86 ioapic: In mpparse use mp_register_ioapic
>       x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
>       x86 ioapic: Optimize pin_2_irq
>       x86 ioapic: Simplify probe_nr_irqs_gsi.
>       x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
>       x86 irq: Kill io_apic_renumber_irq
>
>  arch/ia64/kernel/acpi.c          |    8 ++
>  arch/x86/include/asm/io_apic.h   |   12 ++--
>  arch/x86/include/asm/mpspec.h    |   10 ---
>  arch/x86/kernel/acpi/boot.c      |  133 ++++++++++++++++++++++++--------------
>  arch/x86/kernel/apic/es7000_32.c |   19 ------
>  arch/x86/kernel/apic/io_apic.c   |   99 +++++++++++++---------------
>  arch/x86/kernel/mpparse.c        |   25 +-------
>  arch/x86/kernel/sfi.c            |    4 +-
>  drivers/acpi/pci_irq.c           |    8 ++-
>  include/linux/acpi.h             |    5 +-
>  10 files changed, 154 insertions(+), 169 deletions(-)

ping

Where are we at with this patchset?

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Introduce apci_isa_irq_to_gsi
  2010-03-30  8:07             ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
@ 2010-05-05  2:06               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:06 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  2c2df8418ac7908eec4558407b83f16739006c54
Gitweb:     http://git.kernel.org/tip/2c2df8418ac7908eec4558407b83f16739006c54
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:02 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:23 -0700

x86, acpi/irq: Introduce apci_isa_irq_to_gsi

There are a number of cases where the current code makes the assumption
that isa irqs identity map to the first 16 acpi global system intereupts.
In most instances that assumption is correct as that is the required
behaviour in dual i8259 mode and the default behavior in ioapic mode.

However there are some systems out there that take advantage of acpis
interrupt remapping  for the isa irqs to have a completely different
mapping of isa_irq to gsi.

Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the
code that needs it.  Initially this will be just the current assumed
identity mapping to ensure it's introduction does not cause regressions.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-1-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/ia64/kernel/acpi.c     |    8 ++++++++
 arch/x86/kernel/acpi/boot.c |    8 ++++++++
 include/linux/acpi.h        |    1 +
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 4d1a7e9..c6c90f3 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -785,6 +785,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  *  ACPI based hotplug CPU support
  */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index cd40aba..da718d6 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -458,6 +458,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 	return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+	if (isa_irq >= 16)
+		return -1;
+	*gsi = isa_irq;
+	return 0;
+}
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b926afe..7a937da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags;
 
 int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
  2010-03-30  8:07             ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
@ 2010-05-05  2:07               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:07 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  9a0a91bb56d2915cdb8585717de38376ad20fef9
Gitweb:     http://git.kernel.org/tip/9a0a91bb56d2915cdb8585717de38376ad20fef9
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:03 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:27 -0700

x86, acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq

In perverse acpi implementations the isa irqs are not identity mapped
to the first 16 gsi.  Furthermore at least the extended interrupt
resource capability may return gsi's and not isa irqs.  So since
what we get from acpi is a gsi teach acpi_get_overrride_irq to
operate on a gsi instead of an isa_irq.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-2-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/apic/io_apic.c |   23 ++++++++++++++---------
 include/linux/acpi.h           |    4 ++--
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 127b871..73ec928 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4082,22 +4082,27 @@ int __init io_apic_get_version(int ioapic)
 	return reg_01.bits.version;
 }
 
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
 {
-	int i;
+	int ioapic, pin, idx;
 
 	if (skip_ioapic_setup)
 		return -1;
 
-	for (i = 0; i < mp_irq_entries; i++)
-		if (mp_irqs[i].irqtype == mp_INT &&
-		    mp_irqs[i].srcbusirq == bus_irq)
-			break;
-	if (i >= mp_irq_entries)
+	ioapic = mp_find_ioapic(gsi);
+	if (ioapic < 0)
+		return -1;
+
+	pin = mp_find_ioapic_pin(ioapic, gsi);
+	if (pin < 0)
+		return -1;
+
+	idx = find_irq_entry(ioapic, pin, mp_INT);
+	if (idx < 0)
 		return -1;
 
-	*trigger = irq_trigger(i);
-	*polarity = irq_polarity(i);
+	*trigger = irq_trigger(idx);
+	*polarity = irq_polarity(idx);
 	return 0;
 }
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a937da..3da73f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 #else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
 #endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: pci device dev->irq is an isa irq not a gsi
  2010-03-30  8:07             ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
@ 2010-05-05  2:07               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:07 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  414d3448dbcb40807a1265ace64b2576ef919fbe
Gitweb:     http://git.kernel.org/tip/414d3448dbcb40807a1265ace64b2576ef919fbe
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:04 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:30 -0700

x86, acpi/irq: pci device dev->irq is an isa irq not a gsi

Strictly speaking on x86 (where acpi is used) dev->irq must be
a dual i8259 irq input aka an isa irq.  Therefore we should translate
that isa irq into a gsi before passing it to a function that
takes a gsi.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-3-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 drivers/acpi/pci_irq.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index b0a71ec..e4804fb 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -401,11 +401,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 	 * driver reported one, then use it. Exit in any case.
 	 */
 	if (gsi < 0) {
+		u32 dev_gsi;
 		dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq > 0 && (dev->irq <= 0xF)) {
-			printk(" - using IRQ %d\n", dev->irq);
-			acpi_register_gsi(&dev->dev, dev->irq,
+		if (dev->irq > 0 && (dev->irq <= 0xF) &&
+		    (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+			printk(" - using ISA IRQ %d\n", dev->irq);
+			acpi_register_gsi(&dev->dev, dev_gsi,
 					  ACPI_LEVEL_SENSITIVE,
 					  ACPI_ACTIVE_LOW);
 			return 0;

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
  2010-03-30  8:07             ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
@ 2010-05-05  2:07               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:07 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  9d2062b879495649bb525cf7979126da2e45d288
Gitweb:     http://git.kernel.org/tip/9d2062b879495649bb525cf7979126da2e45d288
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:05 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:34 -0700

x86, acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi

Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with
bus_irq == gsi, which is wrong if we are comming from an override
Instead pass the bus_irq into acpi_sci_ioapic_setup.

This fix was inspired by a similar fix from:
Yinghai Lu <yinghai@kernel.org>

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-4-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/acpi/boot.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index da718d6..0a036dc 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -313,7 +313,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
 {
 	if (trigger == 0)	/* compatible SCI trigger is level */
 		trigger = 3;
@@ -333,7 +333,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
 	 * If GSI is < 16, this will update its flags,
 	 * else it will create a new mp_irqs[] entry.
 	 */
-	mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
 	/*
 	 * stash over-ride to indicate we've been here
@@ -357,9 +357,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-		acpi_sci_ioapic_setup(intsrc->global_irq,
+		acpi_sci_ioapic_setup(intsrc->source_irq,
 				      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
-				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+				      (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+				      intsrc->global_irq);
 		return 0;
 	}
 
@@ -1162,7 +1163,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	 * pretend we got one so we can set the SCI flags.
 	 */
 	if (!acpi_sci_override_gsi)
-		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+				      acpi_gbl_FADT.sci_interrupt);
 
 	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Generalize mp_config_acpi_legacy_irqs
  2010-03-30  8:07             ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
@ 2010-05-05  2:07               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:07 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  0fd52670fb6400be0996ac492b5ed77f3d83d69a
Gitweb:     http://git.kernel.org/tip/0fd52670fb6400be0996ac492b5ed77f3d83d69a
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:06 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:38 -0700

x86, acpi/irq: Generalize mp_config_acpi_legacy_irqs

Remove the assumption that there is not an override for isa irq 0.
Instead lookup the gsi and from that lookup the ioapic and pin of each
isa irq indivdually.

In general this should not have any behavioural affect but in
perverse cases this gets all of the details correct, instead of
doing something weird.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-5-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/acpi/boot.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0a036dc..3ee92f2 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -961,8 +961,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 void __init mp_config_acpi_legacy_irqs(void)
 {
 	int i;
-	int ioapic;
-	unsigned int dstapic;
 	struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -983,19 +981,27 @@ void __init mp_config_acpi_legacy_irqs(void)
 #endif
 
 	/*
-	 * Locate the IOAPIC that manages the ISA IRQs (0-15).
-	 */
-	ioapic = mp_find_ioapic(0);
-	if (ioapic < 0)
-		return;
-	dstapic = mp_ioapics[ioapic].apicid;
-
-	/*
 	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overridden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int ioapic, pin;
+		unsigned int dstapic;
 		int idx;
+		u32 gsi;
+
+		/* Locate the gsi that irq i maps to. */
+		if (acpi_isa_irq_to_gsi(i, &gsi))
+			continue;
+
+		/*
+		 * Locate the IOAPIC that manages the ISA IRQ.
+		 */
+		ioapic = mp_find_ioapic(gsi);
+		if (ioapic < 0)
+			continue;
+		pin = mp_find_ioapic_pin(ioapic, gsi);
+		dstapic = mp_ioapics[ioapic].apicid;
 
 		for (idx = 0; idx < mp_irq_entries; idx++) {
 			struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1005,7 +1011,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 				break;
 
 			/* Do we already have a mapping for this IOAPIC pin */
-			if (irq->dstapic == dstapic && irq->dstirq == i)
+			if (irq->dstapic == dstapic && irq->dstirq == pin)
 				break;
 		}
 
@@ -1020,7 +1026,7 @@ void __init mp_config_acpi_legacy_irqs(void)
 		mp_irq.dstapic = dstapic;
 		mp_irq.irqtype = mp_INT;
 		mp_irq.srcbusirq = i; /* Identity mapped */
-		mp_irq.dstirq = i;
+		mp_irq.dstirq = pin;
 
 		save_mp_irq(&mp_irq);
 	}

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
  2010-03-30  8:07             ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
@ 2010-05-05  2:08               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:08 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  9638fa521e42c9281c874c6b5a382b1ced4ee496
Gitweb:     http://git.kernel.org/tip/9638fa521e42c9281c874c6b5a382b1ced4ee496
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:07 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:44 -0700

x86, ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h

Multiple declarations of the same function in different headers
is a pain to maintain.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-6-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/mpspec.h |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..29994f0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -106,10 +106,6 @@ struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
 extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
 #else /* !CONFIG_ACPI: */
 static inline int acpi_probe_gsi(void)
 {

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Fix io_apic_redir_entries to return the number of entries.
  2010-03-30  8:07             ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
@ 2010-05-05  2:08               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:08 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  4b6b19a1c7302477653d799a53d48063dd53d555
Gitweb:     http://git.kernel.org/tip/4b6b19a1c7302477653d799a53d48063dd53d555
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:08 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:48 -0700

x86, ioapic: Fix io_apic_redir_entries to return the number of entries.

io_apic_redir_entries has a huge conceptual bug.  It returns the maximum
redirection entry not the number of redirection entries.  Which simply
does not match what the name of the function.  This just caught me
and it caught  Feng Tang, and  Len Brown when they wrote sfi_parse_ioapic.

Modify io_apic_redir_entries to actually return the number of redirection
entries, and fix the callers so that they properly handle receiving the
number of the number of redirection table entries, instead of the
number of redirection table entries less one.

While the usage in sfi.c does not show up in this patch it is fixed
by virtue of the fact that io_apic_redir_entries now has the semantics
sfi_parse_ioapic most reasonably expects.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-7-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/apic/io_apic.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 73ec928..0a053e6 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3855,7 +3855,11 @@ int __init io_apic_get_redir_entries (int ioapic)
 	reg_01.raw = io_apic_read(ioapic, 1);
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
-	return reg_01.bits.entries;
+	/* The register returns the maximum index redir index
+	 * supported, which is one less than the total number of redir
+	 * entries.
+	 */
+	return reg_01.bits.entries + 1;
 }
 
 void __init probe_nr_irqs_gsi(void)
@@ -3871,7 +3875,7 @@ void __init probe_nr_irqs_gsi(void)
 
 		nr = 0;
 		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx) + 1;
+			nr += io_apic_get_redir_entries(idx);
 
 		if (nr > nr_irqs_gsi)
 			nr_irqs_gsi = nr;
@@ -4306,7 +4310,7 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 */
 	mp_gsi_routing[idx].gsi_base = gsi_base;
 	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx);
+	    io_apic_get_redir_entries(idx) - 1;
 
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Fix the types of gsi values
  2010-03-30  8:07             ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
@ 2010-05-05  2:08               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:08 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  eddb0c55a14074d6bac8c2ef169aefd7e2c6f139
Gitweb:     http://git.kernel.org/tip/eddb0c55a14074d6bac8c2ef169aefd7e2c6f139
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:09 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:52 -0700

x86, ioapic: Fix the types of gsi values

This patches fixes the types of gsi_base and gsi_end values in
struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic
and mp_find_ioapic_pin

A gsi is cannonically a u32, not an int.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-8-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/io_apic.h |   10 +++++-----
 arch/x86/kernel/apic/io_apic.c |    4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..feeaf0d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
 extern void setup_ioapic_ids_from_mpc(void);
 
 struct mp_ioapic_gsi{
-	int gsi_base;
-	int gsi_end;
+	u32 gsi_base;
+	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -197,7 +197,7 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0a053e6..9ab9762 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4247,7 +4247,7 @@ void __init ioapic_insert_resources(void)
 	}
 }
 
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
 {
 	int i = 0;
 
@@ -4262,7 +4262,7 @@ int mp_find_ioapic(int gsi)
 	return -1;
 }
 
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
 	if (WARN_ON(ioapic == -1))
 		return -1;

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Teach mp_register_ioapic to compute a global gsi_end
  2010-03-30  8:07             ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
@ 2010-05-05  2:09               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:09 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  5777372af5c929b8f3c706ed7b295b7279537c88
Gitweb:     http://git.kernel.org/tip/5777372af5c929b8f3c706ed7b295b7279537c88
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:10 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:56 -0700

x86, ioapic: Teach mp_register_ioapic to compute a global gsi_end

Add the global variable gsi_end and teach mp_register_ioapic
to keep it uptodate as we add more ioapics into the system.

ioapics can only be added early in boot so the code that
runs later can treat gsi_end as a constant.

Remove the have hacks in sfi.c to second guess mp_register_ioapic
by keeping t's own running total of how many gsi's have been seen,
and instead use the gsi_end.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-9-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/io_apic.h |    1 +
 arch/x86/kernel/apic/io_apic.c |    6 ++++++
 arch/x86/kernel/sfi.c          |    4 +---
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index feeaf0d..37b0f2b 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,7 @@ struct mp_ioapic_gsi{
 	u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
+extern u32 gsi_end;
 int mp_find_ioapic(u32 gsi);
 int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 9ab9762..f807255 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -89,6 +89,9 @@ int nr_ioapics;
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
 
+/* The last gsi number used */
+u32 gsi_end;
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
@@ -4312,6 +4315,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	mp_gsi_routing[idx].gsi_end = gsi_base +
 	    io_apic_get_redir_entries(idx) - 1;
 
+	if (mp_gsi_routing[idx].gsi_end > gsi_end)
+		gsi_end = mp_gsi_routing[idx].gsi_end;
+
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
 	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index 34e0993..7ded578 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 	pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
 	for (i = 0; i < num; i++) {
-		mp_register_ioapic(i, pentry->phys_addr, gsi_base);
-		gsi_base += io_apic_get_redir_entries(i);
+		mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
 		pentry++;
 	}
 

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: In mpparse use mp_register_ioapic
  2010-03-30  8:07             ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
@ 2010-05-05  2:09               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:09 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  cf7500c0ea133d66f8449d86392d83f840102632
Gitweb:     http://git.kernel.org/tip/cf7500c0ea133d66f8449d86392d83f840102632
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:11 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:34:59 -0700

x86, ioapic: In mpparse use mp_register_ioapic

Long ago MP_ioapic_info was the primary way of setting up our
ioapic data structures and mp_register_ioapic was a compatibility
shim for acpi code.  Now the situation is reversed and
and mp_register_ioapic is the primary way of setting up our
ioapic data structures.

Keep the setting up of ioapic data structures uniform by
having mp_register_ioapic call mp_register_ioapic.

This changes a few fields:

- type: is now hardset to MP_IOAPIC but type had to
  bey MP_IOAPIC or MP_ioapic_info would not have been called.

- flags: is now hard coded to MPC_APIC_USABLE.
  We require flags to contain at least MPC_APIC_USEBLE in
  MP_ioapic_info and we don't ever examine flags so dropping
  a few flags that might possibly exist that we have never
  used is harmless.

- apicaddr: Unchanged

- apicver: Read from the ioapic instead of using the cached
  hardware value in the MP table.  The real hardware value
  will be more accurate.

- apicid: Now verified to be unique and changed if it is not.
  If the BIOS got this right this is a noop.  If the BIOS did
  not fixing things appears to be the better solution.

This adds gsi_base and gsi_end values to our ioapics defined with
the mpatable, which will make our lives simpler later since
we can always assume gsi_base and gsi_end are valid.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-10-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/mpparse.c |   25 +------------------------
 1 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index e81030f..5ae5d24 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
-static int bad_ioapic(unsigned long address)
-{
-	if (nr_ioapics >= MAX_IO_APICS) {
-		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-		       "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-	}
-	if (!address) {
-		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-		       " found in table, skipping!\n");
-		return 1;
-	}
-	return 0;
-}
-
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
 	if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
 	printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
 	       m->apicid, m->apicver, m->apicaddr);
 
-	if (bad_ioapic(m->apicaddr))
-		return;
-
-	mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
-	mp_ioapics[nr_ioapics].apicid = m->apicid;
-	mp_ioapics[nr_ioapics].type = m->type;
-	mp_ioapics[nr_ioapics].apicver = m->apicver;
-	mp_ioapics[nr_ioapics].flags = m->flags;
-	nr_ioapics++;
+	mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
 }
 
 static void print_MP_intsrc_info(struct mpc_intsrc *m)

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
  2010-03-30  8:07             ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
@ 2010-05-05  2:09               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:09 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  7716a5c4ff5f1f3dc5e9edcab125cbf7fceef0af
Gitweb:     http://git.kernel.org/tip/7716a5c4ff5f1f3dc5e9edcab125cbf7fceef0af
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:12 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:35:03 -0700

x86, ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.

Now that all ioapic registration happens in mp_register_ioapic we can
move the calculation of nr_ioapic_registers there from enable_IO_APIC.
The number of ioapic registers is already calucated in mp_register_ioapic
so all that really needs to be done is to save the caluclated value
in nr_ioapic_registers.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-11-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/apic/io_apic.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f807255..dae9240 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1953,20 +1953,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 void __init enable_IO_APIC(void)
 {
-	union IO_APIC_reg_01 reg_01;
 	int i8259_apic, i8259_pin;
 	int apic;
-	unsigned long flags;
-
-	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		raw_spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(apic, 1);
-		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-	}
 
 	if (!legacy_pic->nr_legacy_irqs)
 		return;
@@ -4293,6 +4281,7 @@ static int bad_ioapic(unsigned long address)
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
 	int idx = 0;
+	int entries;
 
 	if (bad_ioapic(address))
 		return;
@@ -4311,9 +4300,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
+	entries = io_apic_get_redir_entries(idx);
 	mp_gsi_routing[idx].gsi_base = gsi_base;
-	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx) - 1;
+	mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	nr_ioapic_registers[idx] = entries;
 
 	if (mp_gsi_routing[idx].gsi_end > gsi_end)
 		gsi_end = mp_gsi_routing[idx].gsi_end;

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Optimize pin_2_irq
  2010-03-30  8:07             ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
@ 2010-05-05  2:09               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:09 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  d464207c4fdd70c2a0febd4f9c58206fa915bb36
Gitweb:     http://git.kernel.org/tip/d464207c4fdd70c2a0febd4f9c58206fa915bb36
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:13 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:35:08 -0700

x86, ioapic: Optimize pin_2_irq

Now that all ioapics have valid gsi_base values use this to
accellerate pin_2_irq.  In the case of acpi this also ensures
that pin_2_irq will compute the same irq value for an ioapic
pin as acpi will.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-12-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/apic/io_apic.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index dae9240..0d35f46 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1019,7 +1019,7 @@ static inline int irq_trigger(int idx)
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-	int irq, i;
+	int irq;
 	int bus = mp_irqs[idx].srcbus;
 
 	/*
@@ -1031,18 +1031,13 @@ static int pin_2_irq(int idx, int apic, int pin)
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
+		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
 		/*
                  * For MPS mode, so far only needed by ES7000 platform
                  */
 		if (ioapic_renumber_irq)
-			irq = ioapic_renumber_irq(apic, irq);
+			gsi = ioapic_renumber_irq(apic, gsi);
+		irq = gsi;
 	}
 
 #ifdef CONFIG_X86_32

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, ioapic: Simplify probe_nr_irqs_gsi.
  2010-03-30  8:07             ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-05-05  2:10               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:10 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  4afc51a835d3aeba11c35090f524e05c84586d27
Gitweb:     http://git.kernel.org/tip/4afc51a835d3aeba11c35090f524e05c84586d27
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:14 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:35:11 -0700

x86, ioapic: Simplify probe_nr_irqs_gsi.

Use the global gsi_end value now that all ioapics have
valid gsi numbers instead of a combination of acpi_probe_gsi
and walking all of the ioapics and couting their number of
entries by hand if acpi_probe_gsi gave us an answer we did
not like.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-13-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/mpspec.h  |    6 ------
 arch/x86/kernel/acpi/boot.c    |   23 -----------------------
 arch/x86/kernel/apic/io_apic.c |   17 +++--------------
 3 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 29994f0..c82868e 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
-extern int acpi_probe_gsi(void);
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
-	return 0;
-}
 #endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 3ee92f2..07a63ce 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -876,29 +876,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-int __init acpi_probe_gsi(void)
-{
-	int idx;
-	int gsi;
-	int max_gsi = 0;
-
-	if (acpi_disabled)
-		return 0;
-
-	if (!acpi_ioapic)
-		return 0;
-
-	max_gsi = 0;
-	for (idx = 0; idx < nr_ioapics; idx++) {
-		gsi = mp_gsi_routing[idx].gsi_end;
-
-		if (gsi > max_gsi)
-			max_gsi = gsi;
-	}
-
-	return max_gsi + 1;
-}
-
 static void assign_to_mp_irq(struct mpc_intsrc *m,
 				    struct mpc_intsrc *mp_irq)
 {
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0d35f46..9f3f6ca 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3850,22 +3850,11 @@ int __init io_apic_get_redir_entries (int ioapic)
 
 void __init probe_nr_irqs_gsi(void)
 {
-	int nr = 0;
+	int nr;
 
-	nr = acpi_probe_gsi();
-	if (nr > nr_irqs_gsi) {
+	nr = gsi_end + 1;
+	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
-	} else {
-		/* for acpi=off or acpi is not compiled in */
-		int idx;
-
-		nr = 0;
-		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx);
-
-		if (nr > nr_irqs_gsi)
-			nr_irqs_gsi = nr;
-	}
 
 	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-03-30  8:07             ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-05-05  2:10               ` tip-bot for Eric W. Biederman
  2010-05-05  7:49                 ` Yinghai
  2010-05-05  8:56                 ` Ingo Molnar
  0 siblings, 2 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:10 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  988856ee1623bd37e384105f7bb2b7fe44c009f6
Gitweb:     http://git.kernel.org/tip/988856ee1623bd37e384105f7bb2b7fe44c009f6
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:15 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:35:17 -0700

x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.

ACPI irq source overrides are allowed for the 16 isa irqs and are
allowed to map any gsi to any isa irq.  A few motherboards have been
seen to take advantage of this and put the isa irqs on the 2nd or
3rd ioapic.  This causes some problems, most notably the fact
that we can not use any gsi < 16.

To correct this move the gsis that are not isa irqs and have
a gsi number < 16 into the linux irq space just past gsi_end.
This is what the es7000 platform is doing today.  Moving only the
low 16 gsis above the rest of the gsi's only penalizes weird
platforms, leaving sane acpi implementations with a 1-1 mapping
of gsis and irqs.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-14-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/kernel/acpi/boot.c    |   57 +++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/apic/io_apic.c |    8 ++++-
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 07a63ce..325fbba 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -94,6 +94,53 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
 
 /*
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+	unsigned int irq = gsi + NR_IRQS_LEGACY;
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+		if (isa_irq_to_gsi[i] == gsi) {
+			return i;
+		}
+	}
+
+	/* Provide an identity mapping of gsi == irq
+	 * except on truly weird platforms that have
+	 * non isa irqs in the first 16 gsis.
+	 */
+	if (gsi >= NR_IRQS_LEGACY)
+		irq = gsi;
+	else
+		irq = gsi_end + 1 + gsi;
+
+	return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+	unsigned int gsi;
+
+	if (irq < NR_IRQS_LEGACY)
+		gsi = isa_irq_to_gsi[irq];
+	else if (irq <= gsi_end)
+		gsi = irq;
+	else if (irq <= (gsi_end + NR_IRQS_LEGACY))
+		gsi = irq - gsi_end;
+	else
+		gsi = 0xffffffff;
+
+	return gsi;
+}
+
+/*
  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
  * provides a single page, and it is possible that the page is not
@@ -449,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-	*irq = gsi;
+	*irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -463,7 +510,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 {
 	if (isa_irq >= 16)
 		return -1;
-	*gsi = isa_irq;
+	*gsi = irq_to_gsi(isa_irq);
 	return 0;
 }
 
@@ -491,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
 	}
 #endif
-	irq = plat_gsi;
+	irq = gsi_to_irq(plat_gsi);
 
 	return irq;
 }
@@ -933,6 +980,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 	mp_irq.dstirq = pin;	/* INTIN# */
 
 	save_mp_irq(&mp_irq);
+
+	isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
@@ -1086,7 +1135,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	io_apic_set_pci_routing(dev, gsi, &irq_attr);
+	io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 
 	return gsi;
 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 9f3f6ca..594827c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1037,7 +1037,11 @@ static int pin_2_irq(int idx, int apic, int pin)
                  */
 		if (ioapic_renumber_irq)
 			gsi = ioapic_renumber_irq(apic, gsi);
-		irq = gsi;
+
+		if (gsi >= NR_IRQS_LEGACY)
+			irq = gsi;
+		else
+			irq = gsi_end + 1 + gsi;
 	}
 
 #ifdef CONFIG_X86_32
@@ -3852,7 +3856,7 @@ void __init probe_nr_irqs_gsi(void)
 {
 	int nr;
 
-	nr = gsi_end + 1;
+	nr = gsi_end + 1 + NR_IRQS_LEGACY;
 	if (nr > nr_irqs_gsi)
 		nr_irqs_gsi = nr;
 

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, irq: Kill io_apic_renumber_irq
  2010-03-30  8:07             ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
@ 2010-05-05  2:10               ` tip-bot for Eric W. Biederman
  0 siblings, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-05  2:10 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, tglx, ebiederm

Commit-ID:  7b20bd5fb902088579af4e70f7f802b93181a628
Gitweb:     http://git.kernel.org/tip/7b20bd5fb902088579af4e70f7f802b93181a628
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Tue, 30 Mar 2010 01:07:16 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 4 May 2010 13:35:20 -0700

x86, irq: Kill io_apic_renumber_irq

Now that the generic irq layer is performing the exact same remapping as
io_apic_renumber_irq we can kill this weird  es7000 specific function.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <1269936436-7039-15-git-send-email-ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/io_apic.h   |    1 -
 arch/x86/kernel/acpi/boot.c      |    5 -----
 arch/x86/kernel/apic/es7000_32.c |   19 -------------------
 arch/x86/kernel/apic/io_apic.c   |    6 ------
 4 files changed, 0 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 37b0f2b..9da192a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
 void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
 
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 325fbba..9a5ed58 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1117,11 +1117,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
 	ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
-#ifdef CONFIG_X86_32
-	if (ioapic_renumber_irq)
-		gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 		       "%d-%d\n", mp_ioapics[ioapic].apicid,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 03ba1b8..425e53a 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -131,24 +131,6 @@ int					es7000_plat;
 
 static unsigned int			base;
 
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-	if (es7000_plat == ES7000_ZORRO)
-		return gsi;
-
-	if (!base) {
-		int i;
-		for (i = 0; i < nr_ioapics; i++)
-			base += nr_ioapic_registers[i];
-	}
-
-	if (!ioapic && (gsi < 16))
-		gsi += base;
-
-	return gsi;
-}
-
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
 	unsigned long vect = 0, psaival = 0;
@@ -190,7 +172,6 @@ static void setup_unisys(void)
 		es7000_plat = ES7000_ZORRO;
 	else
 		es7000_plat = ES7000_CLASSIC;
-	ioapic_renumber_irq = es7000_rename_gsi;
 }
 
 /*
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 594827c..d174d88 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1016,7 +1016,6 @@ static inline int irq_trigger(int idx)
 	return MPBIOS_trigger(idx);
 }
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq;
@@ -1032,11 +1031,6 @@ static int pin_2_irq(int idx, int apic, int pin)
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
 		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
-		/*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-		if (ioapic_renumber_irq)
-			gsi = ioapic_renumber_irq(apic, gsi);
 
 		if (gsi >= NR_IRQS_LEGACY)
 			irq = gsi;

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
@ 2010-05-05  7:49                 ` Yinghai
  2010-05-05  8:53                   ` [PATCH] x86 acpi/irq: Fix harmless typo Eric W. Biederman
  2010-05-05  9:32                   ` [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
  2010-05-05  8:56                 ` Ingo Molnar
  1 sibling, 2 replies; 115+ messages in thread
From: Yinghai @ 2010-05-05  7:49 UTC (permalink / raw)
  To: mingo, hpa, linux-kernel, tglx, ebiederm

On 05/04/2010 07:10 PM, tip-bot for Eric W. Biederman wrote:
> Commit-ID:  988856ee1623bd37e384105f7bb2b7fe44c009f6
> Gitweb:     http://git.kernel.org/tip/988856ee1623bd37e384105f7bb2b7fe44c009f6
> Author:     Eric W. Biederman <ebiederm@xmission.com>
> AuthorDate: Tue, 30 Mar 2010 01:07:15 -0700
> Committer:  H. Peter Anvin <hpa@zytor.com>
> CommitDate: Tue, 4 May 2010 13:35:17 -0700
> 
> x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
> 
> ACPI irq source overrides are allowed for the 16 isa irqs and are
> allowed to map any gsi to any isa irq.  A few motherboards have been
> seen to take advantage of this and put the isa irqs on the 2nd or
> 3rd ioapic.  This causes some problems, most notably the fact
> that we can not use any gsi < 16.
> 
> To correct this move the gsis that are not isa irqs and have
> a gsi number < 16 into the linux irq space just past gsi_end.
> This is what the es7000 platform is doing today.  Moving only the
> low 16 gsis above the rest of the gsi's only penalizes weird
> platforms, leaving sane acpi implementations with a 1-1 mapping
> of gsis and irqs.
> 
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> LKML-Reference: <1269936436-7039-14-git-send-email-ebiederm@xmission.com>
> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
> ---
>  arch/x86/kernel/acpi/boot.c    |   57 +++++++++++++++++++++++++++++++++++++---
>  arch/x86/kernel/apic/io_apic.c |    8 ++++-
>  2 files changed, 59 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 07a63ce..325fbba 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -94,6 +94,53 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
>  
>  
>  /*
> + * ISA irqs by default are the first 16 gsis but can be
> + * any gsi as specified by an interrupt source override.
> + */
> +static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
> +	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
> +};
> +
> +static unsigned int gsi_to_irq(unsigned int gsi)
> +{
> +	unsigned int irq = gsi + NR_IRQS_LEGACY;
> +	unsigned int i;
> +
> +	for (i = 0; i < NR_IRQS_LEGACY; i++) {
> +		if (isa_irq_to_gsi[i] == gsi) {
> +			return i;
> +		}
> +	}
> +
> +	/* Provide an identity mapping of gsi == irq
> +	 * except on truly weird platforms that have
> +	 * non isa irqs in the first 16 gsis.
> +	 */
> +	if (gsi >= NR_IRQS_LEGACY)
> +		irq = gsi;
> +	else
> +		irq = gsi_end + 1 + gsi;
> +
> +	return irq;
> +}
> +
> +static u32 irq_to_gsi(int irq)
> +{
> +	unsigned int gsi;
> +
> +	if (irq < NR_IRQS_LEGACY)
> +		gsi = isa_irq_to_gsi[irq];
> +	else if (irq <= gsi_end)
> +		gsi = irq;
> +	else if (irq <= (gsi_end + NR_IRQS_LEGACY))
> +		gsi = irq - gsi_end;

here should be
	gsi = irq - gsi_end - 1;

> +	else
> +		gsi = 0xffffffff;
> +
> +	return gsi;
> +}
> +
> +/*
>   * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
>   * to map the target physical address. The problem is that set_fixmap()
>   * provides a single page, and it is possible that the page is not
> @@ -449,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
>  
>  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>  {
> -	*irq = gsi;
> +	*irq = gsi_to_irq(gsi);
>  
>  #ifdef CONFIG_X86_IO_APIC
>  	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
> @@ -463,7 +510,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
>  {
>  	if (isa_irq >= 16)
>  		return -1;
> -	*gsi = isa_irq;
> +	*gsi = irq_to_gsi(isa_irq);
>  	return 0;
>  }
>  
> @@ -491,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>  		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
>  	}
>  #endif
> -	irq = plat_gsi;
> +	irq = gsi_to_irq(plat_gsi);
>  
>  	return irq;
>  }
> @@ -933,6 +980,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
>  	mp_irq.dstirq = pin;	/* INTIN# */
>  
>  	save_mp_irq(&mp_irq);
> +
> +	isa_irq_to_gsi[bus_irq] = gsi;
>  }
>  
>  void __init mp_config_acpi_legacy_irqs(void)
> @@ -1086,7 +1135,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
>  	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
>  			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
>  			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
> -	io_apic_set_pci_routing(dev, gsi, &irq_attr);
> +	io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
>  
>  	return gsi;
>  }
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index 9f3f6ca..594827c 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -1037,7 +1037,11 @@ static int pin_2_irq(int idx, int apic, int pin)
>                   */
>  		if (ioapic_renumber_irq)
>  			gsi = ioapic_renumber_irq(apic, gsi);
> -		irq = gsi;
> +
> +		if (gsi >= NR_IRQS_LEGACY)
> +			irq = gsi;
> +		else
> +			irq = gsi_end + 1 + gsi;
>  	}
>  
>  #ifdef CONFIG_X86_32
> @@ -3852,7 +3856,7 @@ void __init probe_nr_irqs_gsi(void)
>  {
>  	int nr;
>  
> -	nr = gsi_end + 1;
> +	nr = gsi_end + 1 + NR_IRQS_LEGACY;
>  	if (nr > nr_irqs_gsi)
>  		nr_irqs_gsi = nr;

can you use legacy_irq->nr_legacy_irqs instead of NR_IRQS_LEGACY ?

YH

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH] x86 acpi/irq: Fix harmless typo.
  2010-05-05  7:49                 ` Yinghai
@ 2010-05-05  8:53                   ` Eric W. Biederman
  2010-05-05  8:58                     ` Ingo Molnar
  2010-05-05  9:32                   ` [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
  1 sibling, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-05-05  8:53 UTC (permalink / raw)
  To: Yinghai; +Cc: mingo, hpa, linux-kernel, tglx


YH noticed that the function irq_to_gsi has an off by one error
when translating high irq numbers to gsis.  Today this bug is harmless
because all of the callers restrict their input to the first 16 irqs
so this bug does not matter, but we should fix it to avoid confusion
and later.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/kernel/acpi/boot.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c9a5d3f..78222c8 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -132,7 +132,7 @@ static u32 irq_to_gsi(int irq)
 	else if (irq <= gsi_end)
 		gsi = irq;
 	else if (irq <= (gsi_end + NR_IRQS_LEGACY))
-		gsi = irq - gsi_end;
+		gsi = irq - (gsi_end + 1);
 	else
 		gsi = 0xffffffff;
 
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  2010-05-05  7:49                 ` Yinghai
@ 2010-05-05  8:56                 ` Ingo Molnar
  2010-05-05  9:36                   ` Eric Biederman
  1 sibling, 1 reply; 115+ messages in thread
From: Ingo Molnar @ 2010-05-05  8:56 UTC (permalink / raw)
  To: mingo, hpa, linux-kernel, tglx, ebiederm, Yinghai Lu; +Cc: linux-tip-commits


* tip-bot for Eric W. Biederman <ebiederm@xmission.com> wrote:

> Commit-ID:  988856ee1623bd37e384105f7bb2b7fe44c009f6
> Gitweb:     http://git.kernel.org/tip/988856ee1623bd37e384105f7bb2b7fe44c009f6
> Author:     Eric W. Biederman <ebiederm@xmission.com>
> AuthorDate: Tue, 30 Mar 2010 01:07:15 -0700
> Committer:  H. Peter Anvin <hpa@zytor.com>
> CommitDate: Tue, 4 May 2010 13:35:17 -0700
> 
> x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.

FYI, the patchset causes this build error with certain configs:

arch/x86/kernel/acpi/boot.c:122: error: 'gsi_end' undeclared (first use in this function)
arch/x86/kernel/acpi/boot.c:122: error: (Each undeclared identifier is reported only once
arch/x86/kernel/acpi/boot.c:122: error: for each function it appears in.)
arch/x86/kernel/acpi/boot.c:133: error: 'gsi_end' undeclared (first use in this function)

	Ingo

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [PATCH] x86 acpi/irq: Fix harmless typo.
  2010-05-05  8:53                   ` [PATCH] x86 acpi/irq: Fix harmless typo Eric W. Biederman
@ 2010-05-05  8:58                     ` Ingo Molnar
  0 siblings, 0 replies; 115+ messages in thread
From: Ingo Molnar @ 2010-05-05  8:58 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Yinghai, mingo, hpa, linux-kernel, tglx


* Eric W. Biederman <ebiederm@xmission.com> wrote:

> YH noticed that the function irq_to_gsi has an off by one error
> when translating high irq numbers to gsis.  Today this bug is harmless
> because all of the callers restrict their input to the first 16 irqs
> so this bug does not matter, but we should fix it to avoid confusion
> and later.
> 
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

Please use the Reported-by tag.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-05-05  7:49                 ` Yinghai
  2010-05-05  8:53                   ` [PATCH] x86 acpi/irq: Fix harmless typo Eric W. Biederman
@ 2010-05-05  9:32                   ` Eric W. Biederman
  2010-06-07 21:05                     ` H. Peter Anvin
  1 sibling, 1 reply; 115+ messages in thread
From: Eric W. Biederman @ 2010-05-05  9:32 UTC (permalink / raw)
  To: Yinghai; +Cc: mingo, hpa, linux-kernel, tglx, Feng Tang, Len Brown, Jacob Pan

Yinghai <yinghai.lu@oracle.com> writes:

>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index 9f3f6ca..594827c 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -1037,7 +1037,11 @@ static int pin_2_irq(int idx, int apic, int pin)
>>                   */
>>  		if (ioapic_renumber_irq)
>>  			gsi = ioapic_renumber_irq(apic, gsi);
>> -		irq = gsi;
>> +
>> +		if (gsi >= NR_IRQS_LEGACY)
>> +			irq = gsi;
>> +		else
>> +			irq = gsi_end + 1 + gsi;
>>  	}
>>  
>>  #ifdef CONFIG_X86_32
>> @@ -3852,7 +3856,7 @@ void __init probe_nr_irqs_gsi(void)
>>  {
>>  	int nr;
>>  
>> -	nr = gsi_end + 1;
>> +	nr = gsi_end + 1 + NR_IRQS_LEGACY;
>>  	if (nr > nr_irqs_gsi)
>>  		nr_irqs_gsi = nr;
>
> can you use legacy_irq->nr_legacy_irqs instead of NR_IRQS_LEGACY ?

No. legacy_irq->nr_legacy_irqs is just for dealing with hardware that
does not have i8259 pics.

Here I am reserving 16 irqs above the gsi range in case we get a
weird gsi to isa irq mapping.

Currently the sfi spec doesn't mention anything explicitly.  I
took a quick read through it and sfi and I presume Moorestown
is talking about non pci irqs.  So I would not be surprised
if we didn't have isa device drivers running on platforms
without i8259s.

Currently the code had a small bug dealing with multiple ioapics and
the spec really is incomplete about how you map irqs from pci devices
to interrupts.  So it looks like SFI and Moorestown are more a lab
experiment than real hardware at the moment.  So I expect when
it gets completely fleshed out we will have to jump through a
similar set of hoops as we do with acpi to ensure the first 16
irqs are not used for anything except isa irqs.

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not  identity mapped to gsi's.
  2010-05-05  8:56                 ` Ingo Molnar
@ 2010-05-05  9:36                   ` Eric Biederman
  2010-05-05 10:05                     ` Ingo Molnar
  0 siblings, 1 reply; 115+ messages in thread
From: Eric Biederman @ 2010-05-05  9:36 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: mingo, hpa, linux-kernel, tglx, ebiederm, Yinghai Lu, linux-tip-commits

On Wed, May 5, 2010 at 1:56 AM, Ingo Molnar <mingo@elte.hu> wrote:
>
> * tip-bot for Eric W. Biederman <ebiederm@xmission.com> wrote:
>
>> Commit-ID:  988856ee1623bd37e384105f7bb2b7fe44c009f6
>> Gitweb:     http://git.kernel.org/tip/988856ee1623bd37e384105f7bb2b7fe44c009f6
>> Author:     Eric W. Biederman <ebiederm@xmission.com>
>> AuthorDate: Tue, 30 Mar 2010 01:07:15 -0700
>> Committer:  H. Peter Anvin <hpa@zytor.com>
>> CommitDate: Tue, 4 May 2010 13:35:17 -0700
>>
>> x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
>
> FYI, the patchset causes this build error with certain configs:
>
> arch/x86/kernel/acpi/boot.c:122: error: 'gsi_end' undeclared (first use in this function)
> arch/x86/kernel/acpi/boot.c:122: error: (Each undeclared identifier is reported only once
> arch/x86/kernel/acpi/boot.c:122: error: for each function it appears in.)
> arch/x86/kernel/acpi/boot.c:133: error: 'gsi_end' undeclared (first use in this function)

What configuration supports acpi and doesn't support ioapics?

Eric

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-05-05  9:36                   ` Eric Biederman
@ 2010-05-05 10:05                     ` Ingo Molnar
  2010-05-05 20:22                       ` [PATCH] x86 acpi/irq: Define gsi_end when X86_IO_APIC is undefined Eric W. Biederman
  0 siblings, 1 reply; 115+ messages in thread
From: Ingo Molnar @ 2010-05-05 10:05 UTC (permalink / raw)
  To: Eric Biederman
  Cc: mingo, hpa, linux-kernel, tglx, ebiederm, Yinghai Lu, linux-tip-commits


* Eric Biederman <ebiederm@aristanetworks.com> wrote:

> On Wed, May 5, 2010 at 1:56 AM, Ingo Molnar <mingo@elte.hu> wrote:
> >
> > * tip-bot for Eric W. Biederman <ebiederm@xmission.com> wrote:
> >
> >> Commit-ID: ?988856ee1623bd37e384105f7bb2b7fe44c009f6
> >> Gitweb: ? ? http://git.kernel.org/tip/988856ee1623bd37e384105f7bb2b7fe44c009f6
> >> Author: ? ? Eric W. Biederman <ebiederm@xmission.com>
> >> AuthorDate: Tue, 30 Mar 2010 01:07:15 -0700
> >> Committer: ?H. Peter Anvin <hpa@zytor.com>
> >> CommitDate: Tue, 4 May 2010 13:35:17 -0700
> >>
> >> x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
> >
> > FYI, the patchset causes this build error with certain configs:
> >
> > arch/x86/kernel/acpi/boot.c:122: error: 'gsi_end' undeclared (first use in this function)
> > arch/x86/kernel/acpi/boot.c:122: error: (Each undeclared identifier is reported only once
> > arch/x86/kernel/acpi/boot.c:122: error: for each function it appears in.)
> > arch/x86/kernel/acpi/boot.c:133: error: 'gsi_end' undeclared (first use in this function)
> 
> What configuration supports acpi and doesn't support ioapics?

an UP kernel with ACPI turned on for example.

	Ingo

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [PATCH] x86 acpi/irq:  Define gsi_end when X86_IO_APIC is undefined
  2010-05-05 10:05                     ` Ingo Molnar
@ 2010-05-05 20:22                       ` Eric W. Biederman
  2010-05-06  6:18                         ` Ingo Molnar
  2010-05-06 10:07                         ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  0 siblings, 2 replies; 115+ messages in thread
From: Eric W. Biederman @ 2010-05-05 20:22 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: mingo, hpa, linux-kernel, tglx, Yinghai Lu, linux-tip-commits


Oops.  My recent changes introducing a global gsi_end variable failed
to take into account the case of using acpi on a system not built to
support IO_APICs, causing the build to fail.  Define gsi_end to 15 when
CONFIG_X86_IO_APIC is not set to avoid compile errors.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/x86/include/asm/io_apic.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 9da192a..63cb409 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -197,6 +197,7 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
+#define gsi_end (NR_IRQS_LEGACY - 1)
 static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [PATCH] x86 acpi/irq:  Define gsi_end when X86_IO_APIC is undefined
  2010-05-05 20:22                       ` [PATCH] x86 acpi/irq: Define gsi_end when X86_IO_APIC is undefined Eric W. Biederman
@ 2010-05-06  6:18                         ` Ingo Molnar
  2010-05-06 10:07                         ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
  1 sibling, 0 replies; 115+ messages in thread
From: Ingo Molnar @ 2010-05-06  6:18 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: mingo, hpa, linux-kernel, tglx, Yinghai Lu, linux-tip-commits


* Eric W. Biederman <ebiederm@xmission.com> wrote:

> Oops.  My recent changes introducing a global gsi_end variable failed
> to take into account the case of using acpi on a system not built to
> support IO_APICs, causing the build to fail.  Define gsi_end to 15 when
> CONFIG_X86_IO_APIC is not set to avoid compile errors.
> 
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
>  arch/x86/include/asm/io_apic.h |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)

Applied to tip:x86/irq, thanks Eric!

	Ingo

^ permalink raw reply	[flat|nested] 115+ messages in thread

* [tip:x86/irq] x86, acpi/irq: Define gsi_end when X86_IO_APIC is undefined
  2010-05-05 20:22                       ` [PATCH] x86 acpi/irq: Define gsi_end when X86_IO_APIC is undefined Eric W. Biederman
  2010-05-06  6:18                         ` Ingo Molnar
@ 2010-05-06 10:07                         ` tip-bot for Eric W. Biederman
  1 sibling, 0 replies; 115+ messages in thread
From: tip-bot for Eric W. Biederman @ 2010-05-06 10:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, yinghai, tglx, mingo, ebiederm

Commit-ID:  4f47b4c9f0b711bf84adb8c27774ae80d346b628
Gitweb:     http://git.kernel.org/tip/4f47b4c9f0b711bf84adb8c27774ae80d346b628
Author:     Eric W. Biederman <ebiederm@xmission.com>
AuthorDate: Wed, 5 May 2010 13:22:25 -0700
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 6 May 2010 08:17:51 +0200

x86, acpi/irq: Define gsi_end when X86_IO_APIC is undefined

My recent changes introducing a global gsi_end variable
failed to take into account the case of using acpi on a system
not built to support IO_APICs, causing the build to fail.

Define gsi_end to 15 when CONFIG_X86_IO_APIC is not set to avoid
compile errors.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <m1tyqm14la.fsf_-_@fess.ebiederm.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/include/asm/io_apic.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 9da192a..63cb409 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -197,6 +197,7 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
+#define gsi_end (NR_IRQS_LEGACY - 1)
 static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;

^ permalink raw reply related	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-05-05  9:32                   ` [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-06-07 21:05                     ` H. Peter Anvin
  2010-06-08 22:20                       ` Yinghai Lu
  0 siblings, 1 reply; 115+ messages in thread
From: H. Peter Anvin @ 2010-06-07 21:05 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Yinghai, mingo, linux-kernel, tglx, Feng Tang, Len Brown, Jacob Pan

On 05/05/2010 02:32 AM, Eric W. Biederman wrote:
>>
>> can you use legacy_irq->nr_legacy_irqs instead of NR_IRQS_LEGACY ?
> 
> No. legacy_irq->nr_legacy_irqs is just for dealing with hardware that
> does not have i8259 pics.
> 

I don't know if it is "just" for this purpose.  Quite on the contrary.
In fact, the fact that NR_IRQS_LEGACY is showing up at all looks like a
real problem.

> Here I am reserving 16 irqs above the gsi range in case we get a
> weird gsi to isa irq mapping.

But that 16 is exactly because those are the (platform-specific) legacy
IRQs.

> Currently the sfi spec doesn't mention anything explicitly.  I
> took a quick read through it and sfi and I presume Moorestown
> is talking about non pci irqs.  So I would not be surprised
> if we didn't have isa device drivers running on platforms
> without i8259s.

I'm confused about the above.  Where do you see any mention to fixed
(ISA) IRQs in SFI or Moorestown?  Jacob tells me they don't exist.

> Currently the code had a small bug dealing with multiple ioapics and
> the spec really is incomplete about how you map irqs from pci devices
> to interrupts.  So it looks like SFI and Moorestown are more a lab
> experiment than real hardware at the moment.  So I expect when
> it gets completely fleshed out we will have to jump through a
> similar set of hoops as we do with acpi to ensure the first 16
> irqs are not used for anything except isa irqs.

Moorestown hardware certainly exists, although not all the support is
upstream yet.

Either which way, anything which perpetuates NR_IRQS_LEGACY as a
compile-time constant is begging for people to get things wrong, and it
really needs to go away.

	-hpa

^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
  2010-06-07 21:05                     ` H. Peter Anvin
@ 2010-06-08 22:20                       ` Yinghai Lu
  0 siblings, 0 replies; 115+ messages in thread
From: Yinghai Lu @ 2010-06-08 22:20 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Eric W. Biederman, mingo, linux-kernel, tglx, Feng Tang,
	Len Brown, Jacob Pan

On 06/07/2010 02:05 PM, H. Peter Anvin wrote:
> On 05/05/2010 02:32 AM, Eric W. Biederman wrote:
>>>
>>> can you use legacy_irq->nr_legacy_irqs instead of NR_IRQS_LEGACY ?
>>
>> No. legacy_irq->nr_legacy_irqs is just for dealing with hardware that
>> does not have i8259 pics.
>>
> 
> I don't know if it is "just" for this purpose.  Quite on the contrary.
> In fact, the fact that NR_IRQS_LEGACY is showing up at all looks like a
> real problem.
> 
>> Here I am reserving 16 irqs above the gsi range in case we get a
>> weird gsi to isa irq mapping.
> 
> But that 16 is exactly because those are the (platform-specific) legacy
> IRQs.
> 
>> Currently the sfi spec doesn't mention anything explicitly.  I
>> took a quick read through it and sfi and I presume Moorestown
>> is talking about non pci irqs.  So I would not be surprised
>> if we didn't have isa device drivers running on platforms
>> without i8259s.
> 
> I'm confused about the above.  Where do you see any mention to fixed
> (ISA) IRQs in SFI or Moorestown?  Jacob tells me they don't exist.
> 
>> Currently the code had a small bug dealing with multiple ioapics and
>> the spec really is incomplete about how you map irqs from pci devices
>> to interrupts.  So it looks like SFI and Moorestown are more a lab
>> experiment than real hardware at the moment.  So I expect when
>> it gets completely fleshed out we will have to jump through a
>> similar set of hoops as we do with acpi to ensure the first 16
>> irqs are not used for anything except isa irqs.
> 
> Moorestown hardware certainly exists, although not all the support is
> upstream yet.
> 
> Either which way, anything which perpetuates NR_IRQS_LEGACY as a
> compile-time constant is begging for people to get things wrong, and it
> really needs to go away.

yes, it should be replaced legacy_irq->nr_legacy_irs to make Moorestown to have sane irq index.

otherwise gsi_to_irq will mapping all [0, 15] to start from nr_irqs_gsi.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 115+ messages in thread

end of thread, other threads:[~2010-06-08 22:20 UTC | newest]

Thread overview: 115+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-22  1:36 [PATCH 00/10] x86/irq Yinghai Lu
2010-03-22  1:36 ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Yinghai Lu
2010-03-22  1:36   ` Yinghai Lu
2010-03-22  1:36   ` Yinghai Lu
2010-03-22  1:56   ` [PATCH 01/10] irq: move some interrupt arch_* functions into Michael Ellerman
2010-03-22  1:56     ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Michael Ellerman
2010-03-22  1:56     ` Michael Ellerman
2010-03-22  3:32     ` [PATCH 01/10] irq: move some interrupt arch_* functions into Yinghai Lu
2010-03-22  3:32       ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Yinghai Lu
2010-03-22  3:32       ` Yinghai Lu
2010-03-23  7:10       ` Paul Mundt
2010-03-23  7:10         ` Paul Mundt
2010-03-23  7:10         ` Paul Mundt
2010-03-24 13:33         ` [PATCH 01/10] irq: move some interrupt arch_* functions into Ian Campbell
2010-03-24 13:33           ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Ian Campbell
2010-03-24 13:33           ` Ian Campbell
2010-03-22 10:19   ` [PATCH 01/10] irq: move some interrupt arch_* functions into Thomas Gleixner
2010-03-22 10:19     ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Thomas Gleixner
2010-03-22 10:19     ` Thomas Gleixner
2010-03-24 13:32     ` [PATCH 01/10] irq: move some interrupt arch_* functions into Ian Campbell
2010-03-24 13:32       ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Ian Campbell
2010-03-24 13:32       ` Ian Campbell
2010-03-24 17:44       ` [PATCH 01/10] irq: move some interrupt arch_* functions into Thomas Gleixner
2010-03-24 17:44         ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Thomas Gleixner
2010-03-24 17:44         ` Thomas Gleixner
2010-03-24 19:16         ` [PATCH 01/10] irq: move some interrupt arch_* functions into Ian Campbell
2010-03-24 19:16           ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Ian Campbell
2010-03-24 19:16           ` Ian Campbell
2010-03-24 21:25           ` [PATCH 01/10] irq: move some interrupt arch_* functions into Thomas Gleixner
2010-03-24 21:25             ` [PATCH 01/10] irq: move some interrupt arch_* functions into struct irq_chip Thomas Gleixner
2010-03-24 21:25             ` Thomas Gleixner
2010-03-22  1:36 ` [PATCH 02/10] x86: fix out of order of gsi - full Yinghai Lu
2010-03-22 11:14   ` Thomas Gleixner
2010-03-22 19:45     ` Yinghai Lu
2010-03-29 13:40     ` Eric W. Biederman
2010-03-29 17:57       ` H. Peter Anvin
2010-03-29 23:19         ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
2010-03-29 23:20           ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-03-29 23:20           ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
2010-03-29 23:20           ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
2010-03-29 23:20           ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
2010-03-29 23:20           ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
2010-03-29 23:20           ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
2010-03-29 23:20           ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
2010-03-29 23:20           ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
2010-03-29 23:20           ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
2010-03-29 23:20           ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
2010-03-29 23:20           ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
2010-03-29 23:20           ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
2010-03-30  2:16             ` Yinghai Lu
2010-03-30  2:16               ` Yinghai Lu
2010-03-30  4:43               ` Eric W. Biederman
2010-03-30  4:43                 ` Eric W. Biederman
2010-03-30  4:55                 ` Yinghai Lu
2010-03-30  5:41                   ` Eric W. Biederman
2010-03-29 23:20           ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
2010-03-29 23:20           ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
2010-03-30  8:06           ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-03-30  8:07             ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-05-05  2:06               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
2010-05-05  2:07               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
2010-05-05  2:08               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
2010-05-05  2:09               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-05-05  7:49                 ` Yinghai
2010-05-05  8:53                   ` [PATCH] x86 acpi/irq: Fix harmless typo Eric W. Biederman
2010-05-05  8:58                     ` Ingo Molnar
2010-05-05  9:32                   ` [tip:x86/irq] x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
2010-06-07 21:05                     ` H. Peter Anvin
2010-06-08 22:20                       ` Yinghai Lu
2010-05-05  8:56                 ` Ingo Molnar
2010-05-05  9:36                   ` Eric Biederman
2010-05-05 10:05                     ` Ingo Molnar
2010-05-05 20:22                       ` [PATCH] x86 acpi/irq: Define gsi_end when X86_IO_APIC is undefined Eric W. Biederman
2010-05-06  6:18                         ` Ingo Molnar
2010-05-06 10:07                         ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-03-30  8:07             ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
2010-05-05  2:10               ` [tip:x86/irq] x86, " tip-bot for Eric W. Biederman
2010-05-03 23:21             ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-04-01  2:02           ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
2010-04-01  3:31             ` Eric W. Biederman
2010-03-22  1:36 ` [PATCH 03/10] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi Yinghai Lu
2010-03-22  1:36 ` [PATCH 04/10] x86: kill smpboot_hooks.h Yinghai Lu
2010-03-22 13:34   ` Thomas Gleixner
2010-03-22  1:36 ` [PATCH 05/10] x86: use vector_desc instead of vector_irq Yinghai Lu
2010-03-22 13:58   ` Thomas Gleixner
2010-03-22 14:04     ` Eric W. Biederman
2010-03-22 14:16       ` Thomas Gleixner
2010-03-22  1:36 ` [PATCH 06/10] irq: Start the transition of irq_chip methods taking a desc Yinghai Lu
2010-03-22  1:36 ` [PATCH 07/10] x86/irq: use irq_desc *desc with irq_chip Yinghai Lu
2010-03-22  1:36 ` [PATCH 08/10] genericirq: add set_irq_desc_chip/data Yinghai Lu
2010-03-22  1:36 ` [PATCH 09/10] x86/iommu/dmar: update iommu/inter_remapping to use desc Yinghai Lu
2010-03-22  1:36 ` [PATCH 10/10] x86: remove arch_probe_nr_irqs Yinghai Lu

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.