All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/20] x86: early_res and irq_desc
@ 2010-03-21  7:13 ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

01 - 06: early_res related
07 - 15: irq_desc releated
19 - 20: pci related

Thanks

Yinghai

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

* [PATCH 00/20] x86: early_res and irq_desc
@ 2010-03-21  7:13 ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

01 - 06: early_res related
07 - 15: irq_desc releated
19 - 20: pci related

Thanks

Yinghai

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

* [PATCH 01/20] x86: add find_e820_area_node
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

David Miller pointed out that early_res have problem to find node data on correct node
when we have
node0: [0, 2g), [4g, 6g), [10g, 14g)
node1: [6g, 10g), [14g, 18g)
the cross node case

the problem is there for x86 bits even before we are using early_res for bootmem replacement.
after early_res for bootmem replacement, alloc_bootmem_node still can get range on correct node

this patch is fixing problem before bootmem or early_res replacement for bootmem.

now only user is for x86 64bit numa to find node data.

the point is use early_node_map with find_e820_area_node()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h |    1 +
 arch/x86/kernel/e820.c      |   15 +++++++++++++++
 arch/x86/mm/numa_64.c       |    4 ++--
 include/linux/mm.h          |    2 ++
 mm/page_alloc.c             |   37 +++++++++++++++++++++++--------------
 5 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 0e22296..b48f371 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -111,6 +111,7 @@ extern unsigned long end_user_pfn;
 
 extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
 extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
+u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
 #include <linux/early_res.h>
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 740b440..05ee724 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -787,6 +787,21 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
 	return -1ULL;
 }
 
+u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	u64 addr;
+	/*
+	 * need to call this function after e820_register_active_regions
+	 * so early_node_map[] is set
+	 */
+	addr = find_memory_core_early(nid, size, align, start, end);
+	if (addr != -1ULL)
+		return addr;
+
+	/* fallback, should already have start end in the node range */
+	return find_e820_area(start, end, size, align);
+}
+
 /*
  * pre allocated 4k and reserved it in e820
  */
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 8948f47..ffc5ad5 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -174,7 +174,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 	if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
 	    end > (MAX_DMA32_PFN<<PAGE_SHIFT))
 		start = MAX_DMA32_PFN<<PAGE_SHIFT;
-	mem = find_e820_area(start, end, size, align);
+	mem = find_e820_area_node(nodeid, start, end, size, align);
 	if (mem != -1L)
 		return __va(mem);
 
@@ -184,7 +184,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 		start = MAX_DMA32_PFN<<PAGE_SHIFT;
 	else
 		start = MAX_DMA_PFN<<PAGE_SHIFT;
-	mem = find_e820_area(start, end, size, align);
+	mem = find_e820_area_node(nodeid, start, end, size, align);
 	if (mem != -1L)
 		return __va(mem);
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e70f21b..5c2d17e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1160,6 +1160,8 @@ extern void free_bootmem_with_active_regions(int nid,
 						unsigned long max_low_pfn);
 int add_from_early_node_map(struct range *range, int az,
 				   int nr_range, int nid);
+u64 __init find_memory_core_early(int nid, u64 size, u64 align,
+					u64 goal, u64 limit);
 void *__alloc_memory_core_early(int nodeid, u64 size, u64 align,
 				 u64 goal, u64 limit);
 typedef int (*work_fn_t)(unsigned long, unsigned long, void *);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d03c946..eef3757 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3408,12 +3408,11 @@ int __init add_from_early_node_map(struct range *range, int az,
 	return nr_range;
 }
 
-#ifdef CONFIG_NO_BOOTMEM
-void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
+#ifdef CONFIG_HAVE_EARLY_RES
+u64 __init find_memory_core_early(int nid, u64 size, u64 align,
 					u64 goal, u64 limit)
 {
 	int i;
-	void *ptr;
 
 	/* need to go over early_node_map to find out good range for node */
 	for_each_active_range_index_in_nid(i, nid) {
@@ -3430,20 +3429,30 @@ void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
 		if (addr == -1ULL)
 			continue;
 
-#if 0
-		printk(KERN_DEBUG "alloc (nid=%d %llx - %llx) (%llx - %llx) %llx %llx => %llx\n",
-				nid,
-				ei_start, ei_last, goal, limit, size,
-				align, addr);
+		return addr;
+	}
+
+	return -1ULL;
+}
 #endif
 
-		ptr = phys_to_virt(addr);
-		memset(ptr, 0, size);
-		reserve_early_without_check(addr, addr + size, "BOOTMEM");
-		return ptr;
-	}
+#ifdef CONFIG_NO_BOOTMEM
+void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
+					u64 goal, u64 limit)
+{
+	void *ptr;
 
-	return NULL;
+	u64 addr;
+
+	addr = find_memory_core_early(nid, size, align, goal, limit);
+
+	if (addr == -1ULL)
+		return NULL;
+
+	ptr = phys_to_virt(addr);
+	memset(ptr, 0, size);
+	reserve_early_without_check(addr, addr + size, "BOOTMEM");
+	return ptr;
 }
 #endif
 
-- 
1.6.4.2


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

* [PATCH 01/20] x86: add find_e820_area_node
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

David Miller pointed out that early_res have problem to find node data on correct node
when we have
node0: [0, 2g), [4g, 6g), [10g, 14g)
node1: [6g, 10g), [14g, 18g)
the cross node case

the problem is there for x86 bits even before we are using early_res for bootmem replacement.
after early_res for bootmem replacement, alloc_bootmem_node still can get range on correct node

this patch is fixing problem before bootmem or early_res replacement for bootmem.

now only user is for x86 64bit numa to find node data.

the point is use early_node_map with find_e820_area_node()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h |    1 +
 arch/x86/kernel/e820.c      |   15 +++++++++++++++
 arch/x86/mm/numa_64.c       |    4 ++--
 include/linux/mm.h          |    2 ++
 mm/page_alloc.c             |   37 +++++++++++++++++++++++--------------
 5 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 0e22296..b48f371 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -111,6 +111,7 @@ extern unsigned long end_user_pfn;
 
 extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
 extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
+u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
 #include <linux/early_res.h>
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 740b440..05ee724 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -787,6 +787,21 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
 	return -1ULL;
 }
 
+u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	u64 addr;
+	/*
+	 * need to call this function after e820_register_active_regions
+	 * so early_node_map[] is set
+	 */
+	addr = find_memory_core_early(nid, size, align, start, end);
+	if (addr != -1ULL)
+		return addr;
+
+	/* fallback, should already have start end in the node range */
+	return find_e820_area(start, end, size, align);
+}
+
 /*
  * pre allocated 4k and reserved it in e820
  */
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 8948f47..ffc5ad5 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -174,7 +174,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 	if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
 	    end > (MAX_DMA32_PFN<<PAGE_SHIFT))
 		start = MAX_DMA32_PFN<<PAGE_SHIFT;
-	mem = find_e820_area(start, end, size, align);
+	mem = find_e820_area_node(nodeid, start, end, size, align);
 	if (mem != -1L)
 		return __va(mem);
 
@@ -184,7 +184,7 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 		start = MAX_DMA32_PFN<<PAGE_SHIFT;
 	else
 		start = MAX_DMA_PFN<<PAGE_SHIFT;
-	mem = find_e820_area(start, end, size, align);
+	mem = find_e820_area_node(nodeid, start, end, size, align);
 	if (mem != -1L)
 		return __va(mem);
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e70f21b..5c2d17e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1160,6 +1160,8 @@ extern void free_bootmem_with_active_regions(int nid,
 						unsigned long max_low_pfn);
 int add_from_early_node_map(struct range *range, int az,
 				   int nr_range, int nid);
+u64 __init find_memory_core_early(int nid, u64 size, u64 align,
+					u64 goal, u64 limit);
 void *__alloc_memory_core_early(int nodeid, u64 size, u64 align,
 				 u64 goal, u64 limit);
 typedef int (*work_fn_t)(unsigned long, unsigned long, void *);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d03c946..eef3757 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3408,12 +3408,11 @@ int __init add_from_early_node_map(struct range *range, int az,
 	return nr_range;
 }
 
-#ifdef CONFIG_NO_BOOTMEM
-void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
+#ifdef CONFIG_HAVE_EARLY_RES
+u64 __init find_memory_core_early(int nid, u64 size, u64 align,
 					u64 goal, u64 limit)
 {
 	int i;
-	void *ptr;
 
 	/* need to go over early_node_map to find out good range for node */
 	for_each_active_range_index_in_nid(i, nid) {
@@ -3430,20 +3429,30 @@ void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
 		if (addr == -1ULL)
 			continue;
 
-#if 0
-		printk(KERN_DEBUG "alloc (nid=%d %llx - %llx) (%llx - %llx) %llx %llx => %llx\n",
-				nid,
-				ei_start, ei_last, goal, limit, size,
-				align, addr);
+		return addr;
+	}
+
+	return -1ULL;
+}
 #endif
 
-		ptr = phys_to_virt(addr);
-		memset(ptr, 0, size);
-		reserve_early_without_check(addr, addr + size, "BOOTMEM");
-		return ptr;
-	}
+#ifdef CONFIG_NO_BOOTMEM
+void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
+					u64 goal, u64 limit)
+{
+	void *ptr;
 
-	return NULL;
+	u64 addr;
+
+	addr = find_memory_core_early(nid, size, align, goal, limit);
+
+	if (addr == -1ULL)
+		return NULL;
+
+	ptr = phys_to_virt(addr);
+	memset(ptr, 0, size);
+	reserve_early_without_check(addr, addr + size, "BOOTMEM");
+	return ptr;
 }
 #endif
 
-- 
1.6.4.2

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

* [PATCH 02/20] x86: add get_centaur_ram_top
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

so we can avoid to access e820.map[] directly.

later we could move e820 to static and _initdata

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h   |    9 ++++++
 arch/x86/kernel/cpu/centaur.c |   53 +------------------------------------
 arch/x86/kernel/e820.c        |   57 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c       |    2 +
 4 files changed, 70 insertions(+), 51 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index b48f371..38828c7 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -72,6 +72,15 @@ struct e820map {
 extern struct e820map e820;
 extern struct e820map e820_saved;
 
+#ifdef CONFIG_X86_OOSTORE
+extern int centaur_ram_top;
+void get_centaur_ram_top(void);
+#else
+static inline void get_centaur_ram_top(void)
+{
+}
+#endif
+
 extern unsigned long pci_mem_start;
 extern int e820_any_mapped(u64 start, u64 end, unsigned type);
 extern int e820_all_mapped(u64 start, u64 end, unsigned type);
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index e58d978..bb49358 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -37,63 +37,14 @@ static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
 	mtrr_centaur_report_mcr(reg, lo, hi);	/* Tell the mtrr driver */
 }
 
-/*
- * Figure what we can cover with MCR's
- *
- * Shortcut: We know you can't put 4Gig of RAM on a winchip
- */
-static u32 __cpuinit ramtop(void)
-{
-	u32 clip = 0xFFFFFFFFUL;
-	u32 top = 0;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		unsigned long start, end;
-
-		if (e820.map[i].addr > 0xFFFFFFFFUL)
-			continue;
-		/*
-		 * Don't MCR over reserved space. Ignore the ISA hole
-		 * we frob around that catastrophe already
-		 */
-		if (e820.map[i].type == E820_RESERVED) {
-			if (e820.map[i].addr >= 0x100000UL &&
-			    e820.map[i].addr < clip)
-				clip = e820.map[i].addr;
-			continue;
-		}
-		start = e820.map[i].addr;
-		end = e820.map[i].addr + e820.map[i].size;
-		if (start >= end)
-			continue;
-		if (end > top)
-			top = end;
-	}
-	/*
-	 * Everything below 'top' should be RAM except for the ISA hole.
-	 * Because of the limited MCR's we want to map NV/ACPI into our
-	 * MCR range for gunk in RAM
-	 *
-	 * Clip might cause us to MCR insufficient RAM but that is an
-	 * acceptable failure mode and should only bite obscure boxes with
-	 * a VESA hole at 15Mb
-	 *
-	 * The second case Clip sometimes kicks in is when the EBDA is marked
-	 * as reserved. Again we fail safe with reasonable results
-	 */
-	if (top > clip)
-		top = clip;
-
-	return top;
-}
+int __cpuinitdata centaur_ram_top;
 
 /*
  * Compute a set of MCR's to give maximum coverage
  */
 static int __cpuinit centaur_mcr_compute(int nr, int key)
 {
-	u32 mem = ramtop();
+	u32 mem = centaur_ram_top;
 	u32 root = power2(mem);
 	u32 base = root;
 	u32 top = root;
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 05ee724..119c0e1 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1209,3 +1209,60 @@ void __init setup_memory_map(void)
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 	e820_print_map(who);
 }
+
+#ifdef CONFIG_X86_OOSTORE
+/*
+ * Figure what we can cover with MCR's
+ *
+ * Shortcut: We know you can't put 4Gig of RAM on a winchip
+ */
+void __init get_centaur_ram_top(void)
+{
+	u32 clip = 0xFFFFFFFFUL;
+	u32 top = 0;
+	int i;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
+		return;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		unsigned long start, end;
+
+		if (e820.map[i].addr > 0xFFFFFFFFUL)
+			continue;
+		/*
+		 * Don't MCR over reserved space. Ignore the ISA hole
+		 * we frob around that catastrophe already
+		 */
+		if (e820.map[i].type == E820_RESERVED) {
+			if (e820.map[i].addr >= 0x100000UL &&
+			    e820.map[i].addr < clip)
+				clip = e820.map[i].addr;
+			continue;
+		}
+		start = e820.map[i].addr;
+		end = e820.map[i].addr + e820.map[i].size;
+		if (start >= end)
+			continue;
+		if (end > top)
+			top = end;
+	}
+	/*
+	 * Everything below 'top' should be RAM except for the ISA hole.
+	 * Because of the limited MCR's we want to map NV/ACPI into our
+	 * MCR range for gunk in RAM
+	 *
+	 * Clip might cause us to MCR insufficient RAM but that is an
+	 * acceptable failure mode and should only bite obscure boxes with
+	 * a VESA hole at 15Mb
+	 *
+	 * The second case Clip sometimes kicks in is when the EBDA is marked
+	 * as reserved. Again we fail safe with reasonable results
+	 */
+	if (top > clip)
+		top = clip;
+
+	centaur_ram_top = top;
+}
+#endif
+
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 5d7ba1a..c5ea524 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -875,6 +875,8 @@ void __init setup_arch(char **cmdline_p)
 	if (mtrr_trim_uncached_memory(max_pfn))
 		max_pfn = e820_end_of_ram_pfn();
 
+	get_centaur_ram_top();
+
 #ifdef CONFIG_X86_32
 	/* max_low_pfn get updated here */
 	find_low_pfn_range();
-- 
1.6.4.2


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

* [PATCH 02/20] x86: add get_centaur_ram_top
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

so we can avoid to access e820.map[] directly.

later we could move e820 to static and _initdata

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h   |    9 ++++++
 arch/x86/kernel/cpu/centaur.c |   53 +------------------------------------
 arch/x86/kernel/e820.c        |   57 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c       |    2 +
 4 files changed, 70 insertions(+), 51 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index b48f371..38828c7 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -72,6 +72,15 @@ struct e820map {
 extern struct e820map e820;
 extern struct e820map e820_saved;
 
+#ifdef CONFIG_X86_OOSTORE
+extern int centaur_ram_top;
+void get_centaur_ram_top(void);
+#else
+static inline void get_centaur_ram_top(void)
+{
+}
+#endif
+
 extern unsigned long pci_mem_start;
 extern int e820_any_mapped(u64 start, u64 end, unsigned type);
 extern int e820_all_mapped(u64 start, u64 end, unsigned type);
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index e58d978..bb49358 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -37,63 +37,14 @@ static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
 	mtrr_centaur_report_mcr(reg, lo, hi);	/* Tell the mtrr driver */
 }
 
-/*
- * Figure what we can cover with MCR's
- *
- * Shortcut: We know you can't put 4Gig of RAM on a winchip
- */
-static u32 __cpuinit ramtop(void)
-{
-	u32 clip = 0xFFFFFFFFUL;
-	u32 top = 0;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		unsigned long start, end;
-
-		if (e820.map[i].addr > 0xFFFFFFFFUL)
-			continue;
-		/*
-		 * Don't MCR over reserved space. Ignore the ISA hole
-		 * we frob around that catastrophe already
-		 */
-		if (e820.map[i].type == E820_RESERVED) {
-			if (e820.map[i].addr >= 0x100000UL &&
-			    e820.map[i].addr < clip)
-				clip = e820.map[i].addr;
-			continue;
-		}
-		start = e820.map[i].addr;
-		end = e820.map[i].addr + e820.map[i].size;
-		if (start >= end)
-			continue;
-		if (end > top)
-			top = end;
-	}
-	/*
-	 * Everything below 'top' should be RAM except for the ISA hole.
-	 * Because of the limited MCR's we want to map NV/ACPI into our
-	 * MCR range for gunk in RAM
-	 *
-	 * Clip might cause us to MCR insufficient RAM but that is an
-	 * acceptable failure mode and should only bite obscure boxes with
-	 * a VESA hole at 15Mb
-	 *
-	 * The second case Clip sometimes kicks in is when the EBDA is marked
-	 * as reserved. Again we fail safe with reasonable results
-	 */
-	if (top > clip)
-		top = clip;
-
-	return top;
-}
+int __cpuinitdata centaur_ram_top;
 
 /*
  * Compute a set of MCR's to give maximum coverage
  */
 static int __cpuinit centaur_mcr_compute(int nr, int key)
 {
-	u32 mem = ramtop();
+	u32 mem = centaur_ram_top;
 	u32 root = power2(mem);
 	u32 base = root;
 	u32 top = root;
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 05ee724..119c0e1 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1209,3 +1209,60 @@ void __init setup_memory_map(void)
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 	e820_print_map(who);
 }
+
+#ifdef CONFIG_X86_OOSTORE
+/*
+ * Figure what we can cover with MCR's
+ *
+ * Shortcut: We know you can't put 4Gig of RAM on a winchip
+ */
+void __init get_centaur_ram_top(void)
+{
+	u32 clip = 0xFFFFFFFFUL;
+	u32 top = 0;
+	int i;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
+		return;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		unsigned long start, end;
+
+		if (e820.map[i].addr > 0xFFFFFFFFUL)
+			continue;
+		/*
+		 * Don't MCR over reserved space. Ignore the ISA hole
+		 * we frob around that catastrophe already
+		 */
+		if (e820.map[i].type == E820_RESERVED) {
+			if (e820.map[i].addr >= 0x100000UL &&
+			    e820.map[i].addr < clip)
+				clip = e820.map[i].addr;
+			continue;
+		}
+		start = e820.map[i].addr;
+		end = e820.map[i].addr + e820.map[i].size;
+		if (start >= end)
+			continue;
+		if (end > top)
+			top = end;
+	}
+	/*
+	 * Everything below 'top' should be RAM except for the ISA hole.
+	 * Because of the limited MCR's we want to map NV/ACPI into our
+	 * MCR range for gunk in RAM
+	 *
+	 * Clip might cause us to MCR insufficient RAM but that is an
+	 * acceptable failure mode and should only bite obscure boxes with
+	 * a VESA hole at 15Mb
+	 *
+	 * The second case Clip sometimes kicks in is when the EBDA is marked
+	 * as reserved. Again we fail safe with reasonable results
+	 */
+	if (top > clip)
+		top = clip;
+
+	centaur_ram_top = top;
+}
+#endif
+
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 5d7ba1a..c5ea524 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -875,6 +875,8 @@ void __init setup_arch(char **cmdline_p)
 	if (mtrr_trim_uncached_memory(max_pfn))
 		max_pfn = e820_end_of_ram_pfn();
 
+	get_centaur_ram_top();
+
 #ifdef CONFIG_X86_32
 	/* max_low_pfn get updated here */
 	find_low_pfn_range();
-- 
1.6.4.2

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

* [PATCH 03/20] x86: make e820 to be static
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

make sanitize_e820_map() not take e820.map directly.

and could change e820_saved to initdata

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h |    7 ++-----
 arch/x86/kernel/e820.c      |   28 +++++++++++++++++++---------
 arch/x86/kernel/efi.c       |    2 +-
 arch/x86/kernel/setup.c     |   10 +++++-----
 arch/x86/xen/setup.c        |    4 +---
 5 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 38828c7..71c0348 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -68,9 +68,6 @@ struct e820map {
 #define BIOS_END		0x00100000
 
 #ifdef __KERNEL__
-/* see comment in arch/x86/kernel/e820.c */
-extern struct e820map e820;
-extern struct e820map e820_saved;
 
 #ifdef CONFIG_X86_OOSTORE
 extern int centaur_ram_top;
@@ -86,8 +83,8 @@ extern int e820_any_mapped(u64 start, u64 end, unsigned type);
 extern int e820_all_mapped(u64 start, u64 end, unsigned type);
 extern void e820_add_region(u64 start, u64 size, int type);
 extern void e820_print_map(char *who);
-extern int
-sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
+int sanitize_e820_map(void);
+void save_e820_map(void);
 extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
 			       unsigned new_type);
 extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 119c0e1..40c04cf 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -34,8 +34,8 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-struct e820map e820;
-struct e820map e820_saved;
+static struct e820map e820;
+static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0xaeedbabe;
@@ -224,7 +224,7 @@ void __init e820_print_map(char *who)
  *	   ______________________4_
  */
 
-int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+static int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
 			     u32 *pnr_map)
 {
 	struct change_member {
@@ -383,6 +383,11 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
 	return 0;
 }
 
+int __init sanitize_e820_map(void)
+{
+	return __sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+}
+
 static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
 {
 	while (nr_map) {
@@ -555,7 +560,7 @@ void __init update_e820(void)
 	u32 nr_map;
 
 	nr_map = e820.nr_map;
-	if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
+	if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
 		return;
 	e820.nr_map = nr_map;
 	printk(KERN_INFO "modified physical RAM map:\n");
@@ -566,7 +571,7 @@ static void __init update_e820_saved(void)
 	u32 nr_map;
 
 	nr_map = e820_saved.nr_map;
-	if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
+	if (__sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
 		return;
 	e820_saved.nr_map = nr_map;
 }
@@ -661,7 +666,7 @@ void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
 		sdata = early_ioremap(pa_data, map_len);
 	extmap = (struct e820entry *)(sdata->data);
 	__append_e820_map(extmap, entries);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 	if (map_len > PAGE_SIZE)
 		early_iounmap(sdata, map_len);
 	printk(KERN_INFO "extended physical RAM map:\n");
@@ -1043,7 +1048,7 @@ void __init finish_e820_parsing(void)
 	if (userdef) {
 		u32 nr = e820.nr_map;
 
-		if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
+		if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
 			early_panic("Invalid user supplied memory map");
 		e820.nr_map = nr;
 
@@ -1173,7 +1178,7 @@ char *__init default_machine_specific_memory_setup(void)
 	 * the next section from 1mb->appropriate_mem_k
 	 */
 	new_nr = boot_params.e820_entries;
-	sanitize_e820_map(boot_params.e820_map,
+	__sanitize_e820_map(boot_params.e820_map,
 			ARRAY_SIZE(boot_params.e820_map),
 			&new_nr);
 	boot_params.e820_entries = new_nr;
@@ -1200,12 +1205,17 @@ char *__init default_machine_specific_memory_setup(void)
 	return who;
 }
 
+void __init save_e820_map(void)
+{
+	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+}
+
 void __init setup_memory_map(void)
 {
 	char *who;
 
 	who = x86_init.resources.memory_setup();
-	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+	save_e820_map();
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 	e820_print_map(who);
 }
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index c2fa9b8..299f03f 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -272,7 +272,7 @@ static void __init do_add_efi_memmap(void)
 		}
 		e820_add_region(start, size, e820_type);
 	}
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 }
 
 void __init efi_reserve_early(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c5ea524..82533cf 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -461,8 +461,8 @@ static void __init e820_reserve_setup_data(void)
 	if (!found)
 		return;
 
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+	sanitize_e820_map();
+	save_e820_map();
 	printk(KERN_INFO "extended physical RAM map:\n");
 	e820_print_map("reserve setup_data");
 }
@@ -614,7 +614,7 @@ static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 		d->ident);
 
 	e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 
 	return 0;
 }
@@ -683,7 +683,7 @@ static void __init trim_bios_range(void)
 	 * take them out.
 	 */
 	e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 }
 
 /*
@@ -854,7 +854,7 @@ void __init setup_arch(char **cmdline_p)
 	if (ppro_with_ram_bug()) {
 		e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
 				  E820_RESERVED);
-		sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+		sanitize_e820_map();
 		printk(KERN_INFO "fixed physical RAM map:\n");
 		e820_print_map("bad_ppro");
 	}
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index ad0047f..3f2c411 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -43,8 +43,6 @@ char * __init xen_memory_setup(void)
 
 	max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
 
-	e820.nr_map = 0;
-
 	e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
 
 	/*
@@ -65,7 +63,7 @@ char * __init xen_memory_setup(void)
 		      __pa(xen_start_info->pt_base),
 			"XEN START INFO");
 
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 
 	return "Xen";
 }
-- 
1.6.4.2


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

* [PATCH 03/20] x86: make e820 to be static
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

make sanitize_e820_map() not take e820.map directly.

and could change e820_saved to initdata

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h |    7 ++-----
 arch/x86/kernel/e820.c      |   28 +++++++++++++++++++---------
 arch/x86/kernel/efi.c       |    2 +-
 arch/x86/kernel/setup.c     |   10 +++++-----
 arch/x86/xen/setup.c        |    4 +---
 5 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 38828c7..71c0348 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -68,9 +68,6 @@ struct e820map {
 #define BIOS_END		0x00100000
 
 #ifdef __KERNEL__
-/* see comment in arch/x86/kernel/e820.c */
-extern struct e820map e820;
-extern struct e820map e820_saved;
 
 #ifdef CONFIG_X86_OOSTORE
 extern int centaur_ram_top;
@@ -86,8 +83,8 @@ extern int e820_any_mapped(u64 start, u64 end, unsigned type);
 extern int e820_all_mapped(u64 start, u64 end, unsigned type);
 extern void e820_add_region(u64 start, u64 size, int type);
 extern void e820_print_map(char *who);
-extern int
-sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
+int sanitize_e820_map(void);
+void save_e820_map(void);
 extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
 			       unsigned new_type);
 extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 119c0e1..40c04cf 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -34,8 +34,8 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-struct e820map e820;
-struct e820map e820_saved;
+static struct e820map e820;
+static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0xaeedbabe;
@@ -224,7 +224,7 @@ void __init e820_print_map(char *who)
  *	   ______________________4_
  */
 
-int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+static int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
 			     u32 *pnr_map)
 {
 	struct change_member {
@@ -383,6 +383,11 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
 	return 0;
 }
 
+int __init sanitize_e820_map(void)
+{
+	return __sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+}
+
 static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
 {
 	while (nr_map) {
@@ -555,7 +560,7 @@ void __init update_e820(void)
 	u32 nr_map;
 
 	nr_map = e820.nr_map;
-	if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
+	if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
 		return;
 	e820.nr_map = nr_map;
 	printk(KERN_INFO "modified physical RAM map:\n");
@@ -566,7 +571,7 @@ static void __init update_e820_saved(void)
 	u32 nr_map;
 
 	nr_map = e820_saved.nr_map;
-	if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
+	if (__sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
 		return;
 	e820_saved.nr_map = nr_map;
 }
@@ -661,7 +666,7 @@ void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
 		sdata = early_ioremap(pa_data, map_len);
 	extmap = (struct e820entry *)(sdata->data);
 	__append_e820_map(extmap, entries);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 	if (map_len > PAGE_SIZE)
 		early_iounmap(sdata, map_len);
 	printk(KERN_INFO "extended physical RAM map:\n");
@@ -1043,7 +1048,7 @@ void __init finish_e820_parsing(void)
 	if (userdef) {
 		u32 nr = e820.nr_map;
 
-		if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
+		if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
 			early_panic("Invalid user supplied memory map");
 		e820.nr_map = nr;
 
@@ -1173,7 +1178,7 @@ char *__init default_machine_specific_memory_setup(void)
 	 * the next section from 1mb->appropriate_mem_k
 	 */
 	new_nr = boot_params.e820_entries;
-	sanitize_e820_map(boot_params.e820_map,
+	__sanitize_e820_map(boot_params.e820_map,
 			ARRAY_SIZE(boot_params.e820_map),
 			&new_nr);
 	boot_params.e820_entries = new_nr;
@@ -1200,12 +1205,17 @@ char *__init default_machine_specific_memory_setup(void)
 	return who;
 }
 
+void __init save_e820_map(void)
+{
+	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+}
+
 void __init setup_memory_map(void)
 {
 	char *who;
 
 	who = x86_init.resources.memory_setup();
-	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+	save_e820_map();
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 	e820_print_map(who);
 }
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index c2fa9b8..299f03f 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -272,7 +272,7 @@ static void __init do_add_efi_memmap(void)
 		}
 		e820_add_region(start, size, e820_type);
 	}
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 }
 
 void __init efi_reserve_early(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c5ea524..82533cf 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -461,8 +461,8 @@ static void __init e820_reserve_setup_data(void)
 	if (!found)
 		return;
 
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-	memcpy(&e820_saved, &e820, sizeof(struct e820map));
+	sanitize_e820_map();
+	save_e820_map();
 	printk(KERN_INFO "extended physical RAM map:\n");
 	e820_print_map("reserve setup_data");
 }
@@ -614,7 +614,7 @@ static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 		d->ident);
 
 	e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 
 	return 0;
 }
@@ -683,7 +683,7 @@ static void __init trim_bios_range(void)
 	 * take them out.
 	 */
 	e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 }
 
 /*
@@ -854,7 +854,7 @@ void __init setup_arch(char **cmdline_p)
 	if (ppro_with_ram_bug()) {
 		e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
 				  E820_RESERVED);
-		sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+		sanitize_e820_map();
 		printk(KERN_INFO "fixed physical RAM map:\n");
 		e820_print_map("bad_ppro");
 	}
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index ad0047f..3f2c411 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -43,8 +43,6 @@ char * __init xen_memory_setup(void)
 
 	max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
 
-	e820.nr_map = 0;
-
 	e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
 
 	/*
@@ -65,7 +63,7 @@ char * __init xen_memory_setup(void)
 		      __pa(xen_start_info->pt_base),
 			"XEN START INFO");
 
-	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+	sanitize_e820_map();
 
 	return "Xen";
 }
-- 
1.6.4.2

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

* [PATCH 04/20] x86: use wake_system_ram_range instead of e820_any_mapped in agp path
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

put apterture_valid back to .c
and early path still use e820_any_mapped()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/gart.h   |   22 ----------------------
 arch/x86/kernel/aperture_64.c |   22 ++++++++++++++++++++++
 drivers/char/agp/amd64-agp.c  |   39 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 4ac5b0f..2b63a91 100644
--- a/arch/x86/include/asm/gart.h
+++ b/arch/x86/include/asm/gart.h
@@ -74,26 +74,4 @@ static inline void enable_gart_translation(struct pci_dev *dev, u64 addr)
         pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
 }
 
-static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
-{
-	if (!aper_base)
-		return 0;
-
-	if (aper_base + aper_size > 0x100000000ULL) {
-		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
-		return 0;
-	}
-	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
-		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
-		return 0;
-	}
-	if (aper_size < min_size) {
-		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
-				 aper_size>>20, min_size>>20);
-		return 0;
-	}
-
-	return 1;
-}
-
 #endif /* _ASM_X86_GART_H */
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 3704997..f6e6270 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -145,6 +145,28 @@ static u32 __init find_cap(int bus, int slot, int func, int cap)
 	return 0;
 }
 
+static int __init aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
+{
+	if (!aper_base)
+		return 0;
+
+	if (aper_base + aper_size > 0x100000000ULL) {
+		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
+		return 0;
+	}
+	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
+		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
+		return 0;
+	}
+	if (aper_size < min_size) {
+		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
+				 aper_size>>20, min_size>>20);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Read a standard AGPv3 bridge header */
 static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
 {
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index fd50ead..85cabd0 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -14,7 +14,6 @@
 #include <linux/agp_backend.h>
 #include <linux/mmzone.h>
 #include <asm/page.h>		/* PAGE_SIZE */
-#include <asm/e820.h>
 #include <asm/k8.h>
 #include <asm/gart.h>
 #include "agp.h"
@@ -231,6 +230,44 @@ static const struct agp_bridge_driver amd_8151_driver = {
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
+static int __devinit
+__is_ram(unsigned long pfn, unsigned long nr_pages, void *arg)
+{
+	return 1;
+}
+
+static int __devinit any_ram_in_range(u64 base, u64 size)
+{
+	unsigned long pfn, nr_pages;
+
+	pfn = base >> PAGE_SHIFT;
+	nr_pages = size >> PAGE_SHIFT;
+
+	return walk_system_ram_range(pfn, nr_pages, NULL, __is_ram) == 1;
+}
+
+static int __devinit aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
+{
+	if (!aper_base)
+		return 0;
+
+	if (aper_base + aper_size > 0x100000000ULL) {
+		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
+		return 0;
+	}
+	if (any_ram_in_range(aper_base, aper_size)) {
+		printk(KERN_INFO "Aperture pointing to E820 RAM. Ignoring.\n");
+		return 0;
+	}
+	if (aper_size < min_size) {
+		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
+				 aper_size>>20, min_size>>20);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Some basic sanity checks for the aperture. */
 static int __devinit agp_aperture_valid(u64 aper, u32 size)
 {
-- 
1.6.4.2


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

* [PATCH 04/20] x86: use wake_system_ram_range instead of e820_any_mapped in agp path
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

put apterture_valid back to .c
and early path still use e820_any_mapped()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/gart.h   |   22 ----------------------
 arch/x86/kernel/aperture_64.c |   22 ++++++++++++++++++++++
 drivers/char/agp/amd64-agp.c  |   39 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h
index 4ac5b0f..2b63a91 100644
--- a/arch/x86/include/asm/gart.h
+++ b/arch/x86/include/asm/gart.h
@@ -74,26 +74,4 @@ static inline void enable_gart_translation(struct pci_dev *dev, u64 addr)
         pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
 }
 
-static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
-{
-	if (!aper_base)
-		return 0;
-
-	if (aper_base + aper_size > 0x100000000ULL) {
-		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
-		return 0;
-	}
-	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
-		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
-		return 0;
-	}
-	if (aper_size < min_size) {
-		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
-				 aper_size>>20, min_size>>20);
-		return 0;
-	}
-
-	return 1;
-}
-
 #endif /* _ASM_X86_GART_H */
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 3704997..f6e6270 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -145,6 +145,28 @@ static u32 __init find_cap(int bus, int slot, int func, int cap)
 	return 0;
 }
 
+static int __init aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
+{
+	if (!aper_base)
+		return 0;
+
+	if (aper_base + aper_size > 0x100000000ULL) {
+		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
+		return 0;
+	}
+	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
+		printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
+		return 0;
+	}
+	if (aper_size < min_size) {
+		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
+				 aper_size>>20, min_size>>20);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Read a standard AGPv3 bridge header */
 static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
 {
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index fd50ead..85cabd0 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -14,7 +14,6 @@
 #include <linux/agp_backend.h>
 #include <linux/mmzone.h>
 #include <asm/page.h>		/* PAGE_SIZE */
-#include <asm/e820.h>
 #include <asm/k8.h>
 #include <asm/gart.h>
 #include "agp.h"
@@ -231,6 +230,44 @@ static const struct agp_bridge_driver amd_8151_driver = {
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
+static int __devinit
+__is_ram(unsigned long pfn, unsigned long nr_pages, void *arg)
+{
+	return 1;
+}
+
+static int __devinit any_ram_in_range(u64 base, u64 size)
+{
+	unsigned long pfn, nr_pages;
+
+	pfn = base >> PAGE_SHIFT;
+	nr_pages = size >> PAGE_SHIFT;
+
+	return walk_system_ram_range(pfn, nr_pages, NULL, __is_ram) == 1;
+}
+
+static int __devinit aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
+{
+	if (!aper_base)
+		return 0;
+
+	if (aper_base + aper_size > 0x100000000ULL) {
+		printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
+		return 0;
+	}
+	if (any_ram_in_range(aper_base, aper_size)) {
+		printk(KERN_INFO "Aperture pointing to E820 RAM. Ignoring.\n");
+		return 0;
+	}
+	if (aper_size < min_size) {
+		printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
+				 aper_size>>20, min_size>>20);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Some basic sanity checks for the aperture. */
 static int __devinit agp_aperture_valid(u64 aper, u32 size)
 {
-- 
1.6.4.2

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

* [PATCH 05/20] x86: make e820 to be initdata
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

and we don't need to expose e820_any_mapped anymore

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

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 40c04cf..a558609 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -34,7 +34,7 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-static struct e820map e820;
+static struct e820map __initdata e820;
 static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
@@ -46,9 +46,10 @@ EXPORT_SYMBOL(pci_mem_start);
 /*
  * This function checks if any part of the range <start,end> is mapped
  * with type.
+ * phys_pud_init() is using it and is _meminit, but we have !after_bootmem
+ * so could use refok here
  */
-int
-e820_any_mapped(u64 start, u64 end, unsigned type)
+int __init_refok e820_any_mapped(u64 start, u64 end, unsigned type)
 {
 	int i;
 
@@ -63,7 +64,6 @@ e820_any_mapped(u64 start, u64 end, unsigned type)
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(e820_any_mapped);
 
 /*
  * This function checks if the entire range <start,end> is mapped with type.
-- 
1.6.4.2


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

* [PATCH 05/20] x86: make e820 to be initdata
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

and we don't need to expose e820_any_mapped anymore

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

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 40c04cf..a558609 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -34,7 +34,7 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-static struct e820map e820;
+static struct e820map __initdata e820;
 static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
@@ -46,9 +46,10 @@ EXPORT_SYMBOL(pci_mem_start);
 /*
  * This function checks if any part of the range <start,end> is mapped
  * with type.
+ * phys_pud_init() is using it and is _meminit, but we have !after_bootmem
+ * so could use refok here
  */
-int
-e820_any_mapped(u64 start, u64 end, unsigned type)
+int __init_refok e820_any_mapped(u64 start, u64 end, unsigned type)
 {
 	int i;
 
@@ -63,7 +64,6 @@ e820_any_mapped(u64 start, u64 end, unsigned type)
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(e820_any_mapped);
 
 /*
  * This function checks if the entire range <start,end> is mapped with type.
-- 
1.6.4.2

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

* [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

move it to kernel/fw_memmap.c from arch/x86/kernel/e820.c

-v2: add fw_memmap wrapper to some func...
     move some functions back to e820.c

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h  |  176 ++++++-------
 arch/x86/kernel/e820.c       |  638 ++----------------------------------------
 include/linux/bootmem.h      |    2 +-
 include/linux/early_res.h    |    1 +
 include/linux/fw_memmap.h    |   40 +++
 kernel/Makefile              |    2 +-
 kernel/fw_memmap.c           |  625 +++++++++++++++++++++++++++++++++++++++++
 kernel/fw_memmap_internals.h |   49 ++++
 8 files changed, 822 insertions(+), 711 deletions(-)
 create mode 100644 include/linux/fw_memmap.h
 create mode 100644 kernel/fw_memmap.c
 create mode 100644 kernel/fw_memmap_internals.h

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 71c0348..c038616 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -1,65 +1,10 @@
 #ifndef _ASM_X86_E820_H
 #define _ASM_X86_E820_H
-#define E820MAP	0x2d0		/* our map */
-#define E820MAX	128		/* number of entries in E820MAP */
-
-/*
- * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
- * constrained space in the zeropage.  If we have more nodes than
- * that, and if we've booted off EFI firmware, then the EFI tables
- * passed us from the EFI firmware can list more nodes.  Size our
- * internal memory map tables to have room for these additional
- * nodes, based on up to three entries per node for which the
- * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
- * plus E820MAX, allowing space for the possible duplicate E820
- * entries that might need room in the same arrays, prior to the
- * call to sanitize_e820_map() to remove duplicates.  The allowance
- * of three memory map entries per node is "enough" entries for
- * the initial hardware platform motivating this mechanism to make
- * use of additional EFI map entries.  Future platforms may want
- * to allow more than three entries per node or otherwise refine
- * this size.
- */
-
-/*
- * Odd: 'make headers_check' complains about numa.h if I try
- * to collapse the next two #ifdef lines to a single line:
- *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
- */
-#ifdef __KERNEL__
-#ifdef CONFIG_EFI
-#include <linux/numa.h>
-#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
-#else	/* ! CONFIG_EFI */
-#define E820_X_MAX E820MAX
-#endif
-#else	/* ! __KERNEL__ */
-#define E820_X_MAX E820MAX
-#endif
-
-#define E820NR	0x1e8		/* # entries in E820MAP */
-
-#define E820_RAM	1
-#define E820_RESERVED	2
-#define E820_ACPI	3
-#define E820_NVS	4
-#define E820_UNUSABLE	5
 
 /* reserved RAM used by kernel itself */
 #define E820_RESERVED_KERN        128
 
 #ifndef __ASSEMBLY__
-#include <linux/types.h>
-struct e820entry {
-	__u64 addr;	/* start of memory segment */
-	__u64 size;	/* size of memory segment */
-	__u32 type;	/* type of memory segment */
-} __attribute__((packed));
-
-struct e820map {
-	__u32 nr_map;
-	struct e820entry map[E820_X_MAX];
-};
 
 #define ISA_START_ADDRESS	0xa0000
 #define ISA_END_ADDRESS		0x100000
@@ -69,32 +14,18 @@ struct e820map {
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_X86_OOSTORE
-extern int centaur_ram_top;
-void get_centaur_ram_top(void);
+#include <linux/fw_memmap.h>
+
+#ifdef CONFIG_MEMTEST
+extern void early_memtest(unsigned long start, unsigned long end);
 #else
-static inline void get_centaur_ram_top(void)
+static inline void early_memtest(unsigned long start, unsigned long end)
 {
 }
 #endif
 
 extern unsigned long pci_mem_start;
-extern int e820_any_mapped(u64 start, u64 end, unsigned type);
-extern int e820_all_mapped(u64 start, u64 end, unsigned type);
-extern void e820_add_region(u64 start, u64 size, int type);
-extern void e820_print_map(char *who);
-int sanitize_e820_map(void);
-void save_e820_map(void);
-extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
-			       unsigned new_type);
-extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype);
-extern void update_e820(void);
 extern void e820_setup_gap(void);
-extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
-			unsigned long start_addr, unsigned long long end_addr);
-struct setup_data;
-extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
 
 #if defined(CONFIG_X86_64) || \
 	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
@@ -105,37 +36,80 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
 }
 #endif
 
-#ifdef CONFIG_MEMTEST
-extern void early_memtest(unsigned long start, unsigned long end);
-#else
-static inline void early_memtest(unsigned long start, unsigned long end)
+static inline void e820_add_region(u64 start, u64 size, int type)
 {
+	fw_memmap_add_region(start, size, type);
+}
+
+static inline void e820_print_map(char *who)
+{
+	fw_memmap_print_map(who);
+}
+
+static inline int sanitize_e820_map(void)
+{
+	return sanitize_fw_memmap();
+}
+
+static inline void finish_e820_parsing(void)
+{
+	finish_fw_memmap_parsing();
+}
+
+static inline void e820_register_active_regions(int nid,
+						unsigned long start_pfn,
+						unsigned long end_pfn)
+{
+	fw_memmap_register_active_regions(nid, start_pfn, end_pfn);
+}
+
+static inline u64 e820_hole_size(u64 start, u64 end)
+{
+	return fw_memmap_hole_size(start, end);
+}
+
+static inline u64 find_e820_area(u64 start, u64 end, u64 size, u64 align)
+{
+	return find_fw_memmap_area(start, end, size, align);
+}
+
+static inline u64 find_e820_area_node(int nid, u64 start, u64 end,
+					 u64 size, u64 align)
+{
+	return find_fw_memmap_area_node(nid, start, end, size, align);
 }
-#endif
 
-extern unsigned long end_user_pfn;
+static inline unsigned long e820_end_of_ram_pfn(void)
+{
+	return fw_memmap_end_of_ram_pfn();
+}
+
+void clear_e820_map(void);
+
+extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
+				int checktype);
+struct e820entry;
+int __sanitize_e820_map(struct e820entry *biosmap, int max_nr, u32 *pnr_map);
+extern unsigned long e820_end_of_low_ram_pfn(void);
+
+extern int e820_any_mapped(u64 start, u64 end, unsigned type);
+extern int e820_all_mapped(u64 start, u64 end, unsigned type);
+extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
+			       unsigned new_type);
+
+extern void update_e820(void);
+void save_e820_map(void);
+struct setup_data;
+extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+extern char *default_machine_specific_memory_setup(void);
+extern void setup_memory_map(void);
 
-extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
 extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
-u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
+
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
-#include <linux/early_res.h>
 
-extern unsigned long e820_end_of_ram_pfn(void);
-extern unsigned long e820_end_of_low_ram_pfn(void);
-extern int e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn);
-extern void e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long end_pfn);
-extern u64 e820_hole_size(u64 start, u64 end);
-extern void finish_e820_parsing(void);
 extern void e820_reserve_resources(void);
 extern void e820_reserve_resources_late(void);
-extern void setup_memory_map(void);
-extern char *default_machine_specific_memory_setup(void);
 
 /*
  * Returns true iff the specified range [s,e) is completely contained inside
@@ -146,7 +120,17 @@ static inline bool is_ISA_range(u64 s, u64 e)
 	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
 }
 
+#ifdef CONFIG_X86_OOSTORE
+extern int centaur_ram_top;
+void get_centaur_ram_top(void);
+#else
+static inline void get_centaur_ram_top(void)
+{
+}
+#endif
+
 #endif /* __KERNEL__ */
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef __KERNEL__
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index a558609..9f125ca 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -12,18 +12,15 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
-#include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/firmware-map.h>
 
 #include <asm/e820.h>
-#include <asm/proto.h>
 #include <asm/setup.h>
 
+#include "../../../kernel/fw_memmap_internals.h"
+
 /*
- * The e820 map is the map that gets modified e.g. with command line parameters
- * and that is also registered with modifications in the kernel resource tree
- * with the iomem_resource as parent.
  *
  * The e820_saved is directly saved after the BIOS-provided memory map is
  * copied. It doesn't get modified afterwards. It's registered for the
@@ -34,7 +31,6 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-static struct e820map __initdata e820;
 static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
@@ -99,295 +95,6 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type)
 	return 0;
 }
 
-/*
- * Add a memory region to the kernel e820 map.
- */
-static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
-					 int type)
-{
-	int x = e820x->nr_map;
-
-	if (x >= ARRAY_SIZE(e820x->map)) {
-		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-		return;
-	}
-
-	e820x->map[x].addr = start;
-	e820x->map[x].size = size;
-	e820x->map[x].type = type;
-	e820x->nr_map++;
-}
-
-void __init e820_add_region(u64 start, u64 size, int type)
-{
-	__e820_add_region(&e820, start, size, type);
-}
-
-static void __init e820_print_type(u32 type)
-{
-	switch (type) {
-	case E820_RAM:
-	case E820_RESERVED_KERN:
-		printk(KERN_CONT "(usable)");
-		break;
-	case E820_RESERVED:
-		printk(KERN_CONT "(reserved)");
-		break;
-	case E820_ACPI:
-		printk(KERN_CONT "(ACPI data)");
-		break;
-	case E820_NVS:
-		printk(KERN_CONT "(ACPI NVS)");
-		break;
-	case E820_UNUSABLE:
-		printk(KERN_CONT "(unusable)");
-		break;
-	default:
-		printk(KERN_CONT "type %u", type);
-		break;
-	}
-}
-
-void __init e820_print_map(char *who)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
-		       (unsigned long long) e820.map[i].addr,
-		       (unsigned long long)
-		       (e820.map[i].addr + e820.map[i].size));
-		e820_print_type(e820.map[i].type);
-		printk(KERN_CONT "\n");
-	}
-}
-
-/*
- * Sanitize the BIOS e820 map.
- *
- * Some e820 responses include overlapping entries. The following
- * replaces the original e820 map with a new one, removing overlaps,
- * and resolving conflicting memory types in favor of highest
- * numbered type.
- *
- * The input parameter biosmap points to an array of 'struct
- * e820entry' which on entry has elements in the range [0, *pnr_map)
- * valid, and which has space for up to max_nr_map entries.
- * On return, the resulting sanitized e820 map entries will be in
- * overwritten in the same location, starting at biosmap.
- *
- * The integer pointed to by pnr_map must be valid on entry (the
- * current number of valid entries located at biosmap) and will
- * be updated on return, with the new number of valid entries
- * (something no more than max_nr_map.)
- *
- * The return value from sanitize_e820_map() is zero if it
- * successfully 'sanitized' the map entries passed in, and is -1
- * if it did nothing, which can happen if either of (1) it was
- * only passed one map entry, or (2) any of the input map entries
- * were invalid (start + size < start, meaning that the size was
- * so big the described memory range wrapped around through zero.)
- *
- *	Visually we're performing the following
- *	(1,2,3,4 = memory types)...
- *
- *	Sample memory map (w/overlaps):
- *	   ____22__________________
- *	   ______________________4_
- *	   ____1111________________
- *	   _44_____________________
- *	   11111111________________
- *	   ____________________33__
- *	   ___________44___________
- *	   __________33333_________
- *	   ______________22________
- *	   ___________________2222_
- *	   _________111111111______
- *	   _____________________11_
- *	   _________________4______
- *
- *	Sanitized equivalent (no overlap):
- *	   1_______________________
- *	   _44_____________________
- *	   ___1____________________
- *	   ____22__________________
- *	   ______11________________
- *	   _________1______________
- *	   __________3_____________
- *	   ___________44___________
- *	   _____________33_________
- *	   _______________2________
- *	   ________________1_______
- *	   _________________4______
- *	   ___________________2____
- *	   ____________________33__
- *	   ______________________4_
- */
-
-static int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
-			     u32 *pnr_map)
-{
-	struct change_member {
-		struct e820entry *pbios; /* pointer to original bios entry */
-		unsigned long long addr; /* address for this change point */
-	};
-	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
-	static struct change_member *change_point[2*E820_X_MAX] __initdata;
-	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
-	static struct e820entry new_bios[E820_X_MAX] __initdata;
-	struct change_member *change_tmp;
-	unsigned long current_type, last_type;
-	unsigned long long last_addr;
-	int chgidx, still_changing;
-	int overlap_entries;
-	int new_bios_entry;
-	int old_nr, new_nr, chg_nr;
-	int i;
-
-	/* if there's only one memory region, don't bother */
-	if (*pnr_map < 2)
-		return -1;
-
-	old_nr = *pnr_map;
-	BUG_ON(old_nr > max_nr_map);
-
-	/* bail out if we find any unreasonable addresses in bios map */
-	for (i = 0; i < old_nr; i++)
-		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
-			return -1;
-
-	/* create pointers for initial change-point information (for sorting) */
-	for (i = 0; i < 2 * old_nr; i++)
-		change_point[i] = &change_point_list[i];
-
-	/* record all known change-points (starting and ending addresses),
-	   omitting those that are for empty memory regions */
-	chgidx = 0;
-	for (i = 0; i < old_nr; i++)	{
-		if (biosmap[i].size != 0) {
-			change_point[chgidx]->addr = biosmap[i].addr;
-			change_point[chgidx++]->pbios = &biosmap[i];
-			change_point[chgidx]->addr = biosmap[i].addr +
-				biosmap[i].size;
-			change_point[chgidx++]->pbios = &biosmap[i];
-		}
-	}
-	chg_nr = chgidx;
-
-	/* sort change-point list by memory addresses (low -> high) */
-	still_changing = 1;
-	while (still_changing)	{
-		still_changing = 0;
-		for (i = 1; i < chg_nr; i++)  {
-			unsigned long long curaddr, lastaddr;
-			unsigned long long curpbaddr, lastpbaddr;
-
-			curaddr = change_point[i]->addr;
-			lastaddr = change_point[i - 1]->addr;
-			curpbaddr = change_point[i]->pbios->addr;
-			lastpbaddr = change_point[i - 1]->pbios->addr;
-
-			/*
-			 * swap entries, when:
-			 *
-			 * curaddr > lastaddr or
-			 * curaddr == lastaddr and curaddr == curpbaddr and
-			 * lastaddr != lastpbaddr
-			 */
-			if (curaddr < lastaddr ||
-			    (curaddr == lastaddr && curaddr == curpbaddr &&
-			     lastaddr != lastpbaddr)) {
-				change_tmp = change_point[i];
-				change_point[i] = change_point[i-1];
-				change_point[i-1] = change_tmp;
-				still_changing = 1;
-			}
-		}
-	}
-
-	/* create a new bios memory map, removing overlaps */
-	overlap_entries = 0;	 /* number of entries in the overlap table */
-	new_bios_entry = 0;	 /* index for creating new bios map entries */
-	last_type = 0;		 /* start with undefined memory type */
-	last_addr = 0;		 /* start with 0 as last starting address */
-
-	/* loop through change-points, determining affect on the new bios map */
-	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
-		/* keep track of all overlapping bios entries */
-		if (change_point[chgidx]->addr ==
-		    change_point[chgidx]->pbios->addr) {
-			/*
-			 * add map entry to overlap list (> 1 entry
-			 * implies an overlap)
-			 */
-			overlap_list[overlap_entries++] =
-				change_point[chgidx]->pbios;
-		} else {
-			/*
-			 * remove entry from list (order independent,
-			 * so swap with last)
-			 */
-			for (i = 0; i < overlap_entries; i++) {
-				if (overlap_list[i] ==
-				    change_point[chgidx]->pbios)
-					overlap_list[i] =
-						overlap_list[overlap_entries-1];
-			}
-			overlap_entries--;
-		}
-		/*
-		 * if there are overlapping entries, decide which
-		 * "type" to use (larger value takes precedence --
-		 * 1=usable, 2,3,4,4+=unusable)
-		 */
-		current_type = 0;
-		for (i = 0; i < overlap_entries; i++)
-			if (overlap_list[i]->type > current_type)
-				current_type = overlap_list[i]->type;
-		/*
-		 * continue building up new bios map based on this
-		 * information
-		 */
-		if (current_type != last_type)	{
-			if (last_type != 0)	 {
-				new_bios[new_bios_entry].size =
-					change_point[chgidx]->addr - last_addr;
-				/*
-				 * move forward only if the new size
-				 * was non-zero
-				 */
-				if (new_bios[new_bios_entry].size != 0)
-					/*
-					 * no more space left for new
-					 * bios entries ?
-					 */
-					if (++new_bios_entry >= max_nr_map)
-						break;
-			}
-			if (current_type != 0)	{
-				new_bios[new_bios_entry].addr =
-					change_point[chgidx]->addr;
-				new_bios[new_bios_entry].type = current_type;
-				last_addr = change_point[chgidx]->addr;
-			}
-			last_type = current_type;
-		}
-	}
-	/* retain count for new bios entries */
-	new_nr = new_bios_entry;
-
-	/* copy new bios mapping into original location */
-	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
-	*pnr_map = new_nr;
-
-	return 0;
-}
-
-int __init sanitize_e820_map(void)
-{
-	return __sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-}
-
 static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
 {
 	while (nr_map) {
@@ -509,52 +216,6 @@ static u64 __init e820_update_range_saved(u64 start, u64 size,
 				     new_type);
 }
 
-/* make e820 not cover the range */
-u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype)
-{
-	int i;
-	u64 end;
-	u64 real_removed_size = 0;
-
-	if (size > (ULLONG_MAX - start))
-		size = ULLONG_MAX - start;
-
-	end = start + size;
-	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
-		       (unsigned long long) start,
-		       (unsigned long long) end);
-	e820_print_type(old_type);
-	printk(KERN_CONT "\n");
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 final_start, final_end;
-
-		if (checktype && ei->type != old_type)
-			continue;
-		/* totally covered? */
-		if (ei->addr >= start &&
-		    (ei->addr + ei->size) <= (start + size)) {
-			real_removed_size += ei->size;
-			memset(ei, 0, sizeof(struct e820entry));
-			continue;
-		}
-		/* partially covered */
-		final_start = max(start, ei->addr);
-		final_end = min(start + size, ei->addr + ei->size);
-		if (final_start >= final_end)
-			continue;
-		real_removed_size += final_end - final_start;
-
-		ei->size -= final_end - final_start;
-		if (ei->addr < final_start)
-			continue;
-		ei->addr = final_end;
-	}
-	return real_removed_size;
-}
-
 void __init update_e820(void)
 {
 	u32 nr_map;
@@ -566,20 +227,24 @@ void __init update_e820(void)
 	printk(KERN_INFO "modified physical RAM map:\n");
 	e820_print_map("modified");
 }
+
 static void __init update_e820_saved(void)
 {
 	u32 nr_map;
+	int max_nr_map = ARRAY_SIZE(e820_saved.map);
 
 	nr_map = e820_saved.nr_map;
-	if (__sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
+	if (__sanitize_e820_map(e820_saved.map, max_nr_map, &nr_map))
 		return;
 	e820_saved.nr_map = nr_map;
 }
+
 #define MAX_GAP_END 0x100000000ull
 /*
  * Search for a gap in the e820 memory space from start_addr to end_addr.
  */
-__init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
+static int __init
+e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
 		unsigned long start_addr, unsigned long long end_addr)
 {
 	unsigned long long last;
@@ -726,37 +391,6 @@ static int __init e820_mark_nvs_memory(void)
 core_initcall(e820_mark_nvs_memory);
 #endif
 
-/*
- * Find a free area with specified alignment in a specific range.
- */
-u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 addr;
-		u64 ei_start, ei_last;
-
-		if (ei->type != E820_RAM)
-			continue;
-
-		ei_last = ei->addr + ei->size;
-		ei_start = ei->addr;
-		addr = find_early_area(ei_start, ei_last, start, end,
-					 size, align);
-
-		if (addr != -1ULL)
-			return addr;
-	}
-	return -1ULL;
-}
-
-u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
-{
-	return find_e820_area(start, end, size, align);
-}
-
 u64 __init get_max_mapped(void)
 {
 	u64 end = max_pfn_mapped;
@@ -765,6 +399,7 @@ u64 __init get_max_mapped(void)
 
 	return end;
 }
+
 /*
  * Find next free range after *start
  */
@@ -792,21 +427,6 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
 	return -1ULL;
 }
 
-u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
-{
-	u64 addr;
-	/*
-	 * need to call this function after e820_register_active_regions
-	 * so early_node_map[] is set
-	 */
-	addr = find_memory_core_early(nid, size, align, start, end);
-	if (addr != -1ULL)
-		return addr;
-
-	/* fallback, should already have start end in the node range */
-	return find_e820_area(start, end, size, align);
-}
-
 /*
  * pre allocated 4k and reserved it in e820
  */
@@ -843,220 +463,6 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
 	return addr;
 }
 
-#ifdef CONFIG_X86_32
-# ifdef CONFIG_X86_PAE
-#  define MAX_ARCH_PFN		(1ULL<<(36-PAGE_SHIFT))
-# else
-#  define MAX_ARCH_PFN		(1ULL<<(32-PAGE_SHIFT))
-# endif
-#else /* CONFIG_X86_32 */
-# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
-#endif
-
-/*
- * Find the highest page frame number we have available
- */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
-{
-	int i;
-	unsigned long last_pfn = 0;
-	unsigned long max_arch_pfn = MAX_ARCH_PFN;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		unsigned long start_pfn;
-		unsigned long end_pfn;
-
-		if (ei->type != type)
-			continue;
-
-		start_pfn = ei->addr >> PAGE_SHIFT;
-		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
-
-		if (start_pfn >= limit_pfn)
-			continue;
-		if (end_pfn > limit_pfn) {
-			last_pfn = limit_pfn;
-			break;
-		}
-		if (end_pfn > last_pfn)
-			last_pfn = end_pfn;
-	}
-
-	if (last_pfn > max_arch_pfn)
-		last_pfn = max_arch_pfn;
-
-	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
-			 last_pfn, max_arch_pfn);
-	return last_pfn;
-}
-unsigned long __init e820_end_of_ram_pfn(void)
-{
-	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
-}
-
-unsigned long __init e820_end_of_low_ram_pfn(void)
-{
-	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
-}
-/*
- * Finds an active region in the address range from start_pfn to last_pfn and
- * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
- */
-int __init e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn)
-{
-	u64 align = PAGE_SIZE;
-
-	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
-	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
-
-	/* Skip map entries smaller than a page */
-	if (*ei_startpfn >= *ei_endpfn)
-		return 0;
-
-	/* Skip if map is outside the node */
-	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
-				    *ei_startpfn >= last_pfn)
-		return 0;
-
-	/* Check for overlaps */
-	if (*ei_startpfn < start_pfn)
-		*ei_startpfn = start_pfn;
-	if (*ei_endpfn > last_pfn)
-		*ei_endpfn = last_pfn;
-
-	return 1;
-}
-
-/* Walk the e820 map and register active regions within a node */
-void __init e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long last_pfn)
-{
-	unsigned long ei_startpfn;
-	unsigned long ei_endpfn;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++)
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			add_active_range(nid, ei_startpfn, ei_endpfn);
-}
-
-/*
- * Find the hole size (in bytes) in the memory range.
- * @start: starting address of the memory range to scan
- * @end: ending address of the memory range to scan
- */
-u64 __init e820_hole_size(u64 start, u64 end)
-{
-	unsigned long start_pfn = start >> PAGE_SHIFT;
-	unsigned long last_pfn = end >> PAGE_SHIFT;
-	unsigned long ei_startpfn, ei_endpfn, ram = 0;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			ram += ei_endpfn - ei_startpfn;
-	}
-	return end - start - ((u64)ram << PAGE_SHIFT);
-}
-
-static void early_panic(char *msg)
-{
-	early_printk(msg);
-	panic(msg);
-}
-
-static int userdef __initdata;
-
-/* "mem=nopentium" disables the 4MB page tables. */
-static int __init parse_memopt(char *p)
-{
-	u64 mem_size;
-
-	if (!p)
-		return -EINVAL;
-
-#ifdef CONFIG_X86_32
-	if (!strcmp(p, "nopentium")) {
-		setup_clear_cpu_cap(X86_FEATURE_PSE);
-		return 0;
-	}
-#endif
-
-	userdef = 1;
-	mem_size = memparse(p, &p);
-	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
-
-	return 0;
-}
-early_param("mem", parse_memopt);
-
-static int __init parse_memmap_opt(char *p)
-{
-	char *oldp;
-	u64 start_at, mem_size;
-
-	if (!p)
-		return -EINVAL;
-
-	if (!strncmp(p, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-		/*
-		 * If we are doing a crash dump, we still need to know
-		 * the real mem size before original memory map is
-		 * reset.
-		 */
-		saved_max_pfn = e820_end_of_ram_pfn();
-#endif
-		e820.nr_map = 0;
-		userdef = 1;
-		return 0;
-	}
-
-	oldp = p;
-	mem_size = memparse(p, &p);
-	if (p == oldp)
-		return -EINVAL;
-
-	userdef = 1;
-	if (*p == '@') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RAM);
-	} else if (*p == '#') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_ACPI);
-	} else if (*p == '$') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RESERVED);
-	} else
-		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
-
-	return *p == '\0' ? 0 : -EINVAL;
-}
-early_param("memmap", parse_memmap_opt);
-
-void __init finish_e820_parsing(void)
-{
-	if (userdef) {
-		u32 nr = e820.nr_map;
-
-		if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
-			early_panic("Invalid user supplied memory map");
-		e820.nr_map = nr;
-
-		printk(KERN_INFO "user-defined physical RAM map:\n");
-		e820_print_map("user");
-	}
-}
-
 static inline const char *e820_type_to_string(int e820_type)
 {
 	switch (e820_type) {
@@ -1098,7 +504,8 @@ void __init e820_reserve_resources(void)
 		 * pci device BAR resource and insert them later in
 		 * pcibios_resource_survey()
 		 */
-		if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
+		if (e820.map[i].type != E820_RESERVED ||
+		    res->start < (1ULL<<20)) {
 			res->flags |= IORESOURCE_BUSY;
 			insert_resource(&iomem_resource, res);
 		}
@@ -1114,7 +521,7 @@ void __init e820_reserve_resources(void)
 }
 
 /* How much should we pad RAM ending depending on where it is? */
-static unsigned long ram_alignment(resource_size_t pos)
+static unsigned long __init ram_alignment(resource_size_t pos)
 {
 	unsigned long mb = pos >> 20;
 
@@ -1196,7 +603,7 @@ char *__init default_machine_specific_memory_setup(void)
 			who = "BIOS-e801";
 		}
 
-		e820.nr_map = 0;
+		clear_e820_map();
 		e820_add_region(0, LOWMEMSIZE(), E820_RAM);
 		e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
 	}
@@ -1204,7 +611,6 @@ char *__init default_machine_specific_memory_setup(void)
 	/* In case someone cares... */
 	return who;
 }
-
 void __init save_e820_map(void)
 {
 	memcpy(&e820_saved, &e820, sizeof(struct e820map));
@@ -1221,20 +627,18 @@ void __init setup_memory_map(void)
 }
 
 #ifdef CONFIG_X86_OOSTORE
+
 /*
  * Figure what we can cover with MCR's
  *
  * Shortcut: We know you can't put 4Gig of RAM on a winchip
  */
-void __init get_centaur_ram_top(void)
+static void __init __get_special_low_ram_top(void)
 {
 	u32 clip = 0xFFFFFFFFUL;
 	u32 top = 0;
 	int i;
 
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
-		return;
-
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long start, end;
 
@@ -1272,7 +676,15 @@ void __init get_centaur_ram_top(void)
 	if (top > clip)
 		top = clip;
 
-	centaur_ram_top = top;
+	return top;
 }
-#endif
 
+int centaur_ram_top;
+void __init get_centaur_ram_top(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
+		return;
+
+	centaur_ram_top = __get_special_low_ram_top();
+}
+#endif
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 266ab92..c341c18 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -6,7 +6,7 @@
 
 #include <linux/mmzone.h>
 #include <asm/dma.h>
-
+#include <linux/early_res.h>
 /*
  *  simple boot-time physical memory area allocator.
  */
diff --git a/include/linux/early_res.h b/include/linux/early_res.h
index 29c09f5..0f4590f 100644
--- a/include/linux/early_res.h
+++ b/include/linux/early_res.h
@@ -14,6 +14,7 @@ u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
 u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
 			 u64 *sizep, u64 align);
 u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
+u64 find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
 u64 get_max_mapped(void);
 #include <linux/range.h>
 int get_free_all_memory_range(struct range **rangep, int nodeid);
diff --git a/include/linux/fw_memmap.h b/include/linux/fw_memmap.h
new file mode 100644
index 0000000..e0fcc1b
--- /dev/null
+++ b/include/linux/fw_memmap.h
@@ -0,0 +1,40 @@
+#ifndef _LINUX_FW_MEMMAP_H
+#define _LINUX_FW_MEMMAP_H
+#define E820MAX	128		/* number of entries in E820MAP */
+
+#define FW_MEMMAP_RAM	1
+#define FW_MEMMAP_RESERVED	2
+
+#define E820_RAM	FW_MEMMAP_RAM
+#define E820_RESERVED	FW_MEMMAP_RESERVED
+
+#define E820_ACPI	3
+#define E820_NVS	4
+#define E820_UNUSABLE	5
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+struct e820entry {
+	__u64 addr;	/* start of memory segment */
+	__u64 size;	/* size of memory segment */
+	__u32 type;	/* type of memory segment */
+} __attribute__((packed));
+
+#ifdef __KERNEL__
+
+void fw_memmap_add_region(u64 start, u64 size, int type);
+void fw_memmap_print_map(char *who);
+int sanitize_fw_memmap(void);
+void finish_fw_memmap_parsing(void);
+
+#include <linux/early_res.h>
+
+unsigned long fw_memmap_end_of_ram_pfn(void);
+void fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long end_pfn);
+u64 fw_memmap_hole_size(u64 start, u64 end);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_FW_MEMMAP_H */
diff --git a/kernel/Makefile b/kernel/Makefile
index d5c3006..b0afaa5 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
 	    notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
 	    async.o range.o
-obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o
+obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o fw_memmap.o
 obj-y += groups.o
 
 ifdef CONFIG_FUNCTION_TRACER
diff --git a/kernel/fw_memmap.c b/kernel/fw_memmap.c
new file mode 100644
index 0000000..11067f3
--- /dev/null
+++ b/kernel/fw_memmap.c
@@ -0,0 +1,625 @@
+/*
+ * Handle the memory map.
+ * The functions here do the job until bootmem takes over.
+ *
+ *  Getting sanitize_e820_map() in sync with i386 version by applying change:
+ *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
+ *     Alex Achenbach <xela@slit.de>, December 2002.
+ *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/suspend.h>
+#include <linux/ioport.h>
+
+#include <linux/fw_memmap.h>
+#include "fw_memmap_internals.h"
+
+/*
+ * The e820 map is the map that gets modified e.g. with command line parameters
+ * and that is also registered with modifications in the kernel resource tree
+ * with the iomem_resource as parent.
+ */
+struct e820map __initdata e820;
+
+/*
+ * Add a memory region to the kernel e820 map.
+ */
+void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
+					 int type)
+{
+	int x = e820x->nr_map;
+
+	if (x >= ARRAY_SIZE(e820x->map)) {
+		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+		return;
+	}
+
+	e820x->map[x].addr = start;
+	e820x->map[x].size = size;
+	e820x->map[x].type = type;
+	e820x->nr_map++;
+}
+
+void __init fw_memmap_add_region(u64 start, u64 size, int type)
+{
+	__e820_add_region(&e820, start, size, type);
+}
+
+/* make e820 not cover the range */
+u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
+			     int checktype)
+{
+	int i;
+	u64 end;
+	u64 real_removed_size = 0;
+
+	if (size > (ULLONG_MAX - start))
+		size = ULLONG_MAX - start;
+
+	end = start + size;
+	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
+		       (unsigned long long) start,
+		       (unsigned long long) end);
+	e820_print_type(old_type);
+	printk(KERN_CONT "\n");
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		u64 final_start, final_end;
+
+		if (checktype && ei->type != old_type)
+			continue;
+		/* totally covered? */
+		if (ei->addr >= start &&
+		    (ei->addr + ei->size) <= (start + size)) {
+			real_removed_size += ei->size;
+			memset(ei, 0, sizeof(struct e820entry));
+			continue;
+		}
+		/* partially covered */
+		final_start = max(start, ei->addr);
+		final_end = min(start + size, ei->addr + ei->size);
+		if (final_start >= final_end)
+			continue;
+		real_removed_size += final_end - final_start;
+
+		ei->size -= final_end - final_start;
+		if (ei->addr < final_start)
+			continue;
+		ei->addr = final_end;
+	}
+	return real_removed_size;
+}
+
+void __init e820_print_type(u32 type)
+{
+	switch (type) {
+	case E820_RAM:
+	case E820_RESERVED_KERN:
+		printk(KERN_CONT "(usable)");
+		break;
+	case E820_RESERVED:
+		printk(KERN_CONT "(reserved)");
+		break;
+	case E820_ACPI:
+		printk(KERN_CONT "(ACPI data)");
+		break;
+	case E820_NVS:
+		printk(KERN_CONT "(ACPI NVS)");
+		break;
+	case E820_UNUSABLE:
+		printk(KERN_CONT "(unusable)");
+		break;
+	default:
+		printk(KERN_CONT "type %u", type);
+		break;
+	}
+}
+
+void __init fw_memmap_print_map(char *who)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
+		       (unsigned long long) e820.map[i].addr,
+		       (unsigned long long)
+		       (e820.map[i].addr + e820.map[i].size));
+		e820_print_type(e820.map[i].type);
+		printk(KERN_CONT "\n");
+	}
+}
+
+/*
+ * Sanitize the BIOS e820 map.
+ *
+ * Some e820 responses include overlapping entries. The following
+ * replaces the original e820 map with a new one, removing overlaps,
+ * and resolving conflicting memory types in favor of highest
+ * numbered type.
+ *
+ * The input parameter biosmap points to an array of 'struct
+ * e820entry' which on entry has elements in the range [0, *pnr_map)
+ * valid, and which has space for up to max_nr_map entries.
+ * On return, the resulting sanitized e820 map entries will be in
+ * overwritten in the same location, starting at biosmap.
+ *
+ * The integer pointed to by pnr_map must be valid on entry (the
+ * current number of valid entries located at biosmap) and will
+ * be updated on return, with the new number of valid entries
+ * (something no more than max_nr_map.)
+ *
+ * The return value from sanitize_e820_map() is zero if it
+ * successfully 'sanitized' the map entries passed in, and is -1
+ * if it did nothing, which can happen if either of (1) it was
+ * only passed one map entry, or (2) any of the input map entries
+ * were invalid (start + size < start, meaning that the size was
+ * so big the described memory range wrapped around through zero.)
+ *
+ *	Visually we're performing the following
+ *	(1,2,3,4 = memory types)...
+ *
+ *	Sample memory map (w/overlaps):
+ *	   ____22__________________
+ *	   ______________________4_
+ *	   ____1111________________
+ *	   _44_____________________
+ *	   11111111________________
+ *	   ____________________33__
+ *	   ___________44___________
+ *	   __________33333_________
+ *	   ______________22________
+ *	   ___________________2222_
+ *	   _________111111111______
+ *	   _____________________11_
+ *	   _________________4______
+ *
+ *	Sanitized equivalent (no overlap):
+ *	   1_______________________
+ *	   _44_____________________
+ *	   ___1____________________
+ *	   ____22__________________
+ *	   ______11________________
+ *	   _________1______________
+ *	   __________3_____________
+ *	   ___________44___________
+ *	   _____________33_________
+ *	   _______________2________
+ *	   ________________1_______
+ *	   _________________4______
+ *	   ___________________2____
+ *	   ____________________33__
+ *	   ______________________4_
+ */
+
+int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+			     u32 *pnr_map)
+{
+	struct change_member {
+		struct e820entry *pbios; /* pointer to original bios entry */
+		unsigned long long addr; /* address for this change point */
+	};
+	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
+	static struct change_member *change_point[2*E820_X_MAX] __initdata;
+	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
+	static struct e820entry new_bios[E820_X_MAX] __initdata;
+	struct change_member *change_tmp;
+	unsigned long current_type, last_type;
+	unsigned long long last_addr;
+	int chgidx, still_changing;
+	int overlap_entries;
+	int new_bios_entry;
+	int old_nr, new_nr, chg_nr;
+	int i;
+
+	/* if there's only one memory region, don't bother */
+	if (*pnr_map < 2)
+		return -1;
+
+	old_nr = *pnr_map;
+	BUG_ON(old_nr > max_nr_map);
+
+	/* bail out if we find any unreasonable addresses in bios map */
+	for (i = 0; i < old_nr; i++)
+		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+			return -1;
+
+	/* create pointers for initial change-point information (for sorting) */
+	for (i = 0; i < 2 * old_nr; i++)
+		change_point[i] = &change_point_list[i];
+
+	/* record all known change-points (starting and ending addresses),
+	   omitting those that are for empty memory regions */
+	chgidx = 0;
+	for (i = 0; i < old_nr; i++)	{
+		if (biosmap[i].size != 0) {
+			change_point[chgidx]->addr = biosmap[i].addr;
+			change_point[chgidx++]->pbios = &biosmap[i];
+			change_point[chgidx]->addr = biosmap[i].addr +
+				biosmap[i].size;
+			change_point[chgidx++]->pbios = &biosmap[i];
+		}
+	}
+	chg_nr = chgidx;
+
+	/* sort change-point list by memory addresses (low -> high) */
+	still_changing = 1;
+	while (still_changing)	{
+		still_changing = 0;
+		for (i = 1; i < chg_nr; i++)  {
+			unsigned long long curaddr, lastaddr;
+			unsigned long long curpbaddr, lastpbaddr;
+
+			curaddr = change_point[i]->addr;
+			lastaddr = change_point[i - 1]->addr;
+			curpbaddr = change_point[i]->pbios->addr;
+			lastpbaddr = change_point[i - 1]->pbios->addr;
+
+			/*
+			 * swap entries, when:
+			 *
+			 * curaddr > lastaddr or
+			 * curaddr == lastaddr and curaddr == curpbaddr and
+			 * lastaddr != lastpbaddr
+			 */
+			if (curaddr < lastaddr ||
+			    (curaddr == lastaddr && curaddr == curpbaddr &&
+			     lastaddr != lastpbaddr)) {
+				change_tmp = change_point[i];
+				change_point[i] = change_point[i-1];
+				change_point[i-1] = change_tmp;
+				still_changing = 1;
+			}
+		}
+	}
+
+	/* create a new bios memory map, removing overlaps */
+	overlap_entries = 0;	 /* number of entries in the overlap table */
+	new_bios_entry = 0;	 /* index for creating new bios map entries */
+	last_type = 0;		 /* start with undefined memory type */
+	last_addr = 0;		 /* start with 0 as last starting address */
+
+	/* loop through change-points, determining affect on the new bios map */
+	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
+		/* keep track of all overlapping bios entries */
+		if (change_point[chgidx]->addr ==
+		    change_point[chgidx]->pbios->addr) {
+			/*
+			 * add map entry to overlap list (> 1 entry
+			 * implies an overlap)
+			 */
+			overlap_list[overlap_entries++] =
+				change_point[chgidx]->pbios;
+		} else {
+			/*
+			 * remove entry from list (order independent,
+			 * so swap with last)
+			 */
+			for (i = 0; i < overlap_entries; i++) {
+				if (overlap_list[i] ==
+				    change_point[chgidx]->pbios)
+					overlap_list[i] =
+						overlap_list[overlap_entries-1];
+			}
+			overlap_entries--;
+		}
+		/*
+		 * if there are overlapping entries, decide which
+		 * "type" to use (larger value takes precedence --
+		 * 1=usable, 2,3,4,4+=unusable)
+		 */
+		current_type = 0;
+		for (i = 0; i < overlap_entries; i++)
+			if (overlap_list[i]->type > current_type)
+				current_type = overlap_list[i]->type;
+		/*
+		 * continue building up new bios map based on this
+		 * information
+		 */
+		if (current_type != last_type)	{
+			if (last_type != 0)	 {
+				new_bios[new_bios_entry].size =
+					change_point[chgidx]->addr - last_addr;
+				/*
+				 * move forward only if the new size
+				 * was non-zero
+				 */
+				if (new_bios[new_bios_entry].size != 0)
+					/*
+					 * no more space left for new
+					 * bios entries ?
+					 */
+					if (++new_bios_entry >= max_nr_map)
+						break;
+			}
+			if (current_type != 0)	{
+				new_bios[new_bios_entry].addr =
+					change_point[chgidx]->addr;
+				new_bios[new_bios_entry].type = current_type;
+				last_addr = change_point[chgidx]->addr;
+			}
+			last_type = current_type;
+		}
+	}
+	/* retain count for new bios entries */
+	new_nr = new_bios_entry;
+
+	/* copy new bios mapping into original location */
+	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
+	*pnr_map = new_nr;
+
+	return 0;
+}
+
+int __init sanitize_fw_memmap(void)
+{
+	int max_nr_map = ARRAY_SIZE(e820.map);
+
+	return __sanitize_e820_map(e820.map, max_nr_map, &e820.nr_map);
+}
+
+void __init clear_e820_map(void)
+{
+	e820.nr_map = 0;
+}
+
+static int userdef __initdata;
+
+/* "mem=nopentium" disables the 4MB page tables. */
+static int __init parse_memopt(char *p)
+{
+	u64 mem_size;
+
+	if (!p)
+		return -EINVAL;
+
+#ifdef CONFIG_X86_32
+	if (!strcmp(p, "nopentium")) {
+		setup_clear_cpu_cap(X86_FEATURE_PSE);
+		return 0;
+	}
+#endif
+
+	userdef = 1;
+	mem_size = memparse(p, &p);
+	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
+	return 0;
+}
+early_param("mem", parse_memopt);
+
+static int __init parse_memmap_opt(char *p)
+{
+	char *oldp;
+	u64 start_at, mem_size;
+
+	if (!p)
+		return -EINVAL;
+
+	if (!strncmp(p, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+		/*
+		 * If we are doing a crash dump, we still need to know
+		 * the real mem size before original memory map is
+		 * reset.
+		 */
+		saved_max_pfn = fw_memmap_end_of_ram_pfn();
+#endif
+		e820.nr_map = 0;
+		userdef = 1;
+		return 0;
+	}
+
+	oldp = p;
+	mem_size = memparse(p, &p);
+	if (p == oldp)
+		return -EINVAL;
+
+	userdef = 1;
+	if (*p == '@') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_RAM);
+	} else if (*p == '#') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_ACPI);
+	} else if (*p == '$') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_RESERVED);
+	} else
+		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
+	return *p == '\0' ? 0 : -EINVAL;
+}
+early_param("memmap", parse_memmap_opt);
+
+static void early_panic(char *msg)
+{
+	early_printk(msg);
+	panic(msg);
+}
+
+void __init finish_fw_memmap_parsing(void)
+{
+	if (userdef) {
+		u32 nr = e820.nr_map;
+		int max_nr_map = ARRAY_SIZE(e820.map);
+
+		if (__sanitize_e820_map(e820.map, max_nr_map, &nr) < 0)
+			early_panic("Invalid user supplied memory map");
+		e820.nr_map = nr;
+
+		printk(KERN_INFO "user-defined physical RAM map:\n");
+		e820_print_map("user");
+	}
+}
+
+/*
+ * Find a free area with specified alignment in a specific range.
+ */
+u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		u64 addr;
+		u64 ei_start, ei_last;
+
+		if (ei->type != E820_RAM)
+			continue;
+
+		ei_last = ei->addr + ei->size;
+		ei_start = ei->addr;
+		addr = find_early_area(ei_start, ei_last, start, end,
+					 size, align);
+
+		if (addr != -1ULL)
+			return addr;
+	}
+	return -1ULL;
+}
+
+u64 __init
+find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	u64 addr;
+	/*
+	 * need to call this function after e820_register_active_regions
+	 * so early_node_map[] is set
+	 */
+	addr = find_memory_core_early(nid, size, align, start, end);
+	if (addr != -1ULL)
+		return addr;
+
+	/* fallback, should already have start end in the node range */
+	return find_fw_memmap_area(start, end, size, align);
+}
+
+#ifdef CONFIG_X86_32
+# ifdef CONFIG_X86_PAE
+#  define MAX_ARCH_PFN	(1ULL<<(36-PAGE_SHIFT))
+# else
+#  define MAX_ARCH_PFN	(1ULL<<(32-PAGE_SHIFT))
+# endif
+#else /* CONFIG_X86_32 */
+# define MAX_ARCH_PFN	(MAXMEM>>PAGE_SHIFT)
+#endif
+
+/*
+ * Find the highest page frame number we have available
+ */
+static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+{
+	int i;
+	unsigned long last_pfn = 0;
+	unsigned long max_arch_pfn = MAX_ARCH_PFN;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		unsigned long start_pfn;
+		unsigned long end_pfn;
+
+		if (ei->type != type)
+			continue;
+
+		start_pfn = ei->addr >> PAGE_SHIFT;
+		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
+
+		if (start_pfn >= limit_pfn)
+			continue;
+		if (end_pfn > limit_pfn) {
+			last_pfn = limit_pfn;
+			break;
+		}
+		if (end_pfn > last_pfn)
+			last_pfn = end_pfn;
+	}
+
+	if (last_pfn > max_arch_pfn)
+		last_pfn = max_arch_pfn;
+
+	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
+			 last_pfn, max_arch_pfn);
+	return last_pfn;
+}
+unsigned long __init fw_memmap_end_of_ram_pfn(void)
+{
+	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+}
+
+unsigned long __init e820_end_of_low_ram_pfn(void)
+{
+	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
+}
+/*
+ * Finds an active region in the address range from start_pfn to last_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
+ */
+static int __init e820_find_active_region(const struct e820entry *ei,
+				  unsigned long start_pfn,
+				  unsigned long last_pfn,
+				  unsigned long *ei_startpfn,
+				  unsigned long *ei_endpfn)
+{
+	u64 align = PAGE_SIZE;
+
+	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
+	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
+
+	/* Skip map entries smaller than a page */
+	if (*ei_startpfn >= *ei_endpfn)
+		return 0;
+
+	/* Skip if map is outside the node */
+	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
+				    *ei_startpfn >= last_pfn)
+		return 0;
+
+	/* Check for overlaps */
+	if (*ei_startpfn < start_pfn)
+		*ei_startpfn = start_pfn;
+	if (*ei_endpfn > last_pfn)
+		*ei_endpfn = last_pfn;
+
+	return 1;
+}
+
+/* Walk the e820 map and register active regions within a node */
+void __init fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long last_pfn)
+{
+	unsigned long ei_startpfn;
+	unsigned long ei_endpfn;
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++)
+		if (e820_find_active_region(&e820.map[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			add_active_range(nid, ei_startpfn, ei_endpfn);
+}
+
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+u64 __init fw_memmap_hole_size(u64 start, u64 end)
+{
+	unsigned long start_pfn = start >> PAGE_SHIFT;
+	unsigned long last_pfn = end >> PAGE_SHIFT;
+	unsigned long ei_startpfn, ei_endpfn, ram = 0;
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		if (e820_find_active_region(&e820.map[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			ram += ei_endpfn - ei_startpfn;
+	}
+	return end - start - ((u64)ram << PAGE_SHIFT);
+}
diff --git a/kernel/fw_memmap_internals.h b/kernel/fw_memmap_internals.h
new file mode 100644
index 0000000..f217602
--- /dev/null
+++ b/kernel/fw_memmap_internals.h
@@ -0,0 +1,49 @@
+#ifndef __KERNEL_FW_MEMMAP_INTERNALS_H
+#define __KERNEL_FW_MEMMAP_INTERNALS_H
+
+/*
+ * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
+ * constrained space in the zeropage.  If we have more nodes than
+ * that, and if we've booted off EFI firmware, then the EFI tables
+ * passed us from the EFI firmware can list more nodes.  Size our
+ * internal memory map tables to have room for these additional
+ * nodes, based on up to three entries per node for which the
+ * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
+ * plus E820MAX, allowing space for the possible duplicate E820
+ * entries that might need room in the same arrays, prior to the
+ * call to sanitize_e820_map() to remove duplicates.  The allowance
+ * of three memory map entries per node is "enough" entries for
+ * the initial hardware platform motivating this mechanism to make
+ * use of additional EFI map entries.  Future platforms may want
+ * to allow more than three entries per node or otherwise refine
+ * this size.
+ */
+
+/*
+ * Odd: 'make headers_check' complains about numa.h if I try
+ * to collapse the next two #ifdef lines to a single line:
+ *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
+ */
+#ifdef __KERNEL__
+#ifdef CONFIG_EFI
+#include <linux/numa.h>
+#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
+#else	/* ! CONFIG_EFI */
+#define E820_X_MAX E820MAX
+#endif
+#else	/* ! __KERNEL__ */
+#define E820_X_MAX E820MAX
+#endif
+
+#ifndef __ASSEMBLY__
+struct e820map {
+	__u32 nr_map;
+	struct e820entry map[E820_X_MAX];
+};
+#endif
+
+extern struct e820map __initdata e820;
+void e820_print_type(u32 type);
+void __e820_add_region(struct e820map *e820x, u64 start, u64 size, int type);
+
+#endif
-- 
1.6.4.2


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

* [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

move it to kernel/fw_memmap.c from arch/x86/kernel/e820.c

-v2: add fw_memmap wrapper to some func...
     move some functions back to e820.c

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/e820.h  |  176 ++++++-------
 arch/x86/kernel/e820.c       |  638 ++----------------------------------------
 include/linux/bootmem.h      |    2 +-
 include/linux/early_res.h    |    1 +
 include/linux/fw_memmap.h    |   40 +++
 kernel/Makefile              |    2 +-
 kernel/fw_memmap.c           |  625 +++++++++++++++++++++++++++++++++++++++++
 kernel/fw_memmap_internals.h |   49 ++++
 8 files changed, 822 insertions(+), 711 deletions(-)
 create mode 100644 include/linux/fw_memmap.h
 create mode 100644 kernel/fw_memmap.c
 create mode 100644 kernel/fw_memmap_internals.h

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 71c0348..c038616 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -1,65 +1,10 @@
 #ifndef _ASM_X86_E820_H
 #define _ASM_X86_E820_H
-#define E820MAP	0x2d0		/* our map */
-#define E820MAX	128		/* number of entries in E820MAP */
-
-/*
- * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
- * constrained space in the zeropage.  If we have more nodes than
- * that, and if we've booted off EFI firmware, then the EFI tables
- * passed us from the EFI firmware can list more nodes.  Size our
- * internal memory map tables to have room for these additional
- * nodes, based on up to three entries per node for which the
- * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
- * plus E820MAX, allowing space for the possible duplicate E820
- * entries that might need room in the same arrays, prior to the
- * call to sanitize_e820_map() to remove duplicates.  The allowance
- * of three memory map entries per node is "enough" entries for
- * the initial hardware platform motivating this mechanism to make
- * use of additional EFI map entries.  Future platforms may want
- * to allow more than three entries per node or otherwise refine
- * this size.
- */
-
-/*
- * Odd: 'make headers_check' complains about numa.h if I try
- * to collapse the next two #ifdef lines to a single line:
- *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
- */
-#ifdef __KERNEL__
-#ifdef CONFIG_EFI
-#include <linux/numa.h>
-#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
-#else	/* ! CONFIG_EFI */
-#define E820_X_MAX E820MAX
-#endif
-#else	/* ! __KERNEL__ */
-#define E820_X_MAX E820MAX
-#endif
-
-#define E820NR	0x1e8		/* # entries in E820MAP */
-
-#define E820_RAM	1
-#define E820_RESERVED	2
-#define E820_ACPI	3
-#define E820_NVS	4
-#define E820_UNUSABLE	5
 
 /* reserved RAM used by kernel itself */
 #define E820_RESERVED_KERN        128
 
 #ifndef __ASSEMBLY__
-#include <linux/types.h>
-struct e820entry {
-	__u64 addr;	/* start of memory segment */
-	__u64 size;	/* size of memory segment */
-	__u32 type;	/* type of memory segment */
-} __attribute__((packed));
-
-struct e820map {
-	__u32 nr_map;
-	struct e820entry map[E820_X_MAX];
-};
 
 #define ISA_START_ADDRESS	0xa0000
 #define ISA_END_ADDRESS		0x100000
@@ -69,32 +14,18 @@ struct e820map {
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_X86_OOSTORE
-extern int centaur_ram_top;
-void get_centaur_ram_top(void);
+#include <linux/fw_memmap.h>
+
+#ifdef CONFIG_MEMTEST
+extern void early_memtest(unsigned long start, unsigned long end);
 #else
-static inline void get_centaur_ram_top(void)
+static inline void early_memtest(unsigned long start, unsigned long end)
 {
 }
 #endif
 
 extern unsigned long pci_mem_start;
-extern int e820_any_mapped(u64 start, u64 end, unsigned type);
-extern int e820_all_mapped(u64 start, u64 end, unsigned type);
-extern void e820_add_region(u64 start, u64 size, int type);
-extern void e820_print_map(char *who);
-int sanitize_e820_map(void);
-void save_e820_map(void);
-extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
-			       unsigned new_type);
-extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype);
-extern void update_e820(void);
 extern void e820_setup_gap(void);
-extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
-			unsigned long start_addr, unsigned long long end_addr);
-struct setup_data;
-extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
 
 #if defined(CONFIG_X86_64) || \
 	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
@@ -105,37 +36,80 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
 }
 #endif
 
-#ifdef CONFIG_MEMTEST
-extern void early_memtest(unsigned long start, unsigned long end);
-#else
-static inline void early_memtest(unsigned long start, unsigned long end)
+static inline void e820_add_region(u64 start, u64 size, int type)
 {
+	fw_memmap_add_region(start, size, type);
+}
+
+static inline void e820_print_map(char *who)
+{
+	fw_memmap_print_map(who);
+}
+
+static inline int sanitize_e820_map(void)
+{
+	return sanitize_fw_memmap();
+}
+
+static inline void finish_e820_parsing(void)
+{
+	finish_fw_memmap_parsing();
+}
+
+static inline void e820_register_active_regions(int nid,
+						unsigned long start_pfn,
+						unsigned long end_pfn)
+{
+	fw_memmap_register_active_regions(nid, start_pfn, end_pfn);
+}
+
+static inline u64 e820_hole_size(u64 start, u64 end)
+{
+	return fw_memmap_hole_size(start, end);
+}
+
+static inline u64 find_e820_area(u64 start, u64 end, u64 size, u64 align)
+{
+	return find_fw_memmap_area(start, end, size, align);
+}
+
+static inline u64 find_e820_area_node(int nid, u64 start, u64 end,
+					 u64 size, u64 align)
+{
+	return find_fw_memmap_area_node(nid, start, end, size, align);
 }
-#endif
 
-extern unsigned long end_user_pfn;
+static inline unsigned long e820_end_of_ram_pfn(void)
+{
+	return fw_memmap_end_of_ram_pfn();
+}
+
+void clear_e820_map(void);
+
+extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
+				int checktype);
+struct e820entry;
+int __sanitize_e820_map(struct e820entry *biosmap, int max_nr, u32 *pnr_map);
+extern unsigned long e820_end_of_low_ram_pfn(void);
+
+extern int e820_any_mapped(u64 start, u64 end, unsigned type);
+extern int e820_all_mapped(u64 start, u64 end, unsigned type);
+extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
+			       unsigned new_type);
+
+extern void update_e820(void);
+void save_e820_map(void);
+struct setup_data;
+extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+extern char *default_machine_specific_memory_setup(void);
+extern void setup_memory_map(void);
 
-extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
 extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
-u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
+
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
-#include <linux/early_res.h>
 
-extern unsigned long e820_end_of_ram_pfn(void);
-extern unsigned long e820_end_of_low_ram_pfn(void);
-extern int e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn);
-extern void e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long end_pfn);
-extern u64 e820_hole_size(u64 start, u64 end);
-extern void finish_e820_parsing(void);
 extern void e820_reserve_resources(void);
 extern void e820_reserve_resources_late(void);
-extern void setup_memory_map(void);
-extern char *default_machine_specific_memory_setup(void);
 
 /*
  * Returns true iff the specified range [s,e) is completely contained inside
@@ -146,7 +120,17 @@ static inline bool is_ISA_range(u64 s, u64 e)
 	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
 }
 
+#ifdef CONFIG_X86_OOSTORE
+extern int centaur_ram_top;
+void get_centaur_ram_top(void);
+#else
+static inline void get_centaur_ram_top(void)
+{
+}
+#endif
+
 #endif /* __KERNEL__ */
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef __KERNEL__
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index a558609..9f125ca 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -12,18 +12,15 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
-#include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/firmware-map.h>
 
 #include <asm/e820.h>
-#include <asm/proto.h>
 #include <asm/setup.h>
 
+#include "../../../kernel/fw_memmap_internals.h"
+
 /*
- * The e820 map is the map that gets modified e.g. with command line parameters
- * and that is also registered with modifications in the kernel resource tree
- * with the iomem_resource as parent.
  *
  * The e820_saved is directly saved after the BIOS-provided memory map is
  * copied. It doesn't get modified afterwards. It's registered for the
@@ -34,7 +31,6 @@
  * user can e.g. boot the original kernel with mem=1G while still booting the
  * next kernel with full memory.
  */
-static struct e820map __initdata e820;
 static struct e820map __initdata e820_saved;
 
 /* For PCI or other memory-mapped resources */
@@ -99,295 +95,6 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type)
 	return 0;
 }
 
-/*
- * Add a memory region to the kernel e820 map.
- */
-static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
-					 int type)
-{
-	int x = e820x->nr_map;
-
-	if (x >= ARRAY_SIZE(e820x->map)) {
-		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-		return;
-	}
-
-	e820x->map[x].addr = start;
-	e820x->map[x].size = size;
-	e820x->map[x].type = type;
-	e820x->nr_map++;
-}
-
-void __init e820_add_region(u64 start, u64 size, int type)
-{
-	__e820_add_region(&e820, start, size, type);
-}
-
-static void __init e820_print_type(u32 type)
-{
-	switch (type) {
-	case E820_RAM:
-	case E820_RESERVED_KERN:
-		printk(KERN_CONT "(usable)");
-		break;
-	case E820_RESERVED:
-		printk(KERN_CONT "(reserved)");
-		break;
-	case E820_ACPI:
-		printk(KERN_CONT "(ACPI data)");
-		break;
-	case E820_NVS:
-		printk(KERN_CONT "(ACPI NVS)");
-		break;
-	case E820_UNUSABLE:
-		printk(KERN_CONT "(unusable)");
-		break;
-	default:
-		printk(KERN_CONT "type %u", type);
-		break;
-	}
-}
-
-void __init e820_print_map(char *who)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
-		       (unsigned long long) e820.map[i].addr,
-		       (unsigned long long)
-		       (e820.map[i].addr + e820.map[i].size));
-		e820_print_type(e820.map[i].type);
-		printk(KERN_CONT "\n");
-	}
-}
-
-/*
- * Sanitize the BIOS e820 map.
- *
- * Some e820 responses include overlapping entries. The following
- * replaces the original e820 map with a new one, removing overlaps,
- * and resolving conflicting memory types in favor of highest
- * numbered type.
- *
- * The input parameter biosmap points to an array of 'struct
- * e820entry' which on entry has elements in the range [0, *pnr_map)
- * valid, and which has space for up to max_nr_map entries.
- * On return, the resulting sanitized e820 map entries will be in
- * overwritten in the same location, starting at biosmap.
- *
- * The integer pointed to by pnr_map must be valid on entry (the
- * current number of valid entries located at biosmap) and will
- * be updated on return, with the new number of valid entries
- * (something no more than max_nr_map.)
- *
- * The return value from sanitize_e820_map() is zero if it
- * successfully 'sanitized' the map entries passed in, and is -1
- * if it did nothing, which can happen if either of (1) it was
- * only passed one map entry, or (2) any of the input map entries
- * were invalid (start + size < start, meaning that the size was
- * so big the described memory range wrapped around through zero.)
- *
- *	Visually we're performing the following
- *	(1,2,3,4 = memory types)...
- *
- *	Sample memory map (w/overlaps):
- *	   ____22__________________
- *	   ______________________4_
- *	   ____1111________________
- *	   _44_____________________
- *	   11111111________________
- *	   ____________________33__
- *	   ___________44___________
- *	   __________33333_________
- *	   ______________22________
- *	   ___________________2222_
- *	   _________111111111______
- *	   _____________________11_
- *	   _________________4______
- *
- *	Sanitized equivalent (no overlap):
- *	   1_______________________
- *	   _44_____________________
- *	   ___1____________________
- *	   ____22__________________
- *	   ______11________________
- *	   _________1______________
- *	   __________3_____________
- *	   ___________44___________
- *	   _____________33_________
- *	   _______________2________
- *	   ________________1_______
- *	   _________________4______
- *	   ___________________2____
- *	   ____________________33__
- *	   ______________________4_
- */
-
-static int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
-			     u32 *pnr_map)
-{
-	struct change_member {
-		struct e820entry *pbios; /* pointer to original bios entry */
-		unsigned long long addr; /* address for this change point */
-	};
-	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
-	static struct change_member *change_point[2*E820_X_MAX] __initdata;
-	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
-	static struct e820entry new_bios[E820_X_MAX] __initdata;
-	struct change_member *change_tmp;
-	unsigned long current_type, last_type;
-	unsigned long long last_addr;
-	int chgidx, still_changing;
-	int overlap_entries;
-	int new_bios_entry;
-	int old_nr, new_nr, chg_nr;
-	int i;
-
-	/* if there's only one memory region, don't bother */
-	if (*pnr_map < 2)
-		return -1;
-
-	old_nr = *pnr_map;
-	BUG_ON(old_nr > max_nr_map);
-
-	/* bail out if we find any unreasonable addresses in bios map */
-	for (i = 0; i < old_nr; i++)
-		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
-			return -1;
-
-	/* create pointers for initial change-point information (for sorting) */
-	for (i = 0; i < 2 * old_nr; i++)
-		change_point[i] = &change_point_list[i];
-
-	/* record all known change-points (starting and ending addresses),
-	   omitting those that are for empty memory regions */
-	chgidx = 0;
-	for (i = 0; i < old_nr; i++)	{
-		if (biosmap[i].size != 0) {
-			change_point[chgidx]->addr = biosmap[i].addr;
-			change_point[chgidx++]->pbios = &biosmap[i];
-			change_point[chgidx]->addr = biosmap[i].addr +
-				biosmap[i].size;
-			change_point[chgidx++]->pbios = &biosmap[i];
-		}
-	}
-	chg_nr = chgidx;
-
-	/* sort change-point list by memory addresses (low -> high) */
-	still_changing = 1;
-	while (still_changing)	{
-		still_changing = 0;
-		for (i = 1; i < chg_nr; i++)  {
-			unsigned long long curaddr, lastaddr;
-			unsigned long long curpbaddr, lastpbaddr;
-
-			curaddr = change_point[i]->addr;
-			lastaddr = change_point[i - 1]->addr;
-			curpbaddr = change_point[i]->pbios->addr;
-			lastpbaddr = change_point[i - 1]->pbios->addr;
-
-			/*
-			 * swap entries, when:
-			 *
-			 * curaddr > lastaddr or
-			 * curaddr == lastaddr and curaddr == curpbaddr and
-			 * lastaddr != lastpbaddr
-			 */
-			if (curaddr < lastaddr ||
-			    (curaddr == lastaddr && curaddr == curpbaddr &&
-			     lastaddr != lastpbaddr)) {
-				change_tmp = change_point[i];
-				change_point[i] = change_point[i-1];
-				change_point[i-1] = change_tmp;
-				still_changing = 1;
-			}
-		}
-	}
-
-	/* create a new bios memory map, removing overlaps */
-	overlap_entries = 0;	 /* number of entries in the overlap table */
-	new_bios_entry = 0;	 /* index for creating new bios map entries */
-	last_type = 0;		 /* start with undefined memory type */
-	last_addr = 0;		 /* start with 0 as last starting address */
-
-	/* loop through change-points, determining affect on the new bios map */
-	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
-		/* keep track of all overlapping bios entries */
-		if (change_point[chgidx]->addr ==
-		    change_point[chgidx]->pbios->addr) {
-			/*
-			 * add map entry to overlap list (> 1 entry
-			 * implies an overlap)
-			 */
-			overlap_list[overlap_entries++] =
-				change_point[chgidx]->pbios;
-		} else {
-			/*
-			 * remove entry from list (order independent,
-			 * so swap with last)
-			 */
-			for (i = 0; i < overlap_entries; i++) {
-				if (overlap_list[i] ==
-				    change_point[chgidx]->pbios)
-					overlap_list[i] =
-						overlap_list[overlap_entries-1];
-			}
-			overlap_entries--;
-		}
-		/*
-		 * if there are overlapping entries, decide which
-		 * "type" to use (larger value takes precedence --
-		 * 1=usable, 2,3,4,4+=unusable)
-		 */
-		current_type = 0;
-		for (i = 0; i < overlap_entries; i++)
-			if (overlap_list[i]->type > current_type)
-				current_type = overlap_list[i]->type;
-		/*
-		 * continue building up new bios map based on this
-		 * information
-		 */
-		if (current_type != last_type)	{
-			if (last_type != 0)	 {
-				new_bios[new_bios_entry].size =
-					change_point[chgidx]->addr - last_addr;
-				/*
-				 * move forward only if the new size
-				 * was non-zero
-				 */
-				if (new_bios[new_bios_entry].size != 0)
-					/*
-					 * no more space left for new
-					 * bios entries ?
-					 */
-					if (++new_bios_entry >= max_nr_map)
-						break;
-			}
-			if (current_type != 0)	{
-				new_bios[new_bios_entry].addr =
-					change_point[chgidx]->addr;
-				new_bios[new_bios_entry].type = current_type;
-				last_addr = change_point[chgidx]->addr;
-			}
-			last_type = current_type;
-		}
-	}
-	/* retain count for new bios entries */
-	new_nr = new_bios_entry;
-
-	/* copy new bios mapping into original location */
-	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
-	*pnr_map = new_nr;
-
-	return 0;
-}
-
-int __init sanitize_e820_map(void)
-{
-	return __sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-}
-
 static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
 {
 	while (nr_map) {
@@ -509,52 +216,6 @@ static u64 __init e820_update_range_saved(u64 start, u64 size,
 				     new_type);
 }
 
-/* make e820 not cover the range */
-u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
-			     int checktype)
-{
-	int i;
-	u64 end;
-	u64 real_removed_size = 0;
-
-	if (size > (ULLONG_MAX - start))
-		size = ULLONG_MAX - start;
-
-	end = start + size;
-	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
-		       (unsigned long long) start,
-		       (unsigned long long) end);
-	e820_print_type(old_type);
-	printk(KERN_CONT "\n");
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 final_start, final_end;
-
-		if (checktype && ei->type != old_type)
-			continue;
-		/* totally covered? */
-		if (ei->addr >= start &&
-		    (ei->addr + ei->size) <= (start + size)) {
-			real_removed_size += ei->size;
-			memset(ei, 0, sizeof(struct e820entry));
-			continue;
-		}
-		/* partially covered */
-		final_start = max(start, ei->addr);
-		final_end = min(start + size, ei->addr + ei->size);
-		if (final_start >= final_end)
-			continue;
-		real_removed_size += final_end - final_start;
-
-		ei->size -= final_end - final_start;
-		if (ei->addr < final_start)
-			continue;
-		ei->addr = final_end;
-	}
-	return real_removed_size;
-}
-
 void __init update_e820(void)
 {
 	u32 nr_map;
@@ -566,20 +227,24 @@ void __init update_e820(void)
 	printk(KERN_INFO "modified physical RAM map:\n");
 	e820_print_map("modified");
 }
+
 static void __init update_e820_saved(void)
 {
 	u32 nr_map;
+	int max_nr_map = ARRAY_SIZE(e820_saved.map);
 
 	nr_map = e820_saved.nr_map;
-	if (__sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
+	if (__sanitize_e820_map(e820_saved.map, max_nr_map, &nr_map))
 		return;
 	e820_saved.nr_map = nr_map;
 }
+
 #define MAX_GAP_END 0x100000000ull
 /*
  * Search for a gap in the e820 memory space from start_addr to end_addr.
  */
-__init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
+static int __init
+e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
 		unsigned long start_addr, unsigned long long end_addr)
 {
 	unsigned long long last;
@@ -726,37 +391,6 @@ static int __init e820_mark_nvs_memory(void)
 core_initcall(e820_mark_nvs_memory);
 #endif
 
-/*
- * Find a free area with specified alignment in a specific range.
- */
-u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 addr;
-		u64 ei_start, ei_last;
-
-		if (ei->type != E820_RAM)
-			continue;
-
-		ei_last = ei->addr + ei->size;
-		ei_start = ei->addr;
-		addr = find_early_area(ei_start, ei_last, start, end,
-					 size, align);
-
-		if (addr != -1ULL)
-			return addr;
-	}
-	return -1ULL;
-}
-
-u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
-{
-	return find_e820_area(start, end, size, align);
-}
-
 u64 __init get_max_mapped(void)
 {
 	u64 end = max_pfn_mapped;
@@ -765,6 +399,7 @@ u64 __init get_max_mapped(void)
 
 	return end;
 }
+
 /*
  * Find next free range after *start
  */
@@ -792,21 +427,6 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
 	return -1ULL;
 }
 
-u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
-{
-	u64 addr;
-	/*
-	 * need to call this function after e820_register_active_regions
-	 * so early_node_map[] is set
-	 */
-	addr = find_memory_core_early(nid, size, align, start, end);
-	if (addr != -1ULL)
-		return addr;
-
-	/* fallback, should already have start end in the node range */
-	return find_e820_area(start, end, size, align);
-}
-
 /*
  * pre allocated 4k and reserved it in e820
  */
@@ -843,220 +463,6 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
 	return addr;
 }
 
-#ifdef CONFIG_X86_32
-# ifdef CONFIG_X86_PAE
-#  define MAX_ARCH_PFN		(1ULL<<(36-PAGE_SHIFT))
-# else
-#  define MAX_ARCH_PFN		(1ULL<<(32-PAGE_SHIFT))
-# endif
-#else /* CONFIG_X86_32 */
-# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
-#endif
-
-/*
- * Find the highest page frame number we have available
- */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
-{
-	int i;
-	unsigned long last_pfn = 0;
-	unsigned long max_arch_pfn = MAX_ARCH_PFN;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		unsigned long start_pfn;
-		unsigned long end_pfn;
-
-		if (ei->type != type)
-			continue;
-
-		start_pfn = ei->addr >> PAGE_SHIFT;
-		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
-
-		if (start_pfn >= limit_pfn)
-			continue;
-		if (end_pfn > limit_pfn) {
-			last_pfn = limit_pfn;
-			break;
-		}
-		if (end_pfn > last_pfn)
-			last_pfn = end_pfn;
-	}
-
-	if (last_pfn > max_arch_pfn)
-		last_pfn = max_arch_pfn;
-
-	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
-			 last_pfn, max_arch_pfn);
-	return last_pfn;
-}
-unsigned long __init e820_end_of_ram_pfn(void)
-{
-	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
-}
-
-unsigned long __init e820_end_of_low_ram_pfn(void)
-{
-	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
-}
-/*
- * Finds an active region in the address range from start_pfn to last_pfn and
- * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
- */
-int __init e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn)
-{
-	u64 align = PAGE_SIZE;
-
-	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
-	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
-
-	/* Skip map entries smaller than a page */
-	if (*ei_startpfn >= *ei_endpfn)
-		return 0;
-
-	/* Skip if map is outside the node */
-	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
-				    *ei_startpfn >= last_pfn)
-		return 0;
-
-	/* Check for overlaps */
-	if (*ei_startpfn < start_pfn)
-		*ei_startpfn = start_pfn;
-	if (*ei_endpfn > last_pfn)
-		*ei_endpfn = last_pfn;
-
-	return 1;
-}
-
-/* Walk the e820 map and register active regions within a node */
-void __init e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long last_pfn)
-{
-	unsigned long ei_startpfn;
-	unsigned long ei_endpfn;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++)
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			add_active_range(nid, ei_startpfn, ei_endpfn);
-}
-
-/*
- * Find the hole size (in bytes) in the memory range.
- * @start: starting address of the memory range to scan
- * @end: ending address of the memory range to scan
- */
-u64 __init e820_hole_size(u64 start, u64 end)
-{
-	unsigned long start_pfn = start >> PAGE_SHIFT;
-	unsigned long last_pfn = end >> PAGE_SHIFT;
-	unsigned long ei_startpfn, ei_endpfn, ram = 0;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			ram += ei_endpfn - ei_startpfn;
-	}
-	return end - start - ((u64)ram << PAGE_SHIFT);
-}
-
-static void early_panic(char *msg)
-{
-	early_printk(msg);
-	panic(msg);
-}
-
-static int userdef __initdata;
-
-/* "mem=nopentium" disables the 4MB page tables. */
-static int __init parse_memopt(char *p)
-{
-	u64 mem_size;
-
-	if (!p)
-		return -EINVAL;
-
-#ifdef CONFIG_X86_32
-	if (!strcmp(p, "nopentium")) {
-		setup_clear_cpu_cap(X86_FEATURE_PSE);
-		return 0;
-	}
-#endif
-
-	userdef = 1;
-	mem_size = memparse(p, &p);
-	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
-
-	return 0;
-}
-early_param("mem", parse_memopt);
-
-static int __init parse_memmap_opt(char *p)
-{
-	char *oldp;
-	u64 start_at, mem_size;
-
-	if (!p)
-		return -EINVAL;
-
-	if (!strncmp(p, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-		/*
-		 * If we are doing a crash dump, we still need to know
-		 * the real mem size before original memory map is
-		 * reset.
-		 */
-		saved_max_pfn = e820_end_of_ram_pfn();
-#endif
-		e820.nr_map = 0;
-		userdef = 1;
-		return 0;
-	}
-
-	oldp = p;
-	mem_size = memparse(p, &p);
-	if (p == oldp)
-		return -EINVAL;
-
-	userdef = 1;
-	if (*p == '@') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RAM);
-	} else if (*p == '#') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_ACPI);
-	} else if (*p == '$') {
-		start_at = memparse(p+1, &p);
-		e820_add_region(start_at, mem_size, E820_RESERVED);
-	} else
-		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
-
-	return *p == '\0' ? 0 : -EINVAL;
-}
-early_param("memmap", parse_memmap_opt);
-
-void __init finish_e820_parsing(void)
-{
-	if (userdef) {
-		u32 nr = e820.nr_map;
-
-		if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
-			early_panic("Invalid user supplied memory map");
-		e820.nr_map = nr;
-
-		printk(KERN_INFO "user-defined physical RAM map:\n");
-		e820_print_map("user");
-	}
-}
-
 static inline const char *e820_type_to_string(int e820_type)
 {
 	switch (e820_type) {
@@ -1098,7 +504,8 @@ void __init e820_reserve_resources(void)
 		 * pci device BAR resource and insert them later in
 		 * pcibios_resource_survey()
 		 */
-		if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
+		if (e820.map[i].type != E820_RESERVED ||
+		    res->start < (1ULL<<20)) {
 			res->flags |= IORESOURCE_BUSY;
 			insert_resource(&iomem_resource, res);
 		}
@@ -1114,7 +521,7 @@ void __init e820_reserve_resources(void)
 }
 
 /* How much should we pad RAM ending depending on where it is? */
-static unsigned long ram_alignment(resource_size_t pos)
+static unsigned long __init ram_alignment(resource_size_t pos)
 {
 	unsigned long mb = pos >> 20;
 
@@ -1196,7 +603,7 @@ char *__init default_machine_specific_memory_setup(void)
 			who = "BIOS-e801";
 		}
 
-		e820.nr_map = 0;
+		clear_e820_map();
 		e820_add_region(0, LOWMEMSIZE(), E820_RAM);
 		e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
 	}
@@ -1204,7 +611,6 @@ char *__init default_machine_specific_memory_setup(void)
 	/* In case someone cares... */
 	return who;
 }
-
 void __init save_e820_map(void)
 {
 	memcpy(&e820_saved, &e820, sizeof(struct e820map));
@@ -1221,20 +627,18 @@ void __init setup_memory_map(void)
 }
 
 #ifdef CONFIG_X86_OOSTORE
+
 /*
  * Figure what we can cover with MCR's
  *
  * Shortcut: We know you can't put 4Gig of RAM on a winchip
  */
-void __init get_centaur_ram_top(void)
+static void __init __get_special_low_ram_top(void)
 {
 	u32 clip = 0xFFFFFFFFUL;
 	u32 top = 0;
 	int i;
 
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
-		return;
-
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long start, end;
 
@@ -1272,7 +676,15 @@ void __init get_centaur_ram_top(void)
 	if (top > clip)
 		top = clip;
 
-	centaur_ram_top = top;
+	return top;
 }
-#endif
 
+int centaur_ram_top;
+void __init get_centaur_ram_top(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
+		return;
+
+	centaur_ram_top = __get_special_low_ram_top();
+}
+#endif
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 266ab92..c341c18 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -6,7 +6,7 @@
 
 #include <linux/mmzone.h>
 #include <asm/dma.h>
-
+#include <linux/early_res.h>
 /*
  *  simple boot-time physical memory area allocator.
  */
diff --git a/include/linux/early_res.h b/include/linux/early_res.h
index 29c09f5..0f4590f 100644
--- a/include/linux/early_res.h
+++ b/include/linux/early_res.h
@@ -14,6 +14,7 @@ u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
 u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
 			 u64 *sizep, u64 align);
 u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
+u64 find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
 u64 get_max_mapped(void);
 #include <linux/range.h>
 int get_free_all_memory_range(struct range **rangep, int nodeid);
diff --git a/include/linux/fw_memmap.h b/include/linux/fw_memmap.h
new file mode 100644
index 0000000..e0fcc1b
--- /dev/null
+++ b/include/linux/fw_memmap.h
@@ -0,0 +1,40 @@
+#ifndef _LINUX_FW_MEMMAP_H
+#define _LINUX_FW_MEMMAP_H
+#define E820MAX	128		/* number of entries in E820MAP */
+
+#define FW_MEMMAP_RAM	1
+#define FW_MEMMAP_RESERVED	2
+
+#define E820_RAM	FW_MEMMAP_RAM
+#define E820_RESERVED	FW_MEMMAP_RESERVED
+
+#define E820_ACPI	3
+#define E820_NVS	4
+#define E820_UNUSABLE	5
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+struct e820entry {
+	__u64 addr;	/* start of memory segment */
+	__u64 size;	/* size of memory segment */
+	__u32 type;	/* type of memory segment */
+} __attribute__((packed));
+
+#ifdef __KERNEL__
+
+void fw_memmap_add_region(u64 start, u64 size, int type);
+void fw_memmap_print_map(char *who);
+int sanitize_fw_memmap(void);
+void finish_fw_memmap_parsing(void);
+
+#include <linux/early_res.h>
+
+unsigned long fw_memmap_end_of_ram_pfn(void);
+void fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long end_pfn);
+u64 fw_memmap_hole_size(u64 start, u64 end);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_FW_MEMMAP_H */
diff --git a/kernel/Makefile b/kernel/Makefile
index d5c3006..b0afaa5 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
 	    notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
 	    async.o range.o
-obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o
+obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o fw_memmap.o
 obj-y += groups.o
 
 ifdef CONFIG_FUNCTION_TRACER
diff --git a/kernel/fw_memmap.c b/kernel/fw_memmap.c
new file mode 100644
index 0000000..11067f3
--- /dev/null
+++ b/kernel/fw_memmap.c
@@ -0,0 +1,625 @@
+/*
+ * Handle the memory map.
+ * The functions here do the job until bootmem takes over.
+ *
+ *  Getting sanitize_e820_map() in sync with i386 version by applying change:
+ *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
+ *     Alex Achenbach <xela@slit.de>, December 2002.
+ *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/suspend.h>
+#include <linux/ioport.h>
+
+#include <linux/fw_memmap.h>
+#include "fw_memmap_internals.h"
+
+/*
+ * The e820 map is the map that gets modified e.g. with command line parameters
+ * and that is also registered with modifications in the kernel resource tree
+ * with the iomem_resource as parent.
+ */
+struct e820map __initdata e820;
+
+/*
+ * Add a memory region to the kernel e820 map.
+ */
+void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
+					 int type)
+{
+	int x = e820x->nr_map;
+
+	if (x >= ARRAY_SIZE(e820x->map)) {
+		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+		return;
+	}
+
+	e820x->map[x].addr = start;
+	e820x->map[x].size = size;
+	e820x->map[x].type = type;
+	e820x->nr_map++;
+}
+
+void __init fw_memmap_add_region(u64 start, u64 size, int type)
+{
+	__e820_add_region(&e820, start, size, type);
+}
+
+/* make e820 not cover the range */
+u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
+			     int checktype)
+{
+	int i;
+	u64 end;
+	u64 real_removed_size = 0;
+
+	if (size > (ULLONG_MAX - start))
+		size = ULLONG_MAX - start;
+
+	end = start + size;
+	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
+		       (unsigned long long) start,
+		       (unsigned long long) end);
+	e820_print_type(old_type);
+	printk(KERN_CONT "\n");
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		u64 final_start, final_end;
+
+		if (checktype && ei->type != old_type)
+			continue;
+		/* totally covered? */
+		if (ei->addr >= start &&
+		    (ei->addr + ei->size) <= (start + size)) {
+			real_removed_size += ei->size;
+			memset(ei, 0, sizeof(struct e820entry));
+			continue;
+		}
+		/* partially covered */
+		final_start = max(start, ei->addr);
+		final_end = min(start + size, ei->addr + ei->size);
+		if (final_start >= final_end)
+			continue;
+		real_removed_size += final_end - final_start;
+
+		ei->size -= final_end - final_start;
+		if (ei->addr < final_start)
+			continue;
+		ei->addr = final_end;
+	}
+	return real_removed_size;
+}
+
+void __init e820_print_type(u32 type)
+{
+	switch (type) {
+	case E820_RAM:
+	case E820_RESERVED_KERN:
+		printk(KERN_CONT "(usable)");
+		break;
+	case E820_RESERVED:
+		printk(KERN_CONT "(reserved)");
+		break;
+	case E820_ACPI:
+		printk(KERN_CONT "(ACPI data)");
+		break;
+	case E820_NVS:
+		printk(KERN_CONT "(ACPI NVS)");
+		break;
+	case E820_UNUSABLE:
+		printk(KERN_CONT "(unusable)");
+		break;
+	default:
+		printk(KERN_CONT "type %u", type);
+		break;
+	}
+}
+
+void __init fw_memmap_print_map(char *who)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
+		       (unsigned long long) e820.map[i].addr,
+		       (unsigned long long)
+		       (e820.map[i].addr + e820.map[i].size));
+		e820_print_type(e820.map[i].type);
+		printk(KERN_CONT "\n");
+	}
+}
+
+/*
+ * Sanitize the BIOS e820 map.
+ *
+ * Some e820 responses include overlapping entries. The following
+ * replaces the original e820 map with a new one, removing overlaps,
+ * and resolving conflicting memory types in favor of highest
+ * numbered type.
+ *
+ * The input parameter biosmap points to an array of 'struct
+ * e820entry' which on entry has elements in the range [0, *pnr_map)
+ * valid, and which has space for up to max_nr_map entries.
+ * On return, the resulting sanitized e820 map entries will be in
+ * overwritten in the same location, starting at biosmap.
+ *
+ * The integer pointed to by pnr_map must be valid on entry (the
+ * current number of valid entries located at biosmap) and will
+ * be updated on return, with the new number of valid entries
+ * (something no more than max_nr_map.)
+ *
+ * The return value from sanitize_e820_map() is zero if it
+ * successfully 'sanitized' the map entries passed in, and is -1
+ * if it did nothing, which can happen if either of (1) it was
+ * only passed one map entry, or (2) any of the input map entries
+ * were invalid (start + size < start, meaning that the size was
+ * so big the described memory range wrapped around through zero.)
+ *
+ *	Visually we're performing the following
+ *	(1,2,3,4 = memory types)...
+ *
+ *	Sample memory map (w/overlaps):
+ *	   ____22__________________
+ *	   ______________________4_
+ *	   ____1111________________
+ *	   _44_____________________
+ *	   11111111________________
+ *	   ____________________33__
+ *	   ___________44___________
+ *	   __________33333_________
+ *	   ______________22________
+ *	   ___________________2222_
+ *	   _________111111111______
+ *	   _____________________11_
+ *	   _________________4______
+ *
+ *	Sanitized equivalent (no overlap):
+ *	   1_______________________
+ *	   _44_____________________
+ *	   ___1____________________
+ *	   ____22__________________
+ *	   ______11________________
+ *	   _________1______________
+ *	   __________3_____________
+ *	   ___________44___________
+ *	   _____________33_________
+ *	   _______________2________
+ *	   ________________1_______
+ *	   _________________4______
+ *	   ___________________2____
+ *	   ____________________33__
+ *	   ______________________4_
+ */
+
+int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+			     u32 *pnr_map)
+{
+	struct change_member {
+		struct e820entry *pbios; /* pointer to original bios entry */
+		unsigned long long addr; /* address for this change point */
+	};
+	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
+	static struct change_member *change_point[2*E820_X_MAX] __initdata;
+	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
+	static struct e820entry new_bios[E820_X_MAX] __initdata;
+	struct change_member *change_tmp;
+	unsigned long current_type, last_type;
+	unsigned long long last_addr;
+	int chgidx, still_changing;
+	int overlap_entries;
+	int new_bios_entry;
+	int old_nr, new_nr, chg_nr;
+	int i;
+
+	/* if there's only one memory region, don't bother */
+	if (*pnr_map < 2)
+		return -1;
+
+	old_nr = *pnr_map;
+	BUG_ON(old_nr > max_nr_map);
+
+	/* bail out if we find any unreasonable addresses in bios map */
+	for (i = 0; i < old_nr; i++)
+		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+			return -1;
+
+	/* create pointers for initial change-point information (for sorting) */
+	for (i = 0; i < 2 * old_nr; i++)
+		change_point[i] = &change_point_list[i];
+
+	/* record all known change-points (starting and ending addresses),
+	   omitting those that are for empty memory regions */
+	chgidx = 0;
+	for (i = 0; i < old_nr; i++)	{
+		if (biosmap[i].size != 0) {
+			change_point[chgidx]->addr = biosmap[i].addr;
+			change_point[chgidx++]->pbios = &biosmap[i];
+			change_point[chgidx]->addr = biosmap[i].addr +
+				biosmap[i].size;
+			change_point[chgidx++]->pbios = &biosmap[i];
+		}
+	}
+	chg_nr = chgidx;
+
+	/* sort change-point list by memory addresses (low -> high) */
+	still_changing = 1;
+	while (still_changing)	{
+		still_changing = 0;
+		for (i = 1; i < chg_nr; i++)  {
+			unsigned long long curaddr, lastaddr;
+			unsigned long long curpbaddr, lastpbaddr;
+
+			curaddr = change_point[i]->addr;
+			lastaddr = change_point[i - 1]->addr;
+			curpbaddr = change_point[i]->pbios->addr;
+			lastpbaddr = change_point[i - 1]->pbios->addr;
+
+			/*
+			 * swap entries, when:
+			 *
+			 * curaddr > lastaddr or
+			 * curaddr == lastaddr and curaddr == curpbaddr and
+			 * lastaddr != lastpbaddr
+			 */
+			if (curaddr < lastaddr ||
+			    (curaddr == lastaddr && curaddr == curpbaddr &&
+			     lastaddr != lastpbaddr)) {
+				change_tmp = change_point[i];
+				change_point[i] = change_point[i-1];
+				change_point[i-1] = change_tmp;
+				still_changing = 1;
+			}
+		}
+	}
+
+	/* create a new bios memory map, removing overlaps */
+	overlap_entries = 0;	 /* number of entries in the overlap table */
+	new_bios_entry = 0;	 /* index for creating new bios map entries */
+	last_type = 0;		 /* start with undefined memory type */
+	last_addr = 0;		 /* start with 0 as last starting address */
+
+	/* loop through change-points, determining affect on the new bios map */
+	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
+		/* keep track of all overlapping bios entries */
+		if (change_point[chgidx]->addr ==
+		    change_point[chgidx]->pbios->addr) {
+			/*
+			 * add map entry to overlap list (> 1 entry
+			 * implies an overlap)
+			 */
+			overlap_list[overlap_entries++] =
+				change_point[chgidx]->pbios;
+		} else {
+			/*
+			 * remove entry from list (order independent,
+			 * so swap with last)
+			 */
+			for (i = 0; i < overlap_entries; i++) {
+				if (overlap_list[i] ==
+				    change_point[chgidx]->pbios)
+					overlap_list[i] =
+						overlap_list[overlap_entries-1];
+			}
+			overlap_entries--;
+		}
+		/*
+		 * if there are overlapping entries, decide which
+		 * "type" to use (larger value takes precedence --
+		 * 1=usable, 2,3,4,4+=unusable)
+		 */
+		current_type = 0;
+		for (i = 0; i < overlap_entries; i++)
+			if (overlap_list[i]->type > current_type)
+				current_type = overlap_list[i]->type;
+		/*
+		 * continue building up new bios map based on this
+		 * information
+		 */
+		if (current_type != last_type)	{
+			if (last_type != 0)	 {
+				new_bios[new_bios_entry].size =
+					change_point[chgidx]->addr - last_addr;
+				/*
+				 * move forward only if the new size
+				 * was non-zero
+				 */
+				if (new_bios[new_bios_entry].size != 0)
+					/*
+					 * no more space left for new
+					 * bios entries ?
+					 */
+					if (++new_bios_entry >= max_nr_map)
+						break;
+			}
+			if (current_type != 0)	{
+				new_bios[new_bios_entry].addr =
+					change_point[chgidx]->addr;
+				new_bios[new_bios_entry].type = current_type;
+				last_addr = change_point[chgidx]->addr;
+			}
+			last_type = current_type;
+		}
+	}
+	/* retain count for new bios entries */
+	new_nr = new_bios_entry;
+
+	/* copy new bios mapping into original location */
+	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
+	*pnr_map = new_nr;
+
+	return 0;
+}
+
+int __init sanitize_fw_memmap(void)
+{
+	int max_nr_map = ARRAY_SIZE(e820.map);
+
+	return __sanitize_e820_map(e820.map, max_nr_map, &e820.nr_map);
+}
+
+void __init clear_e820_map(void)
+{
+	e820.nr_map = 0;
+}
+
+static int userdef __initdata;
+
+/* "mem=nopentium" disables the 4MB page tables. */
+static int __init parse_memopt(char *p)
+{
+	u64 mem_size;
+
+	if (!p)
+		return -EINVAL;
+
+#ifdef CONFIG_X86_32
+	if (!strcmp(p, "nopentium")) {
+		setup_clear_cpu_cap(X86_FEATURE_PSE);
+		return 0;
+	}
+#endif
+
+	userdef = 1;
+	mem_size = memparse(p, &p);
+	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
+	return 0;
+}
+early_param("mem", parse_memopt);
+
+static int __init parse_memmap_opt(char *p)
+{
+	char *oldp;
+	u64 start_at, mem_size;
+
+	if (!p)
+		return -EINVAL;
+
+	if (!strncmp(p, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+		/*
+		 * If we are doing a crash dump, we still need to know
+		 * the real mem size before original memory map is
+		 * reset.
+		 */
+		saved_max_pfn = fw_memmap_end_of_ram_pfn();
+#endif
+		e820.nr_map = 0;
+		userdef = 1;
+		return 0;
+	}
+
+	oldp = p;
+	mem_size = memparse(p, &p);
+	if (p == oldp)
+		return -EINVAL;
+
+	userdef = 1;
+	if (*p == '@') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_RAM);
+	} else if (*p == '#') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_ACPI);
+	} else if (*p == '$') {
+		start_at = memparse(p+1, &p);
+		e820_add_region(start_at, mem_size, E820_RESERVED);
+	} else
+		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
+	return *p == '\0' ? 0 : -EINVAL;
+}
+early_param("memmap", parse_memmap_opt);
+
+static void early_panic(char *msg)
+{
+	early_printk(msg);
+	panic(msg);
+}
+
+void __init finish_fw_memmap_parsing(void)
+{
+	if (userdef) {
+		u32 nr = e820.nr_map;
+		int max_nr_map = ARRAY_SIZE(e820.map);
+
+		if (__sanitize_e820_map(e820.map, max_nr_map, &nr) < 0)
+			early_panic("Invalid user supplied memory map");
+		e820.nr_map = nr;
+
+		printk(KERN_INFO "user-defined physical RAM map:\n");
+		e820_print_map("user");
+	}
+}
+
+/*
+ * Find a free area with specified alignment in a specific range.
+ */
+u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		u64 addr;
+		u64 ei_start, ei_last;
+
+		if (ei->type != E820_RAM)
+			continue;
+
+		ei_last = ei->addr + ei->size;
+		ei_start = ei->addr;
+		addr = find_early_area(ei_start, ei_last, start, end,
+					 size, align);
+
+		if (addr != -1ULL)
+			return addr;
+	}
+	return -1ULL;
+}
+
+u64 __init
+find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	u64 addr;
+	/*
+	 * need to call this function after e820_register_active_regions
+	 * so early_node_map[] is set
+	 */
+	addr = find_memory_core_early(nid, size, align, start, end);
+	if (addr != -1ULL)
+		return addr;
+
+	/* fallback, should already have start end in the node range */
+	return find_fw_memmap_area(start, end, size, align);
+}
+
+#ifdef CONFIG_X86_32
+# ifdef CONFIG_X86_PAE
+#  define MAX_ARCH_PFN	(1ULL<<(36-PAGE_SHIFT))
+# else
+#  define MAX_ARCH_PFN	(1ULL<<(32-PAGE_SHIFT))
+# endif
+#else /* CONFIG_X86_32 */
+# define MAX_ARCH_PFN	(MAXMEM>>PAGE_SHIFT)
+#endif
+
+/*
+ * Find the highest page frame number we have available
+ */
+static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+{
+	int i;
+	unsigned long last_pfn = 0;
+	unsigned long max_arch_pfn = MAX_ARCH_PFN;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		unsigned long start_pfn;
+		unsigned long end_pfn;
+
+		if (ei->type != type)
+			continue;
+
+		start_pfn = ei->addr >> PAGE_SHIFT;
+		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
+
+		if (start_pfn >= limit_pfn)
+			continue;
+		if (end_pfn > limit_pfn) {
+			last_pfn = limit_pfn;
+			break;
+		}
+		if (end_pfn > last_pfn)
+			last_pfn = end_pfn;
+	}
+
+	if (last_pfn > max_arch_pfn)
+		last_pfn = max_arch_pfn;
+
+	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
+			 last_pfn, max_arch_pfn);
+	return last_pfn;
+}
+unsigned long __init fw_memmap_end_of_ram_pfn(void)
+{
+	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+}
+
+unsigned long __init e820_end_of_low_ram_pfn(void)
+{
+	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
+}
+/*
+ * Finds an active region in the address range from start_pfn to last_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
+ */
+static int __init e820_find_active_region(const struct e820entry *ei,
+				  unsigned long start_pfn,
+				  unsigned long last_pfn,
+				  unsigned long *ei_startpfn,
+				  unsigned long *ei_endpfn)
+{
+	u64 align = PAGE_SIZE;
+
+	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
+	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
+
+	/* Skip map entries smaller than a page */
+	if (*ei_startpfn >= *ei_endpfn)
+		return 0;
+
+	/* Skip if map is outside the node */
+	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
+				    *ei_startpfn >= last_pfn)
+		return 0;
+
+	/* Check for overlaps */
+	if (*ei_startpfn < start_pfn)
+		*ei_startpfn = start_pfn;
+	if (*ei_endpfn > last_pfn)
+		*ei_endpfn = last_pfn;
+
+	return 1;
+}
+
+/* Walk the e820 map and register active regions within a node */
+void __init fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long last_pfn)
+{
+	unsigned long ei_startpfn;
+	unsigned long ei_endpfn;
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++)
+		if (e820_find_active_region(&e820.map[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			add_active_range(nid, ei_startpfn, ei_endpfn);
+}
+
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+u64 __init fw_memmap_hole_size(u64 start, u64 end)
+{
+	unsigned long start_pfn = start >> PAGE_SHIFT;
+	unsigned long last_pfn = end >> PAGE_SHIFT;
+	unsigned long ei_startpfn, ei_endpfn, ram = 0;
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		if (e820_find_active_region(&e820.map[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			ram += ei_endpfn - ei_startpfn;
+	}
+	return end - start - ((u64)ram << PAGE_SHIFT);
+}
diff --git a/kernel/fw_memmap_internals.h b/kernel/fw_memmap_internals.h
new file mode 100644
index 0000000..f217602
--- /dev/null
+++ b/kernel/fw_memmap_internals.h
@@ -0,0 +1,49 @@
+#ifndef __KERNEL_FW_MEMMAP_INTERNALS_H
+#define __KERNEL_FW_MEMMAP_INTERNALS_H
+
+/*
+ * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
+ * constrained space in the zeropage.  If we have more nodes than
+ * that, and if we've booted off EFI firmware, then the EFI tables
+ * passed us from the EFI firmware can list more nodes.  Size our
+ * internal memory map tables to have room for these additional
+ * nodes, based on up to three entries per node for which the
+ * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
+ * plus E820MAX, allowing space for the possible duplicate E820
+ * entries that might need room in the same arrays, prior to the
+ * call to sanitize_e820_map() to remove duplicates.  The allowance
+ * of three memory map entries per node is "enough" entries for
+ * the initial hardware platform motivating this mechanism to make
+ * use of additional EFI map entries.  Future platforms may want
+ * to allow more than three entries per node or otherwise refine
+ * this size.
+ */
+
+/*
+ * Odd: 'make headers_check' complains about numa.h if I try
+ * to collapse the next two #ifdef lines to a single line:
+ *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
+ */
+#ifdef __KERNEL__
+#ifdef CONFIG_EFI
+#include <linux/numa.h>
+#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
+#else	/* ! CONFIG_EFI */
+#define E820_X_MAX E820MAX
+#endif
+#else	/* ! __KERNEL__ */
+#define E820_X_MAX E820MAX
+#endif
+
+#ifndef __ASSEMBLY__
+struct e820map {
+	__u32 nr_map;
+	struct e820entry map[E820_X_MAX];
+};
+#endif
+
+extern struct e820map __initdata e820;
+void e820_print_type(u32 type);
+void __e820_add_region(struct e820map *e820x, u64 start, u64 size, int type);
+
+#endif
-- 
1.6.4.2

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

* [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip.
  2010-03-21  7:13 ` Yinghai Lu
                     ` (2 preceding siblings ...)
  (?)
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Andrew Morton, David Miller, Jes
  Cc: linux-arch, 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] 111+ messages in thread

* [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Ian Campbell,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, 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] 111+ messages in thread

* [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Andrew Morton, David Miller, Jes
  Cc: linux-arch, 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] 111+ messages in thread

* [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Ian Campbell,
	Ingo Molnar, 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] 111+ messages in thread

* [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip.
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: linux-arch, 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] 111+ messages in thread

* [PATCH 08/20] x86: fix out of order of gsi - full
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu,
	Thomas Renninger, 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] 111+ messages in thread

* [PATCH 08/20] x86: fix out of order of gsi - full
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu,
	Thomas Renninger, 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] 111+ messages in thread

* [PATCH 09/20] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 09/20] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 10/20] x86: kill smpboot_hooks.h
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 10/20] x86: kill smpboot_hooks.h
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 11/20] x86: use vector_desc instead of vector_irq
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 11/20] x86: use vector_desc instead of vector_irq
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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] 111+ messages in thread

* [PATCH 12/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- x86 and core
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

will have
void            (*ack)(struct irq_desc *desc);
void            (*mask)(struct irq_desc *desc);
void            (*mask_ack)(struct irq_desc *desc);
void            (*unmask)(struct irq_desc *desc);
void            (*eoi)(struct irq_desc *desc);

so for sparseirq with raidix tree, we don't call extra irq_to_desc, and could use desc directly

-v2: change all member of irq_chip to use desc only.
-v2.1: update after legacy_pic
-v2.2: update to irq one short fix

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/alpha/include/asm/hardirq.h            |    3 +-
 arch/alpha/kernel/irq.c                     |    4 +-
 arch/arm/include/asm/hw_irq.h               |    3 +-
 arch/arm/kernel/irq.c                       |    2 +-
 arch/blackfin/include/asm/hardirq.h         |    3 +-
 arch/blackfin/kernel/irqchip.c              |    4 +-
 arch/frv/include/asm/hardirq.h              |    3 +-
 arch/ia64/hp/sim/hpsim_irq.c                |    6 +-
 arch/ia64/include/asm/hardirq.h             |    2 +-
 arch/ia64/kernel/iosapic.c                  |   41 ++++----
 arch/ia64/kernel/irq.c                      |   10 +-
 arch/ia64/kernel/irq_lsapic.c               |    8 +-
 arch/ia64/kernel/msi_ia64.c                 |   21 +++--
 arch/ia64/kernel/smpboot.c                  |    6 +-
 arch/ia64/sn/kernel/irq.c                   |   25 +++--
 arch/ia64/sn/kernel/msi_sn.c                |   12 ++-
 arch/mips/include/asm/hardirq.h             |    3 +-
 arch/mips/kernel/irq.c                      |    3 +-
 arch/mn10300/include/asm/hardirq.h          |    2 +-
 arch/mn10300/kernel/irq.c                   |    4 +-
 arch/powerpc/include/asm/hardirq.h          |    4 +-
 arch/sh/include/asm/hardirq.h               |    3 +-
 arch/sh/kernel/irq.c                        |    4 +-
 arch/sparc/include/asm/hardirq_64.h         |    3 +-
 arch/sparc/kernel/irq_64.c                  |    3 +-
 arch/um/kernel/irq.c                        |    2 +-
 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              |  143 ++++++++++-----------------
 arch/x86/kernel/hpet.c                      |   16 ++--
 arch/x86/kernel/i8259.c                     |   31 ++++---
 arch/x86/kernel/irq.c                       |   12 +-
 arch/x86/kernel/uv_irq.c                    |   14 ++--
 arch/x86/kernel/visws_quirks.c              |   29 +++---
 arch/x86/kernel/vmiclock_32.c               |    8 +-
 arch/x86/lguest/boot.c                      |    8 +-
 arch/xtensa/include/asm/hardirq.h           |    3 +-
 arch/xtensa/kernel/irq.c                    |    4 +-
 drivers/dma/ipu/ipu_irq.c                   |   18 ++--
 drivers/gpio/langwell_gpio.c                |   11 +-
 drivers/gpio/pca953x.c                      |   23 +++--
 drivers/gpio/pl061.c                        |   19 ++--
 drivers/gpio/timbgpio.c                     |   17 ++--
 drivers/gpio/vr41xx_giu.c                   |   32 +++---
 drivers/infiniband/hw/ipath/ipath_iba6110.c |    2 +-
 drivers/mfd/asic3.c                         |   27 +++--
 drivers/mfd/ezx-pcap.c                      |   12 ++-
 drivers/mfd/htc-egpio.c                     |   12 ++-
 drivers/mfd/t7l66xb.c                       |    8 +-
 drivers/mfd/tc6393xb.c                      |   14 ++-
 drivers/mfd/twl4030-irq.c                   |   16 ++--
 drivers/mfd/wm831x-irq.c                    |   18 ++--
 drivers/misc/sgi-gru/grufile.c              |    2 +-
 drivers/parisc/dino.c                       |   12 +-
 drivers/parisc/eisa.c                       |   10 +-
 drivers/parisc/gsc.c                        |   12 +-
 drivers/parisc/iosapic.c                    |   16 ++-
 drivers/parisc/superio.c                    |   10 +-
 drivers/pci/dmar.c                          |   16 ++--
 drivers/pci/htirq.c                         |   22 ++--
 drivers/pci/msi.c                           |   13 ++-
 drivers/vlynq/vlynq.c                       |   23 +++--
 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                         |   49 +++++-----
 include/linux/msi.h                         |    4 +-
 kernel/irq/autoprobe.c                      |   12 +-
 kernel/irq/chip.c                           |   68 ++++++-------
 kernel/irq/handle.c                         |   24 ++---
 kernel/irq/internals.h                      |   16 ++--
 kernel/irq/manage.c                         |   67 ++++++-------
 kernel/irq/migration.c                      |   16 +--
 kernel/irq/pm.c                             |    4 +-
 kernel/irq/resend.c                         |    8 +-
 kernel/irq/spurious.c                       |    4 +-
 79 files changed, 585 insertions(+), 562 deletions(-)

diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h
index 242c09b..80f79f4 100644
--- a/arch/alpha/include/asm/hardirq.h
+++ b/arch/alpha/include/asm/hardirq.h
@@ -1,7 +1,8 @@
 #ifndef _ALPHA_HARDIRQ_H
 #define _ALPHA_HARDIRQ_H
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 #include <asm-generic/hardirq.h>
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 5f2cf23..08a6384 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -33,10 +33,10 @@
 
 volatile unsigned long irq_err_count;
 
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	irq_err_count++;
-	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
+	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", desc->irq);
 }
 
 #ifdef CONFIG_SMP 
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index 90831f6..43a8c03 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -4,7 +4,8 @@
 #ifndef _ARCH_ARM_HW_IRQ_H
 #define _ARCH_ARM_HW_IRQ_H
 
-static inline void ack_bad_irq(int irq)
+struct irq_desc;
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
 	extern unsigned long irq_err_count;
 	irq_err_count++;
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b7cb45b..265e78c 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -116,7 +116,7 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 	if (unlikely(irq >= NR_IRQS)) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Bad IRQ%u\n", irq);
-		ack_bad_irq(irq);
+		ack_bad_irq(irq_to_desc(irq));
 	} else {
 		generic_handle_irq(irq);
 	}
diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h
index c078dd7..e5ed5d5 100644
--- a/arch/blackfin/include/asm/hardirq.h
+++ b/arch/blackfin/include/asm/hardirq.h
@@ -9,7 +9,8 @@
 
 #define __ARCH_IRQ_EXIT_IRQS_DISABLED	1
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 /* Define until common code gets sane defaults */
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 64cff54..707a93b 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -15,10 +15,10 @@
 #include <asm/pda.h>
 
 static atomic_t irq_err_count;
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
-	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+	printk(KERN_ERR "IRQ: spurious interrupt %d\n", desc->irq);
 }
 
 static struct irq_desc bad_irq_desc = {
diff --git a/arch/frv/include/asm/hardirq.h b/arch/frv/include/asm/hardirq.h
index 5fc8b6f..2c49141 100644
--- a/arch/frv/include/asm/hardirq.h
+++ b/arch/frv/include/asm/hardirq.h
@@ -14,8 +14,9 @@
 
 #include <asm/atomic.h>
 
+struct irq_desc;
 extern atomic_t irq_err_count;
-static inline void ack_bad_irq(int irq)
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
 }
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index b272261..de7c5d1 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -11,18 +11,18 @@
 #include <linux/irq.h>
 
 static unsigned int
-hpsim_irq_startup (unsigned int irq)
+hpsim_irq_startup(struct irq_desc *desc)
 {
 	return 0;
 }
 
 static void
-hpsim_irq_noop (unsigned int irq)
+hpsim_irq_noop(struct irq_desc *desc)
 {
 }
 
 static int
-hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
+hpsim_set_affinity_noop(struct irq_desc *desc, const struct cpumask *b)
 {
 	return 0;
 }
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
index d514cd9..cc9950b 100644
--- a/arch/ia64/include/asm/hardirq.h
+++ b/arch/ia64/include/asm/hardirq.h
@@ -22,6 +22,6 @@
 
 extern void __iomem *ipi_base_addr;
 
-void ack_bad_irq(unsigned int irq);
+void ack_bad_irq(struct irq_desc *desc);
 
 #endif /* _ASM_IA64_HARDIRQ_H */
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 95ac77a..0edfbb4 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -264,7 +264,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
 }
 
 static void
-nop (unsigned int irq)
+nop(struct irq_desc *desc)
 {
 	/* do nothing... */
 }
@@ -294,8 +294,9 @@ kexec_disable_iosapic(void)
 #endif
 
 static void
-mask_irq (unsigned int irq)
+mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 low32;
 	int rte_index;
 	struct iosapic_rte_info *rte;
@@ -312,8 +313,9 @@ mask_irq (unsigned int irq)
 }
 
 static void
-unmask_irq (unsigned int irq)
+unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 low32;
 	int rte_index;
 	struct iosapic_rte_info *rte;
@@ -328,11 +330,11 @@ unmask_irq (unsigned int irq)
 	}
 }
 
-
 static int
-iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
+iosapic_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
 #ifdef CONFIG_SMP
+	unsigned int irq = desc->irq;
 	u32 high32, low32;
 	int cpu, dest, rte_index;
 	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
@@ -386,31 +388,32 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
  */
 
 static unsigned int
-iosapic_startup_level_irq (unsigned int irq)
+iosapic_startup_level_irq (struct irq_desc *desc)
 {
-	unmask_irq(irq);
+	unmask_irq(desc);
 	return 0;
 }
 
 static void
-iosapic_end_level_irq (unsigned int irq)
+iosapic_end_level_irq (struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ia64_vector vec = irq_to_vector(irq);
 	struct iosapic_rte_info *rte;
 	int do_unmask_irq = 0;
 
 	irq_complete_move(irq);
-	if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+	if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
 		do_unmask_irq = 1;
-		mask_irq(irq);
+		mask_irq(desc);
 	}
 
 	list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
 		iosapic_eoi(rte->iosapic->addr, vec);
 
 	if (unlikely(do_unmask_irq)) {
-		move_masked_irq(irq);
-		unmask_irq(irq);
+		move_masked_irq(desc);
+		unmask_irq(desc);
 	}
 }
 
@@ -437,9 +440,9 @@ static struct irq_chip irq_type_iosapic_level = {
  */
 
 static unsigned int
-iosapic_startup_edge_irq (unsigned int irq)
+iosapic_startup_edge_irq (struct irq_desc *desc)
 {
-	unmask_irq(irq);
+	unmask_irq(desc);
 	/*
 	 * IOSAPIC simply drops interrupts pended while the
 	 * corresponding pin was masked, so we can't know if an
@@ -449,20 +452,20 @@ iosapic_startup_edge_irq (unsigned int irq)
 }
 
 static void
-iosapic_ack_edge_irq (unsigned int irq)
+iosapic_ack_edge_irq (struct irq_desc *desc)
 {
-	struct irq_desc *idesc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 
 	irq_complete_move(irq);
-	move_native_irq(irq);
+	move_native_irq(desc);
 	/*
 	 * Once we have recorded IRQ_PENDING already, we can mask the
 	 * interrupt for real. This prevents IRQ storms from unhandled
 	 * devices.
 	 */
-	if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
+	if ((desc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
 	    (IRQ_PENDING|IRQ_DISABLED))
-		mask_irq(irq);
+		mask_irq(desc);
 }
 
 #define iosapic_enable_edge_irq		unmask_irq
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 94ee9d0..d4fe756 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -27,9 +27,9 @@
  * '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)
 {
-	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", desc->irq, smp_processor_id());
 }
 
 #ifdef CONFIG_IA64_GENERIC
@@ -162,10 +162,10 @@ static void migrate_irqs(void)
 			 */
 			if (desc->chip && desc->chip->disable &&
 				desc->chip->enable && desc->chip->set_affinity) {
-				desc->chip->disable(irq);
-				desc->chip->set_affinity(irq,
+				desc->chip->disable(desc);
+				desc->chip->set_affinity(desc,
 							 cpumask_of(new_cpu));
-				desc->chip->enable(irq);
+				desc->chip->enable(desc);
 			} else {
 				WARN_ON((!(desc->chip) || !(desc->chip->disable) ||
 						!(desc->chip->enable) ||
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index fc1549d..438641a 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -15,19 +15,21 @@
 #include <linux/irq.h>
 
 static unsigned int
-lsapic_noop_startup (unsigned int irq)
+lsapic_noop_startup(struct irq_desc *desc)
 {
 	return 0;
 }
 
 static void
-lsapic_noop (unsigned int irq)
+lsapic_noop(struct irq_desc *desc)
 {
 	/* nothing to do... */
 }
 
-static int lsapic_retrigger(unsigned int irq)
+static int lsapic_retrigger(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	ia64_resend_irq(irq);
 
 	return 1;
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 6c89228..d33f88c 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -12,9 +12,10 @@
 static struct irq_chip	ia64_msi_chip;
 
 #ifdef CONFIG_SMP
-static int ia64_set_msi_irq_affinity(unsigned int irq,
+static int ia64_set_msi_irq_affinity(struct irq_desc *desc,
 				      const cpumask_t *cpu_mask)
 {
+	unsigned int irq = desc->irq;
 	struct msi_msg msg;
 	u32 addr, data;
 	int cpu = first_cpu(*cpu_mask);
@@ -38,7 +39,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq,
 	msg.data = data;
 
 	write_msi_msg(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
+	cpumask_copy(desc->affinity, cpumask_of(cpu));
 
 	return 0;
 }
@@ -84,15 +85,17 @@ void ia64_teardown_msi_irq(unsigned int irq)
 	destroy_irq(irq);
 }
 
-static void ia64_ack_msi_irq(unsigned int irq)
+static void ia64_ack_msi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq_complete_move(irq);
-	move_native_irq(irq);
+	move_native_irq(desc);
 	ia64_eoi();
 }
 
-static int ia64_msi_retrigger_irq(unsigned int irq)
+static int ia64_msi_retrigger_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vector = irq_to_vector(irq);
 	ia64_resend_irq(vector);
 
@@ -132,8 +135,9 @@ void arch_teardown_msi_irq(unsigned int irq)
 
 #ifdef CONFIG_DMAR
 #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)
 {
+	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg = irq_cfg + irq;
 	struct msi_msg msg;
 	int cpu = cpumask_first(mask);
@@ -152,7 +156,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 	msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
 
 	dmar_msi_write(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, mask);
+	cpumask_copy(desc->affinity, mask);
 
 	return 0;
 }
@@ -198,11 +202,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);
 	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;
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index e5230b2..7241118 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -696,9 +696,9 @@ int migrate_platform_irqs(unsigned int cpu)
 			 * polling before making changes.
 			 */
 			if (desc) {
-				desc->chip->disable(ia64_cpe_irq);
-				desc->chip->set_affinity(ia64_cpe_irq, mask);
-				desc->chip->enable(ia64_cpe_irq);
+				desc->chip->disable(desc);
+				desc->chip->set_affinity(desc, mask);
+				desc->chip->enable(desc);
 				printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
 			}
 		}
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 40d6eed..78bf9c3 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -77,31 +77,34 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
 	return ret_stuff.status;
 }
 
-static unsigned int sn_startup_irq(unsigned int irq)
+static unsigned int sn_startup_irq(struct irq_desc *desc)
 {
 	return 0;
 }
 
-static void sn_shutdown_irq(unsigned int irq)
+static void sn_shutdown_irq(struct irq_desc *desc)
 {
 }
 
 extern void ia64_mca_register_cpev(int);
 
-static void sn_disable_irq(unsigned int irq)
+static void sn_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
 		ia64_mca_register_cpev(0);
 }
 
-static void sn_enable_irq(unsigned int irq)
+static void sn_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
 		ia64_mca_register_cpev(irq);
 }
 
-static void sn_ack_irq(unsigned int irq)
+static void sn_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 event_occurred, mask;
 
 	irq = irq & 0xff;
@@ -110,11 +113,12 @@ static void sn_ack_irq(unsigned int irq)
 	HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
 	__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
 
-	move_native_irq(irq);
+	move_native_irq(desc);
 }
 
-static void sn_end_irq(unsigned int irq)
+static void sn_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ivec;
 	u64 event_occurred;
 
@@ -227,8 +231,9 @@ finish_up:
 	return new_irq_info;
 }
 
-static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
+static int sn_set_affinity_irq(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
 	nasid_t nasid;
 	int slice;
@@ -258,12 +263,12 @@ void sn_set_err_irq_affinity(unsigned int irq) { }
 #endif
 
 static void
-sn_mask_irq(unsigned int irq)
+sn_mask_irq(struct irq_desc *desc)
 {
 }
 
 static void
-sn_unmask_irq(unsigned int irq)
+sn_unmask_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index fbbfb97..df63df0 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -151,9 +151,10 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
 }
 
 #ifdef CONFIG_SMP
-static int sn_set_msi_irq_affinity(unsigned int irq,
+static int sn_set_msi_irq_affinity(struct irq_desc *desc,
 				    const struct cpumask *cpu_mask)
 {
+	unsigned int irq = desc->irq;
 	struct msi_msg msg;
 	int slice;
 	nasid_t nasid;
@@ -205,20 +206,21 @@ static int sn_set_msi_irq_affinity(unsigned int irq,
 	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
 	write_msi_msg(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, cpu_mask);
+	cpumask_copy(desc->affinity, cpu_mask);
 
 	return 0;
 }
 #endif /* CONFIG_SMP */
 
-static void sn_ack_msi_irq(unsigned int irq)
+static void sn_ack_msi_irq(struct irq_desc *desc)
 {
-	move_native_irq(irq);
+	move_native_irq(desc);
 	ia64_eoi();
 }
 
-static int sn_msi_retrigger_irq(unsigned int irq)
+static int sn_msi_retrigger_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vector = irq;
 	ia64_resend_irq(vector);
 
diff --git a/arch/mips/include/asm/hardirq.h b/arch/mips/include/asm/hardirq.h
index c977a86..a230b5e 100644
--- a/arch/mips/include/asm/hardirq.h
+++ b/arch/mips/include/asm/hardirq.h
@@ -10,7 +10,8 @@
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 #include <asm-generic/hardirq.h>
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 981f86c..619db4a 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -74,8 +74,9 @@ void free_irqno(unsigned int irq)
  * '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)
 {
+	unsigned int irq = desc->irq;
 	smtc_im_ack_irq(irq);
 	printk("unexpected IRQ # %d\n", irq);
 }
diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h
index 54d9501..725a812 100644
--- a/arch/mn10300/include/asm/hardirq.h
+++ b/arch/mn10300/include/asm/hardirq.h
@@ -26,7 +26,7 @@ typedef struct {
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
-extern void ack_bad_irq(int irq);
+extern void ack_bad_irq(struct irq_desc *desc);
 
 /*
  * manipulate stubs in the MN10300 CPU Trap/Interrupt Vector table
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index e2d5ed8..bc98665 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -100,9 +100,9 @@ static struct irq_chip mn10300_cpu_pic_edge = {
  * '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(int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
-	printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 /*
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 3147a29..945c7d2 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -18,9 +18,9 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define local_softirq_pending()	__get_cpu_var(irq_stat).__softirq_pending
 
-static inline void ack_bad_irq(unsigned int irq)
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
-	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 extern u64 arch_irq_stat_cpu(unsigned int cpu);
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index 48b1913..c5c08c8 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -11,6 +11,7 @@ typedef struct {
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index d2d41d0..556e3d3 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -25,10 +25,10 @@ atomic_t irq_err_count;
  * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
-	printk("unexpected IRQ trap at vector %02x\n", irq);
+	printk("unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 #if defined(CONFIG_PROC_FS)
diff --git a/arch/sparc/include/asm/hardirq_64.h b/arch/sparc/include/asm/hardirq_64.h
index 7c29fd1..6601974 100644
--- a/arch/sparc/include/asm/hardirq_64.h
+++ b/arch/sparc/include/asm/hardirq_64.h
@@ -12,7 +12,8 @@
 #define local_softirq_pending() \
 	(local_cpu_data().__softirq_pending)
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 
 #define HARDIRQ_BITS	8
 
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index e1cbdb9..4e7419c 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -689,8 +689,9 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 	return virt_irq;
 }
 
-void ack_bad_irq(unsigned int virt_irq)
+void ack_bad_irq(struct irq_desc_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
 
 	if (!ino)
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 89474ba..2c21218 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(reactivate_fd);
  * irq_chip must define (startup || enable) &&
  * (shutdown || disable) && end
  */
-static void dummy(unsigned int irq)
+static void dummy(struct irq_desc *desc)
 {
 }
 
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..d3b2f0b 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,8 @@ 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;
@@ -3481,9 +3448,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,8 +3548,9 @@ 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;
 
@@ -3590,7 +3558,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 	write_msi_msg(irq, &msg);
 
 	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
 		/*
 		 * irq migration in process context
 		 */
@@ -3672,9 +3639,8 @@ 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 +3650,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 +3682,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 +3697,8 @@ 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 +3708,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 +3770,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 +3795,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 +3806,11 @@ 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 +3819,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 +3874,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 +4364,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..2b601d3 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,9 @@ 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/arch/xtensa/include/asm/hardirq.h b/arch/xtensa/include/asm/hardirq.h
index 87cb19d..f0230ff 100644
--- a/arch/xtensa/include/asm/hardirq.h
+++ b/arch/xtensa/include/asm/hardirq.h
@@ -22,7 +22,8 @@ typedef struct {
 	unsigned int __nmi_count;	       /* arch dependent */
 } ____cacheline_aligned irq_cpustat_t;
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
 #endif	/* _XTENSA_HARDIRQ_H */
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 8cd3848..f86cf05 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -30,9 +30,9 @@ atomic_t irq_err_count;
  * '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)
 {
-          printk("unexpected IRQ trap at vector %02x\n", irq);
+          printk("unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 /*
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index dd8ebc7..62f4307 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -94,9 +94,9 @@ static struct ipu_irq_map *src2map(unsigned int src)
 	return NULL;
 }
 
-static void ipu_irq_unmask(unsigned int irq)
+static void ipu_irq_unmask(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	uint32_t reg;
 	unsigned long lock_flags;
@@ -106,7 +106,7 @@ static void ipu_irq_unmask(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
@@ -117,9 +117,9 @@ static void ipu_irq_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
-static void ipu_irq_mask(unsigned int irq)
+static void ipu_irq_mask(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	uint32_t reg;
 	unsigned long lock_flags;
@@ -129,7 +129,7 @@ static void ipu_irq_mask(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
@@ -140,9 +140,9 @@ static void ipu_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
-static void ipu_irq_ack(unsigned int irq)
+static void ipu_irq_ack(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	unsigned long lock_flags;
 
@@ -151,7 +151,7 @@ static void ipu_irq_ack(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 6c0ebbd..0eb44e7 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(struct irq_desc *desc, unsigned type)
 {
-	struct lnw_gpio *lnw = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
 };
 
-static void lnw_irq_mask(unsigned irq)
+static void lnw_irq_mask(struct irq_desc *desc)
 {
 };
 
@@ -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(desc);
 }
 
 static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index ab5daab..9fb1ba3 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);
+	unsigned int irq = desc->irq;
+	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);
+	unsigned int irq = desc->irq;
+	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);
+	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);
+	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);
+	unsigned int irq = desc->irq;
+	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/pl061.c b/drivers/gpio/pl061.c
index 3ad1eeb..9dddd6e 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -122,9 +122,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
 /*
  * PL061 GPIO IRQ
  */
-static void pl061_irq_disable(unsigned irq)
+static void pl061_irq_disable(struct irq_desc *desc)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpioie;
@@ -136,9 +137,10 @@ static void pl061_irq_disable(unsigned irq)
 	spin_unlock_irqrestore(&chip->irq_lock, flags);
 }
 
-static void pl061_irq_enable(unsigned irq)
+static void pl061_irq_enable(struct irq_desc *desc)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpioie;
@@ -150,9 +152,10 @@ static void pl061_irq_enable(unsigned irq)
 	spin_unlock_irqrestore(&chip->irq_lock, flags);
 }
 
-static int pl061_irq_type(unsigned irq, unsigned trigger)
+static int pl061_irq_type(struct irq_desc *desc, unsigned trigger)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpiois, gpioibe, gpioiev;
@@ -207,7 +210,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 	struct list_head *ptr;
 	struct pl061_gpio *chip;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 	list_for_each(ptr, chip_list) {
 		unsigned long pending;
 		int offset;
@@ -222,7 +225,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
 			generic_handle_irq(pl061_to_irq(&chip->gc, offset));
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index d4295fa..55c51f5 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(struct irq_desc *desc)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc, unsigned trigger)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(desc);
 	ipr = ioread32(tgpio->membase + TGPIO_IPR);
 	iowrite32(ipr, tgpio->membase + TGPIO_ICR);
 
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c
index b16c9a8..ea2e00f 100644
--- a/drivers/gpio/vr41xx_giu.c
+++ b/drivers/gpio/vr41xx_giu.c
@@ -111,28 +111,28 @@ static inline u16 giu_clear(u16 offset, u16 clear)
 	return data;
 }
 
-static void ack_giuint_low(unsigned int irq)
+static void ack_giuint_low(struct irq_desc *desc)
 {
-	giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
-static void mask_giuint_low(unsigned int irq)
+static void mask_giuint_low(struct irq_desc *desc)
 {
-	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
-static void mask_ack_giuint_low(unsigned int irq)
+static void mask_ack_giuint_low(struct irq_desc *desc)
 {
 	unsigned int pin;
 
-	pin = GPIO_PIN_OF_IRQ(irq);
+	pin = GPIO_PIN_OF_IRQ(desc->irq);
 	giu_clear(GIUINTENL, 1 << pin);
 	giu_write(GIUINTSTATL, 1 << pin);
 }
 
-static void unmask_giuint_low(unsigned int irq)
+static void unmask_giuint_low(struct irq_desc *desc)
 {
-	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
 static struct irq_chip giuint_low_irq_chip = {
@@ -143,29 +143,29 @@ static struct irq_chip giuint_low_irq_chip = {
 	.unmask		= unmask_giuint_low,
 };
 
-static void ack_giuint_high(unsigned int irq)
+static void ack_giuint_high(struct irq_desc *desc)
 {
 	giu_write(GIUINTSTATH,
-		  1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+		  1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
-static void mask_giuint_high(unsigned int irq)
+static void mask_giuint_high(struct irq_desc *desc)
 {
-	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
-static void mask_ack_giuint_high(unsigned int irq)
+static void mask_ack_giuint_high(struct irq_desc *desc)
 {
 	unsigned int pin;
 
-	pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
+	pin = GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET;
 	giu_clear(GIUINTENH, 1 << pin);
 	giu_write(GIUINTSTATH, 1 << pin);
 }
 
-static void unmask_giuint_high(unsigned int irq)
+static void unmask_giuint_high(struct irq_desc *desc)
 {
-	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
 static struct irq_chip giuint_high_irq_chip = {
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/asic3.c b/drivers/mfd/asic3.c
index 95c1e6b..609da5b 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -142,7 +142,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
 	unsigned long flags;
 	struct asic3 *asic;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	asic = desc->handler_data;
 
@@ -225,9 +225,10 @@ static inline int asic3_irq_to_index(struct asic3 *asic, int irq)
 	return (irq - asic->irq_base) & 0xf;
 }
 
-static void asic3_mask_gpio_irq(unsigned int irq)
+static void asic3_mask_gpio_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 val, bank, index;
 	unsigned long flags;
 
@@ -241,9 +242,10 @@ static void asic3_mask_gpio_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_mask_irq(unsigned int irq)
+static void asic3_mask_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	int regval;
 	unsigned long flags;
 
@@ -262,9 +264,10 @@ static void asic3_mask_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_unmask_gpio_irq(unsigned int irq)
+static void asic3_unmask_gpio_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 val, bank, index;
 	unsigned long flags;
 
@@ -278,9 +281,10 @@ static void asic3_unmask_gpio_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_unmask_irq(unsigned int irq)
+static void asic3_unmask_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	int regval;
 	unsigned long flags;
 
@@ -299,9 +303,10 @@ static void asic3_unmask_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
+static int asic3_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 bank, index;
 	u16 trigger, level, edge, bit;
 	unsigned long flags;
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index df405af..26d6f9b 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(struct irq_desc *desc)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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/htc-egpio.c b/drivers/mfd/htc-egpio.c
index addb846..629176b 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -69,22 +69,24 @@ static inline void ack_irqs(struct egpio_info *ei)
 			ei->ack_write, ei->ack_register << ei->bus_shift);
 }
 
-static void egpio_ack(unsigned int irq)
+static void egpio_ack(struct irq_desc *desc)
 {
 }
 
 /* There does not appear to be a way to proactively mask interrupts
  * on the egpio chip itself.  So, we simply ignore interrupts that
  * aren't desired. */
-static void egpio_mask(unsigned int irq)
+static void egpio_mask(struct irq_desc *desc)
 {
-	struct egpio_info *ei = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct egpio_info *ei = get_irq_desc_chip_data(desc);
 	ei->irqs_enabled &= ~(1 << (irq - ei->irq_start));
 	pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled);
 }
-static void egpio_unmask(unsigned int irq)
+static void egpio_unmask(struct irq_desc *desc)
 {
-	struct egpio_info *ei = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct egpio_info *ei = get_irq_desc_chip_data(desc);
 	ei->irqs_enabled |= 1 << (irq - ei->irq_start);
 	pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled);
 }
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 26d9176..05f23cd 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -198,9 +198,10 @@ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc)
 				generic_handle_irq(irq_base + i);
 }
 
-static void t7l66xb_irq_mask(unsigned int irq)
+static void t7l66xb_irq_mask(struct irq_desc *desc)
 {
-	struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct t7l66xb *t7l66xb = get_irq_desc_chip_data(desc);
 	unsigned long			flags;
 	u8 imr;
 
@@ -211,8 +212,9 @@ static void t7l66xb_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&t7l66xb->lock, flags);
 }
 
-static void t7l66xb_irq_unmask(unsigned int irq)
+static void t7l66xb_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
 	unsigned long flags;
 	u8 imr;
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index c59e5c5..882a463 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -512,7 +512,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
 static void
 tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_data(irq);
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned int isr;
 	unsigned int i, irq_base;
 
@@ -526,13 +526,14 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
 		}
 }
 
-static void tc6393xb_irq_ack(unsigned int irq)
+static void tc6393xb_irq_ack(struct irq_desc *desc)
 {
 }
 
-static void tc6393xb_irq_mask(unsigned int irq)
+static void tc6393xb_irq_mask(struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u8 imr;
 
@@ -543,9 +544,10 @@ static void tc6393xb_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&tc6393xb->lock, flags);
 }
 
-static void tc6393xb_irq_unmask(unsigned int irq)
+static void tc6393xb_irq_unmask(struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u8 imr;
 
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 9df9a5a..b5e30d5 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(struct irq_desc *desc)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc, unsigned trigger)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
+	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..18ec226 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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	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(struct irq_desc *des)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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..36281e3 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(struct irq_desc *desc)
 {
 }
 
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index c542c7b..3c89196 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -296,9 +296,9 @@ static struct pci_port_ops dino_port_ops = {
 	.outl	= dino_out32
 };
 
-static void dino_disable_irq(unsigned int irq)
+static void dino_disable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct dino_device *dino_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
 
@@ -309,9 +309,9 @@ static void dino_disable_irq(unsigned int irq)
 	__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 }
 
-static void dino_enable_irq(unsigned int irq)
+static void dino_enable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct dino_device *dino_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
 	u32 tmp;
@@ -347,9 +347,9 @@ static void dino_enable_irq(unsigned int irq)
 	}
 }
 
-static unsigned int dino_startup_irq(unsigned int irq)
+static unsigned int dino_startup_irq(struct irq_desc *desc)
 {
-	dino_enable_irq(irq);
+	dino_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 46f503f..f00d28e 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -144,8 +144,9 @@ static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered *
 
 
 /* called by free irq */
-static void eisa_disable_irq(unsigned int irq)
+static void eisa_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 	EISA_DBG("disable irq %d\n", irq);
@@ -164,8 +165,9 @@ static void eisa_disable_irq(unsigned int irq)
 }
 
 /* called by request irq */
-static void eisa_enable_irq(unsigned int irq)
+static void eisa_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	EISA_DBG("enable irq %d\n", irq);
 		
@@ -182,9 +184,9 @@ static void eisa_enable_irq(unsigned int irq)
 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
 }
 
-static unsigned int eisa_startup_irq(unsigned int irq)
+static unsigned int eisa_startup_irq(struct irq_desc *desc)
 {
-	eisa_enable_irq(irq);
+	eisa_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index c4e1f3c..d2fc47b 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -106,9 +106,9 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
 	return NO_IRQ;
 }
 
-static void gsc_asic_disable_irq(unsigned int irq)
+static void gsc_asic_disable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct gsc_asic *irq_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
 	u32 imr;
@@ -122,9 +122,9 @@ static void gsc_asic_disable_irq(unsigned int irq)
 	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
 }
 
-static void gsc_asic_enable_irq(unsigned int irq)
+static void gsc_asic_enable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct gsc_asic *irq_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
 	u32 imr;
@@ -142,9 +142,9 @@ static void gsc_asic_enable_irq(unsigned int irq)
 	 */
 }
 
-static unsigned int gsc_asic_startup_irq(unsigned int irq)
+static unsigned int gsc_asic_startup_irq(struct irq_desc *desc)
 {
-	gsc_asic_enable_irq(irq);
+	gsc_asic_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index c768367..2ac290b 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -622,8 +622,9 @@ static struct vector_info *iosapic_get_vector(unsigned int irq)
 	return desc->chip_data;
 }
 
-static void iosapic_disable_irq(unsigned int irq)
+static void iosapic_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
@@ -635,8 +636,9 @@ static void iosapic_disable_irq(unsigned int irq)
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-static void iosapic_enable_irq(unsigned int irq)
+static void iosapic_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
 
@@ -686,8 +688,9 @@ printk("\n");
  * i386/ia64 support ISA devices and have to deal with
  * edge-triggered interrupts too.
  */
-static void iosapic_end_irq(unsigned int irq)
+static void iosapic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
 			vi->eoi_addr, vi->eoi_data);
@@ -695,16 +698,17 @@ static void iosapic_end_irq(unsigned int irq)
 	cpu_end_irq(irq);
 }
 
-static unsigned int iosapic_startup_irq(unsigned int irq)
+static unsigned int iosapic_startup_irq(struct irq_desc *desc)
 {
-	iosapic_enable_irq(irq);
+	iosapic_enable_irq(desc);
 	return 0;
 }
 
 #ifdef CONFIG_SMP
-static int iosapic_set_affinity_irq(unsigned int irq,
+static int iosapic_set_affinity_irq(struct irq_desc *desc,
 				     const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1, dummy_d0;
 	unsigned long flags;
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index f7806d8..084b1c7 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -286,8 +286,9 @@ superio_init(struct pci_dev *pcidev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
 
-static void superio_disable_irq(unsigned int irq)
+static void superio_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r8;
 
 	if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -303,8 +304,9 @@ static void superio_disable_irq(unsigned int irq)
 	outb (r8,IC_PIC1+1);
 }
 
-static void superio_enable_irq(unsigned int irq)
+static void superio_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r8;
 
 	if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -319,9 +321,9 @@ static void superio_enable_irq(unsigned int irq)
 	outb (r8,IC_PIC1+1);
 }
 
-static unsigned int superio_startup_irq(unsigned int irq)
+static unsigned int superio_startup_irq(struct irq_desc *desc)
 {
-	superio_enable_irq(irq);
+	superio_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 83aae47..6b5ad63 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1230,9 +1230,9 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
 	}
 }
 
-void dmar_msi_unmask(unsigned int irq)
+void dmar_msi_unmask(struct irq_desc *desc)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	/* unmask it */
@@ -1243,10 +1243,10 @@ 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(struct irq_desc *desc)
 {
 	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 +1256,9 @@ 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(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1268,9 +1268,9 @@ 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(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	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..3eecee3 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,14 +183,14 @@ static void msi_set_mask_bit(unsigned irq, u32 flag)
 	}
 }
 
-void mask_msi_irq(unsigned int irq)
+void mask_msi_irq(struct irq_desc *desc)
 {
-	msi_set_mask_bit(irq, 1);
+	msi_set_mask_bit(desc, 1);
 }
 
-void unmask_msi_irq(unsigned int irq)
+void unmask_msi_irq(struct irq_desc *desc)
 {
-	msi_set_mask_bit(irq, 0);
+	msi_set_mask_bit(desc, 0);
 }
 
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index 9554ad5..34a11e5 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -133,10 +133,11 @@ static void vlynq_reset(struct vlynq_device *dev)
 	msleep(5);
 }
 
-static void vlynq_irq_unmask(unsigned int irq)
+static void vlynq_irq_unmask(struct irq_desc *desc)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -146,10 +147,11 @@ static void vlynq_irq_unmask(unsigned int irq)
 	writel(val, &dev->remote->int_device[virq >> 2]);
 }
 
-static void vlynq_irq_mask(unsigned int irq)
+static void vlynq_irq_mask(struct irq_desc *desc)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -159,10 +161,11 @@ static void vlynq_irq_mask(unsigned int irq)
 	writel(val, &dev->remote->int_device[virq >> 2]);
 }
 
-static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
+static int vlynq_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -190,9 +193,9 @@ static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
 	return 0;
 }
 
-static void vlynq_local_ack(unsigned int irq)
+static void vlynq_local_ack(struct irq_desc *desc)
 {
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 
 	u32 status = readl(&dev->local->status);
 
@@ -201,9 +204,9 @@ static void vlynq_local_ack(unsigned int irq)
 	writel(status, &dev->local->status);
 }
 
-static void vlynq_remote_ack(unsigned int irq)
+static void vlynq_remote_ack(struct irq_desc *desc)
 {
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 
 	u32 status = readl(&dev->remote->status);
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 64cbbe4..fd16b80 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(struct irq_desc *desc, const struct cpumask *dest)
 {
 	unsigned tcpu = cpumask_first(dest);
 
-	return rebind_irq_to_cpu(irq, tcpu);
+	return rebind_irq_to_cpu(desc->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(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
 	if (VALID_EVTCHN(evtchn))
 		unmask_evtchn(evtchn);
 }
 
-static void disable_dynirq(unsigned int irq)
+static void disable_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
 	if (VALID_EVTCHN(evtchn))
 		mask_evtchn(evtchn);
 }
 
-static void ack_dynirq(unsigned int irq)
+static void ack_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
-	move_native_irq(irq);
+	move_native_irq(desc);
 
 	if (VALID_EVTCHN(evtchn))
 		clear_evtchn(evtchn);
 }
 
-static int retrigger_dynirq(unsigned int irq)
+static int retrigger_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->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..afc7506 100644
--- a/include/asm-generic/hardirq.h
+++ b/include/asm-generic/hardirq.h
@@ -12,9 +12,9 @@ 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(struct irq_desc *desc)
 {
-	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 #endif
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 659a765..6b4227a 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(struct irq_desc *);
+extern void dmar_msi_mask(struct irq_desc *);
+extern void dmar_msi_read(struct irq_desc *desc, struct msi_msg *msg);
+extern void dmar_msi_write(struct irq_desc *desc, 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 60f3368..fb8c376 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -110,30 +110,31 @@ 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)(struct irq_desc *desc);
+	void		(*shutdown)(struct irq_desc *desc);
+	void		(*enable)(struct irq_desc *desc);
+	void		(*disable)(struct irq_desc *desc);
+
+	void		(*ack)(struct irq_desc *desc);
+	void		(*mask)(struct irq_desc *desc);
+	void		(*mask_ack)(struct irq_desc *desc);
+	void		(*unmask)(struct irq_desc *desc);
+	void		(*eoi)(struct irq_desc *desc);
+
+	void		(*end)(struct irq_desc *desc);
+	int		(*set_affinity)(struct irq_desc *desc,
 					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)(struct irq_desc *desc);
 
-	void		(*bus_lock)(unsigned int irq);
-	void		(*bus_sync_unlock)(unsigned int irq);
+	int		(*set_type)(struct irq_desc *desc, unsigned int flow_type);
+	int		(*set_wake)(struct irq_desc *desc, unsigned int on);
+
+	void		(*bus_lock)(struct irq_desc *desc);
+	void		(*bus_sync_unlock)(struct irq_desc *desc);
 
 	/* Currently used only by UML, might disappear one day.*/
 #ifdef CONFIG_IRQ_RELEASE_METHOD
-	void		(*release)(unsigned int irq, void *dev_id);
+	void		(*release)(struct irq_desc *desc, void *dev_id);
 #endif
 	/*
 	 * For compatibility, ->typename is copied into ->name.
@@ -252,8 +253,8 @@ 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(struct irq_desc *desc);
+void move_masked_irq(struct irq_desc *desc);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ */
 
@@ -261,11 +262,11 @@ static inline void move_irq(int irq)
 {
 }
 
-static inline void move_native_irq(int irq)
+static inline void move_native_irq(struct irq_desc *desc)
 {
 }
 
-static inline void move_masked_irq(int irq)
+static inline void move_masked_irq(struct irq_desc *desc)
 {
 }
 
@@ -338,7 +339,7 @@ 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);
+void check_irq_resend(struct irq_desc *desc);
 
 /* 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..dc6a904 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -11,8 +11,8 @@ 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 mask_msi_irq(struct irq_desc *);
+extern void unmask_msi_irq(struct irq_desc *);
 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);
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 2295a31..02ab31e 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -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(desc, IRQ_TYPE_PROBE);
+			desc->chip->startup(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -76,7 +76,7 @@ unsigned long probe_irq_on(void)
 		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(desc))
 				desc->status |= IRQ_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
@@ -98,7 +98,7 @@ 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(desc);
 			} else
 				if (i < 32)
 					mask |= 1 << i;
@@ -137,7 +137,7 @@ unsigned int probe_irq_mask(unsigned long val)
 				mask |= 1 << i;
 
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -181,7 +181,7 @@ int probe_irq_off(unsigned long val)
 				nr_of_irqs++;
 			}
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3dcdd2f..043557a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -131,7 +131,7 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
 	unsigned long flags;
 
 	if (!desc) {
-		WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+		WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n",irq);
 		return -EINVAL;
 	}
 
@@ -287,40 +287,34 @@ EXPORT_SYMBOL_GPL(set_irq_nested_thread);
 /*
  * default enable function
  */
-static void default_enable(unsigned int irq)
+static void default_enable(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	desc->status &= ~IRQ_MASKED;
 }
 
 /*
  * default disable function
  */
-static void default_disable(unsigned int irq)
+static void default_disable(struct irq_desc *desc)
 {
 }
 
 /*
  * default startup function
  */
-static unsigned int default_startup(unsigned int irq)
+static unsigned int default_startup(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->enable(irq);
+	desc->chip->enable(desc);
 	return 0;
 }
 
 /*
  * default shutdown function
  */
-static void default_shutdown(unsigned int irq)
+static void default_shutdown(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 	desc->status |= IRQ_MASKED;
 }
 
@@ -350,30 +344,30 @@ void irq_chip_set_defaults(struct irq_chip *chip)
 		chip->end = dummy_irq_chip.end;
 }
 
-static inline void mask_ack_irq(struct irq_desc *desc, int irq)
+static inline void mask_ack_irq(struct irq_desc *desc)
 {
 	if (desc->chip->mask_ack)
-		desc->chip->mask_ack(irq);
+		desc->chip->mask_ack(desc);
 	else {
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 		if (desc->chip->ack)
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 	}
 	desc->status |= IRQ_MASKED;
 }
 
-static inline void mask_irq(struct irq_desc *desc, int irq)
+static inline void mask_irq(struct irq_desc *desc)
 {
 	if (desc->chip->mask) {
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 		desc->status |= IRQ_MASKED;
 	}
 }
 
-static inline void unmask_irq(struct irq_desc *desc, int irq)
+static inline void unmask_irq(struct irq_desc *desc)
 {
 	if (desc->chip->unmask) {
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 		desc->status &= ~IRQ_MASKED;
 	}
 }
@@ -476,7 +470,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 	irqreturn_t action_ret;
 
 	raw_spin_lock(&desc->lock);
-	mask_ack_irq(desc, irq);
+	mask_ack_irq(desc);
 
 	if (unlikely(desc->status & IRQ_INPROGRESS))
 		goto out_unlock;
@@ -502,7 +496,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 	desc->status &= ~IRQ_INPROGRESS;
 
 	if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))
-		unmask_irq(desc, irq);
+		unmask_irq(desc);
 out_unlock:
 	raw_spin_unlock(&desc->lock);
 }
@@ -539,7 +533,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
 		desc->status |= IRQ_PENDING;
-		mask_irq(desc, irq);
+		mask_irq(desc);
 		goto out;
 	}
 
@@ -554,7 +548,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(desc);
 
 	raw_spin_unlock(&desc->lock);
 }
@@ -590,14 +584,14 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
 		    !desc->action)) {
 		desc->status |= (IRQ_PENDING | IRQ_MASKED);
-		mask_ack_irq(desc, irq);
+		mask_ack_irq(desc);
 		goto out_unlock;
 	}
 	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/* Start handling the irq */
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
@@ -607,7 +601,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 		irqreturn_t action_ret;
 
 		if (unlikely(!action)) {
-			mask_irq(desc, irq);
+			mask_irq(desc);
 			goto out_unlock;
 		}
 
@@ -619,7 +613,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 		if (unlikely((desc->status &
 			       (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
 			      (IRQ_PENDING | IRQ_MASKED))) {
-			unmask_irq(desc, irq);
+			unmask_irq(desc);
 		}
 
 		desc->status &= ~IRQ_PENDING;
@@ -651,14 +645,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(desc);
 
 	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(desc);
 }
 
 void
@@ -670,7 +664,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 
 	if (!desc) {
 		printk(KERN_ERR
-		       "Trying to install type control for IRQ%d\n", irq);
+		       "Trying to install type control for IRQ%d\n",irq);
 		return;
 	}
 
@@ -689,13 +683,13 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 		desc->chip = &dummy_irq_chip;
 	}
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
 
 	/* Uninstall? */
 	if (handle == handle_bad_irq) {
 		if (desc->chip != &no_irq_chip)
-			mask_ack_irq(desc, irq);
+			mask_ack_irq(desc);
 		desc->status |= IRQ_DISABLED;
 		desc->depth = 1;
 	}
@@ -706,10 +700,10 @@ __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(desc);
 	}
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL_GPL(__set_irq_handler);
 
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index f30c9c7..d7a61a0 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(desc);
 }
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
@@ -295,22 +295,20 @@ 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(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	print_irq_desc(irq, desc);
-	ack_bad_irq(irq);
+	print_irq_desc(desc);
+	ack_bad_irq(desc);
 }
 
 /*
  * NOP functions
  */
-static void noop(unsigned int irq)
+static void noop(struct irq_desc *desc)
 {
 }
 
-static unsigned int noop_ret(unsigned int irq)
+static unsigned int noop_ret(struct irq_desc *des)
 {
 	return 0;
 }
@@ -464,19 +462,19 @@ unsigned int __do_IRQ(unsigned int irq)
 		 * No locking required for CPU-local interrupts:
 		 */
 		if (desc->chip->ack)
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 		if (likely(!(desc->status & IRQ_DISABLED))) {
 			action_ret = handle_IRQ_event(irq, desc->action);
 			if (!noirqdebug)
 				note_interrupt(irq, desc, action_ret);
 		}
-		desc->chip->end(irq);
+		desc->chip->end(desc);
 		return 1;
 	}
 
 	raw_spin_lock(&desc->lock);
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 	/*
 	 * 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 +534,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(desc);
 	raw_spin_unlock(&desc->lock);
 
 	return 1;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index c63f3bc..f74a64f 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -12,8 +12,8 @@ extern void compat_irq_chip_set_default_handler(struct irq_desc *desc);
 
 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);
+extern void __disable_irq(struct irq_desc *desc, bool susp);
+extern void __enable_irq(struct irq_desc *desc, bool resume);
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
@@ -41,16 +41,16 @@ extern int irq_select_affinity_usr(unsigned int irq);
 extern void irq_set_thread_affinity(struct irq_desc *desc);
 
 /* Inline functions for support of irq chips on slow busses */
-static inline void chip_bus_lock(unsigned int irq, struct irq_desc *desc)
+static inline void chip_bus_lock(struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_lock))
-		desc->chip->bus_lock(irq);
+		desc->chip->bus_lock(desc);
 }
 
-static inline void chip_bus_sync_unlock(unsigned int irq, struct irq_desc *desc)
+static inline void chip_bus_sync_unlock(struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_sync_unlock))
-		desc->chip->bus_sync_unlock(irq);
+		desc->chip->bus_sync_unlock(desc);
 }
 
 /*
@@ -61,10 +61,10 @@ 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/manage.c b/kernel/irq/manage.c
index 69a3d7b..868521a 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(desc, 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(desc, 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(desc, desc->affinity);
 
 	return 0;
 }
@@ -197,7 +197,7 @@ static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
 }
 #endif
 
-void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
+void __disable_irq(struct irq_desc *desc, bool suspend)
 {
 	if (suspend) {
 		if (!desc->action || (desc->action->flags & IRQF_TIMER))
@@ -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(desc);
 	}
 }
 
@@ -230,11 +230,11 @@ void disable_irq_nosync(unsigned int irq)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	__disable_irq(desc, irq, false);
+	__disable_irq(desc, false);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(disable_irq_nosync);
 
@@ -263,7 +263,7 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
-void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
+void __enable_irq(struct irq_desc *desc, bool resume)
 {
 	if (resume)
 		desc->status &= ~IRQ_SUSPENDED;
@@ -271,7 +271,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
 	switch (desc->depth) {
 	case 0:
  err_out:
-		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
+		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", desc->irq);
 		break;
 	case 1: {
 		unsigned int status = desc->status & ~IRQ_DISABLED;
@@ -280,7 +280,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
 			goto err_out;
 		/* Prevent probing on this irq: */
 		desc->status = status | IRQ_NOPROBE;
-		check_irq_resend(desc, irq);
+		check_irq_resend(desc);
 		/* fall-through */
 	}
 	default:
@@ -307,21 +307,20 @@ void enable_irq(unsigned int irq)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	__enable_irq(desc, irq, false);
+	__enable_irq(desc, false);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(enable_irq);
 
-static int set_irq_wake_real(unsigned int irq, unsigned int on)
+static int set_irq_wake_real(struct irq_desc *desc, unsigned int on)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	int ret = -ENXIO;
 
 	if (desc->chip->set_wake)
-		ret = desc->chip->set_wake(irq, on);
+		ret = desc->chip->set_wake(desc, on);
 
 	return ret;
 }
@@ -350,7 +349,7 @@ int set_irq_wake(unsigned int irq, unsigned int on)
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	if (on) {
 		if (desc->wake_depth++ == 0) {
-			ret = set_irq_wake_real(irq, on);
+			ret = set_irq_wake_real(desc, on);
 			if (ret)
 				desc->wake_depth = 0;
 			else
@@ -360,7 +359,7 @@ int set_irq_wake(unsigned int irq, unsigned int on)
 		if (desc->wake_depth == 0) {
 			WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
 		} else if (--desc->wake_depth == 0) {
-			ret = set_irq_wake_real(irq, on);
+			ret = set_irq_wake_real(desc, on);
 			if (ret)
 				desc->wake_depth = 1;
 			else
@@ -425,7 +424,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(desc, flags);
 
 	if (ret)
 		pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
@@ -481,10 +480,10 @@ static int irq_wait_for_interrupt(struct irqaction *action)
  * handler finished. unmask if the interrupt has not been disabled and
  * is marked MASKED.
  */
-static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc)
+static void irq_finalize_oneshot(struct irq_desc *desc)
 {
 again:
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irq(&desc->lock);
 
 	/*
@@ -498,17 +497,17 @@ again:
 	 */
 	if (unlikely(desc->status & IRQ_INPROGRESS)) {
 		raw_spin_unlock_irq(&desc->lock);
-		chip_bus_sync_unlock(irq, desc);
+		chip_bus_sync_unlock(desc);
 		cpu_relax();
 		goto again;
 	}
 
 	if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
 		desc->status &= ~IRQ_MASKED;
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 	}
 	raw_spin_unlock_irq(&desc->lock);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 
 #ifdef CONFIG_SMP
@@ -580,7 +579,7 @@ static int irq_thread(void *data)
 			action->thread_fn(action->irq, action->dev_id);
 
 			if (oneshot)
-				irq_finalize_oneshot(action->irq, desc);
+				irq_finalize_oneshot(desc);
 		}
 
 		wake = atomic_dec_and_test(&desc->threads_active);
@@ -756,7 +755,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(desc);
 		} else
 			/* Undo nested disables: */
 			desc->depth = 1;
@@ -790,7 +789,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	 */
 	if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) {
 		desc->status &= ~IRQ_SPURIOUS_DISABLED;
-		__enable_irq(desc, irq, false);
+		__enable_irq(desc, false);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -897,9 +896,9 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	if (!desc->action) {
 		desc->status |= IRQ_DISABLED;
 		if (desc->chip->shutdown)
-			desc->chip->shutdown(irq);
+			desc->chip->shutdown(desc);
 		else
-			desc->chip->disable(irq);
+			desc->chip->disable(desc);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -968,9 +967,9 @@ void free_irq(unsigned int irq, void *dev_id)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	kfree(__free_irq(irq, dev_id));
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(free_irq);
 
@@ -1077,9 +1076,9 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
 	action->name = devname;
 	action->dev_id = dev_id;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	retval = __setup_irq(irq, desc, action);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 
 	if (retval)
 		kfree(action);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 2419622..6b3d1aa 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -4,10 +4,8 @@
 
 #include "internals.h"
 
-void move_masked_irq(int irq)
+void move_masked_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
 
@@ -43,7 +41,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(desc, desc->pending_mask)) {
 			cpumask_copy(desc->affinity, desc->pending_mask);
 			irq_set_thread_affinity(desc);
 		}
@@ -51,18 +49,16 @@ void move_masked_irq(int irq)
 	cpumask_clear(desc->pending_mask);
 }
 
-void move_native_irq(int irq)
+void move_native_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
 
 	if (unlikely(desc->status & IRQ_DISABLED))
 		return;
 
-	desc->chip->mask(irq);
-	move_masked_irq(irq);
-	desc->chip->unmask(irq);
+	desc->chip->mask(desc);
+	move_masked_irq(desc);
+	desc->chip->unmask(desc);
 }
 
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index 0d4005d..a43c93d 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -29,7 +29,7 @@ void suspend_device_irqs(void)
 		unsigned long flags;
 
 		raw_spin_lock_irqsave(&desc->lock, flags);
-		__disable_irq(desc, irq, true);
+		__disable_irq(desc, true);
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 
@@ -57,7 +57,7 @@ void resume_device_irqs(void)
 			continue;
 
 		raw_spin_lock_irqsave(&desc->lock, flags);
-		__enable_irq(desc, irq, true);
+		__enable_irq(desc, true);
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 090c376..ddf75cd 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -53,14 +53,14 @@ static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
  *
  * Is called with interrupts disabled and desc->lock held.
  */
-void check_irq_resend(struct irq_desc *desc, unsigned int irq)
+void check_irq_resend(struct irq_desc *desc)
 {
 	unsigned int status = desc->status;
 
 	/*
 	 * Make sure the interrupt is enabled, before resending it:
 	 */
-	desc->chip->enable(irq);
+	desc->chip->enable(desc);
 
 	/*
 	 * We do not resend level type interrupts. Level type
@@ -70,10 +70,10 @@ 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(desc)) {
 #ifdef CONFIG_HARDIRQS_SW_RESEND
 			/* Set it pending and activate the softirq: */
-			set_bit(irq, irqs_resend);
+			set_bit(desc->irq, irqs_resend);
 			tasklet_schedule(&resend_tasklet);
 #endif
 		}
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 89fb90a..42b0972 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(desc);
 	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(desc);
 
 		mod_timer(&poll_spurious_irq_timer,
 			  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
-- 
1.6.4.2


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

* [PATCH 12/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- x86 and core
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

will have
void            (*ack)(struct irq_desc *desc);
void            (*mask)(struct irq_desc *desc);
void            (*mask_ack)(struct irq_desc *desc);
void            (*unmask)(struct irq_desc *desc);
void            (*eoi)(struct irq_desc *desc);

so for sparseirq with raidix tree, we don't call extra irq_to_desc, and could use desc directly

-v2: change all member of irq_chip to use desc only.
-v2.1: update after legacy_pic
-v2.2: update to irq one short fix

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/alpha/include/asm/hardirq.h            |    3 +-
 arch/alpha/kernel/irq.c                     |    4 +-
 arch/arm/include/asm/hw_irq.h               |    3 +-
 arch/arm/kernel/irq.c                       |    2 +-
 arch/blackfin/include/asm/hardirq.h         |    3 +-
 arch/blackfin/kernel/irqchip.c              |    4 +-
 arch/frv/include/asm/hardirq.h              |    3 +-
 arch/ia64/hp/sim/hpsim_irq.c                |    6 +-
 arch/ia64/include/asm/hardirq.h             |    2 +-
 arch/ia64/kernel/iosapic.c                  |   41 ++++----
 arch/ia64/kernel/irq.c                      |   10 +-
 arch/ia64/kernel/irq_lsapic.c               |    8 +-
 arch/ia64/kernel/msi_ia64.c                 |   21 +++--
 arch/ia64/kernel/smpboot.c                  |    6 +-
 arch/ia64/sn/kernel/irq.c                   |   25 +++--
 arch/ia64/sn/kernel/msi_sn.c                |   12 ++-
 arch/mips/include/asm/hardirq.h             |    3 +-
 arch/mips/kernel/irq.c                      |    3 +-
 arch/mn10300/include/asm/hardirq.h          |    2 +-
 arch/mn10300/kernel/irq.c                   |    4 +-
 arch/powerpc/include/asm/hardirq.h          |    4 +-
 arch/sh/include/asm/hardirq.h               |    3 +-
 arch/sh/kernel/irq.c                        |    4 +-
 arch/sparc/include/asm/hardirq_64.h         |    3 +-
 arch/sparc/kernel/irq_64.c                  |    3 +-
 arch/um/kernel/irq.c                        |    2 +-
 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              |  143 ++++++++++-----------------
 arch/x86/kernel/hpet.c                      |   16 ++--
 arch/x86/kernel/i8259.c                     |   31 ++++---
 arch/x86/kernel/irq.c                       |   12 +-
 arch/x86/kernel/uv_irq.c                    |   14 ++--
 arch/x86/kernel/visws_quirks.c              |   29 +++---
 arch/x86/kernel/vmiclock_32.c               |    8 +-
 arch/x86/lguest/boot.c                      |    8 +-
 arch/xtensa/include/asm/hardirq.h           |    3 +-
 arch/xtensa/kernel/irq.c                    |    4 +-
 drivers/dma/ipu/ipu_irq.c                   |   18 ++--
 drivers/gpio/langwell_gpio.c                |   11 +-
 drivers/gpio/pca953x.c                      |   23 +++--
 drivers/gpio/pl061.c                        |   19 ++--
 drivers/gpio/timbgpio.c                     |   17 ++--
 drivers/gpio/vr41xx_giu.c                   |   32 +++---
 drivers/infiniband/hw/ipath/ipath_iba6110.c |    2 +-
 drivers/mfd/asic3.c                         |   27 +++--
 drivers/mfd/ezx-pcap.c                      |   12 ++-
 drivers/mfd/htc-egpio.c                     |   12 ++-
 drivers/mfd/t7l66xb.c                       |    8 +-
 drivers/mfd/tc6393xb.c                      |   14 ++-
 drivers/mfd/twl4030-irq.c                   |   16 ++--
 drivers/mfd/wm831x-irq.c                    |   18 ++--
 drivers/misc/sgi-gru/grufile.c              |    2 +-
 drivers/parisc/dino.c                       |   12 +-
 drivers/parisc/eisa.c                       |   10 +-
 drivers/parisc/gsc.c                        |   12 +-
 drivers/parisc/iosapic.c                    |   16 ++-
 drivers/parisc/superio.c                    |   10 +-
 drivers/pci/dmar.c                          |   16 ++--
 drivers/pci/htirq.c                         |   22 ++--
 drivers/pci/msi.c                           |   13 ++-
 drivers/vlynq/vlynq.c                       |   23 +++--
 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                         |   49 +++++-----
 include/linux/msi.h                         |    4 +-
 kernel/irq/autoprobe.c                      |   12 +-
 kernel/irq/chip.c                           |   68 ++++++-------
 kernel/irq/handle.c                         |   24 ++---
 kernel/irq/internals.h                      |   16 ++--
 kernel/irq/manage.c                         |   67 ++++++-------
 kernel/irq/migration.c                      |   16 +--
 kernel/irq/pm.c                             |    4 +-
 kernel/irq/resend.c                         |    8 +-
 kernel/irq/spurious.c                       |    4 +-
 79 files changed, 585 insertions(+), 562 deletions(-)

diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h
index 242c09b..80f79f4 100644
--- a/arch/alpha/include/asm/hardirq.h
+++ b/arch/alpha/include/asm/hardirq.h
@@ -1,7 +1,8 @@
 #ifndef _ALPHA_HARDIRQ_H
 #define _ALPHA_HARDIRQ_H
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 #include <asm-generic/hardirq.h>
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 5f2cf23..08a6384 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -33,10 +33,10 @@
 
 volatile unsigned long irq_err_count;
 
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	irq_err_count++;
-	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
+	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", desc->irq);
 }
 
 #ifdef CONFIG_SMP 
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index 90831f6..43a8c03 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -4,7 +4,8 @@
 #ifndef _ARCH_ARM_HW_IRQ_H
 #define _ARCH_ARM_HW_IRQ_H
 
-static inline void ack_bad_irq(int irq)
+struct irq_desc;
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
 	extern unsigned long irq_err_count;
 	irq_err_count++;
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b7cb45b..265e78c 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -116,7 +116,7 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 	if (unlikely(irq >= NR_IRQS)) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Bad IRQ%u\n", irq);
-		ack_bad_irq(irq);
+		ack_bad_irq(irq_to_desc(irq));
 	} else {
 		generic_handle_irq(irq);
 	}
diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h
index c078dd7..e5ed5d5 100644
--- a/arch/blackfin/include/asm/hardirq.h
+++ b/arch/blackfin/include/asm/hardirq.h
@@ -9,7 +9,8 @@
 
 #define __ARCH_IRQ_EXIT_IRQS_DISABLED	1
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 /* Define until common code gets sane defaults */
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 64cff54..707a93b 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -15,10 +15,10 @@
 #include <asm/pda.h>
 
 static atomic_t irq_err_count;
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
-	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+	printk(KERN_ERR "IRQ: spurious interrupt %d\n", desc->irq);
 }
 
 static struct irq_desc bad_irq_desc = {
diff --git a/arch/frv/include/asm/hardirq.h b/arch/frv/include/asm/hardirq.h
index 5fc8b6f..2c49141 100644
--- a/arch/frv/include/asm/hardirq.h
+++ b/arch/frv/include/asm/hardirq.h
@@ -14,8 +14,9 @@
 
 #include <asm/atomic.h>
 
+struct irq_desc;
 extern atomic_t irq_err_count;
-static inline void ack_bad_irq(int irq)
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
 }
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index b272261..de7c5d1 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -11,18 +11,18 @@
 #include <linux/irq.h>
 
 static unsigned int
-hpsim_irq_startup (unsigned int irq)
+hpsim_irq_startup(struct irq_desc *desc)
 {
 	return 0;
 }
 
 static void
-hpsim_irq_noop (unsigned int irq)
+hpsim_irq_noop(struct irq_desc *desc)
 {
 }
 
 static int
-hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
+hpsim_set_affinity_noop(struct irq_desc *desc, const struct cpumask *b)
 {
 	return 0;
 }
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
index d514cd9..cc9950b 100644
--- a/arch/ia64/include/asm/hardirq.h
+++ b/arch/ia64/include/asm/hardirq.h
@@ -22,6 +22,6 @@
 
 extern void __iomem *ipi_base_addr;
 
-void ack_bad_irq(unsigned int irq);
+void ack_bad_irq(struct irq_desc *desc);
 
 #endif /* _ASM_IA64_HARDIRQ_H */
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 95ac77a..0edfbb4 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -264,7 +264,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
 }
 
 static void
-nop (unsigned int irq)
+nop(struct irq_desc *desc)
 {
 	/* do nothing... */
 }
@@ -294,8 +294,9 @@ kexec_disable_iosapic(void)
 #endif
 
 static void
-mask_irq (unsigned int irq)
+mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 low32;
 	int rte_index;
 	struct iosapic_rte_info *rte;
@@ -312,8 +313,9 @@ mask_irq (unsigned int irq)
 }
 
 static void
-unmask_irq (unsigned int irq)
+unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 low32;
 	int rte_index;
 	struct iosapic_rte_info *rte;
@@ -328,11 +330,11 @@ unmask_irq (unsigned int irq)
 	}
 }
 
-
 static int
-iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
+iosapic_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
 #ifdef CONFIG_SMP
+	unsigned int irq = desc->irq;
 	u32 high32, low32;
 	int cpu, dest, rte_index;
 	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
@@ -386,31 +388,32 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
  */
 
 static unsigned int
-iosapic_startup_level_irq (unsigned int irq)
+iosapic_startup_level_irq (struct irq_desc *desc)
 {
-	unmask_irq(irq);
+	unmask_irq(desc);
 	return 0;
 }
 
 static void
-iosapic_end_level_irq (unsigned int irq)
+iosapic_end_level_irq (struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ia64_vector vec = irq_to_vector(irq);
 	struct iosapic_rte_info *rte;
 	int do_unmask_irq = 0;
 
 	irq_complete_move(irq);
-	if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+	if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
 		do_unmask_irq = 1;
-		mask_irq(irq);
+		mask_irq(desc);
 	}
 
 	list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
 		iosapic_eoi(rte->iosapic->addr, vec);
 
 	if (unlikely(do_unmask_irq)) {
-		move_masked_irq(irq);
-		unmask_irq(irq);
+		move_masked_irq(desc);
+		unmask_irq(desc);
 	}
 }
 
@@ -437,9 +440,9 @@ static struct irq_chip irq_type_iosapic_level = {
  */
 
 static unsigned int
-iosapic_startup_edge_irq (unsigned int irq)
+iosapic_startup_edge_irq (struct irq_desc *desc)
 {
-	unmask_irq(irq);
+	unmask_irq(desc);
 	/*
 	 * IOSAPIC simply drops interrupts pended while the
 	 * corresponding pin was masked, so we can't know if an
@@ -449,20 +452,20 @@ iosapic_startup_edge_irq (unsigned int irq)
 }
 
 static void
-iosapic_ack_edge_irq (unsigned int irq)
+iosapic_ack_edge_irq (struct irq_desc *desc)
 {
-	struct irq_desc *idesc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 
 	irq_complete_move(irq);
-	move_native_irq(irq);
+	move_native_irq(desc);
 	/*
 	 * Once we have recorded IRQ_PENDING already, we can mask the
 	 * interrupt for real. This prevents IRQ storms from unhandled
 	 * devices.
 	 */
-	if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
+	if ((desc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
 	    (IRQ_PENDING|IRQ_DISABLED))
-		mask_irq(irq);
+		mask_irq(desc);
 }
 
 #define iosapic_enable_edge_irq		unmask_irq
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 94ee9d0..d4fe756 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -27,9 +27,9 @@
  * '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)
 {
-	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", desc->irq, smp_processor_id());
 }
 
 #ifdef CONFIG_IA64_GENERIC
@@ -162,10 +162,10 @@ static void migrate_irqs(void)
 			 */
 			if (desc->chip && desc->chip->disable &&
 				desc->chip->enable && desc->chip->set_affinity) {
-				desc->chip->disable(irq);
-				desc->chip->set_affinity(irq,
+				desc->chip->disable(desc);
+				desc->chip->set_affinity(desc,
 							 cpumask_of(new_cpu));
-				desc->chip->enable(irq);
+				desc->chip->enable(desc);
 			} else {
 				WARN_ON((!(desc->chip) || !(desc->chip->disable) ||
 						!(desc->chip->enable) ||
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index fc1549d..438641a 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -15,19 +15,21 @@
 #include <linux/irq.h>
 
 static unsigned int
-lsapic_noop_startup (unsigned int irq)
+lsapic_noop_startup(struct irq_desc *desc)
 {
 	return 0;
 }
 
 static void
-lsapic_noop (unsigned int irq)
+lsapic_noop(struct irq_desc *desc)
 {
 	/* nothing to do... */
 }
 
-static int lsapic_retrigger(unsigned int irq)
+static int lsapic_retrigger(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	ia64_resend_irq(irq);
 
 	return 1;
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 6c89228..d33f88c 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -12,9 +12,10 @@
 static struct irq_chip	ia64_msi_chip;
 
 #ifdef CONFIG_SMP
-static int ia64_set_msi_irq_affinity(unsigned int irq,
+static int ia64_set_msi_irq_affinity(struct irq_desc *desc,
 				      const cpumask_t *cpu_mask)
 {
+	unsigned int irq = desc->irq;
 	struct msi_msg msg;
 	u32 addr, data;
 	int cpu = first_cpu(*cpu_mask);
@@ -38,7 +39,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq,
 	msg.data = data;
 
 	write_msi_msg(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
+	cpumask_copy(desc->affinity, cpumask_of(cpu));
 
 	return 0;
 }
@@ -84,15 +85,17 @@ void ia64_teardown_msi_irq(unsigned int irq)
 	destroy_irq(irq);
 }
 
-static void ia64_ack_msi_irq(unsigned int irq)
+static void ia64_ack_msi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq_complete_move(irq);
-	move_native_irq(irq);
+	move_native_irq(desc);
 	ia64_eoi();
 }
 
-static int ia64_msi_retrigger_irq(unsigned int irq)
+static int ia64_msi_retrigger_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vector = irq_to_vector(irq);
 	ia64_resend_irq(vector);
 
@@ -132,8 +135,9 @@ void arch_teardown_msi_irq(unsigned int irq)
 
 #ifdef CONFIG_DMAR
 #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)
 {
+	unsigned int irq = desc->irq;
 	struct irq_cfg *cfg = irq_cfg + irq;
 	struct msi_msg msg;
 	int cpu = cpumask_first(mask);
@@ -152,7 +156,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 	msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
 
 	dmar_msi_write(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, mask);
+	cpumask_copy(desc->affinity, mask);
 
 	return 0;
 }
@@ -198,11 +202,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);
 	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;
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index e5230b2..7241118 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -696,9 +696,9 @@ int migrate_platform_irqs(unsigned int cpu)
 			 * polling before making changes.
 			 */
 			if (desc) {
-				desc->chip->disable(ia64_cpe_irq);
-				desc->chip->set_affinity(ia64_cpe_irq, mask);
-				desc->chip->enable(ia64_cpe_irq);
+				desc->chip->disable(desc);
+				desc->chip->set_affinity(desc, mask);
+				desc->chip->enable(desc);
 				printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
 			}
 		}
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 40d6eed..78bf9c3 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -77,31 +77,34 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
 	return ret_stuff.status;
 }
 
-static unsigned int sn_startup_irq(unsigned int irq)
+static unsigned int sn_startup_irq(struct irq_desc *desc)
 {
 	return 0;
 }
 
-static void sn_shutdown_irq(unsigned int irq)
+static void sn_shutdown_irq(struct irq_desc *desc)
 {
 }
 
 extern void ia64_mca_register_cpev(int);
 
-static void sn_disable_irq(unsigned int irq)
+static void sn_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
 		ia64_mca_register_cpev(0);
 }
 
-static void sn_enable_irq(unsigned int irq)
+static void sn_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
 		ia64_mca_register_cpev(irq);
 }
 
-static void sn_ack_irq(unsigned int irq)
+static void sn_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 event_occurred, mask;
 
 	irq = irq & 0xff;
@@ -110,11 +113,12 @@ static void sn_ack_irq(unsigned int irq)
 	HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
 	__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
 
-	move_native_irq(irq);
+	move_native_irq(desc);
 }
 
-static void sn_end_irq(unsigned int irq)
+static void sn_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ivec;
 	u64 event_occurred;
 
@@ -227,8 +231,9 @@ finish_up:
 	return new_irq_info;
 }
 
-static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
+static int sn_set_affinity_irq(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
 	nasid_t nasid;
 	int slice;
@@ -258,12 +263,12 @@ void sn_set_err_irq_affinity(unsigned int irq) { }
 #endif
 
 static void
-sn_mask_irq(unsigned int irq)
+sn_mask_irq(struct irq_desc *desc)
 {
 }
 
 static void
-sn_unmask_irq(unsigned int irq)
+sn_unmask_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index fbbfb97..df63df0 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -151,9 +151,10 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
 }
 
 #ifdef CONFIG_SMP
-static int sn_set_msi_irq_affinity(unsigned int irq,
+static int sn_set_msi_irq_affinity(struct irq_desc *desc,
 				    const struct cpumask *cpu_mask)
 {
+	unsigned int irq = desc->irq;
 	struct msi_msg msg;
 	int slice;
 	nasid_t nasid;
@@ -205,20 +206,21 @@ static int sn_set_msi_irq_affinity(unsigned int irq,
 	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
 	write_msi_msg(irq, &msg);
-	cpumask_copy(irq_desc[irq].affinity, cpu_mask);
+	cpumask_copy(desc->affinity, cpu_mask);
 
 	return 0;
 }
 #endif /* CONFIG_SMP */
 
-static void sn_ack_msi_irq(unsigned int irq)
+static void sn_ack_msi_irq(struct irq_desc *desc)
 {
-	move_native_irq(irq);
+	move_native_irq(desc);
 	ia64_eoi();
 }
 
-static int sn_msi_retrigger_irq(unsigned int irq)
+static int sn_msi_retrigger_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vector = irq;
 	ia64_resend_irq(vector);
 
diff --git a/arch/mips/include/asm/hardirq.h b/arch/mips/include/asm/hardirq.h
index c977a86..a230b5e 100644
--- a/arch/mips/include/asm/hardirq.h
+++ b/arch/mips/include/asm/hardirq.h
@@ -10,7 +10,8 @@
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 #define ack_bad_irq ack_bad_irq
 
 #include <asm-generic/hardirq.h>
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 981f86c..619db4a 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -74,8 +74,9 @@ void free_irqno(unsigned int irq)
  * '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)
 {
+	unsigned int irq = desc->irq;
 	smtc_im_ack_irq(irq);
 	printk("unexpected IRQ # %d\n", irq);
 }
diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h
index 54d9501..725a812 100644
--- a/arch/mn10300/include/asm/hardirq.h
+++ b/arch/mn10300/include/asm/hardirq.h
@@ -26,7 +26,7 @@ typedef struct {
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
-extern void ack_bad_irq(int irq);
+extern void ack_bad_irq(struct irq_desc *desc);
 
 /*
  * manipulate stubs in the MN10300 CPU Trap/Interrupt Vector table
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index e2d5ed8..bc98665 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -100,9 +100,9 @@ static struct irq_chip mn10300_cpu_pic_edge = {
  * '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(int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
-	printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 /*
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 3147a29..945c7d2 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -18,9 +18,9 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define local_softirq_pending()	__get_cpu_var(irq_stat).__softirq_pending
 
-static inline void ack_bad_irq(unsigned int irq)
+static inline void ack_bad_irq(struct irq_desc *desc)
 {
-	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 extern u64 arch_irq_stat_cpu(unsigned int cpu);
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index 48b1913..c5c08c8 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -11,6 +11,7 @@ typedef struct {
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
-extern void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+extern void ack_bad_irq(struct irq_desc *desc);
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index d2d41d0..556e3d3 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -25,10 +25,10 @@ atomic_t irq_err_count;
  * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
-void ack_bad_irq(unsigned int irq)
+void ack_bad_irq(struct irq_desc *desc)
 {
 	atomic_inc(&irq_err_count);
-	printk("unexpected IRQ trap at vector %02x\n", irq);
+	printk("unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 #if defined(CONFIG_PROC_FS)
diff --git a/arch/sparc/include/asm/hardirq_64.h b/arch/sparc/include/asm/hardirq_64.h
index 7c29fd1..6601974 100644
--- a/arch/sparc/include/asm/hardirq_64.h
+++ b/arch/sparc/include/asm/hardirq_64.h
@@ -12,7 +12,8 @@
 #define local_softirq_pending() \
 	(local_cpu_data().__softirq_pending)
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 
 #define HARDIRQ_BITS	8
 
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index e1cbdb9..4e7419c 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -689,8 +689,9 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 	return virt_irq;
 }
 
-void ack_bad_irq(unsigned int virt_irq)
+void ack_bad_irq(struct irq_desc_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
 
 	if (!ino)
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 89474ba..2c21218 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(reactivate_fd);
  * irq_chip must define (startup || enable) &&
  * (shutdown || disable) && end
  */
-static void dummy(unsigned int irq)
+static void dummy(struct irq_desc *desc)
 {
 }
 
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..d3b2f0b 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,8 @@ 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;
@@ -3481,9 +3448,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,8 +3548,9 @@ 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;
 
@@ -3590,7 +3558,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 	write_msi_msg(irq, &msg);
 
 	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
 		/*
 		 * irq migration in process context
 		 */
@@ -3672,9 +3639,8 @@ 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 +3650,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 +3682,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 +3697,8 @@ 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 +3708,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 +3770,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 +3795,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 +3806,11 @@ 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 +3819,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 +3874,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 +4364,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..2b601d3 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,9 @@ 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/arch/xtensa/include/asm/hardirq.h b/arch/xtensa/include/asm/hardirq.h
index 87cb19d..f0230ff 100644
--- a/arch/xtensa/include/asm/hardirq.h
+++ b/arch/xtensa/include/asm/hardirq.h
@@ -22,7 +22,8 @@ typedef struct {
 	unsigned int __nmi_count;	       /* arch dependent */
 } ____cacheline_aligned irq_cpustat_t;
 
-void ack_bad_irq(unsigned int irq);
+struct irq_desc;
+void ack_bad_irq(struct irq_desc *desc);
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
 #endif	/* _XTENSA_HARDIRQ_H */
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 8cd3848..f86cf05 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -30,9 +30,9 @@ atomic_t irq_err_count;
  * '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)
 {
-          printk("unexpected IRQ trap at vector %02x\n", irq);
+          printk("unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 
 /*
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index dd8ebc7..62f4307 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -94,9 +94,9 @@ static struct ipu_irq_map *src2map(unsigned int src)
 	return NULL;
 }
 
-static void ipu_irq_unmask(unsigned int irq)
+static void ipu_irq_unmask(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	uint32_t reg;
 	unsigned long lock_flags;
@@ -106,7 +106,7 @@ static void ipu_irq_unmask(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
@@ -117,9 +117,9 @@ static void ipu_irq_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
-static void ipu_irq_mask(unsigned int irq)
+static void ipu_irq_mask(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	uint32_t reg;
 	unsigned long lock_flags;
@@ -129,7 +129,7 @@ static void ipu_irq_mask(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
@@ -140,9 +140,9 @@ static void ipu_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
-static void ipu_irq_ack(unsigned int irq)
+static void ipu_irq_ack(struct irq_desc *desc)
 {
-	struct ipu_irq_map *map = get_irq_chip_data(irq);
+	struct ipu_irq_map *map = get_irq_desc_chip_data(desc);
 	struct ipu_irq_bank *bank;
 	unsigned long lock_flags;
 
@@ -151,7 +151,7 @@ static void ipu_irq_ack(unsigned int irq)
 	bank = map->bank;
 	if (!bank) {
 		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+		pr_err("IPU: %s(%u) - unmapped!\n", __func__, desc->irq);
 		return;
 	}
 
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 6c0ebbd..0eb44e7 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(struct irq_desc *desc, unsigned type)
 {
-	struct lnw_gpio *lnw = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
 };
 
-static void lnw_irq_mask(unsigned irq)
+static void lnw_irq_mask(struct irq_desc *desc)
 {
 };
 
@@ -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(desc);
 }
 
 static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index ab5daab..9fb1ba3 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);
+	unsigned int irq = desc->irq;
+	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);
+	unsigned int irq = desc->irq;
+	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);
+	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);
+	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);
+	unsigned int irq = desc->irq;
+	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/pl061.c b/drivers/gpio/pl061.c
index 3ad1eeb..9dddd6e 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -122,9 +122,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
 /*
  * PL061 GPIO IRQ
  */
-static void pl061_irq_disable(unsigned irq)
+static void pl061_irq_disable(struct irq_desc *desc)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpioie;
@@ -136,9 +137,10 @@ static void pl061_irq_disable(unsigned irq)
 	spin_unlock_irqrestore(&chip->irq_lock, flags);
 }
 
-static void pl061_irq_enable(unsigned irq)
+static void pl061_irq_enable(struct irq_desc *desc)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpioie;
@@ -150,9 +152,10 @@ static void pl061_irq_enable(unsigned irq)
 	spin_unlock_irqrestore(&chip->irq_lock, flags);
 }
 
-static int pl061_irq_type(unsigned irq, unsigned trigger)
+static int pl061_irq_type(struct irq_desc *desc, unsigned trigger)
 {
-	struct pl061_gpio *chip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct pl061_gpio *chip = get_irq_desc_chip_data(desc);
 	int offset = irq - chip->irq_base;
 	unsigned long flags;
 	u8 gpiois, gpioibe, gpioiev;
@@ -207,7 +210,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 	struct list_head *ptr;
 	struct pl061_gpio *chip;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 	list_for_each(ptr, chip_list) {
 		unsigned long pending;
 		int offset;
@@ -222,7 +225,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
 			generic_handle_irq(pl061_to_irq(&chip->gc, offset));
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index d4295fa..55c51f5 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(struct irq_desc *desc)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc, unsigned trigger)
 {
-	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(desc);
 	ipr = ioread32(tgpio->membase + TGPIO_IPR);
 	iowrite32(ipr, tgpio->membase + TGPIO_ICR);
 
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c
index b16c9a8..ea2e00f 100644
--- a/drivers/gpio/vr41xx_giu.c
+++ b/drivers/gpio/vr41xx_giu.c
@@ -111,28 +111,28 @@ static inline u16 giu_clear(u16 offset, u16 clear)
 	return data;
 }
 
-static void ack_giuint_low(unsigned int irq)
+static void ack_giuint_low(struct irq_desc *desc)
 {
-	giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
-static void mask_giuint_low(unsigned int irq)
+static void mask_giuint_low(struct irq_desc *desc)
 {
-	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
-static void mask_ack_giuint_low(unsigned int irq)
+static void mask_ack_giuint_low(struct irq_desc *desc)
 {
 	unsigned int pin;
 
-	pin = GPIO_PIN_OF_IRQ(irq);
+	pin = GPIO_PIN_OF_IRQ(desc->irq);
 	giu_clear(GIUINTENL, 1 << pin);
 	giu_write(GIUINTSTATL, 1 << pin);
 }
 
-static void unmask_giuint_low(unsigned int irq)
+static void unmask_giuint_low(struct irq_desc *desc)
 {
-	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(desc->irq));
 }
 
 static struct irq_chip giuint_low_irq_chip = {
@@ -143,29 +143,29 @@ static struct irq_chip giuint_low_irq_chip = {
 	.unmask		= unmask_giuint_low,
 };
 
-static void ack_giuint_high(unsigned int irq)
+static void ack_giuint_high(struct irq_desc *desc)
 {
 	giu_write(GIUINTSTATH,
-		  1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+		  1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
-static void mask_giuint_high(unsigned int irq)
+static void mask_giuint_high(struct irq_desc *desc)
 {
-	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
-static void mask_ack_giuint_high(unsigned int irq)
+static void mask_ack_giuint_high(struct irq_desc *desc)
 {
 	unsigned int pin;
 
-	pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
+	pin = GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET;
 	giu_clear(GIUINTENH, 1 << pin);
 	giu_write(GIUINTSTATH, 1 << pin);
 }
 
-static void unmask_giuint_high(unsigned int irq)
+static void unmask_giuint_high(struct irq_desc *desc)
 {
-	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(desc->irq) - GIUINT_HIGH_OFFSET));
 }
 
 static struct irq_chip giuint_high_irq_chip = {
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/asic3.c b/drivers/mfd/asic3.c
index 95c1e6b..609da5b 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -142,7 +142,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
 	unsigned long flags;
 	struct asic3 *asic;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	asic = desc->handler_data;
 
@@ -225,9 +225,10 @@ static inline int asic3_irq_to_index(struct asic3 *asic, int irq)
 	return (irq - asic->irq_base) & 0xf;
 }
 
-static void asic3_mask_gpio_irq(unsigned int irq)
+static void asic3_mask_gpio_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 val, bank, index;
 	unsigned long flags;
 
@@ -241,9 +242,10 @@ static void asic3_mask_gpio_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_mask_irq(unsigned int irq)
+static void asic3_mask_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	int regval;
 	unsigned long flags;
 
@@ -262,9 +264,10 @@ static void asic3_mask_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_unmask_gpio_irq(unsigned int irq)
+static void asic3_unmask_gpio_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 val, bank, index;
 	unsigned long flags;
 
@@ -278,9 +281,10 @@ static void asic3_unmask_gpio_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static void asic3_unmask_irq(unsigned int irq)
+static void asic3_unmask_irq(struct irq_desc *desc)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	int regval;
 	unsigned long flags;
 
@@ -299,9 +303,10 @@ static void asic3_unmask_irq(unsigned int irq)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
+static int asic3_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
-	struct asic3 *asic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct asic3 *asic = get_irq_desc_chip_data(desc);
 	u32 bank, index;
 	u16 trigger, level, edge, bit;
 	unsigned long flags;
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index df405af..26d6f9b 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(struct irq_desc *desc)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct pcap_chip *pcap = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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/htc-egpio.c b/drivers/mfd/htc-egpio.c
index addb846..629176b 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -69,22 +69,24 @@ static inline void ack_irqs(struct egpio_info *ei)
 			ei->ack_write, ei->ack_register << ei->bus_shift);
 }
 
-static void egpio_ack(unsigned int irq)
+static void egpio_ack(struct irq_desc *desc)
 {
 }
 
 /* There does not appear to be a way to proactively mask interrupts
  * on the egpio chip itself.  So, we simply ignore interrupts that
  * aren't desired. */
-static void egpio_mask(unsigned int irq)
+static void egpio_mask(struct irq_desc *desc)
 {
-	struct egpio_info *ei = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct egpio_info *ei = get_irq_desc_chip_data(desc);
 	ei->irqs_enabled &= ~(1 << (irq - ei->irq_start));
 	pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled);
 }
-static void egpio_unmask(unsigned int irq)
+static void egpio_unmask(struct irq_desc *desc)
 {
-	struct egpio_info *ei = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct egpio_info *ei = get_irq_desc_chip_data(desc);
 	ei->irqs_enabled |= 1 << (irq - ei->irq_start);
 	pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled);
 }
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 26d9176..05f23cd 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -198,9 +198,10 @@ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc)
 				generic_handle_irq(irq_base + i);
 }
 
-static void t7l66xb_irq_mask(unsigned int irq)
+static void t7l66xb_irq_mask(struct irq_desc *desc)
 {
-	struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct t7l66xb *t7l66xb = get_irq_desc_chip_data(desc);
 	unsigned long			flags;
 	u8 imr;
 
@@ -211,8 +212,9 @@ static void t7l66xb_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&t7l66xb->lock, flags);
 }
 
-static void t7l66xb_irq_unmask(unsigned int irq)
+static void t7l66xb_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
 	unsigned long flags;
 	u8 imr;
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index c59e5c5..882a463 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -512,7 +512,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
 static void
 tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_data(irq);
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned int isr;
 	unsigned int i, irq_base;
 
@@ -526,13 +526,14 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
 		}
 }
 
-static void tc6393xb_irq_ack(unsigned int irq)
+static void tc6393xb_irq_ack(struct irq_desc *desc)
 {
 }
 
-static void tc6393xb_irq_mask(unsigned int irq)
+static void tc6393xb_irq_mask(struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u8 imr;
 
@@ -543,9 +544,10 @@ static void tc6393xb_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&tc6393xb->lock, flags);
 }
 
-static void tc6393xb_irq_unmask(unsigned int irq)
+static void tc6393xb_irq_unmask(struct irq_desc *desc)
 {
-	struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct tc6393xb *tc6393xb = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u8 imr;
 
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 9df9a5a..b5e30d5 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(struct irq_desc *desc)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc, unsigned trigger)
 {
-	struct sih_agent *sih = get_irq_chip_data(irq);
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
+	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..18ec226 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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	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(struct irq_desc *des)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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(struct irq_desc *desc)
 {
-	struct wm831x *wm831x = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	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..36281e3 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(struct irq_desc *desc)
 {
 }
 
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index c542c7b..3c89196 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -296,9 +296,9 @@ static struct pci_port_ops dino_port_ops = {
 	.outl	= dino_out32
 };
 
-static void dino_disable_irq(unsigned int irq)
+static void dino_disable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct dino_device *dino_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
 
@@ -309,9 +309,9 @@ static void dino_disable_irq(unsigned int irq)
 	__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 }
 
-static void dino_enable_irq(unsigned int irq)
+static void dino_enable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct dino_device *dino_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
 	u32 tmp;
@@ -347,9 +347,9 @@ static void dino_enable_irq(unsigned int irq)
 	}
 }
 
-static unsigned int dino_startup_irq(unsigned int irq)
+static unsigned int dino_startup_irq(struct irq_desc *desc)
 {
-	dino_enable_irq(irq);
+	dino_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 46f503f..f00d28e 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -144,8 +144,9 @@ static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered *
 
 
 /* called by free irq */
-static void eisa_disable_irq(unsigned int irq)
+static void eisa_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 	EISA_DBG("disable irq %d\n", irq);
@@ -164,8 +165,9 @@ static void eisa_disable_irq(unsigned int irq)
 }
 
 /* called by request irq */
-static void eisa_enable_irq(unsigned int irq)
+static void eisa_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	EISA_DBG("enable irq %d\n", irq);
 		
@@ -182,9 +184,9 @@ static void eisa_enable_irq(unsigned int irq)
 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
 }
 
-static unsigned int eisa_startup_irq(unsigned int irq)
+static unsigned int eisa_startup_irq(struct irq_desc *desc)
 {
-	eisa_enable_irq(irq);
+	eisa_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index c4e1f3c..d2fc47b 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -106,9 +106,9 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
 	return NO_IRQ;
 }
 
-static void gsc_asic_disable_irq(unsigned int irq)
+static void gsc_asic_disable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct gsc_asic *irq_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
 	u32 imr;
@@ -122,9 +122,9 @@ static void gsc_asic_disable_irq(unsigned int irq)
 	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
 }
 
-static void gsc_asic_enable_irq(unsigned int irq)
+static void gsc_asic_enable_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
+	unsigned int irq = desc->irq;
 	struct gsc_asic *irq_dev = desc->chip_data;
 	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
 	u32 imr;
@@ -142,9 +142,9 @@ static void gsc_asic_enable_irq(unsigned int irq)
 	 */
 }
 
-static unsigned int gsc_asic_startup_irq(unsigned int irq)
+static unsigned int gsc_asic_startup_irq(struct irq_desc *desc)
 {
-	gsc_asic_enable_irq(irq);
+	gsc_asic_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index c768367..2ac290b 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -622,8 +622,9 @@ static struct vector_info *iosapic_get_vector(unsigned int irq)
 	return desc->chip_data;
 }
 
-static void iosapic_disable_irq(unsigned int irq)
+static void iosapic_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
@@ -635,8 +636,9 @@ static void iosapic_disable_irq(unsigned int irq)
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-static void iosapic_enable_irq(unsigned int irq)
+static void iosapic_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
 
@@ -686,8 +688,9 @@ printk("\n");
  * i386/ia64 support ISA devices and have to deal with
  * edge-triggered interrupts too.
  */
-static void iosapic_end_irq(unsigned int irq)
+static void iosapic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
 			vi->eoi_addr, vi->eoi_data);
@@ -695,16 +698,17 @@ static void iosapic_end_irq(unsigned int irq)
 	cpu_end_irq(irq);
 }
 
-static unsigned int iosapic_startup_irq(unsigned int irq)
+static unsigned int iosapic_startup_irq(struct irq_desc *desc)
 {
-	iosapic_enable_irq(irq);
+	iosapic_enable_irq(desc);
 	return 0;
 }
 
 #ifdef CONFIG_SMP
-static int iosapic_set_affinity_irq(unsigned int irq,
+static int iosapic_set_affinity_irq(struct irq_desc *desc,
 				     const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1, dummy_d0;
 	unsigned long flags;
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index f7806d8..084b1c7 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -286,8 +286,9 @@ superio_init(struct pci_dev *pcidev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
 
-static void superio_disable_irq(unsigned int irq)
+static void superio_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r8;
 
 	if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -303,8 +304,9 @@ static void superio_disable_irq(unsigned int irq)
 	outb (r8,IC_PIC1+1);
 }
 
-static void superio_enable_irq(unsigned int irq)
+static void superio_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r8;
 
 	if ((irq < 1) || (irq == 2) || (irq > 7)) {
@@ -319,9 +321,9 @@ static void superio_enable_irq(unsigned int irq)
 	outb (r8,IC_PIC1+1);
 }
 
-static unsigned int superio_startup_irq(unsigned int irq)
+static unsigned int superio_startup_irq(struct irq_desc *desc)
 {
-	superio_enable_irq(irq);
+	superio_enable_irq(desc);
 	return 0;
 }
 
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 83aae47..6b5ad63 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1230,9 +1230,9 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
 	}
 }
 
-void dmar_msi_unmask(unsigned int irq)
+void dmar_msi_unmask(struct irq_desc *desc)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	/* unmask it */
@@ -1243,10 +1243,10 @@ 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(struct irq_desc *desc)
 {
 	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 +1256,9 @@ 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(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	struct intel_iommu *iommu = get_irq_desc_data(desc);
 	unsigned long flag;
 
 	spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1268,9 +1268,9 @@ 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(struct irq_desc *desc, struct msi_msg *msg)
 {
-	struct intel_iommu *iommu = get_irq_data(irq);
+	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..3eecee3 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,14 +183,14 @@ static void msi_set_mask_bit(unsigned irq, u32 flag)
 	}
 }
 
-void mask_msi_irq(unsigned int irq)
+void mask_msi_irq(struct irq_desc *desc)
 {
-	msi_set_mask_bit(irq, 1);
+	msi_set_mask_bit(desc, 1);
 }
 
-void unmask_msi_irq(unsigned int irq)
+void unmask_msi_irq(struct irq_desc *desc)
 {
-	msi_set_mask_bit(irq, 0);
+	msi_set_mask_bit(desc, 0);
 }
 
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index 9554ad5..34a11e5 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -133,10 +133,11 @@ static void vlynq_reset(struct vlynq_device *dev)
 	msleep(5);
 }
 
-static void vlynq_irq_unmask(unsigned int irq)
+static void vlynq_irq_unmask(struct irq_desc *desc)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -146,10 +147,11 @@ static void vlynq_irq_unmask(unsigned int irq)
 	writel(val, &dev->remote->int_device[virq >> 2]);
 }
 
-static void vlynq_irq_mask(unsigned int irq)
+static void vlynq_irq_mask(struct irq_desc *desc)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -159,10 +161,11 @@ static void vlynq_irq_mask(unsigned int irq)
 	writel(val, &dev->remote->int_device[virq >> 2]);
 }
 
-static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
+static int vlynq_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
 	u32 val;
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 	int virq;
 
 	BUG_ON(!dev);
@@ -190,9 +193,9 @@ static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
 	return 0;
 }
 
-static void vlynq_local_ack(unsigned int irq)
+static void vlynq_local_ack(struct irq_desc *desc)
 {
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 
 	u32 status = readl(&dev->local->status);
 
@@ -201,9 +204,9 @@ static void vlynq_local_ack(unsigned int irq)
 	writel(status, &dev->local->status);
 }
 
-static void vlynq_remote_ack(unsigned int irq)
+static void vlynq_remote_ack(struct irq_desc *desc)
 {
-	struct vlynq_device *dev = get_irq_chip_data(irq);
+	struct vlynq_device *dev = get_irq_desc_chip_data(desc);
 
 	u32 status = readl(&dev->remote->status);
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 64cbbe4..fd16b80 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(struct irq_desc *desc, const struct cpumask *dest)
 {
 	unsigned tcpu = cpumask_first(dest);
 
-	return rebind_irq_to_cpu(irq, tcpu);
+	return rebind_irq_to_cpu(desc->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(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
 	if (VALID_EVTCHN(evtchn))
 		unmask_evtchn(evtchn);
 }
 
-static void disable_dynirq(unsigned int irq)
+static void disable_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
 	if (VALID_EVTCHN(evtchn))
 		mask_evtchn(evtchn);
 }
 
-static void ack_dynirq(unsigned int irq)
+static void ack_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->irq);
 
-	move_native_irq(irq);
+	move_native_irq(desc);
 
 	if (VALID_EVTCHN(evtchn))
 		clear_evtchn(evtchn);
 }
 
-static int retrigger_dynirq(unsigned int irq)
+static int retrigger_dynirq(struct irq_desc *desc)
 {
-	int evtchn = evtchn_from_irq(irq);
+	int evtchn = evtchn_from_irq(desc->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..afc7506 100644
--- a/include/asm-generic/hardirq.h
+++ b/include/asm-generic/hardirq.h
@@ -12,9 +12,9 @@ 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(struct irq_desc *desc)
 {
-	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", desc->irq);
 }
 #endif
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 659a765..6b4227a 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(struct irq_desc *);
+extern void dmar_msi_mask(struct irq_desc *);
+extern void dmar_msi_read(struct irq_desc *desc, struct msi_msg *msg);
+extern void dmar_msi_write(struct irq_desc *desc, 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 60f3368..fb8c376 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -110,30 +110,31 @@ 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)(struct irq_desc *desc);
+	void		(*shutdown)(struct irq_desc *desc);
+	void		(*enable)(struct irq_desc *desc);
+	void		(*disable)(struct irq_desc *desc);
+
+	void		(*ack)(struct irq_desc *desc);
+	void		(*mask)(struct irq_desc *desc);
+	void		(*mask_ack)(struct irq_desc *desc);
+	void		(*unmask)(struct irq_desc *desc);
+	void		(*eoi)(struct irq_desc *desc);
+
+	void		(*end)(struct irq_desc *desc);
+	int		(*set_affinity)(struct irq_desc *desc,
 					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)(struct irq_desc *desc);
 
-	void		(*bus_lock)(unsigned int irq);
-	void		(*bus_sync_unlock)(unsigned int irq);
+	int		(*set_type)(struct irq_desc *desc, unsigned int flow_type);
+	int		(*set_wake)(struct irq_desc *desc, unsigned int on);
+
+	void		(*bus_lock)(struct irq_desc *desc);
+	void		(*bus_sync_unlock)(struct irq_desc *desc);
 
 	/* Currently used only by UML, might disappear one day.*/
 #ifdef CONFIG_IRQ_RELEASE_METHOD
-	void		(*release)(unsigned int irq, void *dev_id);
+	void		(*release)(struct irq_desc *desc, void *dev_id);
 #endif
 	/*
 	 * For compatibility, ->typename is copied into ->name.
@@ -252,8 +253,8 @@ 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(struct irq_desc *desc);
+void move_masked_irq(struct irq_desc *desc);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ */
 
@@ -261,11 +262,11 @@ static inline void move_irq(int irq)
 {
 }
 
-static inline void move_native_irq(int irq)
+static inline void move_native_irq(struct irq_desc *desc)
 {
 }
 
-static inline void move_masked_irq(int irq)
+static inline void move_masked_irq(struct irq_desc *desc)
 {
 }
 
@@ -338,7 +339,7 @@ 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);
+void check_irq_resend(struct irq_desc *desc);
 
 /* 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..dc6a904 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -11,8 +11,8 @@ 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 mask_msi_irq(struct irq_desc *);
+extern void unmask_msi_irq(struct irq_desc *);
 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);
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 2295a31..02ab31e 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -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(desc, IRQ_TYPE_PROBE);
+			desc->chip->startup(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -76,7 +76,7 @@ unsigned long probe_irq_on(void)
 		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(desc))
 				desc->status |= IRQ_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
@@ -98,7 +98,7 @@ 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(desc);
 			} else
 				if (i < 32)
 					mask |= 1 << i;
@@ -137,7 +137,7 @@ unsigned int probe_irq_mask(unsigned long val)
 				mask |= 1 << i;
 
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -181,7 +181,7 @@ int probe_irq_off(unsigned long val)
 				nr_of_irqs++;
 			}
 			desc->status = status & ~IRQ_AUTODETECT;
-			desc->chip->shutdown(i);
+			desc->chip->shutdown(desc);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3dcdd2f..043557a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -131,7 +131,7 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
 	unsigned long flags;
 
 	if (!desc) {
-		WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+		WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n",irq);
 		return -EINVAL;
 	}
 
@@ -287,40 +287,34 @@ EXPORT_SYMBOL_GPL(set_irq_nested_thread);
 /*
  * default enable function
  */
-static void default_enable(unsigned int irq)
+static void default_enable(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	desc->status &= ~IRQ_MASKED;
 }
 
 /*
  * default disable function
  */
-static void default_disable(unsigned int irq)
+static void default_disable(struct irq_desc *desc)
 {
 }
 
 /*
  * default startup function
  */
-static unsigned int default_startup(unsigned int irq)
+static unsigned int default_startup(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->enable(irq);
+	desc->chip->enable(desc);
 	return 0;
 }
 
 /*
  * default shutdown function
  */
-static void default_shutdown(unsigned int irq)
+static void default_shutdown(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 	desc->status |= IRQ_MASKED;
 }
 
@@ -350,30 +344,30 @@ void irq_chip_set_defaults(struct irq_chip *chip)
 		chip->end = dummy_irq_chip.end;
 }
 
-static inline void mask_ack_irq(struct irq_desc *desc, int irq)
+static inline void mask_ack_irq(struct irq_desc *desc)
 {
 	if (desc->chip->mask_ack)
-		desc->chip->mask_ack(irq);
+		desc->chip->mask_ack(desc);
 	else {
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 		if (desc->chip->ack)
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 	}
 	desc->status |= IRQ_MASKED;
 }
 
-static inline void mask_irq(struct irq_desc *desc, int irq)
+static inline void mask_irq(struct irq_desc *desc)
 {
 	if (desc->chip->mask) {
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 		desc->status |= IRQ_MASKED;
 	}
 }
 
-static inline void unmask_irq(struct irq_desc *desc, int irq)
+static inline void unmask_irq(struct irq_desc *desc)
 {
 	if (desc->chip->unmask) {
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 		desc->status &= ~IRQ_MASKED;
 	}
 }
@@ -476,7 +470,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 	irqreturn_t action_ret;
 
 	raw_spin_lock(&desc->lock);
-	mask_ack_irq(desc, irq);
+	mask_ack_irq(desc);
 
 	if (unlikely(desc->status & IRQ_INPROGRESS))
 		goto out_unlock;
@@ -502,7 +496,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 	desc->status &= ~IRQ_INPROGRESS;
 
 	if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))
-		unmask_irq(desc, irq);
+		unmask_irq(desc);
 out_unlock:
 	raw_spin_unlock(&desc->lock);
 }
@@ -539,7 +533,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
 		desc->status |= IRQ_PENDING;
-		mask_irq(desc, irq);
+		mask_irq(desc);
 		goto out;
 	}
 
@@ -554,7 +548,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(desc);
 
 	raw_spin_unlock(&desc->lock);
 }
@@ -590,14 +584,14 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
 		    !desc->action)) {
 		desc->status |= (IRQ_PENDING | IRQ_MASKED);
-		mask_ack_irq(desc, irq);
+		mask_ack_irq(desc);
 		goto out_unlock;
 	}
 	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/* Start handling the irq */
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
@@ -607,7 +601,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 		irqreturn_t action_ret;
 
 		if (unlikely(!action)) {
-			mask_irq(desc, irq);
+			mask_irq(desc);
 			goto out_unlock;
 		}
 
@@ -619,7 +613,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 		if (unlikely((desc->status &
 			       (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
 			      (IRQ_PENDING | IRQ_MASKED))) {
-			unmask_irq(desc, irq);
+			unmask_irq(desc);
 		}
 
 		desc->status &= ~IRQ_PENDING;
@@ -651,14 +645,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(desc);
 
 	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(desc);
 }
 
 void
@@ -670,7 +664,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 
 	if (!desc) {
 		printk(KERN_ERR
-		       "Trying to install type control for IRQ%d\n", irq);
+		       "Trying to install type control for IRQ%d\n",irq);
 		return;
 	}
 
@@ -689,13 +683,13 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 		desc->chip = &dummy_irq_chip;
 	}
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
 
 	/* Uninstall? */
 	if (handle == handle_bad_irq) {
 		if (desc->chip != &no_irq_chip)
-			mask_ack_irq(desc, irq);
+			mask_ack_irq(desc);
 		desc->status |= IRQ_DISABLED;
 		desc->depth = 1;
 	}
@@ -706,10 +700,10 @@ __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(desc);
 	}
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL_GPL(__set_irq_handler);
 
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index f30c9c7..d7a61a0 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(desc);
 }
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
@@ -295,22 +295,20 @@ 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(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	print_irq_desc(irq, desc);
-	ack_bad_irq(irq);
+	print_irq_desc(desc);
+	ack_bad_irq(desc);
 }
 
 /*
  * NOP functions
  */
-static void noop(unsigned int irq)
+static void noop(struct irq_desc *desc)
 {
 }
 
-static unsigned int noop_ret(unsigned int irq)
+static unsigned int noop_ret(struct irq_desc *des)
 {
 	return 0;
 }
@@ -464,19 +462,19 @@ unsigned int __do_IRQ(unsigned int irq)
 		 * No locking required for CPU-local interrupts:
 		 */
 		if (desc->chip->ack)
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 		if (likely(!(desc->status & IRQ_DISABLED))) {
 			action_ret = handle_IRQ_event(irq, desc->action);
 			if (!noirqdebug)
 				note_interrupt(irq, desc, action_ret);
 		}
-		desc->chip->end(irq);
+		desc->chip->end(desc);
 		return 1;
 	}
 
 	raw_spin_lock(&desc->lock);
 	if (desc->chip->ack)
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 	/*
 	 * 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 +534,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(desc);
 	raw_spin_unlock(&desc->lock);
 
 	return 1;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index c63f3bc..f74a64f 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -12,8 +12,8 @@ extern void compat_irq_chip_set_default_handler(struct irq_desc *desc);
 
 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);
+extern void __disable_irq(struct irq_desc *desc, bool susp);
+extern void __enable_irq(struct irq_desc *desc, bool resume);
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
@@ -41,16 +41,16 @@ extern int irq_select_affinity_usr(unsigned int irq);
 extern void irq_set_thread_affinity(struct irq_desc *desc);
 
 /* Inline functions for support of irq chips on slow busses */
-static inline void chip_bus_lock(unsigned int irq, struct irq_desc *desc)
+static inline void chip_bus_lock(struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_lock))
-		desc->chip->bus_lock(irq);
+		desc->chip->bus_lock(desc);
 }
 
-static inline void chip_bus_sync_unlock(unsigned int irq, struct irq_desc *desc)
+static inline void chip_bus_sync_unlock(struct irq_desc *desc)
 {
 	if (unlikely(desc->chip->bus_sync_unlock))
-		desc->chip->bus_sync_unlock(irq);
+		desc->chip->bus_sync_unlock(desc);
 }
 
 /*
@@ -61,10 +61,10 @@ 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/manage.c b/kernel/irq/manage.c
index 69a3d7b..868521a 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(desc, 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(desc, 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(desc, desc->affinity);
 
 	return 0;
 }
@@ -197,7 +197,7 @@ static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
 }
 #endif
 
-void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
+void __disable_irq(struct irq_desc *desc, bool suspend)
 {
 	if (suspend) {
 		if (!desc->action || (desc->action->flags & IRQF_TIMER))
@@ -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(desc);
 	}
 }
 
@@ -230,11 +230,11 @@ void disable_irq_nosync(unsigned int irq)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	__disable_irq(desc, irq, false);
+	__disable_irq(desc, false);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(disable_irq_nosync);
 
@@ -263,7 +263,7 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
-void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
+void __enable_irq(struct irq_desc *desc, bool resume)
 {
 	if (resume)
 		desc->status &= ~IRQ_SUSPENDED;
@@ -271,7 +271,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
 	switch (desc->depth) {
 	case 0:
  err_out:
-		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
+		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", desc->irq);
 		break;
 	case 1: {
 		unsigned int status = desc->status & ~IRQ_DISABLED;
@@ -280,7 +280,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
 			goto err_out;
 		/* Prevent probing on this irq: */
 		desc->status = status | IRQ_NOPROBE;
-		check_irq_resend(desc, irq);
+		check_irq_resend(desc);
 		/* fall-through */
 	}
 	default:
@@ -307,21 +307,20 @@ void enable_irq(unsigned int irq)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	__enable_irq(desc, irq, false);
+	__enable_irq(desc, false);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(enable_irq);
 
-static int set_irq_wake_real(unsigned int irq, unsigned int on)
+static int set_irq_wake_real(struct irq_desc *desc, unsigned int on)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	int ret = -ENXIO;
 
 	if (desc->chip->set_wake)
-		ret = desc->chip->set_wake(irq, on);
+		ret = desc->chip->set_wake(desc, on);
 
 	return ret;
 }
@@ -350,7 +349,7 @@ int set_irq_wake(unsigned int irq, unsigned int on)
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	if (on) {
 		if (desc->wake_depth++ == 0) {
-			ret = set_irq_wake_real(irq, on);
+			ret = set_irq_wake_real(desc, on);
 			if (ret)
 				desc->wake_depth = 0;
 			else
@@ -360,7 +359,7 @@ int set_irq_wake(unsigned int irq, unsigned int on)
 		if (desc->wake_depth == 0) {
 			WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
 		} else if (--desc->wake_depth == 0) {
-			ret = set_irq_wake_real(irq, on);
+			ret = set_irq_wake_real(desc, on);
 			if (ret)
 				desc->wake_depth = 1;
 			else
@@ -425,7 +424,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(desc, flags);
 
 	if (ret)
 		pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
@@ -481,10 +480,10 @@ static int irq_wait_for_interrupt(struct irqaction *action)
  * handler finished. unmask if the interrupt has not been disabled and
  * is marked MASKED.
  */
-static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc)
+static void irq_finalize_oneshot(struct irq_desc *desc)
 {
 again:
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	raw_spin_lock_irq(&desc->lock);
 
 	/*
@@ -498,17 +497,17 @@ again:
 	 */
 	if (unlikely(desc->status & IRQ_INPROGRESS)) {
 		raw_spin_unlock_irq(&desc->lock);
-		chip_bus_sync_unlock(irq, desc);
+		chip_bus_sync_unlock(desc);
 		cpu_relax();
 		goto again;
 	}
 
 	if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
 		desc->status &= ~IRQ_MASKED;
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 	}
 	raw_spin_unlock_irq(&desc->lock);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 
 #ifdef CONFIG_SMP
@@ -580,7 +579,7 @@ static int irq_thread(void *data)
 			action->thread_fn(action->irq, action->dev_id);
 
 			if (oneshot)
-				irq_finalize_oneshot(action->irq, desc);
+				irq_finalize_oneshot(desc);
 		}
 
 		wake = atomic_dec_and_test(&desc->threads_active);
@@ -756,7 +755,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(desc);
 		} else
 			/* Undo nested disables: */
 			desc->depth = 1;
@@ -790,7 +789,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	 */
 	if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) {
 		desc->status &= ~IRQ_SPURIOUS_DISABLED;
-		__enable_irq(desc, irq, false);
+		__enable_irq(desc, false);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -897,9 +896,9 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	if (!desc->action) {
 		desc->status |= IRQ_DISABLED;
 		if (desc->chip->shutdown)
-			desc->chip->shutdown(irq);
+			desc->chip->shutdown(desc);
 		else
-			desc->chip->disable(irq);
+			desc->chip->disable(desc);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -968,9 +967,9 @@ void free_irq(unsigned int irq, void *dev_id)
 	if (!desc)
 		return;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	kfree(__free_irq(irq, dev_id));
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(free_irq);
 
@@ -1077,9 +1076,9 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
 	action->name = devname;
 	action->dev_id = dev_id;
 
-	chip_bus_lock(irq, desc);
+	chip_bus_lock(desc);
 	retval = __setup_irq(irq, desc, action);
-	chip_bus_sync_unlock(irq, desc);
+	chip_bus_sync_unlock(desc);
 
 	if (retval)
 		kfree(action);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 2419622..6b3d1aa 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -4,10 +4,8 @@
 
 #include "internals.h"
 
-void move_masked_irq(int irq)
+void move_masked_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
 
@@ -43,7 +41,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(desc, desc->pending_mask)) {
 			cpumask_copy(desc->affinity, desc->pending_mask);
 			irq_set_thread_affinity(desc);
 		}
@@ -51,18 +49,16 @@ void move_masked_irq(int irq)
 	cpumask_clear(desc->pending_mask);
 }
 
-void move_native_irq(int irq)
+void move_native_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-
 	if (likely(!(desc->status & IRQ_MOVE_PENDING)))
 		return;
 
 	if (unlikely(desc->status & IRQ_DISABLED))
 		return;
 
-	desc->chip->mask(irq);
-	move_masked_irq(irq);
-	desc->chip->unmask(irq);
+	desc->chip->mask(desc);
+	move_masked_irq(desc);
+	desc->chip->unmask(desc);
 }
 
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index 0d4005d..a43c93d 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -29,7 +29,7 @@ void suspend_device_irqs(void)
 		unsigned long flags;
 
 		raw_spin_lock_irqsave(&desc->lock, flags);
-		__disable_irq(desc, irq, true);
+		__disable_irq(desc, true);
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 
@@ -57,7 +57,7 @@ void resume_device_irqs(void)
 			continue;
 
 		raw_spin_lock_irqsave(&desc->lock, flags);
-		__enable_irq(desc, irq, true);
+		__enable_irq(desc, true);
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 090c376..ddf75cd 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -53,14 +53,14 @@ static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
  *
  * Is called with interrupts disabled and desc->lock held.
  */
-void check_irq_resend(struct irq_desc *desc, unsigned int irq)
+void check_irq_resend(struct irq_desc *desc)
 {
 	unsigned int status = desc->status;
 
 	/*
 	 * Make sure the interrupt is enabled, before resending it:
 	 */
-	desc->chip->enable(irq);
+	desc->chip->enable(desc);
 
 	/*
 	 * We do not resend level type interrupts. Level type
@@ -70,10 +70,10 @@ 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(desc)) {
 #ifdef CONFIG_HARDIRQS_SW_RESEND
 			/* Set it pending and activate the softirq: */
-			set_bit(irq, irqs_resend);
+			set_bit(desc->irq, irqs_resend);
 			tasklet_schedule(&resend_tasklet);
 #endif
 		}
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 89fb90a..42b0972 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(desc);
 	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(desc);
 
 		mod_timer(&poll_spurious_irq_timer,
 			  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
-- 
1.6.4.2

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

* [PATCH 13/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- other arch
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

will have
void            (*ack)(struct irq_desc *desc);
void            (*mask)(struct irq_desc *desc);
void            (*mask_ack)(struct irq_desc *desc);
void            (*unmask)(struct irq_desc *desc);
void            (*eoi)(struct irq_desc *desc);

so for sparseirq with raidix tree, we don't call extra irq_to_desc, and could use desc directly

-v2: change all member of irq_chip to use desc only.
-v2.1: update after legacy_pic
-v2.2: update to irq one short fix

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 Documentation/DocBook/genericirq.tmpl            |   24 ++--
 arch/alpha/kernel/irq_alpha.c                    |    4 +-
 arch/alpha/kernel/irq_i8259.c                    |   22 +++--
 arch/alpha/kernel/irq_impl.h                     |   10 +-
 arch/alpha/kernel/irq_pyxis.c                    |   21 ++--
 arch/alpha/kernel/irq_srm.c                      |   18 ++--
 arch/alpha/kernel/sys_alcor.c                    |   28 +++---
 arch/alpha/kernel/sys_cabriolet.c                |   18 ++--
 arch/alpha/kernel/sys_dp264.c                    |   44 ++++----
 arch/alpha/kernel/sys_eb64p.c                    |   18 ++--
 arch/alpha/kernel/sys_eiger.c                    |   18 ++--
 arch/alpha/kernel/sys_jensen.c                   |   40 ++++----
 arch/alpha/kernel/sys_marvel.c                   |   26 +++---
 arch/alpha/kernel/sys_mikasa.c                   |   18 ++--
 arch/alpha/kernel/sys_noritake.c                 |   18 ++--
 arch/alpha/kernel/sys_rawhide.c                  |   19 ++--
 arch/alpha/kernel/sys_rx164.c                    |   18 ++--
 arch/alpha/kernel/sys_sable.c                    |   26 +++---
 arch/alpha/kernel/sys_takara.c                   |   18 ++--
 arch/alpha/kernel/sys_titan.c                    |   22 ++--
 arch/alpha/kernel/sys_wildfire.c                 |   32 ++++---
 arch/arm/common/gic.c                            |   20 ++--
 arch/arm/common/it8152.c                         |    8 +-
 arch/arm/common/locomo.c                         |   18 ++--
 arch/arm/common/sa1111.c                         |   58 ++++++----
 arch/arm/common/vic.c                            |   21 +++--
 arch/arm/kernel/ecard.c                          |   12 ++-
 arch/arm/kernel/smp_twd.c                        |    6 +-
 arch/arm/mach-aaec2000/core.c                    |    6 +-
 arch/arm/mach-at91/gpio.c                        |   17 ++--
 arch/arm/mach-at91/irq.c                         |   15 ++-
 arch/arm/mach-bcmring/irq.c                      |   24 +++-
 arch/arm/mach-clps711x/irq.c                     |   18 ++-
 arch/arm/mach-davinci/cp_intc.c                  |   14 ++-
 arch/arm/mach-davinci/gpio.c                     |   32 +++---
 arch/arm/mach-davinci/irq.c                      |    9 +-
 arch/arm/mach-dove/irq.c                         |    9 +-
 arch/arm/mach-ebsa110/core.c                     |    6 +-
 arch/arm/mach-ep93xx/gpio.c                      |   20 ++--
 arch/arm/mach-footbridge/common.c                |    6 +-
 arch/arm/mach-footbridge/isa-irq.c               |   18 ++-
 arch/arm/mach-gemini/gpio.c                      |   12 ++-
 arch/arm/mach-gemini/irq.c                       |    9 +-
 arch/arm/mach-h720x/common.c                     |   15 ++-
 arch/arm/mach-h720x/cpu-h7202.c                  |    8 +-
 arch/arm/mach-integrator/integrator_ap.c         |    6 +-
 arch/arm/mach-integrator/integrator_cp.c         |   18 ++-
 arch/arm/mach-iop13xx/irq.c                      |   24 +++--
 arch/arm/mach-iop13xx/msi.c                      |    2 +-
 arch/arm/mach-iop32x/irq.c                       |    6 +-
 arch/arm/mach-ixp2000/core.c                     |   30 ++++--
 arch/arm/mach-ixp2000/ixdp2x00.c                 |   10 +-
 arch/arm/mach-ixp2000/ixdp2x01.c                 |   10 +-
 arch/arm/mach-ixp23xx/core.c                     |   25 +++--
 arch/arm/mach-ixp23xx/ixdp2351.c                 |   20 ++--
 arch/arm/mach-ixp4xx/common.c                    |   14 ++-
 arch/arm/mach-ks8695/irq.c                       |   31 +++---
 arch/arm/mach-l7200/core.c                       |    6 +-
 arch/arm/mach-lh7a40x/arch-kev7a400.c            |    9 +-
 arch/arm/mach-lh7a40x/arch-lpd7a40x.c            |   13 ++-
 arch/arm/mach-lh7a40x/irq-lh7a400.c              |    9 +-
 arch/arm/mach-lh7a40x/irq-lh7a404.c              |   18 ++-
 arch/arm/mach-lh7a40x/irq-lpd7a40x.c             |   12 ++-
 arch/arm/mach-netx/generic.c                     |   12 ++-
 arch/arm/mach-nomadik/gpio.c                     |   26 +++--
 arch/arm/mach-ns9xxx/board-a9m9750dev.c          |   15 ++-
 arch/arm/mach-ns9xxx/irq.c                       |   15 ++-
 arch/arm/mach-omap1/fpga.c                       |   14 ++-
 arch/arm/mach-omap1/irq.c                        |   24 +++--
 arch/arm/mach-omap2/irq.c                        |   14 ++-
 arch/arm/mach-pnx4008/irq.c                      |   22 +++--
 arch/arm/mach-pxa/balloon3.c                     |    8 +-
 arch/arm/mach-pxa/generic.h                      |    3 +-
 arch/arm/mach-pxa/irq.c                          |   18 ++-
 arch/arm/mach-pxa/lpd270.c                       |    6 +-
 arch/arm/mach-pxa/lubbock.c                      |    6 +-
 arch/arm/mach-pxa/mainstone.c                    |    6 +-
 arch/arm/mach-pxa/pcm990-baseboard.c             |    6 +-
 arch/arm/mach-pxa/pxa25x.c                       |    4 +-
 arch/arm/mach-pxa/pxa27x.c                       |    4 +-
 arch/arm/mach-pxa/pxa3xx.c                       |    9 +-
 arch/arm/mach-pxa/viper.c                        |    9 +-
 arch/arm/mach-pxa/zeus.c                         |   12 ++-
 arch/arm/mach-rpc/irq.c                          |   27 +++--
 arch/arm/mach-s3c2410/bast-irq.c                 |   24 +++--
 arch/arm/mach-s3c2412/irq.c                      |   39 ++++---
 arch/arm/mach-s3c2440/irq.c                      |   15 ++-
 arch/arm/mach-s3c2443/irq.c                      |   75 ++++++++-----
 arch/arm/mach-sa1100/irq.c                       |   36 ++++--
 arch/arm/mach-sa1100/neponset.c                  |    8 +-
 arch/arm/mach-shark/irq.c                        |   10 ++-
 arch/arm/mach-stmp378x/stmp378x.c                |    9 +-
 arch/arm/mach-stmp37xx/stmp37xx.c                |    9 +-
 arch/arm/mach-versatile/core.c                   |    6 +-
 arch/arm/mach-w90x900/irq.c                      |    8 +-
 arch/arm/oprofile/op_model_mpcore.c              |    4 +-
 arch/arm/plat-mxc/gpio.c                         |   12 ++-
 arch/arm/plat-mxc/irq.c                          |    6 +-
 arch/arm/plat-omap/gpio.c                        |   37 ++++---
 arch/arm/plat-orion/gpio.c                       |   21 ++--
 arch/arm/plat-orion/irq.c                        |   10 +-
 arch/arm/plat-pxa/gpio.c                         |   12 ++-
 arch/arm/plat-pxa/include/plat/gpio.h            |    3 +-
 arch/arm/plat-s3c24xx/include/plat/irq.h         |    4 +-
 arch/arm/plat-s3c24xx/irq-pm.c                   |    3 +-
 arch/arm/plat-s3c24xx/irq.c                      |  116 ++++++++++++---------
 arch/arm/plat-s5pc1xx/irq-eint.c                 |   41 ++++---
 arch/arm/plat-s5pc1xx/irq-gpio.c                 |   18 ++--
 arch/arm/plat-stmp3xxx/irq.c                     |    2 +-
 arch/arm/plat-stmp3xxx/pinmux.c                  |   14 ++-
 arch/avr32/mach-at32ap/extint.c                  |   26 +++--
 arch/avr32/mach-at32ap/pio.c                     |    9 +-
 arch/blackfin/include/asm/bfin-global.h          |    2 +-
 arch/blackfin/include/asm/ipipe.h                |    4 +-
 arch/blackfin/mach-common/ints-priority.c        |   99 ++++++++++-------
 arch/cris/arch-v10/kernel/irq.c                  |   16 ++--
 arch/frv/kernel/irq-mb93091.c                    |   12 ++-
 arch/frv/kernel/irq-mb93093.c                    |   12 ++-
 arch/frv/kernel/irq-mb93493.c                    |    8 +-
 arch/frv/kernel/irq.c                            |   27 +++--
 arch/h8300/kernel/irq.c                          |   14 ++-
 arch/m32r/platforms/m32104ut/setup.c             |   19 ++--
 arch/m32r/platforms/m32700ut/setup.c             |   92 +++++++++-------
 arch/m32r/platforms/mappi/setup.c                |   23 +++--
 arch/m32r/platforms/mappi2/setup.c               |   21 ++--
 arch/m32r/platforms/mappi3/setup.c               |   21 ++--
 arch/m32r/platforms/oaks32r/setup.c              |   21 ++--
 arch/m32r/platforms/opsput/setup.c               |  124 ++++++++++++----------
 arch/m32r/platforms/usrv/setup.c                 |   42 ++++---
 arch/m68knommu/platform/5249/intc2.c             |    9 +-
 arch/m68knommu/platform/5272/intc.c              |   11 ++-
 arch/m68knommu/platform/68328/ints.c             |    6 +-
 arch/m68knommu/platform/68360/ints.c             |    9 +-
 arch/m68knommu/platform/coldfire/intc-2.c        |    6 +-
 arch/m68knommu/platform/coldfire/intc-simr.c     |    9 +-
 arch/m68knommu/platform/coldfire/intc.c          |    8 +-
 arch/microblaze/kernel/intc.c                    |   15 ++-
 arch/mips/alchemy/common/irq.c                   |   54 ++++++----
 arch/mips/alchemy/devboards/bcsr.c               |    9 +-
 arch/mips/ar7/irq.c                              |   18 ++-
 arch/mips/bcm63xx/irq.c                          |   33 ++++---
 arch/mips/cavium-octeon/octeon-irq.c             |  102 ++++++++++--------
 arch/mips/dec/ioasic-irq.c                       |   21 ++--
 arch/mips/dec/kn02-irq.c                         |   10 +-
 arch/mips/emma/markeins/irq.c                    |   24 +++--
 arch/mips/jazz/irq.c                             |    6 +-
 arch/mips/kernel/i8259.c                         |   15 ++-
 arch/mips/kernel/irq-gic.c                       |   17 ++-
 arch/mips/kernel/irq-gt641xx.c                   |   12 ++-
 arch/mips/kernel/irq-msc01.c                     |   22 +++--
 arch/mips/kernel/irq-rm7000.c                    |    6 +-
 arch/mips/kernel/irq-rm9000.c                    |   26 +++--
 arch/mips/kernel/irq_cpu.c                       |   16 ++-
 arch/mips/kernel/irq_txx9.c                      |   14 ++-
 arch/mips/lasat/interrupt.c                      |   14 ++-
 arch/mips/loongson/common/bonito-irq.c           |    6 +-
 arch/mips/nxp/pnx833x/common/interrupts.c        |   33 ++++--
 arch/mips/nxp/pnx8550/common/int.c               |    8 +-
 arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c       |   12 ++-
 arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c       |    9 +-
 arch/mips/powertv/asic/irq_asic.c                |    6 +-
 arch/mips/rb532/irq.c                            |   28 +++--
 arch/mips/sgi-ip22/ip22-int.c                    |   24 +++--
 arch/mips/sgi-ip27/ip27-irq.c                    |   12 ++-
 arch/mips/sgi-ip27/ip27-timer.c                  |    4 +-
 arch/mips/sgi-ip32/ip32-irq.c                    |   68 +++++++-----
 arch/mips/sibyte/bcm1480/irq.c                   |   28 +++--
 arch/mips/sibyte/sb1250/irq.c                    |   28 +++--
 arch/mips/sni/a20r.c                             |   12 ++-
 arch/mips/sni/pcimt.c                            |   12 ++-
 arch/mips/sni/pcit.c                             |   12 ++-
 arch/mips/sni/rm200.c                            |   21 +++--
 arch/mips/txx9/generic/irq_tx4939.c              |   14 ++-
 arch/mips/txx9/jmr3927/irq.c                     |    6 +-
 arch/mips/txx9/rbtx4927/irq.c                    |   10 +-
 arch/mips/txx9/rbtx4938/irq.c                    |   10 +-
 arch/mips/txx9/rbtx4939/irq.c                    |    6 +-
 arch/mips/vr41xx/common/icu.c                    |   12 ++-
 arch/mips/vr41xx/common/irq.c                    |    8 +-
 arch/mn10300/kernel/irq.c                        |   19 +++-
 arch/mn10300/kernel/mn10300-serial.c             |    5 +-
 arch/parisc/include/asm/irq.h                    |   11 +-
 arch/parisc/kernel/irq.c                         |   43 +++++---
 arch/powerpc/include/asm/mpic.h                  |    6 +-
 arch/powerpc/include/asm/qe_ic.h                 |    6 +-
 arch/powerpc/kernel/crash.c                      |    4 +-
 arch/powerpc/kernel/irq.c                        |    2 +-
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    6 +-
 arch/powerpc/platforms/52xx/media5200.c          |   16 ++--
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   20 ++--
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   35 ++++--
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    6 +-
 arch/powerpc/platforms/85xx/ksi8560.c            |    2 +-
 arch/powerpc/platforms/85xx/mpc85xx_ads.c        |    2 +-
 arch/powerpc/platforms/85xx/mpc85xx_ds.c         |    2 +-
 arch/powerpc/platforms/85xx/sbc8560.c            |    2 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   20 +++--
 arch/powerpc/platforms/85xx/stx_gp3.c            |    2 +-
 arch/powerpc/platforms/85xx/tqm85xx.c            |    2 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |   12 ++-
 arch/powerpc/platforms/86xx/pic.c                |    2 +-
 arch/powerpc/platforms/8xx/m8xx_setup.c          |    4 +-
 arch/powerpc/platforms/cell/axon_msi.c           |    2 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |   14 ++-
 arch/powerpc/platforms/cell/interrupt.c          |   12 +-
 arch/powerpc/platforms/cell/setup.c              |    2 +-
 arch/powerpc/platforms/cell/spider-pic.c         |   15 ++-
 arch/powerpc/platforms/chrp/setup.c              |    2 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |   12 ++-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   26 +++--
 arch/powerpc/platforms/iseries/irq.c             |   19 ++--
 arch/powerpc/platforms/pasemi/setup.c            |    4 +-
 arch/powerpc/platforms/powermac/pic.c            |   23 +++--
 arch/powerpc/platforms/ps3/interrupt.c           |   27 +++--
 arch/powerpc/platforms/pseries/setup.c           |    2 +-
 arch/powerpc/platforms/pseries/xics.c            |   27 +++--
 arch/powerpc/sysdev/cpm1.c                       |    9 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |   18 ++--
 arch/powerpc/sysdev/fsl_msi.c                    |   12 +-
 arch/powerpc/sysdev/i8259.c                      |   11 ++-
 arch/powerpc/sysdev/ipic.c                       |   16 ++-
 arch/powerpc/sysdev/mpc8xx_pic.c                 |   16 ++-
 arch/powerpc/sysdev/mpic.c                       |   50 +++++----
 arch/powerpc/sysdev/mpic.h                       |    4 +-
 arch/powerpc/sysdev/mpic_pasemi_msi.c            |   14 ++-
 arch/powerpc/sysdev/mpic_u3msi.c                 |   12 +-
 arch/powerpc/sysdev/mv64x60_pic.c                |   21 +++--
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |    6 +-
 arch/powerpc/sysdev/tsi108_pci.c                 |   14 ++-
 arch/powerpc/sysdev/uic.c                        |   36 ++++---
 arch/powerpc/sysdev/xilinx_intc.c                |   26 +++--
 arch/score/kernel/irq.c                          |   10 +-
 arch/sh/boards/mach-cayman/irq.c                 |   10 +-
 arch/sh/boards/mach-dreamcast/irq.c              |    9 +-
 arch/sh/boards/mach-landisk/irq.c                |    6 +-
 arch/sh/boards/mach-microdev/irq.c               |   19 ++--
 arch/sh/boards/mach-se/7206/irq.c                |    9 +-
 arch/sh/boards/mach-se/7343/irq.c                |    8 +-
 arch/sh/boards/mach-se/7722/irq.c                |    8 +-
 arch/sh/boards/mach-se/7724/irq.c                |    6 +-
 arch/sh/boards/mach-systemh/irq.c                |   16 ++--
 arch/sh/cchips/hd6446x/hd64461.c                 |   11 ++-
 arch/sh/kernel/cpu/irq/imask.c                   |    6 +-
 arch/sh/kernel/cpu/irq/intc-sh5.c                |   34 +++---
 arch/sparc/kernel/irq_64.c                       |   78 ++++++++------
 arch/xtensa/variants/s6000/gpio.c                |   18 ++--
 drivers/sh/intc.c                                |   11 +-
 247 files changed, 2572 insertions(+), 1749 deletions(-)

diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index 1448b33..b55b054 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -233,33 +233,33 @@
 		are used by the default flow implementations.
 		The following helper functions are implemented (simplified excerpt):
 		<programlisting>
-default_enable(irq)
+default_enable(desc)
 {
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
-default_disable(irq)
+default_disable(desc)
 {
-	if (!delay_disable(irq))
-		desc->chip->mask(irq);
+	if (!delay_disable(desc->irq))
+		desc->chip->mask(desc);
 }
 
-default_ack(irq)
+default_ack(desc)
 {
-	chip->ack(irq);
+	chip->ack(desc);
 }
 
-default_mask_ack(irq)
+default_mask_ack(desc)
 {
 	if (chip->mask_ack) {
-		chip->mask_ack(irq);
+		chip->mask_ack(desc);
 	} else {
-		chip->mask(irq);
-		chip->ack(irq);
+		chip->mask(desc);
+		chip->ack(desc);
 	}
 }
 
-noop(irq)
+noop(desc)
 {
 }
 
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index cfde865..beb8e3f 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -218,8 +218,8 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
  * processed by PALcode, and comes in via entInt vector 1.
  */
 
-static void rtc_enable_disable(unsigned int irq) { }
-static unsigned int rtc_startup(unsigned int irq) { return 0; }
+static void rtc_enable_disable(struct irq_desc *desc) { }
+static unsigned int rtc_startup(struct irq_desc *desc) { return 0; }
 
 struct irqaction timer_irqaction = {
 	.handler	= timer_interrupt,
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 83a9ac2..2470b14 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -33,8 +33,10 @@ i8259_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 inline void
-i8259a_enable_irq(unsigned int irq)
+i8259a_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	spin_lock(&i8259_irq_lock);
 	i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq));
 	spin_unlock(&i8259_irq_lock);
@@ -47,16 +49,18 @@ __i8259a_disable_irq(unsigned int irq)
 }
 
 void
-i8259a_disable_irq(unsigned int irq)
+i8259a_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&i8259_irq_lock);
-	__i8259a_disable_irq(irq);
+	__i8259a_disable_irq(desc->irq);
 	spin_unlock(&i8259_irq_lock);
 }
 
 void
-i8259a_mask_and_ack_irq(unsigned int irq)
+i8259a_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	spin_lock(&i8259_irq_lock);
 	__i8259a_disable_irq(irq);
 
@@ -70,17 +74,17 @@ i8259a_mask_and_ack_irq(unsigned int irq)
 }
 
 unsigned int
-i8259a_startup_irq(unsigned int irq)
+i8259a_startup_irq(struct irq_desc *desc)
 {
-	i8259a_enable_irq(irq);
+	i8259a_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 void
-i8259a_end_irq(unsigned int irq)
+i8259a_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		i8259a_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		i8259a_enable_irq(desc);
 }
 
 struct irq_chip i8259a_irq_type = {
diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h
index b63ccd7..24e308e 100644
--- a/arch/alpha/kernel/irq_impl.h
+++ b/arch/alpha/kernel/irq_impl.h
@@ -31,11 +31,11 @@ extern void init_rtc_irq(void);
 
 extern void common_init_isa_dma(void);
 
-extern void i8259a_enable_irq(unsigned int);
-extern void i8259a_disable_irq(unsigned int);
-extern void i8259a_mask_and_ack_irq(unsigned int);
-extern unsigned int i8259a_startup_irq(unsigned int);
-extern void i8259a_end_irq(unsigned int);
+extern void i8259a_enable_irq(struct irq_desc *desc);
+extern void i8259a_disable_irq(struct irq_desc *desc);
+extern void i8259a_mask_and_ack_irq(struct irq_desc *desc);
+extern unsigned int i8259a_startup_irq(struct irq_desc *desc);
+extern void i8259a_end_irq(struct irq_desc *desc);
 extern struct irq_chip i8259a_irq_type;
 extern void init_i8259a_irqs(void);
 
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c
index 989ce46..dae795e 100644
--- a/arch/alpha/kernel/irq_pyxis.c
+++ b/arch/alpha/kernel/irq_pyxis.c
@@ -29,34 +29,35 @@ pyxis_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-pyxis_enable_irq(unsigned int irq)
+pyxis_enable_irq(struct irq_desc *desc)
 {
-	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-pyxis_disable_irq(unsigned int irq)
+pyxis_disable_irq(struct irq_desc *desc)
 {
-	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static unsigned int
-pyxis_startup_irq(unsigned int irq)
+pyxis_startup_irq(struct irq_desc *desc)
 {
-	pyxis_enable_irq(irq);
+	pyxis_enable_irq(desc);
 	return 0;
 }
 
 static void
-pyxis_end_irq(unsigned int irq)
+pyxis_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		pyxis_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		pyxis_enable_irq(desc);
 }
 
 static void
-pyxis_mask_and_ack_irq(unsigned int irq)
+pyxis_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long bit = 1UL << (irq - 16);
 	unsigned long mask = cached_irq_mask &= ~bit;
 
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index d63e93e..5e6b09a 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -18,33 +18,33 @@
 DEFINE_SPINLOCK(srm_irq_lock);
 
 static inline void
-srm_enable_irq(unsigned int irq)
+srm_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&srm_irq_lock);
-	cserve_ena(irq - 16);
+	cserve_ena(desc->irq - 16);
 	spin_unlock(&srm_irq_lock);
 }
 
 static void
-srm_disable_irq(unsigned int irq)
+srm_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&srm_irq_lock);
-	cserve_dis(irq - 16);
+	cserve_dis(desc->irq - 16);
 	spin_unlock(&srm_irq_lock);
 }
 
 static unsigned int
-srm_startup_irq(unsigned int irq)
+srm_startup_irq(struct irq_desc *desc)
 {
-	srm_enable_irq(irq);
+	srm_enable_irq(desc);
 	return 0;
 }
 
 static void
-srm_end_irq(unsigned int irq)
+srm_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		srm_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		srm_enable_irq(desc);
 }
 
 /* Handle interrupts from the SRM, assuming no additional weirdness.  */
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 20a30b8..3ba8767 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -44,38 +44,38 @@ alcor_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-alcor_enable_irq(unsigned int irq)
+alcor_enable_irq(struct irq_desc *desc)
 {
-	alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	alcor_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-alcor_disable_irq(unsigned int irq)
+alcor_disable_irq(struct irq_desc *desc)
 {
-	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static void
-alcor_mask_and_ack_irq(unsigned int irq)
+alcor_mask_and_ack_irq(struct irq_desc *desc)
 {
-	alcor_disable_irq(irq);
+	alcor_disable_irq(desc);
 
 	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */
-	*(vuip)GRU_INT_CLEAR = 1 << (irq - 16); mb();
+	*(vuip)GRU_INT_CLEAR = 1 << (desc->irq - 16); mb();
 	*(vuip)GRU_INT_CLEAR = 0; mb();
 }
 
 static unsigned int
-alcor_startup_irq(unsigned int irq)
+alcor_startup_irq(struct irq_desc *desc)
 {
-	alcor_enable_irq(irq);
+	alcor_enable_irq(desc);
 	return 0;
 }
 
 static void
-alcor_isa_mask_and_ack_irq(unsigned int irq)
+alcor_isa_mask_and_ack_irq(struct irq_desc *desc)
 {
-	i8259a_mask_and_ack_irq(irq);
+	i8259a_mask_and_ack_irq(desc);
 
 	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */
 	*(vuip)GRU_INT_CLEAR = 0x80000000; mb();
@@ -83,10 +83,10 @@ alcor_isa_mask_and_ack_irq(unsigned int irq)
 }
 
 static void
-alcor_end_irq(unsigned int irq)
+alcor_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		alcor_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		alcor_enable_irq(desc);
 }
 
 static struct irq_chip alcor_irq_type = {
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index affd0f3..ecbca6b 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -46,29 +46,33 @@ cabriolet_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 static inline void
-cabriolet_enable_irq(unsigned int irq)
+cabriolet_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	cabriolet_update_irq_hw(irq, cached_irq_mask &= ~(1UL << irq));
 }
 
 static void
-cabriolet_disable_irq(unsigned int irq)
+cabriolet_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	cabriolet_update_irq_hw(irq, cached_irq_mask |= 1UL << irq);
 }
 
 static unsigned int
-cabriolet_startup_irq(unsigned int irq)
+cabriolet_startup_irq(struct irq_desc *desc)
 { 
-	cabriolet_enable_irq(irq);
+	cabriolet_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-cabriolet_end_irq(unsigned int irq)
+cabriolet_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		cabriolet_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		cabriolet_enable_irq(desc);
 }
 
 static struct irq_chip cabriolet_irq_type = {
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 4026502..998f813 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -98,67 +98,67 @@ tsunami_update_irq_hw(unsigned long mask)
 }
 
 static void
-dp264_enable_irq(unsigned int irq)
+dp264_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask |= 1UL << irq;
+	cached_irq_mask |= 1UL << desc->irq;
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static void
-dp264_disable_irq(unsigned int irq)
+dp264_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask &= ~(1UL << irq);
+	cached_irq_mask &= ~(1UL << desc->irq);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static unsigned int
-dp264_startup_irq(unsigned int irq)
+dp264_startup_irq(struct irq_desc *desc)
 { 
-	dp264_enable_irq(irq);
+	dp264_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-dp264_end_irq(unsigned int irq)
+dp264_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		dp264_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		dp264_enable_irq(desc);
 }
 
 static void
-clipper_enable_irq(unsigned int irq)
+clipper_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask |= 1UL << (irq - 16);
+	cached_irq_mask |= 1UL << (desc->irq - 16);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static void
-clipper_disable_irq(unsigned int irq)
+clipper_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask &= ~(1UL << (irq - 16));
+	cached_irq_mask &= ~(1UL << (desc->irq - 16));
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static unsigned int
-clipper_startup_irq(unsigned int irq)
+clipper_startup_irq(struct irq_desc *desc)
 { 
-	clipper_enable_irq(irq);
+	clipper_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-clipper_end_irq(unsigned int irq)
+clipper_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		clipper_enable_irq(irq);
+	if (!(irq_desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		clipper_enable_irq(desc);
 }
 
 static void
@@ -177,10 +177,10 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 }
 
 static int
-dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
+dp264_set_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&dp264_irq_lock);
-	cpu_set_irq_affinity(irq, *affinity);
+	cpu_set_irq_affinity(desc->irq, *affinity);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 
@@ -188,10 +188,10 @@ dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
 }
 
 static int
-clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
+clipper_set_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&dp264_irq_lock);
-	cpu_set_irq_affinity(irq - 16, *affinity);
+	cpu_set_irq_affinity(desc->irq - 16, *affinity);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index df2090c..8f6b901 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -44,29 +44,33 @@ eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 static inline void
-eb64p_enable_irq(unsigned int irq)
+eb64p_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	eb64p_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq));
 }
 
 static void
-eb64p_disable_irq(unsigned int irq)
+eb64p_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq);
 }
 
 static unsigned int
-eb64p_startup_irq(unsigned int irq)
+eb64p_startup_irq(struct irq_desc *desc)
 {
-	eb64p_enable_irq(irq);
+	eb64p_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-eb64p_end_irq(unsigned int irq)
+eb64p_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		eb64p_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		eb64p_enable_irq(desc);
 }
 
 static struct irq_chip eb64p_irq_type = {
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 3ca1dbc..57e0094 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -51,33 +51,37 @@ eiger_update_irq_hw(unsigned long irq, unsigned long mask)
 }
 
 static inline void
-eiger_enable_irq(unsigned int irq)
+eiger_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
 	eiger_update_irq_hw(irq, mask);
 }
 
 static void
-eiger_disable_irq(unsigned int irq)
+eiger_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
 	eiger_update_irq_hw(irq, mask);
 }
 
 static unsigned int
-eiger_startup_irq(unsigned int irq)
+eiger_startup_irq(struct irq_desc *desc)
 {
-	eiger_enable_irq(irq);
+	eiger_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-eiger_end_irq(unsigned int irq)
+eiger_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		eiger_enable_irq(irq);
+	if (!(irq_desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		eiger_enable_irq(desc);
 }
 
 static struct irq_chip eiger_irq_type = {
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 7a7ae36..8ee81c6 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -63,59 +63,59 @@
  */
 
 static unsigned int
-jensen_local_startup(unsigned int irq)
+jensen_local_startup(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_startup_irq(1);
+	if (desc->irq == 7)
+		i8259a_startup_irq(irq_to_desc(1));
 	else
 		/*
 		 * For all true local interrupts, set the flag that prevents
 		 * the IPL from being dropped during handler processing.
 		 */
-		if (irq_desc[irq].action)
-			irq_desc[irq].action->flags |= IRQF_DISABLED;
+		if (desc->action)
+			desc->action->flags |= IRQF_DISABLED;
 	return 0;
 }
 
 static void
-jensen_local_shutdown(unsigned int irq)
+jensen_local_shutdown(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_disable_irq(1);
+	if (desc->irq == 7)
+		i8259a_disable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_enable(unsigned int irq)
+jensen_local_enable(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_enable_irq(1);
+	if (desc->irq == 7)
+		i8259a_enable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_disable(unsigned int irq)
+jensen_local_disable(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_disable_irq(1);
+	if (desc->irq == 7)
+		i8259a_disable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_ack(unsigned int irq)
+jensen_local_ack(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_mask_and_ack_irq(1);
+	if (desc->irq == 7)
+		i8259a_mask_and_ack_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_end(unsigned int irq)
+jensen_local_end(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_end_irq(1);
+	if (desc->irq == 7)
+		i8259a_end_irq(irq_to_desc(1));
 }
 
 static struct irq_chip jensen_local_irq_type = {
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 0bb3b5c..5229f49 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -104,15 +104,15 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
 }
 
 static void
-io7_enable_irq(unsigned int irq)
+io7_enable_irq(struct irq_desc *desc)
 {
 	volatile unsigned long *ctl;
 	struct io7 *io7;
 
-	ctl = io7_get_irq_ctl(irq, &io7);
+	ctl = io7_get_irq_ctl(desc->irq, &io7);
 	if (!ctl || !io7) {
 		printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
-		       __func__, irq);
+		       __func__, desc->irq);
 		return;
 	}
 		
@@ -124,15 +124,15 @@ io7_enable_irq(unsigned int irq)
 }
 
 static void
-io7_disable_irq(unsigned int irq)
+io7_disable_irq(struct irq_desc *desc)
 {
 	volatile unsigned long *ctl;
 	struct io7 *io7;
 
-	ctl = io7_get_irq_ctl(irq, &io7);
+	ctl = io7_get_irq_ctl(desc->irq, &io7);
 	if (!ctl || !io7) {
 		printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
-		       __func__, irq);
+		       __func__, desc->irq);
 		return;
 	}
 		
@@ -144,27 +144,27 @@ io7_disable_irq(unsigned int irq)
 }
 
 static unsigned int
-io7_startup_irq(unsigned int irq)
+io7_startup_irq(struct irq_desc *desc)
 {
-	io7_enable_irq(irq);
+	io7_enable_irq(desc);
 	return 0;	/* never anything pending */
 }
 
 static void
-io7_end_irq(unsigned int irq)
+io7_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		io7_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		io7_enable_irq(desc);
 }
 
 static void
-marvel_irq_noop(unsigned int irq) 
+marvel_irq_noop(struct irq_desc *desc)
 { 
 	return; 
 }
 
 static unsigned int
-marvel_irq_noop_return(unsigned int irq) 
+marvel_irq_noop_return(struct irq_desc *desc)
 { 
 	return 0; 
 }
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index ee88651..d4ce8f3 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -43,29 +43,29 @@ mikasa_update_irq_hw(int mask)
 }
 
 static inline void
-mikasa_enable_irq(unsigned int irq)
+mikasa_enable_irq(struct irq_desc *desc)
 {
-	mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16));
+	mikasa_update_irq_hw(cached_irq_mask |= 1 << (desc->irq - 16));
 }
 
 static void
-mikasa_disable_irq(unsigned int irq)
+mikasa_disable_irq(struct irq_desc *desc)
 {
-	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16)));
+	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (desc->irq - 16)));
 }
 
 static unsigned int
-mikasa_startup_irq(unsigned int irq)
+mikasa_startup_irq(struct irq_desc *desc)
 {
-	mikasa_enable_irq(irq);
+	mikasa_enable_irq(desc);
 	return 0;
 }
 
 static void
-mikasa_end_irq(unsigned int irq)
+mikasa_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		mikasa_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		mikasa_enable_irq(desc);
 }
 
 static struct irq_chip mikasa_irq_type = {
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 86503fe..5d175de 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -48,29 +48,33 @@ noritake_update_irq_hw(int irq, int mask)
 }
 
 static void
-noritake_enable_irq(unsigned int irq)
+noritake_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	noritake_update_irq_hw(irq, cached_irq_mask |= 1 << (irq - 16));
 }
 
 static void
-noritake_disable_irq(unsigned int irq)
+noritake_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16)));
 }
 
 static unsigned int
-noritake_startup_irq(unsigned int irq)
+noritake_startup_irq(struct irq_desc *desc)
 {
-	noritake_enable_irq(irq);
+	noritake_enable_irq(desc);
 	return 0;
 }
 
 static void
-noritake_end_irq(unsigned int irq)
+noritake_end_irq(struct irq_desc *desc)
 {
-        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-                noritake_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		noritake_enable_irq(desc);
 }
 
 static struct irq_chip noritake_irq_type = {
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 26c322b..e1dacac 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -56,8 +56,9 @@ rawhide_update_irq_hw(int hose, int mask)
   (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))
 
 static inline void 
-rawhide_enable_irq(unsigned int irq)
+rawhide_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, hose;
 
 	irq -= 16;
@@ -76,8 +77,9 @@ rawhide_enable_irq(unsigned int irq)
 }
 
 static void 
-rawhide_disable_irq(unsigned int irq)
+rawhide_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, hose;
 
 	irq -= 16;
@@ -96,8 +98,9 @@ rawhide_disable_irq(unsigned int irq)
 }
 
 static void
-rawhide_mask_and_ack_irq(unsigned int irq)
+rawhide_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, mask1, hose;
 
 	irq -= 16;
@@ -122,17 +125,17 @@ rawhide_mask_and_ack_irq(unsigned int irq)
 }
 
 static unsigned int
-rawhide_startup_irq(unsigned int irq)
+rawhide_startup_irq(struct irq_desc *desc)
 {
-	rawhide_enable_irq(irq);
+	rawhide_enable_irq(desc);
 	return 0;
 }
 
 static void
-rawhide_end_irq(unsigned int irq)
+rawhide_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		rawhide_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		rawhide_enable_irq(desc);
 }
 
 static struct irq_chip rawhide_irq_type = {
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index be16112..31cb57e 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -47,29 +47,29 @@ rx164_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-rx164_enable_irq(unsigned int irq)
+rx164_enable_irq(struct irq_desc *desc)
 {
-	rx164_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	rx164_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-rx164_disable_irq(unsigned int irq)
+rx164_disable_irq(struct irq_desc *desc)
 {
-	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static unsigned int
-rx164_startup_irq(unsigned int irq)
+rx164_startup_irq(struct irq_desc *desc)
 {
-	rx164_enable_irq(irq);
+	rx164_enable_irq(desc);
 	return 0;
 }
 
 static void
-rx164_end_irq(unsigned int irq)
+rx164_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		rx164_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		rx164_enable_irq(desc);
 }
 
 static struct irq_chip rx164_irq_type = {
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index b2abe27..0eca307 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -443,57 +443,57 @@ lynx_swizzle(struct pci_dev *dev, u8 *pinp)
 /* GENERIC irq routines */
 
 static inline void
-sable_lynx_enable_irq(unsigned int irq)
+sable_lynx_enable_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit);
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
 	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
-	       __func__, mask, bit, irq);
+	       __func__, mask, bit, desc->irq);
 #endif
 }
 
 static void
-sable_lynx_disable_irq(unsigned int irq)
+sable_lynx_disable_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
 	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
-	       __func__, mask, bit, irq);
+	       __func__, mask, bit, desc->irq);
 #endif
 }
 
 static unsigned int
-sable_lynx_startup_irq(unsigned int irq)
+sable_lynx_startup_irq(struct irq_desc *desc)
 {
-	sable_lynx_enable_irq(irq);
+	sable_lynx_enable_irq(desc);
 	return 0;
 }
 
 static void
-sable_lynx_end_irq(unsigned int irq)
+sable_lynx_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		sable_lynx_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		sable_lynx_enable_irq(desc);
 }
 
 static void
-sable_lynx_mask_and_ack_irq(unsigned int irq)
+sable_lynx_mask_and_ack_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 2304648..6c6fa86 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -45,33 +45,37 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask)
 }
 
 static inline void
-takara_enable_irq(unsigned int irq)
+takara_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
 	takara_update_irq_hw(irq, mask);
 }
 
 static void
-takara_disable_irq(unsigned int irq)
+takara_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
 	takara_update_irq_hw(irq, mask);
 }
 
 static unsigned int
-takara_startup_irq(unsigned int irq)
+takara_startup_irq(struct irq_desc *desc)
 {
-	takara_enable_irq(irq);
+	takara_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-takara_end_irq(unsigned int irq)
+takara_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		takara_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		takara_enable_irq(desc);
 }
 
 static struct irq_chip takara_irq_type = {
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 9008d0f..73f661c 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -112,35 +112,35 @@ titan_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-titan_enable_irq(unsigned int irq)
+titan_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&titan_irq_lock);
-	titan_cached_irq_mask |= 1UL << (irq - 16);
+	titan_cached_irq_mask |= 1UL << (desc->irq - 16);
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static inline void
-titan_disable_irq(unsigned int irq)
+titan_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&titan_irq_lock);
-	titan_cached_irq_mask &= ~(1UL << (irq - 16));
+	titan_cached_irq_mask &= ~(1UL << (desc->irq - 16));
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static unsigned int
-titan_startup_irq(unsigned int irq)
+titan_startup_irq(struct irq_desc *desc)
 {
-	titan_enable_irq(irq);
+	titan_enable_irq(desc);
 	return 0;	/* never anything pending */
 }
 
 static void
-titan_end_irq(unsigned int irq)
+titan_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		titan_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		titan_enable_irq(desc);
 }
 
 static void
@@ -158,10 +158,10 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 }
 
 static int
-titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
+titan_set_irq_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&titan_irq_lock);
-	titan_cpu_set_irq_affinity(irq - 16, *affinity);
+	titan_cpu_set_irq_affinity(desc->irq - 16, *affinity);
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index 62fd972..e67555b 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -104,10 +104,12 @@ wildfire_init_irq_hw(void)
 }
 
 static void
-wildfire_enable_irq(unsigned int irq)
+wildfire_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_enable_irq(irq);
+		i8259a_enable_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	set_bit(irq, &cached_irq_mask);
@@ -116,10 +118,12 @@ wildfire_enable_irq(unsigned int irq)
 }
 
 static void
-wildfire_disable_irq(unsigned int irq)
+wildfire_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_disable_irq(irq);
+		i8259a_disable_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	clear_bit(irq, &cached_irq_mask);
@@ -128,10 +132,12 @@ wildfire_disable_irq(unsigned int irq)
 }
 
 static void
-wildfire_mask_and_ack_irq(unsigned int irq)
+wildfire_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_mask_and_ack_irq(irq);
+		i8259a_mask_and_ack_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	clear_bit(irq, &cached_irq_mask);
@@ -140,21 +146,21 @@ wildfire_mask_and_ack_irq(unsigned int irq)
 }
 
 static unsigned int
-wildfire_startup_irq(unsigned int irq)
+wildfire_startup_irq(struct irq_desc *desc)
 { 
-	wildfire_enable_irq(irq);
+	wildfire_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-wildfire_end_irq(unsigned int irq)
+wildfire_end_irq(struct irq_desc *desc)
 { 
 #if 0
-	if (!irq_desc[irq].action)
-		printk("got irq %d\n", irq);
+	if (!desc->action)
+		printk("got irq %d\n", desc->irq);
 #endif
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		wildfire_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		wildfire_enable_irq(desc);
 }
 
 static struct irq_chip wildfire_irq_type = {
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 337741f..7e7f9f7 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -80,8 +80,9 @@ static inline unsigned int gic_irq(unsigned int irq)
  * our "acknowledge" routine disable the interrupt, then mark it as
  * complete.
  */
-static void gic_ack_irq(unsigned int irq)
+static void gic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -90,8 +91,9 @@ static void gic_ack_irq(unsigned int irq)
 	spin_unlock(&irq_controller_lock);
 }
 
-static void gic_mask_irq(unsigned int irq)
+static void gic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -99,8 +101,9 @@ static void gic_mask_irq(unsigned int irq)
 	spin_unlock(&irq_controller_lock);
 }
 
-static void gic_unmask_irq(unsigned int irq)
+static void gic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -109,8 +112,9 @@ static void gic_unmask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
+static int gic_set_cpu(struct irq_desc *desc, const struct cpumask *mask_val)
 {
+	unsigned int irq = desc->irq;
 	void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
 	unsigned int shift = (irq % 4) * 8;
 	unsigned int cpu = cpumask_first(mask_val);
@@ -129,13 +133,13 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
 
 static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 {
-	struct gic_chip_data *chip_data = get_irq_data(irq);
-	struct irq_chip *chip = get_irq_chip(irq);
+	struct gic_chip_data *chip_data = get_irq_desc_data(desc);
+	struct irq_chip *chip = get_irq_desc_chip(desc);
 	unsigned int cascade_irq, gic_irq;
 	unsigned long status;
 
 	/* primary controller ack'ing */
-	chip->ack(irq);
+	chip->ack(desc);
 
 	spin_lock(&irq_controller_lock);
 	status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
@@ -153,7 +157,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 
  out:
 	/* primary controller unmasking */
-	chip->unmask(irq);
+	chip->unmask(desc);
 }
 
 static struct irq_chip gic_chip = {
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index ee1d3b8..94f5146 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -32,8 +32,10 @@
 
 #define MAX_SLOTS		21
 
-static void it8152_mask_irq(unsigned int irq)
+static void it8152_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
        if (irq >= IT8152_LD_IRQ(0)) {
 	       __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) |
 			    (1 << (irq - IT8152_LD_IRQ(0)))),
@@ -49,8 +51,10 @@ static void it8152_mask_irq(unsigned int irq)
        }
 }
 
-static void it8152_unmask_irq(unsigned int irq)
+static void it8152_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
        if (irq >= IT8152_LD_IRQ(0)) {
 	       __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) &
 			     ~(1 << (irq - IT8152_LD_IRQ(0)))),
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 90ae00b..d91ec74 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -140,11 +140,11 @@ static struct locomo_dev_info locomo_devices[] = {
 
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	int req, i;
 
 	/* Acknowledge the parent IRQ */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	/* check why this interrupt was generated */
 	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
@@ -154,29 +154,31 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 		irq = lchip->irq_base;
 		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0100 << i)) {
-				generic_handle_irq(irq);
+				generic_handle_irq_desc(irq, desc);
 			}
 
 		}
 	}
 }
 
-static void locomo_ack_irq(unsigned int irq)
+static void locomo_ack_irq(struct irq_desc *desc)
 {
 }
 
-static void locomo_mask_irq(unsigned int irq)
+static void locomo_mask_irq(struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	unsigned int r;
 	r = locomo_readl(lchip->base + LOCOMO_ICR);
 	r &= ~(0x0010 << (irq - lchip->irq_base));
 	locomo_writel(r, lchip->base + LOCOMO_ICR);
 }
 
-static void locomo_unmask_irq(unsigned int irq)
+static void locomo_unmask_irq(struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	unsigned int r;
 	r = locomo_readl(lchip->base + LOCOMO_ICR);
 	r |= (0x0010 << (irq - lchip->irq_base));
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a52a27c..dff6946 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -205,7 +205,7 @@ static void
 sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int stat0, stat1, i;
-	struct sa1111 *sachip = get_irq_data(irq);
+	struct sa1111 *sachip = get_irq_desc_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 
 	stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
@@ -213,7 +213,7 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
 
@@ -231,19 +231,20 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 			generic_handle_irq(i + sachip->irq_base);
 
 	/* For level-based interrupts */
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 #define SA1111_IRQMASK_LO(x)	(1 << (x - sachip->irq_base))
 #define SA1111_IRQMASK_HI(x)	(1 << (x - sachip->irq_base - 32))
 
-static void sa1111_ack_irq(unsigned int irq)
+static void sa1111_ack_irq(struct irq_desc *desc)
 {
 }
 
-static void sa1111_mask_lowirq(unsigned int irq)
+static void sa1111_mask_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
@@ -252,9 +253,10 @@ static void sa1111_mask_lowirq(unsigned int irq)
 	writel(ie0, mapbase + SA1111_INTEN0);
 }
 
-static void sa1111_unmask_lowirq(unsigned int irq)
+static void sa1111_unmask_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
@@ -270,9 +272,10 @@ static void sa1111_unmask_lowirq(unsigned int irq)
  * be triggered.  In fact, its very difficult, if not impossible to get
  * INTSET to re-trigger the interrupt.
  */
-static int sa1111_retrigger_lowirq(unsigned int irq)
+static int sa1111_retrigger_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long ip0;
@@ -292,9 +295,10 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
 	return i == 8 ? -1 : 0;
 }
 
-static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_lowirq(struct irq_desc *desc, unsigned int flags)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long ip0;
@@ -316,9 +320,10 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
 	return 0;
 }
 
-static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_lowirq(struct irq_desc *desc, unsigned int on)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long we0;
@@ -343,9 +348,10 @@ static struct irq_chip sa1111_low_chip = {
 	.set_wake	= sa1111_wake_lowirq,
 };
 
-static void sa1111_mask_highirq(unsigned int irq)
+static void sa1111_mask_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
@@ -354,9 +360,10 @@ static void sa1111_mask_highirq(unsigned int irq)
 	sa1111_writel(ie1, mapbase + SA1111_INTEN1);
 }
 
-static void sa1111_unmask_highirq(unsigned int irq)
+static void sa1111_unmask_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
@@ -372,9 +379,10 @@ static void sa1111_unmask_highirq(unsigned int irq)
  * be triggered.  In fact, its very difficult, if not impossible to get
  * INTSET to re-trigger the interrupt.
  */
-static int sa1111_retrigger_highirq(unsigned int irq)
+static int sa1111_retrigger_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long ip1;
@@ -394,9 +402,10 @@ static int sa1111_retrigger_highirq(unsigned int irq)
 	return i == 8 ? -1 : 0;
 }
 
-static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_highirq(struct irq_desc *desc, unsigned int flags)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long ip1;
@@ -418,9 +427,10 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
 	return 0;
 }
 
-static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_highirq(struct irq_desc *desc, unsigned int on)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long we1;
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 1cf999a..c4a5dcd 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -204,25 +204,31 @@ static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 res
 static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
 #endif /* CONFIG_PM */
 
-static void vic_ack_irq(unsigned int irq)
+static void vic_ack_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 	/* moreover, clear the soft-triggered, in case it was the reason */
 	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
 }
 
-static void vic_mask_irq(unsigned int irq)
+static void vic_mask_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 }
 
-static void vic_unmask_irq(unsigned int irq)
+static void vic_unmask_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE);
 }
@@ -242,8 +248,9 @@ static struct vic_device *vic_from_irq(unsigned int irq)
 	return NULL;
 }
 
-static int vic_set_wake(unsigned int irq, unsigned int on)
+static int vic_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	struct vic_device *v = vic_from_irq(irq);
 	unsigned int off = irq & 31;
 	u32 bit = 1 << off;
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index eed2f79..7310a4d 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -443,8 +443,9 @@ static expansioncard_ops_t ecard_default_ops = {
  *
  * They are not meant to be called directly, but via enable/disable_irq.
  */
-static void ecard_irq_unmask(unsigned int irqnr)
+static void ecard_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irqnr = desc->irq;
 	ecard_t *ec = slot_to_ecard(irqnr - 32);
 
 	if (ec) {
@@ -459,8 +460,9 @@ static void ecard_irq_unmask(unsigned int irqnr)
 	}
 }
 
-static void ecard_irq_mask(unsigned int irqnr)
+static void ecard_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irqnr = desc->irq;
 	ecard_t *ec = slot_to_ecard(irqnr - 32);
 
 	if (ec) {
@@ -551,7 +553,7 @@ static void ecard_check_lockup(struct irq_desc *desc)
 			printk(KERN_ERR "\nInterrupt lockup detected - "
 			       "disabling all expansion card interrupts\n");
 
-			desc->chip->mask(IRQ_EXPANSIONCARD);
+			desc->chip->mask(irq_to_desc(IRQ_EXPANSIONCARD));
 			ecard_dump_irq_state();
 		}
 	} else
@@ -574,7 +576,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 	ecard_t *ec;
 	int called = 0;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 	for (ec = cards; ec; ec = ec->next) {
 		int pending;
 
@@ -591,7 +593,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 			called ++;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 
 	if (called == 0)
 		ecard_check_lockup(desc);
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index ea02a7b..ff3f4ab 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -145,6 +145,7 @@ static void __cpuinit twd_calibrate_rate(void)
 void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
 	unsigned long flags;
+	struct irq_desc *desc;
 
 	twd_calibrate_rate();
 
@@ -160,8 +161,9 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 
 	/* Make sure our local interrupt controller has this enabled */
 	local_irq_save(flags);
-	irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
-	get_irq_chip(clk->irq)->unmask(clk->irq);
+	desc = irq_to_desc(clk->irq);
+	desc->status |= IRQ_NOPROBE;
+	get_irq_desc_chip(desc)->unmask(desc);
 	local_irq_restore(flags);
 
 	clockevents_register_device(clk);
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index b5c5fc6..41a8ad9 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -67,17 +67,17 @@ void __init aaec2000_map_io(void)
 /*
  * Interrupt handling routines
  */
-static void aaec2000_int_ack(unsigned int irq)
+static void aaec2000_int_ack(struct irq_desc *desc)
 {
 	IRQ_INTSR = 1 << irq;
 }
 
-static void aaec2000_int_mask(unsigned int irq)
+static void aaec2000_int_mask(struct irq_desc *desc)
 {
 	IRQ_INTENC |= (1 << irq);
 }
 
-static void aaec2000_int_unmask(unsigned int irq)
+static void aaec2000_int_unmask(struct irq_desc *desc)
 {
 	IRQ_INTENS |= (1 << irq);
 }
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index ae4772e..55bfcbd 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -274,8 +274,9 @@ EXPORT_SYMBOL(at91_get_gpio_value);
 static u32 wakeups[MAX_GPIO_BANKS];
 static u32 backups[MAX_GPIO_BANKS];
 
-static int gpio_irq_set_wake(unsigned pin, unsigned state)
+static int gpio_irq_set_wake(struct irq_desc *desc, unsigned state)
 {
+	unsigned int pin = desc->irq;
 	unsigned	mask = pin_to_mask(pin);
 	unsigned	bank = (pin - PIN_BASE) / 32;
 
@@ -344,8 +345,9 @@ void at91_gpio_resume(void)
  * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
  */
 
-static void gpio_irq_mask(unsigned pin)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int pin = desc->irq;
 	void __iomem	*pio = pin_to_controller(pin);
 	unsigned	mask = pin_to_mask(pin);
 
@@ -353,8 +355,9 @@ static void gpio_irq_mask(unsigned pin)
 		__raw_writel(mask, pio + PIO_IDR);
 }
 
-static void gpio_irq_unmask(unsigned pin)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int pin = desc->irq;
 	void __iomem	*pio = pin_to_controller(pin);
 	unsigned	mask = pin_to_mask(pin);
 
@@ -362,7 +365,7 @@ static void gpio_irq_unmask(unsigned pin)
 		__raw_writel(mask, pio + PIO_IER);
 }
 
-static int gpio_irq_type(unsigned pin, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
 	switch (type) {
 	case IRQ_TYPE_NONE:
@@ -393,7 +396,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 	pio = at91_gpio->regbase;
 
 	/* temporarily mask (level sensitive) parent IRQ */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 	for (;;) {
 		/* Reading ISR acks pending (edge triggered) GPIO interrupts.
 		 * When there none are pending, we're finished unless we need
@@ -419,7 +422,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 					 * another IRQ must be generated before it actually gets
 					 * here to be disabled on the GPIO controller.
 					 */
-					gpio_irq_mask(pin);
+					gpio_irq_mask(gpio);
 				}
 				else
 					generic_handle_irq(pin);
@@ -429,7 +432,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			isr >>= 1;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	/* now it may re-trigger */
 }
 
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index da3494a..4308334 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -34,14 +34,18 @@
 #include <asm/mach/map.h>
 
 
-static void at91_aic_mask_irq(unsigned int irq)
+static void at91_aic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	/* Disable interrupt on AIC */
 	at91_sys_write(AT91_AIC_IDCR, 1 << irq);
 }
 
-static void at91_aic_unmask_irq(unsigned int irq)
+static void at91_aic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	/* Enable interrupt on AIC */
 	at91_sys_write(AT91_AIC_IECR, 1 << irq);
 }
@@ -50,8 +54,9 @@ unsigned int at91_extern_irq;
 
 #define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
 
-static int at91_aic_set_type(unsigned irq, unsigned type)
+static int at91_aic_set_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int smr, srctype;
 
 	switch (type) {
@@ -87,8 +92,10 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
 static u32 wakeups;
 static u32 backups;
 
-static int at91_aic_set_wake(unsigned irq, unsigned value)
+static int at91_aic_set_wake(struct irq_desc *desc, unsigned value)
 {
+	unsigned int irq = desc->irq;
+
 	if (unlikely(irq >= 32))
 		return -EINVAL;
 
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
index dc1c493..4685c62 100644
--- a/arch/arm/mach-bcmring/irq.c
+++ b/arch/arm/mach-bcmring/irq.c
@@ -30,38 +30,50 @@
 #include <mach/csp/intcHw_reg.h>
 #include <mach/csp/mm_io.h>
 
-static void bcmring_mask_irq0(unsigned int irq)
+static void bcmring_mask_irq0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC0_START),
 	       MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq0(unsigned int irq)
+static void bcmring_unmask_irq0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC0_START),
 	       MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
 }
 
-static void bcmring_mask_irq1(unsigned int irq)
+static void bcmring_mask_irq1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC1_START),
 	       MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq1(unsigned int irq)
+static void bcmring_unmask_irq1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC1_START),
 	       MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
 }
 
-static void bcmring_mask_irq2(unsigned int irq)
+static void bcmring_mask_irq2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_SINTC_START),
 	       MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq2(unsigned int irq)
+static void bcmring_unmask_irq2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_SINTC_START),
 	       MM_IO_BASE_SINTC + INTCHW_INTENABLE);
 }
diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
index 9a12d85..f614852 100644
--- a/arch/arm/mach-clps711x/irq.c
+++ b/arch/arm/mach-clps711x/irq.c
@@ -27,8 +27,9 @@
 
 #include <asm/hardware/clps7111.h>
 
-static void int1_mask(unsigned int irq)
+static void int1_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -36,8 +37,9 @@ static void int1_mask(unsigned int irq)
 	clps_writel(intmr1, INTMR1);
 }
 
-static void int1_ack(unsigned int irq)
+static void int1_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -54,8 +56,9 @@ static void int1_ack(unsigned int irq)
 	}
 }
 
-static void int1_unmask(unsigned int irq)
+static void int1_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -69,8 +72,9 @@ static struct irq_chip int1_chip = {
 	.unmask = int1_unmask,
 };
 
-static void int2_mask(unsigned int irq)
+static void int2_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
@@ -78,8 +82,9 @@ static void int2_mask(unsigned int irq)
 	clps_writel(intmr2, INTMR2);
 }
 
-static void int2_ack(unsigned int irq)
+static void int2_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
@@ -91,8 +96,9 @@ static void int2_ack(unsigned int irq)
 	}
 }
 
-static void int2_unmask(unsigned int irq)
+static void int2_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 37311d1..8284b53 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -27,14 +27,16 @@ static inline void cp_intc_write(unsigned long value, unsigned offset)
 	__raw_writel(value, cp_intc_base + offset);
 }
 
-static void cp_intc_ack_irq(unsigned int irq)
+static void cp_intc_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cp_intc_write(irq, CP_INTC_SYS_STAT_IDX_CLR);
 }
 
 /* Disable interrupt */
-static void cp_intc_mask_irq(unsigned int irq)
+static void cp_intc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX don't know why we need to disable nIRQ here... */
 	cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
 	cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_CLR);
@@ -42,13 +44,15 @@ static void cp_intc_mask_irq(unsigned int irq)
 }
 
 /* Enable interrupt */
-static void cp_intc_unmask_irq(unsigned int irq)
+static void cp_intc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_SET);
 }
 
-static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int cp_intc_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned reg		= BIT_WORD(irq);
 	unsigned mask		= BIT_MASK(irq);
 	unsigned polarity	= cp_intc_read(CP_INTC_SYS_POLARITY(reg));
@@ -86,7 +90,7 @@ static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
  * generic drivers which call {enable|disable}_irq_wake for
  * wake up interrupt sources (eg RTC on DA850).
  */
-static int cp_intc_set_wake(unsigned int irq, unsigned int on)
+static int cp_intc_set_wake(struct irq_desc *desc, unsigned int on)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 744755b..e557755 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -159,20 +159,20 @@ pure_initcall(davinci_gpio_setup);
  * serve as EDMA event triggers.
  */
 
-static void gpio_irq_disable(unsigned irq)
+static void gpio_irq_disable(struct irq_desc *desc)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
 
 	__raw_writel(mask, &g->clr_falling);
 	__raw_writel(mask, &g->clr_rising);
 }
 
-static void gpio_irq_enable(unsigned irq)
+static void gpio_irq_enable(struct irq_desc *desc)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
-	unsigned status = irq_desc[irq].status;
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
+	unsigned status = desc->status;
 
 	status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
 	if (!status)
@@ -184,19 +184,19 @@ static void gpio_irq_enable(unsigned irq)
 		__raw_writel(mask, &g->set_rising);
 }
 
-static int gpio_irq_type(unsigned irq, unsigned trigger)
+static int gpio_irq_type(struct irq_desc *desc, unsigned trigger)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
 
 	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
 		return -EINVAL;
 
-	irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
-	irq_desc[irq].status |= trigger;
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= trigger;
 
 	/* don't enable the IRQ if it's currently disabled */
-	if (irq_desc[irq].depth == 0) {
+	if (desc->depth == 0) {
 		__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
 			     ? &g->set_falling : &g->clr_falling);
 		__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
@@ -223,8 +223,8 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		mask <<= 16;
 
 	/* temporarily mask (level sensitive) parent IRQ */
-	desc->chip->mask(irq);
-	desc->chip->ack(irq);
+	desc->chip->mask(desc);
+	desc->chip->ack(desc);
 	while (1) {
 		u32		status;
 		int		n;
@@ -247,7 +247,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			status >>= res;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	/* now it may re-trigger */
 }
 
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index af92ffe..dc8e7a0 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -53,8 +53,9 @@ static inline void davinci_irq_writel(unsigned long value, int offset)
 }
 
 /* Disable interrupt */
-static void davinci_mask_irq(unsigned int irq)
+static void davinci_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	u32 l;
 
@@ -72,8 +73,9 @@ static void davinci_mask_irq(unsigned int irq)
 }
 
 /* Enable interrupt */
-static void davinci_unmask_irq(unsigned int irq)
+static void davinci_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	u32 l;
 
@@ -91,8 +93,9 @@ static void davinci_unmask_irq(unsigned int irq)
 }
 
 /* EOI interrupt */
-static void davinci_ack_irq(unsigned int irq)
+static void davinci_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = 1 << IRQ_BIT(irq);
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 61bfcb3..a19a4dc 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -36,8 +36,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static void pmu_irq_mask(unsigned int irq)
+static void pmu_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
@@ -46,8 +47,9 @@ static void pmu_irq_mask(unsigned int irq)
 	writel(u, PMU_INTERRUPT_MASK);
 }
 
-static void pmu_irq_unmask(unsigned int irq)
+static void pmu_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
@@ -56,8 +58,9 @@ static void pmu_irq_unmask(unsigned int irq)
 	writel(u, PMU_INTERRUPT_MASK);
 }
 
-static void pmu_irq_ack(unsigned int irq)
+static void pmu_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index c7bc7fb..f5e1e3d 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -35,13 +35,15 @@
 #define IRQ_STAT		0xff000000	/* read */
 #define IRQ_MCLR		0xff000000	/* write */
 
-static void ebsa110_mask_irq(unsigned int irq)
+static void ebsa110_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writeb(1 << irq, IRQ_MCLR);
 }
 
-static void ebsa110_unmask_irq(unsigned int irq)
+static void ebsa110_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writeb(1 << irq, IRQ_MSET);
 }
 
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index cc377ae..3457432 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -112,13 +112,14 @@ static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
 	generic_handle_irq(gpio_irq);
 }
 
-static void ep93xx_gpio_irq_ack(unsigned int irq)
+static void ep93xx_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+	if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 		ep93xx_gpio_update_int_params(port);
 	}
@@ -126,13 +127,14 @@ static void ep93xx_gpio_irq_ack(unsigned int irq)
 	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
-static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
+static void ep93xx_gpio_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+	if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 
 	gpio_int_unmasked[port] &= ~port_mask;
@@ -141,8 +143,9 @@ static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
-static void ep93xx_gpio_irq_mask(unsigned int irq)
+static void ep93xx_gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
@@ -150,8 +153,9 @@ static void ep93xx_gpio_irq_mask(unsigned int irq)
 	ep93xx_gpio_update_int_params(port);
 }
 
-static void ep93xx_gpio_irq_unmask(unsigned int irq)
+static void ep93xx_gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
@@ -164,9 +168,9 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
  * edge (1) triggered, while gpio_int_type2 controls whether it
  * triggers on low/falling (0) or high/rising (1).
  */
-static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
+static int ep93xx_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	const int gpio = irq_to_gpio(irq);
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index e3bc3f6..1a11b2a 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -75,13 +75,15 @@ static const int fb_irq_mask[] = {
 	IRQ_MASK_PCI_PERR,	/* 19 */
 };
 
-static void fb_mask_irq(unsigned int irq)
+static void fb_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
 }
 
-static void fb_unmask_irq(unsigned int irq)
+static void fb_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
 }
 
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index 8bfd06a..7593eeb 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -30,23 +30,26 @@
 
 #include "common.h"
 
-static void isa_mask_pic_lo_irq(unsigned int irq)
+static void isa_mask_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
 }
 
-static void isa_ack_pic_lo_irq(unsigned int irq)
+static void isa_ack_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
 	outb(0x20, PIC_LO);
 }
 
-static void isa_unmask_pic_lo_irq(unsigned int irq)
+static void isa_unmask_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
@@ -58,15 +61,17 @@ static struct irq_chip isa_lo_chip = {
 	.unmask = isa_unmask_pic_lo_irq,
 };
 
-static void isa_mask_pic_hi_irq(unsigned int irq)
+static void isa_mask_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
 }
 
-static void isa_ack_pic_hi_irq(unsigned int irq)
+static void isa_ack_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
@@ -74,8 +79,9 @@ static void isa_ack_pic_hi_irq(unsigned int irq)
 	outb(0x20, PIC_HI);
 }
 
-static void isa_unmask_pic_hi_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index fe3bd5a..66b50ea 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -54,24 +54,27 @@ static void _set_gpio_irqenable(unsigned int base, unsigned int index,
 	__raw_writel(reg, base + GPIO_INT_EN);
 }
 
-static void gpio_ack_irq(unsigned int irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
 	__raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
 }
 
-static void gpio_mask_irq(unsigned int irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
 	_set_gpio_irqenable(base, gpio % 32, 0);
 }
 
-static void gpio_unmask_irq(unsigned int irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
@@ -80,6 +83,7 @@ static void gpio_unmask_irq(unsigned int irq)
 
 static int gpio_set_irq_type(unsigned int irq, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int gpio_mask = 1 << (gpio % 32);
 	unsigned int base = GPIO_BASE(gpio / 32);
@@ -120,7 +124,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)
 	__raw_writel(reg_level, base + GPIO_INT_LEVEL);
 	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
 
-	gpio_ack_irq(irq);
+	gpio_ack_irq(desc);
 
 	return 0;
 }
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
index 9e613ca..30e23be 100644
--- a/arch/arm/mach-gemini/irq.c
+++ b/arch/arm/mach-gemini/irq.c
@@ -32,13 +32,15 @@
 #define FIQ_LEVEL(base_addr)	(base_addr + 0x30)
 #define FIQ_STATUS(base_addr)	(base_addr + 0x34)
 
-static void gemini_ack_irq(unsigned int irq)
+static void gemini_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
 }
 
-static void gemini_mask_irq(unsigned int irq)
+static void gemini_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
@@ -46,8 +48,9 @@ static void gemini_mask_irq(unsigned int irq)
 	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
 }
 
-static void gemini_unmask_irq(unsigned int irq)
+static void gemini_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 7a26148..cb945c0 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -53,16 +53,18 @@ unsigned long h720x_gettimeoffset(void)
 /*
  * mask Global irq's
  */
-static void mask_global_irq (unsigned int irq )
+static void mask_global_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << irq);
 }
 
 /*
  * unmask Global irq's
  */
-static void unmask_global_irq (unsigned int irq )
+static void unmask_global_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << irq);
 }
 
@@ -71,8 +73,9 @@ static void unmask_global_irq (unsigned int irq )
  * ack GPIO irq's
  * Ack only for edge triggered int's valid
  */
-static void inline ack_gpio_irq(u32 irq)
+static inline void ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
@@ -82,8 +85,9 @@ static void inline ack_gpio_irq(u32 irq)
 /*
  * mask GPIO irq's
  */
-static void inline mask_gpio_irq(u32 irq)
+static inline void mask_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	CPU_REG (reg_base, GPIO_MASK) &= ~bit;
@@ -92,8 +96,9 @@ static void inline mask_gpio_irq(u32 irq)
 /*
  * unmask GPIO irq's
  */
-static void inline unmask_gpio_irq(u32 irq)
+static inline void unmask_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	CPU_REG (reg_base, GPIO_MASK) |= bit;
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index fd33a19..b73501e 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -141,8 +141,9 @@ h7202_timer_interrupt(int irq, void *dev_id)
 /*
  * mask multiplexed timer IRQs
  */
-static void inline mask_timerx_irq (u32 irq)
+static inline void mask_timerx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit;
 	bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
 	CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit;
@@ -151,8 +152,9 @@ static void inline mask_timerx_irq (u32 irq)
 /*
  * unmask multiplexed timer IRQs
  */
-static void inline unmask_timerx_irq (u32 irq)
+static inline void unmask_timerx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit;
 	bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
 	CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit;
@@ -196,7 +198,7 @@ void __init h7202_init_irq (void)
 
 	for (irq = IRQ_TIMER1;
 	                  irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) {
-		mask_timerx_irq(irq);
+		mask_timerx_irq(irq_to_desc(irq));
 		set_irq_chip(irq, &h7202_timerx_chip);
 		set_irq_handler(irq, handle_edge_irq);
 		set_irq_flags(irq, IRQF_VALID );
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..3c23890 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -151,13 +151,15 @@ static void __init ap_map_io(void)
 
 #define INTEGRATOR_SC_VALID_INT	0x003fffff
 
-static void sc_mask_irq(unsigned int irq)
+static void sc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void sc_unmask_irq(unsigned int irq)
+static void sc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
 }
 
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..0c8a89c 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -145,14 +145,16 @@ static void __init intcp_map_io(void)
 #define sic_writel	__raw_writel
 #define sic_readl	__raw_readl
 
-static void cic_mask_irq(unsigned int irq)
+static void cic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_CIC_START;
 	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void cic_unmask_irq(unsigned int irq)
+static void cic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_CIC_START;
 	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
 }
@@ -164,14 +166,16 @@ static struct irq_chip cic_chip = {
 	.unmask	= cic_unmask_irq,
 };
 
-static void pic_mask_irq(unsigned int irq)
+static void pic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_PIC_START;
 	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void pic_unmask_irq(unsigned int irq)
+static void pic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_PIC_START;
 	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
 }
@@ -183,14 +187,16 @@ static struct irq_chip pic_chip = {
 	.unmask = pic_unmask_irq,
 };
 
-static void sic_mask_irq(unsigned int irq)
+static void sic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void sic_unmask_irq(unsigned int irq)
+static void sic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
 }
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index 0d099ca..7a41e2f 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -123,50 +123,58 @@ static void write_intsize(u32 val)
 
 /* 0 = Interrupt Masked and 1 = Interrupt not masked */
 static void
-iop13xx_irq_mask0 (unsigned int irq)
+iop13xx_irq_mask0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_0(read_intctl_0() & ~(1 << (irq - 0)));
 }
 
 static void
-iop13xx_irq_mask1 (unsigned int irq)
+iop13xx_irq_mask1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_1(read_intctl_1() & ~(1 << (irq - 32)));
 }
 
 static void
-iop13xx_irq_mask2 (unsigned int irq)
+iop13xx_irq_mask2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_2(read_intctl_2() & ~(1 << (irq - 64)));
 }
 
 static void
-iop13xx_irq_mask3 (unsigned int irq)
+iop13xx_irq_mask3(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_3(read_intctl_3() & ~(1 << (irq - 96)));
 }
 
 static void
-iop13xx_irq_unmask0(unsigned int irq)
+iop13xx_irq_unmask0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_0(read_intctl_0() | (1 << (irq - 0)));
 }
 
 static void
-iop13xx_irq_unmask1(unsigned int irq)
+iop13xx_irq_unmask1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_1(read_intctl_1() | (1 << (irq - 32)));
 }
 
 static void
-iop13xx_irq_unmask2(unsigned int irq)
+iop13xx_irq_unmask2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_2(read_intctl_2() | (1 << (irq - 64)));
 }
 
 static void
-iop13xx_irq_unmask3(unsigned int irq)
+iop13xx_irq_unmask3(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_3(read_intctl_3() | (1 << (irq - 96)));
 }
 
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index f34b0ed..3e10b50 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -156,7 +156,7 @@ void arch_teardown_msi_irq(unsigned int irq)
 	destroy_irq(irq);
 }
 
-static void iop13xx_msi_nop(unsigned int irq)
+static void iop13xx_msi_nop(struct irq_desc *desc)
 {
 	return;
 }
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index ba59b2d..5f8cd81 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -32,15 +32,17 @@ static void intstr_write(u32 val)
 }
 
 static void
-iop32x_irq_mask(unsigned int irq)
+iop32x_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	iop32x_mask &= ~(1 << irq);
 	intctl_write(iop32x_mask);
 }
 
 static void
-iop32x_irq_unmask(unsigned int irq)
+iop32x_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	iop32x_mask |= 1 << irq;
 	intctl_write(iop32x_mask);
 }
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index babb225..127a945 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -309,8 +309,9 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
+static int ixp2000_GPIO_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP2000_GPIO0;
 
 	/*
@@ -342,8 +343,9 @@ static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
+static void ixp2000_GPIO_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 
 	ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
@@ -351,13 +353,15 @@ static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
 	ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
-static void ixp2000_GPIO_irq_mask(unsigned int irq)
+static void ixp2000_GPIO_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
-static void ixp2000_GPIO_irq_unmask(unsigned int irq)
+static void ixp2000_GPIO_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
@@ -368,8 +372,9 @@ static struct irq_chip ixp2000_GPIO_irq_chip = {
 	.set_type	= ixp2000_GPIO_irq_type,
 };
 
-static void ixp2000_pci_irq_mask(unsigned int irq)
+static void ixp2000_pci_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
 	if (irq == IRQ_IXP2000_PCIA)
 		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
@@ -377,8 +382,9 @@ static void ixp2000_pci_irq_mask(unsigned int irq)
 		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
 }
 
-static void ixp2000_pci_irq_unmask(unsigned int irq)
+static void ixp2000_pci_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
 	if (irq == IRQ_IXP2000_PCIA)
 		ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26)));
@@ -401,14 +407,16 @@ static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static void ixp2000_err_irq_mask(unsigned int irq)
+static void ixp2000_err_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
 			(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
 }
 
-static void ixp2000_err_irq_unmask(unsigned int irq)
+static void ixp2000_err_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
 			(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
 }
@@ -425,13 +433,15 @@ static struct irq_chip ixp2000_pci_irq_chip = {
 	.unmask	= ixp2000_pci_irq_unmask
 };
 
-static void ixp2000_irq_mask(unsigned int irq)
+static void ixp2000_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
 }
 
-static void ixp2000_irq_unmask(unsigned int irq)
+static void ixp2000_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
 }
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 3045130..d3e896e 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -64,8 +64,9 @@ static struct slowport_cfg slowport_cpld_cfg = {
 };
 #endif
 
-static void ixdp2x00_irq_mask(unsigned int irq)
+static void ixdp2x00_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long dummy;
 	static struct slowport_cfg old_cfg;
 
@@ -88,8 +89,9 @@ static void ixdp2x00_irq_mask(unsigned int irq)
 #endif
 }
 
-static void ixdp2x00_irq_unmask(unsigned int irq)
+static void ixdp2x00_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long dummy;
 	static struct slowport_cfg old_cfg;
 
@@ -112,7 +114,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
 	static struct slowport_cfg old_cfg;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 #ifdef CONFIG_ARCH_IXDP2400
 	if (machine_is_ixdp2400())
@@ -134,7 +136,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2x00_cpld_irq_chip = {
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 4a12327..19c0087 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -49,14 +49,16 @@
 /*************************************************************************
  * IXDP2x01 IRQ Handling
  *************************************************************************/
-static void ixdp2x01_irq_mask(unsigned int irq)
+static void ixdp2x01_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
 				IXP2000_BOARD_IRQ_MASK(irq));
 }
 
-static void ixdp2x01_irq_unmask(unsigned int irq)
+static void ixdp2x01_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG,
 				IXP2000_BOARD_IRQ_MASK(irq));
 }
@@ -68,7 +70,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 ex_interrupt;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 	ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask;
 
@@ -84,7 +86,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2x01_irq_chip = {
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index aa4c442..3454c62 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -111,8 +111,9 @@ enum ixp23xx_irq_type {
 
 static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type);
 
-static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
+static int ixp23xx_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
 	u32 int_style;
 	enum ixp23xx_irq_type irq_type;
@@ -173,8 +174,9 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp23xx_irq_mask(unsigned int irq)
+static void ixp23xx_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
 	if (irq >= 56)
@@ -184,8 +186,9 @@ static void ixp23xx_irq_mask(unsigned int irq)
 	*intr_reg &= ~(1 << (irq % 32));
 }
 
-static void ixp23xx_irq_ack(unsigned int irq)
+static void ixp23xx_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
 
 	if ((line < 6) || (line > 15))
@@ -198,11 +201,12 @@ static void ixp23xx_irq_ack(unsigned int irq)
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp23xx_irq_level_unmask(unsigned int irq)
+static void ixp23xx_irq_level_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
-	ixp23xx_irq_ack(irq);
+	ixp23xx_irq_ack(desc);
 
 	if (irq >= 56)
 		irq += 8;
@@ -211,8 +215,9 @@ static void ixp23xx_irq_level_unmask(unsigned int irq)
 	*intr_reg |= (1 << (irq % 32));
 }
 
-static void ixp23xx_irq_edge_unmask(unsigned int irq)
+static void ixp23xx_irq_edge_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
 	if (irq >= 56)
@@ -236,12 +241,12 @@ static struct irq_chip ixp23xx_irq_edge_chip = {
 	.set_type	= ixp23xx_irq_set_type
 };
 
-static void ixp23xx_pci_irq_mask(unsigned int irq)
+static void ixp23xx_pci_irq_mask(struct irq_desc *desc)
 {
 	*IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
 }
 
-static void ixp23xx_pci_irq_unmask(unsigned int irq)
+static void ixp23xx_pci_irq_unmask(struct irq_desc *desc)
 {
 	*IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq));
 }
@@ -256,7 +261,7 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 
 	pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	/* See which PCI_INTA, or PCI_INTB interrupted */
 	if (pci_interrupt & (1 << 26)) {
@@ -269,7 +274,7 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 
 	generic_handle_irq(irqno);
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixp23xx_pci_irq_chip = {
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index f1b124a..63e5f16 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -48,13 +48,15 @@
 /*
  * IXDP2351 Interrupt Handling
  */
-static void ixdp2351_inta_mask(unsigned int irq)
+static void ixdp2351_inta_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(irq);
 }
 
-static void ixdp2351_inta_unmask(unsigned int irq)
+static void ixdp2351_inta_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq);
 }
 
@@ -64,7 +66,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
 		*IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 	for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
@@ -74,7 +76,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2351_inta_chip = {
@@ -83,13 +85,15 @@ static struct irq_chip ixdp2351_inta_chip = {
 	.unmask	= ixdp2351_inta_unmask
 };
 
-static void ixdp2351_intb_mask(unsigned int irq)
+static void ixdp2351_intb_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(irq);
 }
 
-static void ixdp2351_intb_unmask(unsigned int irq)
+static void ixdp2351_intb_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq);
 }
 
@@ -99,7 +103,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
 		*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
 	int i;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
@@ -109,7 +113,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2351_intb_chip = {
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..e42760c 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -128,8 +128,9 @@ int irq_to_gpio(unsigned int irq)
 }
 EXPORT_SYMBOL(irq_to_gpio);
 
-static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
+static int ixp4xx_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq2gpio[irq];
 	u32 int_style;
 	enum ixp4xx_irq_type irq_type;
@@ -193,16 +194,18 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp4xx_irq_mask(unsigned int irq)
+static void ixp4xx_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
 		*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
 	else
 		*IXP4XX_ICMR &= ~(1 << irq);
 }
 
-static void ixp4xx_irq_ack(unsigned int irq)
+static void ixp4xx_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = (irq < 32) ? irq2gpio[irq] : -1;
 
 	if (line >= 0)
@@ -213,10 +216,11 @@ static void ixp4xx_irq_ack(unsigned int irq)
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp4xx_irq_unmask(unsigned int irq)
+static void ixp4xx_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!(ixp4xx_irq_edge & (1 << irq)))
-		ixp4xx_irq_ack(irq);
+		ixp4xx_irq_ack(desc);
 
 	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
 		*IXP4XX_ICMR2 |= (1 << (irq - 32));
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
index e375c1d..05eb2dc 100644
--- a/arch/arm/mach-ks8695/irq.c
+++ b/arch/arm/mach-ks8695/irq.c
@@ -34,29 +34,32 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-static void ks8695_irq_mask(unsigned int irqno)
+static void ks8695_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long inten;
 
 	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-	inten &= ~(1 << irqno);
+	inten &= ~(1 << irq);
 
 	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
 }
 
-static void ks8695_irq_unmask(unsigned int irqno)
+static void ks8695_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long inten;
 
 	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-	inten |= (1 << irqno);
+	inten |= (1 << irq);
 
 	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
 }
 
-static void ks8695_irq_ack(unsigned int irqno)
+static void ks8695_irq_ack(struct irq_desc *desc)
 {
-	__raw_writel((1 << irqno), KS8695_IRQ_VA + KS8695_INTST);
+	unsigned int irq = desc->irq;
+	__raw_writel((1 << irq), KS8695_IRQ_VA + KS8695_INTST);
 }
 
 
@@ -64,8 +67,9 @@ static struct irq_chip ks8695_irq_level_chip;
 static struct irq_chip ks8695_irq_edge_chip;
 
 
-static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
+static int ks8695_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned long ctrl, mode;
 	unsigned short level_triggered = 0;
 
@@ -93,7 +97,7 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
 			return -EINVAL;
 	}
 
-	switch (irqno) {
+	switch (irq) {
 		case KS8695_IRQ_EXTERN0:
 			ctrl &= ~IOPC_IOEINT0TM;
 			ctrl |= IOPC_IOEINT0_MODE(mode);
@@ -115,12 +119,12 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
 	}
 
 	if (level_triggered) {
-		set_irq_chip(irqno, &ks8695_irq_level_chip);
-		set_irq_handler(irqno, handle_level_irq);
+		set_irq_chip(irq, &ks8695_irq_level_chip);
+		set_irq_handler(irq, handle_level_irq);
 	}
 	else {
-		set_irq_chip(irqno, &ks8695_irq_edge_chip);
-		set_irq_handler(irqno, handle_edge_irq);
+		set_irq_chip(irq, &ks8695_irq_edge_chip);
+		set_irq_handler(irq, handle_edge_irq);
 	}
 
 	__raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
@@ -164,7 +168,8 @@ void __init ks8695_init_irq(void)
 
 			/* Edge-triggered interrupts */
 			default:
-				ks8695_irq_ack(irq);	/* clear pending bit */
+				/* clear pending bit */	
+				ks8695_irq_ack(irq_to_desc(irq));
 				set_irq_chip(irq, &ks8695_irq_edge_chip);
 				set_irq_handler(irq, handle_edge_irq);
 		}
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 50d2324..feb33fa 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -45,13 +45,15 @@
 #define FIQ_SOFT	(*(volatile unsigned long *) (IRQ_BASE + 0x110))
 #define FIQ_SOURCESEL	(*(volatile unsigned long *) (IRQ_BASE + 0x118))
 
-static void l7200_mask_irq(unsigned int irq)
+static void l7200_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IRQ_ENABLECLEAR = 1 << irq;
 }
 
-static void l7200_unmask_irq(unsigned int irq)
+static void l7200_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IRQ_ENABLE = 1 << irq;
 }
 
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 3d7bd50..04c7364 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -46,19 +46,22 @@ void __init kev7a400_map_io(void)
 
 static u16 CPLD_IRQ_mask;	/* Mask for CPLD IRQs, 1 == unmasked */
 
-static void kev7a400_ack_cpld_irq (u32 irq)
+static void kev7a400_ack_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD);
 }
 
-static void kev7a400_mask_cpld_irq (u32 irq)
+static void kev7a400_mask_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD));
 	CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
 }
 
-static void kev7a400_unmask_cpld_irq (u32 irq)
+static void kev7a400_unmask_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD);
 	CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
 }
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index cb15e5d..2536349 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -159,8 +159,9 @@ static void __init lpd7a40x_init (void)
 #endif
 }
 
-static void lh7a40x_ack_cpld_irq (u32 irq)
+static void lh7a40x_ack_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* CPLD doesn't have ack capability, but some devices may */
 
 #if defined (CPLD_INTMASK_TOUCH)
@@ -172,8 +173,9 @@ static void lh7a40x_ack_cpld_irq (u32 irq)
 #endif
 }
 
-static void lh7a40x_mask_cpld_irq (u32 irq)
+static void lh7a40x_mask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
@@ -186,8 +188,9 @@ static void lh7a40x_mask_cpld_irq (u32 irq)
 	}
 }
 
-static void lh7a40x_unmask_cpld_irq (u32 irq)
+static void lh7a40x_unmask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
@@ -211,7 +214,7 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int mask = CPLD_INTERRUPTS;
 
-	desc->chip->ack (irq);
+	desc->chip->ack(desc);
 
 	if ((mask & (1<<0)) == 0)	/* WLAN */
 		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
@@ -221,7 +224,7 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 		generic_handle_irq(IRQ_TOUCH);
 #endif
 
-	desc->chip->unmask (irq); /* Level-triggered need this */
+	desc->chip->unmask(desc); /* Level-triggered need this */
 }
 
 
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c
index 1ad3afc..b1b9480 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a400.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c
@@ -21,18 +21,21 @@
 
   /* CPU IRQ handling */
 
-static void lh7a400_mask_irq (u32 irq)
+static void lh7a400_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	INTC_INTENC = (1 << irq);
 }
 
-static void lh7a400_unmask_irq (u32 irq)
+static void lh7a400_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	INTC_INTENS = (1 << irq);
 }
 
-static void lh7a400_ack_gpio_irq (u32 irq)
+static void lh7a400_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	INTC_INTENC = (1 << irq);
 }
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
index 12b045b..cd8c16e 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c
@@ -43,34 +43,40 @@ static unsigned char irq_pri_vic2[] = {
 
   /* CPU IRQ handling */
 
-static void lh7a404_vic1_mask_irq (u32 irq)
+static void lh7a404_vic1_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC1_INTENCLR = (1 << irq);
 }
 
-static void lh7a404_vic1_unmask_irq (u32 irq)
+static void lh7a404_vic1_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC1_INTEN = (1 << irq);
 }
 
-static void lh7a404_vic2_mask_irq (u32 irq)
+static void lh7a404_vic2_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC2_INTENCLR = (1 << (irq - 32));
 }
 
-static void lh7a404_vic2_unmask_irq (u32 irq)
+static void lh7a404_vic2_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC2_INTEN = (1 << (irq - 32));
 }
 
-static void lh7a404_vic1_ack_gpio_irq (u32 irq)
+static void lh7a404_vic1_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	VIC1_INTENCLR = (1 << irq);
 }
 
-static void lh7a404_vic2_ack_gpio_irq (u32 irq)
+static void lh7a404_vic2_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	VIC2_INTENCLR = (1 << irq);
 }
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
index fd033bb..364631f 100644
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -20,13 +20,14 @@
 
 #include "common.h"
 
-static void lh7a40x_ack_cpld_irq (u32 irq)
+static void lh7a40x_ack_cpld_irq(struct irq_desc *desc)
 {
 	/* CPLD doesn't have ack capability */
 }
 
-static void lh7a40x_mask_cpld_irq (u32 irq)
+static void lh7a40x_mask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4;
@@ -37,8 +38,9 @@ static void lh7a40x_mask_cpld_irq (u32 irq)
 	}
 }
 
-static void lh7a40x_unmask_cpld_irq (u32 irq)
+static void lh7a40x_unmask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4;
@@ -60,7 +62,7 @@ static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int mask = CPLD_INTERRUPTS;
 
-	desc->chip->ack (irq);
+	desc->chip->ack(desc);
 
 	if ((mask & 0x1) == 0)	/* WLAN */
 		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
@@ -68,7 +70,7 @@ static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 	if ((mask & 0x2) == 0)	/* Touch */
 		generic_handle_irq(IRQ_LPD7A400_TS);
 
-	desc->chip->unmask (irq); /* Level-triggered need this */
+	desc->chip->unmask(desc); /* Level-triggered need this */
 }
 
 
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 43da8bb..0b1d53d 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -88,8 +88,9 @@ netx_hif_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 }
 
 static int
-netx_hif_irq_type(unsigned int _irq, unsigned int type)
+netx_hif_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	val = readl(NETX_DPMAS_IF_CONF1);
@@ -119,8 +120,9 @@ netx_hif_irq_type(unsigned int _irq, unsigned int type)
 }
 
 static void
-netx_hif_ack_irq(unsigned int _irq)
+netx_hif_ack_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
@@ -134,8 +136,9 @@ netx_hif_ack_irq(unsigned int _irq)
 }
 
 static void
-netx_hif_mask_irq(unsigned int _irq)
+netx_hif_mask_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
@@ -146,8 +149,9 @@ netx_hif_mask_irq(unsigned int _irq)
 }
 
 static void
-netx_hif_unmask_irq(unsigned int _irq)
+netx_hif_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
index 9a09b27..0635e22 100644
--- a/arch/arm/mach-nomadik/gpio.c
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -95,27 +95,29 @@ static inline int nmk_gpio_get_bitmask(int gpio)
 	return 1 << (gpio % 32);
 }
 
-static void nmk_gpio_irq_ack(unsigned int irq)
+static void nmk_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	if (!nmk_chip)
 		return;
 	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
 }
 
-static void nmk_gpio_irq_mask(unsigned int irq)
+static void nmk_gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask, reg;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return;
@@ -135,15 +137,16 @@ static void nmk_gpio_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 };
 
-static void nmk_gpio_irq_unmask(unsigned int irq)
+static void nmk_gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask, reg;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return;
@@ -163,15 +166,16 @@ static void nmk_gpio_irq_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 }
 
-static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
+static int nmk_gpio_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return -EINVAL;
@@ -195,7 +199,7 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
 
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 
-	nmk_gpio_irq_unmask(irq);
+	nmk_gpio_irq_unmask(desc);
 
 	return 0;
 }
@@ -216,7 +220,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 pending;
 	unsigned int first_irq;
 
-	nmk_chip = get_irq_data(irq);
+	nmk_chip = get_irq_desc_data(desc);
 	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
 	while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
 		gpio_irq = first_irq + __ffs(pending);
@@ -224,7 +228,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 	if (0) {/* don't ack parent irq, as ack == disable */
 		host_chip = get_irq_chip(irq);
-		host_chip->ack(irq);
+		host_chip->ack(desc);
 	}
 }
 
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index b45bb3b..9b42b41 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -37,13 +37,14 @@ void __init board_a9m9750dev_map_io(void)
 		     ARRAY_SIZE(board_a9m9750dev_io_desc));
 }
 
-static void a9m9750dev_fpga_ack_irq(unsigned int irq)
+static void a9m9750dev_fpga_ack_irq(struct irq_desc *desc)
 {
 	/* nothing */
 }
 
-static void a9m9750dev_fpga_mask_irq(unsigned int irq)
+static void a9m9750dev_fpga_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 ier;
 
 	ier = __raw_readb(FPGA_IER);
@@ -53,14 +54,16 @@ static void a9m9750dev_fpga_mask_irq(unsigned int irq)
 	__raw_writeb(ier, FPGA_IER);
 }
 
-static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
+static void a9m9750dev_fpga_maskack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	a9m9750dev_fpga_mask_irq(irq);
 	a9m9750dev_fpga_ack_irq(irq);
 }
 
-static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
+static void a9m9750dev_fpga_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 ier;
 
 	ier = __raw_readb(FPGA_IER);
@@ -82,7 +85,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 {
 	u8 stat = __raw_readb(FPGA_ISR);
 
-	desc->chip->mask_ack(irq);
+	desc->chip->mask_ack(desc);
 
 	while (stat != 0) {
 		int irqno = fls(stat) - 1;
@@ -92,7 +95,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 		generic_handle_irq(FPGA_IRQ(irqno));
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 void __init board_a9m9750dev_init_irq(void)
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 038f24d..3e21071 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -22,8 +22,9 @@
 #define irq2prio(i) (i)
 #define prio2irq(p) (p)
 
-static void ns9xxx_mask_irq(unsigned int irq)
+static void ns9xxx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX: better use cpp symbols */
 	int prio = irq2prio(irq);
 	u32 ic = __raw_readl(SYS_IC(prio / 4));
@@ -31,19 +32,21 @@ static void ns9xxx_mask_irq(unsigned int irq)
 	__raw_writel(ic, SYS_IC(prio / 4));
 }
 
-static void ns9xxx_ack_irq(unsigned int irq)
+static void ns9xxx_ack_irq(struct irq_desc *desc)
 {
 	__raw_writel(0, SYS_ISRADDR);
 }
 
-static void ns9xxx_maskack_irq(unsigned int irq)
+static void ns9xxx_maskack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ns9xxx_mask_irq(irq);
 	ns9xxx_ack_irq(irq);
 }
 
-static void ns9xxx_unmask_irq(unsigned int irq)
+static void ns9xxx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX: better use cpp symbols */
 	int prio = irq2prio(irq);
 	u32 ic = __raw_readl(SYS_IC(prio / 4));
@@ -92,10 +95,10 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 
 	if (desc->status & IRQ_DISABLED)
 out_mask:
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 
 	/* ack unconditionally to unmask lower prio irqs */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	raw_spin_unlock(&desc->lock);
 }
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 5cfce16..ad013b0 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -30,8 +30,9 @@
 #include <plat/fpga.h>
 #include <mach/gpio.h>
 
-static void fpga_mask_irq(unsigned int irq)
+static void fpga_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= OMAP_FPGA_IRQ_BASE;
 
 	if (irq < 8)
@@ -58,13 +59,14 @@ static inline u32 get_fpga_unmasked_irqs(void)
 }
 
 
-static void fpga_ack_irq(unsigned int irq)
+static void fpga_ack_irq(struct irq_desc *desc)
 {
 	/* Don't need to explicitly ACK FPGA interrupts */
 }
 
-static void fpga_unmask_irq(unsigned int irq)
+static void fpga_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= OMAP_FPGA_IRQ_BASE;
 
 	if (irq < 8)
@@ -78,10 +80,10 @@ static void fpga_unmask_irq(unsigned int irq)
 			      | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
 }
 
-static void fpga_mask_ack_irq(unsigned int irq)
+static void fpga_mask_ack_irq(struct irq_desc *desc)
 {
-	fpga_mask_irq(irq);
-	fpga_ack_irq(irq);
+	fpga_mask_irq(desc);
+	fpga_ack_irq(desc);
 }
 
 void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index db913c3..7dcaf35 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -70,16 +70,18 @@ static inline void irq_bank_writel(unsigned long value, int bank, int offset)
 	omap_writel(value, irq_banks[bank].base_reg + offset);
 }
 
-static void omap_ack_irq(unsigned int irq)
+static void omap_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq > 31)
 		omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
 
 	omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
 }
 
-static void omap_mask_irq(unsigned int irq)
+static void omap_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 	u32 l;
 
@@ -88,8 +90,9 @@ static void omap_mask_irq(unsigned int irq)
 	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
-static void omap_unmask_irq(unsigned int irq)
+static void omap_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 	u32 l;
 
@@ -98,14 +101,15 @@ static void omap_unmask_irq(unsigned int irq)
 	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
-static void omap_mask_ack_irq(unsigned int irq)
+static void omap_mask_ack_irq(struct irq_desc *desc)
 {
-	omap_mask_irq(irq);
-	omap_ack_irq(irq);
+	omap_mask_irq(desc);
+	omap_ack_irq(desc);
 }
 
-static int omap_wake_irq(unsigned int irq, unsigned int enable)
+static int omap_wake_irq(struct irq_desc *desc, unsigned int enable)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 
 	if (enable)
@@ -234,9 +238,9 @@ void __init omap_init_irq(void)
 	/* Unmask level 2 handler */
 
 	if (cpu_is_omap7xx())
-		omap_unmask_irq(INT_7XX_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_7XX_IH2_IRQ));
 	else if (cpu_is_omap15xx())
-		omap_unmask_irq(INT_1510_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_1510_IH2_IRQ));
 	else if (cpu_is_omap16xx())
-		omap_unmask_irq(INT_1610_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_1610_IH2_IRQ));
 }
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 26aeef5..32f8da9 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -101,13 +101,14 @@ static int omap_check_spurious(unsigned int irq)
 }
 
 /* XXX: FIQ and additional INTC support (only MPU at the moment) */
-static void omap_ack_irq(unsigned int irq)
+static void omap_ack_irq(struct irq_desc *desc)
 {
 	intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
 }
 
-static void omap_mask_irq(unsigned int irq)
+static void omap_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
 	if (cpu_is_omap34xx()) {
@@ -129,8 +130,9 @@ static void omap_mask_irq(unsigned int irq)
 	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
 }
 
-static void omap_unmask_irq(unsigned int irq)
+static void omap_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
 	irq &= (IRQ_BITS_PER_REG - 1);
@@ -138,10 +140,10 @@ static void omap_unmask_irq(unsigned int irq)
 	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
 }
 
-static void omap_mask_ack_irq(unsigned int irq)
+static void omap_mask_ack_irq(struct irq_desc *desc)
 {
-	omap_mask_irq(irq);
-	omap_ack_irq(irq);
+	omap_mask_irq(desc);
+	omap_ack_irq(desc);
 }
 
 static struct irq_chip omap_irq_chip = {
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
index a9ce02b..a08d90f 100644
--- a/arch/arm/mach-pnx4008/irq.c
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -36,24 +36,28 @@
 
 static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
 
-static void pnx4008_mask_irq(unsigned int irq)
+static void pnx4008_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
 }
 
-static void pnx4008_unmask_irq(unsigned int irq)
+static void pnx4008_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq));	/* unmask interrupt */
 }
 
-static void pnx4008_mask_ack_irq(unsigned int irq)
+static void pnx4008_mask_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
 	__raw_writel(INTC_BIT(irq), INTC_SR(irq));	/* clear interrupt status */
 }
 
-static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
+static int pnx4008_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
 		__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq));	/*edge sensitive */
@@ -99,14 +103,14 @@ void __init pnx4008_init_irq(void)
 	for (i = 0; i < NR_IRQS; i++) {
 		set_irq_flags(i, IRQF_VALID);
 		set_irq_chip(i, &pnx4008_irq_chip);
-		pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
+		pnx4008_set_irq_type(irq_to_desc(i), pnx4008_irq_type[i]);
 	}
 
 	/* configure and enable IRQ 0,1,30,31 (cascade interrupts) */
-	pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
-	pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
-	pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
-	pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB1_IRQ_N), pnx4008_irq_type[SUB1_IRQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB2_IRQ_N), pnx4008_irq_type[SUB2_IRQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB1_FIQ_N), pnx4008_irq_type[SUB1_FIQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB2_FIQ_N), pnx4008_irq_type[SUB2_FIQ_N]);
 
 	/* mask all others */
 	__raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index f3b5ace..02b7e00 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -73,15 +73,17 @@ int __init parse_balloon3_features(char *arg)
 }
 early_param("balloon3_features", parse_balloon3_features);
 
-static void balloon3_mask_irq(unsigned int irq)
+static void balloon3_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int balloon3_irq = (irq - BALLOON3_IRQ(0));
 	balloon3_irq_enabled &= ~(1 << balloon3_irq);
 	__raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
 }
 
-static void balloon3_unmask_irq(unsigned int irq)
+static void balloon3_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int balloon3_irq = (irq - BALLOON3_IRQ(0));
 	balloon3_irq_enabled |= (1 << balloon3_irq);
 	__raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
@@ -102,7 +104,7 @@ static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc)
 	do {
 		/* clear useless edge notification */
 		if (desc->chip->ack)
-			desc->chip->ack(BALLOON3_AUX_NIRQ);
+			desc->chip->ack(irq_to_desc(BALLOON3_AUX_NIRQ));
 		while (pending) {
 			irq = BALLOON3_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 890fb90..2d2cb9c 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,9 @@
 struct sys_timer;
 
 extern struct sys_timer pxa_timer;
+struct irq_desc;
 extern void __init pxa_init_irq(int irq_nr,
-				int (*set_wake)(unsigned int, unsigned int));
+				int (*set_wake)(struct irq_desc *desc, unsigned int));
 extern void __init pxa25x_init_irq(void);
 #ifdef CONFIG_CPU_PXA26x
 extern void __init pxa26x_init_irq(void);
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 1beb40f..5103a3d 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -37,13 +37,15 @@
 
 static int pxa_internal_irq_nr;
 
-static void pxa_mask_irq(unsigned int irq)
+static void pxa_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
 }
 
-static void pxa_unmask_irq(unsigned int irq)
+static void pxa_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	_ICMR(irq) |= 1 << IRQ_BIT(irq);
 }
 
@@ -57,8 +59,9 @@ static struct irq_chip pxa_internal_irq_chip = {
 /*
  * GPIO IRQs for GPIO 0 and 1
  */
-static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
+static int pxa_set_low_gpio_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq - IRQ_GPIO0;
 
 	if (__gpio_is_occupied(gpio)) {
@@ -79,18 +82,21 @@ static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void pxa_ack_low_gpio(unsigned int irq)
+static void pxa_ack_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GEDR0 = (1 << (irq - IRQ_GPIO0));
 }
 
-static void pxa_mask_low_gpio(unsigned int irq)
+static void pxa_mask_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
 }
 
-static void pxa_unmask_low_gpio(unsigned int irq)
+static void pxa_unmask_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= 1 << (irq - PXA_IRQ(0));
 }
 
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index d279507..0d6ba7b 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -94,8 +94,9 @@ static unsigned long lpd270_pin_config[] __initdata = {
 
 static unsigned int lpd270_irq_enabled;
 
-static void lpd270_mask_irq(unsigned int irq)
+static void lpd270_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lpd270_irq = irq - LPD270_IRQ(0);
 
 	__raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS);
@@ -104,8 +105,9 @@ static void lpd270_mask_irq(unsigned int irq)
 	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
 }
 
-static void lpd270_unmask_irq(unsigned int irq)
+static void lpd270_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lpd270_irq = irq - LPD270_IRQ(0);
 
 	lpd270_irq_enabled |= 1 << lpd270_irq;
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 63d65a2..c133f49 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -121,14 +121,16 @@ EXPORT_SYMBOL(lubbock_set_misc_wr);
 
 static unsigned long lubbock_irq_enabled;
 
-static void lubbock_mask_irq(unsigned int irq)
+static void lubbock_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
 	LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
 }
 
-static void lubbock_unmask_irq(unsigned int irq)
+static void lubbock_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 5543c64..f7da0c6 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -122,14 +122,16 @@ static unsigned long mainstone_pin_config[] = {
 
 static unsigned long mainstone_irq_enabled;
 
-static void mainstone_mask_irq(unsigned int irq)
+static void mainstone_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
 	MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
 }
 
-static void mainstone_unmask_irq(unsigned int irq)
+static void mainstone_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	MST_INTSETCLR &= ~(1 << mainstone_irq);
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 9d0ecea..9e2f67f 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -241,14 +241,16 @@ static struct platform_device pcm990_backlight_device = {
 
 static unsigned long pcm990_irq_enabled;
 
-static void pcm990_mask_ack_irq(unsigned int irq)
+static void pcm990_mask_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pcm990_irq = (irq - PCM027_IRQ(0));
 	PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
 }
 
-static void pcm990_unmask_irq(unsigned int irq)
+static void pcm990_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pcm990_irq = (irq - PCM027_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	PCM990_INTSETCLR |= 1 << pcm990_irq;
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 0b9ad30..ee62738 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/suspend.h>
 #include <linux/sysdev.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
@@ -282,8 +283,9 @@ static inline void pxa25x_init_pm(void) {}
 /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
  */
 
-static int pxa25x_set_wake(unsigned int irq, unsigned int on)
+static int pxa25x_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int gpio = IRQ_TO_GPIO(irq);
 	uint32_t mask = 0;
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 0af3617..027b5f9 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -17,6 +17,7 @@
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -334,8 +335,9 @@ static inline void pxa27x_init_pm(void) {}
 /* PXA27x:  Various gpios can issue wakeup events.  This logic only
  * handles the simple cases, not the WEMUX2 and WEMUX3 options
  */
-static int pxa27x_set_wake(unsigned int irq, unsigned int on)
+static int pxa27x_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int gpio = IRQ_TO_GPIO(irq);
 	uint32_t mask;
 
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4d7c03e..7204fbd 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -536,19 +536,22 @@ static inline void pxa3xx_init_pm(void) {}
 #define pxa3xx_set_wake	NULL
 #endif
 
-static void pxa_ack_ext_wakeup(unsigned int irq)
+static void pxa_ack_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	PECR |= PECR_IS(irq - IRQ_WAKEUP0);
 }
 
-static void pxa_mask_ext_wakeup(unsigned int irq)
+static void pxa_mask_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
 	PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
 }
 
-static void pxa_unmask_ext_wakeup(unsigned int irq)
+static void pxa_unmask_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
 	PECR |= PECR_IE(irq - IRQ_WAKEUP0);
 }
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 1dd1334..5836c2e 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -247,8 +247,9 @@ static inline int viper_bit_to_irq(int bit)
 	return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
 }
 
-static void viper_ack_irq(unsigned int irq)
+static void viper_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int viper_irq = viper_irq_to_bitmask(irq);
 
 	if (viper_irq & 0xff)
@@ -257,13 +258,15 @@ static void viper_ack_irq(unsigned int irq)
 		VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
 }
 
-static void viper_mask_irq(unsigned int irq)
+static void viper_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq));
 }
 
-static void viper_unmask_irq(unsigned int irq)
+static void viper_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	viper_irq_enabled_mask |= viper_irq_to_bitmask(irq);
 }
 
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 39896d8..e2c96f7 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -82,18 +82,21 @@ static inline int zeus_bit_to_irq(int bit)
 	return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0);
 }
 
-static void zeus_ack_irq(unsigned int irq)
+static void zeus_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writew(zeus_irq_to_bitmask(irq), ZEUS_CPLD_ISA_IRQ);
 }
 
-static void zeus_mask_irq(unsigned int irq)
+static void zeus_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(irq));
 }
 
-static void zeus_unmask_irq(unsigned int irq)
+static void zeus_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	zeus_irq_enabled_mask |= zeus_irq_to_bitmask(irq);
 }
 
@@ -110,7 +113,8 @@ static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc)
 	do {
 		/* we're in a chained irq handler,
 		 * so ack the interrupt by hand */
-		desc->chip->ack(gpio_to_irq(ZEUS_ISA_GPIO));
+		int irqx = gpio_to_irq(ZEUS_ISA_GPIO);
+		desc->chip->ack(irq_to_desc(irqx));
 
 		if (likely(pending)) {
 			irq = zeus_bit_to_irq(__ffs(pending));
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 9dd15d6..e273268 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -6,8 +6,9 @@
 #include <asm/hardware/iomd.h>
 #include <asm/irq.h>
 
-static void iomd_ack_irq_a(unsigned int irq)
+static void iomd_ack_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -16,8 +17,9 @@ static void iomd_ack_irq_a(unsigned int irq)
 	iomd_writeb(mask, IOMD_IRQCLRA);
 }
 
-static void iomd_mask_irq_a(unsigned int irq)
+static void iomd_mask_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -25,8 +27,9 @@ static void iomd_mask_irq_a(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
 }
 
-static void iomd_unmask_irq_a(unsigned int irq)
+static void iomd_unmask_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -40,8 +43,9 @@ static struct irq_chip iomd_a_chip = {
 	.unmask = iomd_unmask_irq_a,
 };
 
-static void iomd_mask_irq_b(unsigned int irq)
+static void iomd_mask_irq_b(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -49,8 +53,9 @@ static void iomd_mask_irq_b(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
 }
 
-static void iomd_unmask_irq_b(unsigned int irq)
+static void iomd_unmask_irq_b(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -64,8 +69,9 @@ static struct irq_chip iomd_b_chip = {
 	.unmask = iomd_unmask_irq_b,
 };
 
-static void iomd_mask_irq_dma(unsigned int irq)
+static void iomd_mask_irq_dma(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -73,8 +79,9 @@ static void iomd_mask_irq_dma(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_DMAMASK);
 }
 
-static void iomd_unmask_irq_dma(unsigned int irq)
+static void iomd_unmask_irq_dma(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -88,8 +95,9 @@ static struct irq_chip iomd_dma_chip = {
 	.unmask = iomd_unmask_irq_dma,
 };
 
-static void iomd_mask_irq_fiq(unsigned int irq)
+static void iomd_mask_irq_fiq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -97,8 +105,9 @@ static void iomd_mask_irq_fiq(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_FIQMASK);
 }
 
-static void iomd_unmask_irq_fiq(unsigned int irq)
+static void iomd_unmask_irq_fiq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 217b102..7f16557 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -75,31 +75,32 @@ static unsigned char bast_pc104_irqmasks[] = {
 static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
 
 static void
-bast_pc104_mask(unsigned int irqno)
+bast_pc104_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp;
 
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-	temp &= ~bast_pc104_irqmasks[irqno];
+	temp &= ~bast_pc104_irqmasks[irq];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
 }
 
 static void
-bast_pc104_maskack(unsigned int irqno)
+bast_pc104_maskack(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + IRQ_ISA;
-
-	bast_pc104_mask(irqno);
-	desc->chip->ack(IRQ_ISA);
+	struct irq_desc *desc_isa = irq_to_desc(IRQ_ISA);
+	bast_pc104_mask(desc);
+	desc_isa->chip->ack(desc_isa);
 }
 
 static void
-bast_pc104_unmask(unsigned int irqno)
+bast_pc104_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp;
 
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-	temp |= bast_pc104_irqmasks[irqno];
+	temp |= bast_pc104_irqmasks[irq];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
 }
 
@@ -120,10 +121,11 @@ bast_irq_pc104_demux(unsigned int irq,
 	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
 
 	if (unlikely(stat == 0)) {
+		struct irq_desc *desc_isa;
 		/* ack if we get an irq with nothing (ie, startup) */
 
-		desc = irq_desc + IRQ_ISA;
-		desc->chip->ack(IRQ_ISA);
+		desc_isa = irq_to_desc(IRQ_ISA);
+		desc_isa->chip->ack(desc_isa);
 	} else {
 		/* handle the IRQ */
 
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index 6000ca9..e7aa082 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -49,9 +49,10 @@
 */
 
 static void
-s3c2412_irq_mask(unsigned int irqno)
+s3c2412_irq_mask(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -62,9 +63,10 @@ s3c2412_irq_mask(unsigned int irqno)
 }
 
 static inline void
-s3c2412_irq_ack(unsigned int irqno)
+s3c2412_irq_ack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 
 	__raw_writel(bitval, S3C2412_EINTPEND);
 	__raw_writel(bitval, S3C2410_SRCPND);
@@ -72,9 +74,10 @@ s3c2412_irq_ack(unsigned int irqno)
 }
 
 static inline void
-s3c2412_irq_maskack(unsigned int irqno)
+s3c2412_irq_maskack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -89,9 +92,10 @@ s3c2412_irq_maskack(unsigned int irqno)
 }
 
 static void
-s3c2412_irq_unmask(unsigned int irqno)
+s3c2412_irq_unmask(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2412_EINTMASK);
@@ -132,19 +136,22 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_CFSDI	(1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
 #define SUBMSK_CFSDI	INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
 
-static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_CFSDI, SUBMSK_CFSDI);
 }
 
-static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_CFSDI);
 }
 
-static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
+static void s3c2412_irq_cfsdi_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_CFSDI, SUBMSK_CFSDI);
 }
 
 static struct irq_chip s3c2412_irq_cfsdi = {
@@ -154,7 +161,7 @@ static struct irq_chip s3c2412_irq_cfsdi = {
 	.unmask		= s3c2412_irq_cfsdi_unmask,
 };
 
-static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
+static int s3c2412_irq_rtc_wake(struct irq_desc *desc, unsigned int state)
 {
 	unsigned long pwrcfg;
 
@@ -165,7 +172,7 @@ static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
 		pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
 	__raw_writel(pwrcfg, S3C2412_PWRCFG);
 
-	return s3c_irq_chip.set_wake(irqno, state);
+	return s3c_irq_chip.set_wake(desc, state);
 }
 
 static struct irq_chip s3c2412_irq_rtc_chip;
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 0c049b9..60b88aa 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -69,21 +69,24 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
 #define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
 
 static void
-s3c_irq_wdtac97_mask(unsigned int irqno)
+s3c_irq_wdtac97_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_WDT, 3<<13);
 }
 
 static void
-s3c_irq_wdtac97_unmask(unsigned int irqno)
+s3c_irq_wdtac97_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_WDT);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_WDT);
 }
 
 static void
-s3c_irq_wdtac97_ack(unsigned int irqno)
+s3c_irq_wdtac97_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_WDT, 3<<13);
 }
 
 static struct irq_chip s3c_irq_wdtac97 = {
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 0e0d693..d87a496 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -75,19 +75,22 @@ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
 #define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
 
-static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
 }
 
-static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_WDTAC97);
 }
 
-static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
+static void s3c2443_irq_wdtac97_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
 }
 
 static struct irq_chip s3c2443_irq_wdtac97 = {
@@ -107,19 +110,22 @@ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
 #define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
 
-static void s3c2443_irq_lcd_mask(unsigned int irqno)
+static void s3c2443_irq_lcd_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_LCD, SUBMSK_LCD);
 }
 
-static void s3c2443_irq_lcd_unmask(unsigned int irqno)
+static void s3c2443_irq_lcd_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_LCD);
 }
 
-static void s3c2443_irq_lcd_ack(unsigned int irqno)
+static void s3c2443_irq_lcd_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_LCD, SUBMSK_LCD);
 }
 
 static struct irq_chip s3c2443_irq_lcd = {
@@ -140,19 +146,22 @@ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
 #define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
 
 
-static void s3c2443_irq_dma_mask(unsigned int irqno)
+static void s3c2443_irq_dma_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_DMA, SUBMSK_DMA);
 }
 
-static void s3c2443_irq_dma_unmask(unsigned int irqno)
+static void s3c2443_irq_dma_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_DMA);
 }
 
-static void s3c2443_irq_dma_ack(unsigned int irqno)
+static void s3c2443_irq_dma_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_DMA, SUBMSK_DMA);
 }
 
 static struct irq_chip s3c2443_irq_dma = {
@@ -173,19 +182,22 @@ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
 #define SUBMSK_UART3	(0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
 
 
-static void s3c2443_irq_uart3_mask(unsigned int irqno)
+static void s3c2443_irq_uart3_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART3, SUBMSK_UART3);
 }
 
-static void s3c2443_irq_uart3_unmask(unsigned int irqno)
+static void s3c2443_irq_uart3_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART3);
 }
 
-static void s3c2443_irq_uart3_ack(unsigned int irqno)
+static void s3c2443_irq_uart3_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART3, SUBMSK_UART3);
 }
 
 static struct irq_chip s3c2443_irq_uart3 = {
@@ -205,19 +217,22 @@ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
 #define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
 
-static void s3c2443_irq_cam_mask(unsigned int irqno)
+static void s3c2443_irq_cam_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_CAM, SUBMSK_CAM);
 }
 
-static void s3c2443_irq_cam_unmask(unsigned int irqno)
+static void s3c2443_irq_cam_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_CAM);
 }
 
-static void s3c2443_irq_cam_ack(unsigned int irqno)
+static void s3c2443_irq_cam_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_CAM, SUBMSK_CAM);
 }
 
 static struct irq_chip s3c2443_irq_cam = {
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 3093d46..f54c973 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -37,8 +37,9 @@ static int GPIO_IRQ_mask = (1 << 11) - 1;
 #define GPIO_11_27_IRQ(i)	((i) - 21)
 #define GPIO11_27_MASK(irq)	(1 << GPIO_11_27_IRQ(irq))
 
-static int sa1100_gpio_type(unsigned int irq, unsigned int type)
+static int sa1100_gpio_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	if (irq <= 10)
@@ -70,23 +71,27 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
 /*
  * GPIO IRQs must be acknowledged.  This is for IRQs from 0 to 10.
  */
-static void sa1100_low_gpio_ack(unsigned int irq)
+static void sa1100_low_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GEDR = (1 << irq);
 }
 
-static void sa1100_low_gpio_mask(unsigned int irq)
+static void sa1100_low_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << irq);
 }
 
-static void sa1100_low_gpio_unmask(unsigned int irq)
+static void sa1100_low_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= 1 << irq;
 }
 
-static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on)
+static int sa1100_low_gpio_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (on)
 		PWER |= 1 << irq;
 	else
@@ -139,15 +144,17 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
  * In addition, the IRQs are all collected up into one bit in the
  * interrupt controller registers.
  */
-static void sa1100_high_gpio_ack(unsigned int irq)
+static void sa1100_high_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GEDR = mask;
 }
 
-static void sa1100_high_gpio_mask(unsigned int irq)
+static void sa1100_high_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GPIO_IRQ_mask &= ~mask;
@@ -156,8 +163,9 @@ static void sa1100_high_gpio_mask(unsigned int irq)
 	GFER &= ~mask;
 }
 
-static void sa1100_high_gpio_unmask(unsigned int irq)
+static void sa1100_high_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GPIO_IRQ_mask |= mask;
@@ -166,8 +174,9 @@ static void sa1100_high_gpio_unmask(unsigned int irq)
 	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 }
 
-static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on)
+static int sa1100_high_gpio_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (on)
 		PWER |= GPIO11_27_MASK(irq);
 	else
@@ -188,21 +197,24 @@ static struct irq_chip sa1100_high_gpio_chip = {
  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
  * this is for internal IRQs i.e. from 11 to 31.
  */
-static void sa1100_mask_irq(unsigned int irq)
+static void sa1100_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << irq);
 }
 
-static void sa1100_unmask_irq(unsigned int irq)
+static void sa1100_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= (1 << irq);
 }
 
 /*
  * Apart form GPIOs, only the RTC alarm can be a wakeup event.
  */
-static int sa1100_set_wake(unsigned int irq, unsigned int on)
+static int sa1100_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (irq == IRQ_RTCAlrm) {
 		if (on)
 			PWER |= PWER_RTC;
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 0b505d9..4003df3 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -36,7 +36,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 		/*
 		 * Acknowledge the parent IRQ.
 		 */
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 
 		/*
 		 * Read the interrupt reason register.  Let's have all
@@ -54,7 +54,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 		 * recheck the register for any pending IRQs.
 		 */
 		if (irr & (IRR_ETHERNET | IRR_USAR)) {
-			desc->chip->mask(irq);
+			desc->chip->mask(desc);
 
 			/*
 			 * Ack the interrupt now to prevent re-entering
@@ -62,7 +62,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 			 * since we'll check the IRR register prior to
 			 * leaving.
 			 */
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 
 			if (irr & IRR_ETHERNET) {
 				generic_handle_irq(IRQ_NEPONSET_SMC9196);
@@ -72,7 +72,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 				generic_handle_irq(IRQ_NEPONSET_USAR);
 			}
 
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		}
 
 		if (irr & IRR_SA1111) {
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
index c04eb6a..0f17814 100644
--- a/arch/arm/mach-shark/irq.c
+++ b/arch/arm/mach-shark/irq.c
@@ -30,8 +30,9 @@ static unsigned char cached_irq_mask[2] = { 0xfb, 0xff };
  * These have to be protected by the irq controller spinlock
  * before being called.
  */
-static void shark_disable_8259A_irq(unsigned int irq)
+static void shark_disable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	if (irq<8) {
 	  mask = 1 << irq;
@@ -44,8 +45,9 @@ static void shark_disable_8259A_irq(unsigned int irq)
 	}
 }
 
-static void shark_enable_8259A_irq(unsigned int irq)
+static void shark_enable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	if (irq<8) {
 	  mask = ~(1 << irq);
@@ -58,7 +60,9 @@ static void shark_enable_8259A_irq(unsigned int irq)
 	}
 }
 
-static void shark_ack_8259A_irq(unsigned int irq){}
+static void shark_ack_8259A_irq(struct irq_desc *desc)
+{
+}
 
 static irqreturn_t bogus_int(int irq, void *dev_id)
 {
diff --git a/arch/arm/mach-stmp378x/stmp378x.c b/arch/arm/mach-stmp378x/stmp378x.c
index ddd49a7..5224f31 100644
--- a/arch/arm/mach-stmp378x/stmp378x.c
+++ b/arch/arm/mach-stmp378x/stmp378x.c
@@ -47,8 +47,9 @@
 /*
  * IRQ handling
  */
-static void stmp378x_ack_irq(unsigned int irq)
+static void stmp378x_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Tell ICOLL to release IRQ line */
 	__raw_writel(0, REGS_ICOLL_BASE + HW_ICOLL_VECTOR);
 
@@ -60,15 +61,17 @@ static void stmp378x_ack_irq(unsigned int irq)
 	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
 }
 
-static void stmp378x_mask_irq(unsigned int irq)
+static void stmp378x_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ disable */
 	stmp3xxx_clearl(BM_ICOLL_INTERRUPTn_ENABLE,
 			REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + irq * 0x10);
 }
 
-static void stmp378x_unmask_irq(unsigned int irq)
+static void stmp378x_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ enable */
 	stmp3xxx_setl(BM_ICOLL_INTERRUPTn_ENABLE,
 		      REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + irq * 0x10);
diff --git a/arch/arm/mach-stmp37xx/stmp37xx.c b/arch/arm/mach-stmp37xx/stmp37xx.c
index 8c7d6fb..c080776 100644
--- a/arch/arm/mach-stmp37xx/stmp37xx.c
+++ b/arch/arm/mach-stmp37xx/stmp37xx.c
@@ -43,8 +43,9 @@
 /*
  * IRQ handling
  */
-static void stmp37xx_ack_irq(unsigned int irq)
+static void stmp37xx_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Disable IRQ */
 	stmp3xxx_clearl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
@@ -56,15 +57,17 @@ static void stmp37xx_ack_irq(unsigned int irq)
 	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
 }
 
-static void stmp37xx_mask_irq(unsigned int irq)
+static void stmp37xx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ disable */
 	stmp3xxx_clearl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
 }
 
-static void stmp37xx_unmask_irq(unsigned int irq)
+static void stmp37xx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ enable */
 	stmp3xxx_setl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9ddb49b..79892c8 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -62,14 +62,16 @@
 #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 
-static void sic_mask_irq(unsigned int irq)
+static void sic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 }
 
-static void sic_unmask_irq(unsigned int irq)
+static void sic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
 }
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 0ce9d8e..03e5834 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -92,8 +92,9 @@ static void nuc900_group_enable(struct group_irq *gpirq, int enable)
 	__raw_writel(regval, REG_AIC_GEN);
 }
 
-static void nuc900_irq_mask(unsigned int irq)
+static void nuc900_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct group_irq *group_irq;
 
 	group_irq = NULL;
@@ -143,13 +144,14 @@ static void nuc900_irq_mask(unsigned int irq)
  * to REG_AIC_EOSCR for ACK
  */
 
-static void nuc900_irq_ack(unsigned int irq)
+static void nuc900_irq_ack(struct irq_desc *desc)
 {
 	__raw_writel(0x01, REG_AIC_EOSCR);
 }
 
-static void nuc900_irq_unmask(unsigned int irq)
+static void nuc900_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct group_irq *group_irq;
 
 	group_irq = NULL;
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
index f73ce87..1b3afb2 100644
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -270,12 +270,12 @@ static void em_stop(void)
  */
 static void em_route_irq(int irq, unsigned int cpu)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	struct irq_desc *desc = irq_to_desc(irq);
 	const struct cpumask *mask = cpumask_of(cpu);
 
 	spin_lock_irq(&desc->lock);
 	cpumask_copy(desc->affinity, mask);
-	desc->chip->set_affinity(irq, mask);
+	desc->chip->set_affinity(desc, mask);
 	spin_unlock_irq(&desc->lock);
 }
 
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 70b2389..06385cd 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -63,28 +63,32 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
 	__raw_writel(l, port->base + GPIO_IMR);
 }
 
-static void gpio_ack_irq(u32 irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
 }
 
-static void gpio_mask_irq(u32 irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
 }
 
-static void gpio_unmask_irq(u32 irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
 }
 
 static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
 
-static int gpio_set_irq_type(u32 irq, u32 type)
+static int gpio_set_irq_type(struct irq_desc *desc, u32 type)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
 	u32 bit, val;
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 778ddfe..3721b92 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -91,14 +91,16 @@ EXPORT_SYMBOL(mxc_set_irq_fiq);
 #endif /* CONFIG_FIQ */
 
 /* Disable interrupt number "irq" in the AVIC */
-static void mxc_mask_irq(unsigned int irq)
+static void mxc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(irq, avic_base + AVIC_INTDISNUM);
 }
 
 /* Enable interrupt number "irq" in the AVIC */
-static void mxc_unmask_irq(unsigned int irq)
+static void mxc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(irq, avic_base + AVIC_INTENNUM);
 }
 
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 76a347b..ae0f98c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -871,8 +871,9 @@ bad:
 	return -EINVAL;
 }
 
-static int gpio_irq_type(unsigned irq, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	struct gpio_bank *bank;
 	unsigned gpio;
 	int retval;
@@ -894,7 +895,7 @@ static int gpio_irq_type(unsigned irq, unsigned type)
 			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
 		return -EINVAL;
 
-	bank = get_irq_chip_data(irq);
+	bank = get_irq_desc_chip_data(desc);
 	spin_lock_irqsave(&bank->lock, flags);
 	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
 	if (retval == 0) {
@@ -1163,15 +1164,16 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
-static int gpio_wake_enable(unsigned int irq, unsigned int enable)
+static int gpio_wake_enable(struct irq_desc *desc, unsigned int enable)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank;
 	int retval;
 
 	if (check_gpio(gpio) < 0)
 		return -ENODEV;
-	bank = get_irq_chip_data(irq);
+	bank = get_irq_desc_chip_data(desc);
 	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
 
 	return retval;
@@ -1266,7 +1268,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 retrigger = 0;
 	int unmasked = 0;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	bank = get_irq_data(irq);
 #ifdef CONFIG_ARCH_OMAP1
@@ -1318,7 +1320,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		configured, we could unmask GPIO bank interrupt immediately */
 		if (!level_mask && !unmasked) {
 			unmasked = 1;
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		}
 
 		isr |= retrigger;
@@ -1353,28 +1355,31 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	handler(s) are executed in order to avoid spurious bank
 	interrupt */
 	if (!unmasked)
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 
 }
 
-static void gpio_irq_shutdown(unsigned int irq)
+static void gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_reset_gpio(bank, gpio);
 }
 
-static void gpio_ack_irq(unsigned int irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_clear_gpio_irqstatus(bank, gpio);
 }
 
-static void gpio_mask_irq(unsigned int irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
@@ -1382,12 +1387,12 @@ static void gpio_mask_irq(unsigned int irq)
 	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
 }
 
-static void gpio_unmask_irq(unsigned int irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 	unsigned int irq_mask = 1 << get_gpio_index(gpio);
-	struct irq_desc *desc = irq_to_desc(irq);
 	u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK;
 
 	if (trigger)
@@ -1419,21 +1424,23 @@ static struct irq_chip gpio_irq_chip = {
 
 /* MPUIO uses the always-on 32k clock */
 
-static void mpuio_ack_irq(unsigned int irq)
+static void mpuio_ack_irq(struct irq_desc *desc)
 {
 	/* The ISR is reset automatically, so do nothing here. */
 }
 
-static void mpuio_mask_irq(unsigned int irq)
+static void mpuio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_set_gpio_irqenable(bank, gpio, 0);
 }
 
-static void mpuio_unmask_irq(unsigned int irq)
+static void mpuio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index e814803..4fa621a 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -233,19 +233,21 @@ EXPORT_SYMBOL(orion_gpio_set_blink);
  *
  ****************************************************************************/
 
-static void gpio_irq_ack(u32 irq)
+static void gpio_irq_ack(struct irq_desc *desc)
 {
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	unsigned int irq = desc->irq;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
 		int pin = irq_to_gpio(irq);
 		writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin));
 	}
 }
 
-static void gpio_irq_mask(u32 irq)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
 		GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
 	u32 u = readl(reg);
@@ -253,10 +255,11 @@ static void gpio_irq_mask(u32 irq)
 	writel(u, reg);
 }
 
-static void gpio_irq_unmask(u32 irq)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
 		GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
 	u32 u = readl(reg);
@@ -264,10 +267,10 @@ static void gpio_irq_unmask(u32 irq)
 	writel(u, reg);
 }
 
-static int gpio_irq_set_type(u32 irq, u32 type)
+static int gpio_irq_set_type(struct irq_desc *desc, u32 type)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	struct irq_desc *desc;
 	u32 u;
 
 	u = readl(GPIO_IO_CONF(pin)) & (1 << (pin & 31));
@@ -277,8 +280,6 @@ static int gpio_irq_set_type(u32 irq, u32 type)
 		return -EINVAL;
 	}
 
-	desc = irq_desc + irq;
-
 	/*
 	 * Set edge/level type.
 	 */
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
index 3f9d34f..6cce58b 100644
--- a/arch/arm/plat-orion/irq.c
+++ b/arch/arm/plat-orion/irq.c
@@ -14,9 +14,10 @@
 #include <linux/io.h>
 #include <plat/irq.h>
 
-static void orion_irq_mask(u32 irq)
+static void orion_irq_mask(struct irq_desc *desc)
 {
-	void __iomem *maskaddr = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *maskaddr = get_irq_desc_chip_data(desc);
 	u32 mask;
 
 	mask = readl(maskaddr);
@@ -24,9 +25,10 @@ static void orion_irq_mask(u32 irq)
 	writel(mask, maskaddr);
 }
 
-static void orion_irq_unmask(u32 irq)
+static void orion_irq_unmask(struct irq_desc *desc)
 {
-	void __iomem *maskaddr = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *maskaddr = get_irq_desc_chip_data(desc);
 	u32 mask;
 
 	mask = readl(maskaddr);
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c
index 98548c6..00a5c10 100644
--- a/arch/arm/plat-pxa/gpio.c
+++ b/arch/arm/plat-pxa/gpio.c
@@ -155,8 +155,9 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
 	__raw_writel(gfer, c->regbase + GFER_OFFSET);
 }
 
-static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
+static int pxa_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	struct pxa_gpio_chip *c;
 	int gpio = irq_to_gpio(irq);
 	unsigned long gpdr, mask = GPIO_bit(gpio);
@@ -227,16 +228,18 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 	} while (loop);
 }
 
-static void pxa_ack_muxed_gpio(unsigned int irq)
+static void pxa_ack_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 
 	__raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
 }
 
-static void pxa_mask_muxed_gpio(unsigned int irq)
+static void pxa_mask_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 	uint32_t grer, gfer;
@@ -249,8 +252,9 @@ static void pxa_mask_muxed_gpio(unsigned int irq)
 	__raw_writel(gfer, c->regbase + GFER_OFFSET);
 }
 
-static void pxa_unmask_muxed_gpio(unsigned int irq)
+static void pxa_unmask_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 
diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h
index 44248cb..ffc6123 100644
--- a/arch/arm/plat-pxa/include/plat/gpio.h
+++ b/arch/arm/plat-pxa/include/plat/gpio.h
@@ -56,7 +56,8 @@ static inline void gpio_set_value(unsigned gpio, int value)
  */
 extern int pxa_last_gpio;
 
-typedef int (*set_wake_t)(unsigned int irq, unsigned int on);
+struct irq_desc;
+typedef int (*set_wake_t)(struct irq_desc *desc, unsigned int on);
 
 extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
 #endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 69e1be8..b2aac48 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -107,9 +107,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
 /* exported for use in arch/arm/mach-s3c2410 */
 
 #ifdef CONFIG_PM
-extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
+extern int s3c_irq_wake(struct irq_desc *desc, unsigned int state);
 #else
 #define s3c_irq_wake NULL
 #endif
 
-extern int s3c_irqext_type(unsigned int irq, unsigned int type);
+extern int s3c_irqext_type(struct irq_desc *desc, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
index ea8dea3..a8aeca9 100644
--- a/arch/arm/plat-s3c24xx/irq-pm.c
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -30,8 +30,9 @@
 unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
 unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
 
-int s3c_irq_wake(unsigned int irqno, unsigned int state)
+int s3c_irq_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irqno = desc->irq;
 	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
 
 	if (!(s3c_irqwake_intallow & irqbit))
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ad0d44e..87cc0c9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -34,30 +34,33 @@
 #include <plat/irq.h>
 
 static void
-s3c_irq_mask(unsigned int irqno)
+s3c_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= IRQ_EINT0;
+	irq -= IRQ_EINT0;
 
 	mask = __raw_readl(S3C2410_INTMSK);
-	mask |= 1UL << irqno;
+	mask |= 1UL << irq;
 	__raw_writel(mask, S3C2410_INTMSK);
 }
 
 static inline void
-s3c_irq_ack(unsigned int irqno)
+s3c_irq_ack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 
 	__raw_writel(bitval, S3C2410_SRCPND);
 	__raw_writel(bitval, S3C2410_INTPND);
 }
 
 static inline void
-s3c_irq_maskack(unsigned int irqno)
+s3c_irq_maskack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -69,17 +72,18 @@ s3c_irq_maskack(unsigned int irqno)
 
 
 static void
-s3c_irq_unmask(unsigned int irqno)
+s3c_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-		irqdbf2("s3c_irq_unmask %d\n", irqno);
+	if (irq != IRQ_TIMER4 && irq != IRQ_EINT8t23)
+		irqdbf2("s3c_irq_unmask %d\n", irq);
 
-	irqno -= IRQ_EINT0;
+	irq -= IRQ_EINT0;
 
 	mask = __raw_readl(S3C2410_INTMSK);
-	mask &= ~(1UL << irqno);
+	mask &= ~(1UL << irq);
 	__raw_writel(mask, S3C2410_INTMSK);
 }
 
@@ -100,25 +104,27 @@ struct irq_chip s3c_irq_chip = {
 };
 
 static void
-s3c_irqext_mask(unsigned int irqno)
+s3c_irqext_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= EXTINT_OFF;
+	irq -= EXTINT_OFF;
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask |= ( 1UL << irqno);
+	mask |= (1UL << irq);
 	__raw_writel(mask, S3C24XX_EINTMASK);
 }
 
 static void
-s3c_irqext_ack(unsigned int irqno)
+s3c_irqext_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long req;
 	unsigned long bit;
 	unsigned long mask;
 
-	bit = 1UL << (irqno - EXTINT_OFF);
+	bit = 1UL << (irq - EXTINT_OFF);
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
 
@@ -129,30 +135,32 @@ s3c_irqext_ack(unsigned int irqno)
 
 	/* not sure if we should be acking the parent irq... */
 
-	if (irqno <= IRQ_EINT7 ) {
+	if (irq <= IRQ_EINT7) {
 		if ((req & 0xf0) == 0)
-			s3c_irq_ack(IRQ_EINT4t7);
+			s3c_irq_ack(irq_to_desc(IRQ_EINT4t7));
 	} else {
 		if ((req >> 8) == 0)
-			s3c_irq_ack(IRQ_EINT8t23);
+			s3c_irq_ack(irq_to_desc(IRQ_EINT8t23));
 	}
 }
 
 static void
-s3c_irqext_unmask(unsigned int irqno)
+s3c_irqext_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= EXTINT_OFF;
+	irq -= EXTINT_OFF;
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask &= ~( 1UL << irqno);
+	mask &= ~(1UL << irq);
 	__raw_writel(mask, S3C24XX_EINTMASK);
 }
 
 int
-s3c_irqext_type(unsigned int irq, unsigned int type)
+s3c_irqext_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	void __iomem *extint_reg;
 	void __iomem *gpcon_reg;
 	unsigned long gpcon_offset, extint_offset;
@@ -261,21 +269,24 @@ static struct irq_chip s3c_irq_eint0t4 = {
 /* UART0 */
 
 static void
-s3c_irq_uart0_mask(unsigned int irqno)
+s3c_irq_uart0_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART0, 7);
 }
 
 static void
-s3c_irq_uart0_unmask(unsigned int irqno)
+s3c_irq_uart0_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART0);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART0);
 }
 
 static void
-s3c_irq_uart0_ack(unsigned int irqno)
+s3c_irq_uart0_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART0, 7);
 }
 
 static struct irq_chip s3c_irq_uart0 = {
@@ -288,21 +299,24 @@ static struct irq_chip s3c_irq_uart0 = {
 /* UART1 */
 
 static void
-s3c_irq_uart1_mask(unsigned int irqno)
+s3c_irq_uart1_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART1, 7 << 3);
 }
 
 static void
-s3c_irq_uart1_unmask(unsigned int irqno)
+s3c_irq_uart1_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART1);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART1);
 }
 
 static void
-s3c_irq_uart1_ack(unsigned int irqno)
+s3c_irq_uart1_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART1, 7 << 3);
 }
 
 static struct irq_chip s3c_irq_uart1 = {
@@ -315,21 +329,24 @@ static struct irq_chip s3c_irq_uart1 = {
 /* UART2 */
 
 static void
-s3c_irq_uart2_mask(unsigned int irqno)
+s3c_irq_uart2_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART2, 7 << 6);
 }
 
 static void
-s3c_irq_uart2_unmask(unsigned int irqno)
+s3c_irq_uart2_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART2);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART2);
 }
 
 static void
-s3c_irq_uart2_ack(unsigned int irqno)
+s3c_irq_uart2_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART2, 7 << 6);
 }
 
 static struct irq_chip s3c_irq_uart2 = {
@@ -342,21 +359,24 @@ static struct irq_chip s3c_irq_uart2 = {
 /* ADC and Touchscreen */
 
 static void
-s3c_irq_adc_mask(unsigned int irqno)
+s3c_irq_adc_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_ADCPARENT, 3 << 9);
 }
 
 static void
-s3c_irq_adc_unmask(unsigned int irqno)
+s3c_irq_adc_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_ADCPARENT);
 }
 
 static void
-s3c_irq_adc_ack(unsigned int irqno)
+s3c_irq_adc_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_ack(irq, INTMSK_ADCPARENT, 3 << 9);
 }
 
 static struct irq_chip s3c_irq_adc = {
diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
index 373122f..09642cb 100644
--- a/arch/arm/plat-s5pc1xx/irq-eint.c
+++ b/arch/arm/plat-s5pc1xx/irq-eint.c
@@ -67,8 +67,9 @@ static inline int s3c_eint_to_bit(unsigned int irq)
 	return bit;
 }
 
-static inline void s3c_irq_eint_mask(unsigned int irq)
+static inline void s3c_irq_eint_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 	u32 bank = s3c_get_bank(irq);
 
@@ -77,8 +78,9 @@ static inline void s3c_irq_eint_mask(unsigned int irq)
 	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
 }
 
-static void s3c_irq_eint_unmask(unsigned int irq)
+static void s3c_irq_eint_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 	u32 bank = s3c_get_bank(irq);
 
@@ -87,22 +89,24 @@ static void s3c_irq_eint_unmask(unsigned int irq)
 	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
 }
 
-static inline void s3c_irq_eint_ack(unsigned int irq)
+static inline void s3c_irq_eint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bank = s3c_get_bank(irq);
 
 	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
 }
 
-static void s3c_irq_eint_maskack(unsigned int irq)
+static void s3c_irq_eint_maskack(struct irq_desc *desc)
 {
 	/* compiler should in-line these */
-	s3c_irq_eint_mask(irq);
-	s3c_irq_eint_ack(irq);
+	s3c_irq_eint_mask(desc);
+	s3c_irq_eint_ack(desc);
 }
 
-static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+static int s3c_irq_eint_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	u32 bank = s3c_get_bank(irq);
 	int real = s3c_get_eint(irq);
 	int gpio, shift, sfn;
@@ -211,28 +215,31 @@ static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 /*
  * Handle EINT0 ... EINT15 at VIC directly
  */
-static void s3c_irq_vic_eint_mask(unsigned int irq)
+static void s3c_irq_vic_eint_mask(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
 	unsigned int real;
 
-	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_mask(desc);
 	real = s3c_get_eint(irq);
 	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
 }
 
-static void s3c_irq_vic_eint_unmask(unsigned int irq)
+static void s3c_irq_vic_eint_unmask(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
 	unsigned int real;
 
-	s3c_irq_eint_unmask(irq);
+	s3c_irq_eint_unmask(desc);
 	real = s3c_get_eint(irq);
 	writel(1 << real, base + VIC_INT_ENABLE);
 }
 
-static inline void s3c_irq_vic_eint_ack(unsigned int irq)
+static inline void s3c_irq_vic_eint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bit;
 	u32 bank = s3c_get_bank(irq);
 
@@ -240,11 +247,11 @@ static inline void s3c_irq_vic_eint_ack(unsigned int irq)
 	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
 }
 
-static void s3c_irq_vic_eint_maskack(unsigned int irq)
+static void s3c_irq_vic_eint_maskack(struct irq_desc *desc)
 {
 	/* compiler should in-line these */
-	s3c_irq_vic_eint_mask(irq);
-	s3c_irq_vic_eint_ack(irq);
+	s3c_irq_vic_eint_mask(desc);
+	s3c_irq_vic_eint_ack(desc);
 }
 
 static struct irq_chip s3c_irq_vic_eint = {
diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
index fecca7a..32f5395 100644
--- a/arch/arm/plat-s5pc1xx/irq-gpio.c
+++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
@@ -140,8 +140,9 @@ static int s5pc1xx_get_offset(unsigned int irq)
 	return irq - S3C_IRQ_GPIO(chip->base);
 }
 
-static void s5pc1xx_gpioint_ack(unsigned int irq)
+static void s5pc1xx_gpioint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, pend_offset;
 	unsigned int value;
 
@@ -154,8 +155,9 @@ static void s5pc1xx_gpioint_ack(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
 }
 
-static void s5pc1xx_gpioint_mask(unsigned int irq)
+static void s5pc1xx_gpioint_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, mask_offset;
 	unsigned int value;
 
@@ -168,8 +170,9 @@ static void s5pc1xx_gpioint_mask(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
 }
 
-static void s5pc1xx_gpioint_unmask(unsigned int irq)
+static void s5pc1xx_gpioint_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, mask_offset;
 	unsigned int value;
 
@@ -182,14 +185,15 @@ static void s5pc1xx_gpioint_unmask(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
 }
 
-static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
+static void s5pc1xx_gpioint_mask_ack(struct irq_desc *desc)
 {
-	s5pc1xx_gpioint_mask(irq);
-	s5pc1xx_gpioint_ack(irq);
+	s5pc1xx_gpioint_mask(desc);
+	s5pc1xx_gpioint_ack(desc);
 }
 
-static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
+static int s5pc1xx_gpioint_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, con_offset;
 	unsigned int value;
 
diff --git a/arch/arm/plat-stmp3xxx/irq.c b/arch/arm/plat-stmp3xxx/irq.c
index 20de4e0..eeaf936 100644
--- a/arch/arm/plat-stmp3xxx/irq.c
+++ b/arch/arm/plat-stmp3xxx/irq.c
@@ -34,7 +34,7 @@ void __init stmp3xxx_init_irq(struct irq_chip *chip)
 
 	/* Disable all interrupts initially */
 	for (i = 0; i < NR_REAL_IRQS; i++) {
-		chip->mask(i);
+		chip->mask(irq_to_desc(i));
 		set_irq_chip(i, chip);
 		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/plat-stmp3xxx/pinmux.c b/arch/arm/plat-stmp3xxx/pinmux.c
index 6d6b1a4..c0b7002 100644
--- a/arch/arm/plat-stmp3xxx/pinmux.c
+++ b/arch/arm/plat-stmp3xxx/pinmux.c
@@ -365,8 +365,9 @@ static int stmp3xxx_irq_to_gpio(int irq,
 	return -ENOENT;
 }
 
-static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
+static int stmp3xxx_set_irqtype(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 	int l, p;
@@ -398,8 +399,9 @@ static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
 	return 0;
 }
 
-static void stmp3xxx_pin_ack_irq(unsigned irq)
+static void stmp3xxx_pin_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 stat;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
@@ -409,8 +411,9 @@ static void stmp3xxx_pin_ack_irq(unsigned irq)
 	stmp3xxx_clearl(stat, pm->irqstat);
 }
 
-static void stmp3xxx_pin_mask_irq(unsigned irq)
+static void stmp3xxx_pin_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 
@@ -419,8 +422,9 @@ static void stmp3xxx_pin_mask_irq(unsigned irq)
 	stmp3xxx_clearl(1 << gpio, pm->pin2irq);
 }
 
-static void stmp3xxx_pin_unmask_irq(unsigned irq)
+static void stmp3xxx_pin_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 
@@ -533,7 +537,7 @@ int __init stmp3xxx_pinmux_init(int virtual_irq_start)
 		pm->virq = virtual_irq_start + b * 32;
 
 		for (virq = pm->virq; virq < pm->virq; virq++) {
-			gpio_irq_chip.mask(virq);
+			gpio_irq_chip.mask(irq_to_desc(virq));
 			set_irq_chip(virq, &gpio_irq_chip);
 			set_irq_handler(virq, handle_level_irq);
 			set_irq_flags(virq, IRQF_VALID);
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 310477b..da67541 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -60,35 +60,39 @@ struct eic {
 static struct eic *nmi_eic;
 static bool nmi_enabled;
 
-static void eic_ack_irq(unsigned int irq)
+static void eic_ack_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_mask_irq(unsigned int irq)
+static void eic_mask_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_mask_ack_irq(unsigned int irq)
+static void eic_mask_ack_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
 	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_unmask_irq(unsigned int irq)
+static void eic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct eic *eic = get_irq_chip_data(irq);
 	eic_writel(eic, IER, 1 << (irq - eic->first_irq));
 }
 
-static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int eic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct eic *eic = get_irq_chip_data(irq);
-	struct irq_desc *desc;
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	unsigned int i = irq - eic->first_irq;
 	u32 mode, edge, level;
 	int ret = 0;
@@ -97,8 +101,6 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
 	if (flow_type == IRQ_TYPE_NONE)
 		flow_type = IRQ_TYPE_LEVEL_LOW;
 
-	desc = &irq_desc[irq];
-
 	mode = eic_readl(eic, MODE);
 	edge = eic_readl(eic, EDGE);
 	level = eic_readl(eic, LEVEL);
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index 09a274c..7e31607 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -249,24 +249,27 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 
 /* GPIO IRQ support */
 
-static void gpio_irq_mask(unsigned irq)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned		gpio = irq_to_gpio(irq);
 	struct pio_device	*pio = &pio_dev[gpio >> 5];
 
 	pio_writel(pio, IDR, 1 << (gpio & 0x1f));
 }
 
-static void gpio_irq_unmask(unsigned irq)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned		gpio = irq_to_gpio(irq);
 	struct pio_device	*pio = &pio_dev[gpio >> 5];
 
 	pio_writel(pio, IER, 1 << (gpio & 0x1f));
 }
 
-static int gpio_irq_type(unsigned irq, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE)
 		return -EINVAL;
 
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h
index e6485c3..912d974 100644
--- a/arch/blackfin/include/asm/bfin-global.h
+++ b/arch/blackfin/include/asm/bfin-global.h
@@ -51,7 +51,7 @@ extern void program_IAR(void);
 extern asmlinkage void lower_to_irq14(void);
 extern asmlinkage void bfin_return_from_exception(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
+extern int bfin_internal_set_wake(struct irq_desc *desc, unsigned int state);
 
 extern void *l1_data_A_sram_alloc(size_t);
 extern void *l1_data_B_sram_alloc(size_t);
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index d3b4044..4009554 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -115,9 +115,9 @@ void __ipipe_enable_irqdesc(struct ipipe_domain *ipd,
 void __ipipe_disable_irqdesc(struct ipipe_domain *ipd,
 			     unsigned irq);
 
-#define __ipipe_enable_irq(irq)		(irq_desc[irq].chip->unmask(irq))
+#define __ipipe_enable_irq(irq)		(irq_desc[irq].chip->unmask(irq_to_desc(irq)))
 
-#define __ipipe_disable_irq(irq)	(irq_desc[irq].chip->mask(irq))
+#define __ipipe_disable_irq(irq)	(irq_desc[irq].chip->mask(irq_to_desc(irq)))
 
 static inline int __ipipe_check_tickdev(const char *devname)
 {
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 7ad8878..9de18e4 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -121,20 +121,22 @@ static void __init search_IAR(void)
  * This is for core internal IRQs
  */
 
-static void bfin_ack_noop(unsigned int irq)
+static void bfin_ack_noop(struct irq_desc *desc)
 {
 	/* Dummy function.  */
 }
 
-static void bfin_core_mask_irq(unsigned int irq)
+static void bfin_core_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bfin_irq_flags &= ~(1 << irq);
 	if (!irqs_disabled_hw())
 		local_irq_enable_hw();
 }
 
-static void bfin_core_unmask_irq(unsigned int irq)
+static void bfin_core_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bfin_irq_flags |= 1 << irq;
 	/*
 	 * If interrupts are enabled, IMASK must contain the same value
@@ -150,8 +152,9 @@ static void bfin_core_unmask_irq(unsigned int irq)
 	return;
 }
 
-static void bfin_internal_mask_irq(unsigned int irq)
+static void bfin_internal_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 #ifdef CONFIG_BF53x
@@ -174,12 +177,13 @@ static void bfin_internal_mask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void bfin_internal_unmask_irq_affinity(unsigned int irq,
+static void bfin_internal_unmask_irq_affinity(struct irq_desc *desc,
 		const struct cpumask *affinity)
 #else
-static void bfin_internal_unmask_irq(unsigned int irq)
+static void bfin_internal_unmask_irq(struct irq_desc *desc)
 #endif
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 #ifdef CONFIG_BF53x
@@ -208,24 +212,24 @@ static void bfin_internal_unmask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void bfin_internal_unmask_irq(unsigned int irq)
+static void bfin_internal_unmask_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	bfin_internal_unmask_irq_affinity(irq, desc->affinity);
+	bfin_internal_unmask_irq_affinity(desc, desc->affinity);
 }
 
-static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bfin_internal_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	bfin_internal_mask_irq(irq);
-	bfin_internal_unmask_irq_affinity(irq, mask);
+	bfin_internal_mask_irq(desc);
+	bfin_internal_unmask_irq_affinity(desc, mask);
 
 	return 0;
 }
 #endif
 
 #ifdef CONFIG_PM
-int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+int bfin_internal_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	u32 bank, bit, wakeup = 0;
 	unsigned long flags;
 	bank = SIC_SYSIRQ(irq) / 32;
@@ -317,16 +321,18 @@ static void bfin_handle_irq(unsigned irq)
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
 static int error_int_mask;
 
-static void bfin_generic_error_mask_irq(unsigned int irq)
+static void bfin_generic_error_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
 	if (!error_int_mask)
-		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
+		bfin_internal_mask_irq(irq_to_desc(IRQ_GENERIC_ERROR));
 }
 
-static void bfin_generic_error_unmask_irq(unsigned int irq)
+static void bfin_generic_error_unmask_irq(struct irq_desc *desc)
 {
-	bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
+	unsigned int irq = desc->irq;
+	bfin_internal_unmask_irq(irq_to_desc(IRQ_GENERIC_ERROR));
 	error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
 }
 
@@ -548,17 +554,18 @@ extern void bfin_gpio_irq_prepare(unsigned gpio);
 
 #if !defined(CONFIG_BF54x)
 
-static void bfin_gpio_ack_irq(unsigned int irq)
+static void bfin_gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* AFAIK ack_irq in case mask_ack is provided
 	 * get's only called for edge sense irqs
 	 */
 	set_gpio_data(irq_to_gpio(irq), 0);
 }
 
-static void bfin_gpio_mask_ack_irq(unsigned int irq)
+static void bfin_gpio_mask_ack_irq(stuct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	if (desc->handle_irq == handle_edge_irq)
@@ -567,30 +574,34 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
 	set_gpio_maska(gpionr, 0);
 }
 
-static void bfin_gpio_mask_irq(unsigned int irq)
+static void bfin_gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_gpio_maska(irq_to_gpio(irq), 0);
 }
 
-static void bfin_gpio_unmask_irq(unsigned int irq)
+static void bfin_gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_gpio_maska(irq_to_gpio(irq), 1);
 }
 
-static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+static unsigned int bfin_gpio_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	if (__test_and_set_bit(gpionr, gpio_enabled))
 		bfin_gpio_irq_prepare(gpionr);
 
-	bfin_gpio_unmask_irq(irq);
+	bfin_gpio_unmask_irq(desc);
 
 	return 0;
 }
 
-static void bfin_gpio_irq_shutdown(unsigned int irq)
+static void bfin_gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	bfin_gpio_mask_irq(irq);
@@ -598,8 +609,9 @@ static void bfin_gpio_irq_shutdown(unsigned int irq)
 	bfin_gpio_irq_free(gpionr);
 }
 
-static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+static int bfin_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int ret;
 	char buf[16];
 	u32 gpionr = irq_to_gpio(irq);
@@ -660,8 +672,9 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
 }
 
 #ifdef CONFIG_PM
-int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+int bfin_gpio_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	unsigned gpio = irq_to_gpio(irq);
 
 	if (state)
@@ -821,9 +834,9 @@ void init_pint_lut(void)
 	}
 }
 
-static void bfin_gpio_ack_irq(unsigned int irq)
+static void bfin_gpio_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -838,9 +851,9 @@ static void bfin_gpio_ack_irq(unsigned int irq)
 
 }
 
-static void bfin_gpio_mask_ack_irq(unsigned int irq)
+static void bfin_gpio_mask_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -856,15 +869,17 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
 	pint[bank]->mask_clear = pintbit;
 }
 
-static void bfin_gpio_mask_irq(unsigned int irq)
+static void bfin_gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 
 	pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
 }
 
-static void bfin_gpio_unmask_irq(unsigned int irq)
+static void bfin_gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -873,8 +888,9 @@ static void bfin_gpio_unmask_irq(unsigned int irq)
 	pint[bank]->mask_set = pintbit;
 }
 
-static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+static unsigned int bfin_gpio_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 
@@ -888,22 +904,24 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
 	if (__test_and_set_bit(gpionr, gpio_enabled))
 		bfin_gpio_irq_prepare(gpionr);
 
-	bfin_gpio_unmask_irq(irq);
+	bfin_gpio_unmask_irq(desc);
 
 	return 0;
 }
 
-static void bfin_gpio_irq_shutdown(unsigned int irq)
+static void bfin_gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
-	bfin_gpio_mask_irq(irq);
+	bfin_gpio_mask_irq(desc);
 	__clear_bit(gpionr, gpio_enabled);
 	bfin_gpio_irq_free(gpionr);
 }
 
-static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+static int bfin_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int ret;
 	char buf[16];
 	u32 gpionr = irq_to_gpio(irq);
@@ -965,8 +983,9 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
 u32 pint_saved_masks[NR_PINT_SYS_IRQS];
 u32 pint_wakeup_masks[NR_PINT_SYS_IRQS];
 
-int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+int bfin_gpio_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 bank = PINT_2_BANK(pint_val);
@@ -989,7 +1008,7 @@ int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
 		return -EINVAL;
 	}
 
-	bfin_internal_set_wake(pint_irq, state);
+	bfin_internal_set_wake(irq_to_desc(pint_irq), state);
 
 	if (state)
 		pint_wakeup_masks[bank] |= pintbit;
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 1a61efc..46a746e 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -104,31 +104,33 @@ static void (*interrupt[NR_IRQS])(void) = {
 	IRQ31_interrupt
 };
 
-static void enable_crisv10_irq(unsigned int irq);
+static void enable_crisv10_irq(struct irq_desc *desc);
 
-static unsigned int startup_crisv10_irq(unsigned int irq)
+static unsigned int startup_crisv10_irq(struct irq_desc *desc)
 {
-	enable_crisv10_irq(irq);
+	enable_crisv10_irq(desc);
 	return 0;
 }
 
 #define shutdown_crisv10_irq	disable_crisv10_irq
 
-static void enable_crisv10_irq(unsigned int irq)
+static void enable_crisv10_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unmask_irq(irq);
 }
 
-static void disable_crisv10_irq(unsigned int irq)
+static void disable_crisv10_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	mask_irq(irq);
 }
 
-static void ack_crisv10_irq(unsigned int irq)
+static void ack_crisv10_irq(struct irq_desc *desc)
 {
 }
 
-static void end_crisv10_irq(unsigned int irq)
+static void end_crisv10_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 4dd9ada..cc0bf81 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -36,8 +36,9 @@
 /*
  * on-motherboard FPGA PIC operations
  */
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -45,13 +46,15 @@ static void frv_fpga_mask(unsigned int irq)
 	__set_IMR(imr);
 }
 
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -60,8 +63,9 @@ static void frv_fpga_mask_ack(unsigned int irq)
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr &= ~(1 << (irq - IRQ_BASE_FPGA));
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index e452090..db30494 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -35,21 +35,24 @@
 /*
  * off-CPU FPGA PIC operations
  */
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
 	__set_IMR(imr);
 }
 
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -58,8 +61,9 @@ static void frv_fpga_mask_ack(unsigned int irq)
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr &= ~(1 << (irq - IRQ_BASE_FPGA));
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index ba55ecd..85c4a08 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -45,8 +45,9 @@
  * daughter board PIC operations
  * - there is no way to ACK interrupts in the MB93493 chip
  */
-static void frv_mb93493_mask(unsigned int irq)
+static void frv_mb93493_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint32_t iqsr;
 	volatile void *piqsr;
 
@@ -60,12 +61,13 @@ static void frv_mb93493_mask(unsigned int irq)
 	writel(iqsr, piqsr);
 }
 
-static void frv_mb93493_ack(unsigned int irq)
+static void frv_mb93493_ack(struct irq_desc *desc)
 {
 }
 
-static void frv_mb93493_unmask(unsigned int irq)
+static void frv_mb93493_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint32_t iqsr;
 	volatile void *piqsr;
 
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 62d1aba..72c9a73 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -96,32 +96,37 @@ int show_interrupts(struct seq_file *p, void *v)
 /*
  * on-CPU PIC operations
  */
-static void frv_cpupic_ack(unsigned int irqlevel)
+static void frv_cpupic_ack(struct irq_desc *desc)
 {
-	__clr_RC(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_RC(irq);
 	__clr_IRL();
 }
 
-static void frv_cpupic_mask(unsigned int irqlevel)
+static void frv_cpupic_mask(struct irq_desc *desc)
 {
-	__set_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__set_MASK(irq);
 }
 
-static void frv_cpupic_mask_ack(unsigned int irqlevel)
+static void frv_cpupic_mask_ack(struct irq_desc *desc)
 {
-	__set_MASK(irqlevel);
-	__clr_RC(irqlevel);
+	unsigned int irq = desc->irq;
+	__set_MASK(irq);
+	__clr_RC(irq);
 	__clr_IRL();
 }
 
-static void frv_cpupic_unmask(unsigned int irqlevel)
+static void frv_cpupic_unmask(struct irq_desc *desc)
 {
-	__clr_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_MASK(irq);
 }
 
-static void frv_cpupic_end(unsigned int irqlevel)
+static void frv_cpupic_end(struct irq_desc *desc)
 {
-	__clr_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_MASK(irq);
 }
 
 static struct irq_chip frv_cpu_pic = {
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index c25dc2c..4132b2f 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -38,32 +38,36 @@ static inline int is_ext_irq(unsigned int irq)
 	return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS));
 }
 
-static void h8300_enable_irq(unsigned int irq)
+static void h8300_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		IER_REGS |= 1 << (irq - EXT_IRQ0);
 }
 
-static void h8300_disable_irq(unsigned int irq)
+static void h8300_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		IER_REGS &= ~(1 << (irq - EXT_IRQ0));
 }
 
-static void h8300_end_irq(unsigned int irq)
+static void h8300_end_irq(struct irq_desc *desc)
 {
 }
 
-static unsigned int h8300_startup_irq(unsigned int irq)
+static unsigned int h8300_startup_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		return h8300_enable_irq_pin(irq);
 	else
 		return 0;
 }
 
-static void h8300_shutdown_irq(unsigned int irq)
+static void h8300_shutdown_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		h8300_disable_irq_pin(irq);
 }
diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c
index 922fdfd..d4eaf98 100644
--- a/arch/m32r/platforms/m32104ut/setup.c
+++ b/arch/m32r/platforms/m32104ut/setup.c
@@ -21,8 +21,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_m32104ut_irq(unsigned int irq)
+static void disable_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -30,8 +31,9 @@ static void disable_m32104ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_m32104ut_irq(unsigned int irq)
+static void enable_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -39,24 +41,25 @@ static void enable_m32104ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_m32104ut(unsigned int irq)
+static void mask_and_ack_m32104ut(struct irq_desc *desc)
 {
-	disable_m32104ut_irq(irq);
+	disable_m32104ut_irq(desc);
 }
 
 static void end_m32104ut_irq(unsigned int irq)
 {
-	enable_m32104ut_irq(irq);
+	enable_m32104ut_irq(desc);
 }
 
-static unsigned int startup_m32104ut_irq(unsigned int irq)
+static unsigned int startup_m32104ut_irq(struct irq_desc *desc)
 {
-	enable_m32104ut_irq(irq);
+	enable_m32104ut_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32104ut_irq(unsigned int irq)
+static void shutdown_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/m32700ut/setup.c b/arch/m32r/platforms/m32700ut/setup.c
index 9c1bc74..30dc152 100644
--- a/arch/m32r/platforms/m32700ut/setup.c
+++ b/arch/m32r/platforms/m32700ut/setup.c
@@ -27,8 +27,9 @@
 
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
-static void disable_m32700ut_irq(unsigned int irq)
+static void disable_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -36,8 +37,9 @@ static void disable_m32700ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_m32700ut_irq(unsigned int irq)
+static void enable_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -45,24 +47,25 @@ static void enable_m32700ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_m32700ut(unsigned int irq)
+static void mask_and_ack_m32700ut(struct irq_desc *desc)
 {
-	disable_m32700ut_irq(irq);
+	disable_m32700ut_irq(desc);
 }
 
-static void end_m32700ut_irq(unsigned int irq)
+static void end_m32700ut_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_irq(irq);
+	enable_m32700ut_irq(desc);
 }
 
-static unsigned int startup_m32700ut_irq(unsigned int irq)
+static unsigned int startup_m32700ut_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_irq(irq);
+	enable_m32700ut_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_irq(unsigned int irq)
+static void shutdown_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -93,8 +96,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[M32700UT_NUM_PLD_IRQ];
 
-static void disable_m32700ut_pld_irq(unsigned int irq)
+static void disable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -105,8 +109,9 @@ static void disable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_pld_irq(unsigned int irq)
+static void enable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -117,26 +122,27 @@ static void enable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_pld(unsigned int irq)
+static void mask_and_ack_m32700ut_pld(struct irq_desc *desc)
 {
-	disable_m32700ut_pld_irq(irq);
+	disable_m32700ut_pld_irq(desc);
 //	mask_and_ack_m32700ut(M32R_IRQ_INT1);
 }
 
-static void end_m32700ut_pld_irq(unsigned int irq)
+static void end_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT1);
+	enable_m32700ut_pld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
-static unsigned int startup_m32700ut_pld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
+	enable_m32700ut_pld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_pld_irq(unsigned int irq)
+static void shutdown_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -166,8 +172,9 @@ static struct irq_chip m32700ut_pld_irq_type =
 
 static pld_icu_data_t lanpld_icu_data[M32700UT_NUM_LAN_PLD_IRQ];
 
-static void disable_m32700ut_lanpld_irq(unsigned int irq)
+static void disable_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -177,8 +184,9 @@ static void disable_m32700ut_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_lanpld_irq(unsigned int irq)
+static void enable_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -188,29 +196,30 @@ static void enable_m32700ut_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_lanpld(unsigned int irq)
+static void mask_and_ack_m32700ut_lanpld(struct irq_desc *desc)
 {
-	disable_m32700ut_lanpld_irq(irq);
+	disable_m32700ut_lanpld_irq(desc);
 }
 
-static void end_m32700ut_lanpld_irq(unsigned int irq)
+static void end_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lanpld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT0);
+	enable_m32700ut_lanpld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT0));
 }
 
-static unsigned int startup_m32700ut_lanpld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lanpld_irq(irq);
+	enable_m32700ut_lanpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_lanpld_irq(unsigned int irq)
+static void shutdown_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
-	pldirq = irq2lanpldirq(irq);
+	pldirq = irq2lanpldirq(desc);
 	port = lanpldirq2port(pldirq);
 	outw(PLD_ICUCR_ILEVEL7, port);
 }
@@ -235,8 +244,9 @@ static struct irq_chip m32700ut_lanpld_irq_type =
 
 static pld_icu_data_t lcdpld_icu_data[M32700UT_NUM_LCD_PLD_IRQ];
 
-static void disable_m32700ut_lcdpld_irq(unsigned int irq)
+static void disable_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -246,8 +256,9 @@ static void disable_m32700ut_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_lcdpld_irq(unsigned int irq)
+static void enable_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -257,25 +268,26 @@ static void enable_m32700ut_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_lcdpld(unsigned int irq)
+static void mask_and_ack_m32700ut_lcdpld(struct irq_desc *desc)
 {
-	disable_m32700ut_lcdpld_irq(irq);
+	disable_m32700ut_lcdpld_irq(desc);
 }
 
-static void end_m32700ut_lcdpld_irq(unsigned int irq)
+static void end_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lcdpld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT2);
+	enable_m32700ut_lcdpld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT2));
 }
 
-static unsigned int startup_m32700ut_lcdpld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lcdpld_irq(irq);
+	enable_m32700ut_lcdpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_lcdpld_irq(unsigned int irq)
+static void shutdown_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c
index fb4b177..5b29971 100644
--- a/arch/m32r/platforms/mappi/setup.c
+++ b/arch/m32r/platforms/mappi/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi_irq(unsigned int irq)
+static void disable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -29,8 +30,9 @@ static void disable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi_irq(unsigned int irq)
+static void enable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -38,25 +40,26 @@ static void enable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_mappi_irq(irq);
+	disable_mappi_irq(desc);
 }
 
-static void end_mappi_irq(unsigned int irq)
+static void end_mappi_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_mappi_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_mappi_irq(desc);
 }
 
-static unsigned int startup_mappi_irq(unsigned int irq)
+static unsigned int startup_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi_irq(unsigned int irq)
+static void shutdown_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c
index 6a65eda..e364894 100644
--- a/arch/m32r/platforms/mappi2/setup.c
+++ b/arch/m32r/platforms/mappi2/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi2_irq(unsigned int irq)
+static void disable_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -33,8 +34,9 @@ static void disable_mappi2_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi2_irq(unsigned int irq)
+static void enable_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -46,24 +48,25 @@ static void enable_mappi2_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi2(unsigned int irq)
+static void mask_and_ack_mappi2(struct irq_desc *desc)
 {
-	disable_mappi2_irq(irq);
+	disable_mappi2_irq(desc);
 }
 
-static void end_mappi2_irq(unsigned int irq)
+static void end_mappi2_irq(struct irq_desc *desc)
 {
-	enable_mappi2_irq(irq);
+	enable_mappi2_irq(desc);
 }
 
-static unsigned int startup_mappi2_irq(unsigned int irq)
+static unsigned int startup_mappi2_irq(struct irq_desc *desc)
 {
-	enable_mappi2_irq(irq);
+	enable_mappi2_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi2_irq(unsigned int irq)
+static void shutdown_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c
index 9c337ae..5152adf 100644
--- a/arch/m32r/platforms/mappi3/setup.c
+++ b/arch/m32r/platforms/mappi3/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi3_irq(unsigned int irq)
+static void disable_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -33,8 +34,9 @@ static void disable_mappi3_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi3_irq(unsigned int irq)
+static void enable_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -46,24 +48,25 @@ static void enable_mappi3_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi3(unsigned int irq)
+static void mask_and_ack_mappi3(struct irq_desc *desc)
 {
-	disable_mappi3_irq(irq);
+	disable_mappi3_irq(desc);
 }
 
-static void end_mappi3_irq(unsigned int irq)
+static void end_mappi3_irq(struct irq_desc *desc)
 {
-	enable_mappi3_irq(irq);
+	enable_mappi3_irq(desc);
 }
 
-static unsigned int startup_mappi3_irq(unsigned int irq)
+static unsigned int startup_mappi3_irq(struct irq_desc *desc)
 {
-	enable_mappi3_irq(irq);
+	enable_mappi3_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi3_irq(unsigned int irq)
+static void shutdown_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c
index ed86574..396beba 100644
--- a/arch/m32r/platforms/oaks32r/setup.c
+++ b/arch/m32r/platforms/oaks32r/setup.c
@@ -19,8 +19,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_oaks32r_irq(unsigned int irq)
+static void disable_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -28,8 +29,9 @@ static void disable_oaks32r_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_oaks32r_irq(unsigned int irq)
+static void enable_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,24 +39,25 @@ static void enable_oaks32r_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_oaks32r_irq(irq);
+	disable_oaks32r_irq(desc);
 }
 
-static void end_oaks32r_irq(unsigned int irq)
+static void end_oaks32r_irq(struct irq_desc *desc)
 {
-	enable_oaks32r_irq(irq);
+	enable_oaks32r_irq(desc);
 }
 
-static unsigned int startup_oaks32r_irq(unsigned int irq)
+static unsigned int startup_oaks32r_irq(struct irq_desc *desc)
 {
-	enable_oaks32r_irq(irq);
+	enable_oaks32r_irq(desc);
 	return (0);
 }
 
-static void shutdown_oaks32r_irq(unsigned int irq)
+static void shutdown_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/opsput/setup.c b/arch/m32r/platforms/opsput/setup.c
index 80d6806..1c9553b 100644
--- a/arch/m32r/platforms/opsput/setup.c
+++ b/arch/m32r/platforms/opsput/setup.c
@@ -28,8 +28,9 @@
 
 icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
 
-static void disable_opsput_irq(unsigned int irq)
+static void disable_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,8 +38,9 @@ static void disable_opsput_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_opsput_irq(unsigned int irq)
+static void enable_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -46,24 +48,25 @@ static void enable_opsput_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_opsput(unsigned int irq)
+static void mask_and_ack_opsput(struct irq_desc *desc)
 {
-	disable_opsput_irq(irq);
+	disable_opsput_irq(desc);
 }
 
-static void end_opsput_irq(unsigned int irq)
+static void end_opsput_irq(struct irq_desc *desc)
 {
-	enable_opsput_irq(irq);
+	enable_opsput_irq(desc);
 }
 
-static unsigned int startup_opsput_irq(unsigned int irq)
+static unsigned int startup_opsput_irq(struct irq_desc *desc)
 {
-	enable_opsput_irq(irq);
+	enable_opsput_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_irq(unsigned int irq)
+static void shutdown_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -94,8 +97,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[OPSPUT_NUM_PLD_IRQ];
 
-static void disable_opsput_pld_irq(unsigned int irq)
+static void disable_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -106,8 +110,9 @@ static void disable_opsput_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_pld_irq(unsigned int irq)
+static void enable_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -118,26 +123,27 @@ static void enable_opsput_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_pld(unsigned int irq)
+static void mask_and_ack_opsput_pld(struct irq_desc *desc)
 {
-	disable_opsput_pld_irq(irq);
+	disable_opsput_pld_irq(desc);
 //	mask_and_ack_opsput(M32R_IRQ_INT1);
 }
 
-static void end_opsput_pld_irq(unsigned int irq)
+static void end_opsput_pld_irq(struct irq_desc *desc)
 {
-	enable_opsput_pld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT1);
+	enable_opsput_pld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
-static unsigned int startup_opsput_pld_irq(unsigned int irq)
+static unsigned int startup_opsput_pld_irq(struct irq_desc *desc)
 {
-	enable_opsput_pld_irq(irq);
+	enable_opsput_pld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_pld_irq(unsigned int irq)
+static void shutdown_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -167,8 +173,9 @@ static struct irq_chip opsput_pld_irq_type =
 
 static pld_icu_data_t lanpld_icu_data[OPSPUT_NUM_LAN_PLD_IRQ];
 
-static void disable_opsput_lanpld_irq(unsigned int irq)
+static void disable_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -178,8 +185,9 @@ static void disable_opsput_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_lanpld_irq(unsigned int irq)
+static void enable_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -189,25 +197,26 @@ static void enable_opsput_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_lanpld(unsigned int irq)
+static void mask_and_ack_opsput_lanpld(struct irq_desc *desc)
 {
-	disable_opsput_lanpld_irq(irq);
+	disable_opsput_lanpld_irq(desc);
 }
 
-static void end_opsput_lanpld_irq(unsigned int irq)
+static void end_opsput_lanpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lanpld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT0);
+	enable_opsput_lanpld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT0));
 }
 
-static unsigned int startup_opsput_lanpld_irq(unsigned int irq)
+static unsigned int startup_opsput_lanpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lanpld_irq(irq);
+	enable_opsput_lanpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_lanpld_irq(unsigned int irq)
+static void shutdown_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -236,8 +245,9 @@ static struct irq_chip opsput_lanpld_irq_type =
 
 static pld_icu_data_t lcdpld_icu_data[OPSPUT_NUM_LCD_PLD_IRQ];
 
-static void disable_opsput_lcdpld_irq(unsigned int irq)
+static void disable_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -247,8 +257,9 @@ static void disable_opsput_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_lcdpld_irq(unsigned int irq)
+static void enable_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -258,25 +269,26 @@ static void enable_opsput_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_lcdpld(unsigned int irq)
+static void mask_and_ack_opsput_lcdpld(struct irq_desc *desc)
 {
-	disable_opsput_lcdpld_irq(irq);
+	disable_opsput_lcdpld_irq(desc);
 }
 
-static void end_opsput_lcdpld_irq(unsigned int irq)
+static void end_opsput_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lcdpld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT2);
+	enable_opsput_lcdpld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT2));
 }
 
-static unsigned int startup_opsput_lcdpld_irq(unsigned int irq)
+static unsigned int startup_opsput_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lcdpld_irq(irq);
+	enable_opsput_lcdpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_lcdpld_irq(unsigned int irq)
+static void shutdown_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -305,7 +317,7 @@ void __init init_IRQ(void)
 	irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0;
 	irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1;	/* disable nested irq */
 	lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* "H" edge sense */
-	disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN);
+	disable_opsput_lanpld_irq(irq_to_desc(OPSPUT_LAN_IRQ_LAN));
 #endif  /* CONFIG_SMC91X */
 
 	/* MFT2 : system timer */
@@ -314,7 +326,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_MFT2].action = 0;
 	irq_desc[M32R_IRQ_MFT2].depth = 1;
 	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
-	disable_opsput_irq(M32R_IRQ_MFT2);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_MFT2));
 
 	/* SIO0 : receive */
 	irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
@@ -322,7 +334,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO0_R].action = 0;
 	irq_desc[M32R_IRQ_SIO0_R].depth = 1;
 	icu_data[M32R_IRQ_SIO0_R].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO0_R);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO0_R));
 
 	/* SIO0 : send */
 	irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
@@ -330,7 +342,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO0_S].action = 0;
 	irq_desc[M32R_IRQ_SIO0_S].depth = 1;
 	icu_data[M32R_IRQ_SIO0_S].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO0_S);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO0_S));
 
 	/* SIO1 : receive */
 	irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED;
@@ -338,7 +350,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO1_R].action = 0;
 	irq_desc[M32R_IRQ_SIO1_R].depth = 1;
 	icu_data[M32R_IRQ_SIO1_R].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO1_R);
+	disable_opsput_irq(irq_desc(M32R_IRQ_SIO1_R));
 
 	/* SIO1 : send */
 	irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED;
@@ -346,7 +358,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO1_S].action = 0;
 	irq_desc[M32R_IRQ_SIO1_S].depth = 1;
 	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO1_S);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO1_S));
 
 	/* DMA1 : */
 	irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED;
@@ -354,7 +366,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_DMA1].action = 0;
 	irq_desc[M32R_IRQ_DMA1].depth = 1;
 	icu_data[M32R_IRQ_DMA1].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_DMA1);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_DMA1));
 
 #ifdef CONFIG_SERIAL_M32R_PLDSIO
 	/* INT#1: SIO0 Receive on PLD */
@@ -363,7 +375,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_SIO0_RCV].action = 0;
 	irq_desc[PLD_IRQ_SIO0_RCV].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
-	disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_SIO0_RCV));
 
 	/* INT#1: SIO0 Send on PLD */
 	irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED;
@@ -371,7 +383,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_SIO0_SND].action = 0;
 	irq_desc[PLD_IRQ_SIO0_SND].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
-	disable_opsput_pld_irq(PLD_IRQ_SIO0_SND);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_SIO0_SND));
 #endif  /* CONFIG_SERIAL_M32R_PLDSIO */
 
 	/* INT#1: CFC IREQ on PLD */
@@ -380,7 +392,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFIREQ].action = 0;
 	irq_desc[PLD_IRQ_CFIREQ].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* 'L' level sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFIREQ);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFIREQ));
 
 	/* INT#1: CFC Insert on PLD */
 	irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
@@ -388,7 +400,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
 	irq_desc[PLD_IRQ_CFC_INSERT].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00;	/* 'L' edge sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFC_INSERT));
 
 	/* INT#1: CFC Eject on PLD */
 	irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
@@ -396,21 +408,21 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
 	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* 'H' edge sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFC_EJECT));
 
 	/*
 	 * INT0# is used for LAN, DIO
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
-	enable_opsput_irq(M32R_IRQ_INT0);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT0));
 
 	/*
 	 * INT1# is used for UART, MMC, CF Controller in FPGA.
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
-	enable_opsput_irq(M32R_IRQ_INT1);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT1));
 
 #if defined(CONFIG_USB)
 	outw(USBCR_OTGS, USBCR); 	/* USBCR: non-OTG */
@@ -420,14 +432,14 @@ void __init init_IRQ(void)
     irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0;
     irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1;
     lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* "L" level sense */
-    disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1);
+    disable_opsput_lcdpld_irq(irq_to_desc(OPSPUT_LCD_IRQ_USB_INT1));
 #endif
 	/*
 	 * INT2# is used for BAT, USB, AUDIO
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
-	enable_opsput_irq(M32R_IRQ_INT2);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT2));
 
 #if defined(CONFIG_VIDEO_M32R_AR)
 	/*
@@ -438,7 +450,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_INT3].action = 0;
 	irq_desc[M32R_IRQ_INT3].depth = 1;
 	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
-	disable_opsput_irq(M32R_IRQ_INT3);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_INT3));
 #endif /* CONFIG_VIDEO_M32R_AR */
 }
 
diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c
index 7573026..fca1e00 100644
--- a/arch/m32r/platforms/usrv/setup.c
+++ b/arch/m32r/platforms/usrv/setup.c
@@ -19,8 +19,9 @@
 
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
-static void disable_mappi_irq(unsigned int irq)
+static void disable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -28,8 +29,9 @@ static void disable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi_irq(unsigned int irq)
+static void enable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,24 +39,25 @@ static void enable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_mappi_irq(irq);
+	disable_mappi_irq(desc);
 }
 
-static void end_mappi_irq(unsigned int irq)
+static void end_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 }
 
-static unsigned int startup_mappi_irq(unsigned int irq)
+static unsigned int startup_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 	return 0;
 }
 
-static void shutdown_mappi_irq(unsigned int irq)
+static void shutdown_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -85,8 +88,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[M32700UT_NUM_PLD_IRQ];
 
-static void disable_m32700ut_pld_irq(unsigned int irq)
+static void disable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -96,8 +100,9 @@ static void disable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_pld_irq(unsigned int irq)
+static void enable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -107,25 +112,26 @@ static void enable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_pld(unsigned int irq)
+static void mask_and_ack_m32700ut_pld(struct irq_desc *desc)
 {
-	disable_m32700ut_pld_irq(irq);
+	disable_m32700ut_pld_irq(desc);
 }
 
-static void end_m32700ut_pld_irq(unsigned int irq)
+static void end_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
-	end_mappi_irq(M32R_IRQ_INT1);
+	enable_m32700ut_pld_irq(desc);
+	end_mappi_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
 static unsigned int startup_m32700ut_pld_irq(unsigned int irq)
 {
-	enable_m32700ut_pld_irq(irq);
+	enable_m32700ut_pld_irq(desc);
 	return 0;
 }
 
-static void shutdown_m32700ut_pld_irq(unsigned int irq)
+static void shutdown_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c
index d09d9da..f23483f 100644
--- a/arch/m68knommu/platform/5249/intc2.c
+++ b/arch/m68knommu/platform/5249/intc2.c
@@ -17,24 +17,27 @@
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 
-static void intc2_irq_gpio_mask(unsigned int irq)
+static void intc2_irq_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 imr;
 	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 	imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0));
 	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 }
 
-static void intc2_irq_gpio_unmask(unsigned int irq)
+static void intc2_irq_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 imr;
 	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 	imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0));
 	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 }
 
-static void intc2_irq_gpio_ack(unsigned int irq)
+static void intc2_irq_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
 }
 
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
index 7081e0a..0bfea67 100644
--- a/arch/m68knommu/platform/5272/intc.c
+++ b/arch/m68knommu/platform/5272/intc.c
@@ -68,8 +68,9 @@ static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
 	/*MCF_IRQ_SWTO*/	{ .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
 };
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		u32 v;
 		irq -= MCFINT_VECBASE;
@@ -78,8 +79,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		u32 v;
 		irq -= MCFINT_VECBASE;
@@ -88,8 +90,9 @@ static void intc_irq_unmask(unsigned int irq)
 	}
 }
 
-static void intc_irq_ack(unsigned int irq)
+static void intc_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Only external interrupts are acked */
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		irq -= MCFINT_VECBASE;
@@ -101,7 +104,7 @@ static void intc_irq_ack(unsigned int irq)
 	}
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
 	/* We can set the edge type here for external interrupts */
 	return 0;
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index b91ee85..80421cc 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -135,13 +135,15 @@ void process_int(int vec, struct pt_regs *fp)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IMR &= ~(1<<irq);
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IMR |= (1<<irq);
 }
 
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index 1143f77..e99877b 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -37,18 +37,21 @@ extern void *_ramvec[];
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cimr |= (1 << irq);
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cimr &= ~(1 << irq);
 }
 
-static void intc_irq_ack(unsigned int irq)
+static void intc_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cisr = (1 << irq);
 }
 
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
index 5598c8b..598905c 100644
--- a/arch/m68knommu/platform/coldfire/intc-2.c
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -25,8 +25,9 @@
  */
 static u8 intc_intpri = 0x36;
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
 		unsigned long imraddr;
 		u32 val, imrbit;
@@ -42,8 +43,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
 		unsigned long intaddr, imraddr, icraddr;
 		u32 val, imrbit;
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
index 1b01e79..f52e94a 100644
--- a/arch/m68knommu/platform/coldfire/intc-simr.c
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -18,8 +18,9 @@
 #include <asm/mcfsim.h>
 #include <asm/traps.h>
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
@@ -28,8 +29,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
@@ -38,8 +40,9 @@ static void intc_irq_unmask(unsigned int irq)
 	}
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index a4560c8..04bf7d5 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -111,19 +111,21 @@ void mcf_autovector(int irq)
 #endif
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (mcf_irq2imr[irq])
 		mcf_setimr(mcf_irq2imr[irq]);
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (mcf_irq2imr[irq])
 		mcf_clrimr(mcf_irq2imr[irq]);
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
 	return 0;
 }
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1..009d2f6 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -40,8 +40,9 @@ unsigned int nr_irq;
 #define MER_ME (1<<0)
 #define MER_HIE (1<<1)
 
-static void intc_enable_or_unmask(unsigned int irq)
+static void intc_enable_or_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("enable_or_unmask: %d\n", irq);
 	out_be32(INTC_BASE + SIE, mask);
@@ -54,28 +55,32 @@ static void intc_enable_or_unmask(unsigned int irq)
 		out_be32(INTC_BASE + IAR, mask);
 }
 
-static void intc_disable_or_mask(unsigned int irq)
+static void intc_disable_or_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("disable: %d\n", irq);
 	out_be32(INTC_BASE + CIE, 1 << irq);
 }
 
-static void intc_ack(unsigned int irq)
+static void intc_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("ack: %d\n", irq);
 	out_be32(INTC_BASE + IAR, 1 << irq);
 }
 
-static void intc_mask_ack(unsigned int irq)
+static void intc_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("disable_and_ack: %d\n", irq);
 	out_be32(INTC_BASE + CIE, mask);
 	out_be32(INTC_BASE + IAR, mask);
 }
 
-static void intc_end(unsigned int irq)
+static void intc_end(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("end: %d\n", irq);
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index b2821ac..4391efd 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -37,7 +37,7 @@
 #include <asm/mach-pb1x00/pb1000.h>
 #endif
 
-static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
+static int au1x_ic_settype(struct irq_desc *desc, unsigned int flow_type);
 
 /* NOTE on interrupt priorities: The original writers of this code said:
  *
@@ -300,17 +300,19 @@ void restore_au1xxx_intctl(void)
 #endif /* CONFIG_PM */
 
 
-static void au1x_ic0_unmask(unsigned int irq_nr)
+static void au1x_ic0_unmask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 	au_writel(1 << bit, IC0_MASKSET);
 	au_writel(1 << bit, IC0_WAKESET);
 	au_sync();
 }
 
-static void au1x_ic1_unmask(unsigned int irq_nr)
+static void au1x_ic1_unmask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 	au_writel(1 << bit, IC1_MASKSET);
 	au_writel(1 << bit, IC1_WAKESET);
 
@@ -324,25 +326,28 @@ static void au1x_ic1_unmask(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic0_mask(unsigned int irq_nr)
+static void au1x_ic0_mask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 	au_writel(1 << bit, IC0_MASKCLR);
 	au_writel(1 << bit, IC0_WAKECLR);
 	au_sync();
 }
 
-static void au1x_ic1_mask(unsigned int irq_nr)
+static void au1x_ic1_mask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 	au_writel(1 << bit, IC1_MASKCLR);
 	au_writel(1 << bit, IC1_WAKECLR);
 	au_sync();
 }
 
-static void au1x_ic0_ack(unsigned int irq_nr)
+static void au1x_ic0_ack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 
 	/*
 	 * This may assume that we don't get interrupts from
@@ -353,9 +358,10 @@ static void au1x_ic0_ack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic1_ack(unsigned int irq_nr)
+static void au1x_ic1_ack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 
 	/*
 	 * This may assume that we don't get interrupts from
@@ -366,9 +372,10 @@ static void au1x_ic1_ack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic0_maskack(unsigned int irq_nr)
+static void au1x_ic0_maskack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 
 	au_writel(1 << bit, IC0_WAKECLR);
 	au_writel(1 << bit, IC0_MASKCLR);
@@ -377,9 +384,10 @@ static void au1x_ic0_maskack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic1_maskack(unsigned int irq_nr)
+static void au1x_ic1_maskack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 
 	au_writel(1 << bit, IC1_WAKECLR);
 	au_writel(1 << bit, IC1_MASKCLR);
@@ -388,8 +396,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr)
 	au_sync();
 }
 
-static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
+static int au1x_ic1_setwake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - AU1000_INTC1_INT_BASE;
 	unsigned long wakemsk, flags;
 
@@ -435,8 +444,9 @@ static struct irq_chip au1x_ic1_chip = {
 	.set_wake	= au1x_ic1_setwake,
 };
 
-static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
+static int au1x_ic_settype(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	struct irq_chip *chip;
 	unsigned long icr[6];
 	unsigned int bit, ic;
@@ -586,11 +596,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 	 */
 	for (i = AU1000_INTC0_INT_BASE;
 	     (i < AU1000_INTC0_INT_BASE + 32); i++)
-		au1x_ic_settype(i, IRQ_TYPE_NONE);
+		au1x_ic_settype(irq_to_desc(i), IRQ_TYPE_NONE);
 
 	for (i = AU1000_INTC1_INT_BASE;
 	     (i < AU1000_INTC1_INT_BASE + 32); i++)
-		au1x_ic_settype(i, IRQ_TYPE_NONE);
+		au1x_ic_settype(irq_to_desc(i), IRQ_TYPE_NONE);
 
 	/*
 	 * Initialize IC0, which is fixed per processor.
@@ -608,7 +618,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 				au_writel(1 << bit, IC0_ASSIGNSET);
 		}
 
-		au1x_ic_settype(irq_nr, map->im_type);
+		au1x_ic_settype(irq_to_desc(irq_nr), map->im_type);
 		++map;
 	}
 
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 3bc4fd2..e801e8c 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -96,16 +96,18 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
  * CPLD generates tons of spurious interrupts (at least on my DB1200).
  *	-- mlau
  */
-static void bcsr_irq_mask(unsigned int irq_nr)
+static void bcsr_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
 	wmb();
 }
 
-static void bcsr_irq_maskack(unsigned int irq_nr)
+static void bcsr_irq_maskack(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
@@ -113,8 +115,9 @@ static void bcsr_irq_maskack(unsigned int irq_nr)
 	wmb();
 }
 
-static void bcsr_irq_unmask(unsigned int irq_nr)
+static void bcsr_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
index c781556..d65b855 100644
--- a/arch/mips/ar7/irq.c
+++ b/arch/mips/ar7/irq.c
@@ -48,36 +48,42 @@
 
 static int ar7_irq_base;
 
-static void ar7_unmask_irq(unsigned int irq)
+static void ar7_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(ESR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_mask_irq(unsigned int irq)
+static void ar7_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(ECR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_ack_irq(unsigned int irq)
+static void ar7_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(CR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_unmask_sec_irq(unsigned int irq)
+static void ar7_unmask_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
 }
 
-static void ar7_mask_sec_irq(unsigned int irq)
+static void ar7_mask_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
 }
 
-static void ar7_ack_sec_irq(unsigned int irq)
+static void ar7_ack_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
 }
 
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index a0c5cd1..6e0b206 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -75,8 +75,9 @@ asmlinkage void plat_irq_dispatch(void)
  * internal IRQs operations: only mask/unmask on PERF irq mask
  * register.
  */
-static inline void bcm63xx_internal_irq_mask(unsigned int irq)
+static inline void bcm63xx_internal_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 
 	irq -= IRQ_INTERNAL_BASE;
@@ -85,8 +86,9 @@ static inline void bcm63xx_internal_irq_mask(unsigned int irq)
 	bcm_perf_writel(mask, PERF_IRQMASK_REG);
 }
 
-static void bcm63xx_internal_irq_unmask(unsigned int irq)
+static void bcm63xx_internal_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 
 	irq -= IRQ_INTERNAL_BASE;
@@ -95,9 +97,9 @@ static void bcm63xx_internal_irq_unmask(unsigned int irq)
 	bcm_perf_writel(mask, PERF_IRQMASK_REG);
 }
 
-static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
+static unsigned int bcm63xx_internal_irq_startup(struct irq_desc *desc)
 {
-	bcm63xx_internal_irq_unmask(irq);
+	bcm63xx_internal_irq_unmask(desc);
 	return 0;
 }
 
@@ -105,8 +107,9 @@ static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
  * external IRQs operations: mask/unmask and clear on PERF external
  * irq control register.
  */
-static void bcm63xx_external_irq_mask(unsigned int irq)
+static void bcm63xx_external_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -115,8 +118,9 @@ static void bcm63xx_external_irq_mask(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static void bcm63xx_external_irq_unmask(unsigned int irq)
+static void bcm63xx_external_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -125,8 +129,9 @@ static void bcm63xx_external_irq_unmask(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static void bcm63xx_external_irq_clear(unsigned int irq)
+static void bcm63xx_external_irq_clear(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -135,26 +140,28 @@ static void bcm63xx_external_irq_clear(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
+static unsigned int bcm63xx_external_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 	irq_enable_hazard();
-	bcm63xx_external_irq_unmask(irq);
+	bcm63xx_external_irq_unmask(desc);
 	return 0;
 }
 
-static void bcm63xx_external_irq_shutdown(unsigned int irq)
+static void bcm63xx_external_irq_shutdown(struct irq_desc *desc)
 {
-	bcm63xx_external_irq_mask(irq);
+	unsigned int irq = desc->irq;
+	bcm63xx_external_irq_mask(desc);
 	clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 	irq_disable_hazard();
 }
 
-static int bcm63xx_external_irq_set_type(unsigned int irq,
+static int bcm63xx_external_irq_set_type(struct irq_desc *desc,
 					 unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
-	struct irq_desc *desc = irq_desc + irq;
 
 	irq -= IRQ_EXT_BASE;
 
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index c424cd1..e872477 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -25,8 +25,9 @@ static int octeon_coreid_for_cpu(int cpu)
 #endif
 }
 
-static void octeon_irq_core_ack(unsigned int irq)
+static void octeon_irq_core_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * We don't need to disable IRQs to make these atomic since
@@ -39,9 +40,9 @@ static void octeon_irq_core_ack(unsigned int irq)
 		clear_c0_cause(0x100 << bit);
 }
 
-static void octeon_irq_core_eoi(unsigned int irq)
+static void octeon_irq_core_eoi(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * If an IRQ is being processed while we are disabling it the
@@ -58,8 +59,9 @@ static void octeon_irq_core_eoi(unsigned int irq)
 	set_c0_status(0x100 << bit);
 }
 
-static void octeon_irq_core_enable(unsigned int irq)
+static void octeon_irq_core_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 
@@ -85,8 +87,9 @@ static void octeon_irq_core_disable_local(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-static void octeon_irq_core_disable(unsigned int irq)
+static void octeon_irq_core_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 #ifdef CONFIG_SMP
 	on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
 		    (void *) (long) irq, 1);
@@ -104,7 +107,7 @@ static struct irq_chip octeon_irq_chip_core = {
 };
 
 
-static void octeon_irq_ciu0_ack(unsigned int irq)
+static void octeon_irq_ciu0_ack(struct irq_desc *desc)
 {
 	/*
 	 * In order to avoid any locking accessing the CIU, we
@@ -120,7 +123,7 @@ static void octeon_irq_ciu0_ack(unsigned int irq)
 	clear_c0_status(0x100 << 2);
 }
 
-static void octeon_irq_ciu0_eoi(unsigned int irq)
+static void octeon_irq_ciu0_eoi(struct irq_desc *desc)
 {
 	/*
 	 * Enable all CIU interrupts again.  We don't need to disable
@@ -130,8 +133,9 @@ static void octeon_irq_ciu0_eoi(unsigned int irq)
 	set_c0_status(0x100 << 2);
 }
 
-static void octeon_irq_ciu0_enable(unsigned int irq)
+static void octeon_irq_ciu0_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int coreid = cvmx_get_core_num();
 	unsigned long flags;
 	uint64_t en0;
@@ -145,8 +149,9 @@ static void octeon_irq_ciu0_enable(unsigned int irq)
 	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 }
 
-static void octeon_irq_ciu0_disable(unsigned int irq)
+static void octeon_irq_ciu0_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
 	unsigned long flags;
 	uint64_t en0;
@@ -170,8 +175,9 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_enable_v2(unsigned int irq)
+static void octeon_irq_ciu0_enable_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 
@@ -182,10 +188,10 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_ack_v2(unsigned int irq)
+static void octeon_irq_ciu0_ack_v2(struct irq_desc *desc)
 {
 	int index = cvmx_get_core_num() * 2;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 
 	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
 }
@@ -194,34 +200,33 @@ static void octeon_irq_ciu0_ack_v2(unsigned int irq)
  * CIU timer type interrupts must be acknoleged by writing a '1' bit
  * to their sum0 bit.
  */
-static void octeon_irq_ciu0_timer_ack(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack(struct irq_desc *desc)
 {
 	int index = cvmx_get_core_num() * 2;
-	uint64_t mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	uint64_t mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 	cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
 }
 
-static void octeon_irq_ciu0_timer_ack_v1(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack_v1(struct irq_desc *desc)
 {
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack(irq);
+	octeon_irq_ciu0_timer_ack(desc);
+	octeon_irq_ciu0_ack(desc);
 }
 
-static void octeon_irq_ciu0_timer_ack_v2(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack_v2(struct irq_desc *desc)
 {
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack_v2(irq);
+	octeon_irq_ciu0_timer_ack(desc);
+	octeon_irq_ciu0_ack_v2(desc);
 }
 
 /*
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu0_eoi_v2(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
 	int index = cvmx_get_core_num() * 2;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 
 	if ((desc->status & IRQ_DISABLED) == 0)
 		cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
@@ -231,8 +236,9 @@ static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
+static void octeon_irq_ciu0_disable_all_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 	int index;
 	int cpu;
@@ -243,8 +249,9 @@ static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu0_set_affinity(struct irq_desc *desc, const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
@@ -274,9 +281,10 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
  * Set affinity for the irq for chips that have the EN*_W1{S,C}
  * registers.
  */
-static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
+static int octeon_irq_ciu0_set_affinity_v2(struct irq_desc *desc,
 					   const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
@@ -339,7 +347,7 @@ static struct irq_chip octeon_irq_chip_ciu0_timer = {
 };
 
 
-static void octeon_irq_ciu1_ack(unsigned int irq)
+static void octeon_irq_ciu1_ack(struct irq_desc *desc)
 {
 	/*
 	 * In order to avoid any locking accessing the CIU, we
@@ -353,7 +361,7 @@ static void octeon_irq_ciu1_ack(unsigned int irq)
 	clear_c0_status(0x100 << 3);
 }
 
-static void octeon_irq_ciu1_eoi(unsigned int irq)
+static void octeon_irq_ciu1_eoi(struct irq_desc *desc)
 {
 	/*
 	 * Enable all CIU interrupts again.  We don't need to disable
@@ -363,8 +371,9 @@ static void octeon_irq_ciu1_eoi(unsigned int irq)
 	set_c0_status(0x100 << 3);
 }
 
-static void octeon_irq_ciu1_enable(unsigned int irq)
+static void octeon_irq_ciu1_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int coreid = cvmx_get_core_num();
 	unsigned long flags;
 	uint64_t en1;
@@ -378,8 +387,9 @@ static void octeon_irq_ciu1_enable(unsigned int irq)
 	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 }
 
-static void octeon_irq_ciu1_disable(unsigned int irq)
+static void octeon_irq_ciu1_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 	unsigned long flags;
 	uint64_t en1;
@@ -403,8 +413,9 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_enable_v2(unsigned int irq)
+static void octeon_irq_ciu1_enable_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 
@@ -415,8 +426,9 @@ static void octeon_irq_ciu1_enable_v2(unsigned int irq)
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_ack_v2(unsigned int irq)
+static void octeon_irq_ciu1_ack_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 
@@ -427,11 +439,10 @@ static void octeon_irq_ciu1_ack_v2(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu1_eoi_v2(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
 	int index = cvmx_get_core_num() * 2 + 1;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WDOG0);
 
 	if ((desc->status & IRQ_DISABLED) == 0)
 		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
@@ -441,9 +452,9 @@ static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
+static void octeon_irq_ciu1_disable_all_v2(struct irq_desc *desc)
 {
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WDOG0);
 	int index;
 	int cpu;
 	for_each_online_cpu(cpu) {
@@ -453,9 +464,10 @@ static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int octeon_irq_ciu1_set_affinity(unsigned int irq,
+static int octeon_irq_ciu1_set_affinity(struct irq_desc *desc,
 					const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
@@ -486,9 +498,10 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq,
  * Set affinity for the irq for chips that have the EN*_W1{S,C}
  * registers.
  */
-static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
+static int octeon_irq_ciu1_set_affinity_v2(struct irq_desc *desc,
 					   const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
@@ -532,8 +545,9 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
 
 static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
 
-static void octeon_irq_msi_ack(unsigned int irq)
+static void octeon_irq_msi_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/* These chips have PCI */
 		cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
@@ -548,13 +562,14 @@ static void octeon_irq_msi_ack(unsigned int irq)
 	}
 }
 
-static void octeon_irq_msi_eoi(unsigned int irq)
+static void octeon_irq_msi_eoi(struct irq_desc *desc)
 {
 	/* Nothing needed */
 }
 
-static void octeon_irq_msi_enable(unsigned int irq)
+static void octeon_irq_msi_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/*
 		 * Octeon PCI doesn't have the ability to mask/unmask
@@ -581,8 +596,9 @@ static void octeon_irq_msi_enable(unsigned int irq)
 	}
 }
 
-static void octeon_irq_msi_disable(unsigned int irq)
+static void octeon_irq_msi_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/* See comment in enable */
 	} else {
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
index cb41954..e8d60a6 100644
--- a/arch/mips/dec/ioasic-irq.c
+++ b/arch/mips/dec/ioasic-irq.c
@@ -21,8 +21,9 @@
 static int ioasic_irq_base;
 
 
-static inline void unmask_ioasic_irq(unsigned int irq)
+static inline void unmask_ioasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 simr;
 
 	simr = ioasic_read(IO_REG_SIMR);
@@ -30,8 +31,9 @@ static inline void unmask_ioasic_irq(unsigned int irq)
 	ioasic_write(IO_REG_SIMR, simr);
 }
 
-static inline void mask_ioasic_irq(unsigned int irq)
+static inline void mask_ioasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 simr;
 
 	simr = ioasic_read(IO_REG_SIMR);
@@ -47,16 +49,16 @@ static inline void clear_ioasic_irq(unsigned int irq)
 	ioasic_write(IO_REG_SIR, sir);
 }
 
-static inline void ack_ioasic_irq(unsigned int irq)
+static inline void ack_ioasic_irq(struct irq_desc *desc)
 {
-	mask_ioasic_irq(irq);
+	mask_ioasic_irq(desc);
 	fast_iob();
 }
 
-static inline void end_ioasic_irq(unsigned int irq)
+static inline void end_ioasic_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		unmask_ioasic_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_ioasic_irq(desc);
 }
 
 static struct irq_chip ioasic_irq_type = {
@@ -74,11 +76,12 @@ static struct irq_chip ioasic_irq_type = {
 
 #define ack_ioasic_dma_irq ack_ioasic_irq
 
-static inline void end_ioasic_dma_irq(unsigned int irq)
+static inline void end_ioasic_dma_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_ioasic_irq(irq);
 	fast_iob();
-	end_ioasic_irq(irq);
+	end_ioasic_irq(desc);
 }
 
 static struct irq_chip ioasic_dma_irq_type = {
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index ed90a8d..3ea3682 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -31,8 +31,9 @@ u32 cached_kn02_csr;
 static int kn02_irq_base;
 
 
-static inline void unmask_kn02_irq(unsigned int irq)
+static inline void unmask_kn02_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
 						       KN02_CSR);
 
@@ -40,8 +41,9 @@ static inline void unmask_kn02_irq(unsigned int irq)
 	*csr = cached_kn02_csr;
 }
 
-static inline void mask_kn02_irq(unsigned int irq)
+static inline void mask_kn02_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
 						       KN02_CSR);
 
@@ -49,9 +51,9 @@ static inline void mask_kn02_irq(unsigned int irq)
 	*csr = cached_kn02_csr;
 }
 
-static void ack_kn02_irq(unsigned int irq)
+static void ack_kn02_irq(struct irq_desc *desc)
 {
-	mask_kn02_irq(irq);
+	mask_kn02_irq(desc);
 	iob();
 }
 
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 9504b7e..3c2e1c9 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -34,8 +34,9 @@
 
 #include <asm/emma/emma2rh.h>
 
-static void emma2rh_irq_enable(unsigned int irq)
+static void emma2rh_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_value;
 	u32 reg_bitmask;
 	u32 reg_index;
@@ -49,8 +50,9 @@ static void emma2rh_irq_enable(unsigned int irq)
 	emma2rh_out32(reg_index, reg_value | reg_bitmask);
 }
 
-static void emma2rh_irq_disable(unsigned int irq)
+static void emma2rh_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_value;
 	u32 reg_bitmask;
 	u32 reg_index;
@@ -82,8 +84,9 @@ void emma2rh_irq_init(void)
 					      handle_level_irq, "level");
 }
 
-static void emma2rh_sw_irq_enable(unsigned int irq)
+static void emma2rh_sw_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_SW_IRQ_BASE;
@@ -93,8 +96,9 @@ static void emma2rh_sw_irq_enable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
 }
 
-static void emma2rh_sw_irq_disable(unsigned int irq)
+static void emma2rh_sw_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_SW_IRQ_BASE;
@@ -122,8 +126,9 @@ void emma2rh_sw_irq_init(void)
 					      handle_level_irq, "level");
 }
 
-static void emma2rh_gpio_irq_enable(unsigned int irq)
+static void emma2rh_gpio_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
@@ -133,8 +138,9 @@ static void emma2rh_gpio_irq_enable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_disable(unsigned int irq)
+static void emma2rh_gpio_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
@@ -144,14 +150,16 @@ static void emma2rh_gpio_irq_disable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_ack(unsigned int irq)
+static void emma2rh_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
 	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
 }
 
-static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
+static void emma2rh_gpio_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index ee18028..b76cdcd 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -22,8 +22,9 @@
 
 static DEFINE_RAW_SPINLOCK(r4030_lock);
 
-static void enable_r4030_irq(unsigned int irq)
+static void enable_r4030_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - JAZZ_IRQ_START);
 	unsigned long flags;
 
@@ -33,8 +34,9 @@ static void enable_r4030_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&r4030_lock, flags);
 }
 
-void disable_r4030_irq(unsigned int irq)
+void disable_r4030_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START));
 	unsigned long flags;
 
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 2779911..f6f63a3 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -30,9 +30,9 @@
 
 static int i8259A_auto_eoi = -1;
 DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
-static void mask_and_ack_8259A(unsigned int irq);
+static void disable_8259A_irq(struct irq_desc *desc);
+static void enable_8259A_irq(struct irq_desc *desc);
+static void mask_and_ack_8259A(struct irq_desc *desc);
 static void init_8259A(int auto_eoi);
 
 static struct irq_chip i8259A_chip = {
@@ -58,8 +58,9 @@ static unsigned int cached_irq_mask = 0xffff;
 #define cached_master_mask	(cached_irq_mask)
 #define cached_slave_mask	(cached_irq_mask >> 8)
 
-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;
 	unsigned long flags;
 
@@ -74,8 +75,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;
 	unsigned long flags;
 
@@ -144,8 +146,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;
 	unsigned long flags;
 
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index b181f2f..c278afa 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -88,16 +88,18 @@ unsigned int gic_get_int(void)
 	return i;
 }
 
-static unsigned int gic_irq_startup(unsigned int irq)
+static unsigned int gic_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_SET_INTR_MASK(irq);
 	return 0;
 }
 
-static void gic_irq_ack(unsigned int irq)
+static void gic_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_CLR_INTR_MASK(irq);
@@ -106,15 +108,17 @@ static void gic_irq_ack(unsigned int irq)
 		GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
 }
 
-static void gic_mask_irq(unsigned int irq)
+static void gic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_CLR_INTR_MASK(irq);
 }
 
-static void gic_unmask_irq(unsigned int irq)
+static void gic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_SET_INTR_MASK(irq);
@@ -124,8 +128,9 @@ static void gic_unmask_irq(unsigned int irq)
 
 static DEFINE_SPINLOCK(gic_lock);
 
-static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+static int gic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int irq = desc->irq;
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
 	int		i;
@@ -148,7 +153,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 		set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
 
 	}
-	cpumask_copy(irq_desc[irq].affinity, cpumask);
+	cpumask_copy(desc->affinity, cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
index 42ef814..2c323dc 100644
--- a/arch/mips/kernel/irq-gt641xx.c
+++ b/arch/mips/kernel/irq-gt641xx.c
@@ -29,8 +29,9 @@
 
 static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
 
-static void ack_gt641xx_irq(unsigned int irq)
+static void ack_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 cause;
 
@@ -41,8 +42,9 @@ static void ack_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void mask_gt641xx_irq(unsigned int irq)
+static void mask_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 mask;
 
@@ -53,8 +55,9 @@ static void mask_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void mask_ack_gt641xx_irq(unsigned int irq)
+static void mask_ack_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 cause, mask;
 
@@ -69,8 +72,9 @@ static void mask_ack_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void unmask_gt641xx_irq(unsigned int irq)
+static void unmask_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 mask;
 
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 6a8cd28..b860443 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -28,8 +28,9 @@ static unsigned long _icctrl_msc;
 static unsigned int irq_base;
 
 /* mask off an interrupt */
-static inline void mask_msc_irq(unsigned int irq)
+static inline void mask_msc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq < (irq_base + 32))
 		MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
 	else
@@ -37,8 +38,9 @@ static inline void mask_msc_irq(unsigned int irq)
 }
 
 /* unmask an interrupt */
-static inline void unmask_msc_irq(unsigned int irq)
+static inline void unmask_msc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq < (irq_base + 32))
 		MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
 	else
@@ -48,9 +50,10 @@ static inline void unmask_msc_irq(unsigned int irq)
 /*
  * Masks and ACKs an IRQ
  */
-static void level_mask_and_ack_msc_irq(unsigned int irq)
+static void level_mask_and_ack_msc_irq(struct irq_desc *desc)
 {
-	mask_msc_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msc_irq(desc);
 	if (!cpu_has_veic)
 		MSCIC_WRITE(MSC01_IC_EOI, 0);
 	/* This actually needs to be a call into platform code */
@@ -60,9 +63,10 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
 /*
  * Masks and ACKs an IRQ
  */
-static void edge_mask_and_ack_msc_irq(unsigned int irq)
+static void edge_mask_and_ack_msc_irq(struct irq_desc *desc)
 {
-	mask_msc_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msc_irq(desc);
 	if (!cpu_has_veic)
 		MSCIC_WRITE(MSC01_IC_EOI, 0);
 	else {
@@ -77,10 +81,10 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq)
 /*
  * End IRQ processing
  */
-static void end_msc_irq(unsigned int irq)
+static void end_msc_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		unmask_msc_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_msc_irq(desc);
 }
 
 /*
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index fb50cc7..0c5e6c0 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -17,13 +17,15 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-static inline void unmask_rm7k_irq(unsigned int irq)
+static inline void unmask_rm7k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
 }
 
-static inline void mask_rm7k_irq(unsigned int irq)
+static inline void mask_rm7k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
 }
 
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index b47e461..5491ec0 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -18,22 +18,24 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-static inline void unmask_rm9k_irq(unsigned int irq)
+static inline void unmask_rm9k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
 }
 
-static inline void mask_rm9k_irq(unsigned int irq)
+static inline void mask_rm9k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
 }
 
-static inline void rm9k_cpu_irq_enable(unsigned int irq)
+static inline void rm9k_cpu_irq_enable(struct irq_desc *desc)
 {
 	unsigned long flags;
 
 	local_irq_save(flags);
-	unmask_rm9k_irq(irq);
+	unmask_rm9k_irq(desc);
 	local_irq_restore(flags);
 }
 
@@ -42,31 +44,31 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq)
  */
 static void local_rm9k_perfcounter_irq_startup(void *args)
 {
-	unsigned int irq = (unsigned int) args;
+	struct irq_desc *desc = (struct irq_desc *) args;
 
-	rm9k_cpu_irq_enable(irq);
+	rm9k_cpu_irq_enable(desc);
 }
 
-static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
+static unsigned int rm9k_perfcounter_irq_startup(struct irq_desc *desc)
 {
-	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1);
+	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *)desc, 1);
 
 	return 0;
 }
 
 static void local_rm9k_perfcounter_irq_shutdown(void *args)
 {
-	unsigned int irq = (unsigned int) args;
+	struct irq_desc *desc = (struct irq_desc *) args;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	mask_rm9k_irq(irq);
+	mask_rm9k_irq(desc);
 	local_irq_restore(flags);
 }
 
-static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
+static void rm9k_perfcounter_irq_shutdown(struct irq_desc *desc)
 {
-	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1);
+	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *)desc, 1);
 }
 
 static struct irq_chip rm9k_irq_controller = {
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 55c8a3c..ad7c3d0 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -36,14 +36,16 @@
 #include <asm/mipsmtregs.h>
 #include <asm/system.h>
 
-static inline void unmask_mips_irq(unsigned int irq)
+static inline void unmask_mips_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	irq_enable_hazard();
 }
 
-static inline void mask_mips_irq(unsigned int irq)
+static inline void mask_mips_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	irq_disable_hazard();
 }
@@ -64,13 +66,14 @@ static struct irq_chip mips_cpu_irq_controller = {
 #define unmask_mips_mt_irq	unmask_mips_irq
 #define mask_mips_mt_irq	mask_mips_irq
 
-static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
+static unsigned int mips_mt_cpu_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vpflags = dvpe();
 
 	clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	evpe(vpflags);
-	unmask_mips_mt_irq(irq);
+	unmask_mips_mt_irq(desc);
 
 	return 0;
 }
@@ -79,12 +82,13 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for mips_cpu_irq_end.
  */
-static void mips_mt_cpu_irq_ack(unsigned int irq)
+static void mips_mt_cpu_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vpflags = dvpe();
 	clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	evpe(vpflags);
-	mask_mips_mt_irq(irq);
+	mask_mips_mt_irq(desc);
 }
 
 static struct irq_chip mips_mt_cpu_irq_controller = {
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
index 9b78029..5532280 100644
--- a/arch/mips/kernel/irq_txx9.c
+++ b/arch/mips/kernel/irq_txx9.c
@@ -62,8 +62,9 @@ static struct {
 	unsigned char mode;
 } txx9irq[TXx9_MAX_IR] __read_mostly;
 
-static void txx9_irq_unmask(unsigned int irq)
+static void txx9_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
 	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
@@ -78,8 +79,9 @@ static void txx9_irq_unmask(unsigned int irq)
 #endif
 }
 
-static inline void txx9_irq_mask(unsigned int irq)
+static inline void txx9_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
 	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
@@ -98,18 +100,20 @@ static inline void txx9_irq_mask(unsigned int irq)
 #endif
 }
 
-static void txx9_irq_mask_ack(unsigned int irq)
+static void txx9_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 
-	txx9_irq_mask(irq);
+	txx9_irq_mask(desc);
 	/* clear edge detection */
 	if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
 		__raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
 }
 
-static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int txx9_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 cr;
 	u32 __iomem *crp;
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index 1353fb1..9e9edf9 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -32,16 +32,18 @@ static volatile int *lasat_int_status;
 static volatile int *lasat_int_mask;
 static volatile int lasat_int_mask_shift;
 
-void disable_lasat_irq(unsigned int irq_nr)
+void disable_lasat_irq(struct irq_desc *desc)
 {
-	irq_nr -= LASAT_IRQ_BASE;
-	*lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
+	unsigned int irq = desc->irq;
+	irq -= LASAT_IRQ_BASE;
+	*lasat_int_mask &= ~(1 << irq) << lasat_int_mask_shift;
 }
 
-void enable_lasat_irq(unsigned int irq_nr)
+void enable_lasat_irq(struct irq_desc *desc)
 {
-	irq_nr -= LASAT_IRQ_BASE;
-	*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
+	unsigned int irq = desc->irq;
+	irq -= LASAT_IRQ_BASE;
+	*lasat_int_mask |= (1 << irq) << lasat_int_mask_shift;
 }
 
 static struct irq_chip lasat_irq_type = {
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
index 2dc2a4c..00db7a1 100644
--- a/arch/mips/loongson/common/bonito-irq.c
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -16,14 +16,16 @@
 
 #include <loongson.h>
 
-static inline void bonito_irq_enable(unsigned int irq)
+static inline void bonito_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
 
-static inline void bonito_irq_disable(unsigned int irq)
+static inline void bonito_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c
index 941916f..9b4f8b1 100644
--- a/arch/mips/nxp/pnx833x/common/interrupts.c
+++ b/arch/mips/nxp/pnx833x/common/interrupts.c
@@ -158,8 +158,9 @@ static int irqflags[PNX833X_PIC_NUM_IRQ];	/* initialized by zeroes */
 
 static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
 
-static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
+static unsigned int pnx833x_startup_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -172,8 +173,9 @@ static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
 	return 0;
 }
 
-static void pnx833x_shutdown_pic_irq(unsigned int irq)
+static void pnx833x_shutdown_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -185,8 +187,9 @@ static void pnx833x_shutdown_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_enable_pic_irq(unsigned int irq)
+static void pnx833x_enable_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -199,8 +202,9 @@ static void pnx833x_enable_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_disable_pic_irq(unsigned int irq)
+static void pnx833x_disable_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -212,18 +216,19 @@ static void pnx833x_disable_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_ack_pic_irq(unsigned int irq)
+static void pnx833x_ack_pic_irq(struct irq_desc *desc)
 {
 }
 
-static void pnx833x_end_pic_irq(unsigned int irq)
+static void pnx833x_end_pic_irq(struct irq_desc *desc)
 {
 }
 
 static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
 
-static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
+static unsigned int pnx833x_startup_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -232,8 +237,9 @@ static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
 	return 0;
 }
 
-static void pnx833x_enable_gpio_irq(unsigned int irq)
+static void pnx833x_enable_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -241,8 +247,9 @@ static void pnx833x_enable_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_disable_gpio_irq(unsigned int irq)
+static void pnx833x_disable_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -250,12 +257,13 @@ static void pnx833x_disable_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_ack_gpio_irq(unsigned int irq)
+static void pnx833x_ack_gpio_irq(struct irq_desc *desc)
 {
 }
 
-static void pnx833x_end_gpio_irq(unsigned int irq)
+static void pnx833x_end_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -263,8 +271,9 @@ static void pnx833x_end_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
+static int pnx833x_set_type_gpio_irq(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	int gpio_mode;
 
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c
index 7aca7d5..944fe74 100644
--- a/arch/mips/nxp/pnx8550/common/int.c
+++ b/arch/mips/nxp/pnx8550/common/int.c
@@ -115,8 +115,9 @@ static inline void unmask_gic_int(unsigned int irq_nr)
 	PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
 }
 
-static inline void mask_irq(unsigned int irq_nr)
+static inline void mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
 		modify_cp0_intmask(1 << irq_nr, 0);
 	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
@@ -130,8 +131,9 @@ static inline void mask_irq(unsigned int irq_nr)
 	}
 }
 
-static inline void unmask_irq(unsigned int irq_nr)
+static inline void unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
 		modify_cp0_intmask(0, 1 << irq_nr);
 	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
@@ -183,7 +185,7 @@ void __init arch_init_irq(void)
 
 	for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
 		set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
-		mask_irq(i);	/* mask the irq just in case  */
+		mask_irq(irq_to_desc(i));	/* mask the irq just in case  */
 	}
 
 	/* init of GIC/IPC interrupts */
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
index 94c9c2c..47b2be9 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -24,9 +24,9 @@
  * NOTE: We are only enabling support for VPE0 right now.
  */
 
-static inline void unmask_msp_cic_irq(unsigned int irq)
+static inline void unmask_msp_cic_irq(struct irq_desc *desc)
 {
-
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE));
@@ -34,8 +34,9 @@ static inline void unmask_msp_cic_irq(unsigned int irq)
 		*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
 }
 
-static inline void mask_msp_cic_irq(unsigned int irq)
+static inline void mask_msp_cic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE));
@@ -47,9 +48,10 @@ static inline void mask_msp_cic_irq(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for msp_cic_irq_end.
  */
-static inline void ack_msp_cic_irq(unsigned int irq)
+static inline void ack_msp_cic_irq(struct irq_desc *desc)
 {
-	mask_msp_cic_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msp_cic_irq(desc);
 
 	/*
 	 * only really necessary for 18, 16-14 and sometimes 3:0 (since
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
index 61f3902..e73cda1 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
@@ -21,8 +21,9 @@
 #include <msp_slp_int.h>
 #include <msp_regs.h>
 
-static inline void unmask_msp_slp_irq(unsigned int irq)
+static inline void unmask_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
@@ -30,8 +31,9 @@ static inline void unmask_msp_slp_irq(unsigned int irq)
 		*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
 }
 
-static inline void mask_msp_slp_irq(unsigned int irq)
+static inline void mask_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
@@ -43,8 +45,9 @@ static inline void mask_msp_slp_irq(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for msp_slp_irq_end.
  */
-static inline void ack_msp_slp_irq(unsigned int irq)
+static inline void ack_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
index b54d244..a710bc3 100644
--- a/arch/mips/powertv/asic/irq_asic.c
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -20,8 +20,9 @@
 
 #include <asm/mach-powertv/asic_regs.h>
 
-static inline void unmask_asic_irq(unsigned int irq)
+static inline void unmask_asic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long enable_bit;
 
 	enable_bit = (1 << (irq & 0x1f));
@@ -44,8 +45,9 @@ static inline void unmask_asic_irq(unsigned int irq)
 	}
 }
 
-static inline void mask_asic_irq(unsigned int irq)
+static inline void mask_asic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long disable_mask;
 
 	disable_mask = ~(1 << (irq & 0x1f));
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index f078820..39f304a 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -112,14 +112,15 @@ static inline void ack_local_irq(unsigned int ip)
 	clear_c0_cause(ipnum);
 }
 
-static void rb532_enable_irq(unsigned int irq_nr)
+static void rb532_enable_irq(struct irq_desc *desc)
 {
-	int ip = irq_nr - GROUP0_IRQ_BASE;
+	unsigned int irq = desc->irq;
+	int ip = irq - GROUP0_IRQ_BASE;
 	unsigned int group, intr_bit;
 	volatile unsigned int *addr;
 
 	if (ip < 0)
-		enable_local_irq(irq_nr);
+		enable_local_irq(irq);
 	else {
 		group = ip >> 5;
 
@@ -133,14 +134,15 @@ static void rb532_enable_irq(unsigned int irq_nr)
 	}
 }
 
-static void rb532_disable_irq(unsigned int irq_nr)
+static void rb532_disable_irq(struct irq_desc *desc)
 {
-	int ip = irq_nr - GROUP0_IRQ_BASE;
+	unsigned int irq = desc->irq;
+	int ip = irq - GROUP0_IRQ_BASE;
 	unsigned int group, intr_bit, mask;
 	volatile unsigned int *addr;
 
 	if (ip < 0) {
-		disable_local_irq(irq_nr);
+		disable_local_irq(irq);
 	} else {
 		group = ip >> 5;
 
@@ -152,8 +154,8 @@ static void rb532_disable_irq(unsigned int irq_nr)
 		WRITE_MASK(addr, mask);
 
 		/* There is a maximum of 14 GPIO interrupts */
-		if (group == GPIO_MAPPED_IRQ_GROUP && irq_nr <= (GROUP4_IRQ_BASE + 13))
-			rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE);
+		if (group == GPIO_MAPPED_IRQ_GROUP && irq <= (GROUP4_IRQ_BASE + 13))
+			rb532_gpio_set_istat(0, irq - GPIO_MAPPED_IRQ_BASE);
 
 		/*
 		 * if there are no more interrupts enabled in this
@@ -164,14 +166,16 @@ static void rb532_disable_irq(unsigned int irq_nr)
 	}
 }
 
-static void rb532_mask_and_ack_irq(unsigned int irq_nr)
+static void rb532_mask_and_ack_irq(struct irq_desc *desc)
 {
-	rb532_disable_irq(irq_nr);
-	ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
+	unsigned int irq = desc->irq;
+	rb532_disable_irq(desc);
+	ack_local_irq(group_to_ip(irq_to_group(irq)));
 }
 
-static int rb532_set_type(unsigned int irq_nr, unsigned type)
+static int rb532_set_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq_nr = desc->irq;
 	int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
 	int group = irq_to_group(irq_nr);
 
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index 383f11d..93ddd8b 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -31,16 +31,18 @@ static char lc3msk_to_irqnr[256];
 
 extern int ip22_eisa_init(void);
 
-static void enable_local0_irq(unsigned int irq)
+static void enable_local0_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* don't allow mappable interrupt to be enabled from setup_irq,
 	 * we have our own way to do so */
 	if (irq != SGI_MAP_0_IRQ)
 		sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
 }
 
-static void disable_local0_irq(unsigned int irq)
+static void disable_local0_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
 }
 
@@ -52,16 +54,18 @@ static struct irq_chip ip22_local0_irq_type = {
 	.unmask		= enable_local0_irq,
 };
 
-static void enable_local1_irq(unsigned int irq)
+static void enable_local1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* don't allow mappable interrupt to be enabled from setup_irq,
 	 * we have our own way to do so */
 	if (irq != SGI_MAP_1_IRQ)
 		sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
 }
 
-static void disable_local1_irq(unsigned int irq)
+static void disable_local1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
 }
 
@@ -73,14 +77,16 @@ static struct irq_chip ip22_local1_irq_type = {
 	.unmask		= enable_local1_irq,
 };
 
-static void enable_local2_irq(unsigned int irq)
+static void enable_local2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
 	sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
 }
 
-static void disable_local2_irq(unsigned int irq)
+static void disable_local2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
 	if (!sgint->cmeimask0)
 		sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
@@ -94,14 +100,16 @@ static struct irq_chip ip22_local2_irq_type = {
 	.unmask		= enable_local2_irq,
 };
 
-static void enable_local3_irq(unsigned int irq)
+static void enable_local3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
 	sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
 }
 
-static void disable_local3_irq(unsigned int irq)
+static void disable_local3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
 	if (!sgint->cmeimask1)
 		sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index c1c8e40..3fb93b5 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -241,8 +241,9 @@ static int intr_disconnect_level(int cpu, int bit)
 }
 
 /* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(unsigned int irq)
+static unsigned int startup_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct bridge_controller *bc;
 	bridgereg_t device;
 	bridge_t *bridge;
@@ -289,8 +290,9 @@ static unsigned int startup_bridge_irq(unsigned int irq)
 }
 
 /* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-static void shutdown_bridge_irq(unsigned int irq)
+static void shutdown_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
 	bridge_t *bridge = bc->base;
 	int pin, swlevel;
@@ -310,8 +312,9 @@ static void shutdown_bridge_irq(unsigned int irq)
 	bridge->b_wid_tflush;
 }
 
-static inline void enable_bridge_irq(unsigned int irq)
+static inline void enable_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cpuid_t cpu;
 	int swlevel;
 
@@ -319,8 +322,9 @@ static inline void enable_bridge_irq(unsigned int irq)
 	intr_connect_level(cpu, swlevel);
 }
 
-static inline void disable_bridge_irq(unsigned int irq)
+static inline void disable_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cpuid_t cpu;
 	int swlevel;
 
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index d6802d6..13905d4 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -36,11 +36,11 @@
 #include <asm/sn/sn0/hubio.h>
 #include <asm/pci/bridge.h>
 
-static void enable_rt_irq(unsigned int irq)
+static void enable_rt_irq(struct irq_desc *desc)
 {
 }
 
-static void disable_rt_irq(unsigned int irq)
+static void disable_rt_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index d8b6520..2cf45d3 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -131,16 +131,18 @@ static struct irqaction cpuerr_irq = {
 
 static uint64_t crime_mask;
 
-static inline void crime_enable_irq(unsigned int irq)
+static inline void crime_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask |= 1 << bit;
 	crime->imask = crime_mask;
 }
 
-static inline void crime_disable_irq(unsigned int irq)
+static inline void crime_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask &= ~(1 << bit);
@@ -148,15 +150,15 @@ static inline void crime_disable_irq(unsigned int irq)
 	flush_crime_bus();
 }
 
-static void crime_level_mask_and_ack_irq(unsigned int irq)
+static void crime_level_mask_and_ack_irq(struct irq_desc *desc)
 {
-	crime_disable_irq(irq);
+	crime_disable_irq(desc);
 }
 
-static void crime_level_end_irq(unsigned int irq)
+static void crime_level_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		crime_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(desc);
 }
 
 static struct irq_chip crime_level_interrupt = {
@@ -168,8 +170,9 @@ static struct irq_chip crime_level_interrupt = {
 	.end		= crime_level_end_irq,
 };
 
-static void crime_edge_mask_and_ack_irq(unsigned int irq)
+static void crime_edge_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 	uint64_t crime_int;
 
@@ -179,13 +182,13 @@ static void crime_edge_mask_and_ack_irq(unsigned int irq)
 	crime_int &= ~(1 << bit);
 	crime->hard_int = crime_int;
 
-	crime_disable_irq(irq);
+	crime_disable_irq(desc);
 }
 
-static void crime_edge_end_irq(unsigned int irq)
+static void crime_edge_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		crime_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(desc);
 }
 
 static struct irq_chip crime_edge_interrupt = {
@@ -205,16 +208,18 @@ static struct irq_chip crime_edge_interrupt = {
 
 static unsigned long macepci_mask;
 
-static void enable_macepci_irq(unsigned int irq)
+static void enable_macepci_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
 	mace->pci.control = macepci_mask;
 	crime_mask |= 1 << (irq - CRIME_IRQ_BASE);
 	crime->imask = crime_mask;
 }
 
-static void disable_macepci_irq(unsigned int irq)
+static void disable_macepci_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE));
 	crime->imask = crime_mask;
 	flush_crime_bus();
@@ -223,10 +228,10 @@ static void disable_macepci_irq(unsigned int irq)
 	flush_mace_bus();
 }
 
-static void end_macepci_irq(unsigned int irq)
+static void end_macepci_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_macepci_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq(desc);
 }
 
 static struct irq_chip ip32_macepci_interrupt = {
@@ -277,8 +282,9 @@ static struct irq_chip ip32_macepci_interrupt = {
 
 static unsigned long maceisa_mask;
 
-static void enable_maceisa_irq(unsigned int irq)
+static void enable_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int crime_int = 0;
 
 	pr_debug("maceisa enable: %u\n", irq);
@@ -301,8 +307,9 @@ static void enable_maceisa_irq(unsigned int irq)
 	mace->perif.ctrl.imask = maceisa_mask;
 }
 
-static void disable_maceisa_irq(unsigned int irq)
+static void disable_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int crime_int = 0;
 
 	maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
@@ -319,8 +326,9 @@ static void disable_maceisa_irq(unsigned int irq)
 	flush_mace_bus();
 }
 
-static void mask_and_ack_maceisa_irq(unsigned int irq)
+static void mask_and_ack_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mace_int;
 
 	/* edge triggered */
@@ -328,13 +336,13 @@ static void mask_and_ack_maceisa_irq(unsigned int irq)
 	mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
 	mace->perif.ctrl.istat = mace_int;
 
-	disable_maceisa_irq(irq);
+	disable_maceisa_irq(desc);
 }
 
-static void end_maceisa_irq(unsigned irq)
+static void end_maceisa_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_maceisa_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_maceisa_irq(desc);
 }
 
 static struct irq_chip ip32_maceisa_level_interrupt = {
@@ -359,16 +367,18 @@ static struct irq_chip ip32_maceisa_edge_interrupt = {
  * bits 0-3 and 7 in the CRIME register.
  */
 
-static void enable_mace_irq(unsigned int irq)
+static void enable_mace_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask |= (1 << bit);
 	crime->imask = crime_mask;
 }
 
-static void disable_mace_irq(unsigned int irq)
+static void disable_mace_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask &= ~(1 << bit);
@@ -376,10 +386,10 @@ static void disable_mace_irq(unsigned int irq)
 	flush_crime_bus();
 }
 
-static void end_mace_irq(unsigned int irq)
+static void end_mace_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_mace_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq(desc);
 }
 
 static struct irq_chip ip32_mace_interrupt = {
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 06e25d9..1fb5d8c 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -46,12 +46,12 @@
  */
 
 
-static void end_bcm1480_irq(unsigned int irq);
-static void enable_bcm1480_irq(unsigned int irq);
-static void disable_bcm1480_irq(unsigned int irq);
-static void ack_bcm1480_irq(unsigned int irq);
+static void end_bcm1480_irq(struct irq_desc *desc);
+static void enable_bcm1480_irq(struct irq_desc *desc);
+static void disable_bcm1480_irq(struct irq_desc *desc);
+static void ack_bcm1480_irq(struct irq_desc *desc);
 #ifdef CONFIG_SMP
-static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int bcm1480_set_affinity(struct irq_desc *desc, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_PCI
@@ -110,8 +110,9 @@ void bcm1480_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bcm1480_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	int i = 0, old_cpu, cpu, int_on, k;
 	u64 cur_ints;
 	unsigned long flags;
@@ -157,19 +158,22 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 /*****************************************************************************/
 
-static void disable_bcm1480_irq(unsigned int irq)
+static void disable_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
 }
 
-static void enable_bcm1480_irq(unsigned int irq)
+static void enable_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
 }
 
 
-static void ack_bcm1480_irq(unsigned int irq)
+static void ack_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 pending;
 	unsigned int irq_dirty;
 	int k;
@@ -219,11 +223,11 @@ static void ack_bcm1480_irq(unsigned int irq)
 }
 
 
-static void end_bcm1480_irq(unsigned int irq)
+static void end_bcm1480_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	unsigned int irq = desc->irq;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
 		bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
-	}
 }
 
 
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index ab44a2f..0fcde43 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -45,12 +45,12 @@
  */
 
 
-static void end_sb1250_irq(unsigned int irq);
-static void enable_sb1250_irq(unsigned int irq);
-static void disable_sb1250_irq(unsigned int irq);
-static void ack_sb1250_irq(unsigned int irq);
+static void end_sb1250_irq(struct irq_desc *desc);
+static void enable_sb1250_irq(struct irq_desc *desc);
+static void disable_sb1250_irq(struct irq_desc *desc);
+static void ack_sb1250_irq(struct irq_desc *desc);
 #ifdef CONFIG_SMP
-static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int sb1250_set_affinity(struct irq_desc *desc, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
@@ -103,8 +103,9 @@ void sb1250_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int sb1250_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	int i = 0, old_cpu, cpu, int_on;
 	u64 cur_ints;
 	unsigned long flags;
@@ -145,19 +146,22 @@ static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 /*****************************************************************************/
 
-static void disable_sb1250_irq(unsigned int irq)
+static void disable_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sb1250_mask_irq(sb1250_irq_owner[irq], irq);
 }
 
-static void enable_sb1250_irq(unsigned int irq)
+static void enable_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
 }
 
 
-static void ack_sb1250_irq(unsigned int irq)
+static void ack_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 #ifdef CONFIG_SIBYTE_HAS_LDT
 	u64 pending;
 
@@ -201,11 +205,11 @@ static void ack_sb1250_irq(unsigned int irq)
 }
 
 
-static void end_sb1250_irq(unsigned int irq)
+static void end_sb1250_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	unsigned int irq = desc->irq;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
 		sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
-	}
 }
 
 
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index e698089..0753f2c 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -167,23 +167,25 @@ static u32 a20r_ack_hwint(void)
 	return status;
 }
 
-static inline void unmask_a20r_irq(unsigned int irq)
+static inline void unmask_a20r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
 	irq_enable_hazard();
 }
 
-static inline void mask_a20r_irq(unsigned int irq)
+static inline void mask_a20r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
 	irq_disable_hazard();
 }
 
-static void end_a20r_irq(unsigned int irq)
+static void end_a20r_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
 		a20r_ack_hwint();
-		unmask_a20r_irq(irq);
+		unmask_a20r_irq(desc);
 	}
 }
 
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 51e62bb..671e3f8 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -193,24 +193,26 @@ static struct pci_controller sni_controller = {
 	.io_map_base    = SNI_PORT_BASE
 };
 
-static void enable_pcimt_irq(unsigned int irq)
+static void enable_pcimt_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
 
 	*(volatile u8 *) PCIMT_IRQSEL |= mask;
 }
 
-void disable_pcimt_irq(unsigned int irq)
+void disable_pcimt_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
 
 	*(volatile u8 *) PCIMT_IRQSEL &= mask;
 }
 
-static void end_pcimt_irq(unsigned int irq)
+static void end_pcimt_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pcimt_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcimt_irq(desc);
 }
 
 static struct irq_chip pcimt_irq_type = {
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index f4699d3..cae4b89 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -155,24 +155,26 @@ static struct pci_controller sni_pcit_controller = {
 	.io_map_base    = SNI_PORT_BASE
 };
 
-static void enable_pcit_irq(unsigned int irq)
+static void enable_pcit_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
 
 	*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
 }
 
-void disable_pcit_irq(unsigned int irq)
+void disable_pcit_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
 
 	*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
 }
 
-void end_pcit_irq(unsigned int irq)
+void end_pcit_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pcit_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcit_irq(desc);
 }
 
 static struct irq_chip pcit_irq_type = {
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 90c558f..14d364a 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -154,8 +154,9 @@ static __iomem u8 *rm200_pic_slave;
 #define cached_master_mask	(rm200_cached_irq_mask)
 #define cached_slave_mask	(rm200_cached_irq_mask >> 8)
 
-static void sni_rm200_disable_8259A_irq(unsigned int irq)
+static void sni_rm200_disable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	unsigned long flags;
 
@@ -170,8 +171,9 @@ static void sni_rm200_disable_8259A_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 }
 
-static void sni_rm200_enable_8259A_irq(unsigned int irq)
+static void sni_rm200_enable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	unsigned long flags;
 
@@ -209,8 +211,9 @@ static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-void sni_rm200_mask_and_ack_8259A(unsigned int irq)
+void sni_rm200_mask_and_ack_8259A(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irqmask;
 	unsigned long flags;
 
@@ -428,24 +431,26 @@ void __init sni_rm200_i8259_irqs(void)
 #define SNI_RM200_INT_START  24
 #define SNI_RM200_INT_END    28
 
-static void enable_rm200_irq(unsigned int irq)
+static void enable_rm200_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
 
 	*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
 }
 
-void disable_rm200_irq(unsigned int irq)
+void disable_rm200_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
 
 	*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
 }
 
-void end_rm200_irq(unsigned int irq)
+void end_rm200_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_rm200_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_rm200_irq(desc);
 }
 
 static struct irq_chip rm200_irq_type = {
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
index 013213a..e66f101 100644
--- a/arch/mips/txx9/generic/irq_tx4939.c
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -49,8 +49,9 @@ static struct {
 	unsigned char mode;
 } tx4939irq[TX4939_NUM_IR] __read_mostly;
 
-static void tx4939_irq_unmask(unsigned int irq)
+static void tx4939_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *lvlp;
 	int ofs;
@@ -67,8 +68,9 @@ static void tx4939_irq_unmask(unsigned int irq)
 		     lvlp);
 }
 
-static inline void tx4939_irq_mask(unsigned int irq)
+static inline void tx4939_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *lvlp;
 	int ofs;
@@ -86,11 +88,12 @@ static inline void tx4939_irq_mask(unsigned int irq)
 	mmiowb();
 }
 
-static void tx4939_irq_mask_ack(unsigned int irq)
+static void tx4939_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 
-	tx4939_irq_mask(irq);
+	tx4939_irq_mask(desc);
 	if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
 		irq_nr--;
 		/* clear edge detection */
@@ -100,8 +103,9 @@ static void tx4939_irq_mask_ack(unsigned int irq)
 	}
 }
 
-static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int tx4939_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 cr;
 	u32 __iomem *crp;
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
index 6ec626c..b613c2e 100644
--- a/arch/mips/txx9/jmr3927/irq.c
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -46,8 +46,9 @@
  * CP0_STATUS is a thread's resource (saved/restored on context switch).
  * So disable_irq/enable_irq MUST handle IOC/IRC registers.
  */
-static void mask_irq_ioc(unsigned int irq)
+static void mask_irq_ioc(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* 0: mask */
 	unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
 	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
@@ -56,8 +57,9 @@ static void mask_irq_ioc(unsigned int irq)
 	/* flush write buffer */
 	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
 }
-static void unmask_irq_ioc(unsigned int irq)
+static void unmask_irq_ioc(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* 0: mask */
 	unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
 	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
index 9c14ebb..136ae1e 100644
--- a/arch/mips/txx9/rbtx4927/irq.c
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -116,8 +116,8 @@
 #include <asm/txx9/generic.h>
 #include <asm/txx9/rbtx4927.h>
 
-static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
-static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_enable(struct irq_desc *desc);
+static void toshiba_rbtx4927_irq_ioc_disable(struct irq_desc *desc);
 
 #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
 static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
@@ -154,8 +154,9 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void)
 	set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
 }
 
-static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
+static void toshiba_rbtx4927_irq_ioc_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4927_imask_addr);
@@ -163,8 +164,9 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
 	writeb(v, rbtx4927_imask_addr);
 }
 
-static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
+static void toshiba_rbtx4927_irq_ioc_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4927_imask_addr);
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
index 7d21bef..92cdda6 100644
--- a/arch/mips/txx9/rbtx4938/irq.c
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -68,8 +68,8 @@
 #include <asm/txx9/generic.h>
 #include <asm/txx9/rbtx4938.h>
 
-static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
-static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_enable(struct irq_desc *desc);
+static void toshiba_rbtx4938_irq_ioc_disable(struct irq_desc *desc);
 
 #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
 static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
@@ -105,8 +105,9 @@ toshiba_rbtx4938_irq_ioc_init(void)
 }
 
 static void
-toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
+toshiba_rbtx4938_irq_ioc_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4938_imask_addr);
@@ -116,8 +117,9 @@ toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
 }
 
 static void
-toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
+toshiba_rbtx4938_irq_ioc_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4938_imask_addr);
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
index 500cc0a..c3798f5 100644
--- a/arch/mips/txx9/rbtx4939/irq.c
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -18,15 +18,17 @@
  * RBTX4939 IOC controller definition
  */
 
-static void rbtx4939_ioc_irq_unmask(unsigned int irq)
+static void rbtx4939_ioc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ioc_nr = irq - RBTX4939_IRQ_IOC;
 
 	writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
 }
 
-static void rbtx4939_ioc_irq_mask(unsigned int irq)
+static void rbtx4939_ioc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ioc_nr = irq - RBTX4939_IRQ_IOC;
 
 	writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
index 6153b6a..cc042eb 100644
--- a/arch/mips/vr41xx/common/icu.c
+++ b/arch/mips/vr41xx/common/icu.c
@@ -442,13 +442,15 @@ void vr41xx_disable_bcuint(void)
 
 EXPORT_SYMBOL(vr41xx_disable_bcuint);
 
-static void disable_sysint1_irq(unsigned int irq)
+static void disable_sysint1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
-static void enable_sysint1_irq(unsigned int irq)
+static void enable_sysint1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
@@ -460,13 +462,15 @@ static struct irq_chip sysint1_irq_type = {
 	.unmask		= enable_sysint1_irq,
 };
 
-static void disable_sysint2_irq(unsigned int irq)
+static void disable_sysint2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
-static void enable_sysint2_irq(unsigned int irq)
+static void enable_sysint2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index bef0687..c60b2fc 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -74,10 +74,10 @@ static void irq_dispatch(unsigned int irq)
 		int ret;
 		desc = irq_desc + source_irq;
 		if (desc->chip->mask_ack)
-			desc->chip->mask_ack(source_irq);
+			desc->chip->mask_ack(desc);
 		else {
-			desc->chip->mask(source_irq);
-			desc->chip->ack(source_irq);
+			desc->chip->mask(desc);
+			desc->chip->ack(desc);
 		}
 		ret = cascade->get_irq(irq);
 		irq = ret;
@@ -86,7 +86,7 @@ static void irq_dispatch(unsigned int irq)
 		else
 			irq_dispatch(irq);
 		if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-			desc->chip->unmask(source_irq);
+			desc->chip->unmask(desc);
 	} else
 		do_IRQ(irq);
 }
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index bc98665..ccae1ad 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -22,36 +22,45 @@ atomic_t irq_err_count;
 /*
  * MN10300 interrupt controller operations
  */
-static void mn10300_cpupic_ack(unsigned int irq)
+static void mn10300_cpupic_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp;
 	*(volatile u8 *) &GxICR(irq) = GxICR_DETECT;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_mask(unsigned int irq)
+static void mn10300_cpupic_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL);
 	tmp = GxICR(irq);
 }
+static void mn10300_cpupic_mask_desc(struct irq_desc *desc)
+{
+	mn10300_cpupic_mask(desc);
+}
 
-static void mn10300_cpupic_mask_ack(unsigned int irq)
+static void mn10300_cpupic_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_unmask(unsigned int irq)
+static void mn10300_cpupic_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_unmask_clear(unsigned int irq)
+static void mn10300_cpupic_unmask_clear(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* the MN10300 PIC latches its interrupt request bit, even after the
 	 * device has ceased to assert its interrupt line and the interrupt
 	 * channel has been disabled in the PIC, so for level-triggered
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index ef34d5a..8cb05fe 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -325,14 +325,15 @@ struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {
  * note that we can't just leave the line enabled as the baud rate timer *also*
  * generates interrupts
  */
-static void mn10300_serial_mask_ack(unsigned int irq)
+static void mn10300_serial_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp;
 	GxICR(irq) = GxICR_LEVEL_6;
 	tmp = GxICR(irq); /* flush write buffer */
 }
 
-static void mn10300_serial_nop(unsigned int irq)
+static void mn10300_serial_nop(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h
index dfa26b6..2a6516c 100644
--- a/arch/parisc/include/asm/irq.h
+++ b/arch/parisc/include/asm/irq.h
@@ -37,10 +37,11 @@ struct irq_chip;
  * Some useful "we don't have to do anything here" handlers.  Should
  * probably be provided by the generic code.
  */
-void no_ack_irq(unsigned int irq);
-void no_end_irq(unsigned int irq);
-void cpu_ack_irq(unsigned int irq);
-void cpu_end_irq(unsigned int irq);
+struct irq_desc;
+void no_ack_irq(struct irq_desc *desc);
+void no_end_irq(struct irq_desc *desc);
+void cpu_ack_irq(struct irq_desc *desc);
+void cpu_end_irq(struct irq_desc *desc);
 
 extern int txn_alloc_irq(unsigned int nbits);
 extern int txn_claim_irq(int);
@@ -49,7 +50,7 @@ extern unsigned long txn_alloc_addr(unsigned int);
 extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 
 extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
-extern int cpu_check_affinity(unsigned int irq, const struct cpumask *dest);
+extern int cpu_check_affinity(struct irq_desc *desc, const struct cpumask *dest);
 
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index efbcee5..bc47d05 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -52,8 +52,9 @@ static volatile unsigned long cpu_eiem = 0;
 */
 static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
 
-static void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem &= ~eirr_bit;
@@ -63,8 +64,9 @@ static void cpu_disable_irq(unsigned int irq)
 	 * then gets disabled */
 }
 
-static void cpu_enable_irq(unsigned int irq)
+static void cpu_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem |= eirr_bit;
@@ -75,17 +77,18 @@ static void cpu_enable_irq(unsigned int irq)
 	smp_send_all_nop();
 }
 
-static unsigned int cpu_startup_irq(unsigned int irq)
+static unsigned int cpu_startup_irq(struct irq_desc *desc)
 {
-	cpu_enable_irq(irq);
+	cpu_enable_irq(desc);
 	return 0;
 }
 
-void no_ack_irq(unsigned int irq) { }
-void no_end_irq(unsigned int irq) { }
+void no_ack_irq(struct irq_desc *desc) { }
+void no_end_irq(struct irq_desc *desc) { }
 
-void cpu_ack_irq(unsigned int irq)
+void cpu_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = EIEM_MASK(irq);
 	int cpu = smp_processor_id();
 
@@ -99,8 +102,9 @@ void cpu_ack_irq(unsigned int irq)
 	mtctl(mask, 23);
 }
 
-void cpu_end_irq(unsigned int irq)
+void cpu_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = EIEM_MASK(irq);
 	int cpu = smp_processor_id();
 
@@ -112,15 +116,16 @@ void cpu_end_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
+int cpu_check_affinity(struct irq_desc *desc, const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu_dest;
 
 	/* timer and ipi have to always be received on all CPUs */
 	if (CHECK_IRQ_PER_CPU(irq)) {
 		/* Bad linux design decision.  The mask has already
 		 * been set; we must reset it */
-		cpumask_setall(irq_desc[irq].affinity);
+		cpumask_setall(desc->affinity);
 		return -EINVAL;
 	}
 
@@ -130,15 +135,15 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
 	return cpu_dest;
 }
 
-static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
+static int cpu_set_affinity_irq(struct irq_desc *desc, const struct cpumask *dest)
 {
 	int cpu_dest;
 
-	cpu_dest = cpu_check_affinity(irq, dest);
+	cpu_dest = cpu_check_affinity(desc, dest);
 	if (cpu_dest < 0)
 		return -1;
 
-	cpumask_copy(irq_desc[irq].affinity, dest);
+	cpumask_copy(desc->affinity, dest);
 
 	return 0;
 }
@@ -242,15 +247,17 @@ int show_interrupts(struct seq_file *p, void *v)
 
 int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 {
-	if (irq_desc[irq].action)
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (desc->action)
 		return -EBUSY;
-	if (irq_desc[irq].chip != &cpu_interrupt_type)
+	if (desc->chip != &cpu_interrupt_type)
 		return -EBUSY;
 
 	if (type) {
-		irq_desc[irq].chip = type;
-		irq_desc[irq].chip_data = data;
-		cpu_interrupt_type.enable(irq);
+		desc->chip = type;
+		desc->chip_data = data;
+		cpu_interrupt_type.enable(desc);
 	}
 	return 0;
 }
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 61913d9..7f56770 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -470,11 +470,11 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
 void smp_mpic_message_pass(int target, int msg);
 
 /* Unmask a specific virq */
-extern void mpic_unmask_irq(unsigned int irq);
+extern void mpic_unmask_irq(struct irq_desc *desc);
 /* Mask a specific virq */
-extern void mpic_mask_irq(unsigned int irq);
+extern void mpic_mask_irq(struct irq_desc *desc);
 /* EOI a specific virq */
-extern void mpic_end_irq(unsigned int irq);
+extern void mpic_end_irq(struct irq_desc *desc);
 
 /* Fetch interrupt from a given mpic */
 extern unsigned int mpic_get_one_irq(struct mpic *mpic);
diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h
index cf51966..ffd0086 100644
--- a/arch/powerpc/include/asm/qe_ic.h
+++ b/arch/powerpc/include/asm/qe_ic.h
@@ -107,7 +107,7 @@ static inline void qe_ic_cascade_low_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static inline void qe_ic_cascade_high_mpic(unsigned int irq,
@@ -119,7 +119,7 @@ static inline void qe_ic_cascade_high_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
@@ -135,7 +135,7 @@ static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* _ASM_POWERPC_QE_IC_H */
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 6f4613d..e5ccfb2 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -376,10 +376,10 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
 		struct irq_desc *desc = irq_to_desc(i);
 
 		if (desc->status & IRQ_INPROGRESS)
-			desc->chip->eoi(i);
+			desc->chip->eoi(desc);
 
 		if (!(desc->status & IRQ_DISABLED))
-			desc->chip->disable(i);
+			desc->chip->disable(desc);
 	}
 
 	/*
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index cafd378..bc7a593 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -309,7 +309,7 @@ void fixup_irqs(cpumask_t map)
 			mask = map;
 		}
 		if (desc->chip->set_affinity)
-			desc->chip->set_affinity(irq, &mask);
+			desc->chip->set_affinity(desc, &mask);
 		else if (desc->action && !(warned++))
 			printk("Cannot set affinity for irq %i\n", irq);
 	}
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 4ecf4cf..d754acd 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -59,8 +59,9 @@ irq_to_pic_bit(unsigned int irq)
 }
 
 static void
-cpld_mask_irq(unsigned int irq)
+cpld_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
@@ -69,8 +70,9 @@ cpld_mask_irq(unsigned int irq)
 }
 
 static void
-cpld_unmask_irq(unsigned int irq)
+cpld_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 0bac3a3..948a09d 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -49,26 +49,28 @@ struct media5200_irq {
 };
 struct media5200_irq media5200_irq;
 
-static void media5200_irq_unmask(unsigned int virq)
+static void media5200_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 val;
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
+	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[irq].hwirq);
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
 
-static void media5200_irq_mask(unsigned int virq)
+static void media5200_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 val;
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
+	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[irq].hwirq));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
@@ -87,7 +89,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	/* Mask off the cascaded IRQ */
 	raw_spin_lock(&desc->lock);
-	desc->chip->mask(virq);
+	desc->chip->mask(desc);
 	raw_spin_unlock(&desc->lock);
 
 	/* Ask the FPGA for IRQ status.  If 'val' is 0, then no irqs
@@ -105,9 +107,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	/* Processing done; can reenable the cascade now */
 	raw_spin_lock(&desc->lock);
-	desc->chip->ack(virq);
+	desc->chip->ack(desc);
 	if (!(desc->status & IRQ_DISABLED))
-		desc->chip->unmask(virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 5d7cc88..5de11ef 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -133,9 +133,10 @@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
  * Cascaded interrupt controller hooks
  */
 
-static void mpc52xx_gpt_irq_unmask(unsigned int virq)
+static void mpc52xx_gpt_irq_unmask(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&gpt->lock, flags);
@@ -143,9 +144,10 @@ static void mpc52xx_gpt_irq_unmask(unsigned int virq)
 	spin_unlock_irqrestore(&gpt->lock, flags);
 }
 
-static void mpc52xx_gpt_irq_mask(unsigned int virq)
+static void mpc52xx_gpt_irq_mask(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&gpt->lock, flags);
@@ -153,16 +155,18 @@ static void mpc52xx_gpt_irq_mask(unsigned int virq)
 	spin_unlock_irqrestore(&gpt->lock, flags);
 }
 
-static void mpc52xx_gpt_irq_ack(unsigned int virq)
+static void mpc52xx_gpt_irq_ack(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 
 	out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
 }
 
-static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_gpt_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u32 reg;
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 4bf4bf7..bee1838 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -155,8 +155,9 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
 /*
  * IRQ[0-3] interrupt irq_chip
  */
-static void mpc52xx_extirq_mask(unsigned int virq)
+static void mpc52xx_extirq_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -166,8 +167,9 @@ static void mpc52xx_extirq_mask(unsigned int virq)
 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
 }
 
-static void mpc52xx_extirq_unmask(unsigned int virq)
+static void mpc52xx_extirq_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -177,8 +179,9 @@ static void mpc52xx_extirq_unmask(unsigned int virq)
 	io_be_setbit(&intr->ctrl, 11 - l2irq);
 }
 
-static void mpc52xx_extirq_ack(unsigned int virq)
+static void mpc52xx_extirq_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -188,8 +191,9 @@ static void mpc52xx_extirq_ack(unsigned int virq)
 	io_be_setbit(&intr->ctrl, 27-l2irq);
 }
 
-static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_extirq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	u32 ctrl_reg, type;
 	int irq;
 	int l2irq;
@@ -230,13 +234,14 @@ static struct irq_chip mpc52xx_extirq_irqchip = {
 /*
  * Main interrupt irq_chip
  */
-static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_null_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
 	return 0; /* Do nothing so that the sense mask will get updated */
 }
 
-static void mpc52xx_main_mask(unsigned int virq)
+static void mpc52xx_main_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -246,8 +251,9 @@ static void mpc52xx_main_mask(unsigned int virq)
 	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
-static void mpc52xx_main_unmask(unsigned int virq)
+static void mpc52xx_main_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -268,8 +274,9 @@ static struct irq_chip mpc52xx_main_irqchip = {
 /*
  * Peripherals interrupt irq_chip
  */
-static void mpc52xx_periph_mask(unsigned int virq)
+static void mpc52xx_periph_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -279,8 +286,9 @@ static void mpc52xx_periph_mask(unsigned int virq)
 	io_be_setbit(&intr->per_mask, 31 - l2irq);
 }
 
-static void mpc52xx_periph_unmask(unsigned int virq)
+static void mpc52xx_periph_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -301,8 +309,9 @@ static struct irq_chip mpc52xx_periph_irqchip = {
 /*
  * SDMA interrupt irq_chip
  */
-static void mpc52xx_sdma_mask(unsigned int virq)
+static void mpc52xx_sdma_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -312,8 +321,9 @@ static void mpc52xx_sdma_mask(unsigned int virq)
 	io_be_setbit(&sdma->IntMask, l2irq);
 }
 
-static void mpc52xx_sdma_unmask(unsigned int virq)
+static void mpc52xx_sdma_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -323,8 +333,9 @@ static void mpc52xx_sdma_unmask(unsigned int virq)
 	io_be_clrbit(&sdma->IntMask, l2irq);
 }
 
-static void mpc52xx_sdma_ack(unsigned int virq)
+static void mpc52xx_sdma_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index d4a09f8..a44214d 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -38,8 +38,9 @@ struct pq2ads_pci_pic {
 
 #define NUM_IRQS 32
 
-static void pq2ads_pci_mask_irq(unsigned int virq)
+static void pq2ads_pci_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
 	int irq = NUM_IRQS - virq_to_hw(virq) - 1;
 
@@ -54,8 +55,9 @@ static void pq2ads_pci_mask_irq(unsigned int virq)
 	}
 }
 
-static void pq2ads_pci_unmask_irq(unsigned int virq)
+static void pq2ads_pci_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
 	int irq = NUM_IRQS - virq_to_hw(virq) - 1;
 
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
index f4d36b5..c6f4825 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -61,7 +61,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init ksi8560_pic_init(void)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 9438a89..833ab1c 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -55,7 +55,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 544011a..c27ce8a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -52,7 +52,7 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	if (cascade_irq != NO_IRQ) {
 		generic_handle_irq(cascade_irq);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif	/* CONFIG_PPC_I8259 */
 
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index a5ad1c7..b66dd9f 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -46,7 +46,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index d48527f..c8a131a 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -103,12 +103,13 @@ void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
 
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 
 }
 
-static void socrates_fpga_pic_ack(unsigned int virq)
+static void socrates_fpga_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq, irq_line;
 	uint32_t mask;
@@ -124,8 +125,9 @@ static void socrates_fpga_pic_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_mask(unsigned int virq)
+static void socrates_fpga_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -142,8 +144,9 @@ static void socrates_fpga_pic_mask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_mask_ack(unsigned int virq)
+static void socrates_fpga_pic_mask_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -161,8 +164,9 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_unmask(unsigned int virq)
+static void socrates_fpga_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -179,8 +183,9 @@ static void socrates_fpga_pic_unmask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_eoi(unsigned int virq)
+static void socrates_fpga_pic_eoi(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -197,9 +202,10 @@ static void socrates_fpga_pic_eoi(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static int socrates_fpga_pic_set_type(unsigned int virq,
+static int socrates_fpga_pic_set_type(struct irq_desc *desc,
 		unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int polarity;
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index bc33d18..cfea131 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -51,7 +51,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif /* CONFIG_CPM2 */
 
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 5b0ab99..462cc1d 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -49,7 +49,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif /* CONFIG_CPM2 */
 
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 6df9e25..7af4ad4 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -106,12 +106,13 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 
 }
 
-static void gef_pic_mask(unsigned int virq)
+static void gef_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	u32 mask;
@@ -125,16 +126,17 @@ static void gef_pic_mask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
 }
 
-static void gef_pic_mask_ack(unsigned int virq)
+static void gef_pic_mask_ack(struct irq_desc *desc)
 {
 	/* Don't think we actually have to do anything to ack an interrupt,
 	 * we just need to clear down the devices interrupt and it will go away
 	 */
-	gef_pic_mask(virq);
+	gef_pic_mask(desc);
 }
 
-static void gef_pic_unmask(unsigned int virq)
+static void gef_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	u32 mask;
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
index 668275d..4cdaf8a 100644
--- a/arch/powerpc/platforms/86xx/pic.c
+++ b/arch/powerpc/platforms/86xx/pic.c
@@ -22,7 +22,7 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif	/* CONFIG_PPC_I8259 */
 
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 242954c..f1ec06b 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -225,9 +225,9 @@ static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
 		struct irq_desc *cdesc = irq_to_desc(cascade_irq);
 
 		generic_handle_irq(cascade_irq);
-		cdesc->chip->eoi(cascade_irq);
+		cdesc->chip->eoi(cdesc);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /* Initialize the internal interrupt controllers.  The number of
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 96fe896..64578d4 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -144,7 +144,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 		msic->read_offset &= MSIC_FIFO_SIZE_MASK;
 	}
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static struct axon_msic *find_msi_translator(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 682af97..fdb1c60 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -61,8 +61,9 @@ static inline void beatic_update_irq_mask(unsigned int irq_plug)
 		panic("Failed to set mask IRQ!");
 }
 
-static void beatic_mask_irq(unsigned int irq_plug)
+static void beatic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -71,8 +72,9 @@ static void beatic_mask_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_unmask_irq(unsigned int irq_plug)
+static void beatic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -81,8 +83,9 @@ static void beatic_unmask_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_ack_irq(unsigned int irq_plug)
+static void beatic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -91,8 +94,9 @@ static void beatic_ack_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_end_irq(unsigned int irq_plug)
+static void beatic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	s64 err;
 	unsigned long flags;
 
@@ -232,7 +236,7 @@ unsigned int beatic_get_irq(void)
 
 	ret = beatic_get_irq_plug();
 	if (ret != NO_IRQ)
-		beatic_ack_irq(ret);
+		beatic_ack_irq(irq_to_desc(ret));
 	return ret;
 }
 
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 10eb1a4..2ea5935 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -72,15 +72,15 @@ static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
 		return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
 }
 
-static void iic_mask(unsigned int irq)
+static void iic_mask(struct irq_desc *desc)
 {
 }
 
-static void iic_unmask(unsigned int irq)
+static void iic_unmask(struct irq_desc *desc)
 {
 }
 
-static void iic_eoi(unsigned int irq)
+static void iic_eoi(struct irq_desc *desc)
 {
 	struct iic *iic = &__get_cpu_var(cpu_iic);
 	out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
@@ -95,7 +95,7 @@ static struct irq_chip iic_chip = {
 };
 
 
-static void iic_ioexc_eoi(unsigned int irq)
+static void iic_ioexc_eoi(struct irq_desc *desc)
 {
 }
 
@@ -128,7 +128,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
 		if (ack)
 			out_be64(&node_iic->iic_is, ack);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 
@@ -275,7 +275,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
 
 	desc->status &= ~IRQ_INPROGRESS;
 out_eoi:
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 5930536..7ca342c 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -182,7 +182,7 @@ static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
 	virq = mpic_get_one_irq(mpic);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init mpic_init_IRQ(void)
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 5876e88..d80fd72 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -79,24 +79,27 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
 	return pic->regs + TIR_CFGA + 8 * src;
 }
 
-static void spider_unmask_irq(unsigned int virq)
+static void spider_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
 
 	out_be32(cfg, in_be32(cfg) | 0x30000000u);
 }
 
-static void spider_mask_irq(unsigned int virq)
+static void spider_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
 
 	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
 }
 
-static void spider_ack_irq(unsigned int virq)
+static void spider_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -113,13 +116,13 @@ static void spider_ack_irq(unsigned int virq)
 	out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
 }
 
-static int spider_set_irq_type(unsigned int virq, unsigned int type)
+static int spider_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int virq = desc->irq;
 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	unsigned int hw = irq_map[virq].hwirq;
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
-	struct irq_desc *desc = irq_to_desc(virq);
 	u32 old_mask;
 	u32 ic;
 
@@ -217,7 +220,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
 		virq = irq_linear_revmap(pic->host, cs);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /* For hooking up the cascace we have a problem. Our device-tree is
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 8f41685..cab9626 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -369,7 +369,7 @@ static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /*
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index c278bd3..74d93d8 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -46,8 +46,9 @@
  *
  */
 
-static void flipper_pic_mask_and_ack(unsigned int virq)
+static void flipper_pic_mask_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 	u32 mask = 1 << irq;
@@ -57,8 +58,9 @@ static void flipper_pic_mask_and_ack(unsigned int virq)
 	out_be32(io_base + FLIPPER_ICR, mask);
 }
 
-static void flipper_pic_ack(unsigned int virq)
+static void flipper_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
@@ -66,16 +68,18 @@ static void flipper_pic_ack(unsigned int virq)
 	out_be32(io_base + FLIPPER_ICR, 1 << irq);
 }
 
-static void flipper_pic_mask(unsigned int virq)
+static void flipper_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
 	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
 }
 
-static void flipper_pic_unmask(unsigned int virq)
+static void flipper_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index a771f91..58628f7 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -41,36 +41,40 @@
  *
  */
 
-static void hlwd_pic_mask_and_ack(unsigned int virq)
+static void hlwd_pic_mask_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 	u32 mask = 1 << irq;
 
 	clrbits32(io_base + HW_BROADWAY_IMR, mask);
 	out_be32(io_base + HW_BROADWAY_ICR, mask);
 }
 
-static void hlwd_pic_ack(unsigned int virq)
+static void hlwd_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
 }
 
-static void hlwd_pic_mask(unsigned int virq)
+static void hlwd_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
 }
 
-static void hlwd_pic_unmask(unsigned int virq)
+static void hlwd_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
 }
@@ -133,7 +137,7 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 	unsigned int virq;
 
 	raw_spin_lock(&desc->lock);
-	desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
+	desc->chip->mask(desc); /* IRQ_LEVEL */
 	raw_spin_unlock(&desc->lock);
 
 	virq = __hlwd_pic_get_irq(irq_host);
@@ -143,9 +147,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 		pr_err("spurious interrupt!\n");
 
 	raw_spin_lock(&desc->lock);
-	desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
+	desc->chip->ack(desc); /* IRQ_LEVEL */
 	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-		desc->chip->unmask(cascade_virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index ba446bf..8f64743 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -167,8 +167,9 @@ static void pci_event_handler(struct HvLpEvent *event)
  * This will be called by device drivers (via enable_IRQ)
  * to enable INTA in the bridge interrupt status register.
  */
-static void iseries_enable_IRQ(unsigned int irq)
+static void iseries_enable_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -184,8 +185,9 @@ static void iseries_enable_IRQ(unsigned int irq)
 }
 
 /* This is called by iseries_activate_IRQs */
-static unsigned int iseries_startup_IRQ(unsigned int irq)
+static unsigned int iseries_startup_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -200,7 +202,7 @@ static unsigned int iseries_startup_IRQ(unsigned int irq)
 	/* Unmask bridge interrupts in the FISR */
 	mask = 0x01010000 << function;
 	HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
-	iseries_enable_IRQ(irq);
+	iseries_enable_IRQ(desc);
 	return 0;
 }
 
@@ -218,15 +220,16 @@ void __init iSeries_activate_IRQs()
 
 		if (desc && desc->chip && desc->chip->startup) {
 			raw_spin_lock_irqsave(&desc->lock, flags);
-			desc->chip->startup(irq);
+			desc->chip->startup(desc);
 			raw_spin_unlock_irqrestore(&desc->lock, flags);
 		}
 	}
 }
 
 /*  this is not called anywhere currently */
-static void iseries_shutdown_IRQ(unsigned int irq)
+static void iseries_shutdown_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -248,8 +251,9 @@ static void iseries_shutdown_IRQ(unsigned int irq)
  * This will be called by device drivers (via disable_IRQ)
  * to disable INTA in the bridge interrupt status register.
  */
-static void iseries_disable_IRQ(unsigned int irq)
+static void iseries_disable_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -264,8 +268,9 @@ static void iseries_disable_IRQ(unsigned int irq)
 	HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask);
 }
 
-static void iseries_end_IRQ(unsigned int irq)
+static void iseries_end_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
 
 	HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 242f809..98a3573 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -239,7 +239,7 @@ static __init void pas_init_IRQ(void)
 		nmi_virq = irq_create_mapping(NULL, *nmiprop);
 		mpic_irq_set_priority(nmi_virq, 15);
 		set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
-		mpic_unmask_irq(nmi_virq);
+		mpic_unmask_irq(irq_to_desc(nmi_virq));
 	}
 
 	of_node_put(mpic_node);
@@ -265,7 +265,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
 	if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
 		printk(KERN_ERR "NMI delivered\n");
 		debugger(regs);
-		mpic_end_irq(nmi_virq);
+		mpic_end_irq(irq_to_desc(nmi_virq));
 		goto out;
 	}
 
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 630a533..5737fae 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -25,6 +25,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/module.h>
+#include <linux/irq.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
@@ -78,8 +79,9 @@ static void __pmac_retrigger(unsigned int irq_nr)
 	}
 }
 
-static void pmac_mask_and_ack_irq(unsigned int virq)
+static void pmac_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
@@ -100,8 +102,9 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_ack_irq(unsigned int virq)
+static void pmac_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
@@ -145,8 +148,9 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
 /* When an irq gets requested for the first client, if it's an
  * edge interrupt, we clear any previous one on the controller
  */
-static unsigned int pmac_startup_irq(unsigned int virq)
+static unsigned int pmac_startup_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
@@ -162,8 +166,9 @@ static unsigned int pmac_startup_irq(unsigned int virq)
 	return 0;
 }
 
-static void pmac_mask_irq(unsigned int virq)
+static void pmac_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -173,8 +178,9 @@ static void pmac_mask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_unmask_irq(unsigned int virq)
+static void pmac_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -184,8 +190,9 @@ static void pmac_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static int pmac_retrigger(unsigned int virq)
+static int pmac_retrigger(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
@@ -437,7 +444,7 @@ static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = mpic_get_one_irq(mpic);
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
@@ -647,7 +654,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
 	mb();
 	for (i = 0; i < max_real_irqs; ++i)
 		if (test_bit(i, sleep_save_mask))
-			pmac_unmask_irq(i);
+			pmac_unmask_irq(irq_do_desc(i));
 
 	return 0;
 }
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 59d9712..024680f 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -99,9 +99,10 @@ static DEFINE_PER_CPU(struct ps3_private, ps3_private);
  * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
  */
 
-static void ps3_chip_mask(unsigned int virq)
+static void ps3_chip_mask(struct irq_desc *desc)
 {
-	struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
@@ -120,9 +121,10 @@ static void ps3_chip_mask(unsigned int virq)
  * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
  */
 
-static void ps3_chip_unmask(unsigned int virq)
+static void ps3_chip_unmask(struct irq_desc *desc)
 {
-	struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
@@ -141,9 +143,10 @@ static void ps3_chip_unmask(unsigned int virq)
  * Calls lv1_end_of_interrupt_ext().
  */
 
-static void ps3_chip_eoi(unsigned int virq)
+static void ps3_chip_eoi(struct irq_desc *desc)
 {
-	const struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
 }
 
@@ -202,7 +205,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_set;
 	}
 
-	ps3_chip_mask(*virq);
+	ps3_chip_mask(irq_to_desc(*virq));
 
 	return result;
 
@@ -296,7 +299,7 @@ int ps3_irq_plug_destroy(unsigned int virq)
 	pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
 		__LINE__, pd->ppe_id, pd->thread_id, virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
 
@@ -357,7 +360,7 @@ int ps3_event_receive_port_destroy(unsigned int virq)
 
 	pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
@@ -492,7 +495,7 @@ int ps3_io_irq_destroy(unsigned int virq)
 	int result;
 	unsigned long outlet = virq_to_hw(virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	/*
 	 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
@@ -553,7 +556,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 	result = lv1_deconfigure_virtual_uart_irq();
 
 	if (result) {
@@ -605,7 +608,7 @@ int ps3_spe_irq_destroy(unsigned int virq)
 {
 	int result;
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ca5f2e1..056fecb 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -118,7 +118,7 @@ static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init pseries_setup_i8259_cascade(void)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 1bcedd8..e51f3d8 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -194,8 +194,9 @@ static int get_irq_server(unsigned int virq, cpumask_t cpumask,
 #define get_irq_server(virq, cpumask, strict_check) (default_server)
 #endif
 
-static void xics_unmask_irq(unsigned int virq)
+static void xics_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 	int call_status;
 	int server;
@@ -227,18 +228,18 @@ static void xics_unmask_irq(unsigned int virq)
 	}
 }
 
-static unsigned int xics_startup(unsigned int virq)
+static unsigned int xics_startup(struct irq_desc *desc)
 {
 	/*
 	 * The generic MSI code returns with the interrupt disabled on the
 	 * card, using the MSI mask bits. Firmware doesn't appear to unmask
 	 * at that level, so we do it here by hand.
 	 */
-	if (irq_to_desc(virq)->msi_desc)
-		unmask_msi_irq(virq);
+	if (desc->msi_desc)
+		unmask_msi_irq(desc);
 
 	/* unmask it */
-	xics_unmask_irq(virq);
+	xics_unmask_irq(desc);
 	return 0;
 }
 
@@ -266,8 +267,9 @@ static void xics_mask_real_irq(unsigned int irq)
 	}
 }
 
-static void xics_mask_irq(unsigned int virq)
+static void xics_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 
 	pr_devel("xics: mask virq %d\n", virq);
@@ -363,24 +365,27 @@ static unsigned char pop_cppr(void)
 	return os_cppr->stack[--os_cppr->index];
 }
 
-static void xics_eoi_direct(unsigned int virq)
+static void xics_eoi_direct(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
 	direct_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
-static void xics_eoi_lpar(unsigned int virq)
+static void xics_eoi_lpar(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
 	lpar_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
-static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
+static int xics_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 	int status;
 	int xics_status[2];
@@ -930,8 +935,8 @@ void xics_migrate_irqs_away(void)
 		       virq, cpu);
 
 		/* Reset affinity to all cpus */
-		cpumask_setall(irq_to_desc(virq)->affinity);
-		desc->chip->set_affinity(virq, cpu_all_mask);
+		cpumask_setall(desc->affinity);
+		desc->chip->set_affinity(desc, cpu_all_mask);
 unlock:
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index ecad10d..5848b07 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -55,22 +55,25 @@ static cpic8xx_t __iomem *cpic_reg;
 
 static struct irq_host *cpm_pic_host;
 
-static void cpm_mask_irq(unsigned int irq)
+static void cpm_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
-static void cpm_unmask_irq(unsigned int irq)
+static void cpm_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
-static void cpm_end_irq(unsigned int irq)
+static void cpm_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index fcea4ff..ec59695 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -78,8 +78,9 @@ static const u_char irq_to_siubit[] = {
 	24, 25, 26, 27, 28, 29, 30, 31,
 };
 
-static void cpm2_mask_irq(unsigned int virq)
+static void cpm2_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -90,8 +91,9 @@ static void cpm2_mask_irq(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
 }
 
-static void cpm2_unmask_irq(unsigned int virq)
+static void cpm2_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -102,8 +104,9 @@ static void cpm2_unmask_irq(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
 }
 
-static void cpm2_ack(unsigned int virq)
+static void cpm2_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -113,13 +116,12 @@ static void cpm2_ack(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
 }
 
-static void cpm2_end_irq(unsigned int virq)
+static void cpm2_end_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc;
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
-	desc = irq_to_desc(irq_nr);
 	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
 			&& desc->action) {
 
@@ -137,10 +139,10 @@ static void cpm2_end_irq(unsigned int virq)
 	}
 }
 
-static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int cpm2_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = virq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
 	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index e094367..14c3286 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -39,7 +39,7 @@ static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
  * We do not need this actually. The MSIR register has been read once
  * in the cascade interrupt. So, this MSI interrupt has been acked
 */
-static void fsl_msi_end_irq(unsigned int virq)
+static void fsl_msi_end_irq(struct irq_desc *desc)
 {
 }
 
@@ -176,10 +176,10 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 	raw_spin_lock(&desc->lock);
 	if ((msi_data->feature &  FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
 		if (desc->chip->mask_ack)
-			desc->chip->mask_ack(irq);
+			desc->chip->mask_ack(desc);
 		else {
-			desc->chip->mask(irq);
-			desc->chip->ack(irq);
+			desc->chip->mask(desc);
+			desc->chip->ack(desc);
 		}
 	}
 
@@ -217,11 +217,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 
 	switch (msi_data->feature & FSL_PIC_IP_MASK) {
 	case FSL_PIC_IP_MPIC:
-		desc->chip->eoi(irq);
+		desc->chip->eoi(desc);
 		break;
 	case FSL_PIC_IP_IPIC:
 		if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		break;
 	}
 unlock:
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 6323e70..ba3bc94 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -78,8 +78,9 @@ unsigned int i8259_irq(void)
 	return irq;
 }
 
-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+static void i8259_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&i8259_lock, flags);
@@ -104,8 +105,9 @@ static void i8259_set_irq_mask(int irq_nr)
 	outb(cached_21,0x21);
 }
 
-static void i8259_mask_irq(unsigned int irq_nr)
+static void i8259_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	pr_debug("i8259_mask_irq(%d)\n", irq_nr);
@@ -119,8 +121,9 @@ static void i8259_mask_irq(unsigned int irq_nr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
-static void i8259_unmask_irq(unsigned int irq_nr)
+static void i8259_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
@@ -188,7 +191,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
 static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
 {
 	/* Make sure irq is masked in hardware */
-	i8259_mask_irq(virq);
+	i8259_mask_irq(irq_to_desc(virq));
 
 	/* remove chip and handler */
 	set_irq_chip_and_handler(virq, NULL, NULL);
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index d7b9b9c..76a58bf 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -523,8 +523,9 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
 
 #define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
 
-static void ipic_unmask_irq(unsigned int virq)
+static void ipic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -539,8 +540,9 @@ static void ipic_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_mask_irq(unsigned int virq)
+static void ipic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -559,8 +561,9 @@ static void ipic_mask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_ack_irq(unsigned int virq)
+static void ipic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -578,8 +581,9 @@ static void ipic_ack_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_mask_irq_and_ack(unsigned int virq)
+static void ipic_mask_irq_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -601,11 +605,11 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int ipic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
 	if (flow_type == IRQ_TYPE_NONE)
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 8c27d26..08435f0 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -25,8 +25,9 @@ static sysconf8xx_t __iomem *siu_reg;
 
 int cpm_get_irq(struct pt_regs *regs);
 
-static void mpc8xx_unmask_irq(unsigned int virq)
+static void mpc8xx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -37,8 +38,9 @@ static void mpc8xx_unmask_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static void mpc8xx_mask_irq(unsigned int virq)
+static void mpc8xx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -49,8 +51,9 @@ static void mpc8xx_mask_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static void mpc8xx_ack(unsigned int virq)
+static void mpc8xx_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -58,8 +61,9 @@ static void mpc8xx_ack(unsigned int virq)
 	out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
 }
 
-static void mpc8xx_end_irq(unsigned int virq)
+static void mpc8xx_end_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -70,9 +74,9 @@ static void mpc8xx_end_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int mpc8xx_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
+	unsigned int virq = desc->irq;
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 339e8a3..0bda28b 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -663,8 +663,9 @@ static inline void mpic_eoi(struct mpic *mpic)
  */
 
 
-void mpic_unmask_irq(unsigned int irq)
+void mpic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
@@ -683,8 +684,9 @@ void mpic_unmask_irq(unsigned int irq)
 	} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
 }
 
-void mpic_mask_irq(unsigned int irq)
+void mpic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
@@ -704,8 +706,9 @@ void mpic_mask_irq(unsigned int irq)
 	} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
 }
 
-void mpic_end_irq(unsigned int irq)
+void mpic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 
 #ifdef DEBUG_IRQ
@@ -721,39 +724,43 @@ void mpic_end_irq(unsigned int irq)
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
 
-static void mpic_unmask_ht_irq(unsigned int irq)
+static void mpic_unmask_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_unmask_irq(irq);
+	mpic_unmask_irq(desc);
 
-	if (irq_to_desc(irq)->status & IRQ_LEVEL)
+	if (desc->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 }
 
-static unsigned int mpic_startup_ht_irq(unsigned int irq)
+static unsigned int mpic_startup_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_unmask_irq(irq);
-	mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
+	mpic_unmask_irq(desc);
+	mpic_startup_ht_interrupt(mpic, src, desc->status);
 
 	return 0;
 }
 
-static void mpic_shutdown_ht_irq(unsigned int irq)
+static void mpic_shutdown_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
-	mpic_mask_irq(irq);
+	mpic_shutdown_ht_interrupt(mpic, src, desc->status);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_end_ht_irq(unsigned int irq)
+static void mpic_end_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
@@ -765,7 +772,7 @@ static void mpic_end_ht_irq(unsigned int irq)
 	 * latched another edge interrupt coming in anyway
 	 */
 
-	if (irq_to_desc(irq)->status & IRQ_LEVEL)
+	if (desc->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 	mpic_eoi(mpic);
 }
@@ -773,8 +780,9 @@ static void mpic_end_ht_irq(unsigned int irq)
 
 #ifdef CONFIG_SMP
 
-static void mpic_unmask_ipi(unsigned int irq)
+static void mpic_unmask_ipi(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_ipi(irq);
 	unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
 
@@ -782,13 +790,14 @@ static void mpic_unmask_ipi(unsigned int irq)
 	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
 }
 
-static void mpic_mask_ipi(unsigned int irq)
+static void mpic_mask_ipi(struct irq_desc *desc)
 {
 	/* NEVER disable an IPI... that's just plain wrong! */
 }
 
-static void mpic_end_ipi(unsigned int irq)
+static void mpic_end_ipi(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_ipi(irq);
 
 	/*
@@ -803,8 +812,9 @@ static void mpic_end_ipi(unsigned int irq)
 
 #endif /* CONFIG_SMP */
 
-int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+int mpic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
@@ -845,11 +855,11 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
 	}
 }
 
-int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+int mpic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(virq);
 	unsigned int src = mpic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vecpri, vold, vnew;
 
 	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index eff433c..19d7ed4 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -34,8 +34,8 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
 }
 #endif
 
-extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
+extern int mpic_set_irq_type(struct irq_desc *desc, unsigned int flow_type);
 extern void mpic_set_vector(unsigned int virq, unsigned int vector);
-extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int mpic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask);
 
 #endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 3b6a9a4..c05a9c6 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -39,18 +39,20 @@
 static struct mpic *msi_mpic;
 
 
-static void mpic_pasemi_msi_mask_irq(unsigned int irq)
+static void mpic_pasemi_msi_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(desc);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
+static void mpic_pasemi_msi_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(desc);
+	unmask_msi_irq(desc);
 }
 
 static struct irq_chip mpic_pasemi_msi_chip = {
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index bcbfe79..8c4eadd 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -23,16 +23,16 @@
 /* A bit ugly, can we get this from the pci_dev somehow? */
 static struct mpic *msi_mpic;
 
-static void mpic_u3msi_mask_irq(unsigned int irq)
+static void mpic_u3msi_mask_irq(struct irq_desc *desc)
 {
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(desc);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_u3msi_unmask_irq(unsigned int irq)
+static void mpic_u3msi_unmask_irq(struct irq_desc *desc)
 {
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(desc);
+	unmask_msi_irq(desc);
 }
 
 static struct irq_chip mpic_u3msi_chip = {
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 485b924..72f4dfb 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -76,8 +76,9 @@ static struct irq_host *mv64x60_irq_host;
  * mv64x60_chip_low functions
  */
 
-static void mv64x60_mask_low(unsigned int virq)
+static void mv64x60_mask_low(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -89,8 +90,9 @@ static void mv64x60_mask_low(unsigned int virq)
 	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
 }
 
-static void mv64x60_unmask_low(unsigned int virq)
+static void mv64x60_unmask_low(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -113,8 +115,9 @@ static struct irq_chip mv64x60_chip_low = {
  * mv64x60_chip_high functions
  */
 
-static void mv64x60_mask_high(unsigned int virq)
+static void mv64x60_mask_high(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -126,8 +129,9 @@ static void mv64x60_mask_high(unsigned int virq)
 	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
 }
 
-static void mv64x60_unmask_high(unsigned int virq)
+static void mv64x60_unmask_high(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -150,8 +154,9 @@ static struct irq_chip mv64x60_chip_high = {
  * mv64x60_chip_gpp functions
  */
 
-static void mv64x60_mask_gpp(unsigned int virq)
+static void mv64x60_mask_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -163,8 +168,9 @@ static void mv64x60_mask_gpp(unsigned int virq)
 	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
 }
 
-static void mv64x60_mask_ack_gpp(unsigned int virq)
+static void mv64x60_mask_ack_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -178,8 +184,9 @@ static void mv64x60_mask_ack_gpp(unsigned int virq)
 	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
 }
 
-static void mv64x60_unmask_gpp(unsigned int virq)
+static void mv64x60_unmask_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 541ba98..289c0cb 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -194,8 +194,9 @@ static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
 
 #define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
 
-static void qe_ic_unmask_irq(unsigned int virq)
+static void qe_ic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 	unsigned int src = virq_to_hw(virq);
 	unsigned long flags;
@@ -210,8 +211,9 @@ static void qe_ic_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 }
 
-static void qe_ic_mask_irq(unsigned int virq)
+static void qe_ic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 	unsigned int src = virq_to_hw(virq);
 	unsigned long flags;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 595034c..2ff5286 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -344,23 +344,27 @@ static inline unsigned int get_pci_source(void)
  * Linux descriptor level callbacks
  */
 
-static void tsi108_pci_irq_enable(u_int irq)
+static void tsi108_pci_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_unmask(irq);
 }
 
-static void tsi108_pci_irq_disable(u_int irq)
+static void tsi108_pci_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_mask(irq);
 }
 
-static void tsi108_pci_irq_ack(u_int irq)
+static void tsi108_pci_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_mask(irq);
 }
 
-static void tsi108_pci_irq_end(u_int irq)
+static void tsi108_pci_irq_end(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_unmask(irq);
 
 	/* Enable interrupts from PCI block */
@@ -441,5 +445,5 @@ void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = get_pci_source();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 0038fb7..fbed0a4 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -55,10 +55,10 @@ struct uic {
 	struct irq_host	*irqhost;
 };
 
-static void uic_unmask_irq(unsigned int virq)
+static void uic_unmask_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er, sr;
@@ -74,9 +74,10 @@ static void uic_unmask_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_mask_irq(unsigned int virq)
+static void uic_mask_irq(struct irq_desc *desc)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er;
@@ -88,9 +89,10 @@ static void uic_mask_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_ack_irq(unsigned int virq)
+static void uic_ack_irq(struct irq_desc *desc)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 
@@ -99,10 +101,10 @@ static void uic_ack_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_mask_ack_irq(unsigned int virq)
+static void uic_mask_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er, sr;
@@ -125,11 +127,11 @@ static void uic_mask_ack_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int uic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned long flags;
 	int trigger, polarity;
 	u32 tr, pr, mask;
@@ -227,9 +229,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
-		desc->chip->mask(virq);
+		desc->chip->mask(desc);
 	else
-		desc->chip->mask_ack(virq);
+		desc->chip->mask_ack(desc);
 	raw_spin_unlock(&desc->lock);
 
 	msr = mfdcr(uic->dcrbase + UIC_MSR);
@@ -244,9 +246,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
 uic_irq_ret:
 	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
-		desc->chip->ack(virq);
+		desc->chip->ack(desc);
 	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-		desc->chip->unmask(virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 1e0ccfa..f8e3f68 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -69,17 +69,18 @@ static unsigned char xilinx_intc_map_senses[] = {
  *
  * IRQ Chip common (across level and edge) operations
  */
-static void xilinx_intc_mask(unsigned int virq)
+static void xilinx_intc_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("mask: %d\n", irq);
 	out_be32(regs + XINTC_CIE, 1 << irq);
 }
 
-static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
+static int xilinx_intc_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
+	unsigned int virq = desc->irq;
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@@ -91,10 +92,11 @@ static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
 /*
  * IRQ Chip level operations
  */
-static void xilinx_intc_level_unmask(unsigned int virq)
+static void xilinx_intc_level_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
 
@@ -116,18 +118,20 @@ static struct irq_chip xilinx_intc_level_irqchip = {
 /*
  * IRQ Chip edge operations
  */
-static void xilinx_intc_edge_unmask(unsigned int virq)
+static void xilinx_intc_edge_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void *regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
 }
 
-static void xilinx_intc_edge_ack(unsigned int virq)
+static void xilinx_intc_edge_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("ack: %d\n", irq);
 	out_be32(regs + XINTC_IAR, 1 << irq);
 }
@@ -234,7 +238,7 @@ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
 		generic_handle_irq(cascade_irq);
 
 	/* Let xilinx_intc end the interrupt */
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static void __init xilinx_i8259_setup_cascade(void)
diff --git a/arch/score/kernel/irq.c b/arch/score/kernel/irq.c
index 47647dd..663a04b 100644
--- a/arch/score/kernel/irq.c
+++ b/arch/score/kernel/irq.c
@@ -52,9 +52,10 @@ asmlinkage void do_IRQ(int irq)
 	irq_exit();
 }
 
-static void score_mask(unsigned int irq_nr)
+static void score_mask(struct irq_desc *desc)
 {
-	unsigned int irq_source = 63 - irq_nr;
+	unsigned int irq = desc->irq;
+	unsigned int irq_source = 63 - irq;
 
 	if (irq_source < 32)
 		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \
@@ -64,9 +65,10 @@ static void score_mask(unsigned int irq_nr)
 			(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH);
 }
 
-static void score_unmask(unsigned int irq_nr)
+static void score_unmask(struct irq_desc *desc)
 {
-	unsigned int irq_source = 63 - irq_nr;
+	unsigned int irq = desc->irq;
+	unsigned int irq_source = 63 - irq;
 
 	if (irq_source < 32)
 		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index 1394b07..ac3535a 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -55,8 +55,9 @@ static struct irqaction cayman_action_pci2 = {
 	.flags		= IRQF_DISABLED,
 };
 
-static void enable_cayman_irq(unsigned int irq)
+static void enable_cayman_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned long mask;
 	unsigned int reg;
@@ -72,8 +73,9 @@ static void enable_cayman_irq(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-void disable_cayman_irq(unsigned int irq)
+void disable_cayman_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned long mask;
 	unsigned int reg;
@@ -89,9 +91,9 @@ void disable_cayman_irq(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-static void ack_cayman_irq(unsigned int irq)
+static void ack_cayman_irq(struct irq_desc *desc)
 {
-	disable_cayman_irq(irq);
+	disable_cayman_irq(desc);
 }
 
 struct irq_chip cayman_irq_type = {
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index d932667..16cde3e 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -60,8 +60,9 @@
  */
 
 /* Disable the hardware event by masking its bit in its EMR */
-static inline void disable_systemasic_irq(unsigned int irq)
+static inline void disable_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
 
@@ -71,8 +72,9 @@ static inline void disable_systemasic_irq(unsigned int irq)
 }
 
 /* Enable the hardware event by setting its bit in its EMR */
-static inline void enable_systemasic_irq(unsigned int irq)
+static inline void enable_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
 
@@ -82,8 +84,9 @@ static inline void enable_systemasic_irq(unsigned int irq)
 }
 
 /* Acknowledge a hardware event by writing its bit back to its ESR */
-static void mask_ack_systemasic_irq(unsigned int irq)
+static void mask_ack_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
 	disable_systemasic_irq(irq);
 	outl((1 << EVENT_BIT(irq)), esr);
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
index 96f38a4..3bcfb32 100644
--- a/arch/sh/boards/mach-landisk/irq.c
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -18,15 +18,17 @@
 #include <linux/io.h>
 #include <mach-landisk/mach/iodata_landisk.h>
 
-static void disable_landisk_irq(unsigned int irq)
+static void disable_landisk_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char mask = 0xff ^ (0x01 << (irq - 5));
 
 	__raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK);
 }
 
-static void enable_landisk_irq(unsigned int irq)
+static void enable_landisk_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char value = (0x01 << (irq - 5));
 
 	__raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK);
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index a26d166..4b7b5ec 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -65,9 +65,9 @@ static const struct {
 #  error Inconsistancy in defining the IRQ# for primary IDE!
 #endif
 
-static void enable_microdev_irq(unsigned int irq);
-static void disable_microdev_irq(unsigned int irq);
-static void mask_and_ack_microdev(unsigned int);
+static void enable_microdev_irq(struct irq_desc *desc);
+static void disable_microdev_irq(struct irq_desc *desc);
+static void mask_and_ack_microdev(struct irq_desc *desc);
 
 static struct irq_chip microdev_irq_type = {
 	.name = "MicroDev-IRQ",
@@ -76,8 +76,9 @@ static struct irq_chip microdev_irq_type = {
 	.ack = mask_and_ack_microdev,
 };
 
-static void disable_microdev_irq(unsigned int irq)
+static void disable_microdev_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int fpgaIrq;
 
 	if (irq >= NUM_EXTERNAL_IRQS)
@@ -91,8 +92,9 @@ static void disable_microdev_irq(unsigned int irq)
 	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
 }
 
-static void enable_microdev_irq(unsigned int irq)
+static void enable_microdev_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long priorityReg, priorities, pri;
 	unsigned int fpgaIrq;
 
@@ -119,14 +121,15 @@ static void enable_microdev_irq(unsigned int irq)
 /* This function sets the desired irq handler to be a MicroDev type */
 static void __init make_microdev_irq(unsigned int irq)
 {
+	struct irq_desc *desc = irq_to_desc(irq);
 	disable_irq_nosync(irq);
 	set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
-	disable_microdev_irq(irq);
+	disable_microdev_irq(desc);
 }
 
-static void mask_and_ack_microdev(unsigned int irq)
+static void mask_and_ack_microdev(struct irq_desc *desc)
 {
-	disable_microdev_irq(irq);
+	disable_microdev_irq(desc);
 }
 
 extern void __init init_microdev_irq(void)
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index 8d82175..1a71dad 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -25,8 +25,9 @@
 #define INTC_IPR01 0xfffe0818
 #define INTC_ICR1  0xfffe0802
 
-static void disable_se7206_irq(unsigned int irq)
+static void disable_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short val;
 	unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
 	unsigned short msk0,msk1;
@@ -55,8 +56,9 @@ static void disable_se7206_irq(unsigned int irq)
 	__raw_writew(msk1, INTMSK1);
 }
 
-static void enable_se7206_irq(unsigned int irq)
+static void enable_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short val;
 	unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
 	unsigned short msk0,msk1;
@@ -86,8 +88,9 @@ static void enable_se7206_irq(unsigned int irq)
 	__raw_writew(msk1, INTMSK1);
 }
 
-static void eoi_se7206_irq(unsigned int irq)
+static void eoi_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short sts0,sts1;
 	struct irq_desc *desc = irq_to_desc(irq);
 
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index d4305c2..a195d5a 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -18,15 +18,15 @@
 
 unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
 
-static void disable_se7343_irq(unsigned int irq)
+static void disable_se7343_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
 }
 
-static void enable_se7343_irq(unsigned int irq)
+static void enable_se7343_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
 }
 
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 61605db..69cb49a 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -18,15 +18,15 @@
 
 unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
 
-static void disable_se7722_irq(unsigned int irq)
+static void disable_se7722_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
 }
 
-static void enable_se7722_irq(unsigned int irq)
+static void enable_se7722_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
 }
 
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index 0942be2..b0c094d 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -68,15 +68,17 @@ static struct fpga_irq get_fpga_irq(unsigned int irq)
 	return set;
 }
 
-static void disable_se7724_irq(unsigned int irq)
+static void disable_se7724_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
 	__raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
 }
 
-static void enable_se7724_irq(unsigned int irq)
+static void enable_se7724_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
 	__raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 523aea5..fa3a36d 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -24,9 +24,9 @@ static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
 static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
 
 /* forward declaration */
-static void enable_systemh_irq(unsigned int irq);
-static void disable_systemh_irq(unsigned int irq);
-static void mask_and_ack_systemh(unsigned int);
+static void enable_systemh_irq(struct irq_desc *desc);
+static void disable_systemh_irq(struct irq_desc *desc);
+static void mask_and_ack_systemh(struct irq_desc *desc);
 
 static struct irq_chip systemh_irq_type = {
 	.name = " SystemH Register",
@@ -35,8 +35,9 @@ static struct irq_chip systemh_irq_type = {
 	.ack = mask_and_ack_systemh,
 };
 
-static void disable_systemh_irq(unsigned int irq)
+static void disable_systemh_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (systemh_irq_mask_register) {
 		unsigned long val, mask = 0x01 << 1;
 
@@ -51,8 +52,9 @@ static void disable_systemh_irq(unsigned int irq)
 	}
 }
 
-static void enable_systemh_irq(unsigned int irq)
+static void enable_systemh_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (systemh_irq_mask_register) {
 		unsigned long val, mask = 0x01 << 1;
 
@@ -63,9 +65,9 @@ static void enable_systemh_irq(unsigned int irq)
 	}
 }
 
-static void mask_and_ack_systemh(unsigned int irq)
+static void mask_and_ack_systemh(struct irq_desc *desc)
 {
-	disable_systemh_irq(irq);
+	disable_systemh_irq(desc);
 }
 
 void make_systemh_irq(unsigned int irq)
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index bcb31ae..9e9698c 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -17,8 +17,9 @@
 /* This belongs in cpu specific */
 #define INTC_ICR1 0xA4140010UL
 
-static void hd64461_mask_irq(unsigned int irq)
+static void hd64461_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
@@ -27,8 +28,9 @@ static void hd64461_mask_irq(unsigned int irq)
 	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void hd64461_unmask_irq(unsigned int irq)
+static void hd64461_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
@@ -37,9 +39,10 @@ static void hd64461_unmask_irq(unsigned int irq)
 	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void hd64461_mask_and_ack_irq(unsigned int irq)
+static void hd64461_mask_and_ack_irq(struct irq_desc *desc)
 {
-	hd64461_mask_irq(irq);
+	unsigned int irq = desc->irq;
+	hd64461_mask_irq(desc);
 #ifdef CONFIG_HD64461_ENABLER
 	if (irq == HD64461_IRQBASE + 13)
 		__raw_writeb(0x00, HD64461_PCC1CSCR);
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index a351ed8..0598602 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -51,16 +51,18 @@ static inline void set_interrupt_registers(int ip)
 		     : "t");
 }
 
-static void mask_imask_irq(unsigned int irq)
+static void mask_imask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_bit(irq, imask_mask);
 	if (interrupt_priority < IMASK_PRIORITY - irq)
 		interrupt_priority = IMASK_PRIORITY - irq;
 	set_interrupt_registers(interrupt_priority);
 }
 
-static void unmask_imask_irq(unsigned int irq)
+static void unmask_imask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_bit(irq, imask_mask);
 	interrupt_priority = IMASK_PRIORITY -
 		find_first_zero_bit(imask_mask, IMASK_PRIORITY);
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 96a2395..69a90ae 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -77,12 +77,12 @@ int intc_evt_to_irq[(0xE20/0x20)+1] = {
 
 static unsigned long intc_virt;
 
-static unsigned int startup_intc_irq(unsigned int irq);
-static void shutdown_intc_irq(unsigned int irq);
-static void enable_intc_irq(unsigned int irq);
-static void disable_intc_irq(unsigned int irq);
-static void mask_and_ack_intc(unsigned int);
-static void end_intc_irq(unsigned int irq);
+static unsigned int startup_intc_irq(struct irq_desc *desc);
+static void shutdown_intc_irq(struct irq_desc *desc);
+static void enable_intc_irq(struct irq_desc *desc);
+static void disable_intc_irq(struct irq_desc *desc);
+static void mask_and_ack_intc(struct irq_desc *desc);
+static void end_intc_irq(struct irq_desc *desc);
 
 static struct irq_chip intc_irq_type = {
 	.name = "INTC",
@@ -96,19 +96,20 @@ static struct irq_chip intc_irq_type = {
 
 static int irlm;		/* IRL mode */
 
-static unsigned int startup_intc_irq(unsigned int irq)
+static unsigned int startup_intc_irq(struct irq_desc *desc)
 {
-	enable_intc_irq(irq);
+	enable_intc_irq(desc);
 	return 0; /* never anything pending */
 }
 
-static void shutdown_intc_irq(unsigned int irq)
+static void shutdown_intc_irq(struct irq_desc *desc)
 {
-	disable_intc_irq(irq);
+	disable_intc_irq(desc);
 }
 
-static void enable_intc_irq(unsigned int irq)
+static void enable_intc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long reg;
 	unsigned long bitmask;
 
@@ -126,8 +127,9 @@ static void enable_intc_irq(unsigned int irq)
 	__raw_writel(bitmask, reg);
 }
 
-static void disable_intc_irq(unsigned int irq)
+static void disable_intc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long reg;
 	unsigned long bitmask;
 
@@ -142,14 +144,14 @@ static void disable_intc_irq(unsigned int irq)
 	__raw_writel(bitmask, reg);
 }
 
-static void mask_and_ack_intc(unsigned int irq)
+static void mask_and_ack_intc(struct irq_desc *desc)
 {
-	disable_intc_irq(irq);
+	disable_intc_irq(desc);
 }
 
-static void end_intc_irq(unsigned int irq)
+static void end_intc_irq(struct irq_desc *desc)
 {
-	enable_intc_irq(irq);
+	enable_intc_irq(desc);
 }
 
 void __init plat_irq_setup(void)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 4e7419c..1495c97 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -250,8 +250,9 @@ struct irq_handler_data {
 };
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
+static int irq_choose_cpu(struct irq_desc *desc, const struct cpumask *affinity)
 {
+	unsigned int virt_irq = desc->irq;
 	cpumask_t mask;
 	int cpuid;
 
@@ -268,20 +269,20 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
 	return cpuid;
 }
 #else
-#define irq_choose_cpu(virt_irq, affinity)	\
+#define irq_choose_cpu(desc, affinity)	\
 	real_hard_smp_processor_id()
 #endif
 
-static void sun4u_irq_enable(unsigned int virt_irq)
+static void sun4u_irq_enable(struct irq_desc *desc)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (likely(data)) {
 		unsigned long cpuid, imap, val;
 		unsigned int tid;
 
-		cpuid = irq_choose_cpu(virt_irq,
-				       irq_desc[virt_irq].affinity);
+		cpuid = irq_choose_cpu(desc,
+				       desc->affinity);
 		imap = data->imap;
 
 		tid = sun4u_compute_tid(imap, cpuid);
@@ -295,16 +296,16 @@ static void sun4u_irq_enable(unsigned int virt_irq)
 	}
 }
 
-static int sun4u_set_affinity(unsigned int virt_irq,
+static int sun4u_set_affinity(struct irq_desc *desc,
 			       const struct cpumask *mask)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (likely(data)) {
 		unsigned long cpuid, imap, val;
 		unsigned int tid;
 
-		cpuid = irq_choose_cpu(virt_irq, mask);
+		cpuid = irq_choose_cpu(desc, mask);
 		imap = data->imap;
 
 		tid = sun4u_compute_tid(imap, cpuid);
@@ -337,14 +338,13 @@ static int sun4u_set_affinity(unsigned int virt_irq,
  * sees that, it also hooks up a default ->shutdown method which
  * invokes ->mask() which we do not want.  See irq_chip_set_defaults().
  */
-static void sun4u_irq_disable(unsigned int virt_irq)
+static void sun4u_irq_disable(struct irq_desc *desc)
 {
 }
 
-static void sun4u_irq_eoi(unsigned int virt_irq)
+static void sun4u_irq_eoi(struct irq_desc *desc)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-	struct irq_desc *desc = irq_desc + virt_irq;
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		return;
@@ -353,11 +353,11 @@ static void sun4u_irq_eoi(unsigned int virt_irq)
 		upa_writeq(ICLR_IDLE, data->iclr);
 }
 
-static void sun4v_irq_enable(unsigned int virt_irq)
+static void sun4v_irq_enable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq,
-					     irq_desc[virt_irq].affinity);
+	unsigned long cpuid = irq_choose_cpu(desc, desc->affinity);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -374,11 +374,12 @@ static void sun4v_irq_enable(unsigned int virt_irq)
 		       ino, err);
 }
 
-static int sun4v_set_affinity(unsigned int virt_irq,
+static int sun4v_set_affinity(struct irq_desc *desc,
 			       const struct cpumask *mask)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq, mask);
+	unsigned long cpuid = irq_choose_cpu(desc, mask);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -389,8 +390,9 @@ static int sun4v_set_affinity(unsigned int virt_irq,
 	return 0;
 }
 
-static void sun4v_irq_disable(unsigned int virt_irq)
+static void sun4v_irq_disable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
 	int err;
 
@@ -400,10 +402,10 @@ static void sun4v_irq_disable(unsigned int virt_irq)
 		       "err(%d)\n", ino, err);
 }
 
-static void sun4v_irq_eoi(unsigned int virt_irq)
+static void sun4v_irq_eoi(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	struct irq_desc *desc = irq_desc + virt_irq;
 	int err;
 
 	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
@@ -415,12 +417,13 @@ static void sun4v_irq_eoi(unsigned int virt_irq)
 		       "err(%d)\n", ino, err);
 }
 
-static void sun4v_virq_enable(unsigned int virt_irq)
+static void sun4v_virq_enable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity);
+	cpuid = irq_choose_cpu(desc, desc->affinity);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -444,13 +447,14 @@ static void sun4v_virq_enable(unsigned int virt_irq)
 		       dev_handle, dev_ino, err);
 }
 
-static int sun4v_virt_set_affinity(unsigned int virt_irq,
+static int sun4v_virt_set_affinity(struct irq_desc *desc,
 				    const struct cpumask *mask)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq, mask);
+	cpuid = irq_choose_cpu(desc, mask);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -464,8 +468,9 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq,
 	return 0;
 }
 
-static void sun4v_virq_disable(unsigned int virt_irq)
+static void sun4v_virq_disable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long dev_handle, dev_ino;
 	int err;
 
@@ -480,9 +485,9 @@ static void sun4v_virq_disable(unsigned int virt_irq)
 		       dev_handle, dev_ino, err);
 }
 
-static void sun4v_virq_eoi(unsigned int virt_irq)
+static void sun4v_virq_eoi(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + virt_irq;
+	unsigned int virt_irq = desc->irq;
 	unsigned long dev_handle, dev_ino;
 	int err;
 
@@ -802,15 +807,16 @@ void fixup_irqs(void)
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		unsigned long flags;
-
-		raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
-		if (irq_desc[irq].action &&
-		    !(irq_desc[irq].status & IRQ_PER_CPU)) {
-			if (irq_desc[irq].chip->set_affinity)
-				irq_desc[irq].chip->set_affinity(irq,
-					irq_desc[irq].affinity);
+		struct irq_desc *desc = irq_to_desc(irq);
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+		if (desc->action &&
+		    !(desc->status & IRQ_PER_CPU)) {
+			if (desc->chip->set_affinity)
+				desc->chip->set_affinity(desc,
+					desc->affinity);
 		}
-		raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 
 	tick_ops->disable_irq();
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c
index 380a70f..6d1b690 100644
--- a/arch/xtensa/variants/s6000/gpio.c
+++ b/arch/xtensa/variants/s6000/gpio.c
@@ -85,27 +85,31 @@ int s6_gpio_init(u32 afsel)
 	return gpiochip_add(&gpiochip);
 }
 
-static void ack(unsigned int irq)
+static void ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writeb(1 << (irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC);
 }
 
-static void mask(unsigned int irq)
+static void mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r = readb(S6_REG_GPIO + S6_GPIO_IE);
 	r &= ~(1 << (irq - IRQ_BASE));
 	writeb(r, S6_REG_GPIO + S6_GPIO_IE);
 }
 
-static void unmask(unsigned int irq)
+static void unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 m = readb(S6_REG_GPIO + S6_GPIO_IE);
 	m |= 1 << (irq - IRQ_BASE);
 	writeb(m, S6_REG_GPIO + S6_GPIO_IE);
 }
 
-static int set_type(unsigned int irq, unsigned int type)
+static int set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	const u8 m = 1 << (irq - IRQ_BASE);
 	irq_flow_handler_t handler;
 	struct irq_desc *desc;
@@ -164,8 +168,8 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
 	u8 pending;
 	int cirq;
 
-	desc->chip->mask(irq);
-	desc->chip->ack(irq);
+	desc->chip->mask(desc);
+	desc->chip->ack(desc);
 	pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask;
 	cirq = IRQ_BASE - 1;
 	while (pending) {
@@ -174,7 +178,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
 		pending >>= n;
 		generic_handle_irq(cirq);
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS];
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index a3d8677..f9aaed6 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -245,15 +245,16 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)
 	}
 }
 
-static void intc_enable(unsigned int irq)
+static void intc_enable(struct irq_desc *desc)
 {
-	_intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
+	unsigned int irq = desc->irq;
+	_intc_enable(irq, (unsigned long)get_irq_desc_chip_data(desc));
 }
 
-static void intc_disable(unsigned int irq)
+static void intc_disable(struct irq_desc *desc)
 {
 	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = (unsigned long) get_irq_chip_data(irq);
+	unsigned long handle = (unsigned long) get_irq_desc_chip_data(desc);
 	unsigned long addr;
 	unsigned int cpu;
 
@@ -784,7 +785,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
 	}
 
 	/* irq should be disabled by default */
-	d->chip.mask(irq);
+	d->chip.mask(desc);
 
 	if (desc->hw.ack_regs)
 		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
-- 
1.6.4.2


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

* [PATCH 13/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- other arch
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

will have
void            (*ack)(struct irq_desc *desc);
void            (*mask)(struct irq_desc *desc);
void            (*mask_ack)(struct irq_desc *desc);
void            (*unmask)(struct irq_desc *desc);
void            (*eoi)(struct irq_desc *desc);

so for sparseirq with raidix tree, we don't call extra irq_to_desc, and could use desc directly

-v2: change all member of irq_chip to use desc only.
-v2.1: update after legacy_pic
-v2.2: update to irq one short fix

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 Documentation/DocBook/genericirq.tmpl            |   24 ++--
 arch/alpha/kernel/irq_alpha.c                    |    4 +-
 arch/alpha/kernel/irq_i8259.c                    |   22 +++--
 arch/alpha/kernel/irq_impl.h                     |   10 +-
 arch/alpha/kernel/irq_pyxis.c                    |   21 ++--
 arch/alpha/kernel/irq_srm.c                      |   18 ++--
 arch/alpha/kernel/sys_alcor.c                    |   28 +++---
 arch/alpha/kernel/sys_cabriolet.c                |   18 ++--
 arch/alpha/kernel/sys_dp264.c                    |   44 ++++----
 arch/alpha/kernel/sys_eb64p.c                    |   18 ++--
 arch/alpha/kernel/sys_eiger.c                    |   18 ++--
 arch/alpha/kernel/sys_jensen.c                   |   40 ++++----
 arch/alpha/kernel/sys_marvel.c                   |   26 +++---
 arch/alpha/kernel/sys_mikasa.c                   |   18 ++--
 arch/alpha/kernel/sys_noritake.c                 |   18 ++--
 arch/alpha/kernel/sys_rawhide.c                  |   19 ++--
 arch/alpha/kernel/sys_rx164.c                    |   18 ++--
 arch/alpha/kernel/sys_sable.c                    |   26 +++---
 arch/alpha/kernel/sys_takara.c                   |   18 ++--
 arch/alpha/kernel/sys_titan.c                    |   22 ++--
 arch/alpha/kernel/sys_wildfire.c                 |   32 ++++---
 arch/arm/common/gic.c                            |   20 ++--
 arch/arm/common/it8152.c                         |    8 +-
 arch/arm/common/locomo.c                         |   18 ++--
 arch/arm/common/sa1111.c                         |   58 ++++++----
 arch/arm/common/vic.c                            |   21 +++--
 arch/arm/kernel/ecard.c                          |   12 ++-
 arch/arm/kernel/smp_twd.c                        |    6 +-
 arch/arm/mach-aaec2000/core.c                    |    6 +-
 arch/arm/mach-at91/gpio.c                        |   17 ++--
 arch/arm/mach-at91/irq.c                         |   15 ++-
 arch/arm/mach-bcmring/irq.c                      |   24 +++-
 arch/arm/mach-clps711x/irq.c                     |   18 ++-
 arch/arm/mach-davinci/cp_intc.c                  |   14 ++-
 arch/arm/mach-davinci/gpio.c                     |   32 +++---
 arch/arm/mach-davinci/irq.c                      |    9 +-
 arch/arm/mach-dove/irq.c                         |    9 +-
 arch/arm/mach-ebsa110/core.c                     |    6 +-
 arch/arm/mach-ep93xx/gpio.c                      |   20 ++--
 arch/arm/mach-footbridge/common.c                |    6 +-
 arch/arm/mach-footbridge/isa-irq.c               |   18 ++-
 arch/arm/mach-gemini/gpio.c                      |   12 ++-
 arch/arm/mach-gemini/irq.c                       |    9 +-
 arch/arm/mach-h720x/common.c                     |   15 ++-
 arch/arm/mach-h720x/cpu-h7202.c                  |    8 +-
 arch/arm/mach-integrator/integrator_ap.c         |    6 +-
 arch/arm/mach-integrator/integrator_cp.c         |   18 ++-
 arch/arm/mach-iop13xx/irq.c                      |   24 +++--
 arch/arm/mach-iop13xx/msi.c                      |    2 +-
 arch/arm/mach-iop32x/irq.c                       |    6 +-
 arch/arm/mach-ixp2000/core.c                     |   30 ++++--
 arch/arm/mach-ixp2000/ixdp2x00.c                 |   10 +-
 arch/arm/mach-ixp2000/ixdp2x01.c                 |   10 +-
 arch/arm/mach-ixp23xx/core.c                     |   25 +++--
 arch/arm/mach-ixp23xx/ixdp2351.c                 |   20 ++--
 arch/arm/mach-ixp4xx/common.c                    |   14 ++-
 arch/arm/mach-ks8695/irq.c                       |   31 +++---
 arch/arm/mach-l7200/core.c                       |    6 +-
 arch/arm/mach-lh7a40x/arch-kev7a400.c            |    9 +-
 arch/arm/mach-lh7a40x/arch-lpd7a40x.c            |   13 ++-
 arch/arm/mach-lh7a40x/irq-lh7a400.c              |    9 +-
 arch/arm/mach-lh7a40x/irq-lh7a404.c              |   18 ++-
 arch/arm/mach-lh7a40x/irq-lpd7a40x.c             |   12 ++-
 arch/arm/mach-netx/generic.c                     |   12 ++-
 arch/arm/mach-nomadik/gpio.c                     |   26 +++--
 arch/arm/mach-ns9xxx/board-a9m9750dev.c          |   15 ++-
 arch/arm/mach-ns9xxx/irq.c                       |   15 ++-
 arch/arm/mach-omap1/fpga.c                       |   14 ++-
 arch/arm/mach-omap1/irq.c                        |   24 +++--
 arch/arm/mach-omap2/irq.c                        |   14 ++-
 arch/arm/mach-pnx4008/irq.c                      |   22 +++--
 arch/arm/mach-pxa/balloon3.c                     |    8 +-
 arch/arm/mach-pxa/generic.h                      |    3 +-
 arch/arm/mach-pxa/irq.c                          |   18 ++-
 arch/arm/mach-pxa/lpd270.c                       |    6 +-
 arch/arm/mach-pxa/lubbock.c                      |    6 +-
 arch/arm/mach-pxa/mainstone.c                    |    6 +-
 arch/arm/mach-pxa/pcm990-baseboard.c             |    6 +-
 arch/arm/mach-pxa/pxa25x.c                       |    4 +-
 arch/arm/mach-pxa/pxa27x.c                       |    4 +-
 arch/arm/mach-pxa/pxa3xx.c                       |    9 +-
 arch/arm/mach-pxa/viper.c                        |    9 +-
 arch/arm/mach-pxa/zeus.c                         |   12 ++-
 arch/arm/mach-rpc/irq.c                          |   27 +++--
 arch/arm/mach-s3c2410/bast-irq.c                 |   24 +++--
 arch/arm/mach-s3c2412/irq.c                      |   39 ++++---
 arch/arm/mach-s3c2440/irq.c                      |   15 ++-
 arch/arm/mach-s3c2443/irq.c                      |   75 ++++++++-----
 arch/arm/mach-sa1100/irq.c                       |   36 ++++--
 arch/arm/mach-sa1100/neponset.c                  |    8 +-
 arch/arm/mach-shark/irq.c                        |   10 ++-
 arch/arm/mach-stmp378x/stmp378x.c                |    9 +-
 arch/arm/mach-stmp37xx/stmp37xx.c                |    9 +-
 arch/arm/mach-versatile/core.c                   |    6 +-
 arch/arm/mach-w90x900/irq.c                      |    8 +-
 arch/arm/oprofile/op_model_mpcore.c              |    4 +-
 arch/arm/plat-mxc/gpio.c                         |   12 ++-
 arch/arm/plat-mxc/irq.c                          |    6 +-
 arch/arm/plat-omap/gpio.c                        |   37 ++++---
 arch/arm/plat-orion/gpio.c                       |   21 ++--
 arch/arm/plat-orion/irq.c                        |   10 +-
 arch/arm/plat-pxa/gpio.c                         |   12 ++-
 arch/arm/plat-pxa/include/plat/gpio.h            |    3 +-
 arch/arm/plat-s3c24xx/include/plat/irq.h         |    4 +-
 arch/arm/plat-s3c24xx/irq-pm.c                   |    3 +-
 arch/arm/plat-s3c24xx/irq.c                      |  116 ++++++++++++---------
 arch/arm/plat-s5pc1xx/irq-eint.c                 |   41 ++++---
 arch/arm/plat-s5pc1xx/irq-gpio.c                 |   18 ++--
 arch/arm/plat-stmp3xxx/irq.c                     |    2 +-
 arch/arm/plat-stmp3xxx/pinmux.c                  |   14 ++-
 arch/avr32/mach-at32ap/extint.c                  |   26 +++--
 arch/avr32/mach-at32ap/pio.c                     |    9 +-
 arch/blackfin/include/asm/bfin-global.h          |    2 +-
 arch/blackfin/include/asm/ipipe.h                |    4 +-
 arch/blackfin/mach-common/ints-priority.c        |   99 ++++++++++-------
 arch/cris/arch-v10/kernel/irq.c                  |   16 ++--
 arch/frv/kernel/irq-mb93091.c                    |   12 ++-
 arch/frv/kernel/irq-mb93093.c                    |   12 ++-
 arch/frv/kernel/irq-mb93493.c                    |    8 +-
 arch/frv/kernel/irq.c                            |   27 +++--
 arch/h8300/kernel/irq.c                          |   14 ++-
 arch/m32r/platforms/m32104ut/setup.c             |   19 ++--
 arch/m32r/platforms/m32700ut/setup.c             |   92 +++++++++-------
 arch/m32r/platforms/mappi/setup.c                |   23 +++--
 arch/m32r/platforms/mappi2/setup.c               |   21 ++--
 arch/m32r/platforms/mappi3/setup.c               |   21 ++--
 arch/m32r/platforms/oaks32r/setup.c              |   21 ++--
 arch/m32r/platforms/opsput/setup.c               |  124 ++++++++++++----------
 arch/m32r/platforms/usrv/setup.c                 |   42 ++++---
 arch/m68knommu/platform/5249/intc2.c             |    9 +-
 arch/m68knommu/platform/5272/intc.c              |   11 ++-
 arch/m68knommu/platform/68328/ints.c             |    6 +-
 arch/m68knommu/platform/68360/ints.c             |    9 +-
 arch/m68knommu/platform/coldfire/intc-2.c        |    6 +-
 arch/m68knommu/platform/coldfire/intc-simr.c     |    9 +-
 arch/m68knommu/platform/coldfire/intc.c          |    8 +-
 arch/microblaze/kernel/intc.c                    |   15 ++-
 arch/mips/alchemy/common/irq.c                   |   54 ++++++----
 arch/mips/alchemy/devboards/bcsr.c               |    9 +-
 arch/mips/ar7/irq.c                              |   18 ++-
 arch/mips/bcm63xx/irq.c                          |   33 ++++---
 arch/mips/cavium-octeon/octeon-irq.c             |  102 ++++++++++--------
 arch/mips/dec/ioasic-irq.c                       |   21 ++--
 arch/mips/dec/kn02-irq.c                         |   10 +-
 arch/mips/emma/markeins/irq.c                    |   24 +++--
 arch/mips/jazz/irq.c                             |    6 +-
 arch/mips/kernel/i8259.c                         |   15 ++-
 arch/mips/kernel/irq-gic.c                       |   17 ++-
 arch/mips/kernel/irq-gt641xx.c                   |   12 ++-
 arch/mips/kernel/irq-msc01.c                     |   22 +++--
 arch/mips/kernel/irq-rm7000.c                    |    6 +-
 arch/mips/kernel/irq-rm9000.c                    |   26 +++--
 arch/mips/kernel/irq_cpu.c                       |   16 ++-
 arch/mips/kernel/irq_txx9.c                      |   14 ++-
 arch/mips/lasat/interrupt.c                      |   14 ++-
 arch/mips/loongson/common/bonito-irq.c           |    6 +-
 arch/mips/nxp/pnx833x/common/interrupts.c        |   33 ++++--
 arch/mips/nxp/pnx8550/common/int.c               |    8 +-
 arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c       |   12 ++-
 arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c       |    9 +-
 arch/mips/powertv/asic/irq_asic.c                |    6 +-
 arch/mips/rb532/irq.c                            |   28 +++--
 arch/mips/sgi-ip22/ip22-int.c                    |   24 +++--
 arch/mips/sgi-ip27/ip27-irq.c                    |   12 ++-
 arch/mips/sgi-ip27/ip27-timer.c                  |    4 +-
 arch/mips/sgi-ip32/ip32-irq.c                    |   68 +++++++-----
 arch/mips/sibyte/bcm1480/irq.c                   |   28 +++--
 arch/mips/sibyte/sb1250/irq.c                    |   28 +++--
 arch/mips/sni/a20r.c                             |   12 ++-
 arch/mips/sni/pcimt.c                            |   12 ++-
 arch/mips/sni/pcit.c                             |   12 ++-
 arch/mips/sni/rm200.c                            |   21 +++--
 arch/mips/txx9/generic/irq_tx4939.c              |   14 ++-
 arch/mips/txx9/jmr3927/irq.c                     |    6 +-
 arch/mips/txx9/rbtx4927/irq.c                    |   10 +-
 arch/mips/txx9/rbtx4938/irq.c                    |   10 +-
 arch/mips/txx9/rbtx4939/irq.c                    |    6 +-
 arch/mips/vr41xx/common/icu.c                    |   12 ++-
 arch/mips/vr41xx/common/irq.c                    |    8 +-
 arch/mn10300/kernel/irq.c                        |   19 +++-
 arch/mn10300/kernel/mn10300-serial.c             |    5 +-
 arch/parisc/include/asm/irq.h                    |   11 +-
 arch/parisc/kernel/irq.c                         |   43 +++++---
 arch/powerpc/include/asm/mpic.h                  |    6 +-
 arch/powerpc/include/asm/qe_ic.h                 |    6 +-
 arch/powerpc/kernel/crash.c                      |    4 +-
 arch/powerpc/kernel/irq.c                        |    2 +-
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    6 +-
 arch/powerpc/platforms/52xx/media5200.c          |   16 ++--
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   20 ++--
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   35 ++++--
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    6 +-
 arch/powerpc/platforms/85xx/ksi8560.c            |    2 +-
 arch/powerpc/platforms/85xx/mpc85xx_ads.c        |    2 +-
 arch/powerpc/platforms/85xx/mpc85xx_ds.c         |    2 +-
 arch/powerpc/platforms/85xx/sbc8560.c            |    2 +-
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   20 +++--
 arch/powerpc/platforms/85xx/stx_gp3.c            |    2 +-
 arch/powerpc/platforms/85xx/tqm85xx.c            |    2 +-
 arch/powerpc/platforms/86xx/gef_pic.c            |   12 ++-
 arch/powerpc/platforms/86xx/pic.c                |    2 +-
 arch/powerpc/platforms/8xx/m8xx_setup.c          |    4 +-
 arch/powerpc/platforms/cell/axon_msi.c           |    2 +-
 arch/powerpc/platforms/cell/beat_interrupt.c     |   14 ++-
 arch/powerpc/platforms/cell/interrupt.c          |   12 +-
 arch/powerpc/platforms/cell/setup.c              |    2 +-
 arch/powerpc/platforms/cell/spider-pic.c         |   15 ++-
 arch/powerpc/platforms/chrp/setup.c              |    2 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |   12 ++-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   26 +++--
 arch/powerpc/platforms/iseries/irq.c             |   19 ++--
 arch/powerpc/platforms/pasemi/setup.c            |    4 +-
 arch/powerpc/platforms/powermac/pic.c            |   23 +++--
 arch/powerpc/platforms/ps3/interrupt.c           |   27 +++--
 arch/powerpc/platforms/pseries/setup.c           |    2 +-
 arch/powerpc/platforms/pseries/xics.c            |   27 +++--
 arch/powerpc/sysdev/cpm1.c                       |    9 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |   18 ++--
 arch/powerpc/sysdev/fsl_msi.c                    |   12 +-
 arch/powerpc/sysdev/i8259.c                      |   11 ++-
 arch/powerpc/sysdev/ipic.c                       |   16 ++-
 arch/powerpc/sysdev/mpc8xx_pic.c                 |   16 ++-
 arch/powerpc/sysdev/mpic.c                       |   50 +++++----
 arch/powerpc/sysdev/mpic.h                       |    4 +-
 arch/powerpc/sysdev/mpic_pasemi_msi.c            |   14 ++-
 arch/powerpc/sysdev/mpic_u3msi.c                 |   12 +-
 arch/powerpc/sysdev/mv64x60_pic.c                |   21 +++--
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |    6 +-
 arch/powerpc/sysdev/tsi108_pci.c                 |   14 ++-
 arch/powerpc/sysdev/uic.c                        |   36 ++++---
 arch/powerpc/sysdev/xilinx_intc.c                |   26 +++--
 arch/score/kernel/irq.c                          |   10 +-
 arch/sh/boards/mach-cayman/irq.c                 |   10 +-
 arch/sh/boards/mach-dreamcast/irq.c              |    9 +-
 arch/sh/boards/mach-landisk/irq.c                |    6 +-
 arch/sh/boards/mach-microdev/irq.c               |   19 ++--
 arch/sh/boards/mach-se/7206/irq.c                |    9 +-
 arch/sh/boards/mach-se/7343/irq.c                |    8 +-
 arch/sh/boards/mach-se/7722/irq.c                |    8 +-
 arch/sh/boards/mach-se/7724/irq.c                |    6 +-
 arch/sh/boards/mach-systemh/irq.c                |   16 ++--
 arch/sh/cchips/hd6446x/hd64461.c                 |   11 ++-
 arch/sh/kernel/cpu/irq/imask.c                   |    6 +-
 arch/sh/kernel/cpu/irq/intc-sh5.c                |   34 +++---
 arch/sparc/kernel/irq_64.c                       |   78 ++++++++------
 arch/xtensa/variants/s6000/gpio.c                |   18 ++--
 drivers/sh/intc.c                                |   11 +-
 247 files changed, 2572 insertions(+), 1749 deletions(-)

diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index 1448b33..b55b054 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -233,33 +233,33 @@
 		are used by the default flow implementations.
 		The following helper functions are implemented (simplified excerpt):
 		<programlisting>
-default_enable(irq)
+default_enable(desc)
 {
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
-default_disable(irq)
+default_disable(desc)
 {
-	if (!delay_disable(irq))
-		desc->chip->mask(irq);
+	if (!delay_disable(desc->irq))
+		desc->chip->mask(desc);
 }
 
-default_ack(irq)
+default_ack(desc)
 {
-	chip->ack(irq);
+	chip->ack(desc);
 }
 
-default_mask_ack(irq)
+default_mask_ack(desc)
 {
 	if (chip->mask_ack) {
-		chip->mask_ack(irq);
+		chip->mask_ack(desc);
 	} else {
-		chip->mask(irq);
-		chip->ack(irq);
+		chip->mask(desc);
+		chip->ack(desc);
 	}
 }
 
-noop(irq)
+noop(desc)
 {
 }
 
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index cfde865..beb8e3f 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -218,8 +218,8 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
  * processed by PALcode, and comes in via entInt vector 1.
  */
 
-static void rtc_enable_disable(unsigned int irq) { }
-static unsigned int rtc_startup(unsigned int irq) { return 0; }
+static void rtc_enable_disable(struct irq_desc *desc) { }
+static unsigned int rtc_startup(struct irq_desc *desc) { return 0; }
 
 struct irqaction timer_irqaction = {
 	.handler	= timer_interrupt,
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 83a9ac2..2470b14 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -33,8 +33,10 @@ i8259_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 inline void
-i8259a_enable_irq(unsigned int irq)
+i8259a_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	spin_lock(&i8259_irq_lock);
 	i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq));
 	spin_unlock(&i8259_irq_lock);
@@ -47,16 +49,18 @@ __i8259a_disable_irq(unsigned int irq)
 }
 
 void
-i8259a_disable_irq(unsigned int irq)
+i8259a_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&i8259_irq_lock);
-	__i8259a_disable_irq(irq);
+	__i8259a_disable_irq(desc->irq);
 	spin_unlock(&i8259_irq_lock);
 }
 
 void
-i8259a_mask_and_ack_irq(unsigned int irq)
+i8259a_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	spin_lock(&i8259_irq_lock);
 	__i8259a_disable_irq(irq);
 
@@ -70,17 +74,17 @@ i8259a_mask_and_ack_irq(unsigned int irq)
 }
 
 unsigned int
-i8259a_startup_irq(unsigned int irq)
+i8259a_startup_irq(struct irq_desc *desc)
 {
-	i8259a_enable_irq(irq);
+	i8259a_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 void
-i8259a_end_irq(unsigned int irq)
+i8259a_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		i8259a_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		i8259a_enable_irq(desc);
 }
 
 struct irq_chip i8259a_irq_type = {
diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h
index b63ccd7..24e308e 100644
--- a/arch/alpha/kernel/irq_impl.h
+++ b/arch/alpha/kernel/irq_impl.h
@@ -31,11 +31,11 @@ extern void init_rtc_irq(void);
 
 extern void common_init_isa_dma(void);
 
-extern void i8259a_enable_irq(unsigned int);
-extern void i8259a_disable_irq(unsigned int);
-extern void i8259a_mask_and_ack_irq(unsigned int);
-extern unsigned int i8259a_startup_irq(unsigned int);
-extern void i8259a_end_irq(unsigned int);
+extern void i8259a_enable_irq(struct irq_desc *desc);
+extern void i8259a_disable_irq(struct irq_desc *desc);
+extern void i8259a_mask_and_ack_irq(struct irq_desc *desc);
+extern unsigned int i8259a_startup_irq(struct irq_desc *desc);
+extern void i8259a_end_irq(struct irq_desc *desc);
 extern struct irq_chip i8259a_irq_type;
 extern void init_i8259a_irqs(void);
 
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c
index 989ce46..dae795e 100644
--- a/arch/alpha/kernel/irq_pyxis.c
+++ b/arch/alpha/kernel/irq_pyxis.c
@@ -29,34 +29,35 @@ pyxis_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-pyxis_enable_irq(unsigned int irq)
+pyxis_enable_irq(struct irq_desc *desc)
 {
-	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-pyxis_disable_irq(unsigned int irq)
+pyxis_disable_irq(struct irq_desc *desc)
 {
-	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static unsigned int
-pyxis_startup_irq(unsigned int irq)
+pyxis_startup_irq(struct irq_desc *desc)
 {
-	pyxis_enable_irq(irq);
+	pyxis_enable_irq(desc);
 	return 0;
 }
 
 static void
-pyxis_end_irq(unsigned int irq)
+pyxis_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		pyxis_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		pyxis_enable_irq(desc);
 }
 
 static void
-pyxis_mask_and_ack_irq(unsigned int irq)
+pyxis_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long bit = 1UL << (irq - 16);
 	unsigned long mask = cached_irq_mask &= ~bit;
 
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index d63e93e..5e6b09a 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -18,33 +18,33 @@
 DEFINE_SPINLOCK(srm_irq_lock);
 
 static inline void
-srm_enable_irq(unsigned int irq)
+srm_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&srm_irq_lock);
-	cserve_ena(irq - 16);
+	cserve_ena(desc->irq - 16);
 	spin_unlock(&srm_irq_lock);
 }
 
 static void
-srm_disable_irq(unsigned int irq)
+srm_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&srm_irq_lock);
-	cserve_dis(irq - 16);
+	cserve_dis(desc->irq - 16);
 	spin_unlock(&srm_irq_lock);
 }
 
 static unsigned int
-srm_startup_irq(unsigned int irq)
+srm_startup_irq(struct irq_desc *desc)
 {
-	srm_enable_irq(irq);
+	srm_enable_irq(desc);
 	return 0;
 }
 
 static void
-srm_end_irq(unsigned int irq)
+srm_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		srm_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		srm_enable_irq(desc);
 }
 
 /* Handle interrupts from the SRM, assuming no additional weirdness.  */
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 20a30b8..3ba8767 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -44,38 +44,38 @@ alcor_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-alcor_enable_irq(unsigned int irq)
+alcor_enable_irq(struct irq_desc *desc)
 {
-	alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	alcor_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-alcor_disable_irq(unsigned int irq)
+alcor_disable_irq(struct irq_desc *desc)
 {
-	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static void
-alcor_mask_and_ack_irq(unsigned int irq)
+alcor_mask_and_ack_irq(struct irq_desc *desc)
 {
-	alcor_disable_irq(irq);
+	alcor_disable_irq(desc);
 
 	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */
-	*(vuip)GRU_INT_CLEAR = 1 << (irq - 16); mb();
+	*(vuip)GRU_INT_CLEAR = 1 << (desc->irq - 16); mb();
 	*(vuip)GRU_INT_CLEAR = 0; mb();
 }
 
 static unsigned int
-alcor_startup_irq(unsigned int irq)
+alcor_startup_irq(struct irq_desc *desc)
 {
-	alcor_enable_irq(irq);
+	alcor_enable_irq(desc);
 	return 0;
 }
 
 static void
-alcor_isa_mask_and_ack_irq(unsigned int irq)
+alcor_isa_mask_and_ack_irq(struct irq_desc *desc)
 {
-	i8259a_mask_and_ack_irq(irq);
+	i8259a_mask_and_ack_irq(desc);
 
 	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */
 	*(vuip)GRU_INT_CLEAR = 0x80000000; mb();
@@ -83,10 +83,10 @@ alcor_isa_mask_and_ack_irq(unsigned int irq)
 }
 
 static void
-alcor_end_irq(unsigned int irq)
+alcor_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		alcor_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		alcor_enable_irq(desc);
 }
 
 static struct irq_chip alcor_irq_type = {
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index affd0f3..ecbca6b 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -46,29 +46,33 @@ cabriolet_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 static inline void
-cabriolet_enable_irq(unsigned int irq)
+cabriolet_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	cabriolet_update_irq_hw(irq, cached_irq_mask &= ~(1UL << irq));
 }
 
 static void
-cabriolet_disable_irq(unsigned int irq)
+cabriolet_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	cabriolet_update_irq_hw(irq, cached_irq_mask |= 1UL << irq);
 }
 
 static unsigned int
-cabriolet_startup_irq(unsigned int irq)
+cabriolet_startup_irq(struct irq_desc *desc)
 { 
-	cabriolet_enable_irq(irq);
+	cabriolet_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-cabriolet_end_irq(unsigned int irq)
+cabriolet_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		cabriolet_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		cabriolet_enable_irq(desc);
 }
 
 static struct irq_chip cabriolet_irq_type = {
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 4026502..998f813 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -98,67 +98,67 @@ tsunami_update_irq_hw(unsigned long mask)
 }
 
 static void
-dp264_enable_irq(unsigned int irq)
+dp264_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask |= 1UL << irq;
+	cached_irq_mask |= 1UL << desc->irq;
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static void
-dp264_disable_irq(unsigned int irq)
+dp264_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask &= ~(1UL << irq);
+	cached_irq_mask &= ~(1UL << desc->irq);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static unsigned int
-dp264_startup_irq(unsigned int irq)
+dp264_startup_irq(struct irq_desc *desc)
 { 
-	dp264_enable_irq(irq);
+	dp264_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-dp264_end_irq(unsigned int irq)
+dp264_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		dp264_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		dp264_enable_irq(desc);
 }
 
 static void
-clipper_enable_irq(unsigned int irq)
+clipper_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask |= 1UL << (irq - 16);
+	cached_irq_mask |= 1UL << (desc->irq - 16);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static void
-clipper_disable_irq(unsigned int irq)
+clipper_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&dp264_irq_lock);
-	cached_irq_mask &= ~(1UL << (irq - 16));
+	cached_irq_mask &= ~(1UL << (desc->irq - 16));
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 }
 
 static unsigned int
-clipper_startup_irq(unsigned int irq)
+clipper_startup_irq(struct irq_desc *desc)
 { 
-	clipper_enable_irq(irq);
+	clipper_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-clipper_end_irq(unsigned int irq)
+clipper_end_irq(struct irq_desc *desc)
 { 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		clipper_enable_irq(irq);
+	if (!(irq_desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		clipper_enable_irq(desc);
 }
 
 static void
@@ -177,10 +177,10 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 }
 
 static int
-dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
+dp264_set_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&dp264_irq_lock);
-	cpu_set_irq_affinity(irq, *affinity);
+	cpu_set_irq_affinity(desc->irq, *affinity);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 
@@ -188,10 +188,10 @@ dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
 }
 
 static int
-clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
+clipper_set_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&dp264_irq_lock);
-	cpu_set_irq_affinity(irq - 16, *affinity);
+	cpu_set_irq_affinity(desc->irq - 16, *affinity);
 	tsunami_update_irq_hw(cached_irq_mask);
 	spin_unlock(&dp264_irq_lock);
 
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index df2090c..8f6b901 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -44,29 +44,33 @@ eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
 }
 
 static inline void
-eb64p_enable_irq(unsigned int irq)
+eb64p_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	eb64p_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq));
 }
 
 static void
-eb64p_disable_irq(unsigned int irq)
+eb64p_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq);
 }
 
 static unsigned int
-eb64p_startup_irq(unsigned int irq)
+eb64p_startup_irq(struct irq_desc *desc)
 {
-	eb64p_enable_irq(irq);
+	eb64p_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-eb64p_end_irq(unsigned int irq)
+eb64p_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		eb64p_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		eb64p_enable_irq(desc);
 }
 
 static struct irq_chip eb64p_irq_type = {
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 3ca1dbc..57e0094 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -51,33 +51,37 @@ eiger_update_irq_hw(unsigned long irq, unsigned long mask)
 }
 
 static inline void
-eiger_enable_irq(unsigned int irq)
+eiger_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
 	eiger_update_irq_hw(irq, mask);
 }
 
 static void
-eiger_disable_irq(unsigned int irq)
+eiger_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
 	eiger_update_irq_hw(irq, mask);
 }
 
 static unsigned int
-eiger_startup_irq(unsigned int irq)
+eiger_startup_irq(struct irq_desc *desc)
 {
-	eiger_enable_irq(irq);
+	eiger_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-eiger_end_irq(unsigned int irq)
+eiger_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		eiger_enable_irq(irq);
+	if (!(irq_desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		eiger_enable_irq(desc);
 }
 
 static struct irq_chip eiger_irq_type = {
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 7a7ae36..8ee81c6 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -63,59 +63,59 @@
  */
 
 static unsigned int
-jensen_local_startup(unsigned int irq)
+jensen_local_startup(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_startup_irq(1);
+	if (desc->irq == 7)
+		i8259a_startup_irq(irq_to_desc(1));
 	else
 		/*
 		 * For all true local interrupts, set the flag that prevents
 		 * the IPL from being dropped during handler processing.
 		 */
-		if (irq_desc[irq].action)
-			irq_desc[irq].action->flags |= IRQF_DISABLED;
+		if (desc->action)
+			desc->action->flags |= IRQF_DISABLED;
 	return 0;
 }
 
 static void
-jensen_local_shutdown(unsigned int irq)
+jensen_local_shutdown(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_disable_irq(1);
+	if (desc->irq == 7)
+		i8259a_disable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_enable(unsigned int irq)
+jensen_local_enable(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_enable_irq(1);
+	if (desc->irq == 7)
+		i8259a_enable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_disable(unsigned int irq)
+jensen_local_disable(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_disable_irq(1);
+	if (desc->irq == 7)
+		i8259a_disable_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_ack(unsigned int irq)
+jensen_local_ack(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_mask_and_ack_irq(1);
+	if (desc->irq == 7)
+		i8259a_mask_and_ack_irq(irq_to_desc(1));
 }
 
 static void
-jensen_local_end(unsigned int irq)
+jensen_local_end(struct irq_desc *desc)
 {
 	/* the parport is really hw IRQ 1, silly Jensen.  */
-	if (irq == 7)
-		i8259a_end_irq(1);
+	if (desc->irq == 7)
+		i8259a_end_irq(irq_to_desc(1));
 }
 
 static struct irq_chip jensen_local_irq_type = {
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 0bb3b5c..5229f49 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -104,15 +104,15 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
 }
 
 static void
-io7_enable_irq(unsigned int irq)
+io7_enable_irq(struct irq_desc *desc)
 {
 	volatile unsigned long *ctl;
 	struct io7 *io7;
 
-	ctl = io7_get_irq_ctl(irq, &io7);
+	ctl = io7_get_irq_ctl(desc->irq, &io7);
 	if (!ctl || !io7) {
 		printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
-		       __func__, irq);
+		       __func__, desc->irq);
 		return;
 	}
 		
@@ -124,15 +124,15 @@ io7_enable_irq(unsigned int irq)
 }
 
 static void
-io7_disable_irq(unsigned int irq)
+io7_disable_irq(struct irq_desc *desc)
 {
 	volatile unsigned long *ctl;
 	struct io7 *io7;
 
-	ctl = io7_get_irq_ctl(irq, &io7);
+	ctl = io7_get_irq_ctl(desc->irq, &io7);
 	if (!ctl || !io7) {
 		printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
-		       __func__, irq);
+		       __func__, desc->irq);
 		return;
 	}
 		
@@ -144,27 +144,27 @@ io7_disable_irq(unsigned int irq)
 }
 
 static unsigned int
-io7_startup_irq(unsigned int irq)
+io7_startup_irq(struct irq_desc *desc)
 {
-	io7_enable_irq(irq);
+	io7_enable_irq(desc);
 	return 0;	/* never anything pending */
 }
 
 static void
-io7_end_irq(unsigned int irq)
+io7_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		io7_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		io7_enable_irq(desc);
 }
 
 static void
-marvel_irq_noop(unsigned int irq) 
+marvel_irq_noop(struct irq_desc *desc)
 { 
 	return; 
 }
 
 static unsigned int
-marvel_irq_noop_return(unsigned int irq) 
+marvel_irq_noop_return(struct irq_desc *desc)
 { 
 	return 0; 
 }
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index ee88651..d4ce8f3 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -43,29 +43,29 @@ mikasa_update_irq_hw(int mask)
 }
 
 static inline void
-mikasa_enable_irq(unsigned int irq)
+mikasa_enable_irq(struct irq_desc *desc)
 {
-	mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16));
+	mikasa_update_irq_hw(cached_irq_mask |= 1 << (desc->irq - 16));
 }
 
 static void
-mikasa_disable_irq(unsigned int irq)
+mikasa_disable_irq(struct irq_desc *desc)
 {
-	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16)));
+	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (desc->irq - 16)));
 }
 
 static unsigned int
-mikasa_startup_irq(unsigned int irq)
+mikasa_startup_irq(struct irq_desc *desc)
 {
-	mikasa_enable_irq(irq);
+	mikasa_enable_irq(desc);
 	return 0;
 }
 
 static void
-mikasa_end_irq(unsigned int irq)
+mikasa_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		mikasa_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		mikasa_enable_irq(desc);
 }
 
 static struct irq_chip mikasa_irq_type = {
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 86503fe..5d175de 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -48,29 +48,33 @@ noritake_update_irq_hw(int irq, int mask)
 }
 
 static void
-noritake_enable_irq(unsigned int irq)
+noritake_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	noritake_update_irq_hw(irq, cached_irq_mask |= 1 << (irq - 16));
 }
 
 static void
-noritake_disable_irq(unsigned int irq)
+noritake_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16)));
 }
 
 static unsigned int
-noritake_startup_irq(unsigned int irq)
+noritake_startup_irq(struct irq_desc *desc)
 {
-	noritake_enable_irq(irq);
+	noritake_enable_irq(desc);
 	return 0;
 }
 
 static void
-noritake_end_irq(unsigned int irq)
+noritake_end_irq(struct irq_desc *desc)
 {
-        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-                noritake_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		noritake_enable_irq(desc);
 }
 
 static struct irq_chip noritake_irq_type = {
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 26c322b..e1dacac 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -56,8 +56,9 @@ rawhide_update_irq_hw(int hose, int mask)
   (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))
 
 static inline void 
-rawhide_enable_irq(unsigned int irq)
+rawhide_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, hose;
 
 	irq -= 16;
@@ -76,8 +77,9 @@ rawhide_enable_irq(unsigned int irq)
 }
 
 static void 
-rawhide_disable_irq(unsigned int irq)
+rawhide_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, hose;
 
 	irq -= 16;
@@ -96,8 +98,9 @@ rawhide_disable_irq(unsigned int irq)
 }
 
 static void
-rawhide_mask_and_ack_irq(unsigned int irq)
+rawhide_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask, mask1, hose;
 
 	irq -= 16;
@@ -122,17 +125,17 @@ rawhide_mask_and_ack_irq(unsigned int irq)
 }
 
 static unsigned int
-rawhide_startup_irq(unsigned int irq)
+rawhide_startup_irq(struct irq_desc *desc)
 {
-	rawhide_enable_irq(irq);
+	rawhide_enable_irq(desc);
 	return 0;
 }
 
 static void
-rawhide_end_irq(unsigned int irq)
+rawhide_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		rawhide_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		rawhide_enable_irq(desc);
 }
 
 static struct irq_chip rawhide_irq_type = {
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index be16112..31cb57e 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -47,29 +47,29 @@ rx164_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-rx164_enable_irq(unsigned int irq)
+rx164_enable_irq(struct irq_desc *desc)
 {
-	rx164_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+	rx164_update_irq_hw(cached_irq_mask |= 1UL << (desc->irq - 16));
 }
 
 static void
-rx164_disable_irq(unsigned int irq)
+rx164_disable_irq(struct irq_desc *desc)
 {
-	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
+	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (desc->irq - 16)));
 }
 
 static unsigned int
-rx164_startup_irq(unsigned int irq)
+rx164_startup_irq(struct irq_desc *desc)
 {
-	rx164_enable_irq(irq);
+	rx164_enable_irq(desc);
 	return 0;
 }
 
 static void
-rx164_end_irq(unsigned int irq)
+rx164_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		rx164_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		rx164_enable_irq(desc);
 }
 
 static struct irq_chip rx164_irq_type = {
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index b2abe27..0eca307 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -443,57 +443,57 @@ lynx_swizzle(struct pci_dev *dev, u8 *pinp)
 /* GENERIC irq routines */
 
 static inline void
-sable_lynx_enable_irq(unsigned int irq)
+sable_lynx_enable_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit);
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
 	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
-	       __func__, mask, bit, irq);
+	       __func__, mask, bit, desc->irq);
 #endif
 }
 
 static void
-sable_lynx_disable_irq(unsigned int irq)
+sable_lynx_disable_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
 	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
-	       __func__, mask, bit, irq);
+	       __func__, mask, bit, desc->irq);
 #endif
 }
 
 static unsigned int
-sable_lynx_startup_irq(unsigned int irq)
+sable_lynx_startup_irq(struct irq_desc *desc)
 {
-	sable_lynx_enable_irq(irq);
+	sable_lynx_enable_irq(desc);
 	return 0;
 }
 
 static void
-sable_lynx_end_irq(unsigned int irq)
+sable_lynx_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		sable_lynx_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		sable_lynx_enable_irq(desc);
 }
 
 static void
-sable_lynx_mask_and_ack_irq(unsigned int irq)
+sable_lynx_mask_and_ack_irq(struct irq_desc *desc)
 {
 	unsigned long bit, mask;
 
-	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	bit = sable_lynx_irq_swizzle->irq_to_mask[desc->irq];
 	spin_lock(&sable_lynx_irq_lock);
 	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 2304648..6c6fa86 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -45,33 +45,37 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask)
 }
 
 static inline void
-takara_enable_irq(unsigned int irq)
+takara_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
 	takara_update_irq_hw(irq, mask);
 }
 
 static void
-takara_disable_irq(unsigned int irq)
+takara_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
+
 	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
 	takara_update_irq_hw(irq, mask);
 }
 
 static unsigned int
-takara_startup_irq(unsigned int irq)
+takara_startup_irq(struct irq_desc *desc)
 {
-	takara_enable_irq(irq);
+	takara_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-takara_end_irq(unsigned int irq)
+takara_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		takara_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		takara_enable_irq(desc);
 }
 
 static struct irq_chip takara_irq_type = {
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 9008d0f..73f661c 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -112,35 +112,35 @@ titan_update_irq_hw(unsigned long mask)
 }
 
 static inline void
-titan_enable_irq(unsigned int irq)
+titan_enable_irq(struct irq_desc *desc)
 {
 	spin_lock(&titan_irq_lock);
-	titan_cached_irq_mask |= 1UL << (irq - 16);
+	titan_cached_irq_mask |= 1UL << (desc->irq - 16);
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static inline void
-titan_disable_irq(unsigned int irq)
+titan_disable_irq(struct irq_desc *desc)
 {
 	spin_lock(&titan_irq_lock);
-	titan_cached_irq_mask &= ~(1UL << (irq - 16));
+	titan_cached_irq_mask &= ~(1UL << (desc->irq - 16));
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static unsigned int
-titan_startup_irq(unsigned int irq)
+titan_startup_irq(struct irq_desc *desc)
 {
-	titan_enable_irq(irq);
+	titan_enable_irq(desc);
 	return 0;	/* never anything pending */
 }
 
 static void
-titan_end_irq(unsigned int irq)
+titan_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		titan_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		titan_enable_irq(desc);
 }
 
 static void
@@ -158,10 +158,10 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 }
 
 static int
-titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
+titan_set_irq_affinity(struct irq_desc *desc, const struct cpumask *affinity)
 { 
 	spin_lock(&titan_irq_lock);
-	titan_cpu_set_irq_affinity(irq - 16, *affinity);
+	titan_cpu_set_irq_affinity(desc->irq - 16, *affinity);
 	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index 62fd972..e67555b 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -104,10 +104,12 @@ wildfire_init_irq_hw(void)
 }
 
 static void
-wildfire_enable_irq(unsigned int irq)
+wildfire_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_enable_irq(irq);
+		i8259a_enable_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	set_bit(irq, &cached_irq_mask);
@@ -116,10 +118,12 @@ wildfire_enable_irq(unsigned int irq)
 }
 
 static void
-wildfire_disable_irq(unsigned int irq)
+wildfire_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_disable_irq(irq);
+		i8259a_disable_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	clear_bit(irq, &cached_irq_mask);
@@ -128,10 +132,12 @@ wildfire_disable_irq(unsigned int irq)
 }
 
 static void
-wildfire_mask_and_ack_irq(unsigned int irq)
+wildfire_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	if (irq < 16)
-		i8259a_mask_and_ack_irq(irq);
+		i8259a_mask_and_ack_irq(desc);
 
 	spin_lock(&wildfire_irq_lock);
 	clear_bit(irq, &cached_irq_mask);
@@ -140,21 +146,21 @@ wildfire_mask_and_ack_irq(unsigned int irq)
 }
 
 static unsigned int
-wildfire_startup_irq(unsigned int irq)
+wildfire_startup_irq(struct irq_desc *desc)
 { 
-	wildfire_enable_irq(irq);
+	wildfire_enable_irq(desc);
 	return 0; /* never anything pending */
 }
 
 static void
-wildfire_end_irq(unsigned int irq)
+wildfire_end_irq(struct irq_desc *desc)
 { 
 #if 0
-	if (!irq_desc[irq].action)
-		printk("got irq %d\n", irq);
+	if (!desc->action)
+		printk("got irq %d\n", desc->irq);
 #endif
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		wildfire_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		wildfire_enable_irq(desc);
 }
 
 static struct irq_chip wildfire_irq_type = {
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 337741f..7e7f9f7 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -80,8 +80,9 @@ static inline unsigned int gic_irq(unsigned int irq)
  * our "acknowledge" routine disable the interrupt, then mark it as
  * complete.
  */
-static void gic_ack_irq(unsigned int irq)
+static void gic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -90,8 +91,9 @@ static void gic_ack_irq(unsigned int irq)
 	spin_unlock(&irq_controller_lock);
 }
 
-static void gic_mask_irq(unsigned int irq)
+static void gic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -99,8 +101,9 @@ static void gic_mask_irq(unsigned int irq)
 	spin_unlock(&irq_controller_lock);
 }
 
-static void gic_unmask_irq(unsigned int irq)
+static void gic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
@@ -109,8 +112,9 @@ static void gic_unmask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
+static int gic_set_cpu(struct irq_desc *desc, const struct cpumask *mask_val)
 {
+	unsigned int irq = desc->irq;
 	void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
 	unsigned int shift = (irq % 4) * 8;
 	unsigned int cpu = cpumask_first(mask_val);
@@ -129,13 +133,13 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
 
 static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 {
-	struct gic_chip_data *chip_data = get_irq_data(irq);
-	struct irq_chip *chip = get_irq_chip(irq);
+	struct gic_chip_data *chip_data = get_irq_desc_data(desc);
+	struct irq_chip *chip = get_irq_desc_chip(desc);
 	unsigned int cascade_irq, gic_irq;
 	unsigned long status;
 
 	/* primary controller ack'ing */
-	chip->ack(irq);
+	chip->ack(desc);
 
 	spin_lock(&irq_controller_lock);
 	status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
@@ -153,7 +157,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 
  out:
 	/* primary controller unmasking */
-	chip->unmask(irq);
+	chip->unmask(desc);
 }
 
 static struct irq_chip gic_chip = {
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index ee1d3b8..94f5146 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -32,8 +32,10 @@
 
 #define MAX_SLOTS		21
 
-static void it8152_mask_irq(unsigned int irq)
+static void it8152_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
        if (irq >= IT8152_LD_IRQ(0)) {
 	       __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) |
 			    (1 << (irq - IT8152_LD_IRQ(0)))),
@@ -49,8 +51,10 @@ static void it8152_mask_irq(unsigned int irq)
        }
 }
 
-static void it8152_unmask_irq(unsigned int irq)
+static void it8152_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
        if (irq >= IT8152_LD_IRQ(0)) {
 	       __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) &
 			     ~(1 << (irq - IT8152_LD_IRQ(0)))),
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 90ae00b..d91ec74 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -140,11 +140,11 @@ static struct locomo_dev_info locomo_devices[] = {
 
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	int req, i;
 
 	/* Acknowledge the parent IRQ */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	/* check why this interrupt was generated */
 	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
@@ -154,29 +154,31 @@ static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 		irq = lchip->irq_base;
 		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0100 << i)) {
-				generic_handle_irq(irq);
+				generic_handle_irq_desc(irq, desc);
 			}
 
 		}
 	}
 }
 
-static void locomo_ack_irq(unsigned int irq)
+static void locomo_ack_irq(struct irq_desc *desc)
 {
 }
 
-static void locomo_mask_irq(unsigned int irq)
+static void locomo_mask_irq(struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	unsigned int r;
 	r = locomo_readl(lchip->base + LOCOMO_ICR);
 	r &= ~(0x0010 << (irq - lchip->irq_base));
 	locomo_writel(r, lchip->base + LOCOMO_ICR);
 }
 
-static void locomo_unmask_irq(unsigned int irq)
+static void locomo_unmask_irq(struct irq_desc *desc)
 {
-	struct locomo *lchip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct locomo *lchip = get_irq_desc_chip_data(desc);
 	unsigned int r;
 	r = locomo_readl(lchip->base + LOCOMO_ICR);
 	r |= (0x0010 << (irq - lchip->irq_base));
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a52a27c..dff6946 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -205,7 +205,7 @@ static void
 sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int stat0, stat1, i;
-	struct sa1111 *sachip = get_irq_data(irq);
+	struct sa1111 *sachip = get_irq_desc_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 
 	stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
@@ -213,7 +213,7 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 	sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
 
@@ -231,19 +231,20 @@ sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 			generic_handle_irq(i + sachip->irq_base);
 
 	/* For level-based interrupts */
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 #define SA1111_IRQMASK_LO(x)	(1 << (x - sachip->irq_base))
 #define SA1111_IRQMASK_HI(x)	(1 << (x - sachip->irq_base - 32))
 
-static void sa1111_ack_irq(unsigned int irq)
+static void sa1111_ack_irq(struct irq_desc *desc)
 {
 }
 
-static void sa1111_mask_lowirq(unsigned int irq)
+static void sa1111_mask_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
@@ -252,9 +253,10 @@ static void sa1111_mask_lowirq(unsigned int irq)
 	writel(ie0, mapbase + SA1111_INTEN0);
 }
 
-static void sa1111_unmask_lowirq(unsigned int irq)
+static void sa1111_unmask_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
@@ -270,9 +272,10 @@ static void sa1111_unmask_lowirq(unsigned int irq)
  * be triggered.  In fact, its very difficult, if not impossible to get
  * INTSET to re-trigger the interrupt.
  */
-static int sa1111_retrigger_lowirq(unsigned int irq)
+static int sa1111_retrigger_lowirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long ip0;
@@ -292,9 +295,10 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
 	return i == 8 ? -1 : 0;
 }
 
-static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_lowirq(struct irq_desc *desc, unsigned int flags)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long ip0;
@@ -316,9 +320,10 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
 	return 0;
 }
 
-static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_lowirq(struct irq_desc *desc, unsigned int on)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
 	unsigned long we0;
@@ -343,9 +348,10 @@ static struct irq_chip sa1111_low_chip = {
 	.set_wake	= sa1111_wake_lowirq,
 };
 
-static void sa1111_mask_highirq(unsigned int irq)
+static void sa1111_mask_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
@@ -354,9 +360,10 @@ static void sa1111_mask_highirq(unsigned int irq)
 	sa1111_writel(ie1, mapbase + SA1111_INTEN1);
 }
 
-static void sa1111_unmask_highirq(unsigned int irq)
+static void sa1111_unmask_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
@@ -372,9 +379,10 @@ static void sa1111_unmask_highirq(unsigned int irq)
  * be triggered.  In fact, its very difficult, if not impossible to get
  * INTSET to re-trigger the interrupt.
  */
-static int sa1111_retrigger_highirq(unsigned int irq)
+static int sa1111_retrigger_highirq(struct irq_desc *desc)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long ip1;
@@ -394,9 +402,10 @@ static int sa1111_retrigger_highirq(unsigned int irq)
 	return i == 8 ? -1 : 0;
 }
 
-static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
+static int sa1111_type_highirq(struct irq_desc *desc, unsigned int flags)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long ip1;
@@ -418,9 +427,10 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
 	return 0;
 }
 
-static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
+static int sa1111_wake_highirq(struct irq_desc *desc, unsigned int on)
 {
-	struct sa1111 *sachip = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct sa1111 *sachip = get_irq_desc_chip_data(desc);
 	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
 	unsigned long we1;
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 1cf999a..c4a5dcd 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -204,25 +204,31 @@ static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 res
 static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
 #endif /* CONFIG_PM */
 
-static void vic_ack_irq(unsigned int irq)
+static void vic_ack_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 	/* moreover, clear the soft-triggered, in case it was the reason */
 	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
 }
 
-static void vic_mask_irq(unsigned int irq)
+static void vic_mask_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
 }
 
-static void vic_unmask_irq(unsigned int irq)
+static void vic_unmask_irq(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
+
 	irq &= 31;
 	writel(1 << irq, base + VIC_INT_ENABLE);
 }
@@ -242,8 +248,9 @@ static struct vic_device *vic_from_irq(unsigned int irq)
 	return NULL;
 }
 
-static int vic_set_wake(unsigned int irq, unsigned int on)
+static int vic_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	struct vic_device *v = vic_from_irq(irq);
 	unsigned int off = irq & 31;
 	u32 bit = 1 << off;
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index eed2f79..7310a4d 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -443,8 +443,9 @@ static expansioncard_ops_t ecard_default_ops = {
  *
  * They are not meant to be called directly, but via enable/disable_irq.
  */
-static void ecard_irq_unmask(unsigned int irqnr)
+static void ecard_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irqnr = desc->irq;
 	ecard_t *ec = slot_to_ecard(irqnr - 32);
 
 	if (ec) {
@@ -459,8 +460,9 @@ static void ecard_irq_unmask(unsigned int irqnr)
 	}
 }
 
-static void ecard_irq_mask(unsigned int irqnr)
+static void ecard_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irqnr = desc->irq;
 	ecard_t *ec = slot_to_ecard(irqnr - 32);
 
 	if (ec) {
@@ -551,7 +553,7 @@ static void ecard_check_lockup(struct irq_desc *desc)
 			printk(KERN_ERR "\nInterrupt lockup detected - "
 			       "disabling all expansion card interrupts\n");
 
-			desc->chip->mask(IRQ_EXPANSIONCARD);
+			desc->chip->mask(irq_to_desc(IRQ_EXPANSIONCARD));
 			ecard_dump_irq_state();
 		}
 	} else
@@ -574,7 +576,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 	ecard_t *ec;
 	int called = 0;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 	for (ec = cards; ec; ec = ec->next) {
 		int pending;
 
@@ -591,7 +593,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 			called ++;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 
 	if (called == 0)
 		ecard_check_lockup(desc);
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index ea02a7b..ff3f4ab 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -145,6 +145,7 @@ static void __cpuinit twd_calibrate_rate(void)
 void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
 	unsigned long flags;
+	struct irq_desc *desc;
 
 	twd_calibrate_rate();
 
@@ -160,8 +161,9 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 
 	/* Make sure our local interrupt controller has this enabled */
 	local_irq_save(flags);
-	irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
-	get_irq_chip(clk->irq)->unmask(clk->irq);
+	desc = irq_to_desc(clk->irq);
+	desc->status |= IRQ_NOPROBE;
+	get_irq_desc_chip(desc)->unmask(desc);
 	local_irq_restore(flags);
 
 	clockevents_register_device(clk);
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index b5c5fc6..41a8ad9 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -67,17 +67,17 @@ void __init aaec2000_map_io(void)
 /*
  * Interrupt handling routines
  */
-static void aaec2000_int_ack(unsigned int irq)
+static void aaec2000_int_ack(struct irq_desc *desc)
 {
 	IRQ_INTSR = 1 << irq;
 }
 
-static void aaec2000_int_mask(unsigned int irq)
+static void aaec2000_int_mask(struct irq_desc *desc)
 {
 	IRQ_INTENC |= (1 << irq);
 }
 
-static void aaec2000_int_unmask(unsigned int irq)
+static void aaec2000_int_unmask(struct irq_desc *desc)
 {
 	IRQ_INTENS |= (1 << irq);
 }
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index ae4772e..55bfcbd 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -274,8 +274,9 @@ EXPORT_SYMBOL(at91_get_gpio_value);
 static u32 wakeups[MAX_GPIO_BANKS];
 static u32 backups[MAX_GPIO_BANKS];
 
-static int gpio_irq_set_wake(unsigned pin, unsigned state)
+static int gpio_irq_set_wake(struct irq_desc *desc, unsigned state)
 {
+	unsigned int pin = desc->irq;
 	unsigned	mask = pin_to_mask(pin);
 	unsigned	bank = (pin - PIN_BASE) / 32;
 
@@ -344,8 +345,9 @@ void at91_gpio_resume(void)
  * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
  */
 
-static void gpio_irq_mask(unsigned pin)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int pin = desc->irq;
 	void __iomem	*pio = pin_to_controller(pin);
 	unsigned	mask = pin_to_mask(pin);
 
@@ -353,8 +355,9 @@ static void gpio_irq_mask(unsigned pin)
 		__raw_writel(mask, pio + PIO_IDR);
 }
 
-static void gpio_irq_unmask(unsigned pin)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int pin = desc->irq;
 	void __iomem	*pio = pin_to_controller(pin);
 	unsigned	mask = pin_to_mask(pin);
 
@@ -362,7 +365,7 @@ static void gpio_irq_unmask(unsigned pin)
 		__raw_writel(mask, pio + PIO_IER);
 }
 
-static int gpio_irq_type(unsigned pin, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
 	switch (type) {
 	case IRQ_TYPE_NONE:
@@ -393,7 +396,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 	pio = at91_gpio->regbase;
 
 	/* temporarily mask (level sensitive) parent IRQ */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 	for (;;) {
 		/* Reading ISR acks pending (edge triggered) GPIO interrupts.
 		 * When there none are pending, we're finished unless we need
@@ -419,7 +422,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 					 * another IRQ must be generated before it actually gets
 					 * here to be disabled on the GPIO controller.
 					 */
-					gpio_irq_mask(pin);
+					gpio_irq_mask(gpio);
 				}
 				else
 					generic_handle_irq(pin);
@@ -429,7 +432,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			isr >>= 1;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	/* now it may re-trigger */
 }
 
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index da3494a..4308334 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -34,14 +34,18 @@
 #include <asm/mach/map.h>
 
 
-static void at91_aic_mask_irq(unsigned int irq)
+static void at91_aic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	/* Disable interrupt on AIC */
 	at91_sys_write(AT91_AIC_IDCR, 1 << irq);
 }
 
-static void at91_aic_unmask_irq(unsigned int irq)
+static void at91_aic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	/* Enable interrupt on AIC */
 	at91_sys_write(AT91_AIC_IECR, 1 << irq);
 }
@@ -50,8 +54,9 @@ unsigned int at91_extern_irq;
 
 #define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
 
-static int at91_aic_set_type(unsigned irq, unsigned type)
+static int at91_aic_set_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int smr, srctype;
 
 	switch (type) {
@@ -87,8 +92,10 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
 static u32 wakeups;
 static u32 backups;
 
-static int at91_aic_set_wake(unsigned irq, unsigned value)
+static int at91_aic_set_wake(struct irq_desc *desc, unsigned value)
 {
+	unsigned int irq = desc->irq;
+
 	if (unlikely(irq >= 32))
 		return -EINVAL;
 
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
index dc1c493..4685c62 100644
--- a/arch/arm/mach-bcmring/irq.c
+++ b/arch/arm/mach-bcmring/irq.c
@@ -30,38 +30,50 @@
 #include <mach/csp/intcHw_reg.h>
 #include <mach/csp/mm_io.h>
 
-static void bcmring_mask_irq0(unsigned int irq)
+static void bcmring_mask_irq0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC0_START),
 	       MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq0(unsigned int irq)
+static void bcmring_unmask_irq0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC0_START),
 	       MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
 }
 
-static void bcmring_mask_irq1(unsigned int irq)
+static void bcmring_mask_irq1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC1_START),
 	       MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq1(unsigned int irq)
+static void bcmring_unmask_irq1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_INTC1_START),
 	       MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
 }
 
-static void bcmring_mask_irq2(unsigned int irq)
+static void bcmring_mask_irq2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_SINTC_START),
 	       MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
 }
 
-static void bcmring_unmask_irq2(unsigned int irq)
+static void bcmring_unmask_irq2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
+
 	writel(1 << (irq - IRQ_SINTC_START),
 	       MM_IO_BASE_SINTC + INTCHW_INTENABLE);
 }
diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
index 9a12d85..f614852 100644
--- a/arch/arm/mach-clps711x/irq.c
+++ b/arch/arm/mach-clps711x/irq.c
@@ -27,8 +27,9 @@
 
 #include <asm/hardware/clps7111.h>
 
-static void int1_mask(unsigned int irq)
+static void int1_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -36,8 +37,9 @@ static void int1_mask(unsigned int irq)
 	clps_writel(intmr1, INTMR1);
 }
 
-static void int1_ack(unsigned int irq)
+static void int1_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -54,8 +56,9 @@ static void int1_ack(unsigned int irq)
 	}
 }
 
-static void int1_unmask(unsigned int irq)
+static void int1_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr1;
 
 	intmr1 = clps_readl(INTMR1);
@@ -69,8 +72,9 @@ static struct irq_chip int1_chip = {
 	.unmask = int1_unmask,
 };
 
-static void int2_mask(unsigned int irq)
+static void int2_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
@@ -78,8 +82,9 @@ static void int2_mask(unsigned int irq)
 	clps_writel(intmr2, INTMR2);
 }
 
-static void int2_ack(unsigned int irq)
+static void int2_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
@@ -91,8 +96,9 @@ static void int2_ack(unsigned int irq)
 	}
 }
 
-static void int2_unmask(unsigned int irq)
+static void int2_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 intmr2;
 
 	intmr2 = clps_readl(INTMR2);
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 37311d1..8284b53 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -27,14 +27,16 @@ static inline void cp_intc_write(unsigned long value, unsigned offset)
 	__raw_writel(value, cp_intc_base + offset);
 }
 
-static void cp_intc_ack_irq(unsigned int irq)
+static void cp_intc_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cp_intc_write(irq, CP_INTC_SYS_STAT_IDX_CLR);
 }
 
 /* Disable interrupt */
-static void cp_intc_mask_irq(unsigned int irq)
+static void cp_intc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX don't know why we need to disable nIRQ here... */
 	cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
 	cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_CLR);
@@ -42,13 +44,15 @@ static void cp_intc_mask_irq(unsigned int irq)
 }
 
 /* Enable interrupt */
-static void cp_intc_unmask_irq(unsigned int irq)
+static void cp_intc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_SET);
 }
 
-static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int cp_intc_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned reg		= BIT_WORD(irq);
 	unsigned mask		= BIT_MASK(irq);
 	unsigned polarity	= cp_intc_read(CP_INTC_SYS_POLARITY(reg));
@@ -86,7 +90,7 @@ static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
  * generic drivers which call {enable|disable}_irq_wake for
  * wake up interrupt sources (eg RTC on DA850).
  */
-static int cp_intc_set_wake(unsigned int irq, unsigned int on)
+static int cp_intc_set_wake(struct irq_desc *desc, unsigned int on)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 744755b..e557755 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -159,20 +159,20 @@ pure_initcall(davinci_gpio_setup);
  * serve as EDMA event triggers.
  */
 
-static void gpio_irq_disable(unsigned irq)
+static void gpio_irq_disable(struct irq_desc *desc)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
 
 	__raw_writel(mask, &g->clr_falling);
 	__raw_writel(mask, &g->clr_rising);
 }
 
-static void gpio_irq_enable(unsigned irq)
+static void gpio_irq_enable(struct irq_desc *desc)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
-	unsigned status = irq_desc[irq].status;
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
+	unsigned status = desc->status;
 
 	status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
 	if (!status)
@@ -184,19 +184,19 @@ static void gpio_irq_enable(unsigned irq)
 		__raw_writel(mask, &g->set_rising);
 }
 
-static int gpio_irq_type(unsigned irq, unsigned trigger)
+static int gpio_irq_type(struct irq_desc *desc, unsigned trigger)
 {
-	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = (u32) get_irq_data(irq);
+	struct gpio_controller *__iomem g = get_irq_desc_chip_data(desc);
+	u32 mask = (u32) get_irq_desc_data(desc);
 
 	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
 		return -EINVAL;
 
-	irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
-	irq_desc[irq].status |= trigger;
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= trigger;
 
 	/* don't enable the IRQ if it's currently disabled */
-	if (irq_desc[irq].depth == 0) {
+	if (desc->depth == 0) {
 		__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
 			     ? &g->set_falling : &g->clr_falling);
 		__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
@@ -223,8 +223,8 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		mask <<= 16;
 
 	/* temporarily mask (level sensitive) parent IRQ */
-	desc->chip->mask(irq);
-	desc->chip->ack(irq);
+	desc->chip->mask(desc);
+	desc->chip->ack(desc);
 	while (1) {
 		u32		status;
 		int		n;
@@ -247,7 +247,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			status >>= res;
 		}
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 	/* now it may re-trigger */
 }
 
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index af92ffe..dc8e7a0 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -53,8 +53,9 @@ static inline void davinci_irq_writel(unsigned long value, int offset)
 }
 
 /* Disable interrupt */
-static void davinci_mask_irq(unsigned int irq)
+static void davinci_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	u32 l;
 
@@ -72,8 +73,9 @@ static void davinci_mask_irq(unsigned int irq)
 }
 
 /* Enable interrupt */
-static void davinci_unmask_irq(unsigned int irq)
+static void davinci_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	u32 l;
 
@@ -91,8 +93,9 @@ static void davinci_unmask_irq(unsigned int irq)
 }
 
 /* EOI interrupt */
-static void davinci_ack_irq(unsigned int irq)
+static void davinci_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = 1 << IRQ_BIT(irq);
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 61bfcb3..a19a4dc 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -36,8 +36,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static void pmu_irq_mask(unsigned int irq)
+static void pmu_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
@@ -46,8 +47,9 @@ static void pmu_irq_mask(unsigned int irq)
 	writel(u, PMU_INTERRUPT_MASK);
 }
 
-static void pmu_irq_unmask(unsigned int irq)
+static void pmu_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
@@ -56,8 +58,9 @@ static void pmu_irq_unmask(unsigned int irq)
 	writel(u, PMU_INTERRUPT_MASK);
 }
 
-static void pmu_irq_ack(unsigned int irq)
+static void pmu_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_pmu(irq);
 	u32 u;
 
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index c7bc7fb..f5e1e3d 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -35,13 +35,15 @@
 #define IRQ_STAT		0xff000000	/* read */
 #define IRQ_MCLR		0xff000000	/* write */
 
-static void ebsa110_mask_irq(unsigned int irq)
+static void ebsa110_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writeb(1 << irq, IRQ_MCLR);
 }
 
-static void ebsa110_unmask_irq(unsigned int irq)
+static void ebsa110_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writeb(1 << irq, IRQ_MSET);
 }
 
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index cc377ae..3457432 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -112,13 +112,14 @@ static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
 	generic_handle_irq(gpio_irq);
 }
 
-static void ep93xx_gpio_irq_ack(unsigned int irq)
+static void ep93xx_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+	if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 		ep93xx_gpio_update_int_params(port);
 	}
@@ -126,13 +127,14 @@ static void ep93xx_gpio_irq_ack(unsigned int irq)
 	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
-static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
+static void ep93xx_gpio_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+	if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 
 	gpio_int_unmasked[port] &= ~port_mask;
@@ -141,8 +143,9 @@ static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
-static void ep93xx_gpio_irq_mask(unsigned int irq)
+static void ep93xx_gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
@@ -150,8 +153,9 @@ static void ep93xx_gpio_irq_mask(unsigned int irq)
 	ep93xx_gpio_update_int_params(port);
 }
 
-static void ep93xx_gpio_irq_unmask(unsigned int irq)
+static void ep93xx_gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
@@ -164,9 +168,9 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
  * edge (1) triggered, while gpio_int_type2 controls whether it
  * triggers on low/falling (0) or high/rising (1).
  */
-static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
+static int ep93xx_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	const int gpio = irq_to_gpio(irq);
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index e3bc3f6..1a11b2a 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -75,13 +75,15 @@ static const int fb_irq_mask[] = {
 	IRQ_MASK_PCI_PERR,	/* 19 */
 };
 
-static void fb_mask_irq(unsigned int irq)
+static void fb_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
 }
 
-static void fb_unmask_irq(unsigned int irq)
+static void fb_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
 }
 
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index 8bfd06a..7593eeb 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -30,23 +30,26 @@
 
 #include "common.h"
 
-static void isa_mask_pic_lo_irq(unsigned int irq)
+static void isa_mask_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
 }
 
-static void isa_ack_pic_lo_irq(unsigned int irq)
+static void isa_ack_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
 	outb(0x20, PIC_LO);
 }
 
-static void isa_unmask_pic_lo_irq(unsigned int irq)
+static void isa_unmask_pic_lo_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
@@ -58,15 +61,17 @@ static struct irq_chip isa_lo_chip = {
 	.unmask = isa_unmask_pic_lo_irq,
 };
 
-static void isa_mask_pic_hi_irq(unsigned int irq)
+static void isa_mask_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
 }
 
-static void isa_ack_pic_hi_irq(unsigned int irq)
+static void isa_ack_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
@@ -74,8 +79,9 @@ static void isa_ack_pic_hi_irq(unsigned int irq)
 	outb(0x20, PIC_HI);
 }
 
-static void isa_unmask_pic_hi_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq & 7);
 
 	outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index fe3bd5a..66b50ea 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -54,24 +54,27 @@ static void _set_gpio_irqenable(unsigned int base, unsigned int index,
 	__raw_writel(reg, base + GPIO_INT_EN);
 }
 
-static void gpio_ack_irq(unsigned int irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
 	__raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
 }
 
-static void gpio_mask_irq(unsigned int irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
 	_set_gpio_irqenable(base, gpio % 32, 0);
 }
 
-static void gpio_unmask_irq(unsigned int irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int base = GPIO_BASE(gpio / 32);
 
@@ -80,6 +83,7 @@ static void gpio_unmask_irq(unsigned int irq)
 
 static int gpio_set_irq_type(unsigned int irq, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq_to_gpio(irq);
 	unsigned int gpio_mask = 1 << (gpio % 32);
 	unsigned int base = GPIO_BASE(gpio / 32);
@@ -120,7 +124,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)
 	__raw_writel(reg_level, base + GPIO_INT_LEVEL);
 	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
 
-	gpio_ack_irq(irq);
+	gpio_ack_irq(desc);
 
 	return 0;
 }
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
index 9e613ca..30e23be 100644
--- a/arch/arm/mach-gemini/irq.c
+++ b/arch/arm/mach-gemini/irq.c
@@ -32,13 +32,15 @@
 #define FIQ_LEVEL(base_addr)	(base_addr + 0x30)
 #define FIQ_STATUS(base_addr)	(base_addr + 0x34)
 
-static void gemini_ack_irq(unsigned int irq)
+static void gemini_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
 }
 
-static void gemini_mask_irq(unsigned int irq)
+static void gemini_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
@@ -46,8 +48,9 @@ static void gemini_mask_irq(unsigned int irq)
 	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
 }
 
-static void gemini_unmask_irq(unsigned int irq)
+static void gemini_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 7a26148..cb945c0 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -53,16 +53,18 @@ unsigned long h720x_gettimeoffset(void)
 /*
  * mask Global irq's
  */
-static void mask_global_irq (unsigned int irq )
+static void mask_global_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << irq);
 }
 
 /*
  * unmask Global irq's
  */
-static void unmask_global_irq (unsigned int irq )
+static void unmask_global_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << irq);
 }
 
@@ -71,8 +73,9 @@ static void unmask_global_irq (unsigned int irq )
  * ack GPIO irq's
  * Ack only for edge triggered int's valid
  */
-static void inline ack_gpio_irq(u32 irq)
+static inline void ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
@@ -82,8 +85,9 @@ static void inline ack_gpio_irq(u32 irq)
 /*
  * mask GPIO irq's
  */
-static void inline mask_gpio_irq(u32 irq)
+static inline void mask_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	CPU_REG (reg_base, GPIO_MASK) &= ~bit;
@@ -92,8 +96,9 @@ static void inline mask_gpio_irq(u32 irq)
 /*
  * unmask GPIO irq's
  */
-static void inline unmask_gpio_irq(u32 irq)
+static inline void unmask_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
 	u32 bit = IRQ_TO_BIT(irq);
 	CPU_REG (reg_base, GPIO_MASK) |= bit;
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index fd33a19..b73501e 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -141,8 +141,9 @@ h7202_timer_interrupt(int irq, void *dev_id)
 /*
  * mask multiplexed timer IRQs
  */
-static void inline mask_timerx_irq (u32 irq)
+static inline void mask_timerx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit;
 	bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
 	CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit;
@@ -151,8 +152,9 @@ static void inline mask_timerx_irq (u32 irq)
 /*
  * unmask multiplexed timer IRQs
  */
-static void inline unmask_timerx_irq (u32 irq)
+static inline void unmask_timerx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit;
 	bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
 	CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit;
@@ -196,7 +198,7 @@ void __init h7202_init_irq (void)
 
 	for (irq = IRQ_TIMER1;
 	                  irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) {
-		mask_timerx_irq(irq);
+		mask_timerx_irq(irq_to_desc(irq));
 		set_irq_chip(irq, &h7202_timerx_chip);
 		set_irq_handler(irq, handle_edge_irq);
 		set_irq_flags(irq, IRQF_VALID );
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..3c23890 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -151,13 +151,15 @@ static void __init ap_map_io(void)
 
 #define INTEGRATOR_SC_VALID_INT	0x003fffff
 
-static void sc_mask_irq(unsigned int irq)
+static void sc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void sc_unmask_irq(unsigned int irq)
+static void sc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
 }
 
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d..0c8a89c 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -145,14 +145,16 @@ static void __init intcp_map_io(void)
 #define sic_writel	__raw_writel
 #define sic_readl	__raw_readl
 
-static void cic_mask_irq(unsigned int irq)
+static void cic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_CIC_START;
 	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void cic_unmask_irq(unsigned int irq)
+static void cic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_CIC_START;
 	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
 }
@@ -164,14 +166,16 @@ static struct irq_chip cic_chip = {
 	.unmask	= cic_unmask_irq,
 };
 
-static void pic_mask_irq(unsigned int irq)
+static void pic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_PIC_START;
 	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void pic_unmask_irq(unsigned int irq)
+static void pic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_PIC_START;
 	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
 }
@@ -183,14 +187,16 @@ static struct irq_chip pic_chip = {
 	.unmask = pic_unmask_irq,
 };
 
-static void sic_mask_irq(unsigned int irq)
+static void sic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
 }
 
-static void sic_unmask_irq(unsigned int irq)
+static void sic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
 }
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index 0d099ca..7a41e2f 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -123,50 +123,58 @@ static void write_intsize(u32 val)
 
 /* 0 = Interrupt Masked and 1 = Interrupt not masked */
 static void
-iop13xx_irq_mask0 (unsigned int irq)
+iop13xx_irq_mask0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_0(read_intctl_0() & ~(1 << (irq - 0)));
 }
 
 static void
-iop13xx_irq_mask1 (unsigned int irq)
+iop13xx_irq_mask1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_1(read_intctl_1() & ~(1 << (irq - 32)));
 }
 
 static void
-iop13xx_irq_mask2 (unsigned int irq)
+iop13xx_irq_mask2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_2(read_intctl_2() & ~(1 << (irq - 64)));
 }
 
 static void
-iop13xx_irq_mask3 (unsigned int irq)
+iop13xx_irq_mask3(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_3(read_intctl_3() & ~(1 << (irq - 96)));
 }
 
 static void
-iop13xx_irq_unmask0(unsigned int irq)
+iop13xx_irq_unmask0(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_0(read_intctl_0() | (1 << (irq - 0)));
 }
 
 static void
-iop13xx_irq_unmask1(unsigned int irq)
+iop13xx_irq_unmask1(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_1(read_intctl_1() | (1 << (irq - 32)));
 }
 
 static void
-iop13xx_irq_unmask2(unsigned int irq)
+iop13xx_irq_unmask2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_2(read_intctl_2() | (1 << (irq - 64)));
 }
 
 static void
-iop13xx_irq_unmask3(unsigned int irq)
+iop13xx_irq_unmask3(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	write_intctl_3(read_intctl_3() | (1 << (irq - 96)));
 }
 
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index f34b0ed..3e10b50 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -156,7 +156,7 @@ void arch_teardown_msi_irq(unsigned int irq)
 	destroy_irq(irq);
 }
 
-static void iop13xx_msi_nop(unsigned int irq)
+static void iop13xx_msi_nop(struct irq_desc *desc)
 {
 	return;
 }
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index ba59b2d..5f8cd81 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -32,15 +32,17 @@ static void intstr_write(u32 val)
 }
 
 static void
-iop32x_irq_mask(unsigned int irq)
+iop32x_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	iop32x_mask &= ~(1 << irq);
 	intctl_write(iop32x_mask);
 }
 
 static void
-iop32x_irq_unmask(unsigned int irq)
+iop32x_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	iop32x_mask |= 1 << irq;
 	intctl_write(iop32x_mask);
 }
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index babb225..127a945 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -309,8 +309,9 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
+static int ixp2000_GPIO_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP2000_GPIO0;
 
 	/*
@@ -342,8 +343,9 @@ static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
+static void ixp2000_GPIO_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 
 	ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
@@ -351,13 +353,15 @@ static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
 	ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
-static void ixp2000_GPIO_irq_mask(unsigned int irq)
+static void ixp2000_GPIO_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
-static void ixp2000_GPIO_irq_unmask(unsigned int irq)
+static void ixp2000_GPIO_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
@@ -368,8 +372,9 @@ static struct irq_chip ixp2000_GPIO_irq_chip = {
 	.set_type	= ixp2000_GPIO_irq_type,
 };
 
-static void ixp2000_pci_irq_mask(unsigned int irq)
+static void ixp2000_pci_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
 	if (irq == IRQ_IXP2000_PCIA)
 		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
@@ -377,8 +382,9 @@ static void ixp2000_pci_irq_mask(unsigned int irq)
 		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
 }
 
-static void ixp2000_pci_irq_unmask(unsigned int irq)
+static void ixp2000_pci_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
 	if (irq == IRQ_IXP2000_PCIA)
 		ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26)));
@@ -401,14 +407,16 @@ static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static void ixp2000_err_irq_mask(unsigned int irq)
+static void ixp2000_err_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
 			(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
 }
 
-static void ixp2000_err_irq_unmask(unsigned int irq)
+static void ixp2000_err_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
 			(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
 }
@@ -425,13 +433,15 @@ static struct irq_chip ixp2000_pci_irq_chip = {
 	.unmask	= ixp2000_pci_irq_unmask
 };
 
-static void ixp2000_irq_mask(unsigned int irq)
+static void ixp2000_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
 }
 
-static void ixp2000_irq_unmask(unsigned int irq)
+static void ixp2000_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
 }
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 3045130..d3e896e 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -64,8 +64,9 @@ static struct slowport_cfg slowport_cpld_cfg = {
 };
 #endif
 
-static void ixdp2x00_irq_mask(unsigned int irq)
+static void ixdp2x00_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long dummy;
 	static struct slowport_cfg old_cfg;
 
@@ -88,8 +89,9 @@ static void ixdp2x00_irq_mask(unsigned int irq)
 #endif
 }
 
-static void ixdp2x00_irq_unmask(unsigned int irq)
+static void ixdp2x00_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long dummy;
 	static struct slowport_cfg old_cfg;
 
@@ -112,7 +114,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
 	static struct slowport_cfg old_cfg;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 #ifdef CONFIG_ARCH_IXDP2400
 	if (machine_is_ixdp2400())
@@ -134,7 +136,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2x00_cpld_irq_chip = {
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 4a12327..19c0087 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -49,14 +49,16 @@
 /*************************************************************************
  * IXDP2x01 IRQ Handling
  *************************************************************************/
-static void ixdp2x01_irq_mask(unsigned int irq)
+static void ixdp2x01_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
 				IXP2000_BOARD_IRQ_MASK(irq));
 }
 
-static void ixdp2x01_irq_unmask(unsigned int irq)
+static void ixdp2x01_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG,
 				IXP2000_BOARD_IRQ_MASK(irq));
 }
@@ -68,7 +70,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 ex_interrupt;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 	ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask;
 
@@ -84,7 +86,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2x01_irq_chip = {
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index aa4c442..3454c62 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -111,8 +111,9 @@ enum ixp23xx_irq_type {
 
 static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type);
 
-static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
+static int ixp23xx_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
 	u32 int_style;
 	enum ixp23xx_irq_type irq_type;
@@ -173,8 +174,9 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp23xx_irq_mask(unsigned int irq)
+static void ixp23xx_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
 	if (irq >= 56)
@@ -184,8 +186,9 @@ static void ixp23xx_irq_mask(unsigned int irq)
 	*intr_reg &= ~(1 << (irq % 32));
 }
 
-static void ixp23xx_irq_ack(unsigned int irq)
+static void ixp23xx_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
 
 	if ((line < 6) || (line > 15))
@@ -198,11 +201,12 @@ static void ixp23xx_irq_ack(unsigned int irq)
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp23xx_irq_level_unmask(unsigned int irq)
+static void ixp23xx_irq_level_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
-	ixp23xx_irq_ack(irq);
+	ixp23xx_irq_ack(desc);
 
 	if (irq >= 56)
 		irq += 8;
@@ -211,8 +215,9 @@ static void ixp23xx_irq_level_unmask(unsigned int irq)
 	*intr_reg |= (1 << (irq % 32));
 }
 
-static void ixp23xx_irq_edge_unmask(unsigned int irq)
+static void ixp23xx_irq_edge_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile unsigned long *intr_reg;
 
 	if (irq >= 56)
@@ -236,12 +241,12 @@ static struct irq_chip ixp23xx_irq_edge_chip = {
 	.set_type	= ixp23xx_irq_set_type
 };
 
-static void ixp23xx_pci_irq_mask(unsigned int irq)
+static void ixp23xx_pci_irq_mask(struct irq_desc *desc)
 {
 	*IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
 }
 
-static void ixp23xx_pci_irq_unmask(unsigned int irq)
+static void ixp23xx_pci_irq_unmask(struct irq_desc *desc)
 {
 	*IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq));
 }
@@ -256,7 +261,7 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 
 	pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	/* See which PCI_INTA, or PCI_INTB interrupted */
 	if (pci_interrupt & (1 << 26)) {
@@ -269,7 +274,7 @@ static void pci_handler(unsigned int irq, struct irq_desc *desc)
 
 	generic_handle_irq(irqno);
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixp23xx_pci_irq_chip = {
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index f1b124a..63e5f16 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -48,13 +48,15 @@
 /*
  * IXDP2351 Interrupt Handling
  */
-static void ixdp2351_inta_mask(unsigned int irq)
+static void ixdp2351_inta_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(irq);
 }
 
-static void ixdp2351_inta_unmask(unsigned int irq)
+static void ixdp2351_inta_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq);
 }
 
@@ -64,7 +66,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
 		*IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
 	int i;
 
-	desc->chip->mask(irq);
+	desc->chip->mask(desc);
 
 	for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
@@ -74,7 +76,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2351_inta_chip = {
@@ -83,13 +85,15 @@ static struct irq_chip ixdp2351_inta_chip = {
 	.unmask	= ixdp2351_inta_unmask
 };
 
-static void ixdp2351_intb_mask(unsigned int irq)
+static void ixdp2351_intb_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(irq);
 }
 
-static void ixdp2351_intb_unmask(unsigned int irq)
+static void ixdp2351_intb_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	*IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq);
 }
 
@@ -99,7 +103,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
 		*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
 	int i;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
@@ -109,7 +113,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
 		}
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static struct irq_chip ixdp2351_intb_chip = {
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..e42760c 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -128,8 +128,9 @@ int irq_to_gpio(unsigned int irq)
 }
 EXPORT_SYMBOL(irq_to_gpio);
 
-static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
+static int ixp4xx_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int line = irq2gpio[irq];
 	u32 int_style;
 	enum ixp4xx_irq_type irq_type;
@@ -193,16 +194,18 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void ixp4xx_irq_mask(unsigned int irq)
+static void ixp4xx_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
 		*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
 	else
 		*IXP4XX_ICMR &= ~(1 << irq);
 }
 
-static void ixp4xx_irq_ack(unsigned int irq)
+static void ixp4xx_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int line = (irq < 32) ? irq2gpio[irq] : -1;
 
 	if (line >= 0)
@@ -213,10 +216,11 @@ static void ixp4xx_irq_ack(unsigned int irq)
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp4xx_irq_unmask(unsigned int irq)
+static void ixp4xx_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!(ixp4xx_irq_edge & (1 << irq)))
-		ixp4xx_irq_ack(irq);
+		ixp4xx_irq_ack(desc);
 
 	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
 		*IXP4XX_ICMR2 |= (1 << (irq - 32));
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
index e375c1d..05eb2dc 100644
--- a/arch/arm/mach-ks8695/irq.c
+++ b/arch/arm/mach-ks8695/irq.c
@@ -34,29 +34,32 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-static void ks8695_irq_mask(unsigned int irqno)
+static void ks8695_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long inten;
 
 	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-	inten &= ~(1 << irqno);
+	inten &= ~(1 << irq);
 
 	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
 }
 
-static void ks8695_irq_unmask(unsigned int irqno)
+static void ks8695_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long inten;
 
 	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-	inten |= (1 << irqno);
+	inten |= (1 << irq);
 
 	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
 }
 
-static void ks8695_irq_ack(unsigned int irqno)
+static void ks8695_irq_ack(struct irq_desc *desc)
 {
-	__raw_writel((1 << irqno), KS8695_IRQ_VA + KS8695_INTST);
+	unsigned int irq = desc->irq;
+	__raw_writel((1 << irq), KS8695_IRQ_VA + KS8695_INTST);
 }
 
 
@@ -64,8 +67,9 @@ static struct irq_chip ks8695_irq_level_chip;
 static struct irq_chip ks8695_irq_edge_chip;
 
 
-static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
+static int ks8695_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned long ctrl, mode;
 	unsigned short level_triggered = 0;
 
@@ -93,7 +97,7 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
 			return -EINVAL;
 	}
 
-	switch (irqno) {
+	switch (irq) {
 		case KS8695_IRQ_EXTERN0:
 			ctrl &= ~IOPC_IOEINT0TM;
 			ctrl |= IOPC_IOEINT0_MODE(mode);
@@ -115,12 +119,12 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
 	}
 
 	if (level_triggered) {
-		set_irq_chip(irqno, &ks8695_irq_level_chip);
-		set_irq_handler(irqno, handle_level_irq);
+		set_irq_chip(irq, &ks8695_irq_level_chip);
+		set_irq_handler(irq, handle_level_irq);
 	}
 	else {
-		set_irq_chip(irqno, &ks8695_irq_edge_chip);
-		set_irq_handler(irqno, handle_edge_irq);
+		set_irq_chip(irq, &ks8695_irq_edge_chip);
+		set_irq_handler(irq, handle_edge_irq);
 	}
 
 	__raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
@@ -164,7 +168,8 @@ void __init ks8695_init_irq(void)
 
 			/* Edge-triggered interrupts */
 			default:
-				ks8695_irq_ack(irq);	/* clear pending bit */
+				/* clear pending bit */	
+				ks8695_irq_ack(irq_to_desc(irq));
 				set_irq_chip(irq, &ks8695_irq_edge_chip);
 				set_irq_handler(irq, handle_edge_irq);
 		}
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 50d2324..feb33fa 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -45,13 +45,15 @@
 #define FIQ_SOFT	(*(volatile unsigned long *) (IRQ_BASE + 0x110))
 #define FIQ_SOURCESEL	(*(volatile unsigned long *) (IRQ_BASE + 0x118))
 
-static void l7200_mask_irq(unsigned int irq)
+static void l7200_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IRQ_ENABLECLEAR = 1 << irq;
 }
 
-static void l7200_unmask_irq(unsigned int irq)
+static void l7200_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IRQ_ENABLE = 1 << irq;
 }
 
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 3d7bd50..04c7364 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -46,19 +46,22 @@ void __init kev7a400_map_io(void)
 
 static u16 CPLD_IRQ_mask;	/* Mask for CPLD IRQs, 1 == unmasked */
 
-static void kev7a400_ack_cpld_irq (u32 irq)
+static void kev7a400_ack_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD);
 }
 
-static void kev7a400_mask_cpld_irq (u32 irq)
+static void kev7a400_mask_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD));
 	CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
 }
 
-static void kev7a400_unmask_cpld_irq (u32 irq)
+static void kev7a400_unmask_cpld_irq(u32 irq, struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD);
 	CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask;
 }
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index cb15e5d..2536349 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -159,8 +159,9 @@ static void __init lpd7a40x_init (void)
 #endif
 }
 
-static void lh7a40x_ack_cpld_irq (u32 irq)
+static void lh7a40x_ack_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* CPLD doesn't have ack capability, but some devices may */
 
 #if defined (CPLD_INTMASK_TOUCH)
@@ -172,8 +173,9 @@ static void lh7a40x_ack_cpld_irq (u32 irq)
 #endif
 }
 
-static void lh7a40x_mask_cpld_irq (u32 irq)
+static void lh7a40x_mask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
@@ -186,8 +188,9 @@ static void lh7a40x_mask_cpld_irq (u32 irq)
 	}
 }
 
-static void lh7a40x_unmask_cpld_irq (u32 irq)
+static void lh7a40x_unmask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
@@ -211,7 +214,7 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int mask = CPLD_INTERRUPTS;
 
-	desc->chip->ack (irq);
+	desc->chip->ack(desc);
 
 	if ((mask & (1<<0)) == 0)	/* WLAN */
 		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
@@ -221,7 +224,7 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 		generic_handle_irq(IRQ_TOUCH);
 #endif
 
-	desc->chip->unmask (irq); /* Level-triggered need this */
+	desc->chip->unmask(desc); /* Level-triggered need this */
 }
 
 
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c
index 1ad3afc..b1b9480 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a400.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c
@@ -21,18 +21,21 @@
 
   /* CPU IRQ handling */
 
-static void lh7a400_mask_irq (u32 irq)
+static void lh7a400_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	INTC_INTENC = (1 << irq);
 }
 
-static void lh7a400_unmask_irq (u32 irq)
+static void lh7a400_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	INTC_INTENS = (1 << irq);
 }
 
-static void lh7a400_ack_gpio_irq (u32 irq)
+static void lh7a400_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	INTC_INTENC = (1 << irq);
 }
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
index 12b045b..cd8c16e 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c
@@ -43,34 +43,40 @@ static unsigned char irq_pri_vic2[] = {
 
   /* CPU IRQ handling */
 
-static void lh7a404_vic1_mask_irq (u32 irq)
+static void lh7a404_vic1_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC1_INTENCLR = (1 << irq);
 }
 
-static void lh7a404_vic1_unmask_irq (u32 irq)
+static void lh7a404_vic1_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC1_INTEN = (1 << irq);
 }
 
-static void lh7a404_vic2_mask_irq (u32 irq)
+static void lh7a404_vic2_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC2_INTENCLR = (1 << (irq - 32));
 }
 
-static void lh7a404_vic2_unmask_irq (u32 irq)
+static void lh7a404_vic2_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	VIC2_INTEN = (1 << (irq - 32));
 }
 
-static void lh7a404_vic1_ack_gpio_irq (u32 irq)
+static void lh7a404_vic1_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	VIC1_INTENCLR = (1 << irq);
 }
 
-static void lh7a404_vic2_ack_gpio_irq (u32 irq)
+static void lh7a404_vic2_ack_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq));
 	VIC2_INTENCLR = (1 << irq);
 }
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
index fd033bb..364631f 100644
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -20,13 +20,14 @@
 
 #include "common.h"
 
-static void lh7a40x_ack_cpld_irq (u32 irq)
+static void lh7a40x_ack_cpld_irq(struct irq_desc *desc)
 {
 	/* CPLD doesn't have ack capability */
 }
 
-static void lh7a40x_mask_cpld_irq (u32 irq)
+static void lh7a40x_mask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4;
@@ -37,8 +38,9 @@ static void lh7a40x_mask_cpld_irq (u32 irq)
 	}
 }
 
-static void lh7a40x_unmask_cpld_irq (u32 irq)
+static void lh7a40x_unmask_cpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	switch (irq) {
 	case IRQ_LPD7A40X_ETH_INT:
 		CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4;
@@ -60,7 +62,7 @@ static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int mask = CPLD_INTERRUPTS;
 
-	desc->chip->ack (irq);
+	desc->chip->ack(desc);
 
 	if ((mask & 0x1) == 0)	/* WLAN */
 		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
@@ -68,7 +70,7 @@ static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc)
 	if ((mask & 0x2) == 0)	/* Touch */
 		generic_handle_irq(IRQ_LPD7A400_TS);
 
-	desc->chip->unmask (irq); /* Level-triggered need this */
+	desc->chip->unmask(desc); /* Level-triggered need this */
 }
 
 
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 43da8bb..0b1d53d 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -88,8 +88,9 @@ netx_hif_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 }
 
 static int
-netx_hif_irq_type(unsigned int _irq, unsigned int type)
+netx_hif_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	val = readl(NETX_DPMAS_IF_CONF1);
@@ -119,8 +120,9 @@ netx_hif_irq_type(unsigned int _irq, unsigned int type)
 }
 
 static void
-netx_hif_ack_irq(unsigned int _irq)
+netx_hif_ack_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
@@ -134,8 +136,9 @@ netx_hif_ack_irq(unsigned int _irq)
 }
 
 static void
-netx_hif_mask_irq(unsigned int _irq)
+netx_hif_mask_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
@@ -146,8 +149,9 @@ netx_hif_mask_irq(unsigned int _irq)
 }
 
 static void
-netx_hif_unmask_irq(unsigned int _irq)
+netx_hif_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int _irq = desc->irq;
 	unsigned int val, irq;
 
 	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
index 9a09b27..0635e22 100644
--- a/arch/arm/mach-nomadik/gpio.c
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -95,27 +95,29 @@ static inline int nmk_gpio_get_bitmask(int gpio)
 	return 1 << (gpio % 32);
 }
 
-static void nmk_gpio_irq_ack(unsigned int irq)
+static void nmk_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	if (!nmk_chip)
 		return;
 	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
 }
 
-static void nmk_gpio_irq_mask(unsigned int irq)
+static void nmk_gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask, reg;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return;
@@ -135,15 +137,16 @@ static void nmk_gpio_irq_mask(unsigned int irq)
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 };
 
-static void nmk_gpio_irq_unmask(unsigned int irq)
+static void nmk_gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask, reg;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return;
@@ -163,15 +166,16 @@ static void nmk_gpio_irq_unmask(unsigned int irq)
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 }
 
-static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
+static int nmk_gpio_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
 	u32 bitmask;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
+	nmk_chip = get_irq_desc_chip_data(desc);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
 		return -EINVAL;
@@ -195,7 +199,7 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
 
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 
-	nmk_gpio_irq_unmask(irq);
+	nmk_gpio_irq_unmask(desc);
 
 	return 0;
 }
@@ -216,7 +220,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 pending;
 	unsigned int first_irq;
 
-	nmk_chip = get_irq_data(irq);
+	nmk_chip = get_irq_desc_data(desc);
 	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
 	while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
 		gpio_irq = first_irq + __ffs(pending);
@@ -224,7 +228,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	}
 	if (0) {/* don't ack parent irq, as ack == disable */
 		host_chip = get_irq_chip(irq);
-		host_chip->ack(irq);
+		host_chip->ack(desc);
 	}
 }
 
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index b45bb3b..9b42b41 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -37,13 +37,14 @@ void __init board_a9m9750dev_map_io(void)
 		     ARRAY_SIZE(board_a9m9750dev_io_desc));
 }
 
-static void a9m9750dev_fpga_ack_irq(unsigned int irq)
+static void a9m9750dev_fpga_ack_irq(struct irq_desc *desc)
 {
 	/* nothing */
 }
 
-static void a9m9750dev_fpga_mask_irq(unsigned int irq)
+static void a9m9750dev_fpga_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 ier;
 
 	ier = __raw_readb(FPGA_IER);
@@ -53,14 +54,16 @@ static void a9m9750dev_fpga_mask_irq(unsigned int irq)
 	__raw_writeb(ier, FPGA_IER);
 }
 
-static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
+static void a9m9750dev_fpga_maskack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	a9m9750dev_fpga_mask_irq(irq);
 	a9m9750dev_fpga_ack_irq(irq);
 }
 
-static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
+static void a9m9750dev_fpga_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 ier;
 
 	ier = __raw_readb(FPGA_IER);
@@ -82,7 +85,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 {
 	u8 stat = __raw_readb(FPGA_ISR);
 
-	desc->chip->mask_ack(irq);
+	desc->chip->mask_ack(desc);
 
 	while (stat != 0) {
 		int irqno = fls(stat) - 1;
@@ -92,7 +95,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 		generic_handle_irq(FPGA_IRQ(irqno));
 	}
 
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 void __init board_a9m9750dev_init_irq(void)
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 038f24d..3e21071 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -22,8 +22,9 @@
 #define irq2prio(i) (i)
 #define prio2irq(p) (p)
 
-static void ns9xxx_mask_irq(unsigned int irq)
+static void ns9xxx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX: better use cpp symbols */
 	int prio = irq2prio(irq);
 	u32 ic = __raw_readl(SYS_IC(prio / 4));
@@ -31,19 +32,21 @@ static void ns9xxx_mask_irq(unsigned int irq)
 	__raw_writel(ic, SYS_IC(prio / 4));
 }
 
-static void ns9xxx_ack_irq(unsigned int irq)
+static void ns9xxx_ack_irq(struct irq_desc *desc)
 {
 	__raw_writel(0, SYS_ISRADDR);
 }
 
-static void ns9xxx_maskack_irq(unsigned int irq)
+static void ns9xxx_maskack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ns9xxx_mask_irq(irq);
 	ns9xxx_ack_irq(irq);
 }
 
-static void ns9xxx_unmask_irq(unsigned int irq)
+static void ns9xxx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* XXX: better use cpp symbols */
 	int prio = irq2prio(irq);
 	u32 ic = __raw_readl(SYS_IC(prio / 4));
@@ -92,10 +95,10 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 
 	if (desc->status & IRQ_DISABLED)
 out_mask:
-		desc->chip->mask(irq);
+		desc->chip->mask(desc);
 
 	/* ack unconditionally to unmask lower prio irqs */
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	raw_spin_unlock(&desc->lock);
 }
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 5cfce16..ad013b0 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -30,8 +30,9 @@
 #include <plat/fpga.h>
 #include <mach/gpio.h>
 
-static void fpga_mask_irq(unsigned int irq)
+static void fpga_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= OMAP_FPGA_IRQ_BASE;
 
 	if (irq < 8)
@@ -58,13 +59,14 @@ static inline u32 get_fpga_unmasked_irqs(void)
 }
 
 
-static void fpga_ack_irq(unsigned int irq)
+static void fpga_ack_irq(struct irq_desc *desc)
 {
 	/* Don't need to explicitly ACK FPGA interrupts */
 }
 
-static void fpga_unmask_irq(unsigned int irq)
+static void fpga_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= OMAP_FPGA_IRQ_BASE;
 
 	if (irq < 8)
@@ -78,10 +80,10 @@ static void fpga_unmask_irq(unsigned int irq)
 			      | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
 }
 
-static void fpga_mask_ack_irq(unsigned int irq)
+static void fpga_mask_ack_irq(struct irq_desc *desc)
 {
-	fpga_mask_irq(irq);
-	fpga_ack_irq(irq);
+	fpga_mask_irq(desc);
+	fpga_ack_irq(desc);
 }
 
 void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index db913c3..7dcaf35 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -70,16 +70,18 @@ static inline void irq_bank_writel(unsigned long value, int bank, int offset)
 	omap_writel(value, irq_banks[bank].base_reg + offset);
 }
 
-static void omap_ack_irq(unsigned int irq)
+static void omap_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq > 31)
 		omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
 
 	omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
 }
 
-static void omap_mask_irq(unsigned int irq)
+static void omap_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 	u32 l;
 
@@ -88,8 +90,9 @@ static void omap_mask_irq(unsigned int irq)
 	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
-static void omap_unmask_irq(unsigned int irq)
+static void omap_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 	u32 l;
 
@@ -98,14 +101,15 @@ static void omap_unmask_irq(unsigned int irq)
 	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
 }
 
-static void omap_mask_ack_irq(unsigned int irq)
+static void omap_mask_ack_irq(struct irq_desc *desc)
 {
-	omap_mask_irq(irq);
-	omap_ack_irq(irq);
+	omap_mask_irq(desc);
+	omap_ack_irq(desc);
 }
 
-static int omap_wake_irq(unsigned int irq, unsigned int enable)
+static int omap_wake_irq(struct irq_desc *desc, unsigned int enable)
 {
+	unsigned int irq = desc->irq;
 	int bank = IRQ_BANK(irq);
 
 	if (enable)
@@ -234,9 +238,9 @@ void __init omap_init_irq(void)
 	/* Unmask level 2 handler */
 
 	if (cpu_is_omap7xx())
-		omap_unmask_irq(INT_7XX_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_7XX_IH2_IRQ));
 	else if (cpu_is_omap15xx())
-		omap_unmask_irq(INT_1510_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_1510_IH2_IRQ));
 	else if (cpu_is_omap16xx())
-		omap_unmask_irq(INT_1610_IH2_IRQ);
+		omap_unmask_irq(irq_to_desc(INT_1610_IH2_IRQ));
 }
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 26aeef5..32f8da9 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -101,13 +101,14 @@ static int omap_check_spurious(unsigned int irq)
 }
 
 /* XXX: FIQ and additional INTC support (only MPU at the moment) */
-static void omap_ack_irq(unsigned int irq)
+static void omap_ack_irq(struct irq_desc *desc)
 {
 	intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
 }
 
-static void omap_mask_irq(unsigned int irq)
+static void omap_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
 	if (cpu_is_omap34xx()) {
@@ -129,8 +130,9 @@ static void omap_mask_irq(unsigned int irq)
 	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
 }
 
-static void omap_unmask_irq(unsigned int irq)
+static void omap_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
 	irq &= (IRQ_BITS_PER_REG - 1);
@@ -138,10 +140,10 @@ static void omap_unmask_irq(unsigned int irq)
 	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
 }
 
-static void omap_mask_ack_irq(unsigned int irq)
+static void omap_mask_ack_irq(struct irq_desc *desc)
 {
-	omap_mask_irq(irq);
-	omap_ack_irq(irq);
+	omap_mask_irq(desc);
+	omap_ack_irq(desc);
 }
 
 static struct irq_chip omap_irq_chip = {
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
index a9ce02b..a08d90f 100644
--- a/arch/arm/mach-pnx4008/irq.c
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -36,24 +36,28 @@
 
 static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
 
-static void pnx4008_mask_irq(unsigned int irq)
+static void pnx4008_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
 }
 
-static void pnx4008_unmask_irq(unsigned int irq)
+static void pnx4008_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq));	/* unmask interrupt */
 }
 
-static void pnx4008_mask_ack_irq(unsigned int irq)
+static void pnx4008_mask_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
 	__raw_writel(INTC_BIT(irq), INTC_SR(irq));	/* clear interrupt status */
 }
 
-static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
+static int pnx4008_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
 		__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq));	/*edge sensitive */
@@ -99,14 +103,14 @@ void __init pnx4008_init_irq(void)
 	for (i = 0; i < NR_IRQS; i++) {
 		set_irq_flags(i, IRQF_VALID);
 		set_irq_chip(i, &pnx4008_irq_chip);
-		pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
+		pnx4008_set_irq_type(irq_to_desc(i), pnx4008_irq_type[i]);
 	}
 
 	/* configure and enable IRQ 0,1,30,31 (cascade interrupts) */
-	pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
-	pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
-	pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
-	pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB1_IRQ_N), pnx4008_irq_type[SUB1_IRQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB2_IRQ_N), pnx4008_irq_type[SUB2_IRQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB1_FIQ_N), pnx4008_irq_type[SUB1_FIQ_N]);
+	pnx4008_set_irq_type(irq_to_desc(SUB2_FIQ_N), pnx4008_irq_type[SUB2_FIQ_N]);
 
 	/* mask all others */
 	__raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index f3b5ace..02b7e00 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -73,15 +73,17 @@ int __init parse_balloon3_features(char *arg)
 }
 early_param("balloon3_features", parse_balloon3_features);
 
-static void balloon3_mask_irq(unsigned int irq)
+static void balloon3_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int balloon3_irq = (irq - BALLOON3_IRQ(0));
 	balloon3_irq_enabled &= ~(1 << balloon3_irq);
 	__raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
 }
 
-static void balloon3_unmask_irq(unsigned int irq)
+static void balloon3_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int balloon3_irq = (irq - BALLOON3_IRQ(0));
 	balloon3_irq_enabled |= (1 << balloon3_irq);
 	__raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
@@ -102,7 +104,7 @@ static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc)
 	do {
 		/* clear useless edge notification */
 		if (desc->chip->ack)
-			desc->chip->ack(BALLOON3_AUX_NIRQ);
+			desc->chip->ack(irq_to_desc(BALLOON3_AUX_NIRQ));
 		while (pending) {
 			irq = BALLOON3_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 890fb90..2d2cb9c 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,9 @@
 struct sys_timer;
 
 extern struct sys_timer pxa_timer;
+struct irq_desc;
 extern void __init pxa_init_irq(int irq_nr,
-				int (*set_wake)(unsigned int, unsigned int));
+				int (*set_wake)(struct irq_desc *desc, unsigned int));
 extern void __init pxa25x_init_irq(void);
 #ifdef CONFIG_CPU_PXA26x
 extern void __init pxa26x_init_irq(void);
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 1beb40f..5103a3d 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -37,13 +37,15 @@
 
 static int pxa_internal_irq_nr;
 
-static void pxa_mask_irq(unsigned int irq)
+static void pxa_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
 }
 
-static void pxa_unmask_irq(unsigned int irq)
+static void pxa_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	_ICMR(irq) |= 1 << IRQ_BIT(irq);
 }
 
@@ -57,8 +59,9 @@ static struct irq_chip pxa_internal_irq_chip = {
 /*
  * GPIO IRQs for GPIO 0 and 1
  */
-static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
+static int pxa_set_low_gpio_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq - IRQ_GPIO0;
 
 	if (__gpio_is_occupied(gpio)) {
@@ -79,18 +82,21 @@ static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
 	return 0;
 }
 
-static void pxa_ack_low_gpio(unsigned int irq)
+static void pxa_ack_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GEDR0 = (1 << (irq - IRQ_GPIO0));
 }
 
-static void pxa_mask_low_gpio(unsigned int irq)
+static void pxa_mask_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
 }
 
-static void pxa_unmask_low_gpio(unsigned int irq)
+static void pxa_unmask_low_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= 1 << (irq - PXA_IRQ(0));
 }
 
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index d279507..0d6ba7b 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -94,8 +94,9 @@ static unsigned long lpd270_pin_config[] __initdata = {
 
 static unsigned int lpd270_irq_enabled;
 
-static void lpd270_mask_irq(unsigned int irq)
+static void lpd270_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lpd270_irq = irq - LPD270_IRQ(0);
 
 	__raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS);
@@ -104,8 +105,9 @@ static void lpd270_mask_irq(unsigned int irq)
 	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
 }
 
-static void lpd270_unmask_irq(unsigned int irq)
+static void lpd270_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lpd270_irq = irq - LPD270_IRQ(0);
 
 	lpd270_irq_enabled |= 1 << lpd270_irq;
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 63d65a2..c133f49 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -121,14 +121,16 @@ EXPORT_SYMBOL(lubbock_set_misc_wr);
 
 static unsigned long lubbock_irq_enabled;
 
-static void lubbock_mask_irq(unsigned int irq)
+static void lubbock_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
 	LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
 }
 
-static void lubbock_unmask_irq(unsigned int irq)
+static void lubbock_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 5543c64..f7da0c6 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -122,14 +122,16 @@ static unsigned long mainstone_pin_config[] = {
 
 static unsigned long mainstone_irq_enabled;
 
-static void mainstone_mask_irq(unsigned int irq)
+static void mainstone_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
 	MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
 }
 
-static void mainstone_unmask_irq(unsigned int irq)
+static void mainstone_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	MST_INTSETCLR &= ~(1 << mainstone_irq);
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 9d0ecea..9e2f67f 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -241,14 +241,16 @@ static struct platform_device pcm990_backlight_device = {
 
 static unsigned long pcm990_irq_enabled;
 
-static void pcm990_mask_ack_irq(unsigned int irq)
+static void pcm990_mask_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pcm990_irq = (irq - PCM027_IRQ(0));
 	PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
 }
 
-static void pcm990_unmask_irq(unsigned int irq)
+static void pcm990_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pcm990_irq = (irq - PCM027_IRQ(0));
 	/* the irq can be acknowledged only if deasserted, so it's done here */
 	PCM990_INTSETCLR |= 1 << pcm990_irq;
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 0b9ad30..ee62738 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/suspend.h>
 #include <linux/sysdev.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
@@ -282,8 +283,9 @@ static inline void pxa25x_init_pm(void) {}
 /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
  */
 
-static int pxa25x_set_wake(unsigned int irq, unsigned int on)
+static int pxa25x_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int gpio = IRQ_TO_GPIO(irq);
 	uint32_t mask = 0;
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 0af3617..027b5f9 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -17,6 +17,7 @@
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -334,8 +335,9 @@ static inline void pxa27x_init_pm(void) {}
 /* PXA27x:  Various gpios can issue wakeup events.  This logic only
  * handles the simple cases, not the WEMUX2 and WEMUX3 options
  */
-static int pxa27x_set_wake(unsigned int irq, unsigned int on)
+static int pxa27x_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int gpio = IRQ_TO_GPIO(irq);
 	uint32_t mask;
 
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4d7c03e..7204fbd 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -536,19 +536,22 @@ static inline void pxa3xx_init_pm(void) {}
 #define pxa3xx_set_wake	NULL
 #endif
 
-static void pxa_ack_ext_wakeup(unsigned int irq)
+static void pxa_ack_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	PECR |= PECR_IS(irq - IRQ_WAKEUP0);
 }
 
-static void pxa_mask_ext_wakeup(unsigned int irq)
+static void pxa_mask_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
 	PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
 }
 
-static void pxa_unmask_ext_wakeup(unsigned int irq)
+static void pxa_unmask_ext_wakeup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
 	PECR |= PECR_IE(irq - IRQ_WAKEUP0);
 }
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 1dd1334..5836c2e 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -247,8 +247,9 @@ static inline int viper_bit_to_irq(int bit)
 	return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
 }
 
-static void viper_ack_irq(unsigned int irq)
+static void viper_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int viper_irq = viper_irq_to_bitmask(irq);
 
 	if (viper_irq & 0xff)
@@ -257,13 +258,15 @@ static void viper_ack_irq(unsigned int irq)
 		VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
 }
 
-static void viper_mask_irq(unsigned int irq)
+static void viper_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq));
 }
 
-static void viper_unmask_irq(unsigned int irq)
+static void viper_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	viper_irq_enabled_mask |= viper_irq_to_bitmask(irq);
 }
 
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 39896d8..e2c96f7 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -82,18 +82,21 @@ static inline int zeus_bit_to_irq(int bit)
 	return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0);
 }
 
-static void zeus_ack_irq(unsigned int irq)
+static void zeus_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writew(zeus_irq_to_bitmask(irq), ZEUS_CPLD_ISA_IRQ);
 }
 
-static void zeus_mask_irq(unsigned int irq)
+static void zeus_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(irq));
 }
 
-static void zeus_unmask_irq(unsigned int irq)
+static void zeus_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	zeus_irq_enabled_mask |= zeus_irq_to_bitmask(irq);
 }
 
@@ -110,7 +113,8 @@ static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc)
 	do {
 		/* we're in a chained irq handler,
 		 * so ack the interrupt by hand */
-		desc->chip->ack(gpio_to_irq(ZEUS_ISA_GPIO));
+		int irqx = gpio_to_irq(ZEUS_ISA_GPIO);
+		desc->chip->ack(irq_to_desc(irqx));
 
 		if (likely(pending)) {
 			irq = zeus_bit_to_irq(__ffs(pending));
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 9dd15d6..e273268 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -6,8 +6,9 @@
 #include <asm/hardware/iomd.h>
 #include <asm/irq.h>
 
-static void iomd_ack_irq_a(unsigned int irq)
+static void iomd_ack_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -16,8 +17,9 @@ static void iomd_ack_irq_a(unsigned int irq)
 	iomd_writeb(mask, IOMD_IRQCLRA);
 }
 
-static void iomd_mask_irq_a(unsigned int irq)
+static void iomd_mask_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -25,8 +27,9 @@ static void iomd_mask_irq_a(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
 }
 
-static void iomd_unmask_irq_a(unsigned int irq)
+static void iomd_unmask_irq_a(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << irq;
@@ -40,8 +43,9 @@ static struct irq_chip iomd_a_chip = {
 	.unmask = iomd_unmask_irq_a,
 };
 
-static void iomd_mask_irq_b(unsigned int irq)
+static void iomd_mask_irq_b(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -49,8 +53,9 @@ static void iomd_mask_irq_b(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
 }
 
-static void iomd_unmask_irq_b(unsigned int irq)
+static void iomd_unmask_irq_b(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -64,8 +69,9 @@ static struct irq_chip iomd_b_chip = {
 	.unmask = iomd_unmask_irq_b,
 };
 
-static void iomd_mask_irq_dma(unsigned int irq)
+static void iomd_mask_irq_dma(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -73,8 +79,9 @@ static void iomd_mask_irq_dma(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_DMAMASK);
 }
 
-static void iomd_unmask_irq_dma(unsigned int irq)
+static void iomd_unmask_irq_dma(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -88,8 +95,9 @@ static struct irq_chip iomd_dma_chip = {
 	.unmask = iomd_unmask_irq_dma,
 };
 
-static void iomd_mask_irq_fiq(unsigned int irq)
+static void iomd_mask_irq_fiq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
@@ -97,8 +105,9 @@ static void iomd_mask_irq_fiq(unsigned int irq)
 	iomd_writeb(val & ~mask, IOMD_FIQMASK);
 }
 
-static void iomd_unmask_irq_fiq(unsigned int irq)
+static void iomd_unmask_irq_fiq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int val, mask;
 
 	mask = 1 << (irq & 7);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 217b102..7f16557 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -75,31 +75,32 @@ static unsigned char bast_pc104_irqmasks[] = {
 static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
 
 static void
-bast_pc104_mask(unsigned int irqno)
+bast_pc104_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp;
 
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-	temp &= ~bast_pc104_irqmasks[irqno];
+	temp &= ~bast_pc104_irqmasks[irq];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
 }
 
 static void
-bast_pc104_maskack(unsigned int irqno)
+bast_pc104_maskack(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + IRQ_ISA;
-
-	bast_pc104_mask(irqno);
-	desc->chip->ack(IRQ_ISA);
+	struct irq_desc *desc_isa = irq_to_desc(IRQ_ISA);
+	bast_pc104_mask(desc);
+	desc_isa->chip->ack(desc_isa);
 }
 
 static void
-bast_pc104_unmask(unsigned int irqno)
+bast_pc104_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long temp;
 
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-	temp |= bast_pc104_irqmasks[irqno];
+	temp |= bast_pc104_irqmasks[irq];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
 }
 
@@ -120,10 +121,11 @@ bast_irq_pc104_demux(unsigned int irq,
 	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
 
 	if (unlikely(stat == 0)) {
+		struct irq_desc *desc_isa;
 		/* ack if we get an irq with nothing (ie, startup) */
 
-		desc = irq_desc + IRQ_ISA;
-		desc->chip->ack(IRQ_ISA);
+		desc_isa = irq_to_desc(IRQ_ISA);
+		desc_isa->chip->ack(desc_isa);
 	} else {
 		/* handle the IRQ */
 
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index 6000ca9..e7aa082 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -49,9 +49,10 @@
 */
 
 static void
-s3c2412_irq_mask(unsigned int irqno)
+s3c2412_irq_mask(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -62,9 +63,10 @@ s3c2412_irq_mask(unsigned int irqno)
 }
 
 static inline void
-s3c2412_irq_ack(unsigned int irqno)
+s3c2412_irq_ack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 
 	__raw_writel(bitval, S3C2412_EINTPEND);
 	__raw_writel(bitval, S3C2410_SRCPND);
@@ -72,9 +74,10 @@ s3c2412_irq_ack(unsigned int irqno)
 }
 
 static inline void
-s3c2412_irq_maskack(unsigned int irqno)
+s3c2412_irq_maskack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -89,9 +92,10 @@ s3c2412_irq_maskack(unsigned int irqno)
 }
 
 static void
-s3c2412_irq_unmask(unsigned int irqno)
+s3c2412_irq_unmask(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2412_EINTMASK);
@@ -132,19 +136,22 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_CFSDI	(1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
 #define SUBMSK_CFSDI	INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
 
-static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_CFSDI, SUBMSK_CFSDI);
 }
 
-static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
+static void s3c2412_irq_cfsdi_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_CFSDI);
 }
 
-static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
+static void s3c2412_irq_cfsdi_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_CFSDI, SUBMSK_CFSDI);
 }
 
 static struct irq_chip s3c2412_irq_cfsdi = {
@@ -154,7 +161,7 @@ static struct irq_chip s3c2412_irq_cfsdi = {
 	.unmask		= s3c2412_irq_cfsdi_unmask,
 };
 
-static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
+static int s3c2412_irq_rtc_wake(struct irq_desc *desc, unsigned int state)
 {
 	unsigned long pwrcfg;
 
@@ -165,7 +172,7 @@ static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
 		pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
 	__raw_writel(pwrcfg, S3C2412_PWRCFG);
 
-	return s3c_irq_chip.set_wake(irqno, state);
+	return s3c_irq_chip.set_wake(desc, state);
 }
 
 static struct irq_chip s3c2412_irq_rtc_chip;
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 0c049b9..60b88aa 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -69,21 +69,24 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
 #define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
 
 static void
-s3c_irq_wdtac97_mask(unsigned int irqno)
+s3c_irq_wdtac97_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_WDT, 3<<13);
 }
 
 static void
-s3c_irq_wdtac97_unmask(unsigned int irqno)
+s3c_irq_wdtac97_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_WDT);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_WDT);
 }
 
 static void
-s3c_irq_wdtac97_ack(unsigned int irqno)
+s3c_irq_wdtac97_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_WDT, 3<<13);
 }
 
 static struct irq_chip s3c_irq_wdtac97 = {
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 0e0d693..d87a496 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -75,19 +75,22 @@ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
 #define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
 
-static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
 }
 
-static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
+static void s3c2443_irq_wdtac97_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_WDTAC97);
 }
 
-static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
+static void s3c2443_irq_wdtac97_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
 }
 
 static struct irq_chip s3c2443_irq_wdtac97 = {
@@ -107,19 +110,22 @@ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
 #define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
 
-static void s3c2443_irq_lcd_mask(unsigned int irqno)
+static void s3c2443_irq_lcd_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_LCD, SUBMSK_LCD);
 }
 
-static void s3c2443_irq_lcd_unmask(unsigned int irqno)
+static void s3c2443_irq_lcd_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_LCD);
 }
 
-static void s3c2443_irq_lcd_ack(unsigned int irqno)
+static void s3c2443_irq_lcd_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_LCD, SUBMSK_LCD);
 }
 
 static struct irq_chip s3c2443_irq_lcd = {
@@ -140,19 +146,22 @@ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
 #define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
 
 
-static void s3c2443_irq_dma_mask(unsigned int irqno)
+static void s3c2443_irq_dma_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_DMA, SUBMSK_DMA);
 }
 
-static void s3c2443_irq_dma_unmask(unsigned int irqno)
+static void s3c2443_irq_dma_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_DMA);
 }
 
-static void s3c2443_irq_dma_ack(unsigned int irqno)
+static void s3c2443_irq_dma_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_DMA, SUBMSK_DMA);
 }
 
 static struct irq_chip s3c2443_irq_dma = {
@@ -173,19 +182,22 @@ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
 #define SUBMSK_UART3	(0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
 
 
-static void s3c2443_irq_uart3_mask(unsigned int irqno)
+static void s3c2443_irq_uart3_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART3, SUBMSK_UART3);
 }
 
-static void s3c2443_irq_uart3_unmask(unsigned int irqno)
+static void s3c2443_irq_uart3_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART3);
 }
 
-static void s3c2443_irq_uart3_ack(unsigned int irqno)
+static void s3c2443_irq_uart3_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART3, SUBMSK_UART3);
 }
 
 static struct irq_chip s3c2443_irq_uart3 = {
@@ -205,19 +217,22 @@ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
 #define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
 #define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
 
-static void s3c2443_irq_cam_mask(unsigned int irqno)
+static void s3c2443_irq_cam_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_CAM, SUBMSK_CAM);
 }
 
-static void s3c2443_irq_cam_unmask(unsigned int irqno)
+static void s3c2443_irq_cam_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_CAM);
 }
 
-static void s3c2443_irq_cam_ack(unsigned int irqno)
+static void s3c2443_irq_cam_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_CAM, SUBMSK_CAM);
 }
 
 static struct irq_chip s3c2443_irq_cam = {
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 3093d46..f54c973 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -37,8 +37,9 @@ static int GPIO_IRQ_mask = (1 << 11) - 1;
 #define GPIO_11_27_IRQ(i)	((i) - 21)
 #define GPIO11_27_MASK(irq)	(1 << GPIO_11_27_IRQ(irq))
 
-static int sa1100_gpio_type(unsigned int irq, unsigned int type)
+static int sa1100_gpio_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 
 	if (irq <= 10)
@@ -70,23 +71,27 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
 /*
  * GPIO IRQs must be acknowledged.  This is for IRQs from 0 to 10.
  */
-static void sa1100_low_gpio_ack(unsigned int irq)
+static void sa1100_low_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	GEDR = (1 << irq);
 }
 
-static void sa1100_low_gpio_mask(unsigned int irq)
+static void sa1100_low_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << irq);
 }
 
-static void sa1100_low_gpio_unmask(unsigned int irq)
+static void sa1100_low_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= 1 << irq;
 }
 
-static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on)
+static int sa1100_low_gpio_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (on)
 		PWER |= 1 << irq;
 	else
@@ -139,15 +144,17 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
  * In addition, the IRQs are all collected up into one bit in the
  * interrupt controller registers.
  */
-static void sa1100_high_gpio_ack(unsigned int irq)
+static void sa1100_high_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GEDR = mask;
 }
 
-static void sa1100_high_gpio_mask(unsigned int irq)
+static void sa1100_high_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GPIO_IRQ_mask &= ~mask;
@@ -156,8 +163,9 @@ static void sa1100_high_gpio_mask(unsigned int irq)
 	GFER &= ~mask;
 }
 
-static void sa1100_high_gpio_unmask(unsigned int irq)
+static void sa1100_high_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = GPIO11_27_MASK(irq);
 
 	GPIO_IRQ_mask |= mask;
@@ -166,8 +174,9 @@ static void sa1100_high_gpio_unmask(unsigned int irq)
 	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 }
 
-static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on)
+static int sa1100_high_gpio_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (on)
 		PWER |= GPIO11_27_MASK(irq);
 	else
@@ -188,21 +197,24 @@ static struct irq_chip sa1100_high_gpio_chip = {
  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
  * this is for internal IRQs i.e. from 11 to 31.
  */
-static void sa1100_mask_irq(unsigned int irq)
+static void sa1100_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR &= ~(1 << irq);
 }
 
-static void sa1100_unmask_irq(unsigned int irq)
+static void sa1100_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	ICMR |= (1 << irq);
 }
 
 /*
  * Apart form GPIOs, only the RTC alarm can be a wakeup event.
  */
-static int sa1100_set_wake(unsigned int irq, unsigned int on)
+static int sa1100_set_wake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	if (irq == IRQ_RTCAlrm) {
 		if (on)
 			PWER |= PWER_RTC;
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 0b505d9..4003df3 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -36,7 +36,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 		/*
 		 * Acknowledge the parent IRQ.
 		 */
-		desc->chip->ack(irq);
+		desc->chip->ack(desc);
 
 		/*
 		 * Read the interrupt reason register.  Let's have all
@@ -54,7 +54,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 		 * recheck the register for any pending IRQs.
 		 */
 		if (irr & (IRR_ETHERNET | IRR_USAR)) {
-			desc->chip->mask(irq);
+			desc->chip->mask(desc);
 
 			/*
 			 * Ack the interrupt now to prevent re-entering
@@ -62,7 +62,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 			 * since we'll check the IRR register prior to
 			 * leaving.
 			 */
-			desc->chip->ack(irq);
+			desc->chip->ack(desc);
 
 			if (irr & IRR_ETHERNET) {
 				generic_handle_irq(IRQ_NEPONSET_SMC9196);
@@ -72,7 +72,7 @@ neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 				generic_handle_irq(IRQ_NEPONSET_USAR);
 			}
 
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		}
 
 		if (irr & IRR_SA1111) {
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
index c04eb6a..0f17814 100644
--- a/arch/arm/mach-shark/irq.c
+++ b/arch/arm/mach-shark/irq.c
@@ -30,8 +30,9 @@ static unsigned char cached_irq_mask[2] = { 0xfb, 0xff };
  * These have to be protected by the irq controller spinlock
  * before being called.
  */
-static void shark_disable_8259A_irq(unsigned int irq)
+static void shark_disable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	if (irq<8) {
 	  mask = 1 << irq;
@@ -44,8 +45,9 @@ static void shark_disable_8259A_irq(unsigned int irq)
 	}
 }
 
-static void shark_enable_8259A_irq(unsigned int irq)
+static void shark_enable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	if (irq<8) {
 	  mask = ~(1 << irq);
@@ -58,7 +60,9 @@ static void shark_enable_8259A_irq(unsigned int irq)
 	}
 }
 
-static void shark_ack_8259A_irq(unsigned int irq){}
+static void shark_ack_8259A_irq(struct irq_desc *desc)
+{
+}
 
 static irqreturn_t bogus_int(int irq, void *dev_id)
 {
diff --git a/arch/arm/mach-stmp378x/stmp378x.c b/arch/arm/mach-stmp378x/stmp378x.c
index ddd49a7..5224f31 100644
--- a/arch/arm/mach-stmp378x/stmp378x.c
+++ b/arch/arm/mach-stmp378x/stmp378x.c
@@ -47,8 +47,9 @@
 /*
  * IRQ handling
  */
-static void stmp378x_ack_irq(unsigned int irq)
+static void stmp378x_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Tell ICOLL to release IRQ line */
 	__raw_writel(0, REGS_ICOLL_BASE + HW_ICOLL_VECTOR);
 
@@ -60,15 +61,17 @@ static void stmp378x_ack_irq(unsigned int irq)
 	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
 }
 
-static void stmp378x_mask_irq(unsigned int irq)
+static void stmp378x_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ disable */
 	stmp3xxx_clearl(BM_ICOLL_INTERRUPTn_ENABLE,
 			REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + irq * 0x10);
 }
 
-static void stmp378x_unmask_irq(unsigned int irq)
+static void stmp378x_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ enable */
 	stmp3xxx_setl(BM_ICOLL_INTERRUPTn_ENABLE,
 		      REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + irq * 0x10);
diff --git a/arch/arm/mach-stmp37xx/stmp37xx.c b/arch/arm/mach-stmp37xx/stmp37xx.c
index 8c7d6fb..c080776 100644
--- a/arch/arm/mach-stmp37xx/stmp37xx.c
+++ b/arch/arm/mach-stmp37xx/stmp37xx.c
@@ -43,8 +43,9 @@
 /*
  * IRQ handling
  */
-static void stmp37xx_ack_irq(unsigned int irq)
+static void stmp37xx_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Disable IRQ */
 	stmp3xxx_clearl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
@@ -56,15 +57,17 @@ static void stmp37xx_ack_irq(unsigned int irq)
 	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
 }
 
-static void stmp37xx_mask_irq(unsigned int irq)
+static void stmp37xx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ disable */
 	stmp3xxx_clearl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
 }
 
-static void stmp37xx_unmask_irq(unsigned int irq)
+static void stmp37xx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* IRQ enable */
 	stmp3xxx_setl(0x04 << ((irq % 4) * 8),
 		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9ddb49b..79892c8 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -62,14 +62,16 @@
 #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 
-static void sic_mask_irq(unsigned int irq)
+static void sic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 }
 
-static void sic_unmask_irq(unsigned int irq)
+static void sic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= IRQ_SIC_START;
 	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
 }
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 0ce9d8e..03e5834 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -92,8 +92,9 @@ static void nuc900_group_enable(struct group_irq *gpirq, int enable)
 	__raw_writel(regval, REG_AIC_GEN);
 }
 
-static void nuc900_irq_mask(unsigned int irq)
+static void nuc900_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct group_irq *group_irq;
 
 	group_irq = NULL;
@@ -143,13 +144,14 @@ static void nuc900_irq_mask(unsigned int irq)
  * to REG_AIC_EOSCR for ACK
  */
 
-static void nuc900_irq_ack(unsigned int irq)
+static void nuc900_irq_ack(struct irq_desc *desc)
 {
 	__raw_writel(0x01, REG_AIC_EOSCR);
 }
 
-static void nuc900_irq_unmask(unsigned int irq)
+static void nuc900_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct group_irq *group_irq;
 
 	group_irq = NULL;
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
index f73ce87..1b3afb2 100644
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -270,12 +270,12 @@ static void em_stop(void)
  */
 static void em_route_irq(int irq, unsigned int cpu)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	struct irq_desc *desc = irq_to_desc(irq);
 	const struct cpumask *mask = cpumask_of(cpu);
 
 	spin_lock_irq(&desc->lock);
 	cpumask_copy(desc->affinity, mask);
-	desc->chip->set_affinity(irq, mask);
+	desc->chip->set_affinity(desc, mask);
 	spin_unlock_irq(&desc->lock);
 }
 
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 70b2389..06385cd 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -63,28 +63,32 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
 	__raw_writel(l, port->base + GPIO_IMR);
 }
 
-static void gpio_ack_irq(u32 irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
 }
 
-static void gpio_mask_irq(u32 irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
 }
 
-static void gpio_unmask_irq(u32 irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
 }
 
 static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
 
-static int gpio_set_irq_type(u32 irq, u32 type)
+static int gpio_set_irq_type(struct irq_desc *desc, u32 type)
 {
+	unsigned int irq = desc->irq;
 	u32 gpio = irq_to_gpio(irq);
 	struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
 	u32 bit, val;
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 778ddfe..3721b92 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -91,14 +91,16 @@ EXPORT_SYMBOL(mxc_set_irq_fiq);
 #endif /* CONFIG_FIQ */
 
 /* Disable interrupt number "irq" in the AVIC */
-static void mxc_mask_irq(unsigned int irq)
+static void mxc_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(irq, avic_base + AVIC_INTDISNUM);
 }
 
 /* Enable interrupt number "irq" in the AVIC */
-static void mxc_unmask_irq(unsigned int irq)
+static void mxc_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__raw_writel(irq, avic_base + AVIC_INTENNUM);
 }
 
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 76a347b..ae0f98c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -871,8 +871,9 @@ bad:
 	return -EINVAL;
 }
 
-static int gpio_irq_type(unsigned irq, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	struct gpio_bank *bank;
 	unsigned gpio;
 	int retval;
@@ -894,7 +895,7 @@ static int gpio_irq_type(unsigned irq, unsigned type)
 			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
 		return -EINVAL;
 
-	bank = get_irq_chip_data(irq);
+	bank = get_irq_desc_chip_data(desc);
 	spin_lock_irqsave(&bank->lock, flags);
 	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
 	if (retval == 0) {
@@ -1163,15 +1164,16 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
-static int gpio_wake_enable(unsigned int irq, unsigned int enable)
+static int gpio_wake_enable(struct irq_desc *desc, unsigned int enable)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank;
 	int retval;
 
 	if (check_gpio(gpio) < 0)
 		return -ENODEV;
-	bank = get_irq_chip_data(irq);
+	bank = get_irq_desc_chip_data(desc);
 	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
 
 	return retval;
@@ -1266,7 +1268,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	u32 retrigger = 0;
 	int unmasked = 0;
 
-	desc->chip->ack(irq);
+	desc->chip->ack(desc);
 
 	bank = get_irq_data(irq);
 #ifdef CONFIG_ARCH_OMAP1
@@ -1318,7 +1320,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		configured, we could unmask GPIO bank interrupt immediately */
 		if (!level_mask && !unmasked) {
 			unmasked = 1;
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		}
 
 		isr |= retrigger;
@@ -1353,28 +1355,31 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	handler(s) are executed in order to avoid spurious bank
 	interrupt */
 	if (!unmasked)
-		desc->chip->unmask(irq);
+		desc->chip->unmask(desc);
 
 }
 
-static void gpio_irq_shutdown(unsigned int irq)
+static void gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_reset_gpio(bank, gpio);
 }
 
-static void gpio_ack_irq(unsigned int irq)
+static void gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_clear_gpio_irqstatus(bank, gpio);
 }
 
-static void gpio_mask_irq(unsigned int irq)
+static void gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
@@ -1382,12 +1387,12 @@ static void gpio_mask_irq(unsigned int irq)
 	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
 }
 
-static void gpio_unmask_irq(unsigned int irq)
+static void gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 	unsigned int irq_mask = 1 << get_gpio_index(gpio);
-	struct irq_desc *desc = irq_to_desc(irq);
 	u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK;
 
 	if (trigger)
@@ -1419,21 +1424,23 @@ static struct irq_chip gpio_irq_chip = {
 
 /* MPUIO uses the always-on 32k clock */
 
-static void mpuio_ack_irq(unsigned int irq)
+static void mpuio_ack_irq(struct irq_desc *desc)
 {
 	/* The ISR is reset automatically, so do nothing here. */
 }
 
-static void mpuio_mask_irq(unsigned int irq)
+static void mpuio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 	_set_gpio_irqenable(bank, gpio, 0);
 }
 
-static void mpuio_unmask_irq(unsigned int irq)
+static void mpuio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	struct gpio_bank *bank = get_irq_chip_data(irq);
 
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index e814803..4fa621a 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -233,19 +233,21 @@ EXPORT_SYMBOL(orion_gpio_set_blink);
  *
  ****************************************************************************/
 
-static void gpio_irq_ack(u32 irq)
+static void gpio_irq_ack(struct irq_desc *desc)
 {
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	unsigned int irq = desc->irq;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
 		int pin = irq_to_gpio(irq);
 		writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin));
 	}
 }
 
-static void gpio_irq_mask(u32 irq)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
 		GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
 	u32 u = readl(reg);
@@ -253,10 +255,11 @@ static void gpio_irq_mask(u32 irq)
 	writel(u, reg);
 }
 
-static void gpio_irq_unmask(u32 irq)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
+	int type = desc->status & IRQ_TYPE_SENSE_MASK;
 	u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
 		GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
 	u32 u = readl(reg);
@@ -264,10 +267,10 @@ static void gpio_irq_unmask(u32 irq)
 	writel(u, reg);
 }
 
-static int gpio_irq_set_type(u32 irq, u32 type)
+static int gpio_irq_set_type(struct irq_desc *desc, u32 type)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq_to_gpio(irq);
-	struct irq_desc *desc;
 	u32 u;
 
 	u = readl(GPIO_IO_CONF(pin)) & (1 << (pin & 31));
@@ -277,8 +280,6 @@ static int gpio_irq_set_type(u32 irq, u32 type)
 		return -EINVAL;
 	}
 
-	desc = irq_desc + irq;
-
 	/*
 	 * Set edge/level type.
 	 */
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
index 3f9d34f..6cce58b 100644
--- a/arch/arm/plat-orion/irq.c
+++ b/arch/arm/plat-orion/irq.c
@@ -14,9 +14,10 @@
 #include <linux/io.h>
 #include <plat/irq.h>
 
-static void orion_irq_mask(u32 irq)
+static void orion_irq_mask(struct irq_desc *desc)
 {
-	void __iomem *maskaddr = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *maskaddr = get_irq_desc_chip_data(desc);
 	u32 mask;
 
 	mask = readl(maskaddr);
@@ -24,9 +25,10 @@ static void orion_irq_mask(u32 irq)
 	writel(mask, maskaddr);
 }
 
-static void orion_irq_unmask(u32 irq)
+static void orion_irq_unmask(struct irq_desc *desc)
 {
-	void __iomem *maskaddr = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *maskaddr = get_irq_desc_chip_data(desc);
 	u32 mask;
 
 	mask = readl(maskaddr);
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c
index 98548c6..00a5c10 100644
--- a/arch/arm/plat-pxa/gpio.c
+++ b/arch/arm/plat-pxa/gpio.c
@@ -155,8 +155,9 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
 	__raw_writel(gfer, c->regbase + GFER_OFFSET);
 }
 
-static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
+static int pxa_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	struct pxa_gpio_chip *c;
 	int gpio = irq_to_gpio(irq);
 	unsigned long gpdr, mask = GPIO_bit(gpio);
@@ -227,16 +228,18 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 	} while (loop);
 }
 
-static void pxa_ack_muxed_gpio(unsigned int irq)
+static void pxa_ack_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 
 	__raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
 }
 
-static void pxa_mask_muxed_gpio(unsigned int irq)
+static void pxa_mask_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 	uint32_t grer, gfer;
@@ -249,8 +252,9 @@ static void pxa_mask_muxed_gpio(unsigned int irq)
 	__raw_writel(gfer, c->regbase + GFER_OFFSET);
 }
 
-static void pxa_unmask_muxed_gpio(unsigned int irq)
+static void pxa_unmask_muxed_gpio(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int gpio = irq_to_gpio(irq);
 	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
 
diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h
index 44248cb..ffc6123 100644
--- a/arch/arm/plat-pxa/include/plat/gpio.h
+++ b/arch/arm/plat-pxa/include/plat/gpio.h
@@ -56,7 +56,8 @@ static inline void gpio_set_value(unsigned gpio, int value)
  */
 extern int pxa_last_gpio;
 
-typedef int (*set_wake_t)(unsigned int irq, unsigned int on);
+struct irq_desc;
+typedef int (*set_wake_t)(struct irq_desc *desc, unsigned int on);
 
 extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
 #endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 69e1be8..b2aac48 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -107,9 +107,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
 /* exported for use in arch/arm/mach-s3c2410 */
 
 #ifdef CONFIG_PM
-extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
+extern int s3c_irq_wake(struct irq_desc *desc, unsigned int state);
 #else
 #define s3c_irq_wake NULL
 #endif
 
-extern int s3c_irqext_type(unsigned int irq, unsigned int type);
+extern int s3c_irqext_type(struct irq_desc *desc, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
index ea8dea3..a8aeca9 100644
--- a/arch/arm/plat-s3c24xx/irq-pm.c
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -30,8 +30,9 @@
 unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
 unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
 
-int s3c_irq_wake(unsigned int irqno, unsigned int state)
+int s3c_irq_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irqno = desc->irq;
 	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
 
 	if (!(s3c_irqwake_intallow & irqbit))
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ad0d44e..87cc0c9 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -34,30 +34,33 @@
 #include <plat/irq.h>
 
 static void
-s3c_irq_mask(unsigned int irqno)
+s3c_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= IRQ_EINT0;
+	irq -= IRQ_EINT0;
 
 	mask = __raw_readl(S3C2410_INTMSK);
-	mask |= 1UL << irqno;
+	mask |= 1UL << irq;
 	__raw_writel(mask, S3C2410_INTMSK);
 }
 
 static inline void
-s3c_irq_ack(unsigned int irqno)
+s3c_irq_ack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 
 	__raw_writel(bitval, S3C2410_SRCPND);
 	__raw_writel(bitval, S3C2410_INTPND);
 }
 
 static inline void
-s3c_irq_maskack(unsigned int irqno)
+s3c_irq_maskack(struct irq_desc *desc)
 {
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned int irq = desc->irq;
+	unsigned long bitval = 1UL << (irq - IRQ_EINT0);
 	unsigned long mask;
 
 	mask = __raw_readl(S3C2410_INTMSK);
@@ -69,17 +72,18 @@ s3c_irq_maskack(unsigned int irqno)
 
 
 static void
-s3c_irq_unmask(unsigned int irqno)
+s3c_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-		irqdbf2("s3c_irq_unmask %d\n", irqno);
+	if (irq != IRQ_TIMER4 && irq != IRQ_EINT8t23)
+		irqdbf2("s3c_irq_unmask %d\n", irq);
 
-	irqno -= IRQ_EINT0;
+	irq -= IRQ_EINT0;
 
 	mask = __raw_readl(S3C2410_INTMSK);
-	mask &= ~(1UL << irqno);
+	mask &= ~(1UL << irq);
 	__raw_writel(mask, S3C2410_INTMSK);
 }
 
@@ -100,25 +104,27 @@ struct irq_chip s3c_irq_chip = {
 };
 
 static void
-s3c_irqext_mask(unsigned int irqno)
+s3c_irqext_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= EXTINT_OFF;
+	irq -= EXTINT_OFF;
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask |= ( 1UL << irqno);
+	mask |= (1UL << irq);
 	__raw_writel(mask, S3C24XX_EINTMASK);
 }
 
 static void
-s3c_irqext_ack(unsigned int irqno)
+s3c_irqext_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long req;
 	unsigned long bit;
 	unsigned long mask;
 
-	bit = 1UL << (irqno - EXTINT_OFF);
+	bit = 1UL << (irq - EXTINT_OFF);
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
 
@@ -129,30 +135,32 @@ s3c_irqext_ack(unsigned int irqno)
 
 	/* not sure if we should be acking the parent irq... */
 
-	if (irqno <= IRQ_EINT7 ) {
+	if (irq <= IRQ_EINT7) {
 		if ((req & 0xf0) == 0)
-			s3c_irq_ack(IRQ_EINT4t7);
+			s3c_irq_ack(irq_to_desc(IRQ_EINT4t7));
 	} else {
 		if ((req >> 8) == 0)
-			s3c_irq_ack(IRQ_EINT8t23);
+			s3c_irq_ack(irq_to_desc(IRQ_EINT8t23));
 	}
 }
 
 static void
-s3c_irqext_unmask(unsigned int irqno)
+s3c_irqext_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask;
 
-	irqno -= EXTINT_OFF;
+	irq -= EXTINT_OFF;
 
 	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask &= ~( 1UL << irqno);
+	mask &= ~(1UL << irq);
 	__raw_writel(mask, S3C24XX_EINTMASK);
 }
 
 int
-s3c_irqext_type(unsigned int irq, unsigned int type)
+s3c_irqext_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	void __iomem *extint_reg;
 	void __iomem *gpcon_reg;
 	unsigned long gpcon_offset, extint_offset;
@@ -261,21 +269,24 @@ static struct irq_chip s3c_irq_eint0t4 = {
 /* UART0 */
 
 static void
-s3c_irq_uart0_mask(unsigned int irqno)
+s3c_irq_uart0_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART0, 7);
 }
 
 static void
-s3c_irq_uart0_unmask(unsigned int irqno)
+s3c_irq_uart0_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART0);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART0);
 }
 
 static void
-s3c_irq_uart0_ack(unsigned int irqno)
+s3c_irq_uart0_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART0, 7);
 }
 
 static struct irq_chip s3c_irq_uart0 = {
@@ -288,21 +299,24 @@ static struct irq_chip s3c_irq_uart0 = {
 /* UART1 */
 
 static void
-s3c_irq_uart1_mask(unsigned int irqno)
+s3c_irq_uart1_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART1, 7 << 3);
 }
 
 static void
-s3c_irq_uart1_unmask(unsigned int irqno)
+s3c_irq_uart1_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART1);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART1);
 }
 
 static void
-s3c_irq_uart1_ack(unsigned int irqno)
+s3c_irq_uart1_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART1, 7 << 3);
 }
 
 static struct irq_chip s3c_irq_uart1 = {
@@ -315,21 +329,24 @@ static struct irq_chip s3c_irq_uart1 = {
 /* UART2 */
 
 static void
-s3c_irq_uart2_mask(unsigned int irqno)
+s3c_irq_uart2_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_UART2, 7 << 6);
 }
 
 static void
-s3c_irq_uart2_unmask(unsigned int irqno)
+s3c_irq_uart2_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_UART2);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_UART2);
 }
 
 static void
-s3c_irq_uart2_ack(unsigned int irqno)
+s3c_irq_uart2_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_maskack(irq, INTMSK_UART2, 7 << 6);
 }
 
 static struct irq_chip s3c_irq_uart2 = {
@@ -342,21 +359,24 @@ static struct irq_chip s3c_irq_uart2 = {
 /* ADC and Touchscreen */
 
 static void
-s3c_irq_adc_mask(unsigned int irqno)
+s3c_irq_adc_mask(struct irq_desc *desc)
 {
-	s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_mask(irq, INTMSK_ADCPARENT, 3 << 9);
 }
 
 static void
-s3c_irq_adc_unmask(unsigned int irqno)
+s3c_irq_adc_unmask(struct irq_desc *desc)
 {
-	s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_unmask(irq, INTMSK_ADCPARENT);
 }
 
 static void
-s3c_irq_adc_ack(unsigned int irqno)
+s3c_irq_adc_ack(struct irq_desc *desc)
 {
-	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+	unsigned int irq = desc->irq;
+	s3c_irqsub_ack(irq, INTMSK_ADCPARENT, 3 << 9);
 }
 
 static struct irq_chip s3c_irq_adc = {
diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
index 373122f..09642cb 100644
--- a/arch/arm/plat-s5pc1xx/irq-eint.c
+++ b/arch/arm/plat-s5pc1xx/irq-eint.c
@@ -67,8 +67,9 @@ static inline int s3c_eint_to_bit(unsigned int irq)
 	return bit;
 }
 
-static inline void s3c_irq_eint_mask(unsigned int irq)
+static inline void s3c_irq_eint_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 	u32 bank = s3c_get_bank(irq);
 
@@ -77,8 +78,9 @@ static inline void s3c_irq_eint_mask(unsigned int irq)
 	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
 }
 
-static void s3c_irq_eint_unmask(unsigned int irq)
+static void s3c_irq_eint_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 	u32 bank = s3c_get_bank(irq);
 
@@ -87,22 +89,24 @@ static void s3c_irq_eint_unmask(unsigned int irq)
 	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
 }
 
-static inline void s3c_irq_eint_ack(unsigned int irq)
+static inline void s3c_irq_eint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bank = s3c_get_bank(irq);
 
 	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
 }
 
-static void s3c_irq_eint_maskack(unsigned int irq)
+static void s3c_irq_eint_maskack(struct irq_desc *desc)
 {
 	/* compiler should in-line these */
-	s3c_irq_eint_mask(irq);
-	s3c_irq_eint_ack(irq);
+	s3c_irq_eint_mask(desc);
+	s3c_irq_eint_ack(desc);
 }
 
-static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+static int s3c_irq_eint_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	u32 bank = s3c_get_bank(irq);
 	int real = s3c_get_eint(irq);
 	int gpio, shift, sfn;
@@ -211,28 +215,31 @@ static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 /*
  * Handle EINT0 ... EINT15 at VIC directly
  */
-static void s3c_irq_vic_eint_mask(unsigned int irq)
+static void s3c_irq_vic_eint_mask(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
 	unsigned int real;
 
-	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_mask(desc);
 	real = s3c_get_eint(irq);
 	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
 }
 
-static void s3c_irq_vic_eint_unmask(unsigned int irq)
+static void s3c_irq_vic_eint_unmask(struct irq_desc *desc)
 {
-	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	void __iomem *base = get_irq_desc_chip_data(desc);
 	unsigned int real;
 
-	s3c_irq_eint_unmask(irq);
+	s3c_irq_eint_unmask(desc);
 	real = s3c_get_eint(irq);
 	writel(1 << real, base + VIC_INT_ENABLE);
 }
 
-static inline void s3c_irq_vic_eint_ack(unsigned int irq)
+static inline void s3c_irq_vic_eint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bit;
 	u32 bank = s3c_get_bank(irq);
 
@@ -240,11 +247,11 @@ static inline void s3c_irq_vic_eint_ack(unsigned int irq)
 	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
 }
 
-static void s3c_irq_vic_eint_maskack(unsigned int irq)
+static void s3c_irq_vic_eint_maskack(struct irq_desc *desc)
 {
 	/* compiler should in-line these */
-	s3c_irq_vic_eint_mask(irq);
-	s3c_irq_vic_eint_ack(irq);
+	s3c_irq_vic_eint_mask(desc);
+	s3c_irq_vic_eint_ack(desc);
 }
 
 static struct irq_chip s3c_irq_vic_eint = {
diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
index fecca7a..32f5395 100644
--- a/arch/arm/plat-s5pc1xx/irq-gpio.c
+++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
@@ -140,8 +140,9 @@ static int s5pc1xx_get_offset(unsigned int irq)
 	return irq - S3C_IRQ_GPIO(chip->base);
 }
 
-static void s5pc1xx_gpioint_ack(unsigned int irq)
+static void s5pc1xx_gpioint_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, pend_offset;
 	unsigned int value;
 
@@ -154,8 +155,9 @@ static void s5pc1xx_gpioint_ack(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
 }
 
-static void s5pc1xx_gpioint_mask(unsigned int irq)
+static void s5pc1xx_gpioint_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, mask_offset;
 	unsigned int value;
 
@@ -168,8 +170,9 @@ static void s5pc1xx_gpioint_mask(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
 }
 
-static void s5pc1xx_gpioint_unmask(unsigned int irq)
+static void s5pc1xx_gpioint_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, mask_offset;
 	unsigned int value;
 
@@ -182,14 +185,15 @@ static void s5pc1xx_gpioint_unmask(unsigned int irq)
 	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
 }
 
-static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
+static void s5pc1xx_gpioint_mask_ack(struct irq_desc *desc)
 {
-	s5pc1xx_gpioint_mask(irq);
-	s5pc1xx_gpioint_ack(irq);
+	s5pc1xx_gpioint_mask(desc);
+	s5pc1xx_gpioint_ack(desc);
 }
 
-static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
+static int s5pc1xx_gpioint_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int group, offset, con_offset;
 	unsigned int value;
 
diff --git a/arch/arm/plat-stmp3xxx/irq.c b/arch/arm/plat-stmp3xxx/irq.c
index 20de4e0..eeaf936 100644
--- a/arch/arm/plat-stmp3xxx/irq.c
+++ b/arch/arm/plat-stmp3xxx/irq.c
@@ -34,7 +34,7 @@ void __init stmp3xxx_init_irq(struct irq_chip *chip)
 
 	/* Disable all interrupts initially */
 	for (i = 0; i < NR_REAL_IRQS; i++) {
-		chip->mask(i);
+		chip->mask(irq_to_desc(i));
 		set_irq_chip(i, chip);
 		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/plat-stmp3xxx/pinmux.c b/arch/arm/plat-stmp3xxx/pinmux.c
index 6d6b1a4..c0b7002 100644
--- a/arch/arm/plat-stmp3xxx/pinmux.c
+++ b/arch/arm/plat-stmp3xxx/pinmux.c
@@ -365,8 +365,9 @@ static int stmp3xxx_irq_to_gpio(int irq,
 	return -ENOENT;
 }
 
-static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
+static int stmp3xxx_set_irqtype(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 	int l, p;
@@ -398,8 +399,9 @@ static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
 	return 0;
 }
 
-static void stmp3xxx_pin_ack_irq(unsigned irq)
+static void stmp3xxx_pin_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 stat;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
@@ -409,8 +411,9 @@ static void stmp3xxx_pin_ack_irq(unsigned irq)
 	stmp3xxx_clearl(stat, pm->irqstat);
 }
 
-static void stmp3xxx_pin_mask_irq(unsigned irq)
+static void stmp3xxx_pin_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 
@@ -419,8 +422,9 @@ static void stmp3xxx_pin_mask_irq(unsigned irq)
 	stmp3xxx_clearl(1 << gpio, pm->pin2irq);
 }
 
-static void stmp3xxx_pin_unmask_irq(unsigned irq)
+static void stmp3xxx_pin_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct stmp3xxx_pinmux_bank *pm;
 	unsigned gpio;
 
@@ -533,7 +537,7 @@ int __init stmp3xxx_pinmux_init(int virtual_irq_start)
 		pm->virq = virtual_irq_start + b * 32;
 
 		for (virq = pm->virq; virq < pm->virq; virq++) {
-			gpio_irq_chip.mask(virq);
+			gpio_irq_chip.mask(irq_to_desc(virq));
 			set_irq_chip(virq, &gpio_irq_chip);
 			set_irq_handler(virq, handle_level_irq);
 			set_irq_flags(virq, IRQF_VALID);
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 310477b..da67541 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -60,35 +60,39 @@ struct eic {
 static struct eic *nmi_eic;
 static bool nmi_enabled;
 
-static void eic_ack_irq(unsigned int irq)
+static void eic_ack_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_mask_irq(unsigned int irq)
+static void eic_mask_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_mask_ack_irq(unsigned int irq)
+static void eic_mask_ack_irq(struct irq_desc *desc)
 {
-	struct eic *eic = get_irq_chip_data(irq);
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
 	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eic_unmask_irq(unsigned int irq)
+static void eic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct eic *eic = get_irq_chip_data(irq);
 	eic_writel(eic, IER, 1 << (irq - eic->first_irq));
 }
 
-static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int eic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct eic *eic = get_irq_chip_data(irq);
-	struct irq_desc *desc;
+	unsigned int irq = desc->irq;
+	struct eic *eic = get_irq_desc_chip_data(desc);
 	unsigned int i = irq - eic->first_irq;
 	u32 mode, edge, level;
 	int ret = 0;
@@ -97,8 +101,6 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
 	if (flow_type == IRQ_TYPE_NONE)
 		flow_type = IRQ_TYPE_LEVEL_LOW;
 
-	desc = &irq_desc[irq];
-
 	mode = eic_readl(eic, MODE);
 	edge = eic_readl(eic, EDGE);
 	level = eic_readl(eic, LEVEL);
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index 09a274c..7e31607 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -249,24 +249,27 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 
 /* GPIO IRQ support */
 
-static void gpio_irq_mask(unsigned irq)
+static void gpio_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned		gpio = irq_to_gpio(irq);
 	struct pio_device	*pio = &pio_dev[gpio >> 5];
 
 	pio_writel(pio, IDR, 1 << (gpio & 0x1f));
 }
 
-static void gpio_irq_unmask(unsigned irq)
+static void gpio_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned		gpio = irq_to_gpio(irq);
 	struct pio_device	*pio = &pio_dev[gpio >> 5];
 
 	pio_writel(pio, IER, 1 << (gpio & 0x1f));
 }
 
-static int gpio_irq_type(unsigned irq, unsigned type)
+static int gpio_irq_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq = desc->irq;
 	if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE)
 		return -EINVAL;
 
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h
index e6485c3..912d974 100644
--- a/arch/blackfin/include/asm/bfin-global.h
+++ b/arch/blackfin/include/asm/bfin-global.h
@@ -51,7 +51,7 @@ extern void program_IAR(void);
 extern asmlinkage void lower_to_irq14(void);
 extern asmlinkage void bfin_return_from_exception(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
+extern int bfin_internal_set_wake(struct irq_desc *desc, unsigned int state);
 
 extern void *l1_data_A_sram_alloc(size_t);
 extern void *l1_data_B_sram_alloc(size_t);
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index d3b4044..4009554 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -115,9 +115,9 @@ void __ipipe_enable_irqdesc(struct ipipe_domain *ipd,
 void __ipipe_disable_irqdesc(struct ipipe_domain *ipd,
 			     unsigned irq);
 
-#define __ipipe_enable_irq(irq)		(irq_desc[irq].chip->unmask(irq))
+#define __ipipe_enable_irq(irq)		(irq_desc[irq].chip->unmask(irq_to_desc(irq)))
 
-#define __ipipe_disable_irq(irq)	(irq_desc[irq].chip->mask(irq))
+#define __ipipe_disable_irq(irq)	(irq_desc[irq].chip->mask(irq_to_desc(irq)))
 
 static inline int __ipipe_check_tickdev(const char *devname)
 {
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 7ad8878..9de18e4 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -121,20 +121,22 @@ static void __init search_IAR(void)
  * This is for core internal IRQs
  */
 
-static void bfin_ack_noop(unsigned int irq)
+static void bfin_ack_noop(struct irq_desc *desc)
 {
 	/* Dummy function.  */
 }
 
-static void bfin_core_mask_irq(unsigned int irq)
+static void bfin_core_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bfin_irq_flags &= ~(1 << irq);
 	if (!irqs_disabled_hw())
 		local_irq_enable_hw();
 }
 
-static void bfin_core_unmask_irq(unsigned int irq)
+static void bfin_core_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bfin_irq_flags |= 1 << irq;
 	/*
 	 * If interrupts are enabled, IMASK must contain the same value
@@ -150,8 +152,9 @@ static void bfin_core_unmask_irq(unsigned int irq)
 	return;
 }
 
-static void bfin_internal_mask_irq(unsigned int irq)
+static void bfin_internal_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 #ifdef CONFIG_BF53x
@@ -174,12 +177,13 @@ static void bfin_internal_mask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void bfin_internal_unmask_irq_affinity(unsigned int irq,
+static void bfin_internal_unmask_irq_affinity(struct irq_desc *desc,
 		const struct cpumask *affinity)
 #else
-static void bfin_internal_unmask_irq(unsigned int irq)
+static void bfin_internal_unmask_irq(struct irq_desc *desc)
 #endif
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 
 #ifdef CONFIG_BF53x
@@ -208,24 +212,24 @@ static void bfin_internal_unmask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void bfin_internal_unmask_irq(unsigned int irq)
+static void bfin_internal_unmask_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
-	bfin_internal_unmask_irq_affinity(irq, desc->affinity);
+	bfin_internal_unmask_irq_affinity(desc, desc->affinity);
 }
 
-static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bfin_internal_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
-	bfin_internal_mask_irq(irq);
-	bfin_internal_unmask_irq_affinity(irq, mask);
+	bfin_internal_mask_irq(desc);
+	bfin_internal_unmask_irq_affinity(desc, mask);
 
 	return 0;
 }
 #endif
 
 #ifdef CONFIG_PM
-int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+int bfin_internal_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	u32 bank, bit, wakeup = 0;
 	unsigned long flags;
 	bank = SIC_SYSIRQ(irq) / 32;
@@ -317,16 +321,18 @@ static void bfin_handle_irq(unsigned irq)
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
 static int error_int_mask;
 
-static void bfin_generic_error_mask_irq(unsigned int irq)
+static void bfin_generic_error_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
 	if (!error_int_mask)
-		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
+		bfin_internal_mask_irq(irq_to_desc(IRQ_GENERIC_ERROR));
 }
 
-static void bfin_generic_error_unmask_irq(unsigned int irq)
+static void bfin_generic_error_unmask_irq(struct irq_desc *desc)
 {
-	bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
+	unsigned int irq = desc->irq;
+	bfin_internal_unmask_irq(irq_to_desc(IRQ_GENERIC_ERROR));
 	error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
 }
 
@@ -548,17 +554,18 @@ extern void bfin_gpio_irq_prepare(unsigned gpio);
 
 #if !defined(CONFIG_BF54x)
 
-static void bfin_gpio_ack_irq(unsigned int irq)
+static void bfin_gpio_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* AFAIK ack_irq in case mask_ack is provided
 	 * get's only called for edge sense irqs
 	 */
 	set_gpio_data(irq_to_gpio(irq), 0);
 }
 
-static void bfin_gpio_mask_ack_irq(unsigned int irq)
+static void bfin_gpio_mask_ack_irq(stuct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	if (desc->handle_irq == handle_edge_irq)
@@ -567,30 +574,34 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
 	set_gpio_maska(gpionr, 0);
 }
 
-static void bfin_gpio_mask_irq(unsigned int irq)
+static void bfin_gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_gpio_maska(irq_to_gpio(irq), 0);
 }
 
-static void bfin_gpio_unmask_irq(unsigned int irq)
+static void bfin_gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_gpio_maska(irq_to_gpio(irq), 1);
 }
 
-static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+static unsigned int bfin_gpio_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	if (__test_and_set_bit(gpionr, gpio_enabled))
 		bfin_gpio_irq_prepare(gpionr);
 
-	bfin_gpio_unmask_irq(irq);
+	bfin_gpio_unmask_irq(desc);
 
 	return 0;
 }
 
-static void bfin_gpio_irq_shutdown(unsigned int irq)
+static void bfin_gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
 	bfin_gpio_mask_irq(irq);
@@ -598,8 +609,9 @@ static void bfin_gpio_irq_shutdown(unsigned int irq)
 	bfin_gpio_irq_free(gpionr);
 }
 
-static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+static int bfin_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int ret;
 	char buf[16];
 	u32 gpionr = irq_to_gpio(irq);
@@ -660,8 +672,9 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
 }
 
 #ifdef CONFIG_PM
-int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+int bfin_gpio_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	unsigned gpio = irq_to_gpio(irq);
 
 	if (state)
@@ -821,9 +834,9 @@ void init_pint_lut(void)
 	}
 }
 
-static void bfin_gpio_ack_irq(unsigned int irq)
+static void bfin_gpio_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -838,9 +851,9 @@ static void bfin_gpio_ack_irq(unsigned int irq)
 
 }
 
-static void bfin_gpio_mask_ack_irq(unsigned int irq)
+static void bfin_gpio_mask_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -856,15 +869,17 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
 	pint[bank]->mask_clear = pintbit;
 }
 
-static void bfin_gpio_mask_irq(unsigned int irq)
+static void bfin_gpio_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 
 	pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
 }
 
-static void bfin_gpio_unmask_irq(unsigned int irq)
+static void bfin_gpio_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 pintbit = PINT_BIT(pint_val);
 	u32 bank = PINT_2_BANK(pint_val);
@@ -873,8 +888,9 @@ static void bfin_gpio_unmask_irq(unsigned int irq)
 	pint[bank]->mask_set = pintbit;
 }
 
-static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+static unsigned int bfin_gpio_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 
@@ -888,22 +904,24 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
 	if (__test_and_set_bit(gpionr, gpio_enabled))
 		bfin_gpio_irq_prepare(gpionr);
 
-	bfin_gpio_unmask_irq(irq);
+	bfin_gpio_unmask_irq(desc);
 
 	return 0;
 }
 
-static void bfin_gpio_irq_shutdown(unsigned int irq)
+static void bfin_gpio_irq_shutdown(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 gpionr = irq_to_gpio(irq);
 
-	bfin_gpio_mask_irq(irq);
+	bfin_gpio_mask_irq(desc);
 	__clear_bit(gpionr, gpio_enabled);
 	bfin_gpio_irq_free(gpionr);
 }
 
-static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+static int bfin_gpio_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	int ret;
 	char buf[16];
 	u32 gpionr = irq_to_gpio(irq);
@@ -965,8 +983,9 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
 u32 pint_saved_masks[NR_PINT_SYS_IRQS];
 u32 pint_wakeup_masks[NR_PINT_SYS_IRQS];
 
-int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+int bfin_gpio_set_wake(struct irq_desc *desc, unsigned int state)
 {
+	unsigned int irq = desc->irq;
 	u32 pint_irq;
 	u32 pint_val = irq2pint_lut[irq - SYS_IRQS];
 	u32 bank = PINT_2_BANK(pint_val);
@@ -989,7 +1008,7 @@ int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
 		return -EINVAL;
 	}
 
-	bfin_internal_set_wake(pint_irq, state);
+	bfin_internal_set_wake(irq_to_desc(pint_irq), state);
 
 	if (state)
 		pint_wakeup_masks[bank] |= pintbit;
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 1a61efc..46a746e 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -104,31 +104,33 @@ static void (*interrupt[NR_IRQS])(void) = {
 	IRQ31_interrupt
 };
 
-static void enable_crisv10_irq(unsigned int irq);
+static void enable_crisv10_irq(struct irq_desc *desc);
 
-static unsigned int startup_crisv10_irq(unsigned int irq)
+static unsigned int startup_crisv10_irq(struct irq_desc *desc)
 {
-	enable_crisv10_irq(irq);
+	enable_crisv10_irq(desc);
 	return 0;
 }
 
 #define shutdown_crisv10_irq	disable_crisv10_irq
 
-static void enable_crisv10_irq(unsigned int irq)
+static void enable_crisv10_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unmask_irq(irq);
 }
 
-static void disable_crisv10_irq(unsigned int irq)
+static void disable_crisv10_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	mask_irq(irq);
 }
 
-static void ack_crisv10_irq(unsigned int irq)
+static void ack_crisv10_irq(struct irq_desc *desc)
 {
 }
 
-static void end_crisv10_irq(unsigned int irq)
+static void end_crisv10_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 4dd9ada..cc0bf81 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -36,8 +36,9 @@
 /*
  * on-motherboard FPGA PIC operations
  */
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -45,13 +46,15 @@ static void frv_fpga_mask(unsigned int irq)
 	__set_IMR(imr);
 }
 
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -60,8 +63,9 @@ static void frv_fpga_mask_ack(unsigned int irq)
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr &= ~(1 << (irq - IRQ_BASE_FPGA));
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index e452090..db30494 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -35,21 +35,24 @@
 /*
  * off-CPU FPGA PIC operations
  */
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
 	__set_IMR(imr);
 }
 
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr |= 1 << (irq - IRQ_BASE_FPGA);
@@ -58,8 +61,9 @@ static void frv_fpga_mask_ack(unsigned int irq)
 	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
 }
 
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint16_t imr = __get_IMR();
 
 	imr &= ~(1 << (irq - IRQ_BASE_FPGA));
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index ba55ecd..85c4a08 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -45,8 +45,9 @@
  * daughter board PIC operations
  * - there is no way to ACK interrupts in the MB93493 chip
  */
-static void frv_mb93493_mask(unsigned int irq)
+static void frv_mb93493_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint32_t iqsr;
 	volatile void *piqsr;
 
@@ -60,12 +61,13 @@ static void frv_mb93493_mask(unsigned int irq)
 	writel(iqsr, piqsr);
 }
 
-static void frv_mb93493_ack(unsigned int irq)
+static void frv_mb93493_ack(struct irq_desc *desc)
 {
 }
 
-static void frv_mb93493_unmask(unsigned int irq)
+static void frv_mb93493_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	uint32_t iqsr;
 	volatile void *piqsr;
 
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 62d1aba..72c9a73 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -96,32 +96,37 @@ int show_interrupts(struct seq_file *p, void *v)
 /*
  * on-CPU PIC operations
  */
-static void frv_cpupic_ack(unsigned int irqlevel)
+static void frv_cpupic_ack(struct irq_desc *desc)
 {
-	__clr_RC(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_RC(irq);
 	__clr_IRL();
 }
 
-static void frv_cpupic_mask(unsigned int irqlevel)
+static void frv_cpupic_mask(struct irq_desc *desc)
 {
-	__set_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__set_MASK(irq);
 }
 
-static void frv_cpupic_mask_ack(unsigned int irqlevel)
+static void frv_cpupic_mask_ack(struct irq_desc *desc)
 {
-	__set_MASK(irqlevel);
-	__clr_RC(irqlevel);
+	unsigned int irq = desc->irq;
+	__set_MASK(irq);
+	__clr_RC(irq);
 	__clr_IRL();
 }
 
-static void frv_cpupic_unmask(unsigned int irqlevel)
+static void frv_cpupic_unmask(struct irq_desc *desc)
 {
-	__clr_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_MASK(irq);
 }
 
-static void frv_cpupic_end(unsigned int irqlevel)
+static void frv_cpupic_end(struct irq_desc *desc)
 {
-	__clr_MASK(irqlevel);
+	unsigned int irq = desc->irq;
+	__clr_MASK(irq);
 }
 
 static struct irq_chip frv_cpu_pic = {
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index c25dc2c..4132b2f 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -38,32 +38,36 @@ static inline int is_ext_irq(unsigned int irq)
 	return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS));
 }
 
-static void h8300_enable_irq(unsigned int irq)
+static void h8300_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		IER_REGS |= 1 << (irq - EXT_IRQ0);
 }
 
-static void h8300_disable_irq(unsigned int irq)
+static void h8300_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		IER_REGS &= ~(1 << (irq - EXT_IRQ0));
 }
 
-static void h8300_end_irq(unsigned int irq)
+static void h8300_end_irq(struct irq_desc *desc)
 {
 }
 
-static unsigned int h8300_startup_irq(unsigned int irq)
+static unsigned int h8300_startup_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		return h8300_enable_irq_pin(irq);
 	else
 		return 0;
 }
 
-static void h8300_shutdown_irq(unsigned int irq)
+static void h8300_shutdown_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (is_ext_irq(irq))
 		h8300_disable_irq_pin(irq);
 }
diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c
index 922fdfd..d4eaf98 100644
--- a/arch/m32r/platforms/m32104ut/setup.c
+++ b/arch/m32r/platforms/m32104ut/setup.c
@@ -21,8 +21,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_m32104ut_irq(unsigned int irq)
+static void disable_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -30,8 +31,9 @@ static void disable_m32104ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_m32104ut_irq(unsigned int irq)
+static void enable_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -39,24 +41,25 @@ static void enable_m32104ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_m32104ut(unsigned int irq)
+static void mask_and_ack_m32104ut(struct irq_desc *desc)
 {
-	disable_m32104ut_irq(irq);
+	disable_m32104ut_irq(desc);
 }
 
 static void end_m32104ut_irq(unsigned int irq)
 {
-	enable_m32104ut_irq(irq);
+	enable_m32104ut_irq(desc);
 }
 
-static unsigned int startup_m32104ut_irq(unsigned int irq)
+static unsigned int startup_m32104ut_irq(struct irq_desc *desc)
 {
-	enable_m32104ut_irq(irq);
+	enable_m32104ut_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32104ut_irq(unsigned int irq)
+static void shutdown_m32104ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/m32700ut/setup.c b/arch/m32r/platforms/m32700ut/setup.c
index 9c1bc74..30dc152 100644
--- a/arch/m32r/platforms/m32700ut/setup.c
+++ b/arch/m32r/platforms/m32700ut/setup.c
@@ -27,8 +27,9 @@
 
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
-static void disable_m32700ut_irq(unsigned int irq)
+static void disable_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -36,8 +37,9 @@ static void disable_m32700ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_m32700ut_irq(unsigned int irq)
+static void enable_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -45,24 +47,25 @@ static void enable_m32700ut_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_m32700ut(unsigned int irq)
+static void mask_and_ack_m32700ut(struct irq_desc *desc)
 {
-	disable_m32700ut_irq(irq);
+	disable_m32700ut_irq(desc);
 }
 
-static void end_m32700ut_irq(unsigned int irq)
+static void end_m32700ut_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_irq(irq);
+	enable_m32700ut_irq(desc);
 }
 
-static unsigned int startup_m32700ut_irq(unsigned int irq)
+static unsigned int startup_m32700ut_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_irq(irq);
+	enable_m32700ut_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_irq(unsigned int irq)
+static void shutdown_m32700ut_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -93,8 +96,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[M32700UT_NUM_PLD_IRQ];
 
-static void disable_m32700ut_pld_irq(unsigned int irq)
+static void disable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -105,8 +109,9 @@ static void disable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_pld_irq(unsigned int irq)
+static void enable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -117,26 +122,27 @@ static void enable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_pld(unsigned int irq)
+static void mask_and_ack_m32700ut_pld(struct irq_desc *desc)
 {
-	disable_m32700ut_pld_irq(irq);
+	disable_m32700ut_pld_irq(desc);
 //	mask_and_ack_m32700ut(M32R_IRQ_INT1);
 }
 
-static void end_m32700ut_pld_irq(unsigned int irq)
+static void end_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT1);
+	enable_m32700ut_pld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
-static unsigned int startup_m32700ut_pld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
+	enable_m32700ut_pld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_pld_irq(unsigned int irq)
+static void shutdown_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -166,8 +172,9 @@ static struct irq_chip m32700ut_pld_irq_type =
 
 static pld_icu_data_t lanpld_icu_data[M32700UT_NUM_LAN_PLD_IRQ];
 
-static void disable_m32700ut_lanpld_irq(unsigned int irq)
+static void disable_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -177,8 +184,9 @@ static void disable_m32700ut_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_lanpld_irq(unsigned int irq)
+static void enable_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -188,29 +196,30 @@ static void enable_m32700ut_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_lanpld(unsigned int irq)
+static void mask_and_ack_m32700ut_lanpld(struct irq_desc *desc)
 {
-	disable_m32700ut_lanpld_irq(irq);
+	disable_m32700ut_lanpld_irq(desc);
 }
 
-static void end_m32700ut_lanpld_irq(unsigned int irq)
+static void end_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lanpld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT0);
+	enable_m32700ut_lanpld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT0));
 }
 
-static unsigned int startup_m32700ut_lanpld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lanpld_irq(irq);
+	enable_m32700ut_lanpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_lanpld_irq(unsigned int irq)
+static void shutdown_m32700ut_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
-	pldirq = irq2lanpldirq(irq);
+	pldirq = irq2lanpldirq(desc);
 	port = lanpldirq2port(pldirq);
 	outw(PLD_ICUCR_ILEVEL7, port);
 }
@@ -235,8 +244,9 @@ static struct irq_chip m32700ut_lanpld_irq_type =
 
 static pld_icu_data_t lcdpld_icu_data[M32700UT_NUM_LCD_PLD_IRQ];
 
-static void disable_m32700ut_lcdpld_irq(unsigned int irq)
+static void disable_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -246,8 +256,9 @@ static void disable_m32700ut_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_lcdpld_irq(unsigned int irq)
+static void enable_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -257,25 +268,26 @@ static void enable_m32700ut_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_lcdpld(unsigned int irq)
+static void mask_and_ack_m32700ut_lcdpld(struct irq_desc *desc)
 {
-	disable_m32700ut_lcdpld_irq(irq);
+	disable_m32700ut_lcdpld_irq(desc);
 }
 
-static void end_m32700ut_lcdpld_irq(unsigned int irq)
+static void end_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lcdpld_irq(irq);
-	end_m32700ut_irq(M32R_IRQ_INT2);
+	enable_m32700ut_lcdpld_irq(desc);
+	end_m32700ut_irq(irq_to_desc(M32R_IRQ_INT2));
 }
 
-static unsigned int startup_m32700ut_lcdpld_irq(unsigned int irq)
+static unsigned int startup_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_lcdpld_irq(irq);
+	enable_m32700ut_lcdpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_m32700ut_lcdpld_irq(unsigned int irq)
+static void shutdown_m32700ut_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c
index fb4b177..5b29971 100644
--- a/arch/m32r/platforms/mappi/setup.c
+++ b/arch/m32r/platforms/mappi/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi_irq(unsigned int irq)
+static void disable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -29,8 +30,9 @@ static void disable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi_irq(unsigned int irq)
+static void enable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -38,25 +40,26 @@ static void enable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_mappi_irq(irq);
+	disable_mappi_irq(desc);
 }
 
-static void end_mappi_irq(unsigned int irq)
+static void end_mappi_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_mappi_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_mappi_irq(desc);
 }
 
-static unsigned int startup_mappi_irq(unsigned int irq)
+static unsigned int startup_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi_irq(unsigned int irq)
+static void shutdown_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c
index 6a65eda..e364894 100644
--- a/arch/m32r/platforms/mappi2/setup.c
+++ b/arch/m32r/platforms/mappi2/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi2_irq(unsigned int irq)
+static void disable_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -33,8 +34,9 @@ static void disable_mappi2_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi2_irq(unsigned int irq)
+static void enable_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -46,24 +48,25 @@ static void enable_mappi2_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi2(unsigned int irq)
+static void mask_and_ack_mappi2(struct irq_desc *desc)
 {
-	disable_mappi2_irq(irq);
+	disable_mappi2_irq(desc);
 }
 
-static void end_mappi2_irq(unsigned int irq)
+static void end_mappi2_irq(struct irq_desc *desc)
 {
-	enable_mappi2_irq(irq);
+	enable_mappi2_irq(desc);
 }
 
-static unsigned int startup_mappi2_irq(unsigned int irq)
+static unsigned int startup_mappi2_irq(struct irq_desc *desc)
 {
-	enable_mappi2_irq(irq);
+	enable_mappi2_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi2_irq(unsigned int irq)
+static void shutdown_mappi2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c
index 9c337ae..5152adf 100644
--- a/arch/m32r/platforms/mappi3/setup.c
+++ b/arch/m32r/platforms/mappi3/setup.c
@@ -20,8 +20,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_mappi3_irq(unsigned int irq)
+static void disable_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -33,8 +34,9 @@ static void disable_mappi3_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi3_irq(unsigned int irq)
+static void enable_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	if ((irq == 0) ||(irq >= NR_IRQS))  {
@@ -46,24 +48,25 @@ static void enable_mappi3_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi3(unsigned int irq)
+static void mask_and_ack_mappi3(struct irq_desc *desc)
 {
-	disable_mappi3_irq(irq);
+	disable_mappi3_irq(desc);
 }
 
-static void end_mappi3_irq(unsigned int irq)
+static void end_mappi3_irq(struct irq_desc *desc)
 {
-	enable_mappi3_irq(irq);
+	enable_mappi3_irq(desc);
 }
 
-static unsigned int startup_mappi3_irq(unsigned int irq)
+static unsigned int startup_mappi3_irq(struct irq_desc *desc)
 {
-	enable_mappi3_irq(irq);
+	enable_mappi3_irq(desc);
 	return (0);
 }
 
-static void shutdown_mappi3_irq(unsigned int irq)
+static void shutdown_mappi3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c
index ed86574..396beba 100644
--- a/arch/m32r/platforms/oaks32r/setup.c
+++ b/arch/m32r/platforms/oaks32r/setup.c
@@ -19,8 +19,9 @@
 
 icu_data_t icu_data[NR_IRQS];
 
-static void disable_oaks32r_irq(unsigned int irq)
+static void disable_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -28,8 +29,9 @@ static void disable_oaks32r_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_oaks32r_irq(unsigned int irq)
+static void enable_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,24 +39,25 @@ static void enable_oaks32r_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_oaks32r_irq(irq);
+	disable_oaks32r_irq(desc);
 }
 
-static void end_oaks32r_irq(unsigned int irq)
+static void end_oaks32r_irq(struct irq_desc *desc)
 {
-	enable_oaks32r_irq(irq);
+	enable_oaks32r_irq(desc);
 }
 
-static unsigned int startup_oaks32r_irq(unsigned int irq)
+static unsigned int startup_oaks32r_irq(struct irq_desc *desc)
 {
-	enable_oaks32r_irq(irq);
+	enable_oaks32r_irq(desc);
 	return (0);
 }
 
-static void shutdown_oaks32r_irq(unsigned int irq)
+static void shutdown_oaks32r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
diff --git a/arch/m32r/platforms/opsput/setup.c b/arch/m32r/platforms/opsput/setup.c
index 80d6806..1c9553b 100644
--- a/arch/m32r/platforms/opsput/setup.c
+++ b/arch/m32r/platforms/opsput/setup.c
@@ -28,8 +28,9 @@
 
 icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
 
-static void disable_opsput_irq(unsigned int irq)
+static void disable_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,8 +38,9 @@ static void disable_opsput_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_opsput_irq(unsigned int irq)
+static void enable_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -46,24 +48,25 @@ static void enable_opsput_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_opsput(unsigned int irq)
+static void mask_and_ack_opsput(struct irq_desc *desc)
 {
-	disable_opsput_irq(irq);
+	disable_opsput_irq(desc);
 }
 
-static void end_opsput_irq(unsigned int irq)
+static void end_opsput_irq(struct irq_desc *desc)
 {
-	enable_opsput_irq(irq);
+	enable_opsput_irq(desc);
 }
 
-static unsigned int startup_opsput_irq(unsigned int irq)
+static unsigned int startup_opsput_irq(struct irq_desc *desc)
 {
-	enable_opsput_irq(irq);
+	enable_opsput_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_irq(unsigned int irq)
+static void shutdown_opsput_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -94,8 +97,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[OPSPUT_NUM_PLD_IRQ];
 
-static void disable_opsput_pld_irq(unsigned int irq)
+static void disable_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -106,8 +110,9 @@ static void disable_opsput_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_pld_irq(unsigned int irq)
+static void enable_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -118,26 +123,27 @@ static void enable_opsput_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_pld(unsigned int irq)
+static void mask_and_ack_opsput_pld(struct irq_desc *desc)
 {
-	disable_opsput_pld_irq(irq);
+	disable_opsput_pld_irq(desc);
 //	mask_and_ack_opsput(M32R_IRQ_INT1);
 }
 
-static void end_opsput_pld_irq(unsigned int irq)
+static void end_opsput_pld_irq(struct irq_desc *desc)
 {
-	enable_opsput_pld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT1);
+	enable_opsput_pld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
-static unsigned int startup_opsput_pld_irq(unsigned int irq)
+static unsigned int startup_opsput_pld_irq(struct irq_desc *desc)
 {
-	enable_opsput_pld_irq(irq);
+	enable_opsput_pld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_pld_irq(unsigned int irq)
+static void shutdown_opsput_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -167,8 +173,9 @@ static struct irq_chip opsput_pld_irq_type =
 
 static pld_icu_data_t lanpld_icu_data[OPSPUT_NUM_LAN_PLD_IRQ];
 
-static void disable_opsput_lanpld_irq(unsigned int irq)
+static void disable_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -178,8 +185,9 @@ static void disable_opsput_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_lanpld_irq(unsigned int irq)
+static void enable_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -189,25 +197,26 @@ static void enable_opsput_lanpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_lanpld(unsigned int irq)
+static void mask_and_ack_opsput_lanpld(struct irq_desc *desc)
 {
-	disable_opsput_lanpld_irq(irq);
+	disable_opsput_lanpld_irq(desc);
 }
 
-static void end_opsput_lanpld_irq(unsigned int irq)
+static void end_opsput_lanpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lanpld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT0);
+	enable_opsput_lanpld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT0));
 }
 
-static unsigned int startup_opsput_lanpld_irq(unsigned int irq)
+static unsigned int startup_opsput_lanpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lanpld_irq(irq);
+	enable_opsput_lanpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_lanpld_irq(unsigned int irq)
+static void shutdown_opsput_lanpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -236,8 +245,9 @@ static struct irq_chip opsput_lanpld_irq_type =
 
 static pld_icu_data_t lcdpld_icu_data[OPSPUT_NUM_LCD_PLD_IRQ];
 
-static void disable_opsput_lcdpld_irq(unsigned int irq)
+static void disable_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -247,8 +257,9 @@ static void disable_opsput_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_opsput_lcdpld_irq(unsigned int irq)
+static void enable_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -258,25 +269,26 @@ static void enable_opsput_lcdpld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_opsput_lcdpld(unsigned int irq)
+static void mask_and_ack_opsput_lcdpld(struct irq_desc *desc)
 {
-	disable_opsput_lcdpld_irq(irq);
+	disable_opsput_lcdpld_irq(desc);
 }
 
-static void end_opsput_lcdpld_irq(unsigned int irq)
+static void end_opsput_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lcdpld_irq(irq);
-	end_opsput_irq(M32R_IRQ_INT2);
+	enable_opsput_lcdpld_irq(desc);
+	end_opsput_irq(irq_to_desc(M32R_IRQ_INT2));
 }
 
-static unsigned int startup_opsput_lcdpld_irq(unsigned int irq)
+static unsigned int startup_opsput_lcdpld_irq(struct irq_desc *desc)
 {
-	enable_opsput_lcdpld_irq(irq);
+	enable_opsput_lcdpld_irq(desc);
 	return (0);
 }
 
-static void shutdown_opsput_lcdpld_irq(unsigned int irq)
+static void shutdown_opsput_lcdpld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
@@ -305,7 +317,7 @@ void __init init_IRQ(void)
 	irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0;
 	irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1;	/* disable nested irq */
 	lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* "H" edge sense */
-	disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN);
+	disable_opsput_lanpld_irq(irq_to_desc(OPSPUT_LAN_IRQ_LAN));
 #endif  /* CONFIG_SMC91X */
 
 	/* MFT2 : system timer */
@@ -314,7 +326,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_MFT2].action = 0;
 	irq_desc[M32R_IRQ_MFT2].depth = 1;
 	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
-	disable_opsput_irq(M32R_IRQ_MFT2);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_MFT2));
 
 	/* SIO0 : receive */
 	irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
@@ -322,7 +334,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO0_R].action = 0;
 	irq_desc[M32R_IRQ_SIO0_R].depth = 1;
 	icu_data[M32R_IRQ_SIO0_R].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO0_R);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO0_R));
 
 	/* SIO0 : send */
 	irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
@@ -330,7 +342,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO0_S].action = 0;
 	irq_desc[M32R_IRQ_SIO0_S].depth = 1;
 	icu_data[M32R_IRQ_SIO0_S].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO0_S);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO0_S));
 
 	/* SIO1 : receive */
 	irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED;
@@ -338,7 +350,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO1_R].action = 0;
 	irq_desc[M32R_IRQ_SIO1_R].depth = 1;
 	icu_data[M32R_IRQ_SIO1_R].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO1_R);
+	disable_opsput_irq(irq_desc(M32R_IRQ_SIO1_R));
 
 	/* SIO1 : send */
 	irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED;
@@ -346,7 +358,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_SIO1_S].action = 0;
 	irq_desc[M32R_IRQ_SIO1_S].depth = 1;
 	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_SIO1_S);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_SIO1_S));
 
 	/* DMA1 : */
 	irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED;
@@ -354,7 +366,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_DMA1].action = 0;
 	irq_desc[M32R_IRQ_DMA1].depth = 1;
 	icu_data[M32R_IRQ_DMA1].icucr = 0;
-	disable_opsput_irq(M32R_IRQ_DMA1);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_DMA1));
 
 #ifdef CONFIG_SERIAL_M32R_PLDSIO
 	/* INT#1: SIO0 Receive on PLD */
@@ -363,7 +375,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_SIO0_RCV].action = 0;
 	irq_desc[PLD_IRQ_SIO0_RCV].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
-	disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_SIO0_RCV));
 
 	/* INT#1: SIO0 Send on PLD */
 	irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED;
@@ -371,7 +383,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_SIO0_SND].action = 0;
 	irq_desc[PLD_IRQ_SIO0_SND].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
-	disable_opsput_pld_irq(PLD_IRQ_SIO0_SND);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_SIO0_SND));
 #endif  /* CONFIG_SERIAL_M32R_PLDSIO */
 
 	/* INT#1: CFC IREQ on PLD */
@@ -380,7 +392,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFIREQ].action = 0;
 	irq_desc[PLD_IRQ_CFIREQ].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* 'L' level sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFIREQ);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFIREQ));
 
 	/* INT#1: CFC Insert on PLD */
 	irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
@@ -388,7 +400,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
 	irq_desc[PLD_IRQ_CFC_INSERT].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00;	/* 'L' edge sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFC_INSERT));
 
 	/* INT#1: CFC Eject on PLD */
 	irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
@@ -396,21 +408,21 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
 	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
 	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* 'H' edge sense */
-	disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT);
+	disable_opsput_pld_irq(irq_to_desc(PLD_IRQ_CFC_EJECT));
 
 	/*
 	 * INT0# is used for LAN, DIO
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
-	enable_opsput_irq(M32R_IRQ_INT0);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT0));
 
 	/*
 	 * INT1# is used for UART, MMC, CF Controller in FPGA.
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
-	enable_opsput_irq(M32R_IRQ_INT1);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT1));
 
 #if defined(CONFIG_USB)
 	outw(USBCR_OTGS, USBCR); 	/* USBCR: non-OTG */
@@ -420,14 +432,14 @@ void __init init_IRQ(void)
     irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0;
     irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1;
     lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* "L" level sense */
-    disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1);
+    disable_opsput_lcdpld_irq(irq_to_desc(OPSPUT_LCD_IRQ_USB_INT1));
 #endif
 	/*
 	 * INT2# is used for BAT, USB, AUDIO
 	 * We enable it here.
 	 */
 	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
-	enable_opsput_irq(M32R_IRQ_INT2);
+	enable_opsput_irq(irq_to_desc(M32R_IRQ_INT2));
 
 #if defined(CONFIG_VIDEO_M32R_AR)
 	/*
@@ -438,7 +450,7 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_INT3].action = 0;
 	irq_desc[M32R_IRQ_INT3].depth = 1;
 	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
-	disable_opsput_irq(M32R_IRQ_INT3);
+	disable_opsput_irq(irq_to_desc(M32R_IRQ_INT3));
 #endif /* CONFIG_VIDEO_M32R_AR */
 }
 
diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c
index 7573026..fca1e00 100644
--- a/arch/m32r/platforms/usrv/setup.c
+++ b/arch/m32r/platforms/usrv/setup.c
@@ -19,8 +19,9 @@
 
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
-static void disable_mappi_irq(unsigned int irq)
+static void disable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -28,8 +29,9 @@ static void disable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void enable_mappi_irq(unsigned int irq)
+static void enable_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 
 	port = irq2port(irq);
@@ -37,24 +39,25 @@ static void enable_mappi_irq(unsigned int irq)
 	outl(data, port);
 }
 
-static void mask_and_ack_mappi(unsigned int irq)
+static void mask_and_ack_mappi(struct irq_desc *desc)
 {
-	disable_mappi_irq(irq);
+	disable_mappi_irq(desc);
 }
 
-static void end_mappi_irq(unsigned int irq)
+static void end_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 }
 
-static unsigned int startup_mappi_irq(unsigned int irq)
+static unsigned int startup_mappi_irq(struct irq_desc *desc)
 {
-	enable_mappi_irq(irq);
+	enable_mappi_irq(desc);
 	return 0;
 }
 
-static void shutdown_mappi_irq(unsigned int irq)
+static void shutdown_mappi_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 
 	port = irq2port(irq);
@@ -85,8 +88,9 @@ typedef struct {
 
 static pld_icu_data_t pld_icu_data[M32700UT_NUM_PLD_IRQ];
 
-static void disable_m32700ut_pld_irq(unsigned int irq)
+static void disable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -96,8 +100,9 @@ static void disable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void enable_m32700ut_pld_irq(unsigned int irq)
+static void enable_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port, data;
 	unsigned int pldirq;
 
@@ -107,25 +112,26 @@ static void enable_m32700ut_pld_irq(unsigned int irq)
 	outw(data, port);
 }
 
-static void mask_and_ack_m32700ut_pld(unsigned int irq)
+static void mask_and_ack_m32700ut_pld(struct irq_desc *desc)
 {
-	disable_m32700ut_pld_irq(irq);
+	disable_m32700ut_pld_irq(desc);
 }
 
-static void end_m32700ut_pld_irq(unsigned int irq)
+static void end_m32700ut_pld_irq(struct irq_desc *desc)
 {
-	enable_m32700ut_pld_irq(irq);
-	end_mappi_irq(M32R_IRQ_INT1);
+	enable_m32700ut_pld_irq(desc);
+	end_mappi_irq(irq_to_desc(M32R_IRQ_INT1));
 }
 
 static unsigned int startup_m32700ut_pld_irq(unsigned int irq)
 {
-	enable_m32700ut_pld_irq(irq);
+	enable_m32700ut_pld_irq(desc);
 	return 0;
 }
 
-static void shutdown_m32700ut_pld_irq(unsigned int irq)
+static void shutdown_m32700ut_pld_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long port;
 	unsigned int pldirq;
 
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c
index d09d9da..f23483f 100644
--- a/arch/m68knommu/platform/5249/intc2.c
+++ b/arch/m68knommu/platform/5249/intc2.c
@@ -17,24 +17,27 @@
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 
-static void intc2_irq_gpio_mask(unsigned int irq)
+static void intc2_irq_gpio_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 imr;
 	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 	imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0));
 	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 }
 
-static void intc2_irq_gpio_unmask(unsigned int irq)
+static void intc2_irq_gpio_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 imr;
 	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 	imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0));
 	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
 }
 
-static void intc2_irq_gpio_ack(unsigned int irq)
+static void intc2_irq_gpio_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
 }
 
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
index 7081e0a..0bfea67 100644
--- a/arch/m68knommu/platform/5272/intc.c
+++ b/arch/m68knommu/platform/5272/intc.c
@@ -68,8 +68,9 @@ static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
 	/*MCF_IRQ_SWTO*/	{ .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
 };
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		u32 v;
 		irq -= MCFINT_VECBASE;
@@ -78,8 +79,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		u32 v;
 		irq -= MCFINT_VECBASE;
@@ -88,8 +90,9 @@ static void intc_irq_unmask(unsigned int irq)
 	}
 }
 
-static void intc_irq_ack(unsigned int irq)
+static void intc_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* Only external interrupts are acked */
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
 		irq -= MCFINT_VECBASE;
@@ -101,7 +104,7 @@ static void intc_irq_ack(unsigned int irq)
 	}
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
 	/* We can set the edge type here for external interrupts */
 	return 0;
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index b91ee85..80421cc 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -135,13 +135,15 @@ void process_int(int vec, struct pt_regs *fp)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IMR &= ~(1<<irq);
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	IMR |= (1<<irq);
 }
 
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index 1143f77..e99877b 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -37,18 +37,21 @@ extern void *_ramvec[];
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cimr |= (1 << irq);
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cimr &= ~(1 << irq);
 }
 
-static void intc_irq_ack(unsigned int irq)
+static void intc_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pquicc->intr_cisr = (1 << irq);
 }
 
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
index 5598c8b..598905c 100644
--- a/arch/m68knommu/platform/coldfire/intc-2.c
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -25,8 +25,9 @@
  */
 static u8 intc_intpri = 0x36;
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
 		unsigned long imraddr;
 		u32 val, imrbit;
@@ -42,8 +43,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
 		unsigned long intaddr, imraddr, icraddr;
 		u32 val, imrbit;
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
index 1b01e79..f52e94a 100644
--- a/arch/m68knommu/platform/coldfire/intc-simr.c
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -18,8 +18,9 @@
 #include <asm/mcfsim.h>
 #include <asm/traps.h>
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
@@ -28,8 +29,9 @@ static void intc_irq_mask(unsigned int irq)
 	}
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
@@ -38,8 +40,9 @@ static void intc_irq_unmask(unsigned int irq)
 	}
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	if (irq >= MCFINT_VECBASE) {
 		if (irq < MCFINT_VECBASE + 64)
 			__raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index a4560c8..04bf7d5 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -111,19 +111,21 @@ void mcf_autovector(int irq)
 #endif
 }
 
-static void intc_irq_mask(unsigned int irq)
+static void intc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (mcf_irq2imr[irq])
 		mcf_setimr(mcf_irq2imr[irq]);
 }
 
-static void intc_irq_unmask(unsigned int irq)
+static void intc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (mcf_irq2imr[irq])
 		mcf_clrimr(mcf_irq2imr[irq]);
 }
 
-static int intc_irq_set_type(unsigned int irq, unsigned int type)
+static int intc_irq_set_type(struct irq_desc *desc, unsigned int type)
 {
 	return 0;
 }
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1..009d2f6 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -40,8 +40,9 @@ unsigned int nr_irq;
 #define MER_ME (1<<0)
 #define MER_HIE (1<<1)
 
-static void intc_enable_or_unmask(unsigned int irq)
+static void intc_enable_or_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("enable_or_unmask: %d\n", irq);
 	out_be32(INTC_BASE + SIE, mask);
@@ -54,28 +55,32 @@ static void intc_enable_or_unmask(unsigned int irq)
 		out_be32(INTC_BASE + IAR, mask);
 }
 
-static void intc_disable_or_mask(unsigned int irq)
+static void intc_disable_or_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("disable: %d\n", irq);
 	out_be32(INTC_BASE + CIE, 1 << irq);
 }
 
-static void intc_ack(unsigned int irq)
+static void intc_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("ack: %d\n", irq);
 	out_be32(INTC_BASE + IAR, 1 << irq);
 }
 
-static void intc_mask_ack(unsigned int irq)
+static void intc_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("disable_and_ack: %d\n", irq);
 	out_be32(INTC_BASE + CIE, mask);
 	out_be32(INTC_BASE + IAR, mask);
 }
 
-static void intc_end(unsigned int irq)
+static void intc_end(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = 1 << irq;
 	pr_debug("end: %d\n", irq);
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index b2821ac..4391efd 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -37,7 +37,7 @@
 #include <asm/mach-pb1x00/pb1000.h>
 #endif
 
-static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
+static int au1x_ic_settype(struct irq_desc *desc, unsigned int flow_type);
 
 /* NOTE on interrupt priorities: The original writers of this code said:
  *
@@ -300,17 +300,19 @@ void restore_au1xxx_intctl(void)
 #endif /* CONFIG_PM */
 
 
-static void au1x_ic0_unmask(unsigned int irq_nr)
+static void au1x_ic0_unmask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 	au_writel(1 << bit, IC0_MASKSET);
 	au_writel(1 << bit, IC0_WAKESET);
 	au_sync();
 }
 
-static void au1x_ic1_unmask(unsigned int irq_nr)
+static void au1x_ic1_unmask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 	au_writel(1 << bit, IC1_MASKSET);
 	au_writel(1 << bit, IC1_WAKESET);
 
@@ -324,25 +326,28 @@ static void au1x_ic1_unmask(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic0_mask(unsigned int irq_nr)
+static void au1x_ic0_mask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 	au_writel(1 << bit, IC0_MASKCLR);
 	au_writel(1 << bit, IC0_WAKECLR);
 	au_sync();
 }
 
-static void au1x_ic1_mask(unsigned int irq_nr)
+static void au1x_ic1_mask(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 	au_writel(1 << bit, IC1_MASKCLR);
 	au_writel(1 << bit, IC1_WAKECLR);
 	au_sync();
 }
 
-static void au1x_ic0_ack(unsigned int irq_nr)
+static void au1x_ic0_ack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 
 	/*
 	 * This may assume that we don't get interrupts from
@@ -353,9 +358,10 @@ static void au1x_ic0_ack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic1_ack(unsigned int irq_nr)
+static void au1x_ic1_ack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 
 	/*
 	 * This may assume that we don't get interrupts from
@@ -366,9 +372,10 @@ static void au1x_ic1_ack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic0_maskack(unsigned int irq_nr)
+static void au1x_ic0_maskack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC0_INT_BASE;
 
 	au_writel(1 << bit, IC0_WAKECLR);
 	au_writel(1 << bit, IC0_MASKCLR);
@@ -377,9 +384,10 @@ static void au1x_ic0_maskack(unsigned int irq_nr)
 	au_sync();
 }
 
-static void au1x_ic1_maskack(unsigned int irq_nr)
+static void au1x_ic1_maskack(struct irq_desc *desc)
 {
-	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	unsigned int irq = desc->irq;
+	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
 
 	au_writel(1 << bit, IC1_WAKECLR);
 	au_writel(1 << bit, IC1_MASKCLR);
@@ -388,8 +396,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr)
 	au_sync();
 }
 
-static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
+static int au1x_ic1_setwake(struct irq_desc *desc, unsigned int on)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - AU1000_INTC1_INT_BASE;
 	unsigned long wakemsk, flags;
 
@@ -435,8 +444,9 @@ static struct irq_chip au1x_ic1_chip = {
 	.set_wake	= au1x_ic1_setwake,
 };
 
-static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
+static int au1x_ic_settype(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	struct irq_chip *chip;
 	unsigned long icr[6];
 	unsigned int bit, ic;
@@ -586,11 +596,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 	 */
 	for (i = AU1000_INTC0_INT_BASE;
 	     (i < AU1000_INTC0_INT_BASE + 32); i++)
-		au1x_ic_settype(i, IRQ_TYPE_NONE);
+		au1x_ic_settype(irq_to_desc(i), IRQ_TYPE_NONE);
 
 	for (i = AU1000_INTC1_INT_BASE;
 	     (i < AU1000_INTC1_INT_BASE + 32); i++)
-		au1x_ic_settype(i, IRQ_TYPE_NONE);
+		au1x_ic_settype(irq_to_desc(i), IRQ_TYPE_NONE);
 
 	/*
 	 * Initialize IC0, which is fixed per processor.
@@ -608,7 +618,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 				au_writel(1 << bit, IC0_ASSIGNSET);
 		}
 
-		au1x_ic_settype(irq_nr, map->im_type);
+		au1x_ic_settype(irq_to_desc(irq_nr), map->im_type);
 		++map;
 	}
 
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 3bc4fd2..e801e8c 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -96,16 +96,18 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
  * CPLD generates tons of spurious interrupts (at least on my DB1200).
  *	-- mlau
  */
-static void bcsr_irq_mask(unsigned int irq_nr)
+static void bcsr_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
 	wmb();
 }
 
-static void bcsr_irq_maskack(unsigned int irq_nr)
+static void bcsr_irq_maskack(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
@@ -113,8 +115,9 @@ static void bcsr_irq_maskack(unsigned int irq_nr)
 	wmb();
 }
 
-static void bcsr_irq_unmask(unsigned int irq_nr)
+static void bcsr_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
 	__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
 	__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
index c781556..d65b855 100644
--- a/arch/mips/ar7/irq.c
+++ b/arch/mips/ar7/irq.c
@@ -48,36 +48,42 @@
 
 static int ar7_irq_base;
 
-static void ar7_unmask_irq(unsigned int irq)
+static void ar7_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(ESR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_mask_irq(unsigned int irq)
+static void ar7_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(ECR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_ack_irq(unsigned int irq)
+static void ar7_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << ((irq - ar7_irq_base) % 32),
 	       REG(CR_OFFSET(irq - ar7_irq_base)));
 }
 
-static void ar7_unmask_sec_irq(unsigned int irq)
+static void ar7_unmask_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
 }
 
-static void ar7_mask_sec_irq(unsigned int irq)
+static void ar7_mask_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
 }
 
-static void ar7_ack_sec_irq(unsigned int irq)
+static void ar7_ack_sec_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
 }
 
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index a0c5cd1..6e0b206 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -75,8 +75,9 @@ asmlinkage void plat_irq_dispatch(void)
  * internal IRQs operations: only mask/unmask on PERF irq mask
  * register.
  */
-static inline void bcm63xx_internal_irq_mask(unsigned int irq)
+static inline void bcm63xx_internal_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 
 	irq -= IRQ_INTERNAL_BASE;
@@ -85,8 +86,9 @@ static inline void bcm63xx_internal_irq_mask(unsigned int irq)
 	bcm_perf_writel(mask, PERF_IRQMASK_REG);
 }
 
-static void bcm63xx_internal_irq_unmask(unsigned int irq)
+static void bcm63xx_internal_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask;
 
 	irq -= IRQ_INTERNAL_BASE;
@@ -95,9 +97,9 @@ static void bcm63xx_internal_irq_unmask(unsigned int irq)
 	bcm_perf_writel(mask, PERF_IRQMASK_REG);
 }
 
-static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
+static unsigned int bcm63xx_internal_irq_startup(struct irq_desc *desc)
 {
-	bcm63xx_internal_irq_unmask(irq);
+	bcm63xx_internal_irq_unmask(desc);
 	return 0;
 }
 
@@ -105,8 +107,9 @@ static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
  * external IRQs operations: mask/unmask and clear on PERF external
  * irq control register.
  */
-static void bcm63xx_external_irq_mask(unsigned int irq)
+static void bcm63xx_external_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -115,8 +118,9 @@ static void bcm63xx_external_irq_mask(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static void bcm63xx_external_irq_unmask(unsigned int irq)
+static void bcm63xx_external_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -125,8 +129,9 @@ static void bcm63xx_external_irq_unmask(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static void bcm63xx_external_irq_clear(unsigned int irq)
+static void bcm63xx_external_irq_clear(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= IRQ_EXT_BASE;
@@ -135,26 +140,28 @@ static void bcm63xx_external_irq_clear(unsigned int irq)
 	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
 }
 
-static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
+static unsigned int bcm63xx_external_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 	irq_enable_hazard();
-	bcm63xx_external_irq_unmask(irq);
+	bcm63xx_external_irq_unmask(desc);
 	return 0;
 }
 
-static void bcm63xx_external_irq_shutdown(unsigned int irq)
+static void bcm63xx_external_irq_shutdown(struct irq_desc *desc)
 {
-	bcm63xx_external_irq_mask(irq);
+	unsigned int irq = desc->irq;
+	bcm63xx_external_irq_mask(desc);
 	clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 	irq_disable_hazard();
 }
 
-static int bcm63xx_external_irq_set_type(unsigned int irq,
+static int bcm63xx_external_irq_set_type(struct irq_desc *desc,
 					 unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
-	struct irq_desc *desc = irq_desc + irq;
 
 	irq -= IRQ_EXT_BASE;
 
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index c424cd1..e872477 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -25,8 +25,9 @@ static int octeon_coreid_for_cpu(int cpu)
 #endif
 }
 
-static void octeon_irq_core_ack(unsigned int irq)
+static void octeon_irq_core_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * We don't need to disable IRQs to make these atomic since
@@ -39,9 +40,9 @@ static void octeon_irq_core_ack(unsigned int irq)
 		clear_c0_cause(0x100 << bit);
 }
 
-static void octeon_irq_core_eoi(unsigned int irq)
+static void octeon_irq_core_eoi(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * If an IRQ is being processed while we are disabling it the
@@ -58,8 +59,9 @@ static void octeon_irq_core_eoi(unsigned int irq)
 	set_c0_status(0x100 << bit);
 }
 
-static void octeon_irq_core_enable(unsigned int irq)
+static void octeon_irq_core_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 
@@ -85,8 +87,9 @@ static void octeon_irq_core_disable_local(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-static void octeon_irq_core_disable(unsigned int irq)
+static void octeon_irq_core_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 #ifdef CONFIG_SMP
 	on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
 		    (void *) (long) irq, 1);
@@ -104,7 +107,7 @@ static struct irq_chip octeon_irq_chip_core = {
 };
 
 
-static void octeon_irq_ciu0_ack(unsigned int irq)
+static void octeon_irq_ciu0_ack(struct irq_desc *desc)
 {
 	/*
 	 * In order to avoid any locking accessing the CIU, we
@@ -120,7 +123,7 @@ static void octeon_irq_ciu0_ack(unsigned int irq)
 	clear_c0_status(0x100 << 2);
 }
 
-static void octeon_irq_ciu0_eoi(unsigned int irq)
+static void octeon_irq_ciu0_eoi(struct irq_desc *desc)
 {
 	/*
 	 * Enable all CIU interrupts again.  We don't need to disable
@@ -130,8 +133,9 @@ static void octeon_irq_ciu0_eoi(unsigned int irq)
 	set_c0_status(0x100 << 2);
 }
 
-static void octeon_irq_ciu0_enable(unsigned int irq)
+static void octeon_irq_ciu0_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int coreid = cvmx_get_core_num();
 	unsigned long flags;
 	uint64_t en0;
@@ -145,8 +149,9 @@ static void octeon_irq_ciu0_enable(unsigned int irq)
 	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 }
 
-static void octeon_irq_ciu0_disable(unsigned int irq)
+static void octeon_irq_ciu0_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
 	unsigned long flags;
 	uint64_t en0;
@@ -170,8 +175,9 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_enable_v2(unsigned int irq)
+static void octeon_irq_ciu0_enable_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 
@@ -182,10 +188,10 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_ack_v2(unsigned int irq)
+static void octeon_irq_ciu0_ack_v2(struct irq_desc *desc)
 {
 	int index = cvmx_get_core_num() * 2;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 
 	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
 }
@@ -194,34 +200,33 @@ static void octeon_irq_ciu0_ack_v2(unsigned int irq)
  * CIU timer type interrupts must be acknoleged by writing a '1' bit
  * to their sum0 bit.
  */
-static void octeon_irq_ciu0_timer_ack(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack(struct irq_desc *desc)
 {
 	int index = cvmx_get_core_num() * 2;
-	uint64_t mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	uint64_t mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 	cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
 }
 
-static void octeon_irq_ciu0_timer_ack_v1(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack_v1(struct irq_desc *desc)
 {
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack(irq);
+	octeon_irq_ciu0_timer_ack(desc);
+	octeon_irq_ciu0_ack(desc);
 }
 
-static void octeon_irq_ciu0_timer_ack_v2(unsigned int irq)
+static void octeon_irq_ciu0_timer_ack_v2(struct irq_desc *desc)
 {
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack_v2(irq);
+	octeon_irq_ciu0_timer_ack(desc);
+	octeon_irq_ciu0_ack_v2(desc);
 }
 
 /*
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu0_eoi_v2(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
 	int index = cvmx_get_core_num() * 2;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WORKQ0);
 
 	if ((desc->status & IRQ_DISABLED) == 0)
 		cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
@@ -231,8 +236,9 @@ static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
+static void octeon_irq_ciu0_disable_all_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 	int index;
 	int cpu;
@@ -243,8 +249,9 @@ static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu0_set_affinity(struct irq_desc *desc, const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
@@ -274,9 +281,10 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
  * Set affinity for the irq for chips that have the EN*_W1{S,C}
  * registers.
  */
-static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
+static int octeon_irq_ciu0_set_affinity_v2(struct irq_desc *desc,
 					   const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
@@ -339,7 +347,7 @@ static struct irq_chip octeon_irq_chip_ciu0_timer = {
 };
 
 
-static void octeon_irq_ciu1_ack(unsigned int irq)
+static void octeon_irq_ciu1_ack(struct irq_desc *desc)
 {
 	/*
 	 * In order to avoid any locking accessing the CIU, we
@@ -353,7 +361,7 @@ static void octeon_irq_ciu1_ack(unsigned int irq)
 	clear_c0_status(0x100 << 3);
 }
 
-static void octeon_irq_ciu1_eoi(unsigned int irq)
+static void octeon_irq_ciu1_eoi(struct irq_desc *desc)
 {
 	/*
 	 * Enable all CIU interrupts again.  We don't need to disable
@@ -363,8 +371,9 @@ static void octeon_irq_ciu1_eoi(unsigned int irq)
 	set_c0_status(0x100 << 3);
 }
 
-static void octeon_irq_ciu1_enable(unsigned int irq)
+static void octeon_irq_ciu1_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int coreid = cvmx_get_core_num();
 	unsigned long flags;
 	uint64_t en1;
@@ -378,8 +387,9 @@ static void octeon_irq_ciu1_enable(unsigned int irq)
 	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 }
 
-static void octeon_irq_ciu1_disable(unsigned int irq)
+static void octeon_irq_ciu1_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 	unsigned long flags;
 	uint64_t en1;
@@ -403,8 +413,9 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_enable_v2(unsigned int irq)
+static void octeon_irq_ciu1_enable_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 
@@ -415,8 +426,9 @@ static void octeon_irq_ciu1_enable_v2(unsigned int irq)
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_ack_v2(unsigned int irq)
+static void octeon_irq_ciu1_ack_v2(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 
@@ -427,11 +439,10 @@ static void octeon_irq_ciu1_ack_v2(unsigned int irq)
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu1_eoi_v2(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + irq;
 	int index = cvmx_get_core_num() * 2 + 1;
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WDOG0);
 
 	if ((desc->status & IRQ_DISABLED) == 0)
 		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
@@ -441,9 +452,9 @@ static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
+static void octeon_irq_ciu1_disable_all_v2(struct irq_desc *desc)
 {
-	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	u64 mask = 1ull << (desc->irq - OCTEON_IRQ_WDOG0);
 	int index;
 	int cpu;
 	for_each_online_cpu(cpu) {
@@ -453,9 +464,10 @@ static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static int octeon_irq_ciu1_set_affinity(unsigned int irq,
+static int octeon_irq_ciu1_set_affinity(struct irq_desc *desc,
 					const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
@@ -486,9 +498,10 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq,
  * Set affinity for the irq for chips that have the EN*_W1{S,C}
  * registers.
  */
-static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
+static int octeon_irq_ciu1_set_affinity_v2(struct irq_desc *desc,
 					   const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu;
 	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
@@ -532,8 +545,9 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
 
 static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
 
-static void octeon_irq_msi_ack(unsigned int irq)
+static void octeon_irq_msi_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/* These chips have PCI */
 		cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
@@ -548,13 +562,14 @@ static void octeon_irq_msi_ack(unsigned int irq)
 	}
 }
 
-static void octeon_irq_msi_eoi(unsigned int irq)
+static void octeon_irq_msi_eoi(struct irq_desc *desc)
 {
 	/* Nothing needed */
 }
 
-static void octeon_irq_msi_enable(unsigned int irq)
+static void octeon_irq_msi_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/*
 		 * Octeon PCI doesn't have the ability to mask/unmask
@@ -581,8 +596,9 @@ static void octeon_irq_msi_enable(unsigned int irq)
 	}
 }
 
-static void octeon_irq_msi_disable(unsigned int irq)
+static void octeon_irq_msi_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
 		/* See comment in enable */
 	} else {
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
index cb41954..e8d60a6 100644
--- a/arch/mips/dec/ioasic-irq.c
+++ b/arch/mips/dec/ioasic-irq.c
@@ -21,8 +21,9 @@
 static int ioasic_irq_base;
 
 
-static inline void unmask_ioasic_irq(unsigned int irq)
+static inline void unmask_ioasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 simr;
 
 	simr = ioasic_read(IO_REG_SIMR);
@@ -30,8 +31,9 @@ static inline void unmask_ioasic_irq(unsigned int irq)
 	ioasic_write(IO_REG_SIMR, simr);
 }
 
-static inline void mask_ioasic_irq(unsigned int irq)
+static inline void mask_ioasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 simr;
 
 	simr = ioasic_read(IO_REG_SIMR);
@@ -47,16 +49,16 @@ static inline void clear_ioasic_irq(unsigned int irq)
 	ioasic_write(IO_REG_SIR, sir);
 }
 
-static inline void ack_ioasic_irq(unsigned int irq)
+static inline void ack_ioasic_irq(struct irq_desc *desc)
 {
-	mask_ioasic_irq(irq);
+	mask_ioasic_irq(desc);
 	fast_iob();
 }
 
-static inline void end_ioasic_irq(unsigned int irq)
+static inline void end_ioasic_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		unmask_ioasic_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_ioasic_irq(desc);
 }
 
 static struct irq_chip ioasic_irq_type = {
@@ -74,11 +76,12 @@ static struct irq_chip ioasic_irq_type = {
 
 #define ack_ioasic_dma_irq ack_ioasic_irq
 
-static inline void end_ioasic_dma_irq(unsigned int irq)
+static inline void end_ioasic_dma_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_ioasic_irq(irq);
 	fast_iob();
-	end_ioasic_irq(irq);
+	end_ioasic_irq(desc);
 }
 
 static struct irq_chip ioasic_dma_irq_type = {
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index ed90a8d..3ea3682 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -31,8 +31,9 @@ u32 cached_kn02_csr;
 static int kn02_irq_base;
 
 
-static inline void unmask_kn02_irq(unsigned int irq)
+static inline void unmask_kn02_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
 						       KN02_CSR);
 
@@ -40,8 +41,9 @@ static inline void unmask_kn02_irq(unsigned int irq)
 	*csr = cached_kn02_csr;
 }
 
-static inline void mask_kn02_irq(unsigned int irq)
+static inline void mask_kn02_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
 						       KN02_CSR);
 
@@ -49,9 +51,9 @@ static inline void mask_kn02_irq(unsigned int irq)
 	*csr = cached_kn02_csr;
 }
 
-static void ack_kn02_irq(unsigned int irq)
+static void ack_kn02_irq(struct irq_desc *desc)
 {
-	mask_kn02_irq(irq);
+	mask_kn02_irq(desc);
 	iob();
 }
 
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 9504b7e..3c2e1c9 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -34,8 +34,9 @@
 
 #include <asm/emma/emma2rh.h>
 
-static void emma2rh_irq_enable(unsigned int irq)
+static void emma2rh_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_value;
 	u32 reg_bitmask;
 	u32 reg_index;
@@ -49,8 +50,9 @@ static void emma2rh_irq_enable(unsigned int irq)
 	emma2rh_out32(reg_index, reg_value | reg_bitmask);
 }
 
-static void emma2rh_irq_disable(unsigned int irq)
+static void emma2rh_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg_value;
 	u32 reg_bitmask;
 	u32 reg_index;
@@ -82,8 +84,9 @@ void emma2rh_irq_init(void)
 					      handle_level_irq, "level");
 }
 
-static void emma2rh_sw_irq_enable(unsigned int irq)
+static void emma2rh_sw_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_SW_IRQ_BASE;
@@ -93,8 +96,9 @@ static void emma2rh_sw_irq_enable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
 }
 
-static void emma2rh_sw_irq_disable(unsigned int irq)
+static void emma2rh_sw_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_SW_IRQ_BASE;
@@ -122,8 +126,9 @@ void emma2rh_sw_irq_init(void)
 					      handle_level_irq, "level");
 }
 
-static void emma2rh_gpio_irq_enable(unsigned int irq)
+static void emma2rh_gpio_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
@@ -133,8 +138,9 @@ static void emma2rh_gpio_irq_enable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_disable(unsigned int irq)
+static void emma2rh_gpio_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
@@ -144,14 +150,16 @@ static void emma2rh_gpio_irq_disable(unsigned int irq)
 	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_ack(unsigned int irq)
+static void emma2rh_gpio_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
 	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
 }
 
-static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
+static void emma2rh_gpio_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 reg;
 
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index ee18028..b76cdcd 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -22,8 +22,9 @@
 
 static DEFINE_RAW_SPINLOCK(r4030_lock);
 
-static void enable_r4030_irq(unsigned int irq)
+static void enable_r4030_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - JAZZ_IRQ_START);
 	unsigned long flags;
 
@@ -33,8 +34,9 @@ static void enable_r4030_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&r4030_lock, flags);
 }
 
-void disable_r4030_irq(unsigned int irq)
+void disable_r4030_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START));
 	unsigned long flags;
 
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 2779911..f6f63a3 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -30,9 +30,9 @@
 
 static int i8259A_auto_eoi = -1;
 DEFINE_RAW_SPINLOCK(i8259A_lock);
-static void disable_8259A_irq(unsigned int irq);
-static void enable_8259A_irq(unsigned int irq);
-static void mask_and_ack_8259A(unsigned int irq);
+static void disable_8259A_irq(struct irq_desc *desc);
+static void enable_8259A_irq(struct irq_desc *desc);
+static void mask_and_ack_8259A(struct irq_desc *desc);
 static void init_8259A(int auto_eoi);
 
 static struct irq_chip i8259A_chip = {
@@ -58,8 +58,9 @@ static unsigned int cached_irq_mask = 0xffff;
 #define cached_master_mask	(cached_irq_mask)
 #define cached_slave_mask	(cached_irq_mask >> 8)
 
-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;
 	unsigned long flags;
 
@@ -74,8 +75,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;
 	unsigned long flags;
 
@@ -144,8 +146,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;
 	unsigned long flags;
 
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index b181f2f..c278afa 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -88,16 +88,18 @@ unsigned int gic_get_int(void)
 	return i;
 }
 
-static unsigned int gic_irq_startup(unsigned int irq)
+static unsigned int gic_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_SET_INTR_MASK(irq);
 	return 0;
 }
 
-static void gic_irq_ack(unsigned int irq)
+static void gic_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_CLR_INTR_MASK(irq);
@@ -106,15 +108,17 @@ static void gic_irq_ack(unsigned int irq)
 		GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
 }
 
-static void gic_mask_irq(unsigned int irq)
+static void gic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_CLR_INTR_MASK(irq);
 }
 
-static void gic_unmask_irq(unsigned int irq)
+static void gic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	irq -= _irqbase;
 	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
 	GIC_SET_INTR_MASK(irq);
@@ -124,8 +128,9 @@ static void gic_unmask_irq(unsigned int irq)
 
 static DEFINE_SPINLOCK(gic_lock);
 
-static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+static int gic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int irq = desc->irq;
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
 	int		i;
@@ -148,7 +153,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 		set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
 
 	}
-	cpumask_copy(irq_desc[irq].affinity, cpumask);
+	cpumask_copy(desc->affinity, cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
index 42ef814..2c323dc 100644
--- a/arch/mips/kernel/irq-gt641xx.c
+++ b/arch/mips/kernel/irq-gt641xx.c
@@ -29,8 +29,9 @@
 
 static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
 
-static void ack_gt641xx_irq(unsigned int irq)
+static void ack_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 cause;
 
@@ -41,8 +42,9 @@ static void ack_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void mask_gt641xx_irq(unsigned int irq)
+static void mask_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 mask;
 
@@ -53,8 +55,9 @@ static void mask_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void mask_ack_gt641xx_irq(unsigned int irq)
+static void mask_ack_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 cause, mask;
 
@@ -69,8 +72,9 @@ static void mask_ack_gt641xx_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
-static void unmask_gt641xx_irq(unsigned int irq)
+static void unmask_gt641xx_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 mask;
 
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 6a8cd28..b860443 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -28,8 +28,9 @@ static unsigned long _icctrl_msc;
 static unsigned int irq_base;
 
 /* mask off an interrupt */
-static inline void mask_msc_irq(unsigned int irq)
+static inline void mask_msc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq < (irq_base + 32))
 		MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
 	else
@@ -37,8 +38,9 @@ static inline void mask_msc_irq(unsigned int irq)
 }
 
 /* unmask an interrupt */
-static inline void unmask_msc_irq(unsigned int irq)
+static inline void unmask_msc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (irq < (irq_base + 32))
 		MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
 	else
@@ -48,9 +50,10 @@ static inline void unmask_msc_irq(unsigned int irq)
 /*
  * Masks and ACKs an IRQ
  */
-static void level_mask_and_ack_msc_irq(unsigned int irq)
+static void level_mask_and_ack_msc_irq(struct irq_desc *desc)
 {
-	mask_msc_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msc_irq(desc);
 	if (!cpu_has_veic)
 		MSCIC_WRITE(MSC01_IC_EOI, 0);
 	/* This actually needs to be a call into platform code */
@@ -60,9 +63,10 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
 /*
  * Masks and ACKs an IRQ
  */
-static void edge_mask_and_ack_msc_irq(unsigned int irq)
+static void edge_mask_and_ack_msc_irq(struct irq_desc *desc)
 {
-	mask_msc_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msc_irq(desc);
 	if (!cpu_has_veic)
 		MSCIC_WRITE(MSC01_IC_EOI, 0);
 	else {
@@ -77,10 +81,10 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq)
 /*
  * End IRQ processing
  */
-static void end_msc_irq(unsigned int irq)
+static void end_msc_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		unmask_msc_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_msc_irq(desc);
 }
 
 /*
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index fb50cc7..0c5e6c0 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -17,13 +17,15 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-static inline void unmask_rm7k_irq(unsigned int irq)
+static inline void unmask_rm7k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
 }
 
-static inline void mask_rm7k_irq(unsigned int irq)
+static inline void mask_rm7k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
 }
 
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index b47e461..5491ec0 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -18,22 +18,24 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-static inline void unmask_rm9k_irq(unsigned int irq)
+static inline void unmask_rm9k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
 }
 
-static inline void mask_rm9k_irq(unsigned int irq)
+static inline void mask_rm9k_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
 }
 
-static inline void rm9k_cpu_irq_enable(unsigned int irq)
+static inline void rm9k_cpu_irq_enable(struct irq_desc *desc)
 {
 	unsigned long flags;
 
 	local_irq_save(flags);
-	unmask_rm9k_irq(irq);
+	unmask_rm9k_irq(desc);
 	local_irq_restore(flags);
 }
 
@@ -42,31 +44,31 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq)
  */
 static void local_rm9k_perfcounter_irq_startup(void *args)
 {
-	unsigned int irq = (unsigned int) args;
+	struct irq_desc *desc = (struct irq_desc *) args;
 
-	rm9k_cpu_irq_enable(irq);
+	rm9k_cpu_irq_enable(desc);
 }
 
-static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
+static unsigned int rm9k_perfcounter_irq_startup(struct irq_desc *desc)
 {
-	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1);
+	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *)desc, 1);
 
 	return 0;
 }
 
 static void local_rm9k_perfcounter_irq_shutdown(void *args)
 {
-	unsigned int irq = (unsigned int) args;
+	struct irq_desc *desc = (struct irq_desc *) args;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	mask_rm9k_irq(irq);
+	mask_rm9k_irq(desc);
 	local_irq_restore(flags);
 }
 
-static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
+static void rm9k_perfcounter_irq_shutdown(struct irq_desc *desc)
 {
-	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1);
+	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *)desc, 1);
 }
 
 static struct irq_chip rm9k_irq_controller = {
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 55c8a3c..ad7c3d0 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -36,14 +36,16 @@
 #include <asm/mipsmtregs.h>
 #include <asm/system.h>
 
-static inline void unmask_mips_irq(unsigned int irq)
+static inline void unmask_mips_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	irq_enable_hazard();
 }
 
-static inline void mask_mips_irq(unsigned int irq)
+static inline void mask_mips_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	irq_disable_hazard();
 }
@@ -64,13 +66,14 @@ static struct irq_chip mips_cpu_irq_controller = {
 #define unmask_mips_mt_irq	unmask_mips_irq
 #define mask_mips_mt_irq	mask_mips_irq
 
-static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
+static unsigned int mips_mt_cpu_irq_startup(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vpflags = dvpe();
 
 	clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	evpe(vpflags);
-	unmask_mips_mt_irq(irq);
+	unmask_mips_mt_irq(desc);
 
 	return 0;
 }
@@ -79,12 +82,13 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for mips_cpu_irq_end.
  */
-static void mips_mt_cpu_irq_ack(unsigned int irq)
+static void mips_mt_cpu_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int vpflags = dvpe();
 	clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
 	evpe(vpflags);
-	mask_mips_mt_irq(irq);
+	mask_mips_mt_irq(desc);
 }
 
 static struct irq_chip mips_mt_cpu_irq_controller = {
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
index 9b78029..5532280 100644
--- a/arch/mips/kernel/irq_txx9.c
+++ b/arch/mips/kernel/irq_txx9.c
@@ -62,8 +62,9 @@ static struct {
 	unsigned char mode;
 } txx9irq[TXx9_MAX_IR] __read_mostly;
 
-static void txx9_irq_unmask(unsigned int irq)
+static void txx9_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
 	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
@@ -78,8 +79,9 @@ static void txx9_irq_unmask(unsigned int irq)
 #endif
 }
 
-static inline void txx9_irq_mask(unsigned int irq)
+static inline void txx9_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
 	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
@@ -98,18 +100,20 @@ static inline void txx9_irq_mask(unsigned int irq)
 #endif
 }
 
-static void txx9_irq_mask_ack(unsigned int irq)
+static void txx9_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 
-	txx9_irq_mask(irq);
+	txx9_irq_mask(desc);
 	/* clear edge detection */
 	if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
 		__raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
 }
 
-static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int txx9_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 cr;
 	u32 __iomem *crp;
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index 1353fb1..9e9edf9 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -32,16 +32,18 @@ static volatile int *lasat_int_status;
 static volatile int *lasat_int_mask;
 static volatile int lasat_int_mask_shift;
 
-void disable_lasat_irq(unsigned int irq_nr)
+void disable_lasat_irq(struct irq_desc *desc)
 {
-	irq_nr -= LASAT_IRQ_BASE;
-	*lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
+	unsigned int irq = desc->irq;
+	irq -= LASAT_IRQ_BASE;
+	*lasat_int_mask &= ~(1 << irq) << lasat_int_mask_shift;
 }
 
-void enable_lasat_irq(unsigned int irq_nr)
+void enable_lasat_irq(struct irq_desc *desc)
 {
-	irq_nr -= LASAT_IRQ_BASE;
-	*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
+	unsigned int irq = desc->irq;
+	irq -= LASAT_IRQ_BASE;
+	*lasat_int_mask |= (1 << irq) << lasat_int_mask_shift;
 }
 
 static struct irq_chip lasat_irq_type = {
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
index 2dc2a4c..00db7a1 100644
--- a/arch/mips/loongson/common/bonito-irq.c
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -16,14 +16,16 @@
 
 #include <loongson.h>
 
-static inline void bonito_irq_enable(unsigned int irq)
+static inline void bonito_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
 
-static inline void bonito_irq_disable(unsigned int irq)
+static inline void bonito_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c
index 941916f..9b4f8b1 100644
--- a/arch/mips/nxp/pnx833x/common/interrupts.c
+++ b/arch/mips/nxp/pnx833x/common/interrupts.c
@@ -158,8 +158,9 @@ static int irqflags[PNX833X_PIC_NUM_IRQ];	/* initialized by zeroes */
 
 static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
 
-static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
+static unsigned int pnx833x_startup_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -172,8 +173,9 @@ static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
 	return 0;
 }
 
-static void pnx833x_shutdown_pic_irq(unsigned int irq)
+static void pnx833x_shutdown_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -185,8 +187,9 @@ static void pnx833x_shutdown_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_enable_pic_irq(unsigned int irq)
+static void pnx833x_enable_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -199,8 +202,9 @@ static void pnx833x_enable_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_disable_pic_irq(unsigned int irq)
+static void pnx833x_disable_pic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
@@ -212,18 +216,19 @@ static void pnx833x_disable_pic_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_ack_pic_irq(unsigned int irq)
+static void pnx833x_ack_pic_irq(struct irq_desc *desc)
 {
 }
 
-static void pnx833x_end_pic_irq(unsigned int irq)
+static void pnx833x_end_pic_irq(struct irq_desc *desc)
 {
 }
 
 static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
 
-static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
+static unsigned int pnx833x_startup_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -232,8 +237,9 @@ static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
 	return 0;
 }
 
-static void pnx833x_enable_gpio_irq(unsigned int irq)
+static void pnx833x_enable_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -241,8 +247,9 @@ static void pnx833x_enable_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_disable_gpio_irq(unsigned int irq)
+static void pnx833x_disable_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -250,12 +257,13 @@ static void pnx833x_disable_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static void pnx833x_ack_gpio_irq(unsigned int irq)
+static void pnx833x_ack_gpio_irq(struct irq_desc *desc)
 {
 }
 
-static void pnx833x_end_gpio_irq(unsigned int irq)
+static void pnx833x_end_gpio_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
 	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
@@ -263,8 +271,9 @@ static void pnx833x_end_gpio_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
-static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
+static int pnx833x_set_type_gpio_irq(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	int gpio_mode;
 
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c
index 7aca7d5..944fe74 100644
--- a/arch/mips/nxp/pnx8550/common/int.c
+++ b/arch/mips/nxp/pnx8550/common/int.c
@@ -115,8 +115,9 @@ static inline void unmask_gic_int(unsigned int irq_nr)
 	PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
 }
 
-static inline void mask_irq(unsigned int irq_nr)
+static inline void mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
 		modify_cp0_intmask(1 << irq_nr, 0);
 	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
@@ -130,8 +131,9 @@ static inline void mask_irq(unsigned int irq_nr)
 	}
 }
 
-static inline void unmask_irq(unsigned int irq_nr)
+static inline void unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
 		modify_cp0_intmask(0, 1 << irq_nr);
 	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
@@ -183,7 +185,7 @@ void __init arch_init_irq(void)
 
 	for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
 		set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
-		mask_irq(i);	/* mask the irq just in case  */
+		mask_irq(irq_to_desc(i));	/* mask the irq just in case  */
 	}
 
 	/* init of GIC/IPC interrupts */
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
index 94c9c2c..47b2be9 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -24,9 +24,9 @@
  * NOTE: We are only enabling support for VPE0 right now.
  */
 
-static inline void unmask_msp_cic_irq(unsigned int irq)
+static inline void unmask_msp_cic_irq(struct irq_desc *desc)
 {
-
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE));
@@ -34,8 +34,9 @@ static inline void unmask_msp_cic_irq(unsigned int irq)
 		*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
 }
 
-static inline void mask_msp_cic_irq(unsigned int irq)
+static inline void mask_msp_cic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE));
@@ -47,9 +48,10 @@ static inline void mask_msp_cic_irq(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for msp_cic_irq_end.
  */
-static inline void ack_msp_cic_irq(unsigned int irq)
+static inline void ack_msp_cic_irq(struct irq_desc *desc)
 {
-	mask_msp_cic_irq(irq);
+	unsigned int irq = desc->irq;
+	mask_msp_cic_irq(desc);
 
 	/*
 	 * only really necessary for 18, 16-14 and sometimes 3:0 (since
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
index 61f3902..e73cda1 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
@@ -21,8 +21,9 @@
 #include <msp_slp_int.h>
 #include <msp_regs.h>
 
-static inline void unmask_msp_slp_irq(unsigned int irq)
+static inline void unmask_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
@@ -30,8 +31,9 @@ static inline void unmask_msp_slp_irq(unsigned int irq)
 		*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
 }
 
-static inline void mask_msp_slp_irq(unsigned int irq)
+static inline void mask_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
@@ -43,8 +45,9 @@ static inline void mask_msp_slp_irq(unsigned int irq)
  * While we ack the interrupt interrupts are disabled and thus we don't need
  * to deal with concurrency issues.  Same for msp_slp_irq_end.
  */
-static inline void ack_msp_slp_irq(unsigned int irq)
+static inline void ack_msp_slp_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* check for PER interrupt range */
 	if (irq < MSP_PER_INTBASE)
 		*SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
index b54d244..a710bc3 100644
--- a/arch/mips/powertv/asic/irq_asic.c
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -20,8 +20,9 @@
 
 #include <asm/mach-powertv/asic_regs.h>
 
-static inline void unmask_asic_irq(unsigned int irq)
+static inline void unmask_asic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long enable_bit;
 
 	enable_bit = (1 << (irq & 0x1f));
@@ -44,8 +45,9 @@ static inline void unmask_asic_irq(unsigned int irq)
 	}
 }
 
-static inline void mask_asic_irq(unsigned int irq)
+static inline void mask_asic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long disable_mask;
 
 	disable_mask = ~(1 << (irq & 0x1f));
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index f078820..39f304a 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -112,14 +112,15 @@ static inline void ack_local_irq(unsigned int ip)
 	clear_c0_cause(ipnum);
 }
 
-static void rb532_enable_irq(unsigned int irq_nr)
+static void rb532_enable_irq(struct irq_desc *desc)
 {
-	int ip = irq_nr - GROUP0_IRQ_BASE;
+	unsigned int irq = desc->irq;
+	int ip = irq - GROUP0_IRQ_BASE;
 	unsigned int group, intr_bit;
 	volatile unsigned int *addr;
 
 	if (ip < 0)
-		enable_local_irq(irq_nr);
+		enable_local_irq(irq);
 	else {
 		group = ip >> 5;
 
@@ -133,14 +134,15 @@ static void rb532_enable_irq(unsigned int irq_nr)
 	}
 }
 
-static void rb532_disable_irq(unsigned int irq_nr)
+static void rb532_disable_irq(struct irq_desc *desc)
 {
-	int ip = irq_nr - GROUP0_IRQ_BASE;
+	unsigned int irq = desc->irq;
+	int ip = irq - GROUP0_IRQ_BASE;
 	unsigned int group, intr_bit, mask;
 	volatile unsigned int *addr;
 
 	if (ip < 0) {
-		disable_local_irq(irq_nr);
+		disable_local_irq(irq);
 	} else {
 		group = ip >> 5;
 
@@ -152,8 +154,8 @@ static void rb532_disable_irq(unsigned int irq_nr)
 		WRITE_MASK(addr, mask);
 
 		/* There is a maximum of 14 GPIO interrupts */
-		if (group == GPIO_MAPPED_IRQ_GROUP && irq_nr <= (GROUP4_IRQ_BASE + 13))
-			rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE);
+		if (group == GPIO_MAPPED_IRQ_GROUP && irq <= (GROUP4_IRQ_BASE + 13))
+			rb532_gpio_set_istat(0, irq - GPIO_MAPPED_IRQ_BASE);
 
 		/*
 		 * if there are no more interrupts enabled in this
@@ -164,14 +166,16 @@ static void rb532_disable_irq(unsigned int irq_nr)
 	}
 }
 
-static void rb532_mask_and_ack_irq(unsigned int irq_nr)
+static void rb532_mask_and_ack_irq(struct irq_desc *desc)
 {
-	rb532_disable_irq(irq_nr);
-	ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
+	unsigned int irq = desc->irq;
+	rb532_disable_irq(desc);
+	ack_local_irq(group_to_ip(irq_to_group(irq)));
 }
 
-static int rb532_set_type(unsigned int irq_nr, unsigned type)
+static int rb532_set_type(struct irq_desc *desc, unsigned type)
 {
+	unsigned int irq_nr = desc->irq;
 	int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
 	int group = irq_to_group(irq_nr);
 
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index 383f11d..93ddd8b 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -31,16 +31,18 @@ static char lc3msk_to_irqnr[256];
 
 extern int ip22_eisa_init(void);
 
-static void enable_local0_irq(unsigned int irq)
+static void enable_local0_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* don't allow mappable interrupt to be enabled from setup_irq,
 	 * we have our own way to do so */
 	if (irq != SGI_MAP_0_IRQ)
 		sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
 }
 
-static void disable_local0_irq(unsigned int irq)
+static void disable_local0_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
 }
 
@@ -52,16 +54,18 @@ static struct irq_chip ip22_local0_irq_type = {
 	.unmask		= enable_local0_irq,
 };
 
-static void enable_local1_irq(unsigned int irq)
+static void enable_local1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* don't allow mappable interrupt to be enabled from setup_irq,
 	 * we have our own way to do so */
 	if (irq != SGI_MAP_1_IRQ)
 		sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
 }
 
-static void disable_local1_irq(unsigned int irq)
+static void disable_local1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
 }
 
@@ -73,14 +77,16 @@ static struct irq_chip ip22_local1_irq_type = {
 	.unmask		= enable_local1_irq,
 };
 
-static void enable_local2_irq(unsigned int irq)
+static void enable_local2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
 	sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
 }
 
-static void disable_local2_irq(unsigned int irq)
+static void disable_local2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
 	if (!sgint->cmeimask0)
 		sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
@@ -94,14 +100,16 @@ static struct irq_chip ip22_local2_irq_type = {
 	.unmask		= enable_local2_irq,
 };
 
-static void enable_local3_irq(unsigned int irq)
+static void enable_local3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
 	sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
 }
 
-static void disable_local3_irq(unsigned int irq)
+static void disable_local3_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
 	if (!sgint->cmeimask1)
 		sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index c1c8e40..3fb93b5 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -241,8 +241,9 @@ static int intr_disconnect_level(int cpu, int bit)
 }
 
 /* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(unsigned int irq)
+static unsigned int startup_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct bridge_controller *bc;
 	bridgereg_t device;
 	bridge_t *bridge;
@@ -289,8 +290,9 @@ static unsigned int startup_bridge_irq(unsigned int irq)
 }
 
 /* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-static void shutdown_bridge_irq(unsigned int irq)
+static void shutdown_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
 	bridge_t *bridge = bc->base;
 	int pin, swlevel;
@@ -310,8 +312,9 @@ static void shutdown_bridge_irq(unsigned int irq)
 	bridge->b_wid_tflush;
 }
 
-static inline void enable_bridge_irq(unsigned int irq)
+static inline void enable_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cpuid_t cpu;
 	int swlevel;
 
@@ -319,8 +322,9 @@ static inline void enable_bridge_irq(unsigned int irq)
 	intr_connect_level(cpu, swlevel);
 }
 
-static inline void disable_bridge_irq(unsigned int irq)
+static inline void disable_bridge_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	cpuid_t cpu;
 	int swlevel;
 
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index d6802d6..13905d4 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -36,11 +36,11 @@
 #include <asm/sn/sn0/hubio.h>
 #include <asm/pci/bridge.h>
 
-static void enable_rt_irq(unsigned int irq)
+static void enable_rt_irq(struct irq_desc *desc)
 {
 }
 
-static void disable_rt_irq(unsigned int irq)
+static void disable_rt_irq(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index d8b6520..2cf45d3 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -131,16 +131,18 @@ static struct irqaction cpuerr_irq = {
 
 static uint64_t crime_mask;
 
-static inline void crime_enable_irq(unsigned int irq)
+static inline void crime_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask |= 1 << bit;
 	crime->imask = crime_mask;
 }
 
-static inline void crime_disable_irq(unsigned int irq)
+static inline void crime_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask &= ~(1 << bit);
@@ -148,15 +150,15 @@ static inline void crime_disable_irq(unsigned int irq)
 	flush_crime_bus();
 }
 
-static void crime_level_mask_and_ack_irq(unsigned int irq)
+static void crime_level_mask_and_ack_irq(struct irq_desc *desc)
 {
-	crime_disable_irq(irq);
+	crime_disable_irq(desc);
 }
 
-static void crime_level_end_irq(unsigned int irq)
+static void crime_level_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		crime_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(desc);
 }
 
 static struct irq_chip crime_level_interrupt = {
@@ -168,8 +170,9 @@ static struct irq_chip crime_level_interrupt = {
 	.end		= crime_level_end_irq,
 };
 
-static void crime_edge_mask_and_ack_irq(unsigned int irq)
+static void crime_edge_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 	uint64_t crime_int;
 
@@ -179,13 +182,13 @@ static void crime_edge_mask_and_ack_irq(unsigned int irq)
 	crime_int &= ~(1 << bit);
 	crime->hard_int = crime_int;
 
-	crime_disable_irq(irq);
+	crime_disable_irq(desc);
 }
 
-static void crime_edge_end_irq(unsigned int irq)
+static void crime_edge_end_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		crime_enable_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(desc);
 }
 
 static struct irq_chip crime_edge_interrupt = {
@@ -205,16 +208,18 @@ static struct irq_chip crime_edge_interrupt = {
 
 static unsigned long macepci_mask;
 
-static void enable_macepci_irq(unsigned int irq)
+static void enable_macepci_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
 	mace->pci.control = macepci_mask;
 	crime_mask |= 1 << (irq - CRIME_IRQ_BASE);
 	crime->imask = crime_mask;
 }
 
-static void disable_macepci_irq(unsigned int irq)
+static void disable_macepci_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE));
 	crime->imask = crime_mask;
 	flush_crime_bus();
@@ -223,10 +228,10 @@ static void disable_macepci_irq(unsigned int irq)
 	flush_mace_bus();
 }
 
-static void end_macepci_irq(unsigned int irq)
+static void end_macepci_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_macepci_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq(desc);
 }
 
 static struct irq_chip ip32_macepci_interrupt = {
@@ -277,8 +282,9 @@ static struct irq_chip ip32_macepci_interrupt = {
 
 static unsigned long maceisa_mask;
 
-static void enable_maceisa_irq(unsigned int irq)
+static void enable_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int crime_int = 0;
 
 	pr_debug("maceisa enable: %u\n", irq);
@@ -301,8 +307,9 @@ static void enable_maceisa_irq(unsigned int irq)
 	mace->perif.ctrl.imask = maceisa_mask;
 }
 
-static void disable_maceisa_irq(unsigned int irq)
+static void disable_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int crime_int = 0;
 
 	maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
@@ -319,8 +326,9 @@ static void disable_maceisa_irq(unsigned int irq)
 	flush_mace_bus();
 }
 
-static void mask_and_ack_maceisa_irq(unsigned int irq)
+static void mask_and_ack_maceisa_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mace_int;
 
 	/* edge triggered */
@@ -328,13 +336,13 @@ static void mask_and_ack_maceisa_irq(unsigned int irq)
 	mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
 	mace->perif.ctrl.istat = mace_int;
 
-	disable_maceisa_irq(irq);
+	disable_maceisa_irq(desc);
 }
 
-static void end_maceisa_irq(unsigned irq)
+static void end_maceisa_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_maceisa_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_maceisa_irq(desc);
 }
 
 static struct irq_chip ip32_maceisa_level_interrupt = {
@@ -359,16 +367,18 @@ static struct irq_chip ip32_maceisa_edge_interrupt = {
  * bits 0-3 and 7 in the CRIME register.
  */
 
-static void enable_mace_irq(unsigned int irq)
+static void enable_mace_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask |= (1 << bit);
 	crime->imask = crime_mask;
 }
 
-static void disable_mace_irq(unsigned int irq)
+static void disable_mace_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int bit = irq - CRIME_IRQ_BASE;
 
 	crime_mask &= ~(1 << bit);
@@ -376,10 +386,10 @@ static void disable_mace_irq(unsigned int irq)
 	flush_crime_bus();
 }
 
-static void end_mace_irq(unsigned int irq)
+static void end_mace_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_mace_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq(desc);
 }
 
 static struct irq_chip ip32_mace_interrupt = {
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 06e25d9..1fb5d8c 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -46,12 +46,12 @@
  */
 
 
-static void end_bcm1480_irq(unsigned int irq);
-static void enable_bcm1480_irq(unsigned int irq);
-static void disable_bcm1480_irq(unsigned int irq);
-static void ack_bcm1480_irq(unsigned int irq);
+static void end_bcm1480_irq(struct irq_desc *desc);
+static void enable_bcm1480_irq(struct irq_desc *desc);
+static void disable_bcm1480_irq(struct irq_desc *desc);
+static void ack_bcm1480_irq(struct irq_desc *desc);
 #ifdef CONFIG_SMP
-static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int bcm1480_set_affinity(struct irq_desc *desc, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_PCI
@@ -110,8 +110,9 @@ void bcm1480_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bcm1480_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	int i = 0, old_cpu, cpu, int_on, k;
 	u64 cur_ints;
 	unsigned long flags;
@@ -157,19 +158,22 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 /*****************************************************************************/
 
-static void disable_bcm1480_irq(unsigned int irq)
+static void disable_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
 }
 
-static void enable_bcm1480_irq(unsigned int irq)
+static void enable_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
 }
 
 
-static void ack_bcm1480_irq(unsigned int irq)
+static void ack_bcm1480_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u64 pending;
 	unsigned int irq_dirty;
 	int k;
@@ -219,11 +223,11 @@ static void ack_bcm1480_irq(unsigned int irq)
 }
 
 
-static void end_bcm1480_irq(unsigned int irq)
+static void end_bcm1480_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	unsigned int irq = desc->irq;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
 		bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
-	}
 }
 
 
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index ab44a2f..0fcde43 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -45,12 +45,12 @@
  */
 
 
-static void end_sb1250_irq(unsigned int irq);
-static void enable_sb1250_irq(unsigned int irq);
-static void disable_sb1250_irq(unsigned int irq);
-static void ack_sb1250_irq(unsigned int irq);
+static void end_sb1250_irq(struct irq_desc *desc);
+static void enable_sb1250_irq(struct irq_desc *desc);
+static void disable_sb1250_irq(struct irq_desc *desc);
+static void ack_sb1250_irq(struct irq_desc *desc);
 #ifdef CONFIG_SMP
-static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int sb1250_set_affinity(struct irq_desc *desc, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
@@ -103,8 +103,9 @@ void sb1250_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int sb1250_set_affinity(struct irq_desc *desc, const struct cpumask *mask)
 {
+	unsigned int irq = desc->irq;
 	int i = 0, old_cpu, cpu, int_on;
 	u64 cur_ints;
 	unsigned long flags;
@@ -145,19 +146,22 @@ static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 /*****************************************************************************/
 
-static void disable_sb1250_irq(unsigned int irq)
+static void disable_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sb1250_mask_irq(sb1250_irq_owner[irq], irq);
 }
 
-static void enable_sb1250_irq(unsigned int irq)
+static void enable_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
 }
 
 
-static void ack_sb1250_irq(unsigned int irq)
+static void ack_sb1250_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 #ifdef CONFIG_SIBYTE_HAS_LDT
 	u64 pending;
 
@@ -201,11 +205,11 @@ static void ack_sb1250_irq(unsigned int irq)
 }
 
 
-static void end_sb1250_irq(unsigned int irq)
+static void end_sb1250_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	unsigned int irq = desc->irq;
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
 		sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
-	}
 }
 
 
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index e698089..0753f2c 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -167,23 +167,25 @@ static u32 a20r_ack_hwint(void)
 	return status;
 }
 
-static inline void unmask_a20r_irq(unsigned int irq)
+static inline void unmask_a20r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
 	irq_enable_hazard();
 }
 
-static inline void mask_a20r_irq(unsigned int irq)
+static inline void mask_a20r_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
 	irq_disable_hazard();
 }
 
-static void end_a20r_irq(unsigned int irq)
+static void end_a20r_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
 		a20r_ack_hwint();
-		unmask_a20r_irq(irq);
+		unmask_a20r_irq(desc);
 	}
 }
 
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 51e62bb..671e3f8 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -193,24 +193,26 @@ static struct pci_controller sni_controller = {
 	.io_map_base    = SNI_PORT_BASE
 };
 
-static void enable_pcimt_irq(unsigned int irq)
+static void enable_pcimt_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
 
 	*(volatile u8 *) PCIMT_IRQSEL |= mask;
 }
 
-void disable_pcimt_irq(unsigned int irq)
+void disable_pcimt_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
 
 	*(volatile u8 *) PCIMT_IRQSEL &= mask;
 }
 
-static void end_pcimt_irq(unsigned int irq)
+static void end_pcimt_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pcimt_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcimt_irq(desc);
 }
 
 static struct irq_chip pcimt_irq_type = {
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index f4699d3..cae4b89 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -155,24 +155,26 @@ static struct pci_controller sni_pcit_controller = {
 	.io_map_base    = SNI_PORT_BASE
 };
 
-static void enable_pcit_irq(unsigned int irq)
+static void enable_pcit_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
 
 	*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
 }
 
-void disable_pcit_irq(unsigned int irq)
+void disable_pcit_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
 
 	*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
 }
 
-void end_pcit_irq(unsigned int irq)
+void end_pcit_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pcit_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcit_irq(desc);
 }
 
 static struct irq_chip pcit_irq_type = {
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 90c558f..14d364a 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -154,8 +154,9 @@ static __iomem u8 *rm200_pic_slave;
 #define cached_master_mask	(rm200_cached_irq_mask)
 #define cached_slave_mask	(rm200_cached_irq_mask >> 8)
 
-static void sni_rm200_disable_8259A_irq(unsigned int irq)
+static void sni_rm200_disable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	unsigned long flags;
 
@@ -170,8 +171,9 @@ static void sni_rm200_disable_8259A_irq(unsigned int irq)
 	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 }
 
-static void sni_rm200_enable_8259A_irq(unsigned int irq)
+static void sni_rm200_enable_8259A_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask;
 	unsigned long flags;
 
@@ -209,8 +211,9 @@ static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-void sni_rm200_mask_and_ack_8259A(unsigned int irq)
+void sni_rm200_mask_and_ack_8259A(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irqmask;
 	unsigned long flags;
 
@@ -428,24 +431,26 @@ void __init sni_rm200_i8259_irqs(void)
 #define SNI_RM200_INT_START  24
 #define SNI_RM200_INT_END    28
 
-static void enable_rm200_irq(unsigned int irq)
+static void enable_rm200_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
 
 	*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
 }
 
-void disable_rm200_irq(unsigned int irq)
+void disable_rm200_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
 
 	*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
 }
 
-void end_rm200_irq(unsigned int irq)
+void end_rm200_irq(struct irq_desc *desc)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_rm200_irq(irq);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_rm200_irq(desc);
 }
 
 static struct irq_chip rm200_irq_type = {
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
index 013213a..e66f101 100644
--- a/arch/mips/txx9/generic/irq_tx4939.c
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -49,8 +49,9 @@ static struct {
 	unsigned char mode;
 } tx4939irq[TX4939_NUM_IR] __read_mostly;
 
-static void tx4939_irq_unmask(unsigned int irq)
+static void tx4939_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *lvlp;
 	int ofs;
@@ -67,8 +68,9 @@ static void tx4939_irq_unmask(unsigned int irq)
 		     lvlp);
 }
 
-static inline void tx4939_irq_mask(unsigned int irq)
+static inline void tx4939_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 __iomem *lvlp;
 	int ofs;
@@ -86,11 +88,12 @@ static inline void tx4939_irq_mask(unsigned int irq)
 	mmiowb();
 }
 
-static void tx4939_irq_mask_ack(unsigned int irq)
+static void tx4939_irq_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 
-	tx4939_irq_mask(irq);
+	tx4939_irq_mask(desc);
 	if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
 		irq_nr--;
 		/* clear edge detection */
@@ -100,8 +103,9 @@ static void tx4939_irq_mask_ack(unsigned int irq)
 	}
 }
 
-static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int tx4939_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int irq = desc->irq;
 	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
 	u32 cr;
 	u32 __iomem *crp;
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
index 6ec626c..b613c2e 100644
--- a/arch/mips/txx9/jmr3927/irq.c
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -46,8 +46,9 @@
  * CP0_STATUS is a thread's resource (saved/restored on context switch).
  * So disable_irq/enable_irq MUST handle IOC/IRC registers.
  */
-static void mask_irq_ioc(unsigned int irq)
+static void mask_irq_ioc(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* 0: mask */
 	unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
 	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
@@ -56,8 +57,9 @@ static void mask_irq_ioc(unsigned int irq)
 	/* flush write buffer */
 	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
 }
-static void unmask_irq_ioc(unsigned int irq)
+static void unmask_irq_ioc(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* 0: mask */
 	unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
 	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
index 9c14ebb..136ae1e 100644
--- a/arch/mips/txx9/rbtx4927/irq.c
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -116,8 +116,8 @@
 #include <asm/txx9/generic.h>
 #include <asm/txx9/rbtx4927.h>
 
-static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
-static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_enable(struct irq_desc *desc);
+static void toshiba_rbtx4927_irq_ioc_disable(struct irq_desc *desc);
 
 #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
 static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
@@ -154,8 +154,9 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void)
 	set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
 }
 
-static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
+static void toshiba_rbtx4927_irq_ioc_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4927_imask_addr);
@@ -163,8 +164,9 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
 	writeb(v, rbtx4927_imask_addr);
 }
 
-static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
+static void toshiba_rbtx4927_irq_ioc_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4927_imask_addr);
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
index 7d21bef..92cdda6 100644
--- a/arch/mips/txx9/rbtx4938/irq.c
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -68,8 +68,8 @@
 #include <asm/txx9/generic.h>
 #include <asm/txx9/rbtx4938.h>
 
-static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
-static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_enable(struct irq_desc *desc);
+static void toshiba_rbtx4938_irq_ioc_disable(struct irq_desc *desc);
 
 #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
 static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
@@ -105,8 +105,9 @@ toshiba_rbtx4938_irq_ioc_init(void)
 }
 
 static void
-toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
+toshiba_rbtx4938_irq_ioc_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4938_imask_addr);
@@ -116,8 +117,9 @@ toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
 }
 
 static void
-toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
+toshiba_rbtx4938_irq_ioc_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char v;
 
 	v = readb(rbtx4938_imask_addr);
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
index 500cc0a..c3798f5 100644
--- a/arch/mips/txx9/rbtx4939/irq.c
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -18,15 +18,17 @@
  * RBTX4939 IOC controller definition
  */
 
-static void rbtx4939_ioc_irq_unmask(unsigned int irq)
+static void rbtx4939_ioc_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ioc_nr = irq - RBTX4939_IRQ_IOC;
 
 	writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
 }
 
-static void rbtx4939_ioc_irq_mask(unsigned int irq)
+static void rbtx4939_ioc_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	int ioc_nr = irq - RBTX4939_IRQ_IOC;
 
 	writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
index 6153b6a..cc042eb 100644
--- a/arch/mips/vr41xx/common/icu.c
+++ b/arch/mips/vr41xx/common/icu.c
@@ -442,13 +442,15 @@ void vr41xx_disable_bcuint(void)
 
 EXPORT_SYMBOL(vr41xx_disable_bcuint);
 
-static void disable_sysint1_irq(unsigned int irq)
+static void disable_sysint1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
-static void enable_sysint1_irq(unsigned int irq)
+static void enable_sysint1_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
@@ -460,13 +462,15 @@ static struct irq_chip sysint1_irq_type = {
 	.unmask		= enable_sysint1_irq,
 };
 
-static void disable_sysint2_irq(unsigned int irq)
+static void disable_sysint2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
-static void enable_sysint2_irq(unsigned int irq)
+static void enable_sysint2_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index bef0687..c60b2fc 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -74,10 +74,10 @@ static void irq_dispatch(unsigned int irq)
 		int ret;
 		desc = irq_desc + source_irq;
 		if (desc->chip->mask_ack)
-			desc->chip->mask_ack(source_irq);
+			desc->chip->mask_ack(desc);
 		else {
-			desc->chip->mask(source_irq);
-			desc->chip->ack(source_irq);
+			desc->chip->mask(desc);
+			desc->chip->ack(desc);
 		}
 		ret = cascade->get_irq(irq);
 		irq = ret;
@@ -86,7 +86,7 @@ static void irq_dispatch(unsigned int irq)
 		else
 			irq_dispatch(irq);
 		if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-			desc->chip->unmask(source_irq);
+			desc->chip->unmask(desc);
 	} else
 		do_IRQ(irq);
 }
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index bc98665..ccae1ad 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -22,36 +22,45 @@ atomic_t irq_err_count;
 /*
  * MN10300 interrupt controller operations
  */
-static void mn10300_cpupic_ack(unsigned int irq)
+static void mn10300_cpupic_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp;
 	*(volatile u8 *) &GxICR(irq) = GxICR_DETECT;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_mask(unsigned int irq)
+static void mn10300_cpupic_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL);
 	tmp = GxICR(irq);
 }
+static void mn10300_cpupic_mask_desc(struct irq_desc *desc)
+{
+	mn10300_cpupic_mask(desc);
+}
 
-static void mn10300_cpupic_mask_ack(unsigned int irq)
+static void mn10300_cpupic_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_unmask(unsigned int irq)
+static void mn10300_cpupic_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp = GxICR(irq);
 	GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
 	tmp = GxICR(irq);
 }
 
-static void mn10300_cpupic_unmask_clear(unsigned int irq)
+static void mn10300_cpupic_unmask_clear(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	/* the MN10300 PIC latches its interrupt request bit, even after the
 	 * device has ceased to assert its interrupt line and the interrupt
 	 * channel has been disabled in the PIC, so for level-triggered
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index ef34d5a..8cb05fe 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -325,14 +325,15 @@ struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {
  * note that we can't just leave the line enabled as the baud rate timer *also*
  * generates interrupts
  */
-static void mn10300_serial_mask_ack(unsigned int irq)
+static void mn10300_serial_mask_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u16 tmp;
 	GxICR(irq) = GxICR_LEVEL_6;
 	tmp = GxICR(irq); /* flush write buffer */
 }
 
-static void mn10300_serial_nop(unsigned int irq)
+static void mn10300_serial_nop(struct irq_desc *desc)
 {
 }
 
diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h
index dfa26b6..2a6516c 100644
--- a/arch/parisc/include/asm/irq.h
+++ b/arch/parisc/include/asm/irq.h
@@ -37,10 +37,11 @@ struct irq_chip;
  * Some useful "we don't have to do anything here" handlers.  Should
  * probably be provided by the generic code.
  */
-void no_ack_irq(unsigned int irq);
-void no_end_irq(unsigned int irq);
-void cpu_ack_irq(unsigned int irq);
-void cpu_end_irq(unsigned int irq);
+struct irq_desc;
+void no_ack_irq(struct irq_desc *desc);
+void no_end_irq(struct irq_desc *desc);
+void cpu_ack_irq(struct irq_desc *desc);
+void cpu_end_irq(struct irq_desc *desc);
 
 extern int txn_alloc_irq(unsigned int nbits);
 extern int txn_claim_irq(int);
@@ -49,7 +50,7 @@ extern unsigned long txn_alloc_addr(unsigned int);
 extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 
 extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
-extern int cpu_check_affinity(unsigned int irq, const struct cpumask *dest);
+extern int cpu_check_affinity(struct irq_desc *desc, const struct cpumask *dest);
 
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index efbcee5..bc47d05 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -52,8 +52,9 @@ static volatile unsigned long cpu_eiem = 0;
 */
 static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
 
-static void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem &= ~eirr_bit;
@@ -63,8 +64,9 @@ static void cpu_disable_irq(unsigned int irq)
 	 * then gets disabled */
 }
 
-static void cpu_enable_irq(unsigned int irq)
+static void cpu_enable_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem |= eirr_bit;
@@ -75,17 +77,18 @@ static void cpu_enable_irq(unsigned int irq)
 	smp_send_all_nop();
 }
 
-static unsigned int cpu_startup_irq(unsigned int irq)
+static unsigned int cpu_startup_irq(struct irq_desc *desc)
 {
-	cpu_enable_irq(irq);
+	cpu_enable_irq(desc);
 	return 0;
 }
 
-void no_ack_irq(unsigned int irq) { }
-void no_end_irq(unsigned int irq) { }
+void no_ack_irq(struct irq_desc *desc) { }
+void no_end_irq(struct irq_desc *desc) { }
 
-void cpu_ack_irq(unsigned int irq)
+void cpu_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = EIEM_MASK(irq);
 	int cpu = smp_processor_id();
 
@@ -99,8 +102,9 @@ void cpu_ack_irq(unsigned int irq)
 	mtctl(mask, 23);
 }
 
-void cpu_end_irq(unsigned int irq)
+void cpu_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long mask = EIEM_MASK(irq);
 	int cpu = smp_processor_id();
 
@@ -112,15 +116,16 @@ void cpu_end_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
+int cpu_check_affinity(struct irq_desc *desc, const struct cpumask *dest)
 {
+	unsigned int irq = desc->irq;
 	int cpu_dest;
 
 	/* timer and ipi have to always be received on all CPUs */
 	if (CHECK_IRQ_PER_CPU(irq)) {
 		/* Bad linux design decision.  The mask has already
 		 * been set; we must reset it */
-		cpumask_setall(irq_desc[irq].affinity);
+		cpumask_setall(desc->affinity);
 		return -EINVAL;
 	}
 
@@ -130,15 +135,15 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
 	return cpu_dest;
 }
 
-static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
+static int cpu_set_affinity_irq(struct irq_desc *desc, const struct cpumask *dest)
 {
 	int cpu_dest;
 
-	cpu_dest = cpu_check_affinity(irq, dest);
+	cpu_dest = cpu_check_affinity(desc, dest);
 	if (cpu_dest < 0)
 		return -1;
 
-	cpumask_copy(irq_desc[irq].affinity, dest);
+	cpumask_copy(desc->affinity, dest);
 
 	return 0;
 }
@@ -242,15 +247,17 @@ int show_interrupts(struct seq_file *p, void *v)
 
 int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 {
-	if (irq_desc[irq].action)
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (desc->action)
 		return -EBUSY;
-	if (irq_desc[irq].chip != &cpu_interrupt_type)
+	if (desc->chip != &cpu_interrupt_type)
 		return -EBUSY;
 
 	if (type) {
-		irq_desc[irq].chip = type;
-		irq_desc[irq].chip_data = data;
-		cpu_interrupt_type.enable(irq);
+		desc->chip = type;
+		desc->chip_data = data;
+		cpu_interrupt_type.enable(desc);
 	}
 	return 0;
 }
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 61913d9..7f56770 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -470,11 +470,11 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
 void smp_mpic_message_pass(int target, int msg);
 
 /* Unmask a specific virq */
-extern void mpic_unmask_irq(unsigned int irq);
+extern void mpic_unmask_irq(struct irq_desc *desc);
 /* Mask a specific virq */
-extern void mpic_mask_irq(unsigned int irq);
+extern void mpic_mask_irq(struct irq_desc *desc);
 /* EOI a specific virq */
-extern void mpic_end_irq(unsigned int irq);
+extern void mpic_end_irq(struct irq_desc *desc);
 
 /* Fetch interrupt from a given mpic */
 extern unsigned int mpic_get_one_irq(struct mpic *mpic);
diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h
index cf51966..ffd0086 100644
--- a/arch/powerpc/include/asm/qe_ic.h
+++ b/arch/powerpc/include/asm/qe_ic.h
@@ -107,7 +107,7 @@ static inline void qe_ic_cascade_low_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static inline void qe_ic_cascade_high_mpic(unsigned int irq,
@@ -119,7 +119,7 @@ static inline void qe_ic_cascade_high_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
@@ -135,7 +135,7 @@ static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* _ASM_POWERPC_QE_IC_H */
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 6f4613d..e5ccfb2 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -376,10 +376,10 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
 		struct irq_desc *desc = irq_to_desc(i);
 
 		if (desc->status & IRQ_INPROGRESS)
-			desc->chip->eoi(i);
+			desc->chip->eoi(desc);
 
 		if (!(desc->status & IRQ_DISABLED))
-			desc->chip->disable(i);
+			desc->chip->disable(desc);
 	}
 
 	/*
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index cafd378..bc7a593 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -309,7 +309,7 @@ void fixup_irqs(cpumask_t map)
 			mask = map;
 		}
 		if (desc->chip->set_affinity)
-			desc->chip->set_affinity(irq, &mask);
+			desc->chip->set_affinity(desc, &mask);
 		else if (desc->action && !(warned++))
 			printk("Cannot set affinity for irq %i\n", irq);
 	}
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 4ecf4cf..d754acd 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -59,8 +59,9 @@ irq_to_pic_bit(unsigned int irq)
 }
 
 static void
-cpld_mask_irq(unsigned int irq)
+cpld_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
@@ -69,8 +70,9 @@ cpld_mask_irq(unsigned int irq)
 }
 
 static void
-cpld_unmask_irq(unsigned int irq)
+cpld_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 0bac3a3..948a09d 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -49,26 +49,28 @@ struct media5200_irq {
 };
 struct media5200_irq media5200_irq;
 
-static void media5200_irq_unmask(unsigned int virq)
+static void media5200_irq_unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 val;
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
+	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[irq].hwirq);
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
 
-static void media5200_irq_mask(unsigned int virq)
+static void media5200_irq_mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	u32 val;
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
+	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[irq].hwirq));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
@@ -87,7 +89,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	/* Mask off the cascaded IRQ */
 	raw_spin_lock(&desc->lock);
-	desc->chip->mask(virq);
+	desc->chip->mask(desc);
 	raw_spin_unlock(&desc->lock);
 
 	/* Ask the FPGA for IRQ status.  If 'val' is 0, then no irqs
@@ -105,9 +107,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	/* Processing done; can reenable the cascade now */
 	raw_spin_lock(&desc->lock);
-	desc->chip->ack(virq);
+	desc->chip->ack(desc);
 	if (!(desc->status & IRQ_DISABLED))
-		desc->chip->unmask(virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 5d7cc88..5de11ef 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -133,9 +133,10 @@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
  * Cascaded interrupt controller hooks
  */
 
-static void mpc52xx_gpt_irq_unmask(unsigned int virq)
+static void mpc52xx_gpt_irq_unmask(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&gpt->lock, flags);
@@ -143,9 +144,10 @@ static void mpc52xx_gpt_irq_unmask(unsigned int virq)
 	spin_unlock_irqrestore(&gpt->lock, flags);
 }
 
-static void mpc52xx_gpt_irq_mask(unsigned int virq)
+static void mpc52xx_gpt_irq_mask(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	spin_lock_irqsave(&gpt->lock, flags);
@@ -153,16 +155,18 @@ static void mpc52xx_gpt_irq_mask(unsigned int virq)
 	spin_unlock_irqrestore(&gpt->lock, flags);
 }
 
-static void mpc52xx_gpt_irq_ack(unsigned int virq)
+static void mpc52xx_gpt_irq_ack(struct irq_desc *desc)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 
 	out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
 }
 
-static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_gpt_irq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct mpc52xx_gpt_priv *gpt = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 	u32 reg;
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 4bf4bf7..bee1838 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -155,8 +155,9 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
 /*
  * IRQ[0-3] interrupt irq_chip
  */
-static void mpc52xx_extirq_mask(unsigned int virq)
+static void mpc52xx_extirq_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -166,8 +167,9 @@ static void mpc52xx_extirq_mask(unsigned int virq)
 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
 }
 
-static void mpc52xx_extirq_unmask(unsigned int virq)
+static void mpc52xx_extirq_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -177,8 +179,9 @@ static void mpc52xx_extirq_unmask(unsigned int virq)
 	io_be_setbit(&intr->ctrl, 11 - l2irq);
 }
 
-static void mpc52xx_extirq_ack(unsigned int virq)
+static void mpc52xx_extirq_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -188,8 +191,9 @@ static void mpc52xx_extirq_ack(unsigned int virq)
 	io_be_setbit(&intr->ctrl, 27-l2irq);
 }
 
-static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_extirq_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	u32 ctrl_reg, type;
 	int irq;
 	int l2irq;
@@ -230,13 +234,14 @@ static struct irq_chip mpc52xx_extirq_irqchip = {
 /*
  * Main interrupt irq_chip
  */
-static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
+static int mpc52xx_null_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
 	return 0; /* Do nothing so that the sense mask will get updated */
 }
 
-static void mpc52xx_main_mask(unsigned int virq)
+static void mpc52xx_main_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -246,8 +251,9 @@ static void mpc52xx_main_mask(unsigned int virq)
 	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
-static void mpc52xx_main_unmask(unsigned int virq)
+static void mpc52xx_main_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -268,8 +274,9 @@ static struct irq_chip mpc52xx_main_irqchip = {
 /*
  * Peripherals interrupt irq_chip
  */
-static void mpc52xx_periph_mask(unsigned int virq)
+static void mpc52xx_periph_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -279,8 +286,9 @@ static void mpc52xx_periph_mask(unsigned int virq)
 	io_be_setbit(&intr->per_mask, 31 - l2irq);
 }
 
-static void mpc52xx_periph_unmask(unsigned int virq)
+static void mpc52xx_periph_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -301,8 +309,9 @@ static struct irq_chip mpc52xx_periph_irqchip = {
 /*
  * SDMA interrupt irq_chip
  */
-static void mpc52xx_sdma_mask(unsigned int virq)
+static void mpc52xx_sdma_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -312,8 +321,9 @@ static void mpc52xx_sdma_mask(unsigned int virq)
 	io_be_setbit(&sdma->IntMask, l2irq);
 }
 
-static void mpc52xx_sdma_unmask(unsigned int virq)
+static void mpc52xx_sdma_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
@@ -323,8 +333,9 @@ static void mpc52xx_sdma_unmask(unsigned int virq)
 	io_be_clrbit(&sdma->IntMask, l2irq);
 }
 
-static void mpc52xx_sdma_ack(unsigned int virq)
+static void mpc52xx_sdma_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq;
 	int l2irq;
 
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index d4a09f8..a44214d 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -38,8 +38,9 @@ struct pq2ads_pci_pic {
 
 #define NUM_IRQS 32
 
-static void pq2ads_pci_mask_irq(unsigned int virq)
+static void pq2ads_pci_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
 	int irq = NUM_IRQS - virq_to_hw(virq) - 1;
 
@@ -54,8 +55,9 @@ static void pq2ads_pci_mask_irq(unsigned int virq)
 	}
 }
 
-static void pq2ads_pci_unmask_irq(unsigned int virq)
+static void pq2ads_pci_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
 	int irq = NUM_IRQS - virq_to_hw(virq) - 1;
 
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
index f4d36b5..c6f4825 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -61,7 +61,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init ksi8560_pic_init(void)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 9438a89..833ab1c 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -55,7 +55,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 544011a..c27ce8a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -52,7 +52,7 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	if (cascade_irq != NO_IRQ) {
 		generic_handle_irq(cascade_irq);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif	/* CONFIG_PPC_I8259 */
 
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index a5ad1c7..b66dd9f 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -46,7 +46,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 #endif /* CONFIG_CPM2 */
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index d48527f..c8a131a 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -103,12 +103,13 @@ void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
 
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 
 }
 
-static void socrates_fpga_pic_ack(unsigned int virq)
+static void socrates_fpga_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq, irq_line;
 	uint32_t mask;
@@ -124,8 +125,9 @@ static void socrates_fpga_pic_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_mask(unsigned int virq)
+static void socrates_fpga_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -142,8 +144,9 @@ static void socrates_fpga_pic_mask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_mask_ack(unsigned int virq)
+static void socrates_fpga_pic_mask_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -161,8 +164,9 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_unmask(unsigned int virq)
+static void socrates_fpga_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -179,8 +183,9 @@ static void socrates_fpga_pic_unmask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static void socrates_fpga_pic_eoi(unsigned int virq)
+static void socrates_fpga_pic_eoi(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int irq_line;
@@ -197,9 +202,10 @@ static void socrates_fpga_pic_eoi(unsigned int virq)
 	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
-static int socrates_fpga_pic_set_type(unsigned int virq,
+static int socrates_fpga_pic_set_type(struct irq_desc *desc,
 		unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	int polarity;
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index bc33d18..cfea131 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -51,7 +51,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif /* CONFIG_CPM2 */
 
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 5b0ab99..462cc1d 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -49,7 +49,7 @@ static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 	while ((cascade_irq = cpm2_get_irq()) >= 0)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif /* CONFIG_CPM2 */
 
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 6df9e25..7af4ad4 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -106,12 +106,13 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 
 }
 
-static void gef_pic_mask(unsigned int virq)
+static void gef_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	u32 mask;
@@ -125,16 +126,17 @@ static void gef_pic_mask(unsigned int virq)
 	raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
 }
 
-static void gef_pic_mask_ack(unsigned int virq)
+static void gef_pic_mask_ack(struct irq_desc *desc)
 {
 	/* Don't think we actually have to do anything to ack an interrupt,
 	 * we just need to clear down the devices interrupt and it will go away
 	 */
-	gef_pic_mask(virq);
+	gef_pic_mask(desc);
 }
 
-static void gef_pic_unmask(unsigned int virq)
+static void gef_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int hwirq;
 	u32 mask;
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
index 668275d..4cdaf8a 100644
--- a/arch/powerpc/platforms/86xx/pic.c
+++ b/arch/powerpc/platforms/86xx/pic.c
@@ -22,7 +22,7 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 #endif	/* CONFIG_PPC_I8259 */
 
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 242954c..f1ec06b 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -225,9 +225,9 @@ static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
 		struct irq_desc *cdesc = irq_to_desc(cascade_irq);
 
 		generic_handle_irq(cascade_irq);
-		cdesc->chip->eoi(cascade_irq);
+		cdesc->chip->eoi(cdesc);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /* Initialize the internal interrupt controllers.  The number of
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 96fe896..64578d4 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -144,7 +144,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 		msic->read_offset &= MSIC_FIFO_SIZE_MASK;
 	}
 
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static struct axon_msic *find_msi_translator(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 682af97..fdb1c60 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -61,8 +61,9 @@ static inline void beatic_update_irq_mask(unsigned int irq_plug)
 		panic("Failed to set mask IRQ!");
 }
 
-static void beatic_mask_irq(unsigned int irq_plug)
+static void beatic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -71,8 +72,9 @@ static void beatic_mask_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_unmask_irq(unsigned int irq_plug)
+static void beatic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -81,8 +83,9 @@ static void beatic_unmask_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_ack_irq(unsigned int irq_plug)
+static void beatic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
@@ -91,8 +94,9 @@ static void beatic_ack_irq(unsigned int irq_plug)
 	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
-static void beatic_end_irq(unsigned int irq_plug)
+static void beatic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq_plug = desc->irq;
 	s64 err;
 	unsigned long flags;
 
@@ -232,7 +236,7 @@ unsigned int beatic_get_irq(void)
 
 	ret = beatic_get_irq_plug();
 	if (ret != NO_IRQ)
-		beatic_ack_irq(ret);
+		beatic_ack_irq(irq_to_desc(ret));
 	return ret;
 }
 
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 10eb1a4..2ea5935 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -72,15 +72,15 @@ static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
 		return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
 }
 
-static void iic_mask(unsigned int irq)
+static void iic_mask(struct irq_desc *desc)
 {
 }
 
-static void iic_unmask(unsigned int irq)
+static void iic_unmask(struct irq_desc *desc)
 {
 }
 
-static void iic_eoi(unsigned int irq)
+static void iic_eoi(struct irq_desc *desc)
 {
 	struct iic *iic = &__get_cpu_var(cpu_iic);
 	out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
@@ -95,7 +95,7 @@ static struct irq_chip iic_chip = {
 };
 
 
-static void iic_ioexc_eoi(unsigned int irq)
+static void iic_ioexc_eoi(struct irq_desc *desc)
 {
 }
 
@@ -128,7 +128,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
 		if (ack)
 			out_be64(&node_iic->iic_is, ack);
 	}
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 
@@ -275,7 +275,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
 
 	desc->status &= ~IRQ_INPROGRESS;
 out_eoi:
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 5930536..7ca342c 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -182,7 +182,7 @@ static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
 	virq = mpic_get_one_irq(mpic);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init mpic_init_IRQ(void)
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 5876e88..d80fd72 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -79,24 +79,27 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
 	return pic->regs + TIR_CFGA + 8 * src;
 }
 
-static void spider_unmask_irq(unsigned int virq)
+static void spider_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
 
 	out_be32(cfg, in_be32(cfg) | 0x30000000u);
 }
 
-static void spider_mask_irq(unsigned int virq)
+static void spider_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
 
 	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
 }
 
-static void spider_ack_irq(unsigned int virq)
+static void spider_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -113,13 +116,13 @@ static void spider_ack_irq(unsigned int virq)
 	out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
 }
 
-static int spider_set_irq_type(unsigned int virq, unsigned int type)
+static int spider_set_irq_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int virq = desc->irq;
 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	unsigned int hw = irq_map[virq].hwirq;
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
-	struct irq_desc *desc = irq_to_desc(virq);
 	u32 old_mask;
 	u32 ic;
 
@@ -217,7 +220,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
 		virq = irq_linear_revmap(pic->host, cs);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /* For hooking up the cascace we have a problem. Our device-tree is
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 8f41685..cab9626 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -369,7 +369,7 @@ static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 /*
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index c278bd3..74d93d8 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -46,8 +46,9 @@
  *
  */
 
-static void flipper_pic_mask_and_ack(unsigned int virq)
+static void flipper_pic_mask_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 	u32 mask = 1 << irq;
@@ -57,8 +58,9 @@ static void flipper_pic_mask_and_ack(unsigned int virq)
 	out_be32(io_base + FLIPPER_ICR, mask);
 }
 
-static void flipper_pic_ack(unsigned int virq)
+static void flipper_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
@@ -66,16 +68,18 @@ static void flipper_pic_ack(unsigned int virq)
 	out_be32(io_base + FLIPPER_ICR, 1 << irq);
 }
 
-static void flipper_pic_mask(unsigned int virq)
+static void flipper_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
 	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
 }
 
-static void flipper_pic_unmask(unsigned int virq)
+static void flipper_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
 	void __iomem *io_base = get_irq_chip_data(virq);
 
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index a771f91..58628f7 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -41,36 +41,40 @@
  *
  */
 
-static void hlwd_pic_mask_and_ack(unsigned int virq)
+static void hlwd_pic_mask_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 	u32 mask = 1 << irq;
 
 	clrbits32(io_base + HW_BROADWAY_IMR, mask);
 	out_be32(io_base + HW_BROADWAY_ICR, mask);
 }
 
-static void hlwd_pic_ack(unsigned int virq)
+static void hlwd_pic_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
 }
 
-static void hlwd_pic_mask(unsigned int virq)
+static void hlwd_pic_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
 }
 
-static void hlwd_pic_unmask(unsigned int virq)
+static void hlwd_pic_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void __iomem *io_base = get_irq_chip_data(virq);
+	void __iomem *io_base = get_irq_desc_chip_data(desc);
 
 	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
 }
@@ -133,7 +137,7 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 	unsigned int virq;
 
 	raw_spin_lock(&desc->lock);
-	desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
+	desc->chip->mask(desc); /* IRQ_LEVEL */
 	raw_spin_unlock(&desc->lock);
 
 	virq = __hlwd_pic_get_irq(irq_host);
@@ -143,9 +147,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 		pr_err("spurious interrupt!\n");
 
 	raw_spin_lock(&desc->lock);
-	desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
+	desc->chip->ack(desc); /* IRQ_LEVEL */
 	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-		desc->chip->unmask(cascade_virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index ba446bf..8f64743 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -167,8 +167,9 @@ static void pci_event_handler(struct HvLpEvent *event)
  * This will be called by device drivers (via enable_IRQ)
  * to enable INTA in the bridge interrupt status register.
  */
-static void iseries_enable_IRQ(unsigned int irq)
+static void iseries_enable_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -184,8 +185,9 @@ static void iseries_enable_IRQ(unsigned int irq)
 }
 
 /* This is called by iseries_activate_IRQs */
-static unsigned int iseries_startup_IRQ(unsigned int irq)
+static unsigned int iseries_startup_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -200,7 +202,7 @@ static unsigned int iseries_startup_IRQ(unsigned int irq)
 	/* Unmask bridge interrupts in the FISR */
 	mask = 0x01010000 << function;
 	HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
-	iseries_enable_IRQ(irq);
+	iseries_enable_IRQ(desc);
 	return 0;
 }
 
@@ -218,15 +220,16 @@ void __init iSeries_activate_IRQs()
 
 		if (desc && desc->chip && desc->chip->startup) {
 			raw_spin_lock_irqsave(&desc->lock, flags);
-			desc->chip->startup(irq);
+			desc->chip->startup(desc);
 			raw_spin_unlock_irqrestore(&desc->lock, flags);
 		}
 	}
 }
 
 /*  this is not called anywhere currently */
-static void iseries_shutdown_IRQ(unsigned int irq)
+static void iseries_shutdown_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -248,8 +251,9 @@ static void iseries_shutdown_IRQ(unsigned int irq)
  * This will be called by device drivers (via disable_IRQ)
  * to disable INTA in the bridge interrupt status register.
  */
-static void iseries_disable_IRQ(unsigned int irq)
+static void iseries_disable_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
@@ -264,8 +268,9 @@ static void iseries_disable_IRQ(unsigned int irq)
 	HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask);
 }
 
-static void iseries_end_IRQ(unsigned int irq)
+static void iseries_end_IRQ(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
 
 	HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 242f809..98a3573 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -239,7 +239,7 @@ static __init void pas_init_IRQ(void)
 		nmi_virq = irq_create_mapping(NULL, *nmiprop);
 		mpic_irq_set_priority(nmi_virq, 15);
 		set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
-		mpic_unmask_irq(nmi_virq);
+		mpic_unmask_irq(irq_to_desc(nmi_virq));
 	}
 
 	of_node_put(mpic_node);
@@ -265,7 +265,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
 	if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
 		printk(KERN_ERR "NMI delivered\n");
 		debugger(regs);
-		mpic_end_irq(nmi_virq);
+		mpic_end_irq(irq_to_desc(nmi_virq));
 		goto out;
 	}
 
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 630a533..5737fae 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -25,6 +25,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/module.h>
+#include <linux/irq.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
@@ -78,8 +79,9 @@ static void __pmac_retrigger(unsigned int irq_nr)
 	}
 }
 
-static void pmac_mask_and_ack_irq(unsigned int virq)
+static void pmac_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
@@ -100,8 +102,9 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_ack_irq(unsigned int virq)
+static void pmac_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
@@ -145,8 +148,9 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
 /* When an irq gets requested for the first client, if it's an
  * edge interrupt, we clear any previous one on the controller
  */
-static unsigned int pmac_startup_irq(unsigned int virq)
+static unsigned int pmac_startup_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
         unsigned long bit = 1UL << (src & 0x1f);
@@ -162,8 +166,9 @@ static unsigned int pmac_startup_irq(unsigned int virq)
 	return 0;
 }
 
-static void pmac_mask_irq(unsigned int virq)
+static void pmac_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -173,8 +178,9 @@ static void pmac_mask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_unmask_irq(unsigned int virq)
+static void pmac_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
@@ -184,8 +190,9 @@ static void pmac_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static int pmac_retrigger(unsigned int virq)
+static int pmac_retrigger(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
@@ -437,7 +444,7 @@ static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = mpic_get_one_irq(mpic);
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
@@ -647,7 +654,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
 	mb();
 	for (i = 0; i < max_real_irqs; ++i)
 		if (test_bit(i, sleep_save_mask))
-			pmac_unmask_irq(i);
+			pmac_unmask_irq(irq_do_desc(i));
 
 	return 0;
 }
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 59d9712..024680f 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -99,9 +99,10 @@ static DEFINE_PER_CPU(struct ps3_private, ps3_private);
  * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
  */
 
-static void ps3_chip_mask(unsigned int virq)
+static void ps3_chip_mask(struct irq_desc *desc)
 {
-	struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
@@ -120,9 +121,10 @@ static void ps3_chip_mask(unsigned int virq)
  * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
  */
 
-static void ps3_chip_unmask(unsigned int virq)
+static void ps3_chip_unmask(struct irq_desc *desc)
 {
-	struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	unsigned long flags;
 
 	pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
@@ -141,9 +143,10 @@ static void ps3_chip_unmask(unsigned int virq)
  * Calls lv1_end_of_interrupt_ext().
  */
 
-static void ps3_chip_eoi(unsigned int virq)
+static void ps3_chip_eoi(struct irq_desc *desc)
 {
-	const struct ps3_private *pd = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct ps3_private *pd = get_irq_desc_chip_data(desc);
 	lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
 }
 
@@ -202,7 +205,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_set;
 	}
 
-	ps3_chip_mask(*virq);
+	ps3_chip_mask(irq_to_desc(*virq));
 
 	return result;
 
@@ -296,7 +299,7 @@ int ps3_irq_plug_destroy(unsigned int virq)
 	pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
 		__LINE__, pd->ppe_id, pd->thread_id, virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
 
@@ -357,7 +360,7 @@ int ps3_event_receive_port_destroy(unsigned int virq)
 
 	pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
@@ -492,7 +495,7 @@ int ps3_io_irq_destroy(unsigned int virq)
 	int result;
 	unsigned long outlet = virq_to_hw(virq);
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	/*
 	 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
@@ -553,7 +556,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 	result = lv1_deconfigure_virtual_uart_irq();
 
 	if (result) {
@@ -605,7 +608,7 @@ int ps3_spe_irq_destroy(unsigned int virq)
 {
 	int result;
 
-	ps3_chip_mask(virq);
+	ps3_chip_mask(irq_to_desc(virq));
 
 	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ca5f2e1..056fecb 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -118,7 +118,7 @@ static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = i8259_irq();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
 
 static void __init pseries_setup_i8259_cascade(void)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 1bcedd8..e51f3d8 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -194,8 +194,9 @@ static int get_irq_server(unsigned int virq, cpumask_t cpumask,
 #define get_irq_server(virq, cpumask, strict_check) (default_server)
 #endif
 
-static void xics_unmask_irq(unsigned int virq)
+static void xics_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 	int call_status;
 	int server;
@@ -227,18 +228,18 @@ static void xics_unmask_irq(unsigned int virq)
 	}
 }
 
-static unsigned int xics_startup(unsigned int virq)
+static unsigned int xics_startup(struct irq_desc *desc)
 {
 	/*
 	 * The generic MSI code returns with the interrupt disabled on the
 	 * card, using the MSI mask bits. Firmware doesn't appear to unmask
 	 * at that level, so we do it here by hand.
 	 */
-	if (irq_to_desc(virq)->msi_desc)
-		unmask_msi_irq(virq);
+	if (desc->msi_desc)
+		unmask_msi_irq(desc);
 
 	/* unmask it */
-	xics_unmask_irq(virq);
+	xics_unmask_irq(desc);
 	return 0;
 }
 
@@ -266,8 +267,9 @@ static void xics_mask_real_irq(unsigned int irq)
 	}
 }
 
-static void xics_mask_irq(unsigned int virq)
+static void xics_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 
 	pr_devel("xics: mask virq %d\n", virq);
@@ -363,24 +365,27 @@ static unsigned char pop_cppr(void)
 	return os_cppr->stack[--os_cppr->index];
 }
 
-static void xics_eoi_direct(unsigned int virq)
+static void xics_eoi_direct(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
 	direct_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
-static void xics_eoi_lpar(unsigned int virq)
+static void xics_eoi_lpar(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
 	lpar_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
-static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
+static int xics_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int virq = desc->irq;
 	unsigned int irq;
 	int status;
 	int xics_status[2];
@@ -930,8 +935,8 @@ void xics_migrate_irqs_away(void)
 		       virq, cpu);
 
 		/* Reset affinity to all cpus */
-		cpumask_setall(irq_to_desc(virq)->affinity);
-		desc->chip->set_affinity(virq, cpu_all_mask);
+		cpumask_setall(desc->affinity);
+		desc->chip->set_affinity(desc, cpu_all_mask);
 unlock:
 		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index ecad10d..5848b07 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -55,22 +55,25 @@ static cpic8xx_t __iomem *cpic_reg;
 
 static struct irq_host *cpm_pic_host;
 
-static void cpm_mask_irq(unsigned int irq)
+static void cpm_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
-static void cpm_unmask_irq(unsigned int irq)
+static void cpm_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
-static void cpm_end_irq(unsigned int irq)
+static void cpm_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
 
 	out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index fcea4ff..ec59695 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -78,8 +78,9 @@ static const u_char irq_to_siubit[] = {
 	24, 25, 26, 27, 28, 29, 30, 31,
 };
 
-static void cpm2_mask_irq(unsigned int virq)
+static void cpm2_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -90,8 +91,9 @@ static void cpm2_mask_irq(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
 }
 
-static void cpm2_unmask_irq(unsigned int virq)
+static void cpm2_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -102,8 +104,9 @@ static void cpm2_unmask_irq(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
 }
 
-static void cpm2_ack(unsigned int virq)
+static void cpm2_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
@@ -113,13 +116,12 @@ static void cpm2_ack(unsigned int virq)
 	out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
 }
 
-static void cpm2_end_irq(unsigned int virq)
+static void cpm2_end_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc;
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
-	desc = irq_to_desc(irq_nr);
 	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
 			&& desc->action) {
 
@@ -137,10 +139,10 @@ static void cpm2_end_irq(unsigned int virq)
 	}
 }
 
-static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int cpm2_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	unsigned int src = virq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
 	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index e094367..14c3286 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -39,7 +39,7 @@ static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
  * We do not need this actually. The MSIR register has been read once
  * in the cascade interrupt. So, this MSI interrupt has been acked
 */
-static void fsl_msi_end_irq(unsigned int virq)
+static void fsl_msi_end_irq(struct irq_desc *desc)
 {
 }
 
@@ -176,10 +176,10 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 	raw_spin_lock(&desc->lock);
 	if ((msi_data->feature &  FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
 		if (desc->chip->mask_ack)
-			desc->chip->mask_ack(irq);
+			desc->chip->mask_ack(desc);
 		else {
-			desc->chip->mask(irq);
-			desc->chip->ack(irq);
+			desc->chip->mask(desc);
+			desc->chip->ack(desc);
 		}
 	}
 
@@ -217,11 +217,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
 
 	switch (msi_data->feature & FSL_PIC_IP_MASK) {
 	case FSL_PIC_IP_MPIC:
-		desc->chip->eoi(irq);
+		desc->chip->eoi(desc);
 		break;
 	case FSL_PIC_IP_IPIC:
 		if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-			desc->chip->unmask(irq);
+			desc->chip->unmask(desc);
 		break;
 	}
 unlock:
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 6323e70..ba3bc94 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -78,8 +78,9 @@ unsigned int i8259_irq(void)
 	return irq;
 }
 
-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+static void i8259_mask_and_ack_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&i8259_lock, flags);
@@ -104,8 +105,9 @@ static void i8259_set_irq_mask(int irq_nr)
 	outb(cached_21,0x21);
 }
 
-static void i8259_mask_irq(unsigned int irq_nr)
+static void i8259_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	pr_debug("i8259_mask_irq(%d)\n", irq_nr);
@@ -119,8 +121,9 @@ static void i8259_mask_irq(unsigned int irq_nr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
-static void i8259_unmask_irq(unsigned int irq_nr)
+static void i8259_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq_nr = desc->irq;
 	unsigned long flags;
 
 	pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
@@ -188,7 +191,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
 static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
 {
 	/* Make sure irq is masked in hardware */
-	i8259_mask_irq(virq);
+	i8259_mask_irq(irq_to_desc(virq));
 
 	/* remove chip and handler */
 	set_irq_chip_and_handler(virq, NULL, NULL);
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index d7b9b9c..76a58bf 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -523,8 +523,9 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
 
 #define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
 
-static void ipic_unmask_irq(unsigned int virq)
+static void ipic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -539,8 +540,9 @@ static void ipic_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_mask_irq(unsigned int virq)
+static void ipic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -559,8 +561,9 @@ static void ipic_mask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_ack_irq(unsigned int virq)
+static void ipic_ack_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -578,8 +581,9 @@ static void ipic_ack_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static void ipic_mask_irq_and_ack(unsigned int virq)
+static void ipic_mask_irq_and_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
 	unsigned long flags;
@@ -601,11 +605,11 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
 	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
-static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int ipic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
 	if (flow_type == IRQ_TYPE_NONE)
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 8c27d26..08435f0 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -25,8 +25,9 @@ static sysconf8xx_t __iomem *siu_reg;
 
 int cpm_get_irq(struct pt_regs *regs);
 
-static void mpc8xx_unmask_irq(unsigned int virq)
+static void mpc8xx_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -37,8 +38,9 @@ static void mpc8xx_unmask_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static void mpc8xx_mask_irq(unsigned int virq)
+static void mpc8xx_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -49,8 +51,9 @@ static void mpc8xx_mask_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static void mpc8xx_ack(unsigned int virq)
+static void mpc8xx_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int	bit;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -58,8 +61,9 @@ static void mpc8xx_ack(unsigned int virq)
 	out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
 }
 
-static void mpc8xx_end_irq(unsigned int virq)
+static void mpc8xx_end_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int bit, word;
 	unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
 
@@ -70,9 +74,9 @@ static void mpc8xx_end_irq(unsigned int virq)
 	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
 }
 
-static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int mpc8xx_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
+	unsigned int virq = desc->irq;
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 339e8a3..0bda28b 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -663,8 +663,9 @@ static inline void mpic_eoi(struct mpic *mpic)
  */
 
 
-void mpic_unmask_irq(unsigned int irq)
+void mpic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
@@ -683,8 +684,9 @@ void mpic_unmask_irq(unsigned int irq)
 	} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
 }
 
-void mpic_mask_irq(unsigned int irq)
+void mpic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
@@ -704,8 +706,9 @@ void mpic_mask_irq(unsigned int irq)
 	} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
 }
 
-void mpic_end_irq(unsigned int irq)
+void mpic_end_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 
 #ifdef DEBUG_IRQ
@@ -721,39 +724,43 @@ void mpic_end_irq(unsigned int irq)
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
 
-static void mpic_unmask_ht_irq(unsigned int irq)
+static void mpic_unmask_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_unmask_irq(irq);
+	mpic_unmask_irq(desc);
 
-	if (irq_to_desc(irq)->status & IRQ_LEVEL)
+	if (desc->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 }
 
-static unsigned int mpic_startup_ht_irq(unsigned int irq)
+static unsigned int mpic_startup_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_unmask_irq(irq);
-	mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
+	mpic_unmask_irq(desc);
+	mpic_startup_ht_interrupt(mpic, src, desc->status);
 
 	return 0;
 }
 
-static void mpic_shutdown_ht_irq(unsigned int irq)
+static void mpic_shutdown_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
-	mpic_mask_irq(irq);
+	mpic_shutdown_ht_interrupt(mpic, src, desc->status);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_end_ht_irq(unsigned int irq)
+static void mpic_end_ht_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
@@ -765,7 +772,7 @@ static void mpic_end_ht_irq(unsigned int irq)
 	 * latched another edge interrupt coming in anyway
 	 */
 
-	if (irq_to_desc(irq)->status & IRQ_LEVEL)
+	if (desc->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 	mpic_eoi(mpic);
 }
@@ -773,8 +780,9 @@ static void mpic_end_ht_irq(unsigned int irq)
 
 #ifdef CONFIG_SMP
 
-static void mpic_unmask_ipi(unsigned int irq)
+static void mpic_unmask_ipi(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_ipi(irq);
 	unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
 
@@ -782,13 +790,14 @@ static void mpic_unmask_ipi(unsigned int irq)
 	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
 }
 
-static void mpic_mask_ipi(unsigned int irq)
+static void mpic_mask_ipi(struct irq_desc *desc)
 {
 	/* NEVER disable an IPI... that's just plain wrong! */
 }
 
-static void mpic_end_ipi(unsigned int irq)
+static void mpic_end_ipi(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_ipi(irq);
 
 	/*
@@ -803,8 +812,9 @@ static void mpic_end_ipi(unsigned int irq)
 
 #endif /* CONFIG_SMP */
 
-int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+int mpic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
+	unsigned int irq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
@@ -845,11 +855,11 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
 	}
 }
 
-int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+int mpic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
+	unsigned int virq = desc->irq;
 	struct mpic *mpic = mpic_from_irq(virq);
 	unsigned int src = mpic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vecpri, vold, vnew;
 
 	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index eff433c..19d7ed4 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -34,8 +34,8 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
 }
 #endif
 
-extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
+extern int mpic_set_irq_type(struct irq_desc *desc, unsigned int flow_type);
 extern void mpic_set_vector(unsigned int virq, unsigned int vector);
-extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int mpic_set_affinity(struct irq_desc *desc, const struct cpumask *cpumask);
 
 #endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 3b6a9a4..c05a9c6 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -39,18 +39,20 @@
 static struct mpic *msi_mpic;
 
 
-static void mpic_pasemi_msi_mask_irq(unsigned int irq)
+static void mpic_pasemi_msi_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(desc);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
+static void mpic_pasemi_msi_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(desc);
+	unmask_msi_irq(desc);
 }
 
 static struct irq_chip mpic_pasemi_msi_chip = {
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index bcbfe79..8c4eadd 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -23,16 +23,16 @@
 /* A bit ugly, can we get this from the pci_dev somehow? */
 static struct mpic *msi_mpic;
 
-static void mpic_u3msi_mask_irq(unsigned int irq)
+static void mpic_u3msi_mask_irq(struct irq_desc *desc)
 {
-	mask_msi_irq(irq);
-	mpic_mask_irq(irq);
+	mask_msi_irq(desc);
+	mpic_mask_irq(desc);
 }
 
-static void mpic_u3msi_unmask_irq(unsigned int irq)
+static void mpic_u3msi_unmask_irq(struct irq_desc *desc)
 {
-	mpic_unmask_irq(irq);
-	unmask_msi_irq(irq);
+	mpic_unmask_irq(desc);
+	unmask_msi_irq(desc);
 }
 
 static struct irq_chip mpic_u3msi_chip = {
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 485b924..72f4dfb 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -76,8 +76,9 @@ static struct irq_host *mv64x60_irq_host;
  * mv64x60_chip_low functions
  */
 
-static void mv64x60_mask_low(unsigned int virq)
+static void mv64x60_mask_low(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -89,8 +90,9 @@ static void mv64x60_mask_low(unsigned int virq)
 	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
 }
 
-static void mv64x60_unmask_low(unsigned int virq)
+static void mv64x60_unmask_low(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -113,8 +115,9 @@ static struct irq_chip mv64x60_chip_low = {
  * mv64x60_chip_high functions
  */
 
-static void mv64x60_mask_high(unsigned int virq)
+static void mv64x60_mask_high(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -126,8 +129,9 @@ static void mv64x60_mask_high(unsigned int virq)
 	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
 }
 
-static void mv64x60_unmask_high(unsigned int virq)
+static void mv64x60_unmask_high(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -150,8 +154,9 @@ static struct irq_chip mv64x60_chip_high = {
  * mv64x60_chip_gpp functions
  */
 
-static void mv64x60_mask_gpp(unsigned int virq)
+static void mv64x60_mask_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -163,8 +168,9 @@ static void mv64x60_mask_gpp(unsigned int virq)
 	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
 }
 
-static void mv64x60_mask_ack_gpp(unsigned int virq)
+static void mv64x60_mask_ack_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
@@ -178,8 +184,9 @@ static void mv64x60_mask_ack_gpp(unsigned int virq)
 	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
 }
 
-static void mv64x60_unmask_gpp(unsigned int virq)
+static void mv64x60_unmask_gpp(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 541ba98..289c0cb 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -194,8 +194,9 @@ static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
 
 #define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
 
-static void qe_ic_unmask_irq(unsigned int virq)
+static void qe_ic_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 	unsigned int src = virq_to_hw(virq);
 	unsigned long flags;
@@ -210,8 +211,9 @@ static void qe_ic_unmask_irq(unsigned int virq)
 	raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 }
 
-static void qe_ic_mask_irq(unsigned int virq)
+static void qe_ic_mask_irq(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 	unsigned int src = virq_to_hw(virq);
 	unsigned long flags;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 595034c..2ff5286 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -344,23 +344,27 @@ static inline unsigned int get_pci_source(void)
  * Linux descriptor level callbacks
  */
 
-static void tsi108_pci_irq_enable(u_int irq)
+static void tsi108_pci_irq_enable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_unmask(irq);
 }
 
-static void tsi108_pci_irq_disable(u_int irq)
+static void tsi108_pci_irq_disable(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_mask(irq);
 }
 
-static void tsi108_pci_irq_ack(u_int irq)
+static void tsi108_pci_irq_ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_mask(irq);
 }
 
-static void tsi108_pci_irq_end(u_int irq)
+static void tsi108_pci_irq_end(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	tsi108_pci_int_unmask(irq);
 
 	/* Enable interrupts from PCI block */
@@ -441,5 +445,5 @@ void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
 	unsigned int cascade_irq = get_pci_source();
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
-	desc->chip->eoi(irq);
+	desc->chip->eoi(desc);
 }
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 0038fb7..fbed0a4 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -55,10 +55,10 @@ struct uic {
 	struct irq_host	*irqhost;
 };
 
-static void uic_unmask_irq(unsigned int virq)
+static void uic_unmask_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er, sr;
@@ -74,9 +74,10 @@ static void uic_unmask_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_mask_irq(unsigned int virq)
+static void uic_mask_irq(struct irq_desc *desc)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er;
@@ -88,9 +89,10 @@ static void uic_mask_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_ack_irq(unsigned int virq)
+static void uic_ack_irq(struct irq_desc *desc)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 
@@ -99,10 +101,10 @@ static void uic_ack_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static void uic_mask_ack_irq(unsigned int virq)
+static void uic_mask_ack_irq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
 	u32 er, sr;
@@ -125,11 +127,11 @@ static void uic_mask_ack_irq(unsigned int virq)
 	spin_unlock_irqrestore(&uic->lock, flags);
 }
 
-static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
+static int uic_set_irq_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct uic *uic = get_irq_chip_data(virq);
+	unsigned int virq = desc->irq;
+	struct uic *uic = get_irq_desc_chip_data(desc);
 	unsigned int src = uic_irq_to_hw(virq);
-	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned long flags;
 	int trigger, polarity;
 	u32 tr, pr, mask;
@@ -227,9 +229,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
 
 	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
-		desc->chip->mask(virq);
+		desc->chip->mask(desc);
 	else
-		desc->chip->mask_ack(virq);
+		desc->chip->mask_ack(desc);
 	raw_spin_unlock(&desc->lock);
 
 	msr = mfdcr(uic->dcrbase + UIC_MSR);
@@ -244,9 +246,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
 uic_irq_ret:
 	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
-		desc->chip->ack(virq);
+		desc->chip->ack(desc);
 	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-		desc->chip->unmask(virq);
+		desc->chip->unmask(desc);
 	raw_spin_unlock(&desc->lock);
 }
 
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 1e0ccfa..f8e3f68 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -69,17 +69,18 @@ static unsigned char xilinx_intc_map_senses[] = {
  *
  * IRQ Chip common (across level and edge) operations
  */
-static void xilinx_intc_mask(unsigned int virq)
+static void xilinx_intc_mask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("mask: %d\n", irq);
 	out_be32(regs + XINTC_CIE, 1 << irq);
 }
 
-static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
+static int xilinx_intc_set_type(struct irq_desc *desc, unsigned int flow_type)
 {
-	struct irq_desc *desc = irq_to_desc(virq);
+	unsigned int virq = desc->irq;
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@@ -91,10 +92,11 @@ static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
 /*
  * IRQ Chip level operations
  */
-static void xilinx_intc_level_unmask(unsigned int virq)
+static void xilinx_intc_level_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
 
@@ -116,18 +118,20 @@ static struct irq_chip xilinx_intc_level_irqchip = {
 /*
  * IRQ Chip edge operations
  */
-static void xilinx_intc_edge_unmask(unsigned int virq)
+static void xilinx_intc_edge_unmask(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void *regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
 }
 
-static void xilinx_intc_edge_ack(unsigned int virq)
+static void xilinx_intc_edge_ack(struct irq_desc *desc)
 {
+	unsigned int virq = desc->irq;
 	int irq = virq_to_hw(virq);
-	void * regs = get_irq_chip_data(virq);
+	void *regs = get_irq_desc_chip_data(desc);
 	pr_debug("ack: %d\n", irq);
 	out_be32(regs + XINTC_IAR, 1 << irq);
 }
@@ -234,7 +238,7 @@ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
 		generic_handle_irq(cascade_irq);
 
 	/* Let xilinx_intc end the interrupt */
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 static void __init xilinx_i8259_setup_cascade(void)
diff --git a/arch/score/kernel/irq.c b/arch/score/kernel/irq.c
index 47647dd..663a04b 100644
--- a/arch/score/kernel/irq.c
+++ b/arch/score/kernel/irq.c
@@ -52,9 +52,10 @@ asmlinkage void do_IRQ(int irq)
 	irq_exit();
 }
 
-static void score_mask(unsigned int irq_nr)
+static void score_mask(struct irq_desc *desc)
 {
-	unsigned int irq_source = 63 - irq_nr;
+	unsigned int irq = desc->irq;
+	unsigned int irq_source = 63 - irq;
 
 	if (irq_source < 32)
 		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \
@@ -64,9 +65,10 @@ static void score_mask(unsigned int irq_nr)
 			(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH);
 }
 
-static void score_unmask(unsigned int irq_nr)
+static void score_unmask(struct irq_desc *desc)
 {
-	unsigned int irq_source = 63 - irq_nr;
+	unsigned int irq = desc->irq;
+	unsigned int irq_source = 63 - irq;
 
 	if (irq_source < 32)
 		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index 1394b07..ac3535a 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -55,8 +55,9 @@ static struct irqaction cayman_action_pci2 = {
 	.flags		= IRQF_DISABLED,
 };
 
-static void enable_cayman_irq(unsigned int irq)
+static void enable_cayman_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned long mask;
 	unsigned int reg;
@@ -72,8 +73,9 @@ static void enable_cayman_irq(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-void disable_cayman_irq(unsigned int irq)
+void disable_cayman_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long flags;
 	unsigned long mask;
 	unsigned int reg;
@@ -89,9 +91,9 @@ void disable_cayman_irq(unsigned int irq)
 	local_irq_restore(flags);
 }
 
-static void ack_cayman_irq(unsigned int irq)
+static void ack_cayman_irq(struct irq_desc *desc)
 {
-	disable_cayman_irq(irq);
+	disable_cayman_irq(desc);
 }
 
 struct irq_chip cayman_irq_type = {
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index d932667..16cde3e 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -60,8 +60,9 @@
  */
 
 /* Disable the hardware event by masking its bit in its EMR */
-static inline void disable_systemasic_irq(unsigned int irq)
+static inline void disable_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
 
@@ -71,8 +72,9 @@ static inline void disable_systemasic_irq(unsigned int irq)
 }
 
 /* Enable the hardware event by setting its bit in its EMR */
-static inline void enable_systemasic_irq(unsigned int irq)
+static inline void enable_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
 
@@ -82,8 +84,9 @@ static inline void enable_systemasic_irq(unsigned int irq)
 }
 
 /* Acknowledge a hardware event by writing its bit back to its ESR */
-static void mask_ack_systemasic_irq(unsigned int irq)
+static void mask_ack_systemasic_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
 	disable_systemasic_irq(irq);
 	outl((1 << EVENT_BIT(irq)), esr);
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
index 96f38a4..3bcfb32 100644
--- a/arch/sh/boards/mach-landisk/irq.c
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -18,15 +18,17 @@
 #include <linux/io.h>
 #include <mach-landisk/mach/iodata_landisk.h>
 
-static void disable_landisk_irq(unsigned int irq)
+static void disable_landisk_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char mask = 0xff ^ (0x01 << (irq - 5));
 
 	__raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK);
 }
 
-static void enable_landisk_irq(unsigned int irq)
+static void enable_landisk_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned char value = (0x01 << (irq - 5));
 
 	__raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK);
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index a26d166..4b7b5ec 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -65,9 +65,9 @@ static const struct {
 #  error Inconsistancy in defining the IRQ# for primary IDE!
 #endif
 
-static void enable_microdev_irq(unsigned int irq);
-static void disable_microdev_irq(unsigned int irq);
-static void mask_and_ack_microdev(unsigned int);
+static void enable_microdev_irq(struct irq_desc *desc);
+static void disable_microdev_irq(struct irq_desc *desc);
+static void mask_and_ack_microdev(struct irq_desc *desc);
 
 static struct irq_chip microdev_irq_type = {
 	.name = "MicroDev-IRQ",
@@ -76,8 +76,9 @@ static struct irq_chip microdev_irq_type = {
 	.ack = mask_and_ack_microdev,
 };
 
-static void disable_microdev_irq(unsigned int irq)
+static void disable_microdev_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned int fpgaIrq;
 
 	if (irq >= NUM_EXTERNAL_IRQS)
@@ -91,8 +92,9 @@ static void disable_microdev_irq(unsigned int irq)
 	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
 }
 
-static void enable_microdev_irq(unsigned int irq)
+static void enable_microdev_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long priorityReg, priorities, pri;
 	unsigned int fpgaIrq;
 
@@ -119,14 +121,15 @@ static void enable_microdev_irq(unsigned int irq)
 /* This function sets the desired irq handler to be a MicroDev type */
 static void __init make_microdev_irq(unsigned int irq)
 {
+	struct irq_desc *desc = irq_to_desc(irq);
 	disable_irq_nosync(irq);
 	set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
-	disable_microdev_irq(irq);
+	disable_microdev_irq(desc);
 }
 
-static void mask_and_ack_microdev(unsigned int irq)
+static void mask_and_ack_microdev(struct irq_desc *desc)
 {
-	disable_microdev_irq(irq);
+	disable_microdev_irq(desc);
 }
 
 extern void __init init_microdev_irq(void)
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index 8d82175..1a71dad 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -25,8 +25,9 @@
 #define INTC_IPR01 0xfffe0818
 #define INTC_ICR1  0xfffe0802
 
-static void disable_se7206_irq(unsigned int irq)
+static void disable_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short val;
 	unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
 	unsigned short msk0,msk1;
@@ -55,8 +56,9 @@ static void disable_se7206_irq(unsigned int irq)
 	__raw_writew(msk1, INTMSK1);
 }
 
-static void enable_se7206_irq(unsigned int irq)
+static void enable_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short val;
 	unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
 	unsigned short msk0,msk1;
@@ -86,8 +88,9 @@ static void enable_se7206_irq(unsigned int irq)
 	__raw_writew(msk1, INTMSK1);
 }
 
-static void eoi_se7206_irq(unsigned int irq)
+static void eoi_se7206_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short sts0,sts1;
 	struct irq_desc *desc = irq_to_desc(irq);
 
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index d4305c2..a195d5a 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -18,15 +18,15 @@
 
 unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
 
-static void disable_se7343_irq(unsigned int irq)
+static void disable_se7343_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
 }
 
-static void enable_se7343_irq(unsigned int irq)
+static void enable_se7343_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
 }
 
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 61605db..69cb49a 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -18,15 +18,15 @@
 
 unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
 
-static void disable_se7722_irq(unsigned int irq)
+static void disable_se7722_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
 }
 
-static void enable_se7722_irq(unsigned int irq)
+static void enable_se7722_irq(struct irq_desc *desc)
 {
-	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	unsigned int bit = (unsigned int)get_irq_desc_chip_data(desc);
 	__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
 }
 
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index 0942be2..b0c094d 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -68,15 +68,17 @@ static struct fpga_irq get_fpga_irq(unsigned int irq)
 	return set;
 }
 
-static void disable_se7724_irq(unsigned int irq)
+static void disable_se7724_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
 	__raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
 }
 
-static void enable_se7724_irq(unsigned int irq)
+static void enable_se7724_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
 	__raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 523aea5..fa3a36d 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -24,9 +24,9 @@ static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
 static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
 
 /* forward declaration */
-static void enable_systemh_irq(unsigned int irq);
-static void disable_systemh_irq(unsigned int irq);
-static void mask_and_ack_systemh(unsigned int);
+static void enable_systemh_irq(struct irq_desc *desc);
+static void disable_systemh_irq(struct irq_desc *desc);
+static void mask_and_ack_systemh(struct irq_desc *desc);
 
 static struct irq_chip systemh_irq_type = {
 	.name = " SystemH Register",
@@ -35,8 +35,9 @@ static struct irq_chip systemh_irq_type = {
 	.ack = mask_and_ack_systemh,
 };
 
-static void disable_systemh_irq(unsigned int irq)
+static void disable_systemh_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (systemh_irq_mask_register) {
 		unsigned long val, mask = 0x01 << 1;
 
@@ -51,8 +52,9 @@ static void disable_systemh_irq(unsigned int irq)
 	}
 }
 
-static void enable_systemh_irq(unsigned int irq)
+static void enable_systemh_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	if (systemh_irq_mask_register) {
 		unsigned long val, mask = 0x01 << 1;
 
@@ -63,9 +65,9 @@ static void enable_systemh_irq(unsigned int irq)
 	}
 }
 
-static void mask_and_ack_systemh(unsigned int irq)
+static void mask_and_ack_systemh(struct irq_desc *desc)
 {
-	disable_systemh_irq(irq);
+	disable_systemh_irq(desc);
 }
 
 void make_systemh_irq(unsigned int irq)
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index bcb31ae..9e9698c 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -17,8 +17,9 @@
 /* This belongs in cpu specific */
 #define INTC_ICR1 0xA4140010UL
 
-static void hd64461_mask_irq(unsigned int irq)
+static void hd64461_mask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
@@ -27,8 +28,9 @@ static void hd64461_mask_irq(unsigned int irq)
 	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void hd64461_unmask_irq(unsigned int irq)
+static void hd64461_unmask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
@@ -37,9 +39,10 @@ static void hd64461_unmask_irq(unsigned int irq)
 	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void hd64461_mask_and_ack_irq(unsigned int irq)
+static void hd64461_mask_and_ack_irq(struct irq_desc *desc)
 {
-	hd64461_mask_irq(irq);
+	unsigned int irq = desc->irq;
+	hd64461_mask_irq(desc);
 #ifdef CONFIG_HD64461_ENABLER
 	if (irq == HD64461_IRQBASE + 13)
 		__raw_writeb(0x00, HD64461_PCC1CSCR);
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index a351ed8..0598602 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -51,16 +51,18 @@ static inline void set_interrupt_registers(int ip)
 		     : "t");
 }
 
-static void mask_imask_irq(unsigned int irq)
+static void mask_imask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	clear_bit(irq, imask_mask);
 	if (interrupt_priority < IMASK_PRIORITY - irq)
 		interrupt_priority = IMASK_PRIORITY - irq;
 	set_interrupt_registers(interrupt_priority);
 }
 
-static void unmask_imask_irq(unsigned int irq)
+static void unmask_imask_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	set_bit(irq, imask_mask);
 	interrupt_priority = IMASK_PRIORITY -
 		find_first_zero_bit(imask_mask, IMASK_PRIORITY);
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 96a2395..69a90ae 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -77,12 +77,12 @@ int intc_evt_to_irq[(0xE20/0x20)+1] = {
 
 static unsigned long intc_virt;
 
-static unsigned int startup_intc_irq(unsigned int irq);
-static void shutdown_intc_irq(unsigned int irq);
-static void enable_intc_irq(unsigned int irq);
-static void disable_intc_irq(unsigned int irq);
-static void mask_and_ack_intc(unsigned int);
-static void end_intc_irq(unsigned int irq);
+static unsigned int startup_intc_irq(struct irq_desc *desc);
+static void shutdown_intc_irq(struct irq_desc *desc);
+static void enable_intc_irq(struct irq_desc *desc);
+static void disable_intc_irq(struct irq_desc *desc);
+static void mask_and_ack_intc(struct irq_desc *desc);
+static void end_intc_irq(struct irq_desc *desc);
 
 static struct irq_chip intc_irq_type = {
 	.name = "INTC",
@@ -96,19 +96,20 @@ static struct irq_chip intc_irq_type = {
 
 static int irlm;		/* IRL mode */
 
-static unsigned int startup_intc_irq(unsigned int irq)
+static unsigned int startup_intc_irq(struct irq_desc *desc)
 {
-	enable_intc_irq(irq);
+	enable_intc_irq(desc);
 	return 0; /* never anything pending */
 }
 
-static void shutdown_intc_irq(unsigned int irq)
+static void shutdown_intc_irq(struct irq_desc *desc)
 {
-	disable_intc_irq(irq);
+	disable_intc_irq(desc);
 }
 
-static void enable_intc_irq(unsigned int irq)
+static void enable_intc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long reg;
 	unsigned long bitmask;
 
@@ -126,8 +127,9 @@ static void enable_intc_irq(unsigned int irq)
 	__raw_writel(bitmask, reg);
 }
 
-static void disable_intc_irq(unsigned int irq)
+static void disable_intc_irq(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	unsigned long reg;
 	unsigned long bitmask;
 
@@ -142,14 +144,14 @@ static void disable_intc_irq(unsigned int irq)
 	__raw_writel(bitmask, reg);
 }
 
-static void mask_and_ack_intc(unsigned int irq)
+static void mask_and_ack_intc(struct irq_desc *desc)
 {
-	disable_intc_irq(irq);
+	disable_intc_irq(desc);
 }
 
-static void end_intc_irq(unsigned int irq)
+static void end_intc_irq(struct irq_desc *desc)
 {
-	enable_intc_irq(irq);
+	enable_intc_irq(desc);
 }
 
 void __init plat_irq_setup(void)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 4e7419c..1495c97 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -250,8 +250,9 @@ struct irq_handler_data {
 };
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
+static int irq_choose_cpu(struct irq_desc *desc, const struct cpumask *affinity)
 {
+	unsigned int virt_irq = desc->irq;
 	cpumask_t mask;
 	int cpuid;
 
@@ -268,20 +269,20 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
 	return cpuid;
 }
 #else
-#define irq_choose_cpu(virt_irq, affinity)	\
+#define irq_choose_cpu(desc, affinity)	\
 	real_hard_smp_processor_id()
 #endif
 
-static void sun4u_irq_enable(unsigned int virt_irq)
+static void sun4u_irq_enable(struct irq_desc *desc)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (likely(data)) {
 		unsigned long cpuid, imap, val;
 		unsigned int tid;
 
-		cpuid = irq_choose_cpu(virt_irq,
-				       irq_desc[virt_irq].affinity);
+		cpuid = irq_choose_cpu(desc,
+				       desc->affinity);
 		imap = data->imap;
 
 		tid = sun4u_compute_tid(imap, cpuid);
@@ -295,16 +296,16 @@ static void sun4u_irq_enable(unsigned int virt_irq)
 	}
 }
 
-static int sun4u_set_affinity(unsigned int virt_irq,
+static int sun4u_set_affinity(struct irq_desc *desc,
 			       const struct cpumask *mask)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (likely(data)) {
 		unsigned long cpuid, imap, val;
 		unsigned int tid;
 
-		cpuid = irq_choose_cpu(virt_irq, mask);
+		cpuid = irq_choose_cpu(desc, mask);
 		imap = data->imap;
 
 		tid = sun4u_compute_tid(imap, cpuid);
@@ -337,14 +338,13 @@ static int sun4u_set_affinity(unsigned int virt_irq,
  * sees that, it also hooks up a default ->shutdown method which
  * invokes ->mask() which we do not want.  See irq_chip_set_defaults().
  */
-static void sun4u_irq_disable(unsigned int virt_irq)
+static void sun4u_irq_disable(struct irq_desc *desc)
 {
 }
 
-static void sun4u_irq_eoi(unsigned int virt_irq)
+static void sun4u_irq_eoi(struct irq_desc *desc)
 {
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-	struct irq_desc *desc = irq_desc + virt_irq;
+	struct irq_handler_data *data = get_irq_desc_chip_data(desc);
 
 	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		return;
@@ -353,11 +353,11 @@ static void sun4u_irq_eoi(unsigned int virt_irq)
 		upa_writeq(ICLR_IDLE, data->iclr);
 }
 
-static void sun4v_irq_enable(unsigned int virt_irq)
+static void sun4v_irq_enable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq,
-					     irq_desc[virt_irq].affinity);
+	unsigned long cpuid = irq_choose_cpu(desc, desc->affinity);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -374,11 +374,12 @@ static void sun4v_irq_enable(unsigned int virt_irq)
 		       ino, err);
 }
 
-static int sun4v_set_affinity(unsigned int virt_irq,
+static int sun4v_set_affinity(struct irq_desc *desc,
 			       const struct cpumask *mask)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq, mask);
+	unsigned long cpuid = irq_choose_cpu(desc, mask);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -389,8 +390,9 @@ static int sun4v_set_affinity(unsigned int virt_irq,
 	return 0;
 }
 
-static void sun4v_irq_disable(unsigned int virt_irq)
+static void sun4v_irq_disable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
 	int err;
 
@@ -400,10 +402,10 @@ static void sun4v_irq_disable(unsigned int virt_irq)
 		       "err(%d)\n", ino, err);
 }
 
-static void sun4v_irq_eoi(unsigned int virt_irq)
+static void sun4v_irq_eoi(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	struct irq_desc *desc = irq_desc + virt_irq;
 	int err;
 
 	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
@@ -415,12 +417,13 @@ static void sun4v_irq_eoi(unsigned int virt_irq)
 		       "err(%d)\n", ino, err);
 }
 
-static void sun4v_virq_enable(unsigned int virt_irq)
+static void sun4v_virq_enable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity);
+	cpuid = irq_choose_cpu(desc, desc->affinity);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -444,13 +447,14 @@ static void sun4v_virq_enable(unsigned int virt_irq)
 		       dev_handle, dev_ino, err);
 }
 
-static int sun4v_virt_set_affinity(unsigned int virt_irq,
+static int sun4v_virt_set_affinity(struct irq_desc *desc,
 				    const struct cpumask *mask)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq, mask);
+	cpuid = irq_choose_cpu(desc, mask);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -464,8 +468,9 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq,
 	return 0;
 }
 
-static void sun4v_virq_disable(unsigned int virt_irq)
+static void sun4v_virq_disable(struct irq_desc *desc)
 {
+	unsigned int virt_irq = desc->irq;
 	unsigned long dev_handle, dev_ino;
 	int err;
 
@@ -480,9 +485,9 @@ static void sun4v_virq_disable(unsigned int virt_irq)
 		       dev_handle, dev_ino, err);
 }
 
-static void sun4v_virq_eoi(unsigned int virt_irq)
+static void sun4v_virq_eoi(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_desc + virt_irq;
+	unsigned int virt_irq = desc->irq;
 	unsigned long dev_handle, dev_ino;
 	int err;
 
@@ -802,15 +807,16 @@ void fixup_irqs(void)
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		unsigned long flags;
-
-		raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
-		if (irq_desc[irq].action &&
-		    !(irq_desc[irq].status & IRQ_PER_CPU)) {
-			if (irq_desc[irq].chip->set_affinity)
-				irq_desc[irq].chip->set_affinity(irq,
-					irq_desc[irq].affinity);
+		struct irq_desc *desc = irq_to_desc(irq);
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+		if (desc->action &&
+		    !(desc->status & IRQ_PER_CPU)) {
+			if (desc->chip->set_affinity)
+				desc->chip->set_affinity(desc,
+					desc->affinity);
 		}
-		raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 
 	tick_ops->disable_irq();
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c
index 380a70f..6d1b690 100644
--- a/arch/xtensa/variants/s6000/gpio.c
+++ b/arch/xtensa/variants/s6000/gpio.c
@@ -85,27 +85,31 @@ int s6_gpio_init(u32 afsel)
 	return gpiochip_add(&gpiochip);
 }
 
-static void ack(unsigned int irq)
+static void ack(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	writeb(1 << (irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC);
 }
 
-static void mask(unsigned int irq)
+static void mask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 r = readb(S6_REG_GPIO + S6_GPIO_IE);
 	r &= ~(1 << (irq - IRQ_BASE));
 	writeb(r, S6_REG_GPIO + S6_GPIO_IE);
 }
 
-static void unmask(unsigned int irq)
+static void unmask(struct irq_desc *desc)
 {
+	unsigned int irq = desc->irq;
 	u8 m = readb(S6_REG_GPIO + S6_GPIO_IE);
 	m |= 1 << (irq - IRQ_BASE);
 	writeb(m, S6_REG_GPIO + S6_GPIO_IE);
 }
 
-static int set_type(unsigned int irq, unsigned int type)
+static int set_type(struct irq_desc *desc, unsigned int type)
 {
+	unsigned int irq = desc->irq;
 	const u8 m = 1 << (irq - IRQ_BASE);
 	irq_flow_handler_t handler;
 	struct irq_desc *desc;
@@ -164,8 +168,8 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
 	u8 pending;
 	int cirq;
 
-	desc->chip->mask(irq);
-	desc->chip->ack(irq);
+	desc->chip->mask(desc);
+	desc->chip->ack(desc);
 	pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask;
 	cirq = IRQ_BASE - 1;
 	while (pending) {
@@ -174,7 +178,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc)
 		pending >>= n;
 		generic_handle_irq(cirq);
 	}
-	desc->chip->unmask(irq);
+	desc->chip->unmask(desc);
 }
 
 extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS];
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index a3d8677..f9aaed6 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -245,15 +245,16 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)
 	}
 }
 
-static void intc_enable(unsigned int irq)
+static void intc_enable(struct irq_desc *desc)
 {
-	_intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
+	unsigned int irq = desc->irq;
+	_intc_enable(irq, (unsigned long)get_irq_desc_chip_data(desc));
 }
 
-static void intc_disable(unsigned int irq)
+static void intc_disable(struct irq_desc *desc)
 {
 	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = (unsigned long) get_irq_chip_data(irq);
+	unsigned long handle = (unsigned long) get_irq_desc_chip_data(desc);
 	unsigned long addr;
 	unsigned int cpu;
 
@@ -784,7 +785,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
 	}
 
 	/* irq should be disabled by default */
-	d->chip.mask(irq);
+	d->chip.mask(desc);
 
 	if (desc->hw.ack_regs)
 		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
-- 
1.6.4.2

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

* [PATCH 14/20] genericirq: add set_irq_desc_chip/data ...
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 d3b2f0b..5f061b7 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 fb8c376..89d49e8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -412,9 +412,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);
@@ -423,6 +423,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 043557a..502168d 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] 111+ messages in thread

* [PATCH 14/20] genericirq: add set_irq_desc_chip/data ...
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 d3b2f0b..5f061b7 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 fb8c376..89d49e8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -412,9 +412,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);
@@ -423,6 +423,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 043557a..502168d 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] 111+ messages in thread

* [PATCH 15/20] x86/iommu/dmar: update iommu/inter_remapping to use desc
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 |   80 +++++++++++++++++++---------------------
 drivers/pci/intr_remapping.c   |   69 ++++++++++++++--------------------
 include/linux/dmar.h           |   36 +++++++++--------
 4 files changed, 86 insertions(+), 103 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 5f061b7..c03bcd4 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;
@@ -3450,12 +3443,11 @@ static int set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mas
 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))
@@ -3467,7 +3459,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
@@ -3522,7 +3514,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;
@@ -3534,7 +3526,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,
@@ -3544,20 +3536,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);
-	write_msi_msg(irq, &msg);
+	set_irq_desc_msi(desc, msidesc);
+	write_msi_msg_desc(desc, &msg);
 
-	if (irq_remapped(irq)) {
+	irq = desc->irq;
+	if (irq_remapped(desc)) {
 		/*
 		 * irq migration in process context
 		 */
@@ -3574,6 +3568,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;
@@ -3593,6 +3588,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;
 
@@ -3601,7 +3597,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;
@@ -3617,10 +3613,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++;
@@ -3765,7 +3761,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;
 	}
@@ -3776,7 +3772,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 6b4227a..a5f04a1 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] 111+ messages in thread

* [PATCH 15/20] x86/iommu/dmar: update iommu/inter_remapping to use desc
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 |   80 +++++++++++++++++++---------------------
 drivers/pci/intr_remapping.c   |   69 ++++++++++++++--------------------
 include/linux/dmar.h           |   36 +++++++++--------
 4 files changed, 86 insertions(+), 103 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 5f061b7..c03bcd4 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;
@@ -3450,12 +3443,11 @@ static int set_msi_irq_affinity(struct irq_desc *desc, const struct cpumask *mas
 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))
@@ -3467,7 +3459,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
@@ -3522,7 +3514,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;
@@ -3534,7 +3526,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,
@@ -3544,20 +3536,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);
-	write_msi_msg(irq, &msg);
+	set_irq_desc_msi(desc, msidesc);
+	write_msi_msg_desc(desc, &msg);
 
-	if (irq_remapped(irq)) {
+	irq = desc->irq;
+	if (irq_remapped(desc)) {
 		/*
 		 * irq migration in process context
 		 */
@@ -3574,6 +3568,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;
@@ -3593,6 +3588,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;
 
@@ -3601,7 +3597,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;
@@ -3617,10 +3613,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++;
@@ -3765,7 +3761,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;
 	}
@@ -3776,7 +3772,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 6b4227a..a5f04a1 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] 111+ messages in thread

* [PATCH 16/20] x86: use num_processors for possible cpus
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

some systems that have disable cpus entries because same
  BIOS will support 2 sockets and 4 sockets and more at
  same time, BIOS just leave some disable entries, but
  those system do not support cpu hotplug. we don't need
  treat disabled_cpus as hotplug cpus.
so we can make nr_cpu_ids smaller and save more space
  (pcpu data allocations), and could make some systems run
  with logical flat instead of physical flat apic mode

-v2: change to black list instead
-v3: just remove that, and the one use possible_cpus= directly.

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

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a1483ac..3f92885 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1251,7 +1251,6 @@ early_param("possible_cpus", _setup_possible_cpus);
  * - Ashok Raj
  *
  * Three ways to find out the number of additional hotplug CPUs:
- * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
  * - The user can overwrite it with possible_cpus=NUM
  * - Otherwise don't reserve additional CPUs.
  * We do this because additional CPUs waste a lot of memory.
@@ -1266,7 +1265,7 @@ __init void prefill_possible_map(void)
 		num_processors = 1;
 
 	if (setup_possible_cpus == -1)
-		possible = num_processors + disabled_cpus;
+		possible = num_processors;
 	else
 		possible = setup_possible_cpus;
 
-- 
1.6.4.2


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

* [PATCH 16/20] x86: use num_processors for possible cpus
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

some systems that have disable cpus entries because same
  BIOS will support 2 sockets and 4 sockets and more at
  same time, BIOS just leave some disable entries, but
  those system do not support cpu hotplug. we don't need
  treat disabled_cpus as hotplug cpus.
so we can make nr_cpu_ids smaller and save more space
  (pcpu data allocations), and could make some systems run
  with logical flat instead of physical flat apic mode

-v2: change to black list instead
-v3: just remove that, and the one use possible_cpus= directly.

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

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a1483ac..3f92885 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1251,7 +1251,6 @@ early_param("possible_cpus", _setup_possible_cpus);
  * - Ashok Raj
  *
  * Three ways to find out the number of additional hotplug CPUs:
- * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
  * - The user can overwrite it with possible_cpus=NUM
  * - Otherwise don't reserve additional CPUs.
  * We do this because additional CPUs waste a lot of memory.
@@ -1266,7 +1265,7 @@ __init void prefill_possible_map(void)
 		num_processors = 1;
 
 	if (setup_possible_cpus == -1)
-		possible = num_processors + disabled_cpus;
+		possible = num_processors;
 	else
 		possible = setup_possible_cpus;
 
-- 
1.6.4.2

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

* [PATCH 17/20] x86: make 32bit apic flat to physflat switch like 64bit
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

kill def_to_bigsmp
and move switch from default to bigsmp at default_setup_apic_routing...
so make default_setup_apic_routing more like 64 bit
also make the dmi relate code to be __init/__initdata

-v2: refresh it according to change in upstream

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/apic.h      |    3 -
 arch/x86/include/asm/mpspec.h    |    1 -
 arch/x86/kernel/apic/bigsmp_32.c |   48 +---------------
 arch/x86/kernel/apic/probe_32.c  |  115 ++++++++++++++++++++------------------
 arch/x86/kernel/apic/probe_64.c  |    2 +-
 arch/x86/kernel/setup.c          |    2 -
 arch/x86/kernel/smpboot.c        |    2 +-
 7 files changed, 65 insertions(+), 108 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 1fa03e0..6a34763 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -465,9 +465,6 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert)
 	return;
 }
 
-extern void generic_bigsmp_probe(void);
-
-
 #ifdef CONFIG_X86_LOCAL_APIC
 
 #include <asm/smp.h>
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 1a221e0..cb398c8 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -23,7 +23,6 @@ extern int pic_mode;
 
 #define MAX_IRQ_SOURCES		256
 
-extern unsigned int def_to_bigsmp;
 extern u8 apicid_2_node[];
 
 #ifdef CONFIG_X86_NUMAQ
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index cb804c5..350d60e 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -7,7 +7,6 @@
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/dmi.h>
 #include <linux/smp.h>
 
 #include <asm/apicdef.h>
@@ -73,13 +72,6 @@ static void bigsmp_init_apic_ldr(void)
 	apic_write(APIC_LDR, val);
 }
 
-static void bigsmp_setup_apic_routing(void)
-{
-	printk(KERN_INFO
-		"Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
-		nr_ioapics);
-}
-
 static int bigsmp_apicid_to_node(int logical_apicid)
 {
 	return apicid_2_node[hard_smp_processor_id()];
@@ -154,52 +146,16 @@ static void bigsmp_send_IPI_all(int vector)
 	bigsmp_send_IPI_mask(cpu_online_mask, vector);
 }
 
-static int dmi_bigsmp; /* can be set by dmi scanners */
-
-static int hp_ht_bigsmp(const struct dmi_system_id *d)
-{
-	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
-	dmi_bigsmp = 1;
-
-	return 0;
-}
-
-
-static const struct dmi_system_id bigsmp_dmi_table[] = {
-	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
-		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
-		}
-	},
-
-	{ hp_ht_bigsmp, "HP ProLiant DL740",
-		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
-		}
-	},
-	{ } /* NULL entry stops DMI scanning */
-};
-
 static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	cpumask_clear(retmask);
 	cpumask_set_cpu(cpu, retmask);
 }
 
-static int probe_bigsmp(void)
-{
-	if (def_to_bigsmp)
-		dmi_bigsmp = 1;
-	else
-		dmi_check_system(bigsmp_dmi_table);
-
-	return dmi_bigsmp;
-}
-
 struct apic apic_bigsmp = {
 
 	.name				= "bigsmp",
-	.probe				= probe_bigsmp,
+	.probe				= NULL,
 	.acpi_madt_oem_check		= NULL,
 	.apic_id_registered		= bigsmp_apic_id_registered,
 
@@ -217,7 +173,7 @@ struct apic apic_bigsmp = {
 	.init_apic_ldr			= bigsmp_init_apic_ldr,
 
 	.ioapic_phys_id_map		= bigsmp_ioapic_phys_id_map,
-	.setup_apic_routing		= bigsmp_setup_apic_routing,
+	.setup_apic_routing		= NULL,
 	.multi_timer_check		= NULL,
 	.apicid_to_node			= bigsmp_apicid_to_node,
 	.cpu_to_logical_apicid		= bigsmp_cpu_to_logical_apicid,
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 99d2fe0..874f9a3 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -14,6 +14,8 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/dmi.h>
+
 #include <asm/fixmap.h>
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
@@ -52,40 +54,6 @@ static int __init print_ipi_mode(void)
 }
 late_initcall(print_ipi_mode);
 
-void __init default_setup_apic_routing(void)
-{
-	int version = apic_version[boot_cpu_physical_apicid];
-
-	if (num_possible_cpus() > 8) {
-		switch (boot_cpu_data.x86_vendor) {
-		case X86_VENDOR_INTEL:
-			if (!APIC_XAPIC(version)) {
-				def_to_bigsmp = 0;
-				break;
-			}
-			/* If P4 and above fall through */
-		case X86_VENDOR_AMD:
-			def_to_bigsmp = 1;
-		}
-	}
-
-#ifdef CONFIG_X86_BIGSMP
-	generic_bigsmp_probe();
-#endif
-
-	if (apic->setup_apic_routing)
-		apic->setup_apic_routing();
-}
-
-static void setup_apic_flat_routing(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	printk(KERN_INFO
-		"Enabling APIC mode:  Flat.  Using %d I/O APICs\n",
-		nr_ioapics);
-#endif
-}
-
 static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	/*
@@ -101,16 +69,10 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
 	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
-/* should be called last. */
-static int probe_default(void)
-{
-	return 1;
-}
-
 struct apic apic_default = {
 
 	.name				= "default",
-	.probe				= probe_default,
+	.probe				= NULL,
 	.acpi_madt_oem_check		= NULL,
 	.apic_id_registered		= default_apic_id_registered,
 
@@ -128,7 +90,7 @@ struct apic apic_default = {
 	.init_apic_ldr			= default_init_apic_ldr,
 
 	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
-	.setup_apic_routing		= setup_apic_flat_routing,
+	.setup_apic_routing		= NULL,
 	.multi_timer_check		= NULL,
 	.apicid_to_node			= default_apicid_to_node,
 	.cpu_to_logical_apicid		= default_cpu_to_logical_apicid,
@@ -217,24 +179,70 @@ static int __init parse_apic(char *arg)
 }
 early_param("apic", parse_apic);
 
-void __init generic_bigsmp_probe(void)
+static int dmi_bigsmp __initdata; /* can be set by dmi scanners */
+
+static int __init hp_ht_bigsmp(const struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
+	dmi_bigsmp = 1;
+
+	return 0;
+}
+
+static struct dmi_system_id bigsmp_dmi_table[] __initdata = {
+	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
+		}
+	},
+
+	{ hp_ht_bigsmp, "HP ProLiant DL740",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
+		}
+	},
+	{ } /* NULL entry stops DMI scanning */
+};
+
+static inline const char *get_apic_name(struct apic *apic)
+{
+	if (apic == &apic_default)
+		return "flat";
+#ifdef CONFIG_X86_BIGSMP
+	if (apic == &apic_bigsmp)
+		return "physical flat";
+#endif
+	return apic->name;
+}
+
+void __init default_setup_apic_routing(void)
 {
 #ifdef CONFIG_X86_BIGSMP
 	/*
-	 * This routine is used to switch to bigsmp mode when
-	 * - There is no apic= option specified by the user
-	 * - generic_apic_probe() has chosen apic_default as the sub_arch
-	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+	 * make sure we go to bigsmp according to real nr_cpu_ids
 	 */
-
 	if (!cmdline_apic && apic == &apic_default) {
-		if (apic_bigsmp.probe()) {
+		if (nr_cpu_ids > 8)
 			apic = &apic_bigsmp;
-			printk(KERN_INFO "Overriding APIC driver with %s\n",
-			       apic->name);
+		else {
+			dmi_check_system(bigsmp_dmi_table);
+			if (dmi_bigsmp)
+				apic = &apic_bigsmp;
 		}
+		if (apic != &apic_default)
+			printk(KERN_INFO "Overriding APIC driver with %s\n",
+			       get_apic_name(apic));
 	}
 #endif
+	if (apic->setup_apic_routing)
+		apic->setup_apic_routing();
+	else {
+#ifdef CONFIG_X86_IO_APIC
+		printk(KERN_INFO
+			"Enabling APIC mode:  %s.  Using %d I/O APICs\n",
+			get_apic_name(apic), nr_ioapics);
+#endif
+	}
 }
 
 void __init generic_apic_probe(void)
@@ -242,14 +250,13 @@ void __init generic_apic_probe(void)
 	if (!cmdline_apic) {
 		int i;
 		for (i = 0; apic_probe[i]; i++) {
+			if (!apic_probe[i]->probe)
+				continue;
 			if (apic_probe[i]->probe()) {
 				apic = apic_probe[i];
 				break;
 			}
 		}
-		/* Not visible without early console */
-		if (!apic_probe[i])
-			panic("Didn't find an APIC driver");
 	}
 	printk(KERN_INFO "Using APIC driver %s\n", apic->name);
 }
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 83e9be4..ea25de8 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -67,7 +67,7 @@ void __init default_setup_apic_routing(void)
 	}
 #endif
 
-	if (apic == &apic_flat && num_possible_cpus() > 8)
+	if (apic == &apic_flat && nr_cpu_ids > 8)
 			apic = &apic_physflat;
 
 	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 82533cf..e6ea918 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -186,8 +186,6 @@ static void set_mca_bus(int x)
 #endif
 }
 
-unsigned int def_to_bigsmp;
-
 /* for MCA, but anyone else can use it if they want */
 unsigned int machine_id;
 unsigned int machine_submodel_id;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f92885..ffd93b4 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -991,7 +991,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
 	preempt_disable();
 
 #if !defined(CONFIG_X86_BIGSMP) && defined(CONFIG_X86_32)
-	if (def_to_bigsmp && nr_cpu_ids > 8) {
+	if (apic == &apic_default && nr_cpu_ids > 8) {
 		unsigned int cpu;
 		unsigned nr;
 
-- 
1.6.4.2


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

* [PATCH 17/20] x86: make 32bit apic flat to physflat switch like 64bit
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

kill def_to_bigsmp
and move switch from default to bigsmp at default_setup_apic_routing...
so make default_setup_apic_routing more like 64 bit
also make the dmi relate code to be __init/__initdata

-v2: refresh it according to change in upstream

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/apic.h      |    3 -
 arch/x86/include/asm/mpspec.h    |    1 -
 arch/x86/kernel/apic/bigsmp_32.c |   48 +---------------
 arch/x86/kernel/apic/probe_32.c  |  115 ++++++++++++++++++++------------------
 arch/x86/kernel/apic/probe_64.c  |    2 +-
 arch/x86/kernel/setup.c          |    2 -
 arch/x86/kernel/smpboot.c        |    2 +-
 7 files changed, 65 insertions(+), 108 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 1fa03e0..6a34763 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -465,9 +465,6 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert)
 	return;
 }
 
-extern void generic_bigsmp_probe(void);
-
-
 #ifdef CONFIG_X86_LOCAL_APIC
 
 #include <asm/smp.h>
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 1a221e0..cb398c8 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -23,7 +23,6 @@ extern int pic_mode;
 
 #define MAX_IRQ_SOURCES		256
 
-extern unsigned int def_to_bigsmp;
 extern u8 apicid_2_node[];
 
 #ifdef CONFIG_X86_NUMAQ
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index cb804c5..350d60e 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -7,7 +7,6 @@
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/dmi.h>
 #include <linux/smp.h>
 
 #include <asm/apicdef.h>
@@ -73,13 +72,6 @@ static void bigsmp_init_apic_ldr(void)
 	apic_write(APIC_LDR, val);
 }
 
-static void bigsmp_setup_apic_routing(void)
-{
-	printk(KERN_INFO
-		"Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
-		nr_ioapics);
-}
-
 static int bigsmp_apicid_to_node(int logical_apicid)
 {
 	return apicid_2_node[hard_smp_processor_id()];
@@ -154,52 +146,16 @@ static void bigsmp_send_IPI_all(int vector)
 	bigsmp_send_IPI_mask(cpu_online_mask, vector);
 }
 
-static int dmi_bigsmp; /* can be set by dmi scanners */
-
-static int hp_ht_bigsmp(const struct dmi_system_id *d)
-{
-	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
-	dmi_bigsmp = 1;
-
-	return 0;
-}
-
-
-static const struct dmi_system_id bigsmp_dmi_table[] = {
-	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
-		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
-		}
-	},
-
-	{ hp_ht_bigsmp, "HP ProLiant DL740",
-		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
-		}
-	},
-	{ } /* NULL entry stops DMI scanning */
-};
-
 static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	cpumask_clear(retmask);
 	cpumask_set_cpu(cpu, retmask);
 }
 
-static int probe_bigsmp(void)
-{
-	if (def_to_bigsmp)
-		dmi_bigsmp = 1;
-	else
-		dmi_check_system(bigsmp_dmi_table);
-
-	return dmi_bigsmp;
-}
-
 struct apic apic_bigsmp = {
 
 	.name				= "bigsmp",
-	.probe				= probe_bigsmp,
+	.probe				= NULL,
 	.acpi_madt_oem_check		= NULL,
 	.apic_id_registered		= bigsmp_apic_id_registered,
 
@@ -217,7 +173,7 @@ struct apic apic_bigsmp = {
 	.init_apic_ldr			= bigsmp_init_apic_ldr,
 
 	.ioapic_phys_id_map		= bigsmp_ioapic_phys_id_map,
-	.setup_apic_routing		= bigsmp_setup_apic_routing,
+	.setup_apic_routing		= NULL,
 	.multi_timer_check		= NULL,
 	.apicid_to_node			= bigsmp_apicid_to_node,
 	.cpu_to_logical_apicid		= bigsmp_cpu_to_logical_apicid,
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 99d2fe0..874f9a3 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -14,6 +14,8 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/dmi.h>
+
 #include <asm/fixmap.h>
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
@@ -52,40 +54,6 @@ static int __init print_ipi_mode(void)
 }
 late_initcall(print_ipi_mode);
 
-void __init default_setup_apic_routing(void)
-{
-	int version = apic_version[boot_cpu_physical_apicid];
-
-	if (num_possible_cpus() > 8) {
-		switch (boot_cpu_data.x86_vendor) {
-		case X86_VENDOR_INTEL:
-			if (!APIC_XAPIC(version)) {
-				def_to_bigsmp = 0;
-				break;
-			}
-			/* If P4 and above fall through */
-		case X86_VENDOR_AMD:
-			def_to_bigsmp = 1;
-		}
-	}
-
-#ifdef CONFIG_X86_BIGSMP
-	generic_bigsmp_probe();
-#endif
-
-	if (apic->setup_apic_routing)
-		apic->setup_apic_routing();
-}
-
-static void setup_apic_flat_routing(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	printk(KERN_INFO
-		"Enabling APIC mode:  Flat.  Using %d I/O APICs\n",
-		nr_ioapics);
-#endif
-}
-
 static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	/*
@@ -101,16 +69,10 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
 	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
-/* should be called last. */
-static int probe_default(void)
-{
-	return 1;
-}
-
 struct apic apic_default = {
 
 	.name				= "default",
-	.probe				= probe_default,
+	.probe				= NULL,
 	.acpi_madt_oem_check		= NULL,
 	.apic_id_registered		= default_apic_id_registered,
 
@@ -128,7 +90,7 @@ struct apic apic_default = {
 	.init_apic_ldr			= default_init_apic_ldr,
 
 	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
-	.setup_apic_routing		= setup_apic_flat_routing,
+	.setup_apic_routing		= NULL,
 	.multi_timer_check		= NULL,
 	.apicid_to_node			= default_apicid_to_node,
 	.cpu_to_logical_apicid		= default_cpu_to_logical_apicid,
@@ -217,24 +179,70 @@ static int __init parse_apic(char *arg)
 }
 early_param("apic", parse_apic);
 
-void __init generic_bigsmp_probe(void)
+static int dmi_bigsmp __initdata; /* can be set by dmi scanners */
+
+static int __init hp_ht_bigsmp(const struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
+	dmi_bigsmp = 1;
+
+	return 0;
+}
+
+static struct dmi_system_id bigsmp_dmi_table[] __initdata = {
+	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
+		}
+	},
+
+	{ hp_ht_bigsmp, "HP ProLiant DL740",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
+		}
+	},
+	{ } /* NULL entry stops DMI scanning */
+};
+
+static inline const char *get_apic_name(struct apic *apic)
+{
+	if (apic == &apic_default)
+		return "flat";
+#ifdef CONFIG_X86_BIGSMP
+	if (apic == &apic_bigsmp)
+		return "physical flat";
+#endif
+	return apic->name;
+}
+
+void __init default_setup_apic_routing(void)
 {
 #ifdef CONFIG_X86_BIGSMP
 	/*
-	 * This routine is used to switch to bigsmp mode when
-	 * - There is no apic= option specified by the user
-	 * - generic_apic_probe() has chosen apic_default as the sub_arch
-	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+	 * make sure we go to bigsmp according to real nr_cpu_ids
 	 */
-
 	if (!cmdline_apic && apic == &apic_default) {
-		if (apic_bigsmp.probe()) {
+		if (nr_cpu_ids > 8)
 			apic = &apic_bigsmp;
-			printk(KERN_INFO "Overriding APIC driver with %s\n",
-			       apic->name);
+		else {
+			dmi_check_system(bigsmp_dmi_table);
+			if (dmi_bigsmp)
+				apic = &apic_bigsmp;
 		}
+		if (apic != &apic_default)
+			printk(KERN_INFO "Overriding APIC driver with %s\n",
+			       get_apic_name(apic));
 	}
 #endif
+	if (apic->setup_apic_routing)
+		apic->setup_apic_routing();
+	else {
+#ifdef CONFIG_X86_IO_APIC
+		printk(KERN_INFO
+			"Enabling APIC mode:  %s.  Using %d I/O APICs\n",
+			get_apic_name(apic), nr_ioapics);
+#endif
+	}
 }
 
 void __init generic_apic_probe(void)
@@ -242,14 +250,13 @@ void __init generic_apic_probe(void)
 	if (!cmdline_apic) {
 		int i;
 		for (i = 0; apic_probe[i]; i++) {
+			if (!apic_probe[i]->probe)
+				continue;
 			if (apic_probe[i]->probe()) {
 				apic = apic_probe[i];
 				break;
 			}
 		}
-		/* Not visible without early console */
-		if (!apic_probe[i])
-			panic("Didn't find an APIC driver");
 	}
 	printk(KERN_INFO "Using APIC driver %s\n", apic->name);
 }
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 83e9be4..ea25de8 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -67,7 +67,7 @@ void __init default_setup_apic_routing(void)
 	}
 #endif
 
-	if (apic == &apic_flat && num_possible_cpus() > 8)
+	if (apic == &apic_flat && nr_cpu_ids > 8)
 			apic = &apic_physflat;
 
 	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 82533cf..e6ea918 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -186,8 +186,6 @@ static void set_mca_bus(int x)
 #endif
 }
 
-unsigned int def_to_bigsmp;
-
 /* for MCA, but anyone else can use it if they want */
 unsigned int machine_id;
 unsigned int machine_submodel_id;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f92885..ffd93b4 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -991,7 +991,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
 	preempt_disable();
 
 #if !defined(CONFIG_X86_BIGSMP) && defined(CONFIG_X86_32)
-	if (def_to_bigsmp && nr_cpu_ids > 8) {
+	if (apic == &apic_default && nr_cpu_ids > 8) {
 		unsigned int cpu;
 		unsigned nr;
 
-- 
1.6.4.2

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

* [PATCH 18/20] x86: remove arch_probe_nr_irqs
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 c03bcd4..ed8002b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3917,28 +3917,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] 111+ messages in thread

* [PATCH 18/20] x86: remove arch_probe_nr_irqs
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, 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 c03bcd4..ed8002b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3917,28 +3917,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] 111+ messages in thread

* [PATCH 19/20] x86/pci: ioh new version read all at same time
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

also it will add back default range to legacy IOH

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/pci_x86.h |    5 +
 arch/x86/pci/Makefile          |    1 +
 arch/x86/pci/init.c            |    2 +
 arch/x86/pci/intel_bus.c       |  281 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 289 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/pci/intel_bus.c

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 8d8797e..e52c02a 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -107,6 +107,11 @@ extern void pci_direct_init(int type);
 extern void pci_pcbios_init(void);
 extern void __init dmi_check_pciprobe(void);
 extern void __init dmi_check_skip_isa_align(void);
+#ifdef CONFIG_PCI_MMCONFIG
+int intel_postarch_init(void);
+#else
+static inline int intel_postarch_init(void) { return 0; }
+#endif
 
 /* some common used subsys_initcalls */
 extern int __init pci_acpi_init(void);
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index b110d97..08e76bc 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_X86_MRST)		+= mrst.o
 
 obj-y				+= common.o early.o
 obj-y				+= amd_bus.o bus_numa.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= intel_bus.o
 
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index adb62aa..08d5dcf 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -39,6 +39,8 @@ static __init int pci_arch_init(void)
 
 	dmi_check_skip_isa_align();
 
+	intel_postarch_init();
+
 	return 0;
 }
 arch_initcall(pci_arch_init);
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
new file mode 100644
index 0000000..190c2c5
--- /dev/null
+++ b/arch/x86/pci/intel_bus.c
@@ -0,0 +1,281 @@
+/*
+ * to read io range from IOH pci conf, need to do it after mmconfig is there
+ */
+
+#include <linux/delay.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/range.h>
+
+#include <asm/pci_x86.h>
+
+#include "bus_numa.h"
+
+static inline void print_ioh_resources(struct pci_root_info *info)
+{
+	int res_num;
+	int busnum;
+	int i;
+
+	printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n",
+			info->bus_min, info->bus_max);
+	res_num = info->res_num;
+	busnum = info->bus_min;
+	for (i = 0; i < res_num; i++) {
+		struct resource *res;
+
+		res = &info->res[i];
+		printk(KERN_DEBUG "IOH bus: %02x index %x %pR\n",
+				busnum, i, res);
+	}
+}
+
+static void __devinit subtract_mmconf(struct range *range, int nr)
+{
+	struct pci_mmcfg_region *cfg;
+
+	if (list_empty(&pci_mmcfg_list))
+		return;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		subtract_range(range, nr, cfg->res.start, cfg->res.end + 1);
+}
+
+#define IOH_LIO			0x108
+#define IOH_LMMIOL		0x10c
+#define IOH_LMMIOH		0x110
+#define IOH_LMMIOH_BASEU	0x114
+#define IOH_LMMIOH_LIMITU	0x118
+#define IOH_LCFGBUS		0x11c
+
+#define IOH_VTBAR		0x180
+#define IOH_VTSIZE		0x2000  /* Fixed HW size (not programmable) */
+
+#define RANGE_NUM		16
+
+#define RANGE_IO_NUM		16
+#define RANGE_MMIO_NUM		32
+static struct range range_io[RANGE_IO_NUM] __initdata;
+static struct range range_mmio[RANGE_MMIO_NUM] __initdata;
+static int def_ioh __initdata = -1;
+
+static void __init check_ioh_tom(int num, int slot, int func)
+{
+	u32 dword;
+	u64 tocm, tolm, tohm;
+
+	raw_pci_read(0, num, (slot<<3)|func, 0x98, 4, &dword);
+	/* is Legacy IOH with ESI? */
+	if ((dword & (3<<10)) == 0) {
+		if (def_ioh < 0)
+			def_ioh = pci_root_num;
+		else
+			printk(KERN_DEBUG "Multiple legacy IOHs ?\n");
+	}
+
+	/* top of address */
+	tocm = 1ULL<<(((dword >> 3) & 0x1f) + (37 - 5));
+	subtract_range(range_mmio, RANGE_MMIO_NUM, tocm, -1ULL);
+	/* private CSR 64G */
+	subtract_range(range_mmio, RANGE_MMIO_NUM, tocm - (64ULL<<30), tocm);
+	/* top of low mem */
+	raw_pci_read(0, num, (slot<<3)|func, 0xd0, 4, &dword);
+	tolm = dword & (0x3f<<26);
+	tolm += 1<<26;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, 0, tolm);
+	/* top of high mem */
+	raw_pci_read(0, num, (slot<<3)|func, 0xd8, 4, &dword);
+	tohm = dword;
+	tohm <<= 32;
+	raw_pci_read(0, num, (slot<<3)|func, 0xd4, 4, &dword);
+	tohm |= dword & (0x3f<<26);
+	tohm += 1<<26;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, 1ULL<<32, tohm);
+	printk(KERN_DEBUG "IOH bus 0x%02x tolm: 0x%llxM, tohm: 0x%llxM, tocm: 0x%llxM\n",
+			 num, tolm>>20, tohm>>20, tocm>>20);
+}
+
+static void __init read_ioh_res(int num, int slot, int func)
+{
+	u32 dword;
+	struct pci_root_info *info;
+	u16 io_base, io_end;
+	u32 mmiol_base, mmiol_end;
+	u64 mmioh_base, mmioh_end;
+	int bus_base, bus_end;
+	struct range range[RANGE_NUM];
+	int i;
+
+
+	if (pci_root_num >= PCI_ROOT_NR) {
+		printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n");
+		return;
+	}
+
+	check_ioh_tom(num, slot, func);
+
+	info = &pci_root_info[pci_root_num];
+	pci_root_num++;
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LCFGBUS, 2, &dword);
+	bus_base = (dword & 0xff);
+	bus_end = (dword & 0xff00) >> 8;
+	sprintf(info->name, "PCI Bus #%02x", bus_base);
+	info->bus_min = bus_base;
+	info->bus_max = bus_end;
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LIO, 2, &dword);
+	io_base = (dword & 0xf0) << (12 - 4);
+	io_end = (dword & 0xf000) | 0xfff;
+	update_res(info, io_base, io_end, IORESOURCE_IO, 0);
+	subtract_range(range_io, RANGE_IO_NUM, io_base, io_end + 1);
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOL, 4, &dword);
+	mmiol_base = (dword & 0xff00) << (24 - 8);
+	mmiol_end = (dword & 0xff000000) | 0xffffff;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, mmiol_base, mmiol_end + 1);
+	memset(range, 0, sizeof(range));
+	add_range(range, RANGE_NUM, 0, mmiol_base, (u64)mmiol_end + 1);
+	raw_pci_read(0, num, (slot<<3)|func, IOH_VTBAR, 4, &dword);
+	if (dword & 0x1) {
+		u32 vt_base, vt_end;
+
+		vt_base = dword & 0xfffffffe;
+		vt_end = vt_base + IOH_VTSIZE - 1;
+
+		subtract_range(range, RANGE_NUM, vt_base, vt_end + 1);
+		subtract_range(range_mmio, RANGE_MMIO_NUM, vt_base, vt_end + 1);
+	}
+	for (i = 0; i < RANGE_NUM; i++) {
+		if (!range[i].end)
+			continue;
+
+		update_res(info, cap_resource(range[i].start),
+				cap_resource(range[i].end - 1),
+				IORESOURCE_MEM, 0);
+	}
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH, 4, &dword);
+	mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
+	mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff);
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH_BASEU, 4, &dword);
+	mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH_LIMITU, 4, &dword);
+	mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
+	update_res(info, cap_resource(mmioh_base), cap_resource(mmioh_end),
+			 IORESOURCE_MEM, 0);
+	subtract_range(range_mmio, RANGE_MMIO_NUM, mmioh_base, mmioh_end + 1);
+
+	print_ioh_resources(info);
+}
+
+struct pci_check_probe {
+	u32 vendor;
+	u32 device;
+	void (*f)(int num, int slot, int func);
+};
+
+static struct pci_check_probe early_qrk[] __initdata = {
+	{ PCI_VENDOR_ID_INTEL, 0x342e, read_ioh_res }, /* intel IOH */
+	{}
+};
+
+static void __init postarch_check_pci_dev(int num, int slot, int func)
+{
+	u32 vendor;
+	u32 device;
+	int i;
+
+	raw_pci_read(0, num, (slot<<3)|func, PCI_VENDOR_ID, 2, &vendor);
+	raw_pci_read(0, num, (slot<<3)|func, PCI_DEVICE_ID, 2, &device);
+
+	for (i = 0; early_qrk[i].f != NULL; i++) {
+		if (((early_qrk[i].vendor == PCI_ANY_ID) ||
+			(early_qrk[i].vendor == vendor)) &&
+			((early_qrk[i].device == PCI_ANY_ID) ||
+			(early_qrk[i].device == device)))
+				early_qrk[i].f(num, slot, func);
+	}
+}
+
+static void __init postarch_check_pci_devs(void)
+{
+	unsigned bus, slot, func;
+	struct pci_root_info *info;
+	int i;
+
+	memset(range_io, 0, sizeof(range_io));
+	add_range(range_io, RANGE_IO_NUM, 0, 0, 0xffff + 1);
+
+	memset(range_mmio, 0, sizeof(range_mmio));
+	add_range(range_mmio, RANGE_MMIO_NUM, 0, 0, -1ULL);
+
+	for (bus = 0; bus < 256; bus++) {
+		for (slot = 0; slot < 32; slot++) {
+			for (func = 0; func < 8; func++) {
+				u32 class;
+				u32 type;
+
+				raw_pci_read(0, bus, (slot<<3)|func,
+						PCI_CLASS_REVISION, 4, &class);
+				if (class == 0xffffffff)
+					continue;
+
+				postarch_check_pci_dev(bus, slot, func);
+
+				if (func == 0) {
+					raw_pci_read(0, bus, (slot<<3)|func,
+					       PCI_HEADER_TYPE, 1, &type);
+					if (!(type & 0x80))
+						break;
+				}
+			}
+		}
+	}
+
+	if (def_ioh < 0)
+		return;
+
+	/* add default io */
+	info = &pci_root_info[def_ioh];
+	for (i = 0; i < RANGE_IO_NUM; i++) {
+		if (!range_io[i].end)
+			continue;
+
+		update_res(info, range_io[i].start, range_io[i].end - 1,
+			   IORESOURCE_IO, 0);
+	}
+
+	subtract_mmconf(range_mmio, RANGE_MMIO_NUM);
+
+	/* add default default mmio */
+	for (i = 0; i < RANGE_MMIO_NUM; i++) {
+		if (!range_mmio[i].end)
+			continue;
+
+		update_res(info, cap_resource(range_mmio[i].start),
+			   cap_resource(range_mmio[i].end - 1),
+			   IORESOURCE_MEM, 0);
+	}
+	printk(KERN_DEBUG "IOH Legacy final with default routing:\n");
+	print_ioh_resources(info);
+}
+
+/*
+ * need to call it just after pci_arch_init
+ * so we can have mmconf ready
+ */
+int __init intel_postarch_init(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (!pci_ext_cfg_avail(NULL))
+		return 0;
+
+	postarch_check_pci_devs();
+
+	return 0;
+}
+
-- 
1.6.4.2


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

* [PATCH 19/20] x86/pci: ioh new version read all at same time
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

also it will add back default range to legacy IOH

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/pci_x86.h |    5 +
 arch/x86/pci/Makefile          |    1 +
 arch/x86/pci/init.c            |    2 +
 arch/x86/pci/intel_bus.c       |  281 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 289 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/pci/intel_bus.c

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 8d8797e..e52c02a 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -107,6 +107,11 @@ extern void pci_direct_init(int type);
 extern void pci_pcbios_init(void);
 extern void __init dmi_check_pciprobe(void);
 extern void __init dmi_check_skip_isa_align(void);
+#ifdef CONFIG_PCI_MMCONFIG
+int intel_postarch_init(void);
+#else
+static inline int intel_postarch_init(void) { return 0; }
+#endif
 
 /* some common used subsys_initcalls */
 extern int __init pci_acpi_init(void);
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index b110d97..08e76bc 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_X86_MRST)		+= mrst.o
 
 obj-y				+= common.o early.o
 obj-y				+= amd_bus.o bus_numa.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= intel_bus.o
 
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index adb62aa..08d5dcf 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -39,6 +39,8 @@ static __init int pci_arch_init(void)
 
 	dmi_check_skip_isa_align();
 
+	intel_postarch_init();
+
 	return 0;
 }
 arch_initcall(pci_arch_init);
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
new file mode 100644
index 0000000..190c2c5
--- /dev/null
+++ b/arch/x86/pci/intel_bus.c
@@ -0,0 +1,281 @@
+/*
+ * to read io range from IOH pci conf, need to do it after mmconfig is there
+ */
+
+#include <linux/delay.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/range.h>
+
+#include <asm/pci_x86.h>
+
+#include "bus_numa.h"
+
+static inline void print_ioh_resources(struct pci_root_info *info)
+{
+	int res_num;
+	int busnum;
+	int i;
+
+	printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n",
+			info->bus_min, info->bus_max);
+	res_num = info->res_num;
+	busnum = info->bus_min;
+	for (i = 0; i < res_num; i++) {
+		struct resource *res;
+
+		res = &info->res[i];
+		printk(KERN_DEBUG "IOH bus: %02x index %x %pR\n",
+				busnum, i, res);
+	}
+}
+
+static void __devinit subtract_mmconf(struct range *range, int nr)
+{
+	struct pci_mmcfg_region *cfg;
+
+	if (list_empty(&pci_mmcfg_list))
+		return;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		subtract_range(range, nr, cfg->res.start, cfg->res.end + 1);
+}
+
+#define IOH_LIO			0x108
+#define IOH_LMMIOL		0x10c
+#define IOH_LMMIOH		0x110
+#define IOH_LMMIOH_BASEU	0x114
+#define IOH_LMMIOH_LIMITU	0x118
+#define IOH_LCFGBUS		0x11c
+
+#define IOH_VTBAR		0x180
+#define IOH_VTSIZE		0x2000  /* Fixed HW size (not programmable) */
+
+#define RANGE_NUM		16
+
+#define RANGE_IO_NUM		16
+#define RANGE_MMIO_NUM		32
+static struct range range_io[RANGE_IO_NUM] __initdata;
+static struct range range_mmio[RANGE_MMIO_NUM] __initdata;
+static int def_ioh __initdata = -1;
+
+static void __init check_ioh_tom(int num, int slot, int func)
+{
+	u32 dword;
+	u64 tocm, tolm, tohm;
+
+	raw_pci_read(0, num, (slot<<3)|func, 0x98, 4, &dword);
+	/* is Legacy IOH with ESI? */
+	if ((dword & (3<<10)) == 0) {
+		if (def_ioh < 0)
+			def_ioh = pci_root_num;
+		else
+			printk(KERN_DEBUG "Multiple legacy IOHs ?\n");
+	}
+
+	/* top of address */
+	tocm = 1ULL<<(((dword >> 3) & 0x1f) + (37 - 5));
+	subtract_range(range_mmio, RANGE_MMIO_NUM, tocm, -1ULL);
+	/* private CSR 64G */
+	subtract_range(range_mmio, RANGE_MMIO_NUM, tocm - (64ULL<<30), tocm);
+	/* top of low mem */
+	raw_pci_read(0, num, (slot<<3)|func, 0xd0, 4, &dword);
+	tolm = dword & (0x3f<<26);
+	tolm += 1<<26;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, 0, tolm);
+	/* top of high mem */
+	raw_pci_read(0, num, (slot<<3)|func, 0xd8, 4, &dword);
+	tohm = dword;
+	tohm <<= 32;
+	raw_pci_read(0, num, (slot<<3)|func, 0xd4, 4, &dword);
+	tohm |= dword & (0x3f<<26);
+	tohm += 1<<26;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, 1ULL<<32, tohm);
+	printk(KERN_DEBUG "IOH bus 0x%02x tolm: 0x%llxM, tohm: 0x%llxM, tocm: 0x%llxM\n",
+			 num, tolm>>20, tohm>>20, tocm>>20);
+}
+
+static void __init read_ioh_res(int num, int slot, int func)
+{
+	u32 dword;
+	struct pci_root_info *info;
+	u16 io_base, io_end;
+	u32 mmiol_base, mmiol_end;
+	u64 mmioh_base, mmioh_end;
+	int bus_base, bus_end;
+	struct range range[RANGE_NUM];
+	int i;
+
+
+	if (pci_root_num >= PCI_ROOT_NR) {
+		printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n");
+		return;
+	}
+
+	check_ioh_tom(num, slot, func);
+
+	info = &pci_root_info[pci_root_num];
+	pci_root_num++;
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LCFGBUS, 2, &dword);
+	bus_base = (dword & 0xff);
+	bus_end = (dword & 0xff00) >> 8;
+	sprintf(info->name, "PCI Bus #%02x", bus_base);
+	info->bus_min = bus_base;
+	info->bus_max = bus_end;
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LIO, 2, &dword);
+	io_base = (dword & 0xf0) << (12 - 4);
+	io_end = (dword & 0xf000) | 0xfff;
+	update_res(info, io_base, io_end, IORESOURCE_IO, 0);
+	subtract_range(range_io, RANGE_IO_NUM, io_base, io_end + 1);
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOL, 4, &dword);
+	mmiol_base = (dword & 0xff00) << (24 - 8);
+	mmiol_end = (dword & 0xff000000) | 0xffffff;
+	subtract_range(range_mmio, RANGE_MMIO_NUM, mmiol_base, mmiol_end + 1);
+	memset(range, 0, sizeof(range));
+	add_range(range, RANGE_NUM, 0, mmiol_base, (u64)mmiol_end + 1);
+	raw_pci_read(0, num, (slot<<3)|func, IOH_VTBAR, 4, &dword);
+	if (dword & 0x1) {
+		u32 vt_base, vt_end;
+
+		vt_base = dword & 0xfffffffe;
+		vt_end = vt_base + IOH_VTSIZE - 1;
+
+		subtract_range(range, RANGE_NUM, vt_base, vt_end + 1);
+		subtract_range(range_mmio, RANGE_MMIO_NUM, vt_base, vt_end + 1);
+	}
+	for (i = 0; i < RANGE_NUM; i++) {
+		if (!range[i].end)
+			continue;
+
+		update_res(info, cap_resource(range[i].start),
+				cap_resource(range[i].end - 1),
+				IORESOURCE_MEM, 0);
+	}
+
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH, 4, &dword);
+	mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
+	mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff);
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH_BASEU, 4, &dword);
+	mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
+	raw_pci_read(0, num, (slot<<3)|func, IOH_LMMIOH_LIMITU, 4, &dword);
+	mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
+	update_res(info, cap_resource(mmioh_base), cap_resource(mmioh_end),
+			 IORESOURCE_MEM, 0);
+	subtract_range(range_mmio, RANGE_MMIO_NUM, mmioh_base, mmioh_end + 1);
+
+	print_ioh_resources(info);
+}
+
+struct pci_check_probe {
+	u32 vendor;
+	u32 device;
+	void (*f)(int num, int slot, int func);
+};
+
+static struct pci_check_probe early_qrk[] __initdata = {
+	{ PCI_VENDOR_ID_INTEL, 0x342e, read_ioh_res }, /* intel IOH */
+	{}
+};
+
+static void __init postarch_check_pci_dev(int num, int slot, int func)
+{
+	u32 vendor;
+	u32 device;
+	int i;
+
+	raw_pci_read(0, num, (slot<<3)|func, PCI_VENDOR_ID, 2, &vendor);
+	raw_pci_read(0, num, (slot<<3)|func, PCI_DEVICE_ID, 2, &device);
+
+	for (i = 0; early_qrk[i].f != NULL; i++) {
+		if (((early_qrk[i].vendor == PCI_ANY_ID) ||
+			(early_qrk[i].vendor == vendor)) &&
+			((early_qrk[i].device == PCI_ANY_ID) ||
+			(early_qrk[i].device == device)))
+				early_qrk[i].f(num, slot, func);
+	}
+}
+
+static void __init postarch_check_pci_devs(void)
+{
+	unsigned bus, slot, func;
+	struct pci_root_info *info;
+	int i;
+
+	memset(range_io, 0, sizeof(range_io));
+	add_range(range_io, RANGE_IO_NUM, 0, 0, 0xffff + 1);
+
+	memset(range_mmio, 0, sizeof(range_mmio));
+	add_range(range_mmio, RANGE_MMIO_NUM, 0, 0, -1ULL);
+
+	for (bus = 0; bus < 256; bus++) {
+		for (slot = 0; slot < 32; slot++) {
+			for (func = 0; func < 8; func++) {
+				u32 class;
+				u32 type;
+
+				raw_pci_read(0, bus, (slot<<3)|func,
+						PCI_CLASS_REVISION, 4, &class);
+				if (class == 0xffffffff)
+					continue;
+
+				postarch_check_pci_dev(bus, slot, func);
+
+				if (func == 0) {
+					raw_pci_read(0, bus, (slot<<3)|func,
+					       PCI_HEADER_TYPE, 1, &type);
+					if (!(type & 0x80))
+						break;
+				}
+			}
+		}
+	}
+
+	if (def_ioh < 0)
+		return;
+
+	/* add default io */
+	info = &pci_root_info[def_ioh];
+	for (i = 0; i < RANGE_IO_NUM; i++) {
+		if (!range_io[i].end)
+			continue;
+
+		update_res(info, range_io[i].start, range_io[i].end - 1,
+			   IORESOURCE_IO, 0);
+	}
+
+	subtract_mmconf(range_mmio, RANGE_MMIO_NUM);
+
+	/* add default default mmio */
+	for (i = 0; i < RANGE_MMIO_NUM; i++) {
+		if (!range_mmio[i].end)
+			continue;
+
+		update_res(info, cap_resource(range_mmio[i].start),
+			   cap_resource(range_mmio[i].end - 1),
+			   IORESOURCE_MEM, 0);
+	}
+	printk(KERN_DEBUG "IOH Legacy final with default routing:\n");
+	print_ioh_resources(info);
+}
+
+/*
+ * need to call it just after pci_arch_init
+ * so we can have mmconf ready
+ */
+int __init intel_postarch_init(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (!pci_ext_cfg_avail(NULL))
+		return 0;
+
+	postarch_check_pci_devs();
+
+	return 0;
+}
+
-- 
1.6.4.2

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

* [PATCH 20/20] x86/pci: add mmconf range into e820 for when it is from MSR with amd faml0h
  2010-03-21  7:13 ` Yinghai Lu
@ 2010-03-21  7:13   ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

for AMD Fam10h, it we read mmconf from MSR early, we should just trust it
because we check it and correct it already.

so add it to e820

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/kernel/mmconf-fam10h_64.c |   40 ++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
index 7182580..4426fd2 100644
--- a/arch/x86/kernel/mmconf-fam10h_64.c
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -16,6 +16,7 @@
 #include <asm/acpi.h>
 #include <asm/mmconfig.h>
 #include <asm/pci_x86.h>
+#include <asm/e820.h>
 
 struct pci_hostbridge_probe {
 	u32 bus;
@@ -27,23 +28,26 @@ struct pci_hostbridge_probe {
 static u64 __cpuinitdata fam10h_pci_mmconf_base;
 static int __cpuinitdata fam10h_pci_mmconf_base_status;
 
+/* only on BSP */
+static void __init_refok e820_add_mmconf_range(int busnbits)
+{
+	u64 end;
+
+	end = fam10h_pci_mmconf_base + (1ULL<<(busnbits + 20)) - 1;
+	if (!e820_all_mapped(fam10h_pci_mmconf_base, end+1, E820_RESERVED)) {
+		printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n",
+				 fam10h_pci_mmconf_base, end);
+		e820_add_region(fam10h_pci_mmconf_base, 1ULL<<(busnbits + 20),
+				 E820_RESERVED);
+		sanitize_e820_map();
+	}
+}
+
 static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
 	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
 };
 
-static int __cpuinit cmp_range(const void *x1, const void *x2)
-{
-	const struct range *r1 = x1;
-	const struct range *r2 = x2;
-	int start1, start2;
-
-	start1 = r1->start >> 32;
-	start2 = r2->start >> 32;
-
-	return start1 - start2;
-}
-
 /*[47:0] */
 /* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */
 #define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32)
@@ -115,6 +119,7 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 	 * above 4G
 	 */
 	hi_mmio_num = 0;
+	memset(range, 0, sizeof(range));
 	for (i = 0; i < 8; i++) {
 		u32 reg;
 		u64 start;
@@ -130,16 +135,14 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 		if (!end)
 			continue;
 
-		range[hi_mmio_num].start = start;
-		range[hi_mmio_num].end = end;
-		hi_mmio_num++;
+		hi_mmio_num = add_range(range, 8, hi_mmio_num, start, end);
 	}
 
 	if (!hi_mmio_num)
 		goto out;
 
 	/* sort the range */
-	sort(range, hi_mmio_num, sizeof(struct range), cmp_range, NULL);
+	sort_range(range, hi_mmio_num);
 
 	if (range[hi_mmio_num - 1].end < base)
 		goto out;
@@ -169,6 +172,7 @@ fail:
 out:
 	fam10h_pci_mmconf_base = base;
 	fam10h_pci_mmconf_base_status = 1;
+	e820_add_mmconf_range(8);
 }
 
 void __cpuinit fam10h_check_enable_mmcfg(void)
@@ -191,10 +195,12 @@ void __cpuinit fam10h_check_enable_mmcfg(void)
 		/* only trust the one handle 256 buses, if acpi=off */
 		if (!acpi_pci_disabled || busnbits >= 8) {
 			u64 base;
-			base = val & (0xffffULL << 32);
+			base = val & (FAM10H_MMIO_CONF_BASE_MASK <<
+					FAM10H_MMIO_CONF_BASE_SHIFT);
 			if (fam10h_pci_mmconf_base_status <= 0) {
 				fam10h_pci_mmconf_base = base;
 				fam10h_pci_mmconf_base_status = 1;
+				e820_add_mmconf_range(busnbits);
 				return;
 			} else if (fam10h_pci_mmconf_base ==  base)
 				return;
-- 
1.6.4.2


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

* [PATCH 20/20] x86/pci: add mmconf range into e820 for when it is from MSR with amd faml0h
@ 2010-03-21  7:13   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-21  7:13 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Je
  Cc: Eric W. Biederman, linux-kernel, linux-arch, Yinghai Lu

for AMD Fam10h, it we read mmconf from MSR early, we should just trust it
because we check it and correct it already.

so add it to e820

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/kernel/mmconf-fam10h_64.c |   40 ++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
index 7182580..4426fd2 100644
--- a/arch/x86/kernel/mmconf-fam10h_64.c
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -16,6 +16,7 @@
 #include <asm/acpi.h>
 #include <asm/mmconfig.h>
 #include <asm/pci_x86.h>
+#include <asm/e820.h>
 
 struct pci_hostbridge_probe {
 	u32 bus;
@@ -27,23 +28,26 @@ struct pci_hostbridge_probe {
 static u64 __cpuinitdata fam10h_pci_mmconf_base;
 static int __cpuinitdata fam10h_pci_mmconf_base_status;
 
+/* only on BSP */
+static void __init_refok e820_add_mmconf_range(int busnbits)
+{
+	u64 end;
+
+	end = fam10h_pci_mmconf_base + (1ULL<<(busnbits + 20)) - 1;
+	if (!e820_all_mapped(fam10h_pci_mmconf_base, end+1, E820_RESERVED)) {
+		printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n",
+				 fam10h_pci_mmconf_base, end);
+		e820_add_region(fam10h_pci_mmconf_base, 1ULL<<(busnbits + 20),
+				 E820_RESERVED);
+		sanitize_e820_map();
+	}
+}
+
 static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
 	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
 };
 
-static int __cpuinit cmp_range(const void *x1, const void *x2)
-{
-	const struct range *r1 = x1;
-	const struct range *r2 = x2;
-	int start1, start2;
-
-	start1 = r1->start >> 32;
-	start2 = r2->start >> 32;
-
-	return start1 - start2;
-}
-
 /*[47:0] */
 /* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */
 #define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32)
@@ -115,6 +119,7 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 	 * above 4G
 	 */
 	hi_mmio_num = 0;
+	memset(range, 0, sizeof(range));
 	for (i = 0; i < 8; i++) {
 		u32 reg;
 		u64 start;
@@ -130,16 +135,14 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 		if (!end)
 			continue;
 
-		range[hi_mmio_num].start = start;
-		range[hi_mmio_num].end = end;
-		hi_mmio_num++;
+		hi_mmio_num = add_range(range, 8, hi_mmio_num, start, end);
 	}
 
 	if (!hi_mmio_num)
 		goto out;
 
 	/* sort the range */
-	sort(range, hi_mmio_num, sizeof(struct range), cmp_range, NULL);
+	sort_range(range, hi_mmio_num);
 
 	if (range[hi_mmio_num - 1].end < base)
 		goto out;
@@ -169,6 +172,7 @@ fail:
 out:
 	fam10h_pci_mmconf_base = base;
 	fam10h_pci_mmconf_base_status = 1;
+	e820_add_mmconf_range(8);
 }
 
 void __cpuinit fam10h_check_enable_mmcfg(void)
@@ -191,10 +195,12 @@ void __cpuinit fam10h_check_enable_mmcfg(void)
 		/* only trust the one handle 256 buses, if acpi=off */
 		if (!acpi_pci_disabled || busnbits >= 8) {
 			u64 base;
-			base = val & (0xffffULL << 32);
+			base = val & (FAM10H_MMIO_CONF_BASE_MASK <<
+					FAM10H_MMIO_CONF_BASE_SHIFT);
 			if (fam10h_pci_mmconf_base_status <= 0) {
 				fam10h_pci_mmconf_base = base;
 				fam10h_pci_mmconf_base_status = 1;
+				e820_add_mmconf_range(busnbits);
 				return;
 			} else if (fam10h_pci_mmconf_base ==  base)
 				return;
-- 
1.6.4.2

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

* Re: [PATCH 00/20] x86: early_res and irq_desc
  2010-03-21  7:13 ` Yinghai Lu
                   ` (20 preceding siblings ...)
  (?)
@ 2010-03-22  2:35 ` Benjamin Herrenschmidt
  2010-03-22  3:26   ` Yinghai Lu
  -1 siblings, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22  2:35 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

On Sun, 2010-03-21 at 00:13 -0700, Yinghai Lu wrote:
> 01 - 06: early_res related
> 07 - 15: irq_desc releated
> 19 - 20: pci related

First of all, please post separate series, it's hard enough as it-is.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-21  7:13   ` Yinghai Lu
  (?)
@ 2010-03-22  2:37   ` Benjamin Herrenschmidt
  2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
  2010-03-22  3:56     ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
  -1 siblings, 2 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22  2:37 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

On Sun, 2010-03-21 at 00:13 -0700, Yinghai Lu wrote:
> move it to kernel/fw_memmap.c from arch/x86/kernel/e820.c
> 
> -v2: add fw_memmap wrapper to some func...
>      move some functions back to e820.c

NAK

This is even worse than before. You are now moving that entire pile of
x86 gunk into "generic" code, but even keep it names e820 there !

What happened to the discussion we had earlier, which iirc concluded
that a better approach would be to adapt x86 to use LMB ?

Cheers,
Ben.

> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  arch/x86/include/asm/e820.h  |  176 ++++++-------
>  arch/x86/kernel/e820.c       |  638 ++----------------------------------------
>  include/linux/bootmem.h      |    2 +-
>  include/linux/early_res.h    |    1 +
>  include/linux/fw_memmap.h    |   40 +++
>  kernel/Makefile              |    2 +-
>  kernel/fw_memmap.c           |  625 +++++++++++++++++++++++++++++++++++++++++
>  kernel/fw_memmap_internals.h |   49 ++++
>  8 files changed, 822 insertions(+), 711 deletions(-)
>  create mode 100644 include/linux/fw_memmap.h
>  create mode 100644 kernel/fw_memmap.c
>  create mode 100644 kernel/fw_memmap_internals.h
> 
> diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
> index 71c0348..c038616 100644
> --- a/arch/x86/include/asm/e820.h
> +++ b/arch/x86/include/asm/e820.h
> @@ -1,65 +1,10 @@
>  #ifndef _ASM_X86_E820_H
>  #define _ASM_X86_E820_H
> -#define E820MAP	0x2d0		/* our map */
> -#define E820MAX	128		/* number of entries in E820MAP */
> -
> -/*
> - * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
> - * constrained space in the zeropage.  If we have more nodes than
> - * that, and if we've booted off EFI firmware, then the EFI tables
> - * passed us from the EFI firmware can list more nodes.  Size our
> - * internal memory map tables to have room for these additional
> - * nodes, based on up to three entries per node for which the
> - * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
> - * plus E820MAX, allowing space for the possible duplicate E820
> - * entries that might need room in the same arrays, prior to the
> - * call to sanitize_e820_map() to remove duplicates.  The allowance
> - * of three memory map entries per node is "enough" entries for
> - * the initial hardware platform motivating this mechanism to make
> - * use of additional EFI map entries.  Future platforms may want
> - * to allow more than three entries per node or otherwise refine
> - * this size.
> - */
> -
> -/*
> - * Odd: 'make headers_check' complains about numa.h if I try
> - * to collapse the next two #ifdef lines to a single line:
> - *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
> - */
> -#ifdef __KERNEL__
> -#ifdef CONFIG_EFI
> -#include <linux/numa.h>
> -#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
> -#else	/* ! CONFIG_EFI */
> -#define E820_X_MAX E820MAX
> -#endif
> -#else	/* ! __KERNEL__ */
> -#define E820_X_MAX E820MAX
> -#endif
> -
> -#define E820NR	0x1e8		/* # entries in E820MAP */
> -
> -#define E820_RAM	1
> -#define E820_RESERVED	2
> -#define E820_ACPI	3
> -#define E820_NVS	4
> -#define E820_UNUSABLE	5
>  
>  /* reserved RAM used by kernel itself */
>  #define E820_RESERVED_KERN        128
>  
>  #ifndef __ASSEMBLY__
> -#include <linux/types.h>
> -struct e820entry {
> -	__u64 addr;	/* start of memory segment */
> -	__u64 size;	/* size of memory segment */
> -	__u32 type;	/* type of memory segment */
> -} __attribute__((packed));
> -
> -struct e820map {
> -	__u32 nr_map;
> -	struct e820entry map[E820_X_MAX];
> -};
>  
>  #define ISA_START_ADDRESS	0xa0000
>  #define ISA_END_ADDRESS		0x100000
> @@ -69,32 +14,18 @@ struct e820map {
>  
>  #ifdef __KERNEL__
>  
> -#ifdef CONFIG_X86_OOSTORE
> -extern int centaur_ram_top;
> -void get_centaur_ram_top(void);
> +#include <linux/fw_memmap.h>
> +
> +#ifdef CONFIG_MEMTEST
> +extern void early_memtest(unsigned long start, unsigned long end);
>  #else
> -static inline void get_centaur_ram_top(void)
> +static inline void early_memtest(unsigned long start, unsigned long end)
>  {
>  }
>  #endif
>  
>  extern unsigned long pci_mem_start;
> -extern int e820_any_mapped(u64 start, u64 end, unsigned type);
> -extern int e820_all_mapped(u64 start, u64 end, unsigned type);
> -extern void e820_add_region(u64 start, u64 size, int type);
> -extern void e820_print_map(char *who);
> -int sanitize_e820_map(void);
> -void save_e820_map(void);
> -extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
> -			       unsigned new_type);
> -extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
> -			     int checktype);
> -extern void update_e820(void);
>  extern void e820_setup_gap(void);
> -extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
> -			unsigned long start_addr, unsigned long long end_addr);
> -struct setup_data;
> -extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
>  
>  #if defined(CONFIG_X86_64) || \
>  	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
> @@ -105,37 +36,80 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
>  }
>  #endif
>  
> -#ifdef CONFIG_MEMTEST
> -extern void early_memtest(unsigned long start, unsigned long end);
> -#else
> -static inline void early_memtest(unsigned long start, unsigned long end)
> +static inline void e820_add_region(u64 start, u64 size, int type)
>  {
> +	fw_memmap_add_region(start, size, type);
> +}
> +
> +static inline void e820_print_map(char *who)
> +{
> +	fw_memmap_print_map(who);
> +}
> +
> +static inline int sanitize_e820_map(void)
> +{
> +	return sanitize_fw_memmap();
> +}
> +
> +static inline void finish_e820_parsing(void)
> +{
> +	finish_fw_memmap_parsing();
> +}
> +
> +static inline void e820_register_active_regions(int nid,
> +						unsigned long start_pfn,
> +						unsigned long end_pfn)
> +{
> +	fw_memmap_register_active_regions(nid, start_pfn, end_pfn);
> +}
> +
> +static inline u64 e820_hole_size(u64 start, u64 end)
> +{
> +	return fw_memmap_hole_size(start, end);
> +}
> +
> +static inline u64 find_e820_area(u64 start, u64 end, u64 size, u64 align)
> +{
> +	return find_fw_memmap_area(start, end, size, align);
> +}
> +
> +static inline u64 find_e820_area_node(int nid, u64 start, u64 end,
> +					 u64 size, u64 align)
> +{
> +	return find_fw_memmap_area_node(nid, start, end, size, align);
>  }
> -#endif
>  
> -extern unsigned long end_user_pfn;
> +static inline unsigned long e820_end_of_ram_pfn(void)
> +{
> +	return fw_memmap_end_of_ram_pfn();
> +}
> +
> +void clear_e820_map(void);
> +
> +extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
> +				int checktype);
> +struct e820entry;
> +int __sanitize_e820_map(struct e820entry *biosmap, int max_nr, u32 *pnr_map);
> +extern unsigned long e820_end_of_low_ram_pfn(void);
> +
> +extern int e820_any_mapped(u64 start, u64 end, unsigned type);
> +extern int e820_all_mapped(u64 start, u64 end, unsigned type);
> +extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
> +			       unsigned new_type);
> +
> +extern void update_e820(void);
> +void save_e820_map(void);
> +struct setup_data;
> +extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
> +extern char *default_machine_specific_memory_setup(void);
> +extern void setup_memory_map(void);
>  
> -extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
>  extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
> -u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
> +
>  extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
> -#include <linux/early_res.h>
>  
> -extern unsigned long e820_end_of_ram_pfn(void);
> -extern unsigned long e820_end_of_low_ram_pfn(void);
> -extern int e820_find_active_region(const struct e820entry *ei,
> -				  unsigned long start_pfn,
> -				  unsigned long last_pfn,
> -				  unsigned long *ei_startpfn,
> -				  unsigned long *ei_endpfn);
> -extern void e820_register_active_regions(int nid, unsigned long start_pfn,
> -					 unsigned long end_pfn);
> -extern u64 e820_hole_size(u64 start, u64 end);
> -extern void finish_e820_parsing(void);
>  extern void e820_reserve_resources(void);
>  extern void e820_reserve_resources_late(void);
> -extern void setup_memory_map(void);
> -extern char *default_machine_specific_memory_setup(void);
>  
>  /*
>   * Returns true iff the specified range [s,e) is completely contained inside
> @@ -146,7 +120,17 @@ static inline bool is_ISA_range(u64 s, u64 e)
>  	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
>  }
>  
> +#ifdef CONFIG_X86_OOSTORE
> +extern int centaur_ram_top;
> +void get_centaur_ram_top(void);
> +#else
> +static inline void get_centaur_ram_top(void)
> +{
> +}
> +#endif
> +
>  #endif /* __KERNEL__ */
> +
>  #endif /* __ASSEMBLY__ */
>  
>  #ifdef __KERNEL__
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index a558609..9f125ca 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -12,18 +12,15 @@
>  #include <linux/types.h>
>  #include <linux/init.h>
>  #include <linux/bootmem.h>
> -#include <linux/pfn.h>
>  #include <linux/suspend.h>
>  #include <linux/firmware-map.h>
>  
>  #include <asm/e820.h>
> -#include <asm/proto.h>
>  #include <asm/setup.h>
>  
> +#include "../../../kernel/fw_memmap_internals.h"
> +
>  /*
> - * The e820 map is the map that gets modified e.g. with command line parameters
> - * and that is also registered with modifications in the kernel resource tree
> - * with the iomem_resource as parent.
>   *
>   * The e820_saved is directly saved after the BIOS-provided memory map is
>   * copied. It doesn't get modified afterwards. It's registered for the
> @@ -34,7 +31,6 @@
>   * user can e.g. boot the original kernel with mem=1G while still booting the
>   * next kernel with full memory.
>   */
> -static struct e820map __initdata e820;
>  static struct e820map __initdata e820_saved;
>  
>  /* For PCI or other memory-mapped resources */
> @@ -99,295 +95,6 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type)
>  	return 0;
>  }
>  
> -/*
> - * Add a memory region to the kernel e820 map.
> - */
> -static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
> -					 int type)
> -{
> -	int x = e820x->nr_map;
> -
> -	if (x >= ARRAY_SIZE(e820x->map)) {
> -		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
> -		return;
> -	}
> -
> -	e820x->map[x].addr = start;
> -	e820x->map[x].size = size;
> -	e820x->map[x].type = type;
> -	e820x->nr_map++;
> -}
> -
> -void __init e820_add_region(u64 start, u64 size, int type)
> -{
> -	__e820_add_region(&e820, start, size, type);
> -}
> -
> -static void __init e820_print_type(u32 type)
> -{
> -	switch (type) {
> -	case E820_RAM:
> -	case E820_RESERVED_KERN:
> -		printk(KERN_CONT "(usable)");
> -		break;
> -	case E820_RESERVED:
> -		printk(KERN_CONT "(reserved)");
> -		break;
> -	case E820_ACPI:
> -		printk(KERN_CONT "(ACPI data)");
> -		break;
> -	case E820_NVS:
> -		printk(KERN_CONT "(ACPI NVS)");
> -		break;
> -	case E820_UNUSABLE:
> -		printk(KERN_CONT "(unusable)");
> -		break;
> -	default:
> -		printk(KERN_CONT "type %u", type);
> -		break;
> -	}
> -}
> -
> -void __init e820_print_map(char *who)
> -{
> -	int i;
> -
> -	for (i = 0; i < e820.nr_map; i++) {
> -		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
> -		       (unsigned long long) e820.map[i].addr,
> -		       (unsigned long long)
> -		       (e820.map[i].addr + e820.map[i].size));
> -		e820_print_type(e820.map[i].type);
> -		printk(KERN_CONT "\n");
> -	}
> -}
> -
> -/*
> - * Sanitize the BIOS e820 map.
> - *
> - * Some e820 responses include overlapping entries. The following
> - * replaces the original e820 map with a new one, removing overlaps,
> - * and resolving conflicting memory types in favor of highest
> - * numbered type.
> - *
> - * The input parameter biosmap points to an array of 'struct
> - * e820entry' which on entry has elements in the range [0, *pnr_map)
> - * valid, and which has space for up to max_nr_map entries.
> - * On return, the resulting sanitized e820 map entries will be in
> - * overwritten in the same location, starting at biosmap.
> - *
> - * The integer pointed to by pnr_map must be valid on entry (the
> - * current number of valid entries located at biosmap) and will
> - * be updated on return, with the new number of valid entries
> - * (something no more than max_nr_map.)
> - *
> - * The return value from sanitize_e820_map() is zero if it
> - * successfully 'sanitized' the map entries passed in, and is -1
> - * if it did nothing, which can happen if either of (1) it was
> - * only passed one map entry, or (2) any of the input map entries
> - * were invalid (start + size < start, meaning that the size was
> - * so big the described memory range wrapped around through zero.)
> - *
> - *	Visually we're performing the following
> - *	(1,2,3,4 = memory types)...
> - *
> - *	Sample memory map (w/overlaps):
> - *	   ____22__________________
> - *	   ______________________4_
> - *	   ____1111________________
> - *	   _44_____________________
> - *	   11111111________________
> - *	   ____________________33__
> - *	   ___________44___________
> - *	   __________33333_________
> - *	   ______________22________
> - *	   ___________________2222_
> - *	   _________111111111______
> - *	   _____________________11_
> - *	   _________________4______
> - *
> - *	Sanitized equivalent (no overlap):
> - *	   1_______________________
> - *	   _44_____________________
> - *	   ___1____________________
> - *	   ____22__________________
> - *	   ______11________________
> - *	   _________1______________
> - *	   __________3_____________
> - *	   ___________44___________
> - *	   _____________33_________
> - *	   _______________2________
> - *	   ________________1_______
> - *	   _________________4______
> - *	   ___________________2____
> - *	   ____________________33__
> - *	   ______________________4_
> - */
> -
> -static int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
> -			     u32 *pnr_map)
> -{
> -	struct change_member {
> -		struct e820entry *pbios; /* pointer to original bios entry */
> -		unsigned long long addr; /* address for this change point */
> -	};
> -	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
> -	static struct change_member *change_point[2*E820_X_MAX] __initdata;
> -	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
> -	static struct e820entry new_bios[E820_X_MAX] __initdata;
> -	struct change_member *change_tmp;
> -	unsigned long current_type, last_type;
> -	unsigned long long last_addr;
> -	int chgidx, still_changing;
> -	int overlap_entries;
> -	int new_bios_entry;
> -	int old_nr, new_nr, chg_nr;
> -	int i;
> -
> -	/* if there's only one memory region, don't bother */
> -	if (*pnr_map < 2)
> -		return -1;
> -
> -	old_nr = *pnr_map;
> -	BUG_ON(old_nr > max_nr_map);
> -
> -	/* bail out if we find any unreasonable addresses in bios map */
> -	for (i = 0; i < old_nr; i++)
> -		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
> -			return -1;
> -
> -	/* create pointers for initial change-point information (for sorting) */
> -	for (i = 0; i < 2 * old_nr; i++)
> -		change_point[i] = &change_point_list[i];
> -
> -	/* record all known change-points (starting and ending addresses),
> -	   omitting those that are for empty memory regions */
> -	chgidx = 0;
> -	for (i = 0; i < old_nr; i++)	{
> -		if (biosmap[i].size != 0) {
> -			change_point[chgidx]->addr = biosmap[i].addr;
> -			change_point[chgidx++]->pbios = &biosmap[i];
> -			change_point[chgidx]->addr = biosmap[i].addr +
> -				biosmap[i].size;
> -			change_point[chgidx++]->pbios = &biosmap[i];
> -		}
> -	}
> -	chg_nr = chgidx;
> -
> -	/* sort change-point list by memory addresses (low -> high) */
> -	still_changing = 1;
> -	while (still_changing)	{
> -		still_changing = 0;
> -		for (i = 1; i < chg_nr; i++)  {
> -			unsigned long long curaddr, lastaddr;
> -			unsigned long long curpbaddr, lastpbaddr;
> -
> -			curaddr = change_point[i]->addr;
> -			lastaddr = change_point[i - 1]->addr;
> -			curpbaddr = change_point[i]->pbios->addr;
> -			lastpbaddr = change_point[i - 1]->pbios->addr;
> -
> -			/*
> -			 * swap entries, when:
> -			 *
> -			 * curaddr > lastaddr or
> -			 * curaddr == lastaddr and curaddr == curpbaddr and
> -			 * lastaddr != lastpbaddr
> -			 */
> -			if (curaddr < lastaddr ||
> -			    (curaddr == lastaddr && curaddr == curpbaddr &&
> -			     lastaddr != lastpbaddr)) {
> -				change_tmp = change_point[i];
> -				change_point[i] = change_point[i-1];
> -				change_point[i-1] = change_tmp;
> -				still_changing = 1;
> -			}
> -		}
> -	}
> -
> -	/* create a new bios memory map, removing overlaps */
> -	overlap_entries = 0;	 /* number of entries in the overlap table */
> -	new_bios_entry = 0;	 /* index for creating new bios map entries */
> -	last_type = 0;		 /* start with undefined memory type */
> -	last_addr = 0;		 /* start with 0 as last starting address */
> -
> -	/* loop through change-points, determining affect on the new bios map */
> -	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
> -		/* keep track of all overlapping bios entries */
> -		if (change_point[chgidx]->addr ==
> -		    change_point[chgidx]->pbios->addr) {
> -			/*
> -			 * add map entry to overlap list (> 1 entry
> -			 * implies an overlap)
> -			 */
> -			overlap_list[overlap_entries++] =
> -				change_point[chgidx]->pbios;
> -		} else {
> -			/*
> -			 * remove entry from list (order independent,
> -			 * so swap with last)
> -			 */
> -			for (i = 0; i < overlap_entries; i++) {
> -				if (overlap_list[i] ==
> -				    change_point[chgidx]->pbios)
> -					overlap_list[i] =
> -						overlap_list[overlap_entries-1];
> -			}
> -			overlap_entries--;
> -		}
> -		/*
> -		 * if there are overlapping entries, decide which
> -		 * "type" to use (larger value takes precedence --
> -		 * 1=usable, 2,3,4,4+=unusable)
> -		 */
> -		current_type = 0;
> -		for (i = 0; i < overlap_entries; i++)
> -			if (overlap_list[i]->type > current_type)
> -				current_type = overlap_list[i]->type;
> -		/*
> -		 * continue building up new bios map based on this
> -		 * information
> -		 */
> -		if (current_type != last_type)	{
> -			if (last_type != 0)	 {
> -				new_bios[new_bios_entry].size =
> -					change_point[chgidx]->addr - last_addr;
> -				/*
> -				 * move forward only if the new size
> -				 * was non-zero
> -				 */
> -				if (new_bios[new_bios_entry].size != 0)
> -					/*
> -					 * no more space left for new
> -					 * bios entries ?
> -					 */
> -					if (++new_bios_entry >= max_nr_map)
> -						break;
> -			}
> -			if (current_type != 0)	{
> -				new_bios[new_bios_entry].addr =
> -					change_point[chgidx]->addr;
> -				new_bios[new_bios_entry].type = current_type;
> -				last_addr = change_point[chgidx]->addr;
> -			}
> -			last_type = current_type;
> -		}
> -	}
> -	/* retain count for new bios entries */
> -	new_nr = new_bios_entry;
> -
> -	/* copy new bios mapping into original location */
> -	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
> -	*pnr_map = new_nr;
> -
> -	return 0;
> -}
> -
> -int __init sanitize_e820_map(void)
> -{
> -	return __sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
> -}
> -
>  static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
>  {
>  	while (nr_map) {
> @@ -509,52 +216,6 @@ static u64 __init e820_update_range_saved(u64 start, u64 size,
>  				     new_type);
>  }
>  
> -/* make e820 not cover the range */
> -u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
> -			     int checktype)
> -{
> -	int i;
> -	u64 end;
> -	u64 real_removed_size = 0;
> -
> -	if (size > (ULLONG_MAX - start))
> -		size = ULLONG_MAX - start;
> -
> -	end = start + size;
> -	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
> -		       (unsigned long long) start,
> -		       (unsigned long long) end);
> -	e820_print_type(old_type);
> -	printk(KERN_CONT "\n");
> -
> -	for (i = 0; i < e820.nr_map; i++) {
> -		struct e820entry *ei = &e820.map[i];
> -		u64 final_start, final_end;
> -
> -		if (checktype && ei->type != old_type)
> -			continue;
> -		/* totally covered? */
> -		if (ei->addr >= start &&
> -		    (ei->addr + ei->size) <= (start + size)) {
> -			real_removed_size += ei->size;
> -			memset(ei, 0, sizeof(struct e820entry));
> -			continue;
> -		}
> -		/* partially covered */
> -		final_start = max(start, ei->addr);
> -		final_end = min(start + size, ei->addr + ei->size);
> -		if (final_start >= final_end)
> -			continue;
> -		real_removed_size += final_end - final_start;
> -
> -		ei->size -= final_end - final_start;
> -		if (ei->addr < final_start)
> -			continue;
> -		ei->addr = final_end;
> -	}
> -	return real_removed_size;
> -}
> -
>  void __init update_e820(void)
>  {
>  	u32 nr_map;
> @@ -566,20 +227,24 @@ void __init update_e820(void)
>  	printk(KERN_INFO "modified physical RAM map:\n");
>  	e820_print_map("modified");
>  }
> +
>  static void __init update_e820_saved(void)
>  {
>  	u32 nr_map;
> +	int max_nr_map = ARRAY_SIZE(e820_saved.map);
>  
>  	nr_map = e820_saved.nr_map;
> -	if (__sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
> +	if (__sanitize_e820_map(e820_saved.map, max_nr_map, &nr_map))
>  		return;
>  	e820_saved.nr_map = nr_map;
>  }
> +
>  #define MAX_GAP_END 0x100000000ull
>  /*
>   * Search for a gap in the e820 memory space from start_addr to end_addr.
>   */
> -__init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
> +static int __init
> +e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
>  		unsigned long start_addr, unsigned long long end_addr)
>  {
>  	unsigned long long last;
> @@ -726,37 +391,6 @@ static int __init e820_mark_nvs_memory(void)
>  core_initcall(e820_mark_nvs_memory);
>  #endif
>  
> -/*
> - * Find a free area with specified alignment in a specific range.
> - */
> -u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
> -{
> -	int i;
> -
> -	for (i = 0; i < e820.nr_map; i++) {
> -		struct e820entry *ei = &e820.map[i];
> -		u64 addr;
> -		u64 ei_start, ei_last;
> -
> -		if (ei->type != E820_RAM)
> -			continue;
> -
> -		ei_last = ei->addr + ei->size;
> -		ei_start = ei->addr;
> -		addr = find_early_area(ei_start, ei_last, start, end,
> -					 size, align);
> -
> -		if (addr != -1ULL)
> -			return addr;
> -	}
> -	return -1ULL;
> -}
> -
> -u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
> -{
> -	return find_e820_area(start, end, size, align);
> -}
> -
>  u64 __init get_max_mapped(void)
>  {
>  	u64 end = max_pfn_mapped;
> @@ -765,6 +399,7 @@ u64 __init get_max_mapped(void)
>  
>  	return end;
>  }
> +
>  /*
>   * Find next free range after *start
>   */
> @@ -792,21 +427,6 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
>  	return -1ULL;
>  }
>  
> -u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
> -{
> -	u64 addr;
> -	/*
> -	 * need to call this function after e820_register_active_regions
> -	 * so early_node_map[] is set
> -	 */
> -	addr = find_memory_core_early(nid, size, align, start, end);
> -	if (addr != -1ULL)
> -		return addr;
> -
> -	/* fallback, should already have start end in the node range */
> -	return find_e820_area(start, end, size, align);
> -}
> -
>  /*
>   * pre allocated 4k and reserved it in e820
>   */
> @@ -843,220 +463,6 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
>  	return addr;
>  }
>  
> -#ifdef CONFIG_X86_32
> -# ifdef CONFIG_X86_PAE
> -#  define MAX_ARCH_PFN		(1ULL<<(36-PAGE_SHIFT))
> -# else
> -#  define MAX_ARCH_PFN		(1ULL<<(32-PAGE_SHIFT))
> -# endif
> -#else /* CONFIG_X86_32 */
> -# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
> -#endif
> -
> -/*
> - * Find the highest page frame number we have available
> - */
> -static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
> -{
> -	int i;
> -	unsigned long last_pfn = 0;
> -	unsigned long max_arch_pfn = MAX_ARCH_PFN;
> -
> -	for (i = 0; i < e820.nr_map; i++) {
> -		struct e820entry *ei = &e820.map[i];
> -		unsigned long start_pfn;
> -		unsigned long end_pfn;
> -
> -		if (ei->type != type)
> -			continue;
> -
> -		start_pfn = ei->addr >> PAGE_SHIFT;
> -		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
> -
> -		if (start_pfn >= limit_pfn)
> -			continue;
> -		if (end_pfn > limit_pfn) {
> -			last_pfn = limit_pfn;
> -			break;
> -		}
> -		if (end_pfn > last_pfn)
> -			last_pfn = end_pfn;
> -	}
> -
> -	if (last_pfn > max_arch_pfn)
> -		last_pfn = max_arch_pfn;
> -
> -	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
> -			 last_pfn, max_arch_pfn);
> -	return last_pfn;
> -}
> -unsigned long __init e820_end_of_ram_pfn(void)
> -{
> -	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
> -}
> -
> -unsigned long __init e820_end_of_low_ram_pfn(void)
> -{
> -	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
> -}
> -/*
> - * Finds an active region in the address range from start_pfn to last_pfn and
> - * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
> - */
> -int __init e820_find_active_region(const struct e820entry *ei,
> -				  unsigned long start_pfn,
> -				  unsigned long last_pfn,
> -				  unsigned long *ei_startpfn,
> -				  unsigned long *ei_endpfn)
> -{
> -	u64 align = PAGE_SIZE;
> -
> -	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
> -	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
> -
> -	/* Skip map entries smaller than a page */
> -	if (*ei_startpfn >= *ei_endpfn)
> -		return 0;
> -
> -	/* Skip if map is outside the node */
> -	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
> -				    *ei_startpfn >= last_pfn)
> -		return 0;
> -
> -	/* Check for overlaps */
> -	if (*ei_startpfn < start_pfn)
> -		*ei_startpfn = start_pfn;
> -	if (*ei_endpfn > last_pfn)
> -		*ei_endpfn = last_pfn;
> -
> -	return 1;
> -}
> -
> -/* Walk the e820 map and register active regions within a node */
> -void __init e820_register_active_regions(int nid, unsigned long start_pfn,
> -					 unsigned long last_pfn)
> -{
> -	unsigned long ei_startpfn;
> -	unsigned long ei_endpfn;
> -	int i;
> -
> -	for (i = 0; i < e820.nr_map; i++)
> -		if (e820_find_active_region(&e820.map[i],
> -					    start_pfn, last_pfn,
> -					    &ei_startpfn, &ei_endpfn))
> -			add_active_range(nid, ei_startpfn, ei_endpfn);
> -}
> -
> -/*
> - * Find the hole size (in bytes) in the memory range.
> - * @start: starting address of the memory range to scan
> - * @end: ending address of the memory range to scan
> - */
> -u64 __init e820_hole_size(u64 start, u64 end)
> -{
> -	unsigned long start_pfn = start >> PAGE_SHIFT;
> -	unsigned long last_pfn = end >> PAGE_SHIFT;
> -	unsigned long ei_startpfn, ei_endpfn, ram = 0;
> -	int i;
> -
> -	for (i = 0; i < e820.nr_map; i++) {
> -		if (e820_find_active_region(&e820.map[i],
> -					    start_pfn, last_pfn,
> -					    &ei_startpfn, &ei_endpfn))
> -			ram += ei_endpfn - ei_startpfn;
> -	}
> -	return end - start - ((u64)ram << PAGE_SHIFT);
> -}
> -
> -static void early_panic(char *msg)
> -{
> -	early_printk(msg);
> -	panic(msg);
> -}
> -
> -static int userdef __initdata;
> -
> -/* "mem=nopentium" disables the 4MB page tables. */
> -static int __init parse_memopt(char *p)
> -{
> -	u64 mem_size;
> -
> -	if (!p)
> -		return -EINVAL;
> -
> -#ifdef CONFIG_X86_32
> -	if (!strcmp(p, "nopentium")) {
> -		setup_clear_cpu_cap(X86_FEATURE_PSE);
> -		return 0;
> -	}
> -#endif
> -
> -	userdef = 1;
> -	mem_size = memparse(p, &p);
> -	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
> -
> -	return 0;
> -}
> -early_param("mem", parse_memopt);
> -
> -static int __init parse_memmap_opt(char *p)
> -{
> -	char *oldp;
> -	u64 start_at, mem_size;
> -
> -	if (!p)
> -		return -EINVAL;
> -
> -	if (!strncmp(p, "exactmap", 8)) {
> -#ifdef CONFIG_CRASH_DUMP
> -		/*
> -		 * If we are doing a crash dump, we still need to know
> -		 * the real mem size before original memory map is
> -		 * reset.
> -		 */
> -		saved_max_pfn = e820_end_of_ram_pfn();
> -#endif
> -		e820.nr_map = 0;
> -		userdef = 1;
> -		return 0;
> -	}
> -
> -	oldp = p;
> -	mem_size = memparse(p, &p);
> -	if (p == oldp)
> -		return -EINVAL;
> -
> -	userdef = 1;
> -	if (*p == '@') {
> -		start_at = memparse(p+1, &p);
> -		e820_add_region(start_at, mem_size, E820_RAM);
> -	} else if (*p == '#') {
> -		start_at = memparse(p+1, &p);
> -		e820_add_region(start_at, mem_size, E820_ACPI);
> -	} else if (*p == '$') {
> -		start_at = memparse(p+1, &p);
> -		e820_add_region(start_at, mem_size, E820_RESERVED);
> -	} else
> -		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
> -
> -	return *p == '\0' ? 0 : -EINVAL;
> -}
> -early_param("memmap", parse_memmap_opt);
> -
> -void __init finish_e820_parsing(void)
> -{
> -	if (userdef) {
> -		u32 nr = e820.nr_map;
> -
> -		if (__sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
> -			early_panic("Invalid user supplied memory map");
> -		e820.nr_map = nr;
> -
> -		printk(KERN_INFO "user-defined physical RAM map:\n");
> -		e820_print_map("user");
> -	}
> -}
> -
>  static inline const char *e820_type_to_string(int e820_type)
>  {
>  	switch (e820_type) {
> @@ -1098,7 +504,8 @@ void __init e820_reserve_resources(void)
>  		 * pci device BAR resource and insert them later in
>  		 * pcibios_resource_survey()
>  		 */
> -		if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
> +		if (e820.map[i].type != E820_RESERVED ||
> +		    res->start < (1ULL<<20)) {
>  			res->flags |= IORESOURCE_BUSY;
>  			insert_resource(&iomem_resource, res);
>  		}
> @@ -1114,7 +521,7 @@ void __init e820_reserve_resources(void)
>  }
>  
>  /* How much should we pad RAM ending depending on where it is? */
> -static unsigned long ram_alignment(resource_size_t pos)
> +static unsigned long __init ram_alignment(resource_size_t pos)
>  {
>  	unsigned long mb = pos >> 20;
>  
> @@ -1196,7 +603,7 @@ char *__init default_machine_specific_memory_setup(void)
>  			who = "BIOS-e801";
>  		}
>  
> -		e820.nr_map = 0;
> +		clear_e820_map();
>  		e820_add_region(0, LOWMEMSIZE(), E820_RAM);
>  		e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
>  	}
> @@ -1204,7 +611,6 @@ char *__init default_machine_specific_memory_setup(void)
>  	/* In case someone cares... */
>  	return who;
>  }
> -
>  void __init save_e820_map(void)
>  {
>  	memcpy(&e820_saved, &e820, sizeof(struct e820map));
> @@ -1221,20 +627,18 @@ void __init setup_memory_map(void)
>  }
>  
>  #ifdef CONFIG_X86_OOSTORE
> +
>  /*
>   * Figure what we can cover with MCR's
>   *
>   * Shortcut: We know you can't put 4Gig of RAM on a winchip
>   */
> -void __init get_centaur_ram_top(void)
> +static void __init __get_special_low_ram_top(void)
>  {
>  	u32 clip = 0xFFFFFFFFUL;
>  	u32 top = 0;
>  	int i;
>  
> -	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
> -		return;
> -
>  	for (i = 0; i < e820.nr_map; i++) {
>  		unsigned long start, end;
>  
> @@ -1272,7 +676,15 @@ void __init get_centaur_ram_top(void)
>  	if (top > clip)
>  		top = clip;
>  
> -	centaur_ram_top = top;
> +	return top;
>  }
> -#endif
>  
> +int centaur_ram_top;
> +void __init get_centaur_ram_top(void)
> +{
> +	if (boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
> +		return;
> +
> +	centaur_ram_top = __get_special_low_ram_top();
> +}
> +#endif
> diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
> index 266ab92..c341c18 100644
> --- a/include/linux/bootmem.h
> +++ b/include/linux/bootmem.h
> @@ -6,7 +6,7 @@
>  
>  #include <linux/mmzone.h>
>  #include <asm/dma.h>
> -
> +#include <linux/early_res.h>
>  /*
>   *  simple boot-time physical memory area allocator.
>   */
> diff --git a/include/linux/early_res.h b/include/linux/early_res.h
> index 29c09f5..0f4590f 100644
> --- a/include/linux/early_res.h
> +++ b/include/linux/early_res.h
> @@ -14,6 +14,7 @@ u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
>  u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
>  			 u64 *sizep, u64 align);
>  u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
> +u64 find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
>  u64 get_max_mapped(void);
>  #include <linux/range.h>
>  int get_free_all_memory_range(struct range **rangep, int nodeid);
> diff --git a/include/linux/fw_memmap.h b/include/linux/fw_memmap.h
> new file mode 100644
> index 0000000..e0fcc1b
> --- /dev/null
> +++ b/include/linux/fw_memmap.h
> @@ -0,0 +1,40 @@
> +#ifndef _LINUX_FW_MEMMAP_H
> +#define _LINUX_FW_MEMMAP_H
> +#define E820MAX	128		/* number of entries in E820MAP */
> +
> +#define FW_MEMMAP_RAM	1
> +#define FW_MEMMAP_RESERVED	2
> +
> +#define E820_RAM	FW_MEMMAP_RAM
> +#define E820_RESERVED	FW_MEMMAP_RESERVED
> +
> +#define E820_ACPI	3
> +#define E820_NVS	4
> +#define E820_UNUSABLE	5
> +
> +#ifndef __ASSEMBLY__
> +#include <linux/types.h>
> +struct e820entry {
> +	__u64 addr;	/* start of memory segment */
> +	__u64 size;	/* size of memory segment */
> +	__u32 type;	/* type of memory segment */
> +} __attribute__((packed));
> +
> +#ifdef __KERNEL__
> +
> +void fw_memmap_add_region(u64 start, u64 size, int type);
> +void fw_memmap_print_map(char *who);
> +int sanitize_fw_memmap(void);
> +void finish_fw_memmap_parsing(void);
> +
> +#include <linux/early_res.h>
> +
> +unsigned long fw_memmap_end_of_ram_pfn(void);
> +void fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
> +					 unsigned long end_pfn);
> +u64 fw_memmap_hole_size(u64 start, u64 end);
> +
> +#endif /* __KERNEL__ */
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _LINUX_FW_MEMMAP_H */
> diff --git a/kernel/Makefile b/kernel/Makefile
> index d5c3006..b0afaa5 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -11,7 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
>  	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
>  	    notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
>  	    async.o range.o
> -obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o
> +obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o fw_memmap.o
>  obj-y += groups.o
>  
>  ifdef CONFIG_FUNCTION_TRACER
> diff --git a/kernel/fw_memmap.c b/kernel/fw_memmap.c
> new file mode 100644
> index 0000000..11067f3
> --- /dev/null
> +++ b/kernel/fw_memmap.c
> @@ -0,0 +1,625 @@
> +/*
> + * Handle the memory map.
> + * The functions here do the job until bootmem takes over.
> + *
> + *  Getting sanitize_e820_map() in sync with i386 version by applying change:
> + *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
> + *     Alex Achenbach <xela@slit.de>, December 2002.
> + *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
> + *
> + */
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/init.h>
> +#include <linux/bootmem.h>
> +#include <linux/suspend.h>
> +#include <linux/ioport.h>
> +
> +#include <linux/fw_memmap.h>
> +#include "fw_memmap_internals.h"
> +
> +/*
> + * The e820 map is the map that gets modified e.g. with command line parameters
> + * and that is also registered with modifications in the kernel resource tree
> + * with the iomem_resource as parent.
> + */
> +struct e820map __initdata e820;
> +
> +/*
> + * Add a memory region to the kernel e820 map.
> + */
> +void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
> +					 int type)
> +{
> +	int x = e820x->nr_map;
> +
> +	if (x >= ARRAY_SIZE(e820x->map)) {
> +		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
> +		return;
> +	}
> +
> +	e820x->map[x].addr = start;
> +	e820x->map[x].size = size;
> +	e820x->map[x].type = type;
> +	e820x->nr_map++;
> +}
> +
> +void __init fw_memmap_add_region(u64 start, u64 size, int type)
> +{
> +	__e820_add_region(&e820, start, size, type);
> +}
> +
> +/* make e820 not cover the range */
> +u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
> +			     int checktype)
> +{
> +	int i;
> +	u64 end;
> +	u64 real_removed_size = 0;
> +
> +	if (size > (ULLONG_MAX - start))
> +		size = ULLONG_MAX - start;
> +
> +	end = start + size;
> +	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
> +		       (unsigned long long) start,
> +		       (unsigned long long) end);
> +	e820_print_type(old_type);
> +	printk(KERN_CONT "\n");
> +
> +	for (i = 0; i < e820.nr_map; i++) {
> +		struct e820entry *ei = &e820.map[i];
> +		u64 final_start, final_end;
> +
> +		if (checktype && ei->type != old_type)
> +			continue;
> +		/* totally covered? */
> +		if (ei->addr >= start &&
> +		    (ei->addr + ei->size) <= (start + size)) {
> +			real_removed_size += ei->size;
> +			memset(ei, 0, sizeof(struct e820entry));
> +			continue;
> +		}
> +		/* partially covered */
> +		final_start = max(start, ei->addr);
> +		final_end = min(start + size, ei->addr + ei->size);
> +		if (final_start >= final_end)
> +			continue;
> +		real_removed_size += final_end - final_start;
> +
> +		ei->size -= final_end - final_start;
> +		if (ei->addr < final_start)
> +			continue;
> +		ei->addr = final_end;
> +	}
> +	return real_removed_size;
> +}
> +
> +void __init e820_print_type(u32 type)
> +{
> +	switch (type) {
> +	case E820_RAM:
> +	case E820_RESERVED_KERN:
> +		printk(KERN_CONT "(usable)");
> +		break;
> +	case E820_RESERVED:
> +		printk(KERN_CONT "(reserved)");
> +		break;
> +	case E820_ACPI:
> +		printk(KERN_CONT "(ACPI data)");
> +		break;
> +	case E820_NVS:
> +		printk(KERN_CONT "(ACPI NVS)");
> +		break;
> +	case E820_UNUSABLE:
> +		printk(KERN_CONT "(unusable)");
> +		break;
> +	default:
> +		printk(KERN_CONT "type %u", type);
> +		break;
> +	}
> +}
> +
> +void __init fw_memmap_print_map(char *who)
> +{
> +	int i;
> +
> +	for (i = 0; i < e820.nr_map; i++) {
> +		printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
> +		       (unsigned long long) e820.map[i].addr,
> +		       (unsigned long long)
> +		       (e820.map[i].addr + e820.map[i].size));
> +		e820_print_type(e820.map[i].type);
> +		printk(KERN_CONT "\n");
> +	}
> +}
> +
> +/*
> + * Sanitize the BIOS e820 map.
> + *
> + * Some e820 responses include overlapping entries. The following
> + * replaces the original e820 map with a new one, removing overlaps,
> + * and resolving conflicting memory types in favor of highest
> + * numbered type.
> + *
> + * The input parameter biosmap points to an array of 'struct
> + * e820entry' which on entry has elements in the range [0, *pnr_map)
> + * valid, and which has space for up to max_nr_map entries.
> + * On return, the resulting sanitized e820 map entries will be in
> + * overwritten in the same location, starting at biosmap.
> + *
> + * The integer pointed to by pnr_map must be valid on entry (the
> + * current number of valid entries located at biosmap) and will
> + * be updated on return, with the new number of valid entries
> + * (something no more than max_nr_map.)
> + *
> + * The return value from sanitize_e820_map() is zero if it
> + * successfully 'sanitized' the map entries passed in, and is -1
> + * if it did nothing, which can happen if either of (1) it was
> + * only passed one map entry, or (2) any of the input map entries
> + * were invalid (start + size < start, meaning that the size was
> + * so big the described memory range wrapped around through zero.)
> + *
> + *	Visually we're performing the following
> + *	(1,2,3,4 = memory types)...
> + *
> + *	Sample memory map (w/overlaps):
> + *	   ____22__________________
> + *	   ______________________4_
> + *	   ____1111________________
> + *	   _44_____________________
> + *	   11111111________________
> + *	   ____________________33__
> + *	   ___________44___________
> + *	   __________33333_________
> + *	   ______________22________
> + *	   ___________________2222_
> + *	   _________111111111______
> + *	   _____________________11_
> + *	   _________________4______
> + *
> + *	Sanitized equivalent (no overlap):
> + *	   1_______________________
> + *	   _44_____________________
> + *	   ___1____________________
> + *	   ____22__________________
> + *	   ______11________________
> + *	   _________1______________
> + *	   __________3_____________
> + *	   ___________44___________
> + *	   _____________33_________
> + *	   _______________2________
> + *	   ________________1_______
> + *	   _________________4______
> + *	   ___________________2____
> + *	   ____________________33__
> + *	   ______________________4_
> + */
> +
> +int __init __sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
> +			     u32 *pnr_map)
> +{
> +	struct change_member {
> +		struct e820entry *pbios; /* pointer to original bios entry */
> +		unsigned long long addr; /* address for this change point */
> +	};
> +	static struct change_member change_point_list[2*E820_X_MAX] __initdata;
> +	static struct change_member *change_point[2*E820_X_MAX] __initdata;
> +	static struct e820entry *overlap_list[E820_X_MAX] __initdata;
> +	static struct e820entry new_bios[E820_X_MAX] __initdata;
> +	struct change_member *change_tmp;
> +	unsigned long current_type, last_type;
> +	unsigned long long last_addr;
> +	int chgidx, still_changing;
> +	int overlap_entries;
> +	int new_bios_entry;
> +	int old_nr, new_nr, chg_nr;
> +	int i;
> +
> +	/* if there's only one memory region, don't bother */
> +	if (*pnr_map < 2)
> +		return -1;
> +
> +	old_nr = *pnr_map;
> +	BUG_ON(old_nr > max_nr_map);
> +
> +	/* bail out if we find any unreasonable addresses in bios map */
> +	for (i = 0; i < old_nr; i++)
> +		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
> +			return -1;
> +
> +	/* create pointers for initial change-point information (for sorting) */
> +	for (i = 0; i < 2 * old_nr; i++)
> +		change_point[i] = &change_point_list[i];
> +
> +	/* record all known change-points (starting and ending addresses),
> +	   omitting those that are for empty memory regions */
> +	chgidx = 0;
> +	for (i = 0; i < old_nr; i++)	{
> +		if (biosmap[i].size != 0) {
> +			change_point[chgidx]->addr = biosmap[i].addr;
> +			change_point[chgidx++]->pbios = &biosmap[i];
> +			change_point[chgidx]->addr = biosmap[i].addr +
> +				biosmap[i].size;
> +			change_point[chgidx++]->pbios = &biosmap[i];
> +		}
> +	}
> +	chg_nr = chgidx;
> +
> +	/* sort change-point list by memory addresses (low -> high) */
> +	still_changing = 1;
> +	while (still_changing)	{
> +		still_changing = 0;
> +		for (i = 1; i < chg_nr; i++)  {
> +			unsigned long long curaddr, lastaddr;
> +			unsigned long long curpbaddr, lastpbaddr;
> +
> +			curaddr = change_point[i]->addr;
> +			lastaddr = change_point[i - 1]->addr;
> +			curpbaddr = change_point[i]->pbios->addr;
> +			lastpbaddr = change_point[i - 1]->pbios->addr;
> +
> +			/*
> +			 * swap entries, when:
> +			 *
> +			 * curaddr > lastaddr or
> +			 * curaddr == lastaddr and curaddr == curpbaddr and
> +			 * lastaddr != lastpbaddr
> +			 */
> +			if (curaddr < lastaddr ||
> +			    (curaddr == lastaddr && curaddr == curpbaddr &&
> +			     lastaddr != lastpbaddr)) {
> +				change_tmp = change_point[i];
> +				change_point[i] = change_point[i-1];
> +				change_point[i-1] = change_tmp;
> +				still_changing = 1;
> +			}
> +		}
> +	}
> +
> +	/* create a new bios memory map, removing overlaps */
> +	overlap_entries = 0;	 /* number of entries in the overlap table */
> +	new_bios_entry = 0;	 /* index for creating new bios map entries */
> +	last_type = 0;		 /* start with undefined memory type */
> +	last_addr = 0;		 /* start with 0 as last starting address */
> +
> +	/* loop through change-points, determining affect on the new bios map */
> +	for (chgidx = 0; chgidx < chg_nr; chgidx++) {
> +		/* keep track of all overlapping bios entries */
> +		if (change_point[chgidx]->addr ==
> +		    change_point[chgidx]->pbios->addr) {
> +			/*
> +			 * add map entry to overlap list (> 1 entry
> +			 * implies an overlap)
> +			 */
> +			overlap_list[overlap_entries++] =
> +				change_point[chgidx]->pbios;
> +		} else {
> +			/*
> +			 * remove entry from list (order independent,
> +			 * so swap with last)
> +			 */
> +			for (i = 0; i < overlap_entries; i++) {
> +				if (overlap_list[i] ==
> +				    change_point[chgidx]->pbios)
> +					overlap_list[i] =
> +						overlap_list[overlap_entries-1];
> +			}
> +			overlap_entries--;
> +		}
> +		/*
> +		 * if there are overlapping entries, decide which
> +		 * "type" to use (larger value takes precedence --
> +		 * 1=usable, 2,3,4,4+=unusable)
> +		 */
> +		current_type = 0;
> +		for (i = 0; i < overlap_entries; i++)
> +			if (overlap_list[i]->type > current_type)
> +				current_type = overlap_list[i]->type;
> +		/*
> +		 * continue building up new bios map based on this
> +		 * information
> +		 */
> +		if (current_type != last_type)	{
> +			if (last_type != 0)	 {
> +				new_bios[new_bios_entry].size =
> +					change_point[chgidx]->addr - last_addr;
> +				/*
> +				 * move forward only if the new size
> +				 * was non-zero
> +				 */
> +				if (new_bios[new_bios_entry].size != 0)
> +					/*
> +					 * no more space left for new
> +					 * bios entries ?
> +					 */
> +					if (++new_bios_entry >= max_nr_map)
> +						break;
> +			}
> +			if (current_type != 0)	{
> +				new_bios[new_bios_entry].addr =
> +					change_point[chgidx]->addr;
> +				new_bios[new_bios_entry].type = current_type;
> +				last_addr = change_point[chgidx]->addr;
> +			}
> +			last_type = current_type;
> +		}
> +	}
> +	/* retain count for new bios entries */
> +	new_nr = new_bios_entry;
> +
> +	/* copy new bios mapping into original location */
> +	memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
> +	*pnr_map = new_nr;
> +
> +	return 0;
> +}
> +
> +int __init sanitize_fw_memmap(void)
> +{
> +	int max_nr_map = ARRAY_SIZE(e820.map);
> +
> +	return __sanitize_e820_map(e820.map, max_nr_map, &e820.nr_map);
> +}
> +
> +void __init clear_e820_map(void)
> +{
> +	e820.nr_map = 0;
> +}
> +
> +static int userdef __initdata;
> +
> +/* "mem=nopentium" disables the 4MB page tables. */
> +static int __init parse_memopt(char *p)
> +{
> +	u64 mem_size;
> +
> +	if (!p)
> +		return -EINVAL;
> +
> +#ifdef CONFIG_X86_32
> +	if (!strcmp(p, "nopentium")) {
> +		setup_clear_cpu_cap(X86_FEATURE_PSE);
> +		return 0;
> +	}
> +#endif
> +
> +	userdef = 1;
> +	mem_size = memparse(p, &p);
> +	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
> +
> +	return 0;
> +}
> +early_param("mem", parse_memopt);
> +
> +static int __init parse_memmap_opt(char *p)
> +{
> +	char *oldp;
> +	u64 start_at, mem_size;
> +
> +	if (!p)
> +		return -EINVAL;
> +
> +	if (!strncmp(p, "exactmap", 8)) {
> +#ifdef CONFIG_CRASH_DUMP
> +		/*
> +		 * If we are doing a crash dump, we still need to know
> +		 * the real mem size before original memory map is
> +		 * reset.
> +		 */
> +		saved_max_pfn = fw_memmap_end_of_ram_pfn();
> +#endif
> +		e820.nr_map = 0;
> +		userdef = 1;
> +		return 0;
> +	}
> +
> +	oldp = p;
> +	mem_size = memparse(p, &p);
> +	if (p == oldp)
> +		return -EINVAL;
> +
> +	userdef = 1;
> +	if (*p == '@') {
> +		start_at = memparse(p+1, &p);
> +		e820_add_region(start_at, mem_size, E820_RAM);
> +	} else if (*p == '#') {
> +		start_at = memparse(p+1, &p);
> +		e820_add_region(start_at, mem_size, E820_ACPI);
> +	} else if (*p == '$') {
> +		start_at = memparse(p+1, &p);
> +		e820_add_region(start_at, mem_size, E820_RESERVED);
> +	} else
> +		e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
> +
> +	return *p == '\0' ? 0 : -EINVAL;
> +}
> +early_param("memmap", parse_memmap_opt);
> +
> +static void early_panic(char *msg)
> +{
> +	early_printk(msg);
> +	panic(msg);
> +}
> +
> +void __init finish_fw_memmap_parsing(void)
> +{
> +	if (userdef) {
> +		u32 nr = e820.nr_map;
> +		int max_nr_map = ARRAY_SIZE(e820.map);
> +
> +		if (__sanitize_e820_map(e820.map, max_nr_map, &nr) < 0)
> +			early_panic("Invalid user supplied memory map");
> +		e820.nr_map = nr;
> +
> +		printk(KERN_INFO "user-defined physical RAM map:\n");
> +		e820_print_map("user");
> +	}
> +}
> +
> +/*
> + * Find a free area with specified alignment in a specific range.
> + */
> +u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
> +{
> +	int i;
> +
> +	for (i = 0; i < e820.nr_map; i++) {
> +		struct e820entry *ei = &e820.map[i];
> +		u64 addr;
> +		u64 ei_start, ei_last;
> +
> +		if (ei->type != E820_RAM)
> +			continue;
> +
> +		ei_last = ei->addr + ei->size;
> +		ei_start = ei->addr;
> +		addr = find_early_area(ei_start, ei_last, start, end,
> +					 size, align);
> +
> +		if (addr != -1ULL)
> +			return addr;
> +	}
> +	return -1ULL;
> +}
> +
> +u64 __init
> +find_fw_memmap_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
> +{
> +	u64 addr;
> +	/*
> +	 * need to call this function after e820_register_active_regions
> +	 * so early_node_map[] is set
> +	 */
> +	addr = find_memory_core_early(nid, size, align, start, end);
> +	if (addr != -1ULL)
> +		return addr;
> +
> +	/* fallback, should already have start end in the node range */
> +	return find_fw_memmap_area(start, end, size, align);
> +}
> +
> +#ifdef CONFIG_X86_32
> +# ifdef CONFIG_X86_PAE
> +#  define MAX_ARCH_PFN	(1ULL<<(36-PAGE_SHIFT))
> +# else
> +#  define MAX_ARCH_PFN	(1ULL<<(32-PAGE_SHIFT))
> +# endif
> +#else /* CONFIG_X86_32 */
> +# define MAX_ARCH_PFN	(MAXMEM>>PAGE_SHIFT)
> +#endif
> +
> +/*
> + * Find the highest page frame number we have available
> + */
> +static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
> +{
> +	int i;
> +	unsigned long last_pfn = 0;
> +	unsigned long max_arch_pfn = MAX_ARCH_PFN;
> +
> +	for (i = 0; i < e820.nr_map; i++) {
> +		struct e820entry *ei = &e820.map[i];
> +		unsigned long start_pfn;
> +		unsigned long end_pfn;
> +
> +		if (ei->type != type)
> +			continue;
> +
> +		start_pfn = ei->addr >> PAGE_SHIFT;
> +		end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
> +
> +		if (start_pfn >= limit_pfn)
> +			continue;
> +		if (end_pfn > limit_pfn) {
> +			last_pfn = limit_pfn;
> +			break;
> +		}
> +		if (end_pfn > last_pfn)
> +			last_pfn = end_pfn;
> +	}
> +
> +	if (last_pfn > max_arch_pfn)
> +		last_pfn = max_arch_pfn;
> +
> +	printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
> +			 last_pfn, max_arch_pfn);
> +	return last_pfn;
> +}
> +unsigned long __init fw_memmap_end_of_ram_pfn(void)
> +{
> +	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
> +}
> +
> +unsigned long __init e820_end_of_low_ram_pfn(void)
> +{
> +	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
> +}
> +/*
> + * Finds an active region in the address range from start_pfn to last_pfn and
> + * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
> + */
> +static int __init e820_find_active_region(const struct e820entry *ei,
> +				  unsigned long start_pfn,
> +				  unsigned long last_pfn,
> +				  unsigned long *ei_startpfn,
> +				  unsigned long *ei_endpfn)
> +{
> +	u64 align = PAGE_SIZE;
> +
> +	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
> +	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
> +
> +	/* Skip map entries smaller than a page */
> +	if (*ei_startpfn >= *ei_endpfn)
> +		return 0;
> +
> +	/* Skip if map is outside the node */
> +	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
> +				    *ei_startpfn >= last_pfn)
> +		return 0;
> +
> +	/* Check for overlaps */
> +	if (*ei_startpfn < start_pfn)
> +		*ei_startpfn = start_pfn;
> +	if (*ei_endpfn > last_pfn)
> +		*ei_endpfn = last_pfn;
> +
> +	return 1;
> +}
> +
> +/* Walk the e820 map and register active regions within a node */
> +void __init fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
> +					 unsigned long last_pfn)
> +{
> +	unsigned long ei_startpfn;
> +	unsigned long ei_endpfn;
> +	int i;
> +
> +	for (i = 0; i < e820.nr_map; i++)
> +		if (e820_find_active_region(&e820.map[i],
> +					    start_pfn, last_pfn,
> +					    &ei_startpfn, &ei_endpfn))
> +			add_active_range(nid, ei_startpfn, ei_endpfn);
> +}
> +
> +/*
> + * Find the hole size (in bytes) in the memory range.
> + * @start: starting address of the memory range to scan
> + * @end: ending address of the memory range to scan
> + */
> +u64 __init fw_memmap_hole_size(u64 start, u64 end)
> +{
> +	unsigned long start_pfn = start >> PAGE_SHIFT;
> +	unsigned long last_pfn = end >> PAGE_SHIFT;
> +	unsigned long ei_startpfn, ei_endpfn, ram = 0;
> +	int i;
> +
> +	for (i = 0; i < e820.nr_map; i++) {
> +		if (e820_find_active_region(&e820.map[i],
> +					    start_pfn, last_pfn,
> +					    &ei_startpfn, &ei_endpfn))
> +			ram += ei_endpfn - ei_startpfn;
> +	}
> +	return end - start - ((u64)ram << PAGE_SHIFT);
> +}
> diff --git a/kernel/fw_memmap_internals.h b/kernel/fw_memmap_internals.h
> new file mode 100644
> index 0000000..f217602
> --- /dev/null
> +++ b/kernel/fw_memmap_internals.h
> @@ -0,0 +1,49 @@
> +#ifndef __KERNEL_FW_MEMMAP_INTERNALS_H
> +#define __KERNEL_FW_MEMMAP_INTERNALS_H
> +
> +/*
> + * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
> + * constrained space in the zeropage.  If we have more nodes than
> + * that, and if we've booted off EFI firmware, then the EFI tables
> + * passed us from the EFI firmware can list more nodes.  Size our
> + * internal memory map tables to have room for these additional
> + * nodes, based on up to three entries per node for which the
> + * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
> + * plus E820MAX, allowing space for the possible duplicate E820
> + * entries that might need room in the same arrays, prior to the
> + * call to sanitize_e820_map() to remove duplicates.  The allowance
> + * of three memory map entries per node is "enough" entries for
> + * the initial hardware platform motivating this mechanism to make
> + * use of additional EFI map entries.  Future platforms may want
> + * to allow more than three entries per node or otherwise refine
> + * this size.
> + */
> +
> +/*
> + * Odd: 'make headers_check' complains about numa.h if I try
> + * to collapse the next two #ifdef lines to a single line:
> + *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
> + */
> +#ifdef __KERNEL__
> +#ifdef CONFIG_EFI
> +#include <linux/numa.h>
> +#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
> +#else	/* ! CONFIG_EFI */
> +#define E820_X_MAX E820MAX
> +#endif
> +#else	/* ! __KERNEL__ */
> +#define E820_X_MAX E820MAX
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +struct e820map {
> +	__u32 nr_map;
> +	struct e820entry map[E820_X_MAX];
> +};
> +#endif
> +
> +extern struct e820map __initdata e820;
> +void e820_print_type(u32 type);
> +void __e820_add_region(struct e820map *e820x, u64 start, u64 size, int type);
> +
> +#endif



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

* Questions about SMP bootup control
  2010-03-22  2:37   ` Benjamin Herrenschmidt
@ 2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
  2010-03-22  3:56     ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
  1 sibling, 0 replies; 111+ messages in thread
From: Zhu, Yijun (NSN - CN/Beijing) @ 2010-03-22  2:46 UTC (permalink / raw)
  To: linux-kernel, linux-arch

Hi All:

I want to do some modification on the SMP architecture.

Purpose:
Only the first CPU is running the linux OS, while others do some private
services processing.

My solution:
In the end of the start_secondary() function, I try to schedu the slave
cpu to call my private endless loop instead of cpu_idle();

Result:
The system can NOT up, there is no interactive cli.

Question:
Is there some wrong with my modification or I go to the wrong way?

Thank you very much.

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

* Questions about SMP bootup control
@ 2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
  0 siblings, 0 replies; 111+ messages in thread
From: Zhu, Yijun (NSN - CN/Beijing) @ 2010-03-22  2:46 UTC (permalink / raw)
  To: linux-kernel, linux-arch

Hi All:

I want to do some modification on the SMP architecture.

Purpose:
Only the first CPU is running the linux OS, while others do some private
services processing.

My solution:
In the end of the start_secondary() function, I try to schedu the slave
cpu to call my private endless loop instead of cpu_idle();

Result:
The system can NOT up, there is no interactive cli.

Question:
Is there some wrong with my modification or I go to the wrong way?

Thank you very much.

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

* Re: [PATCH 00/20] x86: early_res and irq_desc
  2010-03-22  2:35 ` [PATCH 00/20] x86: early_res and irq_desc Benjamin Herrenschmidt
@ 2010-03-22  3:26   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22  3:26 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

On 03/21/2010 07:35 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2010-03-21 at 00:13 -0700, Yinghai Lu wrote:
>> 01 - 06: early_res related
>> 07 - 15: irq_desc releated
>> 19 - 20: pci related
> 
> First of all, please post separate series, it's hard enough as it-is.
> 
ok, next version seperate early_res and irq_desc related.

YH


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

* Re: Questions about SMP bootup control
  2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
@ 2010-03-22  3:29         ` Andi Kleen
  -1 siblings, 0 replies; 111+ messages in thread
From: Andi Kleen @ 2010-03-22  3:29 UTC (permalink / raw)
  To: Zhu, Yijun (NSN - CN/Beijing); +Cc: linux-kernel, linux-arch

"Zhu, Yijun (NSN - CN/Beijing)" <yijun.zhu@nsn.com> writes:

> Hi All:
>
> I want to do some modification on the SMP architecture.
>
> Purpose:
> Only the first CPU is running the linux OS, while others do some private
> services processing.
>
> My solution:
> In the end of the start_secondary() function, I try to schedu the slave
> cpu to call my private endless loop instead of cpu_idle();
>
> Result:
> The system can NOT up, there is no interactive cli.
>
> Question:
> Is there some wrong with my modification or I go to the wrong way?

Presumably you're doing this to own that CPU exclusively.

Hooking at cpu_idle is not very useful then because interrupts will be
already enabled and the system participate in IPIs etc, so you can't
simply disable them, the others will miss them.

You would rather need to prevent them from being started in the
first place, e.g. by exluding them with maxcpus=..

A better alternative might be to use isolcpus=... and schedule
a standard program.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

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

* Re: Questions about SMP bootup control
@ 2010-03-22  3:29         ` Andi Kleen
  0 siblings, 0 replies; 111+ messages in thread
From: Andi Kleen @ 2010-03-22  3:29 UTC (permalink / raw)
  To: Zhu, Yijun (NSN - CN/Beijing); +Cc: linux-kernel, linux-arch

"Zhu, Yijun (NSN - CN/Beijing)" <yijun.zhu@nsn.com> writes:

> Hi All:
>
> I want to do some modification on the SMP architecture.
>
> Purpose:
> Only the first CPU is running the linux OS, while others do some private
> services processing.
>
> My solution:
> In the end of the start_secondary() function, I try to schedu the slave
> cpu to call my private endless loop instead of cpu_idle();
>
> Result:
> The system can NOT up, there is no interactive cli.
>
> Question:
> Is there some wrong with my modification or I go to the wrong way?

Presumably you're doing this to own that CPU exclusively.

Hooking at cpu_idle is not very useful then because interrupts will be
already enabled and the system participate in IPIs etc, so you can't
simply disable them, the others will miss them.

You would rather need to prevent them from being started in the
first place, e.g. by exluding them with maxcpus=..

A better alternative might be to use isolcpus=... and schedule
a standard program.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  2:37   ` Benjamin Herrenschmidt
  2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
@ 2010-03-22  3:56     ` Yinghai Lu
  2010-03-22  4:00       ` David Miller
  2010-03-22  5:12       ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22  3:56 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

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

On 03/21/2010 07:37 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2010-03-21 at 00:13 -0700, Yinghai Lu wrote:
>> move it to kernel/fw_memmap.c from arch/x86/kernel/e820.c
>>
>> -v2: add fw_memmap wrapper to some func...
>>      move some functions back to e820.c
> 
> NAK
at this point, kernel/early_res.c and kernel/fw_memmap.c is protected with HAVE_EARLY_RES

obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o fw_memmap.o

so it will not increase size that doesn't support early_res/bootmem yet.
 
> 
> This is even worse than before. You are now moving that entire pile of
> x86 gunk into "generic" code, but even keep it names e820 there !

not all of the e820 code. arch/x86/kernel/e820.c are still there.

linux-2.6> wc -l  arch/x86/kernel/e820.c
690 arch/x86/kernel/e820.c
linux-2.6> wc -l kernel/fw_memmap.c
625 kernel/fw_memmap.c

and interface header file

yhlu@linux-siqj:~/xx/xx/kernel/tip/linux-2.6> cat include/linux/fw_memmap.h 
#ifndef _LINUX_FW_MEMMAP_H
#define _LINUX_FW_MEMMAP_H
#define E820MAX	128		/* number of entries in E820MAP */

#define FW_MEMMAP_RAM	1
#define FW_MEMMAP_RESERVED	2

#define E820_RAM	FW_MEMMAP_RAM
#define E820_RESERVED	FW_MEMMAP_RESERVED

#define E820_ACPI	3
#define E820_NVS	4
#define E820_UNUSABLE	5

#ifndef __ASSEMBLY__
#include <linux/types.h>
struct e820entry {
	__u64 addr;	/* start of memory segment */
	__u64 size;	/* size of memory segment */
	__u32 type;	/* type of memory segment */
} __attribute__((packed));

#ifdef __KERNEL__

void fw_memmap_add_region(u64 start, u64 size, int type);
void fw_memmap_print_map(char *who);
int sanitize_fw_memmap(void);
void finish_fw_memmap_parsing(void);

#include <linux/early_res.h>

unsigned long fw_memmap_end_of_ram_pfn(void);
void fw_memmap_register_active_regions(int nid, unsigned long start_pfn,
					 unsigned long end_pfn);
u64 fw_memmap_hole_size(u64 start, u64 end);

#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */

#endif /* _LINUX_FW_MEMMAP_H */

and new arch that support early_res/bootmem, will normally only need to call those six functions
like

+void __init setup_memory_map(void)
+{
+       int i;
+       unsigned long phys_base;
+       /* Find available physical memory...
+        *
+        * Read it twice in order to work around a bug in openfirmware.
+        * The call to grab this table itself can cause openfirmware to
+        * allocate memory, which in turn can take away some space from
+        * the list of available memory.  Reading it twice makes sure
+        * we really do get the final value.
+        */
+       read_obp_translations();
+       read_obp_memory("reg", &pall[0], &pall_ents);
+       read_obp_memory("available", &pavail[0], &pavail_ents);
+       read_obp_memory("available", &pavail[0], &pavail_ents);
+
+       phys_base = 0xffffffffffffffffUL;
+       for (i = 0; i < pavail_ents; i++) {
+               phys_base = min(phys_base, pavail[i].phys_addr);
+               fw_memmap_add_region(pavail[i].phys_addr, pavail[i].reg_size,
+                                FW_MEMMAP_RAM);
+       }
+
+       sanitize_fw_memmap();
+
+       fw_memmap_print_map("obp memmap:");


> 
> What happened to the discussion we had earlier, which iirc concluded
> that a better approach would be to adapt x86 to use LMB ?

e820/early_res is more complicated than lmb. to make x86, we still need to keep e820 related code.
and early_res already can be used to replace bootmem code.

maybe we should find other user other than previous lmb users at first.

attached is the one for sparc64/lmb converting...- i have no chance to debug it.
qemu seems doesn't support sparc64 well yet.


Yinghai

[-- Attachment #2: e820_static_4.patch --]
[-- Type: text/x-patch, Size: 19606 bytes --]

[RFC PATCH -v2 6/6] sparc64: use early_res and nobootmem
From: Yinghai Lu <yinghai@kernel.org>

use early_res/fw_memmap to replace lmb, so could use early_res replace bootmem

-v2: remve e820 reference...

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/sparc/Kconfig                   |   17 ++
 arch/sparc/configs/sparc64_defconfig |    1 
 arch/sparc/include/asm/lmb.h         |   10 -
 arch/sparc/include/asm/pgtable_64.h  |    2 
 arch/sparc/kernel/mdesc.c            |   18 +-
 arch/sparc/kernel/prom_64.c          |    7 
 arch/sparc/kernel/setup_64.c         |   21 --
 arch/sparc/mm/init_64.c              |  252 +++++++++++++++++------------------
 8 files changed, 162 insertions(+), 166 deletions(-)

Index: linux-2.6/arch/sparc/Kconfig
===================================================================
--- linux-2.6.orig/arch/sparc/Kconfig
+++ linux-2.6/arch/sparc/Kconfig
@@ -39,7 +39,6 @@ config SPARC64
 	select HAVE_FUNCTION_TRACER
 	select HAVE_KRETPROBES
 	select HAVE_KPROBES
-	select HAVE_LMB
 	select HAVE_SYSCALL_WRAPPERS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD
@@ -90,6 +89,10 @@ config STACKTRACE_SUPPORT
 	bool
 	default y if SPARC64
 
+config HAVE_EARLY_RES
+	bool
+	default y if SPARC64
+
 config LOCKDEP_SUPPORT
 	bool
 	default y if SPARC64
@@ -287,6 +290,18 @@ config GENERIC_HARDIRQS
 source "kernel/time/Kconfig"
 
 if SPARC64
+
+config NO_BOOTMEM
+	default y
+	bool "Disable Bootmem code"
+	---help---
+	  Use early_res directly instead of bootmem before slab is ready.
+		- allocator (buddy) [generic]
+		- early allocator (bootmem) [generic]
+		- very early allocator (reserve_early*()) [generic]
+	  So reduce one layer between early allocator to final allocator
+
+
 source "drivers/cpufreq/Kconfig"
 
 config US3_FREQ
Index: linux-2.6/arch/sparc/include/asm/pgtable_64.h
===================================================================
--- linux-2.6.orig/arch/sparc/include/asm/pgtable_64.h
+++ linux-2.6/arch/sparc/include/asm/pgtable_64.h
@@ -752,6 +752,8 @@ extern int io_remap_pfn_range(struct vm_
 #define GET_IOSPACE(pfn)		(pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)			(pfn & 0x0fffffffffffffffUL)
 
+#define MAXMEM		_AC(__AC(1,UL)<<60, UL)
+
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
Index: linux-2.6/arch/sparc/kernel/mdesc.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/mdesc.c
+++ linux-2.6/arch/sparc/kernel/mdesc.c
@@ -4,7 +4,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/lmb.h>
+#include <linux/fw_memmap.h>
+#include <linux/early_res.h>
 #include <linux/log2.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -86,7 +87,7 @@ static void mdesc_handle_init(struct mde
 	hp->handle_size = handle_size;
 }
 
-static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size)
+static struct mdesc_handle * __init mdesc_early_alloc(unsigned int mdesc_size)
 {
 	unsigned int handle_size, alloc_size;
 	struct mdesc_handle *hp;
@@ -97,17 +98,18 @@ static struct mdesc_handle * __init mdes
 		       mdesc_size);
 	alloc_size = PAGE_ALIGN(handle_size);
 
-	paddr = lmb_alloc(alloc_size, PAGE_SIZE);
+	paddr = find_fw_memmap_area(0, -1UL, alloc_size, PAGE_SIZE);
 
 	hp = NULL;
 	if (paddr) {
+		reserve_early(paddr, paddr + alloc_size, "mdesc");
 		hp = __va(paddr);
 		mdesc_handle_init(hp, handle_size, hp);
 	}
 	return hp;
 }
 
-static void mdesc_lmb_free(struct mdesc_handle *hp)
+static void mdesc_early_free(struct mdesc_handle *hp)
 {
 	unsigned int alloc_size;
 	unsigned long start;
@@ -120,9 +122,9 @@ static void mdesc_lmb_free(struct mdesc_
 	free_bootmem_late(start, alloc_size);
 }
 
-static struct mdesc_mem_ops lmb_mdesc_ops = {
-	.alloc = mdesc_lmb_alloc,
-	.free  = mdesc_lmb_free,
+static struct mdesc_mem_ops early_mdesc_ops = {
+	.alloc = mdesc_early_alloc,
+	.free  = mdesc_early_free,
 };
 
 static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size)
@@ -914,7 +916,7 @@ void __init sun4v_mdesc_init(void)
 
 	printk("MDESC: Size is %lu bytes.\n", len);
 
-	hp = mdesc_alloc(len, &lmb_mdesc_ops);
+	hp = mdesc_alloc(len, &early_mdesc_ops);
 	if (hp == NULL) {
 		prom_printf("MDESC: alloc of %lu bytes failed.\n", len);
 		prom_halt();
Index: linux-2.6/arch/sparc/kernel/prom_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/prom_64.c
+++ linux-2.6/arch/sparc/kernel/prom_64.c
@@ -20,7 +20,8 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/lmb.h>
+#include <linux/fw_memmap.h>
+#include <linux/early_res.h>
 #include <linux/of_device.h>
 
 #include <asm/prom.h>
@@ -34,14 +35,14 @@
 
 void * __init prom_early_alloc(unsigned long size)
 {
-	unsigned long paddr = lmb_alloc(size, SMP_CACHE_BYTES);
+	unsigned long paddr = find_fw_memmap_area(0, -1UL, size, SMP_CACHE_BYTES);
 	void *ret;
 
 	if (!paddr) {
 		prom_printf("prom_early_alloc(%lu) failed\n");
 		prom_halt();
 	}
-
+	reserve_early(paddr, paddr + size, "prom_alloc");
 	ret = __va(paddr);
 	memset(ret, 0, size);
 	prom_early_allocated += size;
Index: linux-2.6/arch/sparc/kernel/setup_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/setup_64.c
+++ linux-2.6/arch/sparc/kernel/setup_64.c
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
 #include <linux/initrd.h>
+#include <linux/fw_memmap.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -139,21 +140,7 @@ static void __init boot_flags_init(char
 				process_switch(*commands++);
 			continue;
 		}
-		if (!strncmp(commands, "mem=", 4)) {
-			/*
-			 * "mem=XXX[kKmM]" overrides the PROM-reported
-			 * memory size.
-			 */
-			cmdline_memory_size = simple_strtoul(commands + 4,
-							     &commands, 0);
-			if (*commands == 'K' || *commands == 'k') {
-				cmdline_memory_size <<= 10;
-				commands++;
-			} else if (*commands=='M' || *commands=='m') {
-				cmdline_memory_size <<= 20;
-				commands++;
-			}
-		}
+
 		while (*commands && *commands != ' ')
 			commands++;
 	}
@@ -279,11 +266,14 @@ void __init boot_cpu_id_too_large(int cp
 }
 #endif
 
+void __init setup_memory_map(void);
+
 void __init setup_arch(char **cmdline_p)
 {
 	/* Initialize PROM console and command line. */
 	*cmdline_p = prom_getbootargs();
 	strcpy(boot_command_line, *cmdline_p);
+	setup_memory_map();
 	parse_early_param();
 
 	boot_flags_init(*cmdline_p);
@@ -300,6 +290,7 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
+	finish_fw_memmap_parsing();
 
 	idprom_init();
 
Index: linux-2.6/arch/sparc/mm/init_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/mm/init_64.c
+++ linux-2.6/arch/sparc/mm/init_64.c
@@ -24,7 +24,8 @@
 #include <linux/cache.h>
 #include <linux/sort.h>
 #include <linux/percpu.h>
-#include <linux/lmb.h>
+#include <linux/fw_memmap.h>
+#include <linux/early_res.h>
 #include <linux/mmzone.h>
 
 #include <asm/head.h>
@@ -726,7 +727,7 @@ static void __init find_ramdisk(unsigned
 		initrd_start = ramdisk_image;
 		initrd_end = ramdisk_image + sparc_ramdisk_size;
 
-		lmb_reserve(initrd_start, sparc_ramdisk_size);
+		reserve_early(initrd_start, initrd_end, "initrd");
 
 		initrd_start += PAGE_OFFSET;
 		initrd_end += PAGE_OFFSET;
@@ -737,7 +738,9 @@ static void __init find_ramdisk(unsigned
 struct node_mem_mask {
 	unsigned long mask;
 	unsigned long val;
+#ifndef CONFIG_NO_BOOTMEM
 	unsigned long bootmem_paddr;
+#endif
 };
 static struct node_mem_mask node_masks[MAX_NUMNODES];
 static int num_node_masks;
@@ -818,40 +821,52 @@ static unsigned long long nid_range(unsi
  */
 static void __init allocate_node_data(int nid)
 {
-	unsigned long paddr, num_pages, start_pfn, end_pfn;
+	unsigned long paddr, start_pfn, end_pfn;
 	struct pglist_data *p;
 
+	get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-	paddr = lmb_alloc_nid(sizeof(struct pglist_data),
-			      SMP_CACHE_BYTES, nid, nid_range);
+	paddr = find_fw_memmap_area_node(nid, start_pfn << PAGE_SHIFT,
+				end_pfn << PAGE_SHIFT,
+				sizeof(struct pglist_data), SMP_CACHE_BYTES);
 	if (!paddr) {
 		prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
 		prom_halt();
 	}
+	reserve_early(paddr, paddr + sizeof(struct pglist_data), "NODEDATA");
 	NODE_DATA(nid) = __va(paddr);
 	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
+#ifndef CONFIG_NO_BOOTMEM
 	NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
 #endif
+#endif
 
 	p = NODE_DATA(nid);
 
-	get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+	p->node_id = nid;
 	p->node_start_pfn = start_pfn;
 	p->node_spanned_pages = end_pfn - start_pfn;
 
+#ifndef CONFIG_NO_BOOTMEM
 	if (p->node_spanned_pages) {
+		unsigned long num_pages;
 		num_pages = bootmem_bootmap_pages(p->node_spanned_pages);
 
-		paddr = lmb_alloc_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid,
-				      nid_range);
+		paddr = find_fw_memmap_area_node(nid, start_pfn << PAGE_SHIFT,
+					end_pfn << PAGE_SHIFT,
+					num_pages << PAGE_SHIFT, PAGE_SIZE);
 		if (!paddr) {
 			prom_printf("Cannot allocate bootmap for nid[%d]\n",
 				  nid);
 			prom_halt();
 		}
+		reserve_early(paddr, paddr + (num_pages << PAGE_SHIFT),
+					 "BOOTMAP");
 		node_masks[nid].bootmem_paddr = paddr;
 	}
+#endif
 }
 
 static void init_node_masks_nonnuma(void)
@@ -972,30 +987,27 @@ int of_node_to_nid(struct device_node *d
 
 static void __init add_node_ranges(void)
 {
-	int i;
 
-	for (i = 0; i < lmb.memory.cnt; i++) {
-		unsigned long size = lmb_size_bytes(&lmb.memory, i);
-		unsigned long start, end;
+	unsigned long size = max_pfn << PAGE_SHIFT;
+	unsigned long start, end;
+
+	start = 0;
+	end = start + size;
+	while (start < end) {
+		unsigned long this_end;
+		int nid;
 
-		start = lmb.memory.region[i].base;
-		end = start + size;
-		while (start < end) {
-			unsigned long this_end;
-			int nid;
-
-			this_end = nid_range(start, end, &nid);
-
-			numadbg("Adding active range nid[%d] "
-				"start[%lx] end[%lx]\n",
-				nid, start, this_end);
-
-			add_active_range(nid,
-					 start >> PAGE_SHIFT,
-					 this_end >> PAGE_SHIFT);
+		this_end = nid_range(start, end, &nid);
 
-			start = this_end;
-		}
+		numadbg("Adding active range nid[%d] "
+			"start[%lx] end[%lx]\n",
+			nid, start, this_end);
+
+		fw_memmap_register_active_regions(nid,
+				 start >> PAGE_SHIFT,
+				 this_end >> PAGE_SHIFT);
+
+		start = this_end;
 	}
 }
 
@@ -1010,11 +1022,13 @@ static int __init grab_mlgroups(struct m
 	if (!count)
 		return -ENOENT;
 
-	paddr = lmb_alloc(count * sizeof(struct mdesc_mlgroup),
+	paddr = find_fw_memmap_area(0, -1UL, count * sizeof(struct mdesc_mlgroup),
 			  SMP_CACHE_BYTES);
 	if (!paddr)
 		return -ENOMEM;
 
+	reserve_early(paddr, paddr + count * sizeof(struct mdesc_mlgroup),
+			"mlgroups");
 	mlgroups = __va(paddr);
 	num_mlgroups = count;
 
@@ -1051,10 +1065,11 @@ static int __init grab_mblocks(struct md
 	if (!count)
 		return -ENOENT;
 
-	paddr = lmb_alloc(count * sizeof(struct mdesc_mblock),
+	paddr = find_fw_memmap_area(0, -1UL, count * sizeof(struct mdesc_mblock),
 			  SMP_CACHE_BYTES);
 	if (!paddr)
 		return -ENOMEM;
+	reserve_early(paddr, count * sizeof(struct mdesc_mblock), "mblocks");
 
 	mblocks = __va(paddr);
 	num_mblocks = count;
@@ -1279,9 +1294,8 @@ static int bootmem_init_numa(void)
 
 static void __init bootmem_init_nonnuma(void)
 {
-	unsigned long top_of_ram = lmb_end_of_DRAM();
-	unsigned long total_ram = lmb_phys_mem_size();
-	unsigned int i;
+	unsigned long top_of_ram = max_pfn << PAGE_SHIFT;
+	unsigned long total_ram = top_of_ram - fw_memmap_hole_size(0, top_of_ram);
 
 	numadbg("bootmem_init_nonnuma()\n");
 
@@ -1292,61 +1306,21 @@ static void __init bootmem_init_nonnuma(
 
 	init_node_masks_nonnuma();
 
-	for (i = 0; i < lmb.memory.cnt; i++) {
-		unsigned long size = lmb_size_bytes(&lmb.memory, i);
-		unsigned long start_pfn, end_pfn;
-
-		if (!size)
-			continue;
-
-		start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
-		end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
-		add_active_range(0, start_pfn, end_pfn);
-	}
+	remove_all_active_ranges();
+	fw_memmap_register_active_regions(0, 0, top_of_ram);
 
 	allocate_node_data(0);
 
 	node_set_online(0);
 }
 
-static void __init reserve_range_in_node(int nid, unsigned long start,
-					 unsigned long end)
+int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
+				   int flags)
 {
-	numadbg("    reserve_range_in_node(nid[%d],start[%lx],end[%lx]\n",
-		nid, start, end);
-	while (start < end) {
-		unsigned long this_end;
-		int n;
-
-		this_end = nid_range(start, end, &n);
-		if (n == nid) {
-			numadbg("      MATCH reserving range [%lx:%lx]\n",
-				start, this_end);
-			reserve_bootmem_node(NODE_DATA(nid), start,
-					     (this_end - start), BOOTMEM_DEFAULT);
-		} else
-			numadbg("      NO MATCH, advancing start to %lx\n",
-				this_end);
-
-		start = this_end;
-	}
-}
-
-static void __init trim_reserved_in_node(int nid)
-{
-	int i;
-
-	numadbg("  trim_reserved_in_node(%d)\n", nid);
-
-	for (i = 0; i < lmb.reserved.cnt; i++) {
-		unsigned long start = lmb.reserved.region[i].base;
-		unsigned long size = lmb_size_bytes(&lmb.reserved, i);
-		unsigned long end = start + size;
-
-		reserve_range_in_node(nid, start, end);
-	}
+	return reserve_bootmem(phys, len, flags);
 }
 
+#ifndef CONFIG_NO_BOOTMEM
 static void __init bootmem_init_one_node(int nid)
 {
 	struct pglist_data *p;
@@ -1371,20 +1345,26 @@ static void __init bootmem_init_one_node
 			nid, end_pfn);
 		free_bootmem_with_active_regions(nid, end_pfn);
 
-		trim_reserved_in_node(nid);
-
-		numadbg("  sparse_memory_present_with_active_regions(%d)\n",
-			nid);
-		sparse_memory_present_with_active_regions(nid);
 	}
 }
+#endif
+
+u64 __init get_max_mapped(void)
+{
+	/* what is max_pfn_mapped for sparc64 ? */
+	u64 end = max_pfn;
+
+	end <<= PAGE_SHIFT;
+
+	return end;
+}
 
 static unsigned long __init bootmem_init(unsigned long phys_base)
 {
 	unsigned long end_pfn;
 	int nid;
 
-	end_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
+	end_pfn = fw_memmap_end_of_ram_pfn();
 	max_pfn = max_low_pfn = end_pfn;
 	min_low_pfn = (phys_base >> PAGE_SHIFT);
 
@@ -1392,10 +1372,23 @@ static unsigned long __init bootmem_init
 		bootmem_init_nonnuma();
 
 	/* XXX cpu notifier XXX */
-
+#ifndef CONFIG_NO_BOOTMEM
 	for_each_online_node(nid)
 		bootmem_init_one_node(nid);
 
+	early_res_to_bootmem(0, end_pfn << PAGE_SHIFT);
+#endif
+
+	for_each_online_node(nid) {
+		struct pglist_data *p;
+		p = NODE_DATA(nid);
+		if (p->node_spanned_pages) {
+			numadbg("  sparse_memory_present_with_active_regions(%d)\n",
+				nid);
+			sparse_memory_present_with_active_regions(nid);
+		}
+	}
+
 	sparse_init();
 
 	return end_pfn;
@@ -1681,9 +1674,40 @@ pgd_t swapper_pg_dir[2048];
 static void sun4u_pgprot_init(void);
 static void sun4v_pgprot_init(void);
 
+void __init setup_memory_map(void)
+{
+	int i;
+	unsigned long phys_base;
+	/* Find available physical memory...
+	 *
+	 * Read it twice in order to work around a bug in openfirmware.
+	 * The call to grab this table itself can cause openfirmware to
+	 * allocate memory, which in turn can take away some space from
+	 * the list of available memory.  Reading it twice makes sure
+	 * we really do get the final value.
+	 */
+	read_obp_translations();
+	read_obp_memory("reg", &pall[0], &pall_ents);
+	read_obp_memory("available", &pavail[0], &pavail_ents);
+	read_obp_memory("available", &pavail[0], &pavail_ents);
+
+	phys_base = 0xffffffffffffffffUL;
+	for (i = 0; i < pavail_ents; i++) {
+		phys_base = min(phys_base, pavail[i].phys_addr);
+		fw_memmap_add_region(pavail[i].phys_addr, pavail[i].reg_size,
+				 FW_MEMMAP_RAM);
+	}
+
+	sanitize_fw_memmap();
+
+	fw_memmap_print_map("obp memmap:");
+
+	find_ramdisk(phys_base);
+}
+
 void __init paging_init(void)
 {
-	unsigned long end_pfn, shift, phys_base;
+	unsigned long end_pfn, shift;
 	unsigned long real_end, i;
 
 	/* These build time checkes make sure that the dcache_dirty_cpu()
@@ -1734,35 +1758,7 @@ void __init paging_init(void)
 		sun4v_ktsb_init();
 	}
 
-	lmb_init();
-
-	/* Find available physical memory...
-	 *
-	 * Read it twice in order to work around a bug in openfirmware.
-	 * The call to grab this table itself can cause openfirmware to
-	 * allocate memory, which in turn can take away some space from
-	 * the list of available memory.  Reading it twice makes sure
-	 * we really do get the final value.
-	 */
-	read_obp_translations();
-	read_obp_memory("reg", &pall[0], &pall_ents);
-	read_obp_memory("available", &pavail[0], &pavail_ents);
-	read_obp_memory("available", &pavail[0], &pavail_ents);
-
-	phys_base = 0xffffffffffffffffUL;
-	for (i = 0; i < pavail_ents; i++) {
-		phys_base = min(phys_base, pavail[i].phys_addr);
-		lmb_add(pavail[i].phys_addr, pavail[i].reg_size);
-	}
-
-	lmb_reserve(kern_base, kern_size);
-
-	find_ramdisk(phys_base);
-
-	lmb_enforce_memory_limit(cmdline_memory_size);
-
-	lmb_analyze();
-	lmb_dump_all();
+	reserve_early(kern_base, kern_base + kern_size, "Kernel");
 
 	set_bit(0, mmu_context_bmap);
 
@@ -1815,13 +1811,18 @@ void __init paging_init(void)
 	 * IRQ stacks.
 	 */
 	for_each_possible_cpu(i) {
+		unsigned long paddr;
 		/* XXX Use node local allocations... XXX */
-		softirq_stack[i] = __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
-		hardirq_stack[i] = __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+		paddr = find_fw_memmap_area(0, -1UL, THREAD_SIZE, THREAD_SIZE);
+		reserve_early(paddr, paddr + THREAD_SIZE, "softirq_stack");
+		softirq_stack[i] = __va(paddr);
+		paddr = find_fw_memmap_area(0, -1UL, THREAD_SIZE, THREAD_SIZE);
+		reserve_early(paddr, paddr + THREAD_SIZE, "hardirq_stack");
+		hardirq_stack[i] = __va(paddr);
 	}
 
 	/* Setup bootmem... */
-	last_valid_pfn = end_pfn = bootmem_init(phys_base);
+	last_valid_pfn = end_pfn = bootmem_init(0);
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 	max_mapnr = last_valid_pfn;
@@ -1957,6 +1958,9 @@ void __init mem_init(void)
 					free_all_bootmem_node(NODE_DATA(i));
 			}
 		}
+# ifdef CONFIG_NO_BOOTMEM
+		totalram_pages += free_all_memory_core_early(MAX_NUMNODES);
+# endif
 	}
 #else
 	totalram_pages = free_all_bootmem();
@@ -2002,14 +2006,6 @@ void free_initmem(void)
 	unsigned long addr, initend;
 	int do_free = 1;
 
-	/* If the physical memory maps were trimmed by kernel command
-	 * line options, don't even try freeing this initmem stuff up.
-	 * The kernel image could have been in the trimmed out region
-	 * and if so the freeing below will free invalid page structs.
-	 */
-	if (cmdline_memory_size)
-		do_free = 0;
-
 	/*
 	 * The init section is aligned to 8k in vmlinux.lds. Page align for >8k pagesizes.
 	 */
Index: linux-2.6/arch/sparc/configs/sparc64_defconfig
===================================================================
--- linux-2.6.orig/arch/sparc/configs/sparc64_defconfig
+++ linux-2.6/arch/sparc/configs/sparc64_defconfig
@@ -1916,5 +1916,4 @@ CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
Index: linux-2.6/arch/sparc/include/asm/lmb.h
===================================================================
--- linux-2.6.orig/arch/sparc/include/asm/lmb.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _SPARC64_LMB_H
-#define _SPARC64_LMB_H
-
-#include <asm/oplib.h>
-
-#define LMB_DBG(fmt...) prom_printf(fmt)
-
-#define LMB_REAL_LIMIT	0
-
-#endif /* !(_SPARC64_LMB_H) */

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  3:56     ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
@ 2010-03-22  4:00       ` David Miller
  2010-03-22  4:28         ` Yinghai Lu
  2010-03-22  5:12       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 111+ messages in thread
From: David Miller @ 2010-03-22  4:00 UTC (permalink / raw)
  To: yinghai
  Cc: benh, mingo, tglx, hpa, akpm, jbarnes, ebiederm, linux-kernel,
	linux-arch


You really aren't listening to us at all.

We told you a thousand times to investigate using LMB for all of
this.

Instead you are posting the sparc64 conversion to the e820 stuff
again.

That action means you absolutely don't value our feedback at all.

You seem to really not care what a mess you are (unnecessarily)
making.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  4:00       ` David Miller
@ 2010-03-22  4:28         ` Yinghai Lu
  2010-03-22  4:33           ` David Miller
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22  4:28 UTC (permalink / raw)
  To: David Miller
  Cc: benh, mingo, tglx, hpa, akpm, jbarnes, ebiederm, linux-kernel,
	linux-arch

> 
> That action means you absolutely don't value our feedback at all.

[PATCH 01/20] x86: add find_e820_area_node
is addressing your concern that early_res didn't handle memory cross the nodes problem.

YH

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  4:28         ` Yinghai Lu
@ 2010-03-22  4:33           ` David Miller
  2010-03-22  9:28               ` Ingo Molnar
  0 siblings, 1 reply; 111+ messages in thread
From: David Miller @ 2010-03-22  4:33 UTC (permalink / raw)
  To: yinghai
  Cc: benh, mingo, tglx, hpa, akpm, jbarnes, ebiederm, linux-kernel,
	linux-arch

From: Yinghai Lu <yinghai@kernel.org>
Date: Sun, 21 Mar 2010 21:28:38 -0700

>> 
>> That action means you absolutely don't value our feedback at all.
> 
> [PATCH 01/20] x86: add find_e820_area_node
> is addressing your concern that early_res didn't handle memory cross the nodes problem.

Now I know that you _REALLY_ aren't listening to us.

We said to use LMB because 1) it already exists 2) many
platforms have been using it for years and 3) it doesn't
lack the features you're now having to add to e820.

Instead of trying to use LMB, you're just addding feature after
feature to e820 in order to bring it up to having parity with LMB.

You're wasting a lot of time, and you're completely ignoring an
existing facility that has been working on and used for many
years.

And you've never ever convinced any of us familiar with LMB why you
keep doing this, and why LMB can't be used for what you need this
generic e820 crap for.

I'm absolutely flabbergasted at this point, you really have no
value for the feedback you've been given.

None at all.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  3:56     ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
  2010-03-22  4:00       ` David Miller
@ 2010-03-22  5:12       ` Benjamin Herrenschmidt
  2010-03-22  6:09         ` Yinghai Lu
  1 sibling, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22  5:12 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

On Sun, 2010-03-21 at 20:56 -0700, Yinghai Lu wrote:
> On 03/21/2010 07:37 PM, Benjamin Herrenschmidt wrote:
> > On Sun, 2010-03-21 at 00:13 -0700, Yinghai Lu wrote:
> >> move it to kernel/fw_memmap.c from arch/x86/kernel/e820.c
> >>
> >> -v2: add fw_memmap wrapper to some func...
> >>      move some functions back to e820.c
> > 
> > NAK
> at this point, kernel/early_res.c and kernel/fw_memmap.c is protected with HAVE_EARLY_RES
> 
> obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o fw_memmap.o
> 
> so it will not increase size that doesn't support early_res/bootmem yet.

I'm still not at all happy with it. It's not only about increasing the
size of the kernel. It's about moving some x86 specific stuff and more
or less arbitrarily deciding that everybody has to convert to that model
now, despite the fact that more suited alternatives have existed for
years, rather than thinking about doing the logical thing, which is to
convert x86 over to lmb, eventually adding the missing functionalities
in lmb if need be.

Also, there's something just plain gross about the choice of names.

fw_memmap is something I wouldn't wish my enemies to have to type on a
keyboard, it looks ugly, and it lends to way too long function names. In
addition to the fact that your "generic" facility is still all cluttered
with the e820 names and other very x86 centric definitions.

It -may- well be that adapting x86 to lmb isn't a practical approach,
but if that was the case, then please justify why with precise technical
reasons, which we can discuss then in details and make a decision based
on that.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  5:12       ` Benjamin Herrenschmidt
@ 2010-03-22  6:09         ` Yinghai Lu
  2010-03-22  7:05           ` Eric W. Biederman
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22  6:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Jesse Barnes, Eric W. Biederman, linux-kernel,
	linux-arch

On 03/21/2010 10:12 PM, Benjamin Herrenschmidt wrote:
> It -may- well be that adapting x86 to lmb isn't a practical approach,
> but if that was the case, then please justify why with precise technical
> reasons, which we can discuss then in details and make a decision based
> on that.

1. lmb is merging region when you add one new reserved region. 
early_res doesn't do that merge. so later it could figure wrong freeing.
<recently add free_early_partial, for per cpu setup only>
2. mem type in e820 map has more than RAM, it include RAM, reserved, ACPI, acpi nvs, and type 9?, and KERN_RESERVED...
3. early res, every range has one name tag.
4. early_res is array based, and it could auto double the array size and copy the old one to new one. and first entry in new array is for array itself.

if want x86 to use lmb, the e820 map and the lmb.memory are duplicated.
also need to have lmb.memory to support more type, otherwise still need to go back to check e820 about e820 reserved etc.


Thanks

Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  6:09         ` Yinghai Lu
@ 2010-03-22  7:05           ` Eric W. Biederman
  0 siblings, 0 replies; 111+ messages in thread
From: Eric W. Biederman @ 2010-03-22  7:05 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Benjamin Herrenschmidt, Ingo Molnar, Thomas Gleixner,
	H. Peter Anvin, Andrew Morton, David Miller, Jesse Barnes,
	linux-kernel, linux-arch

Yinghai Lu <yinghai@kernel.org> writes:

> On 03/21/2010 10:12 PM, Benjamin Herrenschmidt wrote:
>> It -may- well be that adapting x86 to lmb isn't a practical approach,
>> but if that was the case, then please justify why with precise technical
>> reasons, which we can discuss then in details and make a decision based
>> on that.
>
> 1. lmb is merging region when you add one new reserved region. 
> early_res doesn't do that merge. so later it could figure wrong freeing.
> <recently add free_early_partial, for per cpu setup only>

> 2. mem type in e820 map has more than RAM, it include RAM, reserved, ACPI, acpi nvs, and type 9?, and KERN_RESERVED...
lmb has a reserved type as well.

Beyond that does anything except /proc/iomem and acpi care?

> 3. early res, every range has one name tag.
> 4. early_res is array based, and it could auto double the array size and copy the old one to new one. and first entry in new array is for array itself.
>
> if want x86 to use lmb, the e820 map and the lmb.memory are duplicated.
> also need to have lmb.memory to support more type, otherwise still need to go back to check e820 about e820 reserved etc.

lmb clearly supports reserved regions, as well as ram regions.

Eric

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

* RE: Questions about SMP bootup control
  2010-03-22  3:29         ` Andi Kleen
@ 2010-03-22  7:45           ` Zhu, Yijun (NSN - CN/Beijing)
  -1 siblings, 0 replies; 111+ messages in thread
From: Zhu, Yijun (NSN - CN/Beijing) @ 2010-03-22  7:45 UTC (permalink / raw)
  To: ext Andi Kleen; +Cc: linux-kernel, linux-arch

 

-----Original Message-----
From: ext Andi Kleen [mailto:andi@firstfloor.org] 
Sent: Monday, March 22, 2010 11:29 AM
To: Zhu, Yijun (NSN - CN/Beijing)
Cc: linux-kernel@vger.kernel.org; linux-arch@vger.kernel.org
Subject: Re: Questions about SMP bootup control

"Zhu, Yijun (NSN - CN/Beijing)" <yijun.zhu@nsn.com> writes:

> Hi All:
>
> I want to do some modification on the SMP architecture.
>
> Purpose:
> Only the first CPU is running the linux OS, while others do some
private
> services processing.
>
> My solution:
> In the end of the start_secondary() function, I try to schedu the
slave
> cpu to call my private endless loop instead of cpu_idle();
>
> Result:
> The system can NOT up, there is no interactive cli.
>
> Question:
> Is there some wrong with my modification or I go to the wrong way?


> Presumably you're doing this to own that CPU exclusively.
> 
> Hooking at cpu_idle is not very useful then because interrupts will be
> already enabled and the system participate in IPIs etc, so you can't
> simply disable them, the others will miss them.
> 
> You would rather need to prevent them from being started in the
> first place, e.g. by exluding them with maxcpus=..
> 
> A better alternative might be to use isolcpus=... and schedule
> a standard program.
> 
> -Andi
> -- 
> ak@linux.intel.com -- Speaking for myself only.

Thank you very much. But when I try to apply with the isolcpus opinion,
It seems it still can NOT work.
All other CPUs are isolated, only the first one is left.
Then I found all others are still initialized by the start_secondary()
even I use the isolated opinion, in the end,
I add an endless loop instead of cpu_idle(), The system still can NOT
up.

So is there any mistake in what I did, could someone be kindness to give
me more suggestions.

Thanks in advance.




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

* RE: Questions about SMP bootup control
@ 2010-03-22  7:45           ` Zhu, Yijun (NSN - CN/Beijing)
  0 siblings, 0 replies; 111+ messages in thread
From: Zhu, Yijun (NSN - CN/Beijing) @ 2010-03-22  7:45 UTC (permalink / raw)
  To: ext Andi Kleen; +Cc: linux-kernel, linux-arch

 

-----Original Message-----
From: ext Andi Kleen [mailto:andi@firstfloor.org] 
Sent: Monday, March 22, 2010 11:29 AM
To: Zhu, Yijun (NSN - CN/Beijing)
Cc: linux-kernel@vger.kernel.org; linux-arch@vger.kernel.org
Subject: Re: Questions about SMP bootup control

"Zhu, Yijun (NSN - CN/Beijing)" <yijun.zhu@nsn.com> writes:

> Hi All:
>
> I want to do some modification on the SMP architecture.
>
> Purpose:
> Only the first CPU is running the linux OS, while others do some
private
> services processing.
>
> My solution:
> In the end of the start_secondary() function, I try to schedu the
slave
> cpu to call my private endless loop instead of cpu_idle();
>
> Result:
> The system can NOT up, there is no interactive cli.
>
> Question:
> Is there some wrong with my modification or I go to the wrong way?


> Presumably you're doing this to own that CPU exclusively.
> 
> Hooking at cpu_idle is not very useful then because interrupts will be
> already enabled and the system participate in IPIs etc, so you can't
> simply disable them, the others will miss them.
> 
> You would rather need to prevent them from being started in the
> first place, e.g. by exluding them with maxcpus=..
> 
> A better alternative might be to use isolcpus=... and schedule
> a standard program.
> 
> -Andi
> -- 
> ak@linux.intel.com -- Speaking for myself only.

Thank you very much. But when I try to apply with the isolcpus opinion,
It seems it still can NOT work.
All other CPUs are isolated, only the first one is left.
Then I found all others are still initialized by the start_secondary()
even I use the isolated opinion, in the end,
I add an endless loop instead of cpu_idle(), The system still can NOT
up.

So is there any mistake in what I did, could someone be kindness to give
me more suggestions.

Thanks in advance.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  4:33           ` David Miller
  2010-03-22  9:28               ` Ingo Molnar
@ 2010-03-22  9:28               ` Ingo Molnar
  0 siblings, 0 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22  9:28 UTC (permalink / raw)
  To: David Miller, Andrew Morton, Linus Torvalds
  Cc: yinghai, benh, tglx, hpa, akpm, jbarnes, ebiederm, linux-kernel,
	linux-arch


( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
  memory management. )

* David Miller <davem@davemloft.net> wrote:

> From: Yinghai Lu <yinghai@kernel.org>
> Date: Sun, 21 Mar 2010 21:28:38 -0700
> 
> >> 
> >> That action means you absolutely don't value our feedback at all.
> > 
> > [PATCH 01/20] x86: add find_e820_area_node
> > is addressing your concern that early_res didn't handle memory cross the nodes problem.
> 
> Now I know that you _REALLY_ aren't listening to us.

[ He has done a bit more than just to simply listen: he seems to have written 
  a patch which he thinks is addressing the concerns you pointed out. It might
  not be the response you wished for (and it might be inadequate) for but it
  sure gives me the impression of him listening to you - unless by 'listening' 
  you mean 'follow my exact opinion without argument'. ]

> We said to use LMB because 1) it already exists 2) many platforms have been 
> using it for years and 3) it doesn't lack the features you're now having to 
> add to e820.

The thing is, lib/lmb.c was librarized two years ago by you (much after 
early_res has been written for x86), but was not properly integrated into the 
core kernel nor into x86. It was first suggested by you in the early_res 
context about ten days ago, when Yinghai started posting Sparc64 patches.

Which is about half a year after the whole very difficult early_res/bootmem 
work was started by Yinghai :-(

I dont mind LMB per se, logically it seems quite similar to the early_res bits 
Yinghai has generalized (to a certain degree), and is quite a bit cleaner as 
you are writing very clean code.

Note the other side of the coin: LMB appears to be deployed on only 4 non-x86 
architectures that muster ~1% of the Linux boxes while early_res is deployed 
on more than 95%.

So there's a very real hardship of testing and conversion here that we cannot 
ignore and an even better path may be to gradually transform the more tested 
and more deployed early_res code to meet the interface details of LMB.

Please also realize the difficulties Yinghai has gone through already: 
converting and generalizing _all_ of the x86 early allocation code to a more 
generic core kernel approach, with essentially zero interest from _any_ 
non-x86 person ...

Those early_res patches were posted all over on lkml, it was literally 
hundreds of difficult patches, and now, months down the line, after we've 
tested and upstreamed it (with many nasty regressions fixed on x86 during the 
development of it) you come with a rigid "do it some other way, convert all of 
x86 over again or else" position.

I really wish non-x86 architectures apprecitated (and helped) the core kernel 
work x86 is doing, because it is subsidizing non-x86 architectures all the 
time.

For example when LMB was plopped into lib/lmb.c in 2008 why was it not ported 
to x86, our most popular architecture? Did you consider posting LMB patches 
for x86 instead of expecting Yinghai to post Sparc64, PowerPC, SH and 
Microblaze patches?

Anyway, i'm sure we can work out an approach, and yes, LMB looks pretty good 
and could be picked up if it can be done gradually - given some mutual 
willingness to work on this as equals.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
@ 2010-03-22  9:28               ` Ingo Molnar
  0 siblings, 0 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22  9:28 UTC (permalink / raw)
  To: David Miller, Linus Torvalds
  Cc: yinghai, benh, tglx, hpa, akpm, jbarnes, ebiederm, linux-kernel,
	linux-arch


( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
  memory management. )

* David Miller <davem@davemloft.net> wrote:

> From: Yinghai Lu <yinghai@kernel.org>
> Date: Sun, 21 Mar 2010 21:28:38 -0700
> 
> >> 
> >> That action means you absolutely don't value our feedback at all.
> > 
> > [PATCH 01/20] x86: add find_e820_area_node
> > is addressing your concern that early_res didn't handle memory cross the nodes problem.
> 
> Now I know that you _REALLY_ aren't listening to us.

[ He has done a bit more than just to simply listen: he seems to have written 
  a patch which he thinks is addressing the concerns you pointed out. It might
  not be the response you wished for (and it might be inadequate) for but it
  sure gives me the impression of him listening to you - unless by 'listening' 
  you mean 'follow my exact opinion without argument'. ]

> We said to use LMB because 1) it already exists 2) many platforms have been 
> using it for years and 3) it doesn't lack the features you're now having to 
> add to e820.

The thing is, lib/lmb.c was librarized two years ago by you (much after 
early_res has been written for x86), but was not properly integrated into the 
core kernel nor into x86. It was first suggested by you in the early_res 
context about ten days ago, when Yinghai started posting Sparc64 patches.

Which is about half a year after the whole very difficult early_res/bootmem 
work was started by Yinghai :-(

I dont mind LMB per se, logically it seems quite similar to the early_res bits 
Yinghai has generalized (to a certain degree), and is quite a bit cleaner as 
you are writing very clean code.

Note the other side of the coin: LMB appears to be deployed on only 4 non-x86 
architectures that muster ~1% of the Linux boxes while early_res is deployed 
on more than 95%.

So there's a very real hardship of testing and conversion here that we cannot 
ignore and an even better path may be to gradually transform the more tested 
and more deployed early_res code to meet the interface details of LMB.

Please also realize the difficulties Yinghai has gone through already: 
converting and generalizing _all_ of the x86 early allocation code to a more 
generic core kernel approach, with essentially zero interest from _any_ 
non-x86 person ...

Those early_res patches were posted all over on lkml, it was literally 
hundreds of difficult patches, and now, months down the line, after we've 
tested and upstreamed it (with many nasty regressions fixed on x86 during the 
development of it) you come with a rigid "do it some other way, convert all of 
x86 over again or else" position.

I really wish non-x86 architectures apprecitated (and helped) the core kernel 
work x86 is doing, because it is subsidizing non-x86 architectures all the 
time.

For example when LMB was plopped into lib/lmb.c in 2008 why was it not ported 
to x86, our most popular architecture? Did you consider posting LMB patches 
for x86 instead of expecting Yinghai to post Sparc64, PowerPC, SH and 
Microblaze patches?

Anyway, i'm sure we can work out an approach, and yes, LMB looks pretty good 
and could be picked up if it can be done gradually - given some mutual 
willingness to work on this as equals.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
@ 2010-03-22  9:28               ` Ingo Molnar
  0 siblings, 0 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22  9:28 UTC (permalink / raw)
  To: David Miller, Andrew Morton, Linus Torvalds
  Cc: yinghai, benh, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
  memory management. )

* David Miller <davem@davemloft.net> wrote:

> From: Yinghai Lu <yinghai@kernel.org>
> Date: Sun, 21 Mar 2010 21:28:38 -0700
> 
> >> 
> >> That action means you absolutely don't value our feedback at all.
> > 
> > [PATCH 01/20] x86: add find_e820_area_node
> > is addressing your concern that early_res didn't handle memory cross the nodes problem.
> 
> Now I know that you _REALLY_ aren't listening to us.

[ He has done a bit more than just to simply listen: he seems to have written 
  a patch which he thinks is addressing the concerns you pointed out. It might
  not be the response you wished for (and it might be inadequate) for but it
  sure gives me the impression of him listening to you - unless by 'listening' 
  you mean 'follow my exact opinion without argument'. ]

> We said to use LMB because 1) it already exists 2) many platforms have been 
> using it for years and 3) it doesn't lack the features you're now having to 
> add to e820.

The thing is, lib/lmb.c was librarized two years ago by you (much after 
early_res has been written for x86), but was not properly integrated into the 
core kernel nor into x86. It was first suggested by you in the early_res 
context about ten days ago, when Yinghai started posting Sparc64 patches.

Which is about half a year after the whole very difficult early_res/bootmem 
work was started by Yinghai :-(

I dont mind LMB per se, logically it seems quite similar to the early_res bits 
Yinghai has generalized (to a certain degree), and is quite a bit cleaner as 
you are writing very clean code.

Note the other side of the coin: LMB appears to be deployed on only 4 non-x86 
architectures that muster ~1% of the Linux boxes while early_res is deployed 
on more than 95%.

So there's a very real hardship of testing and conversion here that we cannot 
ignore and an even better path may be to gradually transform the more tested 
and more deployed early_res code to meet the interface details of LMB.

Please also realize the difficulties Yinghai has gone through already: 
converting and generalizing _all_ of the x86 early allocation code to a more 
generic core kernel approach, with essentially zero interest from _any_ 
non-x86 person ...

Those early_res patches were posted all over on lkml, it was literally 
hundreds of difficult patches, and now, months down the line, after we've 
tested and upstreamed it (with many nasty regressions fixed on x86 during the 
development of it) you come with a rigid "do it some other way, convert all of 
x86 over again or else" position.

I really wish non-x86 architectures apprecitated (and helped) the core kernel 
work x86 is doing, because it is subsidizing non-x86 architectures all the 
time.

For example when LMB was plopped into lib/lmb.c in 2008 why was it not ported 
to x86, our most popular architecture? Did you consider posting LMB patches 
for x86 instead of expecting Yinghai to post Sparc64, PowerPC, SH and 
Microblaze patches?

Anyway, i'm sure we can work out an approach, and yes, LMB looks pretty good 
and could be picked up if it can be done gradually - given some mutual 
willingness to work on this as equals.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  9:28               ` Ingo Molnar
  (?)
  (?)
@ 2010-03-22 11:30               ` Paul Mackerras
  2010-03-22 13:05                 ` Ingo Molnar
  -1 siblings, 1 reply; 111+ messages in thread
From: Paul Mackerras @ 2010-03-22 11:30 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, benh, tglx,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, Mar 22, 2010 at 10:28:09AM +0100, Ingo Molnar wrote:

> ( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
>   memory management. )

[snip]

> Please also realize the difficulties Yinghai has gone through already: 
> converting and generalizing _all_ of the x86 early allocation code to a more 
> generic core kernel approach, with essentially zero interest from _any_ 
> non-x86 person ...

It still seemed to have a lot that was x86-specific - in particular it
seemed to have a lot of code to cope with various mistakes that
firmware might have made in the memory map.  That adds code which is
basically just bloat on architectures where those problems don't
arise.

The fw_memmap.c code also still seemed to be tied to the x86 e820 data
structures and layouts.

> Those early_res patches were posted all over on lkml, it was literally 
> hundreds of difficult patches, and now, months down the line, after we've 
> tested and upstreamed it (with many nasty regressions fixed on x86 during the 
> development of it) you come with a rigid "do it some other way, convert all of 
> x86 over again or else" position.

Well I personally don't mind if x86 uses early_res or whatever other
code in arch/x86 to handle the problems that arise from deficient
firmware.  I just don't see any value in converting powerpc or sparc64
over to using ~2000 lines of early_res/fw_memmap code where the
existing ~500 lines of lmb code is working just fine.

And I don't see the point of moving the x86 e820 stuff into the kernel
directory.  Does any other platform use e820 tables?

> I really wish non-x86 architectures apprecitated (and helped) the core kernel 
> work x86 is doing, because it is subsidizing non-x86 architectures all the 
> time.

We do help with core kernel work.  Coping with deficient x86 firmware
doesn't really feel like core kernel work to me though.

Paul.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 11:30               ` Paul Mackerras
@ 2010-03-22 13:05                 ` Ingo Molnar
  2010-03-22 21:04                   ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22 13:05 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, benh, tglx,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch


* Paul Mackerras <paulus@samba.org> wrote:

> And I don't see the point of moving the x86 e820 stuff into the kernel 
> directory. [...]

I dont see the point of that either - that is a mistake. e820 is an x86 bios 
call and we shouldnt name a generic mechanism after that. e820 is absolutely 
messy and has no place anywhere beyond x86.

The main technical argument i see is 'early_res versus LMB'. Even there i'd 
prefer LMB from a technical quality POV.

> Well I personally don't mind if x86 uses early_res or whatever other code in 
> arch/x86 to handle the problems that arise from deficient firmware.  I just 
> don't see any value in converting powerpc or sparc64 over to using ~2000 
> lines of early_res/fw_memmap code where the existing ~500 lines of lmb code 
> is working just fine.

Lets put it this way then: do you see any point in PowerPC making use of a 10+ 
million lines of code kernel that is being mainly (80%+) financed, developed, 
tested and deployed by people who care about x86 mostly?

If yes then it seems like a pretty damn good deal to me for PowerPC to go 
beyond its narrow short-term self-interest and work towards generalizations 
more actively, and even consider touching its 500 lines of lmb code ...

I dont know how many times we've accomodated for non-x86 architectures in 
various pieces of kernel code.

Obviously if there's bloat affecting PowerPC then that can be addressed via 
technical measures. But we really shouldnt leave the slightly incompatible 
early allocators in place. (we shouldnt have let them get created in the first 
place, but that is water down the bridge.)

Thanks,

	Ingo

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

* Re: [PATCH 19/20] x86/pci: ioh new version read all at same time
  2010-03-21  7:13   ` Yinghai Lu
  (?)
@ 2010-03-22 16:16     ` Jesse Barnes
  -1 siblings, 0 replies; 111+ messages in thread
From: Jesse Barnes @ 2010-03-22 16:16 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Eric W. Biederman, linux-kernel, linux-arch,
	Yinghai Lu

On Sun, 21 Mar 2010 00:13:20 -0700
Yinghai Lu <yinghai@kernel.org> wrote:

> also it will add back default range to legacy IOH
> 

This patch is a bit short on details.  Are we fixing a real bug here
that _CRS fails to cover?  Or is it just for debug purposes?

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 19/20] x86/pci: ioh new version read all at same time
@ 2010-03-22 16:16     ` Jesse Barnes
  0 siblings, 0 replies; 111+ messages in thread
From: Jesse Barnes @ 2010-03-22 16:16 UTC (permalink / raw)
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Eric W. Biederman, linux-kernel, linux-arch,
	Yinghai Lu

On Sun, 21 Mar 2010 00:13:20 -0700
Yinghai Lu <yinghai@kernel.org> wrote:

> also it will add back default range to legacy IOH
> 

This patch is a bit short on details.  Are we fixing a real bug here
that _CRS fails to cover?  Or is it just for debug purposes?

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 19/20] x86/pci: ioh new version read all at same time
@ 2010-03-22 16:16     ` Jesse Barnes
  0 siblings, 0 replies; 111+ messages in thread
From: Jesse Barnes @ 2010-03-22 16:16 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Eric W. Biederman, linux-kernel, linux-arch

On Sun, 21 Mar 2010 00:13:20 -0700
Yinghai Lu <yinghai@kernel.org> wrote:

> also it will add back default range to legacy IOH
> 

This patch is a bit short on details.  Are we fixing a real bug here
that _CRS fails to cover?  Or is it just for debug purposes?

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22  9:28               ` Ingo Molnar
                                 ` (2 preceding siblings ...)
  (?)
@ 2010-03-22 18:18               ` Thomas Gleixner
  2010-03-22 19:37                 ` Ingo Molnar
  -1 siblings, 1 reply; 111+ messages in thread
From: Thomas Gleixner @ 2010-03-22 18:18 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, benh, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

Ingo,

On Mon, 22 Mar 2010, Ingo Molnar wrote:
> 
> ( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
>   memory management. )
> 
> * David Miller <davem@davemloft.net> wrote:
> 
> > From: Yinghai Lu <yinghai@kernel.org>
> > Date: Sun, 21 Mar 2010 21:28:38 -0700
> > 
> > >> 
> > >> That action means you absolutely don't value our feedback at all.
> > > 
> > > [PATCH 01/20] x86: add find_e820_area_node
> > > is addressing your concern that early_res didn't handle memory cross the nodes problem.
> > 
> > Now I know that you _REALLY_ aren't listening to us.

> [ He has done a bit more than just to simply listen: he seems to
> have written a patch which he thinks is addressing the concerns you
> pointed out. It might not be the response you wished for (and it
> might be inadequate) for but it sure gives me the impression of him
> listening to you - unless by 'listening' you mean 'follow my exact
> opinion without argument'. ]

I tend to disagree. Fixing the bug pointed out by Dave is not really a
good argument about listening.

The main point is that there is still no answer why lmb cannot be used
and the reposted patch still is a full move of the x86 e820 functions
into kernel/fw_memmap.c.

That's not a generalization, that's simply a relocation of x86 code to
kernel/. And I agree with Dave and Ben that this is an useless
exercise.

> > We said to use LMB because 1) it already exists 2) many platforms
> > have been using it for years and 3) it doesn't lack the features
> > you're now having to add to e820.
>
> The thing is, lib/lmb.c was librarized two years ago by you (much
> after early_res has been written for x86), but was not properly
> integrated into the core kernel nor into x86. It was first suggested
> by you in the early_res context about ten days ago, when Yinghai
> started posting Sparc64 patches.
>
> Which is about half a year after the whole very difficult
> early_res/bootmem work was started by Yinghai :-(

Well, the early_res split out from x86 was mostly an x86 related
effort and there is no point on enforcing that to archs which are
happily using lmb for quite a while.

You have to admit, that we did not notice either that lmb could be
reused for that purpose as well, so blaming Dave now for not paying
attention to the x86 early_res bits is unfair at least.
 
> I dont mind LMB per se, logically it seems quite similar to the
> early_res bits Yinghai has generalized (to a certain degree), and is
> quite a bit cleaner as you are writing very clean code.
>
> Note the other side of the coin: LMB appears to be deployed on only
> 4 non-x86 architectures that muster ~1% of the Linux boxes while
> early_res is deployed on more than 95%.

Come on, that's a stupid argument. The lmb code looks well structured
and understandable which I can't say about early_res.c. And it
definitly got a fair amount of testing and shakeout.

> So there's a very real hardship of testing and conversion here that
> we cannot ignore and an even better path may be to gradually
> transform the more tested and more deployed early_res code to meet
> the interface details of LMB.

I'd rather see moving that code to the cleaner code base of lmb.

> Please also realize the difficulties Yinghai has gone through
> already: converting and generalizing _all_ of the x86 early
> allocation code to a more generic core kernel approach, with
> essentially zero interest from _any_ non-x86 person ...  Those
> early_res patches were posted all over on lkml, it was literally
> hundreds of difficult patches, and now, months down the line, after
> we've tested and upstreamed it (with many nasty regressions fixed on
> x86 during the development of it) you come with a rigid "do it some
> other way, convert all of x86 over again or else" position.

That's not what Dave and Ben said. They just opposed that we push the
e820 horror into kernel/ and enforce it on everybody else.
 
> I really wish non-x86 architectures apprecitated (and helped) the
> core kernel work x86 is doing, because it is subsidizing non-x86
> architectures all the time.

Can we just stop that "x86 is the center of the universe" chant? 

Most of the core kernel work is done by core kernel developers. Just
because you and I ended up being x86 maintainers does not change that
at all.

In some areas the core code actually suffers from x86. Just look at
timers. At least 50% of the code in kernel/time/clock* and tick-* is
just there to cope with x86 specific hardware wreckage.

I don't see a point in doing the same thing with the e820 horror. That
code drop in kernel/fw_memmap.c is _NOT_ what I consider core kernel
work in the sense of providing generalized non arch specific
infrastructure.

Also I consider lmb core infrastructure. It does not have to be placed
in kernel/ to be accounted for it. It's pretty generic and easy to
extend.

> For example when LMB was plopped into lib/lmb.c in 2008 why was it
> not ported to x86, our most popular architecture? Did you consider

Why did _we_ not look at LMB? The early res code of x86 was (and still
is to some degree) a tangled mess and I wouldn't have expected that
some non x86 person would touch that with a ten foot pole.

We made a mistake and it got pointed out, so we better sit down and
make our homework instead of insisting that early_res/fw_memmap is
something set in stone.

> posting LMB patches for x86 instead of expecting Yinghai to post
> Sparc64, PowerPC, SH and Microblaze patches?

Well, it's pretty easy to move those archs over, but I cannot see any
reason why they should move to something which they consider inferior.
 
> Anyway, i'm sure we can work out an approach, and yes, LMB looks
> pretty good and could be picked up if it can be done gradually -
> given some mutual willingness to work on this as equals.

I think it was made entirely clear, that nobody is opposing to extend
lmb if the need arises. 

So before going any further on this early_res stuff, it needs to be
analysed what has to be done (if at all) to make lmb usable for
x86. From that we can figure out on a technical argument how to
proceed, not by reposting e820 -> kernel patches over and over.

Thanks,

	tglx

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

* Re: [PATCH 19/20] x86/pci: ioh new version read all at same time
  2010-03-22 16:16     ` Jesse Barnes
  (?)
  (?)
@ 2010-03-22 19:32     ` Yinghai Lu
  -1 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22 19:32 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
	David Miller, Eric W. Biederman, linux-kernel, linux-arch

On 03/22/2010 09:16 AM, Jesse Barnes wrote:
> On Sun, 21 Mar 2010 00:13:20 -0700
> Yinghai Lu <yinghai@kernel.org> wrote:
> 
>> also it will add back default range to legacy IOH
>>
> 
> This patch is a bit short on details.  Are we fixing a real bug here
> that _CRS fails to cover?  Or is it just for debug purposes?
> 

yes for debug purpose. anyway BIOS need to keep them the same.

one from HW register reading, and one from acpi.

Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 18:18               ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy Thomas Gleixner
@ 2010-03-22 19:37                 ` Ingo Molnar
  2010-03-22 20:07                   ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22 19:37 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, benh, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch


* Thomas Gleixner <tglx@linutronix.de> wrote:

> Ingo,
> 
> On Mon, 22 Mar 2010, Ingo Molnar wrote:
> > 
> > ( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
> >   memory management. )
> > 
> > * David Miller <davem@davemloft.net> wrote:
> > 
> > > From: Yinghai Lu <yinghai@kernel.org>
> > > Date: Sun, 21 Mar 2010 21:28:38 -0700
> > > 
> > > >> 
> > > >> That action means you absolutely don't value our feedback at all.
> > > > 
> > > > [PATCH 01/20] x86: add find_e820_area_node
> > > > is addressing your concern that early_res didn't handle memory cross the nodes problem.
> > > 
> > > Now I know that you _REALLY_ aren't listening to us.
> 
> > [ He has done a bit more than just to simply listen: he seems to
> > have written a patch which he thinks is addressing the concerns you
> > pointed out. It might not be the response you wished for (and it
> > might be inadequate) for but it sure gives me the impression of him
> > listening to you - unless by 'listening' you mean 'follow my exact
> > opinion without argument'. ]
> 
> I tend to disagree. Fixing the bug pointed out by Dave is not really a
> good argument about listening.
> 
> The main point is that there is still no answer why lmb cannot be used and 
> the reposted patch still is a full move of the x86 e820 functions into 
> kernel/fw_memmap.c.
> 
> That's not a generalization, that's simply a relocation of x86 code to 
> kernel/. And I agree with Dave and Ben that this is an useless exercise.

ok - i think you are right. Yinghai, mind having a look at using lib/lmb.c for 
all this?

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 19:37                 ` Ingo Molnar
@ 2010-03-22 20:07                   ` Yinghai Lu
  2010-03-22 21:08                     ` Benjamin Herrenschmidt
  2010-03-22 22:09                     ` Thomas Gleixner
  0 siblings, 2 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22 20:07 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Thomas Gleixner, David Miller, Andrew Morton, Linus Torvalds,
	benh, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/22/2010 12:37 PM, Ingo Molnar wrote:
> 
> * Thomas Gleixner <tglx@linutronix.de> wrote:
> 
>> Ingo,
>>
>> On Mon, 22 Mar 2010, Ingo Molnar wrote:
>>>
>>> ( Cc:-ed Andrew and Linus as this is a general design/policy matter wrt. 
>>>   memory management. )
>>>
>>> * David Miller <davem@davemloft.net> wrote:
>>>
>>>> From: Yinghai Lu <yinghai@kernel.org>
>>>> Date: Sun, 21 Mar 2010 21:28:38 -0700
>>>>
>>>>>>
>>>>>> That action means you absolutely don't value our feedback at all.
>>>>>
>>>>> [PATCH 01/20] x86: add find_e820_area_node
>>>>> is addressing your concern that early_res didn't handle memory cross the nodes problem.
>>>>
>>>> Now I know that you _REALLY_ aren't listening to us.
>>
>>> [ He has done a bit more than just to simply listen: he seems to
>>> have written a patch which he thinks is addressing the concerns you
>>> pointed out. It might not be the response you wished for (and it
>>> might be inadequate) for but it sure gives me the impression of him
>>> listening to you - unless by 'listening' you mean 'follow my exact
>>> opinion without argument'. ]
>>
>> I tend to disagree. Fixing the bug pointed out by Dave is not really a
>> good argument about listening.
>>
>> The main point is that there is still no answer why lmb cannot be used and 
>> the reposted patch still is a full move of the x86 e820 functions into 
>> kernel/fw_memmap.c.
>>
>> That's not a generalization, that's simply a relocation of x86 code to 
>> kernel/. And I agree with Dave and Ben that this is an useless exercise.
> 
> ok - i think you are right. Yinghai, mind having a look at using lib/lmb.c for 
> all this?

1. need to keep e820
2. use e820 range with RAM to fill lmb.memory when finizing_e820
3. use lmb.reserved to replace early_res.

current lmb is merging the region, we can not use name tag any more.

may need to dump early_memtest, and use early_res for bootmem at first.

YH

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  9:28               ` Ingo Molnar
                                 ` (3 preceding siblings ...)
  (?)
@ 2010-03-22 20:47               ` Benjamin Herrenschmidt
  2010-03-22 20:57                 ` Ingo Molnar
  2010-03-22 21:07                 ` Benjamin Herrenschmidt
  -1 siblings, 2 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 20:47 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 10:28 +0100, Ingo Molnar wrote:
> Note the other side of the coin: LMB appears to be deployed on only 4
> non-x86 
> architectures that muster ~1% of the Linux boxes while early_res is
> deployed 
> on more than 95%. 

You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my
killfile with a auto-NACK reply of anything that looks like a patch from
you.

Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 20:47               ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Benjamin Herrenschmidt
@ 2010-03-22 20:57                 ` Ingo Molnar
  2010-03-22 21:54                   ` Benjamin Herrenschmidt
  2010-03-22 21:57                   ` Paul Mackerras
  2010-03-22 21:07                 ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22 20:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch


* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Mon, 2010-03-22 at 10:28 +0100, Ingo Molnar wrote:

> > Note the other side of the coin: LMB appears to be deployed on only 4 
> > non-x86 architectures that muster ~1% of the Linux boxes while early_res 
> > is deployed on more than 95%.
> 
> You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my killfile 
> with a auto-NACK reply of anything that looks like a patch from you.

Does this mean you disagree with that? (I think it's pretty factual, last i 
checked the usage stats of devel kernels was somewhere around 99.7%.)

In any case, i dont dispute that LMB is a bit cleaner than kernel/early_res.c 
- and both are much cleaner than the new e820 kernel/fw_memmap.c code posted 
here by Yinghai.

If you dont disagree then please spare me the insults. (or move me into your 
killfile)

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22  9:28               ` Ingo Molnar
                                 ` (4 preceding siblings ...)
  (?)
@ 2010-03-22 21:01               ` Benjamin Herrenschmidt
  -1 siblings, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 10:28 +0100, Ingo Molnar wrote:
> Those early_res patches were posted all over on lkml, it was literally 
> hundreds of difficult patches, and now, months down the line, after we've 
> tested and upstreamed it (with many nasty regressions fixed on x86 during the 
> development of it) you come with a rigid "do it some other way, convert all of 
> x86 over again or else" position.

There's an easy solution here. Leave that gunk in arch/x86 where it
belongs and if you want to unify things a bit, then do it at the -API-
level only, and leave the implementation where it is.

> I really wish non-x86 architectures apprecitated (and helped) the core kernel 
> work x86 is doing, because it is subsidizing non-x86 architectures all the 
> time. 

I'm not even going to bother replying to that one

Ben.




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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 13:05                 ` Ingo Molnar
@ 2010-03-22 21:04                   ` Benjamin Herrenschmidt
  2010-03-22 21:20                     ` Ingo Molnar
  0 siblings, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Paul Mackerras, David Miller, Andrew Morton, Linus Torvalds,
	yinghai, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 14:05 +0100, Ingo Molnar wrote:
> * Paul Mackerras <paulus@samba.org> wrote:
> 
> > And I don't see the point of moving the x86 e820 stuff into the kernel 
> > directory. [...]
> 
> I dont see the point of that either - that is a mistake. e820 is an x86 bios 
> call and we shouldnt name a generic mechanism after that. e820 is absolutely 
> messy and has no place anywhere beyond x86.
> 
> The main technical argument i see is 'early_res versus LMB'. Even there i'd 
> prefer LMB from a technical quality POV.

Then we have no argument. The point is, we object to that fw_memmap/e820
stuff taking over for non-x86 architectures. We aren't saying that x86
-must- move to LMB, but if the wish is to have a common implementation
in generic code accross all archs, -then- we object to it being e820.

Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 20:47               ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Benjamin Herrenschmidt
  2010-03-22 20:57                 ` Ingo Molnar
@ 2010-03-22 21:07                 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:07 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

On Tue, 2010-03-23 at 07:47 +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2010-03-22 at 10:28 +0100, Ingo Molnar wrote:
> > Note the other side of the coin: LMB appears to be deployed on only
> 4
> > non-x86 
> > architectures that muster ~1% of the Linux boxes while early_res is
> > deployed 
> > on more than 95%. 
> 
> You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my
> killfile with a auto-NACK reply of anything that looks like a patch
> from you.

Allright, I've calmed down now, so my appologies for going over the top
here, I shouldn't reply to emails before breakfast ... but it looks like
Thomas made the point a lot more clearly than me or Dave did so it's all
good. Let's move on.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 20:07                   ` Yinghai Lu
@ 2010-03-22 21:08                     ` Benjamin Herrenschmidt
  2010-03-22 22:09                     ` Thomas Gleixner
  1 sibling, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:08 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 13:07 -0700, Yinghai Lu wrote:
> 1. need to keep e820
> 2. use e820 range with RAM to fill lmb.memory when finizing_e820
> 3. use lmb.reserved to replace early_res.
> 
> current lmb is merging the region, we can not use name tag any more.

Feel free to extend LMB as long as it's reasonable. For example, I
wouldn't object to have flags or similar things to LMB regions, one of
them being used to prevent merge for example.

> may need to dump early_memtest, and use early_res for bootmem at
> first. 

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 21:04                   ` Benjamin Herrenschmidt
@ 2010-03-22 21:20                     ` Ingo Molnar
  2010-03-22 21:52                       ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 111+ messages in thread
From: Ingo Molnar @ 2010-03-22 21:20 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Paul Mackerras, David Miller, Andrew Morton, Linus Torvalds,
	yinghai, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Mon, 2010-03-22 at 14:05 +0100, Ingo Molnar wrote:
> > * Paul Mackerras <paulus@samba.org> wrote:
> > 
> > > And I don't see the point of moving the x86 e820 stuff into the kernel 
> > > directory. [...]
> > 
> > I dont see the point of that either - that is a mistake. e820 is an x86 bios 
> > call and we shouldnt name a generic mechanism after that. e820 is absolutely 
> > messy and has no place anywhere beyond x86.
> > 
> > The main technical argument i see is 'early_res versus LMB'. Even there i'd 
> > prefer LMB from a technical quality POV.
> 
> Then we have no argument. The point is, we object to that fw_memmap/e820 
> stuff taking over for non-x86 architectures. We aren't saying that x86 
> -must- move to LMB, but if the wish is to have a common implementation in 
> generic code accross all archs, -then- we object to it being e820.

Ok, just in case i wasnt clear enough in my first reply (and i guess your mail 
means i wasnt): that whole-sale move of e820 into kernel/fw_memmap.c is a 
total non-starter as far as i'm concerned.

And i kind of like the 'logical memory block' name - it is more intuitive than 
'early_res' (which was always a misnomer IMO, just couldnt find a better name 
for it and it stuck with us).

So no arguments from me at all about the code quality aspects - i just wanted 
to highlight the huge amount of non-trivial work Yinghai has invested into 
this already, with little external help, and that if possible it would be nice 
to minimize the upsetting of related x86 code if possible. Please help him out 
with more specific suggestions about how the two memory allocation spaces 
could be unified best, to serve the needs of all these architectures - if you 
have some spare time.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 21:20                     ` Ingo Molnar
@ 2010-03-22 21:52                       ` Benjamin Herrenschmidt
  2010-03-22 22:14                         ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:52 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Paul Mackerras, David Miller, Andrew Morton, Linus Torvalds,
	yinghai, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 22:20 +0100, Ingo Molnar wrote:
> 
> So no arguments from me at all about the code quality aspects - i just wanted 
> to highlight the huge amount of non-trivial work Yinghai has invested into 
> this already, with little external help, and that if possible it would be nice 
> to minimize the upsetting of related x86 code if possible. Please help him out 
> with more specific suggestions about how the two memory allocation spaces 
> could be unified best, to serve the needs of all these architectures - if you 
> have some spare time. 

Why not start by unifying the APIs to it, while keeping the
implementation in the arch for now ? That would be a good first step and
would give us a good idea of what kind of requirements all the archs
have since to some extent those requirements need to be represented in
this API.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 20:57                 ` Ingo Molnar
@ 2010-03-22 21:54                   ` Benjamin Herrenschmidt
  2010-03-23  8:53                       ` Geert Uytterhoeven
  2010-03-23 11:16                     ` Ingo Molnar
  2010-03-22 21:57                   ` Paul Mackerras
  1 sibling, 2 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-22 21:54 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 2010-03-22 at 21:57 +0100, Ingo Molnar wrote:
> 
> > You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my killfile 
> > with a auto-NACK reply of anything that looks like a patch from you.
> 
> Does this mean you disagree with that? (I think it's pretty factual, last i 
> checked the usage stats of devel kernels was somewhere around 99.7%.)

I disagree with that being a relevant argument in the technical
discussion on the relative merits of two implementations of a given
facility. I also disagree with your numbers, if you talk about
deployement, I would be very very surprised if ARM wasn't close to
on-par with x86.

> In any case, i dont dispute that LMB is a bit cleaner than kernel/early_res.c 
> - and both are much cleaner than the new e820 kernel/fw_memmap.c code posted 
> here by Yinghai.
> 
> If you dont disagree then please spare me the insults. (or move me into your 
> killfile) 

Well, I find some of your arguments quite insulting too, but let's move
on.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 20:57                 ` Ingo Molnar
  2010-03-22 21:54                   ` Benjamin Herrenschmidt
@ 2010-03-22 21:57                   ` Paul Mackerras
  1 sibling, 0 replies; 111+ messages in thread
From: Paul Mackerras @ 2010-03-22 21:57 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Benjamin Herrenschmidt, David Miller, Andrew Morton,
	Linus Torvalds, yinghai, tglx, hpa, jbarnes, ebiederm,
	linux-kernel, linux-arch

On Mon, Mar 22, 2010 at 09:57:03PM +0100, Ingo Molnar wrote:

> Does this mean you disagree with that? (I think it's pretty factual, last i 
> checked the usage stats of devel kernels was somewhere around 99.7%.)

Is that number obtained from Fedora downloads or something?  I
wouldn't be surprised if desktop usage of bleeding-edge kernels is
near 100%, since basically all desktop machines are x86 these days.
I think that number would be biased against server and embedded
machines, but without knowing exactly what you're counting it's hard
to say.

In any case, I don't think the number of machines is particularly
relevant.  Linux runs on maybe 1% of all desktop machines in the
world, according to numbers I've seen, but that doesn't make it
irrelevant or not worth working on.

Paul.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 20:07                   ` Yinghai Lu
  2010-03-22 21:08                     ` Benjamin Herrenschmidt
@ 2010-03-22 22:09                     ` Thomas Gleixner
  2010-03-22 22:25                       ` Yinghai Lu
  1 sibling, 1 reply; 111+ messages in thread
From: Thomas Gleixner @ 2010-03-22 22:09 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

Yinghai,

On Mon, 22 Mar 2010, Yinghai Lu wrote:
> On 03/22/2010 12:37 PM, Ingo Molnar wrote:
> > * Thomas Gleixner <tglx@linutronix.de> wrote:
>
> >> The main point is that there is still no answer why lmb cannot be used and 
> >> the reposted patch still is a full move of the x86 e820 functions into 
> >> kernel/fw_memmap.c.
> >>
> >> That's not a generalization, that's simply a relocation of x86 code to 
> >> kernel/. And I agree with Dave and Ben that this is an useless exercise.
> > 
> > ok - i think you are right. Yinghai, mind having a look at using
> > lib/lmb.c for all this?
> 
> 1. need to keep e820

  That's neither an argument for using lmb nor an argument not to use
  lmb. e820 is x86 specific BIOS wreckage and it's whole purpose is
  just to feed information into a (hopefully) generic early resource
  management facility.

  e820 _CANNOT_ be generalized. Period.

> 2. use e820 range with RAM to fill lmb.memory when finizing_e820

  What's finizing_e820 ???

> 3. use lmb.reserved to replace early_res.

  What's the implication of doing that ?
 
> current lmb is merging the region, we can not use name tag any more.

  What's wrong with merging of regions ? Are you arguing about a
  specific region ("the region") ?

  Which name tag ? And why is that name tag important ?
 
> may need to dump early_memtest, and use early_res for bootmem at
> first.

  Why exactly might early_memtest not longer be possible ?

  What means "early_res for bootmem" ?

Please take some time to explain in detail. Throwing one liners and
buzzwords w/o context into such a discussion is more than counter
productive.

Thanks,

	tglx

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 21:52                       ` Benjamin Herrenschmidt
@ 2010-03-22 22:14                         ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22 22:14 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Paul Mackerras, David Miller, Andrew Morton,
	Linus Torvalds, tglx, hpa, jbarnes, ebiederm, linux-kernel,
	linux-arch

On 03/22/2010 02:52 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2010-03-22 at 22:20 +0100, Ingo Molnar wrote:
>>
>> So no arguments from me at all about the code quality aspects - i just wanted 
>> to highlight the huge amount of non-trivial work Yinghai has invested into 
>> this already, with little external help, and that if possible it would be nice 
>> to minimize the upsetting of related x86 code if possible. Please help him out 
>> with more specific suggestions about how the two memory allocation spaces 
>> could be unified best, to serve the needs of all these architectures - if you 
>> have some spare time. 
> 
> Why not start by unifying the APIs to it, while keeping the
> implementation in the arch for now ? That would be a good first step and
> would give us a good idea of what kind of requirements all the archs
> have since to some extent those requirements need to be represented in
> this API.


current early_res has

reserve/free/find

and don't have alloc, because it is equal to find + reserve.
all the find related will subtract reserved area already.
   and it use start/end (goal/limit) and it will honor goal.

extern void reserve_early(u64 start, u64 end, char *name);
extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
extern void free_early(u64 start, u64 end);
void free_early_partial(u64 start, u64 end);
extern void early_res_to_bootmem(u64 start, u64 end);

void reserve_early_without_check(u64 start, u64 end, char *name);
u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
                         u64 size, u64 align);
u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
                         u64 *sizep, u64 align);
u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
u64 get_max_mapped(void);
int get_free_all_memory_range(struct range **rangep, int nodeid);
 
lmd has:
reserve/free/alloc
and it does have lmb_find, but that doesn't subtract reserved area.

also lmb_alloc doesn't take goal. and only have limit there.


YH

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 22:09                     ` Thomas Gleixner
@ 2010-03-22 22:25                       ` Yinghai Lu
  2010-03-22 22:53                         ` Thomas Gleixner
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22 22:25 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/22/2010 03:09 PM, Thomas Gleixner wrote:
> Yinghai,
> 
> On Mon, 22 Mar 2010, Yinghai Lu wrote:
>> On 03/22/2010 12:37 PM, Ingo Molnar wrote:
>>> * Thomas Gleixner <tglx@linutronix.de> wrote:
>>
>>>> The main point is that there is still no answer why lmb cannot be used and 
>>>> the reposted patch still is a full move of the x86 e820 functions into 
>>>> kernel/fw_memmap.c.
>>>>
>>>> That's not a generalization, that's simply a relocation of x86 code to 
>>>> kernel/. And I agree with Dave and Ben that this is an useless exercise.
>>>
>>> ok - i think you are right. Yinghai, mind having a look at using
>>> lib/lmb.c for all this?
>>
>> 1. need to keep e820
> 
>   That's neither an argument for using lmb nor an argument not to use
>   lmb. e820 is x86 specific BIOS wreckage and it's whole purpose is
>   just to feed information into a (hopefully) generic early resource
>   management facility.
> 
>   e820 _CANNOT_ be generalized. Period.
> 
>> 2. use e820 range with RAM to fill lmb.memory when finizing_e820
> 
>   What's finizing_e820 ???
 finish_e820_parsing();
> 
>> 3. use lmb.reserved to replace early_res.
> 
>   What's the implication of doing that ?

early_res array is only corresponding to lmb.reserved, aka reserved region from kernel.

>  
>> current lmb is merging the region, we can not use name tag any more.
> 
>   What's wrong with merging of regions ? Are you arguing about a
>   specific region ("the region") ?

> 
>   Which name tag ? And why is that name tag important ?

struct early_res {
        u64 start, end;
        char name[15];
        char overlap_ok;
};

>  
>> may need to dump early_memtest, and use early_res for bootmem at
>> first.
> 
>   Why exactly might early_memtest not longer be possible ?
early_memtest need to call find_e820_area_size
current lmb doesn't have that kind of find util.
the one memory subtract reserved memory by kernel.
> 
>   What means "early_res for bootmem" ?

use early_res to replace bootmem, the CONFIG_NO_BOOTMEM.
that need early_res can be double or increase the slots automatically.

Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 22:25                       ` Yinghai Lu
@ 2010-03-22 22:53                         ` Thomas Gleixner
  2010-03-22 23:41                           ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Gleixner @ 2010-03-22 22:53 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, 22 Mar 2010, Yinghai Lu wrote:
> On 03/22/2010 03:09 PM, Thomas Gleixner wrote:
> > On Mon, 22 Mar 2010, Yinghai Lu wrote:
> >> On 03/22/2010 12:37 PM, Ingo Molnar wrote:
>
> >> 1. need to keep e820
> > 
> >   That's neither an argument for using lmb nor an argument not to use
> >   lmb. e820 is x86 specific BIOS wreckage and it's whole purpose is
> >   just to feed information into a (hopefully) generic early resource
> >   management facility.
> > 
> >   e820 _CANNOT_ be generalized. Period.

  I still want to know, what "need to keep e820" means for you.
 
> >> 2. use e820 range with RAM to fill lmb.memory when finizing_e820
> > 
> >   What's finizing_e820 ???
>  finish_e820_parsing();

 Yinghai, come on. Are you really expecting that everyone involved in
 this discussion goes to look up what the heck finish_e820_parsing()
 is doing ?

 You want to explain why your solution is better or why lmb is not
 sufficient, so you better go and explain what finish_e820_parsing()
 is, why finish_e820_parsing() is important and why lmb cannot cope
 with it.

> >> 3. use lmb.reserved to replace early_res.
> > 
> >   What's the implication of doing that ?
>
> early_res array is only corresponding to lmb.reserved, aka reserved
> region from kernel.
 
 Is it only corresponding (somehow) or is it a full equivivalent ?

> >> current lmb is merging the region, we can not use name tag any more.
> > 
> >   What's wrong with merging of regions ? Are you arguing about a
> >   specific region ("the region") ?

 Care to answer my question ?
 
> > 
> >   Which name tag ? And why is that name tag important ?
> 
> struct early_res {
>         u64 start, end;
>         char name[15];
>         char overlap_ok;
> };

 I'm starting to get annoyed, really. What is that name field for and
 why is that "name" field important ?

> >  
> >> may need to dump early_memtest, and use early_res for bootmem at
> >> first.
> > 
> >   Why exactly might early_memtest not longer be possible ?
>
> early_memtest need to call find_e820_area_size
> current lmb doesn't have that kind of find util.
> the one memory subtract reserved memory by kernel.

 What subtracts what ? And why is it that hard to fix that ?

> > 
> >   What means "early_res for bootmem" ?
> 
> use early_res to replace bootmem, the CONFIG_NO_BOOTMEM.
> that need early_res can be double or increase the slots automatically.

 -ENOPARSE

Yinghai, I asked you to take your time and explain things in detail
instead of shooting unparseable answers within a minute.

Everyone else in this discussion tries to be as explanatory as
possible, just you expect that everyone else is going to dig out the
crystal ball to understand the deeper meanings of your patches.

Again, please take your time to explain what needs to be done or what
is impossible to solve in your opinion, so we can get that resolved in
a way which is satisfactory and useful for all parties involved.

Thanks,

	tglx

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 22:53                         ` Thomas Gleixner
@ 2010-03-22 23:41                           ` Yinghai Lu
  2010-03-23  0:45                             ` Thomas Gleixner
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-22 23:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/22/2010 03:53 PM, Thomas Gleixner wrote:
> On Mon, 22 Mar 2010, Yinghai Lu wrote:
>> On 03/22/2010 03:09 PM, Thomas Gleixner wrote:
>>> On Mon, 22 Mar 2010, Yinghai Lu wrote:
>>>> On 03/22/2010 12:37 PM, Ingo Molnar wrote:
>>
>>>> 1. need to keep e820
>>>
>>>   That's neither an argument for using lmb nor an argument not to use
>>>   lmb. e820 is x86 specific BIOS wreckage and it's whole purpose is
>>>   just to feed information into a (hopefully) generic early resource
>>>   management facility.
>>>
>>>   e820 _CANNOT_ be generalized. Period.
> 
>   I still want to know, what "need to keep e820" means for you.

keep the most arch/x86/kernel/e820.c, and later when finish_e820_parsing() is called,
fill lmb.memory according to e820 entries with E820_RAM type.



>  
>>>> 2. use e820 range with RAM to fill lmb.memory when finizing_e820
>>>
>>>   What's finizing_e820 ???
>>  finish_e820_parsing();
> 
>  Yinghai, come on. Are you really expecting that everyone involved in
>  this discussion goes to look up what the heck finish_e820_parsing()
>  is doing ?
> 
>  You want to explain why your solution is better or why lmb is not
>  sufficient, so you better go and explain what finish_e820_parsing()
>  is, why finish_e820_parsing() is important and why lmb cannot cope
>  with it.

current x86:
a. setup e820 array.
b. early_parm mem= and memmap= related code will adjust the e820.

we don't need to call lmb_enforce_memory_limit().

> 
>>>> 3. use lmb.reserved to replace early_res.
>>>
>>>   What's the implication of doing that ?
>>
>> early_res array is only corresponding to lmb.reserved, aka reserved
>> region from kernel.
>  
>  Is it only corresponding (somehow) or is it a full equivivalent ?

early_res is not sorted and merged.

> 
>>>> current lmb is merging the region, we can not use name tag any more.
>>>
>>>   What's wrong with merging of regions ? Are you arguing about a
>>>   specific region ("the region") ?
> 
>  Care to answer my question ?
if range get merged, you can not use name with them.
>  
>>>
>>>   Which name tag ? And why is that name tag important ?
>>
>> struct early_res {
>>         u64 start, end;
>>         char name[15];
>>         char overlap_ok;
>> };
> 
>  I'm starting to get annoyed, really. What is that name field for and
>  why is that "name" field important ?

at least later when some code free a wrong range, we can figure who cause the problem.

> 
>>>  
>>>> may need to dump early_memtest, and use early_res for bootmem at
>>>> first.
>>>
>>>   Why exactly might early_memtest not longer be possible ?
>>
>> early_memtest need to call find_e820_area_size
>> current lmb doesn't have that kind of find util.
>> the one memory subtract reserved memory by kernel.
> 
>  What subtracts what ? And why is it that hard to fix that ?

lmb.memory - lmb.reserved

or e820 E820_RAM entries - early_res

move some code from early_res to lmb.c? 

> 
>>>
>>>   What means "early_res for bootmem" ?
>>
>> use early_res to replace bootmem, the CONFIG_NO_BOOTMEM.
>> that need early_res can be double or increase the slots automatically.
> 
>  -ENOPARSE
> 
> Yinghai, I asked you to take your time and explain things in detail
> instead of shooting unparseable answers within a minute.
> 
> Everyone else in this discussion tries to be as explanatory as
> possible, just you expect that everyone else is going to dig out the
> crystal ball to understand the deeper meanings of your patches.
> 
> Again, please take your time to explain what needs to be done or what
> is impossible to solve in your opinion, so we can get that resolved in
> a way which is satisfactory and useful for all parties involved.

to make x86 to use lmb, we need to extend lmb to have find_early_area.

static int __init find_overlapped_early(u64 start, u64 end)
{
        int i;
        struct lmb_properties *r;

        for (i = 0; i < lmb.reserved_cnt && lmb.reserved.region[i].size; i++) {
                r = &lmb.reserved.region[i];
                if (end > r->base && start < (r->base + r->size))
                        break;
        }

        return i;
}


/* Check for already reserved areas */
static inline int __init bad_addr(u64 *addrp, u64 size, u64 align)
{
        int i;
        u64 addr = *addrp;
        int changed = 0;
        struct lmb_properties *r;
again:
        i = find_overlapped_early(addr, addr + size);
        r = &lmb.reserved.region[i];
        if (i < lmb.reserved.cnt && r->size) {
                *addrp = addr = round_up(r->base + r->size, align);
                changed = 1;
                goto again;
        }
        return changed;
}

u64 __init find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
                         u64 size, u64 align)
{
        u64 addr, last;

        addr = round_up(ei_start, align);
        if (addr < start)
                addr = round_up(start, align);
        if (addr >= ei_last)
                goto out;
        while (bad_addr(&addr, size, align) && addr+size <= ei_last)
                ;
        last = addr + size;
        if (last > ei_last)
                goto out;
        if (last > end)
                goto out;

        return addr;

out:
        return -1ULL;
}

find_early_area_size()...

and use them we can have find_lmb_free_area

/*
 * Find a free area with specified alignment in a specific range.
 */
u64 __init find_lmb_area(u64 start, u64 end, u64 size, u64 align)
{
        int i;

        for (i = 0; i < lmb.memory.cnt; i++) {
                u64 ei_start = lmb.memory.region[i].base;
                u64 ei_end = ei_start + lmb.memory.region[i].size;

                addr = find_early_area(ei_start, ei_last, start, end,
                                         size, align);

                if (addr != -1ULL)
                        return addr;
        }
        return -1ULL;
}


also later we can use with active_range for bootmem replacement.

u64 __init find_memory_core_early(int nid, u64 size, u64 align,
                                        u64 goal, u64 limit)
{
        int i;

        /* need to go over early_node_map to find out good range for node */
        for_each_active_range_index_in_nid(i, nid) {
                u64 addr;
                u64 ei_start, ei_last;

                ei_last = early_node_map[i].end_pfn;
                ei_last <<= PAGE_SHIFT;
                ei_start = early_node_map[i].start_pfn;
                ei_start <<= PAGE_SHIFT;
                addr = find_early_area(ei_start, ei_last,
                                         goal, limit, size, align);

                if (addr == -1ULL)
                        continue;

                return addr;
        }

        return -1ULL;
}


Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-22 23:41                           ` Yinghai Lu
@ 2010-03-23  0:45                             ` Thomas Gleixner
  2010-03-23  1:04                               ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Gleixner @ 2010-03-23  0:45 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

B1;2005;0cYinghai,

On Mon, 22 Mar 2010, Yinghai Lu wrote:
> On 03/22/2010 03:53 PM, Thomas Gleixner wrote:
> > On Mon, 22 Mar 2010, Yinghai Lu wrote:
> >> On 03/22/2010 03:09 PM, Thomas Gleixner wrote:
> >>> On Mon, 22 Mar 2010, Yinghai Lu wrote:
> >>>> On 03/22/2010 12:37 PM, Ingo Molnar wrote:
> >>
> >>>> 1. need to keep e820
> >>>
> >>>   That's neither an argument for using lmb nor an argument not to use
> >>>   lmb. e820 is x86 specific BIOS wreckage and it's whole purpose is
> >>>   just to feed information into a (hopefully) generic early resource
> >>>   management facility.
> >>>
> >>>   e820 _CANNOT_ be generalized. Period.
> > 
> >   I still want to know, what "need to keep e820" means for you.
>
> keep the most arch/x86/kernel/e820.c, and later when
> finish_e820_parsing() is called, fill lmb.memory according to e820
> entries with E820_RAM type.
 
Right, and we never get rid of e820.c at all. Simply because e820 is a
x86 specific clusterfuck. No way to find anything which is remotely
insane like that in any other architecture.

I really do not understand why you ever thought that moving that code
to a generic place is something useful and acceptable.

The point is, that some of the algorithms which e820 needs to sanitize
the maps might be of general use, but definitely not the whole e820
crappola. And if you look close, lmb has most of them already.

> >  
> >>>> 2. use e820 range with RAM to fill lmb.memory when finizing_e820
> >>>
> >>>   What's finizing_e820 ???
> >>  finish_e820_parsing();
> > 
> >  Yinghai, come on. Are you really expecting that everyone involved in
> >  this discussion goes to look up what the heck finish_e820_parsing()
> >  is doing ?
> > 
> >  You want to explain why your solution is better or why lmb is not
> >  sufficient, so you better go and explain what finish_e820_parsing()
> >  is, why finish_e820_parsing() is important and why lmb cannot cope
> >  with it.
> 
> current x86:
> a. setup e820 array.
> b. early_parm mem= and memmap= related code will adjust the e820.

Dammit. I asked for an explanation not for some headword
listing. These bullet points do _NOT_ explain at all why e820 is
superior.
 
> we don't need to call lmb_enforce_memory_limit().

Of course you do not need to call lmb_enforce_memory_limit() simply
because it is not relevant to the existing e820 code at all. 

What's the point ?
 
> > 
> >>>> 3. use lmb.reserved to replace early_res.
> >>>
> >>>   What's the implication of doing that ?
> >>
> >> early_res array is only corresponding to lmb.reserved, aka reserved
> >> region from kernel.
> >  
> >  Is it only corresponding (somehow) or is it a full equivivalent ?
> 
> early_res is not sorted and merged.

So what's the implication for x86 vs. the early_res stuff ? Any down
sides, up sides other than not sorted and merged?
 
> >>>> current lmb is merging the region, we can not use name tag any more.
> >>>
> >>>   What's wrong with merging of regions ? Are you arguing about a
> >>>   specific region ("the region") ?
> > 
> >  Care to answer my question ?
> if range get merged, you can not use name with them.

Why does that matter ?
  
> >>>
> >>>   Which name tag ? And why is that name tag important ?
> >>
> >> struct early_res {
> >>         u64 start, end;
> >>         char name[15];
> >>         char overlap_ok;
> >> };
> > 
> >  I'm starting to get annoyed, really. What is that name field for and
> >  why is that "name" field important ?
> 
> at least later when some code free a wrong range, we can figure who cause the problem.

That does not explain the value of the name field at all. If some code
frees a wrong range a backtrace is always more helpful than some
arbitrary name field. Am I missing something ?
 
> >>>> may need to dump early_memtest, and use early_res for bootmem at
> >>>> first.
> >>>
> >>>   Why exactly might early_memtest not longer be possible ?
> >>
> >> early_memtest need to call find_e820_area_size
> >> current lmb doesn't have that kind of find util.
> >> the one memory subtract reserved memory by kernel.
> > 
> >  What subtracts what ? And why is it that hard to fix that ?
> 
> lmb.memory - lmb.reserved
> 
> or e820 E820_RAM entries - early_res
> 
> move some code from early_res to lmb.c? 

Care to explain in clear wording what you need to solve ? "move some
code from early_res to lmb.c?" is definitely not an useful
explanation.

> >>>
> >>>   What means "early_res for bootmem" ?
> >>
> >> use early_res to replace bootmem, the CONFIG_NO_BOOTMEM.
> >> that need early_res can be double or increase the slots automatically.
> > 
> >  -ENOPARSE
> > 
> > Yinghai, I asked you to take your time and explain things in detail
> > instead of shooting unparseable answers within a minute.
> > 
> > Everyone else in this discussion tries to be as explanatory as
> > possible, just you expect that everyone else is going to dig out the
> > crystal ball to understand the deeper meanings of your patches.
> > 
> > Again, please take your time to explain what needs to be done or what
> > is impossible to solve in your opinion, so we can get that resolved in
> > a way which is satisfactory and useful for all parties involved.
> 
> to make x86 to use lmb, we need to extend lmb to have find_early_area.

Why ?
 
> static int __init find_overlapped_early(u64 start, u64 end)
> {

No, posting arbitrary code snippets which you think are necessary to
solve it is not the way to go.

There is _ZERO_ explanation _WHY_ you think that this is a
prerequisite.

Those largely uncommented commented code snippets (uncommented as the
corresponding code in x86) are _NOT_ an explanation at all.

You just state that you need that whole bunch just w/o telling _WHY_.

The more I look into this I doubt that there is an actual reason for
this complexity. It just looks like it has grown that way by fixing
corner cases all over the place and not out of a real design
requirement.

Either that or it's just the lack of understanding how to map lmb
functionality to the problem at hand as certainly LMB does not map 1:1
to the current x86 way of solving that problem.

Please give a proper explanation for this, really !

Thanks,

	tglx

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  0:45                             ` Thomas Gleixner
@ 2010-03-23  1:04                               ` Yinghai Lu
  2010-03-23  1:36                                 ` Thomas Gleixner
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-23  1:04 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/22/2010 05:45 PM, Thomas Gleixner wrote:
> B1;2005;0cYinghai,
>>
>> to make x86 to use lmb, we need to extend lmb to have find_early_area.
> 
> Why ?

unless you want to dump two users of find_e820_area_size()

YH
  

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  1:04                               ` Yinghai Lu
@ 2010-03-23  1:36                                 ` Thomas Gleixner
  2010-03-23  6:01                                   ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Gleixner @ 2010-03-23  1:36 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

Yinghai,

On Mon, 22 Mar 2010, Yinghai Lu wrote:

> On 03/22/2010 05:45 PM, Thomas Gleixner wrote:
> > B1;2005;0cYinghai,
> >>
> >> to make x86 to use lmb, we need to extend lmb to have find_early_area.
> > 
> > Why ?
> 
> unless you want to dump two users of find_e820_area_size()

I don't care about the two users of find_e820_area_size() as long as
you are not willing to spend more than a split second to explain
things.

I'm really fed up to pull answers from your nose bit by bit. Me and
others wrote lengthy explanations and asked precise questions. 

All we get are some meager bones thrown our way.

If that's your understanding of community work, fine. It's just not
our way of working together. After spending valuable time on that I
completely agree with Dave on:

 "Now I know that you _REALLY_ aren't listening to us."

It's not only that you are not listening, you are simply ignoring our
concerns. Go ahead with that, but do not wonder about us ignoring you
as well.

Thanks,

	tglx


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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  1:36                                 ` Thomas Gleixner
@ 2010-03-23  6:01                                   ` Yinghai Lu
  2010-03-23  8:02                                     ` Ingo Molnar
  0 siblings, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-23  6:01 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds, benh,
	hpa, jbarnes, ebiederm, linux-kernel, linux-arch

please check

[PATCH 01/20] x86: add find_e820_area_node


[RFC PATCH] x86: use lmb to replace early_res

still keep kernel/early_res.c for the extension.

should move those file to lib/lmb.c later?

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/Kconfig               |    1 
 arch/x86/include/asm/e820.h    |   38 +-
 arch/x86/include/asm/lmb.h     |    8 
 arch/x86/kernel/e820.c         |  163 +----------
 arch/x86/kernel/head.c         |    2 
 arch/x86/kernel/head32.c       |    4 
 arch/x86/kernel/head64.c       |    2 
 arch/x86/kernel/setup.c        |    2 
 arch/x86/kernel/setup_percpu.c |    6 
 include/linux/early_res.h      |    9 
 include/linux/lmb.h            |    5 
 kernel/early_res.c             |  594 ++++++++++++++++-------------------------
 lib/lmb.c                      |    9 
 mm/page_alloc.c                |    2 
 mm/sparse-vmemmap.c            |    4 
 15 files changed, 321 insertions(+), 528 deletions(-)

Index: linux-2.6/arch/x86/Kconfig
===================================================================
--- linux-2.6.orig/arch/x86/Kconfig
+++ linux-2.6/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
 	select HAVE_PERF_EVENTS if (!M386 && !M486)
 	select HAVE_IOREMAP_PROT
 	select HAVE_KPROBES
+	select HAVE_LMB
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_FRAME_POINTERS
 	select HAVE_DMA_ATTRS
Index: linux-2.6/arch/x86/include/asm/e820.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/e820.h
+++ linux-2.6/arch/x86/include/asm/e820.h
@@ -113,22 +113,36 @@ static inline void early_memtest(unsigne
 
 extern unsigned long end_user_pfn;
 
-extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
-extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
-u64 find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
-extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
 #include <linux/early_res.h>
+static inline u64 find_e820_area(u64 start, u64 end, u64 size, u64 align)
+{
+	return find_lmb_area(start, end, size, align);
+}
+static inline u64 find_e820_area_size(u64 start, u64 *sizep, u64 align)
+{
+	return find_lmb_area_size(start, sizep, align);
+}
+static inline u64
+find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	return find_lmb_area_node(nid, start, end, size, align);
+}
+extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
 
 extern unsigned long e820_end_of_ram_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
-extern int e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn);
-extern void e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long end_pfn);
-extern u64 e820_hole_size(u64 start, u64 end);
+static inline void e820_register_active_regions(int nid,
+					 unsigned long start_pfn,
+					 unsigned long end_pfn)
+{
+	lmb_register_active_regions(nid, start_pfn, end_pfn);
+}
+static inline u64 e820_hole_size(u64 start, u64 end)
+{
+	return lmb_hole_size(start, end);
+}
+void init_lmb_memory(void);
+void fill_lmb_memory(void);
 extern void finish_e820_parsing(void);
 extern void e820_reserve_resources(void);
 extern void e820_reserve_resources_late(void);
Index: linux-2.6/arch/x86/kernel/e820.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/e820.c
+++ linux-2.6/arch/x86/kernel/e820.c
@@ -15,6 +15,7 @@
 #include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/firmware-map.h>
+#include <linux/lmb.h>
 
 #include <asm/e820.h>
 #include <asm/proto.h>
@@ -727,37 +728,6 @@ static int __init e820_mark_nvs_memory(v
 core_initcall(e820_mark_nvs_memory);
 #endif
 
-/*
- * Find a free area with specified alignment in a specific range.
- */
-u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 addr;
-		u64 ei_start, ei_last;
-
-		if (ei->type != E820_RAM)
-			continue;
-
-		ei_last = ei->addr + ei->size;
-		ei_start = ei->addr;
-		addr = find_early_area(ei_start, ei_last, start, end,
-					 size, align);
-
-		if (addr != -1ULL)
-			return addr;
-	}
-	return -1ULL;
-}
-
-u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
-{
-	return find_e820_area(start, end, size, align);
-}
-
 u64 __init get_max_mapped(void)
 {
 	u64 end = max_pfn_mapped;
@@ -766,47 +736,6 @@ u64 __init get_max_mapped(void)
 
 	return end;
 }
-/*
- * Find next free range after *start
- */
-u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 addr;
-		u64 ei_start, ei_last;
-
-		if (ei->type != E820_RAM)
-			continue;
-
-		ei_last = ei->addr + ei->size;
-		ei_start = ei->addr;
-		addr = find_early_area_size(ei_start, ei_last, start,
-					 sizep, align);
-
-		if (addr != -1ULL)
-			return addr;
-	}
-
-	return -1ULL;
-}
-
-u64 __init find_e820_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
-{
-	u64 addr;
-	/*
-	 * need to call this function after e820_register_active_regions
-	 * so early_node_map[] is set
-	 */
-	addr = find_memory_core_early(nid, size, align, start, end);
-	if (addr != -1ULL)
-		return addr;
-
-	/* fallback, should already have start end in the node range */
-	return find_e820_area(start, end, size, align);
-}
 
 /*
  * pre allocated 4k and reserved it in e820
@@ -900,74 +829,6 @@ unsigned long __init e820_end_of_low_ram
 {
 	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
 }
-/*
- * Finds an active region in the address range from start_pfn to last_pfn and
- * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
- */
-int __init e820_find_active_region(const struct e820entry *ei,
-				  unsigned long start_pfn,
-				  unsigned long last_pfn,
-				  unsigned long *ei_startpfn,
-				  unsigned long *ei_endpfn)
-{
-	u64 align = PAGE_SIZE;
-
-	*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
-	*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
-
-	/* Skip map entries smaller than a page */
-	if (*ei_startpfn >= *ei_endpfn)
-		return 0;
-
-	/* Skip if map is outside the node */
-	if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
-				    *ei_startpfn >= last_pfn)
-		return 0;
-
-	/* Check for overlaps */
-	if (*ei_startpfn < start_pfn)
-		*ei_startpfn = start_pfn;
-	if (*ei_endpfn > last_pfn)
-		*ei_endpfn = last_pfn;
-
-	return 1;
-}
-
-/* Walk the e820 map and register active regions within a node */
-void __init e820_register_active_regions(int nid, unsigned long start_pfn,
-					 unsigned long last_pfn)
-{
-	unsigned long ei_startpfn;
-	unsigned long ei_endpfn;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++)
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			add_active_range(nid, ei_startpfn, ei_endpfn);
-}
-
-/*
- * Find the hole size (in bytes) in the memory range.
- * @start: starting address of the memory range to scan
- * @end: ending address of the memory range to scan
- */
-u64 __init e820_hole_size(u64 start, u64 end)
-{
-	unsigned long start_pfn = start >> PAGE_SHIFT;
-	unsigned long last_pfn = end >> PAGE_SHIFT;
-	unsigned long ei_startpfn, ei_endpfn, ram = 0;
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		if (e820_find_active_region(&e820.map[i],
-					    start_pfn, last_pfn,
-					    &ei_startpfn, &ei_endpfn))
-			ram += ei_endpfn - ei_startpfn;
-	}
-	return end - start - ((u64)ram << PAGE_SHIFT);
-}
 
 static void early_panic(char *msg)
 {
@@ -1058,6 +919,28 @@ void __init finish_e820_parsing(void)
 	}
 }
 
+void __init init_lmb_memory(void)
+{
+	lmb_init();
+}
+
+void __init fill_lmb_memory(void)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+
+		if (ei->type != E820_RAM)
+			continue;
+		lmb_add(ei->addr, ei->size);
+	}
+
+	lmb_analyze();
+
+	lmb_dump_all();
+}
+
 static inline const char *e820_type_to_string(int e820_type)
 {
 	switch (e820_type) {
Index: linux-2.6/arch/x86/kernel/head.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head.c
+++ linux-2.6/arch/x86/kernel/head.c
@@ -51,5 +51,5 @@ void __init reserve_ebda_region(void)
 		lowmem = 0x9f000;
 
 	/* reserve all memory between lowmem and the 1MB mark */
-	reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved");
+	reserve_early(lowmem, 0x100000, "BIOS reserved");
 }
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head32.c
+++ linux-2.6/arch/x86/kernel/head32.c
@@ -29,13 +29,15 @@ static void __init i386_default_early_se
 
 void __init i386_start_kernel(void)
 {
+
+	init_lmb_memory();
 #ifdef CONFIG_X86_TRAMPOLINE
 	/*
 	 * But first pinch a few for the stack/trampoline stuff
 	 * FIXME: Don't need the extra page at 4K, but need to fix
 	 * trampoline before removing it. (see the GDT stuff)
 	 */
-	reserve_early_overlap_ok(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE,
+	reserve_early(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE,
 					 "EX TRAMPOLINE");
 #endif
 
Index: linux-2.6/arch/x86/kernel/head64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head64.c
+++ linux-2.6/arch/x86/kernel/head64.c
@@ -96,6 +96,8 @@ void __init x86_64_start_kernel(char * r
 
 void __init x86_64_start_reservations(char *real_mode_data)
 {
+	init_lmb_memory();
+
 	copy_bootdata(__va(real_mode_data));
 
 	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -892,6 +892,8 @@ void __init setup_arch(char **cmdline_p)
 	max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
 #endif
 
+	fill_lmb_memory();
+
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
 	setup_bios_corruption_check();
 #endif
Index: linux-2.6/arch/x86/kernel/setup_percpu.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup_percpu.c
+++ linux-2.6/arch/x86/kernel/setup_percpu.c
@@ -137,13 +137,7 @@ static void * __init pcpu_fc_alloc(unsig
 
 static void __init pcpu_fc_free(void *ptr, size_t size)
 {
-#ifdef CONFIG_NO_BOOTMEM
-	u64 start = __pa(ptr);
-	u64 end = start + size;
-	free_early_partial(start, end);
-#else
 	free_bootmem(__pa(ptr), size);
-#endif
 }
 
 static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
Index: linux-2.6/include/linux/early_res.h
===================================================================
--- linux-2.6.orig/include/linux/early_res.h
+++ linux-2.6/include/linux/early_res.h
@@ -5,15 +5,18 @@
 extern void reserve_early(u64 start, u64 end, char *name);
 extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
 extern void free_early(u64 start, u64 end);
-void free_early_partial(u64 start, u64 end);
 extern void early_res_to_bootmem(u64 start, u64 end);
 
-void reserve_early_without_check(u64 start, u64 end, char *name);
 u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
 			 u64 size, u64 align);
 u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
 			 u64 *sizep, u64 align);
-u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
+u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
+u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
+u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
+void lmb_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long last_pfn);
+u64 lmb_hole_size(u64 start, u64 end);
 u64 get_max_mapped(void);
 #include <linux/range.h>
 int get_free_all_memory_range(struct range **rangep, int nodeid);
Index: linux-2.6/include/linux/lmb.h
===================================================================
--- linux-2.6.orig/include/linux/lmb.h
+++ linux-2.6/include/linux/lmb.h
@@ -26,7 +26,8 @@ struct lmb_property {
 struct lmb_region {
 	unsigned long cnt;
 	u64 size;
-	struct lmb_property region[MAX_LMB_REGIONS+1];
+	struct lmb_property *region;
+	unsigned long region_array_size;
 };
 
 struct lmb {
@@ -37,6 +38,8 @@ struct lmb {
 };
 
 extern struct lmb lmb;
+extern struct lmb_property lmb_memory_region[MAX_LMB_REGIONS + 1];
+extern struct lmb_property lmb_reserved_region[MAX_LMB_REGIONS + 1];
 
 extern void __init lmb_init(void);
 extern void __init lmb_analyze(void);
Index: linux-2.6/kernel/early_res.c
===================================================================
--- linux-2.6.orig/kernel/early_res.c
+++ linux-2.6/kernel/early_res.c
@@ -6,284 +6,65 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/mm.h>
+#include <linux/lmb.h>
 #include <linux/early_res.h>
 
 /*
  * Early reserved memory areas.
  */
-/*
- * need to make sure this one is bigger enough before
- * find_fw_memmap_area could be used
- */
-#define MAX_EARLY_RES_X 32
-
-struct early_res {
-	u64 start, end;
-	char name[15];
-	char overlap_ok;
-};
-static struct early_res early_res_x[MAX_EARLY_RES_X] __initdata;
-
-static int max_early_res __initdata = MAX_EARLY_RES_X;
-static struct early_res *early_res __initdata = &early_res_x[0];
-static int early_res_count __initdata;
-
-static int __init find_overlapped_early(u64 start, u64 end)
-{
-	int i;
-	struct early_res *r;
-
-	for (i = 0; i < max_early_res && early_res[i].end; i++) {
-		r = &early_res[i];
-		if (end > r->start && start < r->end)
-			break;
-	}
-
-	return i;
-}
-
-/*
- * Drop the i-th range from the early reservation map,
- * by copying any higher ranges down one over it, and
- * clearing what had been the last slot.
- */
-static void __init drop_range(int i)
-{
-	int j;
-
-	for (j = i + 1; j < max_early_res && early_res[j].end; j++)
-		;
-
-	memmove(&early_res[i], &early_res[i + 1],
-	       (j - 1 - i) * sizeof(struct early_res));
-
-	early_res[j - 1].end = 0;
-	early_res_count--;
-}
-
-static void __init drop_range_partial(int i, u64 start, u64 end)
-{
-	u64 common_start, common_end;
-	u64 old_start, old_end;
-
-	old_start = early_res[i].start;
-	old_end = early_res[i].end;
-	common_start = max(old_start, start);
-	common_end = min(old_end, end);
-
-	/* no overlap ? */
-	if (common_start >= common_end)
-		return;
-
-	if (old_start < common_start) {
-		/* make head segment */
-		early_res[i].end = common_start;
-		if (old_end > common_end) {
-			char name[15];
-
-			/*
-			 * Save a local copy of the name, since the
-			 * early_res array could get resized inside
-			 * reserve_early_without_check() ->
-			 * __check_and_double_early_res(), which would
-			 * make the current name pointer invalid.
-			 */
-			strncpy(name, early_res[i].name,
-					 sizeof(early_res[i].name) - 1);
-			/* add another for left over on tail */
-			reserve_early_without_check(common_end, old_end, name);
-		}
-		return;
-	} else {
-		if (old_end > common_end) {
-			/* reuse the entry for tail left */
-			early_res[i].start = common_end;
-			return;
-		}
-		/* all covered */
-		drop_range(i);
-	}
-}
-
-/*
- * Split any existing ranges that:
- *  1) are marked 'overlap_ok', and
- *  2) overlap with the stated range [start, end)
- * into whatever portion (if any) of the existing range is entirely
- * below or entirely above the stated range.  Drop the portion
- * of the existing range that overlaps with the stated range,
- * which will allow the caller of this routine to then add that
- * stated range without conflicting with any existing range.
- */
-static void __init drop_overlaps_that_are_ok(u64 start, u64 end)
-{
-	int i;
-	struct early_res *r;
-	u64 lower_start, lower_end;
-	u64 upper_start, upper_end;
-	char name[15];
-
-	for (i = 0; i < max_early_res && early_res[i].end; i++) {
-		r = &early_res[i];
-
-		/* Continue past non-overlapping ranges */
-		if (end <= r->start || start >= r->end)
-			continue;
-
-		/*
-		 * Leave non-ok overlaps as is; let caller
-		 * panic "Overlapping early reservations"
-		 * when it hits this overlap.
-		 */
-		if (!r->overlap_ok)
-			return;
-
-		/*
-		 * We have an ok overlap.  We will drop it from the early
-		 * reservation map, and add back in any non-overlapping
-		 * portions (lower or upper) as separate, overlap_ok,
-		 * non-overlapping ranges.
-		 */
-
-		/* 1. Note any non-overlapping (lower or upper) ranges. */
-		strncpy(name, r->name, sizeof(name) - 1);
-
-		lower_start = lower_end = 0;
-		upper_start = upper_end = 0;
-		if (r->start < start) {
-			lower_start = r->start;
-			lower_end = start;
-		}
-		if (r->end > end) {
-			upper_start = end;
-			upper_end = r->end;
-		}
-
-		/* 2. Drop the original ok overlapping range */
-		drop_range(i);
-
-		i--;		/* resume for-loop on copied down entry */
-
-		/* 3. Add back in any non-overlapping ranges. */
-		if (lower_end)
-			reserve_early_overlap_ok(lower_start, lower_end, name);
-		if (upper_end)
-			reserve_early_overlap_ok(upper_start, upper_end, name);
-	}
-}
-
-static void __init __reserve_early(u64 start, u64 end, char *name,
-						int overlap_ok)
-{
-	int i;
-	struct early_res *r;
-
-	i = find_overlapped_early(start, end);
-	if (i >= max_early_res)
-		panic("Too many early reservations");
-	r = &early_res[i];
-	if (r->end)
-		panic("Overlapping early reservations "
-		      "%llx-%llx %s to %llx-%llx %s\n",
-		      start, end - 1, name ? name : "", r->start,
-		      r->end - 1, r->name);
-	r->start = start;
-	r->end = end;
-	r->overlap_ok = overlap_ok;
-	if (name)
-		strncpy(r->name, name, sizeof(r->name) - 1);
-	early_res_count++;
-}
-
-/*
- * A few early reservtations come here.
- *
- * The 'overlap_ok' in the name of this routine does -not- mean it
- * is ok for these reservations to overlap an earlier reservation.
- * Rather it means that it is ok for subsequent reservations to
- * overlap this one.
- *
- * Use this entry point to reserve early ranges when you are doing
- * so out of "Paranoia", reserving perhaps more memory than you need,
- * just in case, and don't mind a subsequent overlapping reservation
- * that is known to be needed.
- *
- * The drop_overlaps_that_are_ok() call here isn't really needed.
- * It would be needed if we had two colliding 'overlap_ok'
- * reservations, so that the second such would not panic on the
- * overlap with the first.  We don't have any such as of this
- * writing, but might as well tolerate such if it happens in
- * the future.
- */
-void __init reserve_early_overlap_ok(u64 start, u64 end, char *name)
-{
-	drop_overlaps_that_are_ok(start, end);
-	__reserve_early(start, end, name, 1);
-}
 
 static void __init __check_and_double_early_res(u64 ex_start, u64 ex_end)
 {
 	u64 start, end, size, mem;
-	struct early_res *new;
+	struct lmb_property *new, *old;
+	struct lmb_region *type = &lmb.reserved;
 
 	/* do we have enough slots left ? */
-	if ((max_early_res - early_res_count) > max(max_early_res/8, 2))
+	if ((type->region_array_size - type->cnt) >
+	    max_t(unsigned long, type->region_array_size/8, 2))
 		return;
 
+	old = type->region;
 	/* double it */
 	mem = -1ULL;
-	size = sizeof(struct early_res) * max_early_res * 2;
-	if (early_res == early_res_x)
+	size = sizeof(struct lmb_property) * type->region_array_size * 2;
+	if (old == lmb_reserved_region)
 		start = 0;
 	else
-		start = early_res[0].end;
+		start = __pa(old) + sizeof(struct lmb_property) *
+					 type->region_array_size;
 	end = ex_start;
 	if (start + size < end)
-		mem = find_fw_memmap_area(start, end, size,
-					 sizeof(struct early_res));
+		mem = find_lmb_area(start, end, size,
+					 sizeof(struct lmb_property));
 	if (mem == -1ULL) {
 		start = ex_end;
 		end = get_max_mapped();
 		if (start + size < end)
-			mem = find_fw_memmap_area(start, end, size,
-						 sizeof(struct early_res));
+			mem = find_lmb_area(start, end, size,
+						 sizeof(struct lmb_property));
 	}
 	if (mem == -1ULL)
-		panic("can not find more space for early_res array");
+		panic("can not find more space for lmb.reserved.region array");
 
 	new = __va(mem);
-	/* save the first one for own */
-	new[0].start = mem;
-	new[0].end = mem + size;
-	new[0].overlap_ok = 0;
 	/* copy old to new */
-	if (early_res == early_res_x) {
-		memcpy(&new[1], &early_res[0],
-			 sizeof(struct early_res) * max_early_res);
-		memset(&new[max_early_res+1], 0,
-			 sizeof(struct early_res) * (max_early_res - 1));
-		early_res_count++;
-	} else {
-		memcpy(&new[1], &early_res[1],
-			 sizeof(struct early_res) * (max_early_res - 1));
-		memset(&new[max_early_res], 0,
-			 sizeof(struct early_res) * max_early_res);
-	}
-	memset(&early_res[0], 0, sizeof(struct early_res) * max_early_res);
-	early_res = new;
-	max_early_res *= 2;
-	printk(KERN_DEBUG "early_res array is doubled to %d at [%llx - %llx]\n",
-		max_early_res, mem, mem + size - 1);
+	memcpy(&new[0], &old[0],
+		 sizeof(struct lmb_property) * type->region_array_size);
+	memset(&new[type->region_array_size], 0,
+		 sizeof(struct lmb_property) * type->region_array_size);
+
+	memset(type->region, 0,
+		 sizeof(struct lmb_property) * type->region_array_size);
+	type->region = new;
+	type->region_array_size *= 2;
+	printk(KERN_DEBUG "lmb.reserved.region array is doubled to %ld at [%llx - %llx]\n",
+		type->region_array_size, mem, mem + size - 1);
+	if (old != lmb_reserved_region)
+		lmb_free(__pa(old),
+		 sizeof(struct lmb_property) * type->region_array_size/2);
 }
 
-/*
- * Most early reservations come here.
- *
- * We first have drop_overlaps_that_are_ok() drop any pre-existing
- * 'overlap_ok' ranges, so that we can then reserve this memory
- * range without risk of panic'ing on an overlapping overlap_ok
- * early reservation.
- */
 void __init reserve_early(u64 start, u64 end, char *name)
 {
 	if (start >= end)
@@ -291,68 +72,18 @@ void __init reserve_early(u64 start, u64
 
 	__check_and_double_early_res(start, end);
 
-	drop_overlaps_that_are_ok(start, end);
-	__reserve_early(start, end, name, 0);
-}
-
-void __init reserve_early_without_check(u64 start, u64 end, char *name)
-{
-	struct early_res *r;
-
-	if (start >= end)
-		return;
-
-	__check_and_double_early_res(start, end);
-
-	r = &early_res[early_res_count];
-
-	r->start = start;
-	r->end = end;
-	r->overlap_ok = 0;
-	if (name)
-		strncpy(r->name, name, sizeof(r->name) - 1);
-	early_res_count++;
+	lmb_reserve(start, end - start);
 }
 
 void __init free_early(u64 start, u64 end)
 {
-	struct early_res *r;
-	int i;
-
-	i = find_overlapped_early(start, end);
-	r = &early_res[i];
-	if (i >= max_early_res || r->end != end || r->start != start)
-		panic("free_early on not reserved area: %llx-%llx!",
-			 start, end - 1);
-
-	drop_range(i);
-}
-
-void __init free_early_partial(u64 start, u64 end)
-{
-	struct early_res *r;
-	int i;
-
 	if (start == end)
 		return;
 
-	if (WARN_ONCE(start > end, "free_early_partial: wrong range [%#llx, %#llx]\n", start, end))
+	if (WARN_ONCE(start > end, "free_early: wrong range [%#llx, %#llx]\n", start, end))
 		return;
 
-try_next:
-	i = find_overlapped_early(start, end);
-	if (i >= max_early_res)
-		return;
-
-	r = &early_res[i];
-	/* hole ? */
-	if (r->end >= end && r->start <= start) {
-		drop_range_partial(i, start, end);
-		return;
-	}
-
-	drop_range_partial(i, start, end);
-	goto try_next;
+	lmb_free(start, end - start);
 }
 
 #ifdef CONFIG_NO_BOOTMEM
@@ -360,48 +91,45 @@ static void __init subtract_early_res(st
 {
 	int i, count;
 	u64 final_start, final_end;
-	int idx = 0;
 
-	count  = 0;
-	for (i = 0; i < max_early_res && early_res[i].end; i++)
-		count++;
-
-	/* need to skip first one ?*/
-	if (early_res != early_res_x)
-		idx = 1;
+	count  = lmb.reserved.cnt;
+
+	if (lmb.reserved.region != lmb_reserved_region) {
+		/*take out table it self */
+		lmb_free(__pa(lmb.reserved.region),
+			 sizeof(struct lmb_property) *
+				 lmb.reserved.region_array_size);
+	}
 
 #define DEBUG_PRINT_EARLY_RES 1
 
 #if DEBUG_PRINT_EARLY_RES
 	printk(KERN_INFO "Subtract (%d early reservations)\n", count);
 #endif
-	for (i = idx; i < count; i++) {
-		struct early_res *r = &early_res[i];
+	for (i = 0; i < count; i++) {
+		struct lmb_property *r = &lmb.reserved.region[i];
 #if DEBUG_PRINT_EARLY_RES
-		printk(KERN_INFO "  #%d [%010llx - %010llx] %15s\n", i,
-			r->start, r->end, r->name);
+		printk(KERN_INFO "  #%d [%010llx - %010llx]\n", i,
+			r->base, r->base + r->size);
 #endif
-		final_start = PFN_DOWN(r->start);
-		final_end = PFN_UP(r->end);
+		final_start = PFN_DOWN(r->base);
+		final_end = PFN_UP(r->base + r->size);
 		if (final_start >= final_end)
 			continue;
 		subtract_range(range, az, final_start, final_end);
 	}
-
 }
 
 int __init get_free_all_memory_range(struct range **rangep, int nodeid)
 {
-	int i, count;
+	int count;
 	u64 start = 0, end;
 	u64 size;
 	u64 mem;
 	struct range *range;
 	int nr_range;
 
-	count  = 0;
-	for (i = 0; i < max_early_res && early_res[i].end; i++)
-		count++;
+	count  = lmb.reserved.region_array_size;
 
 	count *= 2;
 
@@ -411,12 +139,15 @@ int __init get_free_all_memory_range(str
 	if (end > (MAX_DMA32_PFN << PAGE_SHIFT))
 		start = MAX_DMA32_PFN << PAGE_SHIFT;
 #endif
-	mem = find_fw_memmap_area(start, end, size, sizeof(struct range));
+	mem = find_lmb_area(start, end, size, sizeof(struct range));
 	if (mem == -1ULL)
 		panic("can not find more space for range free");
 
 	range = __va(mem);
-	/* use early_node_map[] and early_res to get range array at first */
+	/*
+	 * use early_node_map[] and lmb.reserved.region to get range array
+	 * at first
+	 */
 	memset(range, 0, size);
 	nr_range = 0;
 
@@ -430,10 +161,11 @@ int __init get_free_all_memory_range(str
 
 	/* need to clear it ? */
 	if (nodeid == MAX_NUMNODES) {
-		memset(&early_res[0], 0,
-			 sizeof(struct early_res) * max_early_res);
-		early_res = NULL;
-		max_early_res = 0;
+		memset(&lmb.reserved.region[0], 0,
+		 sizeof(struct lmb_property) * lmb.reserved.region_array_size);
+		lmb.reserved.region = NULL;
+		lmb.reserved.region_array_size = 0;
+		lmb.reserved.cnt = 0;
 	}
 
 	*rangep = range;
@@ -444,24 +176,24 @@ void __init early_res_to_bootmem(u64 sta
 {
 	int i, count;
 	u64 final_start, final_end;
-	int idx = 0;
 
-	count  = 0;
-	for (i = 0; i < max_early_res && early_res[i].end; i++)
-		count++;
-
-	/* need to skip first one ?*/
-	if (early_res != early_res_x)
-		idx = 1;
+	count  = lmb.reserved.cnt;
+
+	if (lmb.reserved.region != lmb_reserved_region) {
+		/*take out table it self */
+		lmb_free(__pa(lmb.reserved.region),
+			 sizeof(struct lmb_property) *
+				 lmb.reserved.region_array_size);
+	}
 
 	printk(KERN_INFO "(%d/%d early reservations) ==> bootmem [%010llx - %010llx]\n",
-			 count - idx, max_early_res, start, end);
-	for (i = idx; i < count; i++) {
-		struct early_res *r = &early_res[i];
+			 count, lmb.reserved.cnt, start, end);
+	for (i = 0; i < count; i++) {
+		struct lmb_property *r = &lmb.reserved.region[i];
 		printk(KERN_INFO "  #%d [%010llx - %010llx] %16s", i,
-			r->start, r->end, r->name);
-		final_start = max(start, r->start);
-		final_end = min(end, r->end);
+			r->base, r->base + r->size);
+		final_start = max(start, r->base);
+		final_end = min(end, r->base + r->size);
 		if (final_start >= final_end) {
 			printk(KERN_CONT "\n");
 			continue;
@@ -472,25 +204,43 @@ void __init early_res_to_bootmem(u64 sta
 				BOOTMEM_DEFAULT);
 	}
 	/* clear them */
-	memset(&early_res[0], 0, sizeof(struct early_res) * max_early_res);
-	early_res = NULL;
-	max_early_res = 0;
-	early_res_count = 0;
+	memset(&lmb.reserved.region[0], 0,
+		 sizeof(struct lmb_property) * lmb.reserved.region_array_size);
+	lmb.reserved.region = NULL;
+	lmb.reserved.region_array_size = 0;
+	lmb.reserved.cnt = 0;
 }
 #endif
 
+
+/* following code is for early_res converting */
+
+static int __init find_overlapped_early(u64 start, u64 end)
+{
+	int i;
+	struct lmb_property *r;
+
+	for (i = 0; i < lmb.reserved.cnt && lmb.reserved.region[i].size; i++) {
+		r = &lmb.reserved.region[i];
+		if (end > r->base && start < (r->base + r->size))
+			break;
+	}
+
+	return i;
+}
+
 /* Check for already reserved areas */
 static inline int __init bad_addr(u64 *addrp, u64 size, u64 align)
 {
 	int i;
 	u64 addr = *addrp;
 	int changed = 0;
-	struct early_res *r;
+	struct lmb_property *r;
 again:
 	i = find_overlapped_early(addr, addr + size);
-	r = &early_res[i];
-	if (i < max_early_res && r->end) {
-		*addrp = addr = round_up(r->end, align);
+	r = &lmb.reserved.region[i];
+	if (i < lmb.reserved.cnt && r->size) {
+		*addrp = addr = round_up(r->base + r->size, align);
 		changed = 1;
 		goto again;
 	}
@@ -506,20 +256,20 @@ static inline int __init bad_addr_size(u
 	int changed = 0;
 again:
 	last = addr + size;
-	for (i = 0; i < max_early_res && early_res[i].end; i++) {
-		struct early_res *r = &early_res[i];
-		if (last > r->start && addr < r->start) {
-			size = r->start - addr;
+	for (i = 0; i < lmb.reserved.cnt && lmb.reserved.region[i].size; i++) {
+		struct lmb_property *r = &lmb.reserved.region[i];
+		if (last > r->base && addr < r->base) {
+			size = r->base - addr;
 			changed = 1;
 			goto again;
 		}
-		if (last > r->end && addr < r->end) {
-			addr = round_up(r->end, align);
+		if (last > (r->base + r->size) && addr < (r->base + r->size)) {
+			addr = round_up(r->base + r->size, align);
 			size = last - addr;
 			changed = 1;
 			goto again;
 		}
-		if (last <= r->end && addr >= r->start) {
+		if (last <= (r->base + r->size) && addr >= r->base) {
 			(*sizep)++;
 			return 0;
 		}
@@ -531,13 +281,8 @@ again:
 	return changed;
 }
 
-/*
- * Find a free area with specified alignment in a specific range.
- * only with the area.between start to end is active range from early_node_map
- * so they are good as RAM
- */
 u64 __init find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
-			 u64 size, u64 align)
+				 u64 size, u64 align)
 {
 	u64 addr, last;
 
@@ -582,3 +327,130 @@ u64 __init find_early_area_size(u64 ei_s
 out:
 	return -1ULL;
 }
+
+/*
+ * Find a free area with specified alignment in a specific range.
+ */
+u64 __init find_lmb_area(u64 start, u64 end, u64 size, u64 align)
+{
+	int i;
+
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		u64 ei_start = lmb.memory.region[i].base;
+		u64 ei_last = ei_start + lmb.memory.region[i].size;
+		u64 addr;
+
+		addr = find_early_area(ei_start, ei_last, start, end,
+					 size, align);
+
+		if (addr != -1ULL)
+			return addr;
+	}
+	return -1ULL;
+}
+
+/*
+ * Find next free range after *start
+ */
+u64 __init find_lmb_area_size(u64 start, u64 *sizep, u64 align)
+{
+	int i;
+
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		u64 ei_start = lmb.memory.region[i].base;
+		u64 ei_last = ei_start + lmb.memory.region[i].size;
+		u64 addr;
+
+		addr = find_early_area_size(ei_start, ei_last, start,
+					 sizep, align);
+
+		if (addr != -1ULL)
+			return addr;
+	}
+
+	return -1ULL;
+}
+
+u64 __init find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align)
+{
+	u64 addr;
+	/*
+	 * need to call this function after e820_register_active_regions
+	 * so early_node_map[] is set
+	 */
+	addr = find_memory_core_early(nid, size, align, start, end);
+	if (addr != -1ULL)
+		return addr;
+
+	/* fallback, should already have start end in the node range */
+	return find_lmb_area(start, end, size, align);
+}
+
+/*
+ * Finds an active region in the address range from start_pfn to last_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the lmb entry.
+ */
+static int __init lmb_find_active_region(const struct lmb_property *ei,
+				  unsigned long start_pfn,
+				  unsigned long last_pfn,
+				  unsigned long *ei_startpfn,
+				  unsigned long *ei_endpfn)
+{
+	u64 align = PAGE_SIZE;
+
+	*ei_startpfn = round_up(ei->base, align) >> PAGE_SHIFT;
+	*ei_endpfn = round_down(ei->base + ei->size, align) >> PAGE_SHIFT;
+
+	/* Skip map entries smaller than a page */
+	if (*ei_startpfn >= *ei_endpfn)
+		return 0;
+
+	/* Skip if map is outside the node */
+	if (*ei_endpfn <= start_pfn || *ei_startpfn >= last_pfn)
+		return 0;
+
+	/* Check for overlaps */
+	if (*ei_startpfn < start_pfn)
+		*ei_startpfn = start_pfn;
+	if (*ei_endpfn > last_pfn)
+		*ei_endpfn = last_pfn;
+
+	return 1;
+}
+
+/* Walk the lmb.memory map and register active regions within a node */
+void __init lmb_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long last_pfn)
+{
+	unsigned long ei_startpfn;
+	unsigned long ei_endpfn;
+	int i;
+
+	for (i = 0; i < lmb.memory.cnt; i++)
+		if (lmb_find_active_region(&lmb.memory.region[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			add_active_range(nid, ei_startpfn, ei_endpfn);
+}
+
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+u64 __init lmb_hole_size(u64 start, u64 end)
+{
+	unsigned long start_pfn = start >> PAGE_SHIFT;
+	unsigned long last_pfn = end >> PAGE_SHIFT;
+	unsigned long ei_startpfn, ei_endpfn, ram = 0;
+	int i;
+
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		if (lmb_find_active_region(&lmb.memory.region[i],
+					    start_pfn, last_pfn,
+					    &ei_startpfn, &ei_endpfn))
+			ram += ei_endpfn - ei_startpfn;
+	}
+	return end - start - ((u64)ram << PAGE_SHIFT);
+}
+
Index: linux-2.6/lib/lmb.c
===================================================================
--- linux-2.6.orig/lib/lmb.c
+++ linux-2.6/lib/lmb.c
@@ -18,6 +18,8 @@
 #define LMB_ALLOC_ANYWHERE	0
 
 struct lmb lmb;
+struct lmb_property lmb_memory_region[MAX_LMB_REGIONS + 1];
+struct lmb_property lmb_reserved_region[MAX_LMB_REGIONS + 1];
 
 static int lmb_debug;
 
@@ -106,6 +108,11 @@ static void lmb_coalesce_regions(struct
 
 void __init lmb_init(void)
 {
+	lmb.memory.region   = lmb_memory_region;
+	lmb.memory.region_array_size   = ARRAY_SIZE(lmb_memory_region);
+	lmb.reserved.region = lmb_reserved_region;
+	lmb.reserved.region_array_size = ARRAY_SIZE(lmb_reserved_region);
+
 	/* Create a dummy zero size LMB which will get coalesced away later.
 	 * This simplifies the lmb_add() code below...
 	 */
@@ -539,3 +546,5 @@ int lmb_find(struct lmb_property *res)
 	}
 	return -1;
 }
+
+
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -3457,7 +3457,7 @@ void * __init __alloc_memory_core_early(
 
 	ptr = phys_to_virt(addr);
 	memset(ptr, 0, size);
-	reserve_early_without_check(addr, addr + size, "BOOTMEM");
+	reserve_early(addr, addr + size, "BOOTMEM");
 	return ptr;
 }
 #endif
Index: linux-2.6/mm/sparse-vmemmap.c
===================================================================
--- linux-2.6.orig/mm/sparse-vmemmap.c
+++ linux-2.6/mm/sparse-vmemmap.c
@@ -229,8 +229,8 @@ void __init sparse_mem_maps_populate_nod
 			char name[15];
 
 			snprintf(name, sizeof(name), "MEMMAP %d", nodeid);
-			reserve_early_without_check(__pa(vmemmap_buf_start),
-						    __pa(vmemmap_buf), name);
+			reserve_early(__pa(vmemmap_buf_start),
+					 __pa(vmemmap_buf), name);
 		}
 #else
 		free_bootmem(__pa(vmemmap_buf), vmemmap_buf_end - vmemmap_buf);
Index: linux-2.6/arch/x86/include/asm/lmb.h
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/include/asm/lmb.h
@@ -0,0 +1,8 @@
+#ifndef _X86_LMB_H
+#define _X86_LMB_H
+
+#define LMB_DBG(fmt...) printk(fmt)
+
+#define LMB_REAL_LIMIT	0
+
+#endif

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  6:01                                   ` Yinghai Lu
@ 2010-03-23  8:02                                     ` Ingo Molnar
  2010-03-23  9:02                                       ` Yinghai Lu
  2010-03-24  4:24                                       ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-23  8:02 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Thomas Gleixner, David Miller, Andrew Morton, Linus Torvalds,
	benh, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


* Yinghai Lu <yinghai@kernel.org> wrote:

> please check
> 
> [PATCH 01/20] x86: add find_e820_area_node
> 
> 
> [RFC PATCH] x86: use lmb to replace early_res
> 
> still keep kernel/early_res.c for the extension.
> 
> should move those file to lib/lmb.c later?
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> 
> ---
>  arch/x86/Kconfig               |    1 
>  arch/x86/include/asm/e820.h    |   38 +-
>  arch/x86/include/asm/lmb.h     |    8 
>  arch/x86/kernel/e820.c         |  163 +----------
>  arch/x86/kernel/head.c         |    2 
>  arch/x86/kernel/head32.c       |    4 
>  arch/x86/kernel/head64.c       |    2 
>  arch/x86/kernel/setup.c        |    2 
>  arch/x86/kernel/setup_percpu.c |    6 
>  include/linux/early_res.h      |    9 
>  include/linux/lmb.h            |    5 
>  kernel/early_res.c             |  594 ++++++++++++++++-------------------------
>  lib/lmb.c                      |    9 
>  mm/page_alloc.c                |    2 
>  mm/sparse-vmemmap.c            |    4 
>  15 files changed, 321 insertions(+), 528 deletions(-)

That looks like a very promising direction!

There's several things to do to make the approach fully clean:

1)

I think we want to shape this as a series of simpler (and bisectable) patches.

2)

I think we also need to concentrate the changes back into LMB:

> Index: linux-2.6/include/linux/early_res.h
> ===================================================================
> --- linux-2.6.orig/include/linux/early_res.h
> +++ linux-2.6/include/linux/early_res.h
> @@ -5,15 +5,18 @@
>  extern void reserve_early(u64 start, u64 end, char *name);
>  extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
>  extern void free_early(u64 start, u64 end);
> -void free_early_partial(u64 start, u64 end);
>  extern void early_res_to_bootmem(u64 start, u64 end);
>  
> -void reserve_early_without_check(u64 start, u64 end, char *name);
>  u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
>  			 u64 size, u64 align);
>  u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
>  			 u64 *sizep, u64 align);
> -u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
> +u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
> +u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
> +u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
> +void lmb_register_active_regions(int nid, unsigned long start_pfn,
> +					 unsigned long last_pfn);
> +u64 lmb_hole_size(u64 start, u64 end);
>  u64 get_max_mapped(void);
>  #include <linux/range.h>
>  int get_free_all_memory_range(struct range **rangep, int nodeid);

those new lmb_*() APIs should go into lmb.h.

3) 

Furthermore, i think all of early_res.c should move into lmb.c as well and we 
should eliminate kernel/early_res.c.

early_res.h will go away as well and all the new APIs will be in lmb.h.

4)

Also, we should move lib/lmb.c to mm/lmb.c, as now it's not just some optional 
library but _the_ main early-reserve memory subsystem used by the biggest 
Linux architectures.

5)

Could we perhaps also try to eliminate e820_*() method uses in arch/x86/, and 
replace them by lmb_*() API uses? (that too should be a step by step method, 
for bisectability)

> +++ linux-2.6/include/linux/lmb.h
> @@ -26,7 +26,8 @@ struct lmb_property {
>  struct lmb_region {
>  	unsigned long cnt;
>  	u64 size;
> -	struct lmb_property region[MAX_LMB_REGIONS+1];
> +	struct lmb_property *region;
> +	unsigned long region_array_size;
>  };

I suspect this should keep current LMB architectures still working, right?

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c  to fw_memmap.c
  2010-03-22 21:54                   ` Benjamin Herrenschmidt
@ 2010-03-23  8:53                       ` Geert Uytterhoeven
  2010-03-23 11:16                     ` Ingo Molnar
  1 sibling, 0 replies; 111+ messages in thread
From: Geert Uytterhoeven @ 2010-03-23  8:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds,
	yinghai, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, Mar 22, 2010 at 22:54, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2010-03-22 at 21:57 +0100, Ingo Molnar wrote:
>> > You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my killfile
>> > with a auto-NACK reply of anything that looks like a patch from you.
>>
>> Does this mean you disagree with that? (I think it's pretty factual, last i
>> checked the usage stats of devel kernels was somewhere around 99.7%.)
>
> I disagree with that being a relevant argument in the technical
> discussion on the relative merits of two implementations of a given
> facility. I also disagree with your numbers, if you talk about
> deployement, I would be very very surprised if ARM wasn't close to
> on-par with x86.

FWIW, several years ago a MontaVista representative said there were more Linux
units that did have their RT extensions than there were Linux units
that did not have them...

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
@ 2010-03-23  8:53                       ` Geert Uytterhoeven
  0 siblings, 0 replies; 111+ messages in thread
From: Geert Uytterhoeven @ 2010-03-23  8:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, David Miller, Andrew Morton, Linus Torvalds,
	yinghai, tglx, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Mon, Mar 22, 2010 at 22:54, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2010-03-22 at 21:57 +0100, Ingo Molnar wrote:
>> > You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my killfile
>> > with a auto-NACK reply of anything that looks like a patch from you.
>>
>> Does this mean you disagree with that? (I think it's pretty factual, last i
>> checked the usage stats of devel kernels was somewhere around 99.7%.)
>
> I disagree with that being a relevant argument in the technical
> discussion on the relative merits of two implementations of a given
> facility. I also disagree with your numbers, if you talk about
> deployement, I would be very very surprised if ARM wasn't close to
> on-par with x86.

FWIW, several years ago a MontaVista representative said there were more Linux
units that did have their RT extensions than there were Linux units
that did not have them...

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  8:02                                     ` Ingo Molnar
@ 2010-03-23  9:02                                       ` Yinghai Lu
  2010-03-23  9:48                                         ` Ingo Molnar
  2010-03-24  4:24                                       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-23  9:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Thomas Gleixner, David Miller, Andrew Morton, Linus Torvalds,
	benh, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/23/2010 01:02 AM, Ingo Molnar wrote:
> 
> * Yinghai Lu <yinghai@kernel.org> wrote:
> 
>> please check
>>
>> [PATCH 01/20] x86: add find_e820_area_node
>>
>>
>> [RFC PATCH] x86: use lmb to replace early_res
>>
>> still keep kernel/early_res.c for the extension.
>>
>> should move those file to lib/lmb.c later?
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>>
>> ---
>>  arch/x86/Kconfig               |    1 
>>  arch/x86/include/asm/e820.h    |   38 +-
>>  arch/x86/include/asm/lmb.h     |    8 
>>  arch/x86/kernel/e820.c         |  163 +----------
>>  arch/x86/kernel/head.c         |    2 
>>  arch/x86/kernel/head32.c       |    4 
>>  arch/x86/kernel/head64.c       |    2 
>>  arch/x86/kernel/setup.c        |    2 
>>  arch/x86/kernel/setup_percpu.c |    6 
>>  include/linux/early_res.h      |    9 
>>  include/linux/lmb.h            |    5 
>>  kernel/early_res.c             |  594 ++++++++++++++++-------------------------
>>  lib/lmb.c                      |    9 
>>  mm/page_alloc.c                |    2 
>>  mm/sparse-vmemmap.c            |    4 
>>  15 files changed, 321 insertions(+), 528 deletions(-)
> 
> That looks like a very promising direction!
> 
> There's several things to do to make the approach fully clean:
> 
> 1)
> 
> I think we want to shape this as a series of simpler (and bisectable) patches.

will check it.

at least change include/linux/lmb.h and lib/lmb.c change could be sperated.

other looks a little bit hard.
> 
> 2)
> 
> I think we also need to concentrate the changes back into LMB:

yes. put them in kernel/early_res.c and move them to lmb.c if lmb gugs are happy with the change.

> 
>> Index: linux-2.6/include/linux/early_res.h
>> ===================================================================
>> --- linux-2.6.orig/include/linux/early_res.h
>> +++ linux-2.6/include/linux/early_res.h
>> @@ -5,15 +5,18 @@
>>  extern void reserve_early(u64 start, u64 end, char *name);
>>  extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
>>  extern void free_early(u64 start, u64 end);
>> -void free_early_partial(u64 start, u64 end);
>>  extern void early_res_to_bootmem(u64 start, u64 end);
>>  
>> -void reserve_early_without_check(u64 start, u64 end, char *name);
>>  u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
>>  			 u64 size, u64 align);
>>  u64 find_early_area_size(u64 ei_start, u64 ei_last, u64 start,
>>  			 u64 *sizep, u64 align);
>> -u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
>> +u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
>> +u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
>> +u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
>> +void lmb_register_active_regions(int nid, unsigned long start_pfn,
>> +					 unsigned long last_pfn);
>> +u64 lmb_hole_size(u64 start, u64 end);
>>  u64 get_max_mapped(void);
>>  #include <linux/range.h>
>>  int get_free_all_memory_range(struct range **rangep, int nodeid);
> 
> those new lmb_*() APIs should go into lmb.h.

next version

> 
> 3) 
> 
> Furthermore, i think all of early_res.c should move into lmb.c as well and we 
> should eliminate kernel/early_res.c.
> 
> early_res.h will go away as well and all the new APIs will be in lmb.h.

current have three levels
a. old lmb users
b. x86 with bootmem
c. x86 with no-bootmem

some functions later could be moved to new bootmem.c

> 
> 4)
> 
> Also, we should move lib/lmb.c to mm/lmb.c, as now it's not just some optional 
> library but _the_ main early-reserve memory subsystem used by the biggest 
> Linux architectures.

yes

> 
> 5)
> 
> Could we perhaps also try to eliminate e820_*() method uses in arch/x86/, and 
> replace them by lmb_*() API uses? (that too should be a step by step method, 
> for bisectability)

yes.

except e820_any_mapped(,,E820_RESERVED)

others should not be used after fill_lmb_memory()

> 
>> +++ linux-2.6/include/linux/lmb.h
>> @@ -26,7 +26,8 @@ struct lmb_property {
>>  struct lmb_region {
>>  	unsigned long cnt;
>>  	u64 size;
>> -	struct lmb_property region[MAX_LMB_REGIONS+1];
>> +	struct lmb_property *region;
>> +	unsigned long region_array_size;
>>  };
> 
> I suspect this should keep current LMB architectures still working, right?

they are still working. lmb_init will connect the pointers. 

Index: linux-2.6/lib/lmb.c
===================================================================
--- linux-2.6.orig/lib/lmb.c
+++ linux-2.6/lib/lmb.c
@@ -18,6 +18,8 @@
 #define LMB_ALLOC_ANYWHERE     0
 
 struct lmb lmb;
+struct lmb_property lmb_memory_region[MAX_LMB_REGIONS + 1];
+struct lmb_property lmb_reserved_region[MAX_LMB_REGIONS + 1];
 
 static int lmb_debug;
 
@@ -106,6 +108,11 @@ static void lmb_coalesce_regions(struct
 
 void __init lmb_init(void)
 {
+       lmb.memory.region   = lmb_memory_region;
+       lmb.memory.region_array_size   = ARRAY_SIZE(lmb_memory_region);
+       lmb.reserved.region = lmb_reserved_region;
+       lmb.reserved.region_array_size = ARRAY_SIZE(lmb_reserved_region);
+
        /* Create a dummy zero size LMB which will get coalesced away later.
         * This simplifies the lmb_add() code below...
         */
@@ -169,7 +176,7 @@ static long lmb_add_region(struct lmb_re
 
        if (coalesced)
                return coalesced;
-       if (rgn->cnt >= MAX_LMB_REGIONS)
+       if (rgn->cnt >= (rgn->region_array_size - 1))
                return -1;

Thanks

Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  9:02                                       ` Yinghai Lu
@ 2010-03-23  9:48                                         ` Ingo Molnar
  2010-03-24  4:29                                           ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 111+ messages in thread
From: Ingo Molnar @ 2010-03-23  9:48 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Thomas Gleixner, David Miller, Andrew Morton, Linus Torvalds,
	benh, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


* Yinghai Lu <yinghai@kernel.org> wrote:

> > 2)
> > 
> > I think we also need to concentrate the changes back into LMB:
> 
> yes. put them in kernel/early_res.c and move them to lmb.c if lmb gugs are 
> happy with the change.

Yes, they seemed OK with changing it to accomodate x86, as long as current 
behavior stays compatible and as long as the changes are squeaky-clean.

Both of which are highly reasonable expectations ;-)

> > early_res.h will go away as well and all the new APIs will be in lmb.h.
> 
> current have three levels
> a. old lmb users
> b. x86 with bootmem
> c. x86 with no-bootmem
> 
> some functions later could be moved to new bootmem.c

I think we want to work towards the end result where we dont have bootmem.c 
anymore. I.e. a modern LMB architecture should generally not make use of 
bootmem at all.

We could do that switch on x86 straight away, and make CONFIG_NO_BOOTMEM a 
default-y option, hm? We could also hide the interactivity behind 
CONFIG_DEBUG_VM or so - and eliminate it altogether later on.

We should also switch around the flag and turn it into CONFIG_BOOTMEM.

Hm?

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-22 21:54                   ` Benjamin Herrenschmidt
  2010-03-23  8:53                       ` Geert Uytterhoeven
@ 2010-03-23 11:16                     ` Ingo Molnar
  2010-03-24  4:50                       ` Benjamin Herrenschmidt
  2010-03-24  5:47                         ` Kyle Moffett
  1 sibling, 2 replies; 111+ messages in thread
From: Ingo Molnar @ 2010-03-23 11:16 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch


* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Mon, 2010-03-22 at 21:57 +0100, Ingo Molnar wrote:
> > 
> > > You use that arguemnt ONE MORE FUCKING TIME and you'll end up in my killfile 
> > > with a auto-NACK reply of anything that looks like a patch from you.
> > 
> > Does this mean you disagree with that? (I think it's pretty factual, last i 
> > checked the usage stats of devel kernels was somewhere around 99.7%.)
> 
> I disagree with that being a relevant argument in the technical discussion 
> on the relative merits of two implementations of a given facility. I also 
> disagree with your numbers, if you talk about deployement, I would be very 
> very surprised if ARM wasn't close to on-par with x86.

As an upstream maintainer i mainly care about upstream kernel contributions. 
These contributions have three main forms:

  - patches i get against latest upstream

  - on-lkml review/analysis that is done on those patches

  - test/bug/regression reports i get against latest upstream (either directly 
    on lkml or via kerneloops.org or bugzilla.kernel.org)

So i weigh the architectures based on that input.

Since you mentioned ARM - here's the Git contribution stats. In the last 5 
years since we have kernel Git history, there's been 1080 commits to 
kernel/sched.c. Amongst those 1080 commits i could find only a _single commit_ 
(a minor fix) being related to or contributed by anyone doing ARM development!

To be on the safe side lets assume that i missed many commits, lets up that 
count to ten times of that count: 10 commits. I.e. the 'weight of ARM', when 
it comes to kernel/sched.c, is still less than 1%.
 
'millions of ARM units' alone means little to me, if it does not translate 
into actual upstream kernel contributions. Many of those 'millions of units' 
are walled off from kernel contributions: the users dont even know they are 
running Linux. They are not linked to kerneloops.org and dont produce bugzilla 
bugreports. They do finance Linux developers by proxy - but as far as the 
upstream kernel is concerned they only exist to the extent they finance kernel 
developers to care about it.

Lets look at a counter example: Sparc64. There's literally just a handful of 
Sparc64 'units' that run Linux, still the weight of the arch is much higher - 
due to the well-known highly productive kernel contributor who is using that 
architecture. I have seen about 10 times more scheduler contributions [~15 
commits] from that single unit Sparc64 angle than from the millions of ARM 
units! (and davem isnt even doing scheduler development per se - he's mostly 
doing drive-by fixes and improvements with no particular focus on the 
scheduler.)

Or lets look at an architecture that during its development had a physical 
unit count of _zero_: SGI UV. It was only running in simulators for a year but 
it sure resulted in dozens and dozens of useful patches that extended Linux's 
scalability reach. So did SGI UV matter, despite having had a zero unit count? 
Heck it did ...

I singled out kernel/sched.c but there's a very similar picture and 
contribution weights when it comes to other areas i co-maintain: lockdep, 
perf, tracing, etc.

So if you want your architecture to matter to me the rule is very simple: 
contribute, contribute, contribute, and stop whining. If you dont contribute, 
frankly you dont really exist to me. On the other hand if you are actively 
contributing while your architecture only exists on paper, it already starts 
mattering to me.

I'm really that simple.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  8:02                                     ` Ingo Molnar
  2010-03-23  9:02                                       ` Yinghai Lu
@ 2010-03-24  4:24                                       ` Benjamin Herrenschmidt
  2010-03-24  6:05                                         ` Yinghai Lu
  1 sibling, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  4:24 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Tue, 2010-03-23 at 09:02 +0100, Ingo Molnar wrote:
> > -u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
> > +u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
> > +u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
> > +u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64
> align);
> > +void lmb_register_active_regions(int nid, unsigned long start_pfn,
> > +                                      unsigned long last_pfn);
> > +u64 lmb_hole_size(u64 start, u64 end);
> >  u64 get_max_mapped(void);
> >  #include <linux/range.h>
> >  int get_free_all_memory_range(struct range **rangep, int nodeid);
> 
> those new lmb_*() APIs should go into lmb.h.

And while at it properly documented :-) I wouldn't mind also a
reasonably clear explanation in the changeset comment as to why
they are necessary for x86.

To be honest, that's my #1 grief so far with this entire patch set,
it Yinghai apparent inability to write anything ressembling remotely
like an explanation. All we get is key words, bullet points and half
sentences, and I admit have a very very hard time extracting a meaning
out of anything he's been writing so far.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-23  9:48                                         ` Ingo Molnar
@ 2010-03-24  4:29                                           ` Benjamin Herrenschmidt
  2010-03-24  4:44                                             ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  4:29 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Tue, 2010-03-23 at 10:48 +0100, Ingo Molnar wrote:
> > yes. put them in kernel/early_res.c and move them to lmb.c if lmb
> gugs are 
> > happy with the change.
> 
> Yes, they seemed OK with changing it to accomodate x86, as long as
> current 
> behavior stays compatible and as long as the changes are
> squeaky-clean.
> 
> Both of which are highly reasonable expectations ;-)

Yup. As I said, tho, I'd also like a little better level of explanation
and documentation (and I know the existing LMB interfaces are -not-
documented, but let's not add more shall we ? :-)

> I think we want to work towards the end result where we dont have
> bootmem.c  anymore. I.e. a modern LMB architecture should generally
> not make use of bootmem at all.

bootmem has one advantage over LMB, I think, in that LMB has this
annoying static array of regions, which is prone to being either too big
(wasted space) or too small.

We might want to consider a slightly smarter approach there if we are
going to replace bootmem.

I though one possibility would be to have LMB regions become more lists
than arrays, so that the static storage only needs to cover as much as
is needed during really early boot (and we could probably still move the
BSS top point on some archs to dynamically make more ... actually we
could be smart arses and use LMB to allocate more LMB list heads if we
are reaching the table limit :-)

> We could do that switch on x86 straight away, and make
> CONFIG_NO_BOOTMEM a 
> default-y option, hm? We could also hide the interactivity behind 
> CONFIG_DEBUG_VM or so - and eliminate it altogether later on.
> 
> We should also switch around the flag and turn it into CONFIG_BOOTMEM.

Cheers,
Ben.

> Hm?
> 
>         Ingo
> 
> 


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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  4:29                                           ` Benjamin Herrenschmidt
@ 2010-03-24  4:44                                             ` Benjamin Herrenschmidt
  2010-03-24  5:54                                               ` Yinghai Lu
  2010-03-24  9:00                                               ` Ingo Molnar
  0 siblings, 2 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  4:44 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


> I though one possibility would be to have LMB regions become more lists
> than arrays, so that the static storage only needs to cover as much as
> is needed during really early boot (and we could probably still move the
> BSS top point on some archs to dynamically make more ... actually we
> could be smart arses and use LMB to allocate more LMB list heads if we
> are reaching the table limit :-)

Actually what about that:

LMB entries are linked-listed. The array is just storage for those entry
"heads".

The initial static array only needs to be big enough for very very early
platform specific kernel bits and pieces, so it could even be sized by a
Kconfig option. Or it could just use a klimit moving trick to pick up a
page right after the BSS but that may need to be arch specific.

lmb_init() queues all the entries from the initial array in a freelist

lmb_alloc() and lmb_reserve() just pop entries from that freelist to
populate the two main linked lists (memory and reserved).

When something tries to dequeue up the last freelist entry, then under
the hood, LMB uses it instead to allocate a new block of LMB entries
that gets added to the freelist.

We never free blocks of LMB entries.

That way, we can fine tine the static array to be as small as we can
realistically make it be, and we have no boundary limitations on the
amount of entries in either the memory list or the reserved list.

I'm a bit too flat out right now to write code, but if there's no
objection, I might give that a go either later this week or next week,
see if I can replace bootmem on powerpc.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
  2010-03-23 11:16                     ` Ingo Molnar
@ 2010-03-24  4:50                       ` Benjamin Herrenschmidt
  2010-03-24  5:47                         ` Kyle Moffett
  1 sibling, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  4:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: David Miller, Andrew Morton, Linus Torvalds, yinghai, tglx, hpa,
	jbarnes, ebiederm, linux-kernel, linux-arch

On Tue, 2010-03-23 at 12:16 +0100, Ingo Molnar wrote:
> 
> So if you want your architecture to matter to me the rule is very simple: 
> contribute, contribute, contribute, and stop whining. If you dont contribute, 
> frankly you dont really exist to me. On the other hand if you are actively 
> contributing while your architecture only exists on paper, it already starts 
> mattering to me.
> 
> I'm really that simple.

So basically, what you are saying is that, totally regardless of how
much an architecture is actually used in the field, if the architecture
maintainer for it doesn't also do your work and contribute to every
single of your pet projects, or if everybody is like you, every single
other subsystem in the kernel, then that architecture is irrelevant for
technical considerations and choices regarding any design decision made
to the core kernel ?

Sorry Ingo, but that's just arrogant bullshit. So stop trying to win
this useless argument, all you manage to do is anger people and make us
even less willing to actually work with you.

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c  to fw_memmap.c
  2010-03-23 11:16                     ` Ingo Molnar
@ 2010-03-24  5:47                         ` Kyle Moffett
  2010-03-24  5:47                         ` Kyle Moffett
  1 sibling, 0 replies; 111+ messages in thread
From: Kyle Moffett @ 2010-03-24  5:47 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Benjamin Herrenschmidt, David Miller, Andrew Morton,
	Linus Torvalds, yinghai, tglx, hpa, jbarnes, ebiederm,
	linux-kernel, linux-arch

On Tue, Mar 23, 2010 at 07:16, Ingo Molnar <mingo@elte.hu> wrote:
> * Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>> I disagree with that being a relevant argument in the technical discussion
>> on the relative merits of two implementations of a given facility. I also
>> disagree with your numbers, if you talk about deployement, I would be very
>> very surprised if ARM wasn't close to on-par with x86.
>
> As an upstream maintainer i mainly care about upstream kernel contributions.
> These contributions have three main forms:
>
>  - patches i get against latest upstream
>
>  - on-lkml review/analysis that is done on those patches
>
>  - test/bug/regression reports i get against latest upstream (either directly
>    on lkml or via kerneloops.org or bugzilla.kernel.org)
>
> So i weigh the architectures based on that input.
>
> Since you mentioned ARM - here's the Git contribution stats. In the last 5
> years since we have kernel Git history, there's been 1080 commits to
> kernel/sched.c. Amongst those 1080 commits i could find only a _single commit_
> (a minor fix) being related to or contributed by anyone doing ARM development!

Ingo,

I'd like to assume that you _accidentally_ picked the *worst* possible
example file in the entire repository (with the exception of anything
in arch/x86...).  You should keep in mind that basically nobody doing
ARM development cares one hoot about the scheduler as long as it
"basically works"... most such systems could get away with just
SCHED_FIFO and static priorities.  When you're porting the kernel to a
platform with a 250MHz in-order CPU that's going to have a load
average of zero for 99.5% of the time and a load average of 1.0 for
the other 0.5% of the time that's pretty much the *LAST* thing you
care about.

In fact, I would guess that all the excellent work that has been done
with regards to optimized SMP and UP scheduling on much busier systems
with pathological loads has meant that the scheduler is probably one
of the most reliable pieces of code for the ARM developers.  If you
want some excellent examples that go the other way, I suggest looking
at gpiolib for some great examples of code that don't matter for beans
on 99.95% of X86 boxes yet are essential for any kind of real embedded
development.

So while it's possible that you could make a reasonable point about
developer time by looking at GIT commit logs... You should refrain
from making such insulting and sweeping over-generalizations by
looking at single files, particularly ones which are largely
irrelevant or immaterial for the specific subset of developers.

Cheers,
Kyle Moffett

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c
@ 2010-03-24  5:47                         ` Kyle Moffett
  0 siblings, 0 replies; 111+ messages in thread
From: Kyle Moffett @ 2010-03-24  5:47 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Benjamin Herrenschmidt, David Miller, Andrew Morton,
	Linus Torvalds, yinghai, tglx, hpa, jbarnes, ebiederm,
	linux-kernel, linux-arch

On Tue, Mar 23, 2010 at 07:16, Ingo Molnar <mingo@elte.hu> wrote:
> * Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>> I disagree with that being a relevant argument in the technical discussion
>> on the relative merits of two implementations of a given facility. I also
>> disagree with your numbers, if you talk about deployement, I would be very
>> very surprised if ARM wasn't close to on-par with x86.
>
> As an upstream maintainer i mainly care about upstream kernel contributions.
> These contributions have three main forms:
>
>  - patches i get against latest upstream
>
>  - on-lkml review/analysis that is done on those patches
>
>  - test/bug/regression reports i get against latest upstream (either directly
>    on lkml or via kerneloops.org or bugzilla.kernel.org)
>
> So i weigh the architectures based on that input.
>
> Since you mentioned ARM - here's the Git contribution stats. In the last 5
> years since we have kernel Git history, there's been 1080 commits to
> kernel/sched.c. Amongst those 1080 commits i could find only a _single commit_
> (a minor fix) being related to or contributed by anyone doing ARM development!

Ingo,

I'd like to assume that you _accidentally_ picked the *worst* possible
example file in the entire repository (with the exception of anything
in arch/x86...).  You should keep in mind that basically nobody doing
ARM development cares one hoot about the scheduler as long as it
"basically works"... most such systems could get away with just
SCHED_FIFO and static priorities.  When you're porting the kernel to a
platform with a 250MHz in-order CPU that's going to have a load
average of zero for 99.5% of the time and a load average of 1.0 for
the other 0.5% of the time that's pretty much the *LAST* thing you
care about.

In fact, I would guess that all the excellent work that has been done
with regards to optimized SMP and UP scheduling on much busier systems
with pathological loads has meant that the scheduler is probably one
of the most reliable pieces of code for the ARM developers.  If you
want some excellent examples that go the other way, I suggest looking
at gpiolib for some great examples of code that don't matter for beans
on 99.95% of X86 boxes yet are essential for any kind of real embedded
development.

So while it's possible that you could make a reasonable point about
developer time by looking at GIT commit logs... You should refrain
from making such insulting and sweeping over-generalizations by
looking at single files, particularly ones which are largely
irrelevant or immaterial for the specific subset of developers.

Cheers,
Kyle Moffett

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  4:44                                             ` Benjamin Herrenschmidt
@ 2010-03-24  5:54                                               ` Yinghai Lu
  2010-03-24  7:43                                                 ` Benjamin Herrenschmidt
  2010-03-24  9:00                                               ` Ingo Molnar
  1 sibling, 1 reply; 111+ messages in thread
From: Yinghai Lu @ 2010-03-24  5:54 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/23/2010 09:44 PM, Benjamin Herrenschmidt wrote:
> 
>> I though one possibility would be to have LMB regions become more lists
>> than arrays, so that the static storage only needs to cover as much as
>> is needed during really early boot (and we could probably still move the
>> BSS top point on some archs to dynamically make more ... actually we
>> could be smart arses and use LMB to allocate more LMB list heads if we
>> are reaching the table limit :-)
> 
> Actually what about that:
> 
> LMB entries are linked-listed. The array is just storage for those entry
> "heads".
> 
> The initial static array only needs to be big enough for very very early
> platform specific kernel bits and pieces, so it could even be sized by a
> Kconfig option. Or it could just use a klimit moving trick to pick up a
> page right after the BSS but that may need to be arch specific.
> 
> lmb_init() queues all the entries from the initial array in a freelist
> 
> lmb_alloc() and lmb_reserve() just pop entries from that freelist to
> populate the two main linked lists (memory and reserved).
> 
> When something tries to dequeue up the last freelist entry, then under
> the hood, LMB uses it instead to allocate a new block of LMB entries
> that gets added to the freelist.
> 
> We never free blocks of LMB entries.
> 
> That way, we can fine tine the static array to be as small as we can
> realistically make it be, and we have no boundary limitations on the
> amount of entries in either the memory list or the reserved list.
> 
> I'm a bit too flat out right now to write code, but if there's no
> objection, I might give that a go either later this week or next week,
> see if I can replace bootmem on powerpc.
> 

if the array can be doubled and have old one copied to new one. 
then we don't change lmb.c too much.

new early_res.c exend lmb. and another half already works with x86 to replace bootmem.

will check if i can produce one patch to make powerpc to reuse early_res/nobootmem

Thanks

Yinghai

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  4:24                                       ` Benjamin Herrenschmidt
@ 2010-03-24  6:05                                         ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-24  6:05 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/23/2010 09:24 PM, Benjamin Herrenschmidt wrote:
> On Tue, 2010-03-23 at 09:02 +0100, Ingo Molnar wrote:
>>> -u64 find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align);
>>> +u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
>>> +u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
>>> +u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64
>> align);
>>> +void lmb_register_active_regions(int nid, unsigned long start_pfn,
>>> +                                      unsigned long last_pfn);
>>> +u64 lmb_hole_size(u64 start, u64 end);
>>>  u64 get_max_mapped(void);
>>>  #include <linux/range.h>
>>>  int get_free_all_memory_range(struct range **rangep, int nodeid);
>>
>> those new lmb_*() APIs should go into lmb.h.
> 
> And while at it properly documented :-) I wouldn't mind also a
> reasonably clear explanation in the changeset comment as to why
> they are necessary for x86.

new early_res.c will have
find_lmb_area
reserve_early
free_early
also have get_free_all_memory_range to support bootmem replacement.

find_lmb_area: will take goal/limit, so we can find free region with more control.

when we try to check if there is enough slots for new reserve entry.
we need to make sure the new array will not overlap with range below to
entry that going to be reserved.
so we need to goal for find.
otherwise you have to keep trying with lmb_alloc until get one for new array
that will not overlap with new entry.


> 
> To be honest, that's my #1 grief so far with this entire patch set,
> it Yinghai apparent inability to write anything ressembling remotely
> like an explanation. All we get is key words, bullet points and half
> sentences, and I admit have a very very hard time extracting a meaning
> out of anything he's been writing so far.

will spend more time to write more sentences...

thought you guys like to read code instead.

Thanks for you patience.

Yinghai Lu

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  5:54                                               ` Yinghai Lu
@ 2010-03-24  7:43                                                 ` Benjamin Herrenschmidt
  2010-03-24 18:37                                                   ` Yinghai Lu
  0 siblings, 1 reply; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  7:43 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Ingo Molnar, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Tue, 2010-03-23 at 22:54 -0700, Yinghai Lu wrote:
> if the array can be doubled and have old one copied to new one. 
> then we don't change lmb.c too much.
> 
> new early_res.c exend lmb. and another half already works with x86 to
> replace bootmem.
> 
> will check if i can produce one patch to make powerpc to reuse
> early_res/nobootmem

While at it, can you rename early_res to something that doesn't
suck ? :-)

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  4:44                                             ` Benjamin Herrenschmidt
  2010-03-24  5:54                                               ` Yinghai Lu
@ 2010-03-24  9:00                                               ` Ingo Molnar
  2010-03-24  9:32                                                   ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 111+ messages in thread
From: Ingo Molnar @ 2010-03-24  9:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch


* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> 
> > I though one possibility would be to have LMB regions become more lists
> > than arrays, so that the static storage only needs to cover as much as
> > is needed during really early boot (and we could probably still move the
> > BSS top point on some archs to dynamically make more ... actually we
> > could be smart arses and use LMB to allocate more LMB list heads if we
> > are reaching the table limit :-)
> 
> Actually what about that:
> 
> LMB entries are linked-listed. The array is just storage for those entry
> "heads".
> 
> The initial static array only needs to be big enough for very very early
> platform specific kernel bits and pieces, so it could even be sized by a
> Kconfig option. Or it could just use a klimit moving trick to pick up a
> page right after the BSS but that may need to be arch specific.
> 
> lmb_init() queues all the entries from the initial array in a freelist
> 
> lmb_alloc() and lmb_reserve() just pop entries from that freelist to
> populate the two main linked lists (memory and reserved).
> 
> When something tries to dequeue up the last freelist entry, then under
> the hood, LMB uses it instead to allocate a new block of LMB entries
> that gets added to the freelist.
> 
> We never free blocks of LMB entries.
> 
> That way, we can fine tine the static array to be as small as we can
> realistically make it be, and we have no boundary limitations on the
> amount of entries in either the memory list or the reserved list.
> 
> I'm a bit too flat out right now to write code, but if there's no objection, 
> I might give that a go either later this week or next week, see if I can 
> replace bootmem on powerpc.

That would be fantastic! PowerPC and x86 both doing it would give it enough of 
a critical mass to make the removal of bootmem realistic.

Thanks,

	Ingo

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  9:00                                               ` Ingo Molnar
@ 2010-03-24  9:32                                                   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  9:32 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Wed, 2010-03-24 at 10:00 +0100, Ingo Molnar wrote:
> > I'm a bit too flat out right now to write code, but if there's no objection, 
> > I might give that a go either later this week or next week, see if I can 
> > replace bootmem on powerpc.
> 
> That would be fantastic! PowerPC and x86 both doing it would give it enough of 
> a critical mass to make the removal of bootmem realistic.

>From the look of it, I wont' have any bandwidth this week tho ... but
let's keep that as a plan for moving forward and who gets to do it first
wins a free beer at the next conference :-)

Cheers,
Ben.



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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
@ 2010-03-24  9:32                                                   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 111+ messages in thread
From: Benjamin Herrenschmidt @ 2010-03-24  9:32 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Yinghai Lu, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On Wed, 2010-03-24 at 10:00 +0100, Ingo Molnar wrote:
> > I'm a bit too flat out right now to write code, but if there's no objection, 
> > I might give that a go either later this week or next week, see if I can 
> > replace bootmem on powerpc.
> 
> That would be fantastic! PowerPC and x86 both doing it would give it enough of 
> a critical mass to make the removal of bootmem realistic.

From the look of it, I wont' have any bandwidth this week tho ... but
let's keep that as a plan for moving forward and who gets to do it first
wins a free beer at the next conference :-)

Cheers,
Ben.

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

* Re: [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy
  2010-03-24  7:43                                                 ` Benjamin Herrenschmidt
@ 2010-03-24 18:37                                                   ` Yinghai Lu
  0 siblings, 0 replies; 111+ messages in thread
From: Yinghai Lu @ 2010-03-24 18:37 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Ingo Molnar, Thomas Gleixner, David Miller, Andrew Morton,
	Linus Torvalds, hpa, jbarnes, ebiederm, linux-kernel, linux-arch

On 03/24/2010 12:43 AM, Benjamin Herrenschmidt wrote:
> On Tue, 2010-03-23 at 22:54 -0700, Yinghai Lu wrote:
>> if the array can be doubled and have old one copied to new one. 
>> then we don't change lmb.c too much.
>>
>> new early_res.c exend lmb. and another half already works with x86 to
>> replace bootmem.
>>
>> will check if i can produce one patch to make powerpc to reuse
>> early_res/nobootmem
> 
> While at it, can you rename early_res to something that doesn't
> suck ? :-)
> 
ok, 

please check following renaming is ok to you.

the api from linux/early_res.h

#ifndef _LINUX_EARLY_RES_H
#define _LINUX_EARLY_RES_H
#ifdef __KERNEL__

extern void reserve_early(u64 start, u64 end, char *name);
extern void free_early(u64 start, u64 end);
void lmb_reserved_to_bootmem(u64 start, u64 end);

u64 find_early_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
                         u64 size, u64 align);

void add_lmb_memory(u64 start, u64 end);

u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
void lmb_register_active_regions(int nid, unsigned long start_pfn,
                                         unsigned long last_pfn);
u64 lmb_hole_size(u64 start, u64 end);
u64 get_max_mapped(void);
struct range;
int get_free_all_memory_range(struct range **rangep, int nodeid);

#endif /* __KERNEL__ */

#endif /* _LINUX_EARLY_RES_H */

====>

extern void reserve_lmb(u64 start, u64 end, char *name);
extern void free_lmb(u64 start, u64 end);
void lmb_reserved_to_bootmem(u64 start, u64 end);

u64 __find_lmb_area(u64 ei_start, u64 ei_last, u64 start, u64 end,
                         u64 size, u64 align);

void add_lmb_memory(u64 start, u64 end);

u64 find_lmb_area(u64 start, u64 end, u64 size, u64 align);
u64 find_lmb_area_size(u64 start, u64 *sizep, u64 align);
u64 find_lmb_area_node(int nid, u64 start, u64 end, u64 size, u64 align);
void lmb_register_active_regions(int nid, unsigned long start_pfn,
                                         unsigned long last_pfn);
u64 lmb_hole_size(u64 start, u64 end);
u64 get_max_mapped(void);
struct range;
int get_free_all_memory_range(struct range **rangep, int nodeid);

Thanks

Yinghai

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

end of thread, other threads:[~2010-03-24 18:38 UTC | newest]

Thread overview: 111+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-21  7:13 [PATCH 00/20] x86: early_res and irq_desc Yinghai Lu
2010-03-21  7:13 ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 01/20] x86: add find_e820_area_node Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 02/20] x86: add get_centaur_ram_top Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 03/20] x86: make e820 to be static Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 04/20] x86: use wake_system_ram_range instead of e820_any_mapped in agp path Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 05/20] x86: make e820 to be initdata Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-22  2:37   ` Benjamin Herrenschmidt
2010-03-22  2:46     ` Questions about SMP bootup control Zhu, Yijun (NSN - CN/Beijing)
2010-03-22  2:46       ` Zhu, Yijun (NSN - CN/Beijing)
2010-03-22  3:29       ` Andi Kleen
2010-03-22  3:29         ` Andi Kleen
2010-03-22  7:45         ` Zhu, Yijun (NSN - CN/Beijing)
2010-03-22  7:45           ` Zhu, Yijun (NSN - CN/Beijing)
2010-03-22  3:56     ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Yinghai Lu
2010-03-22  4:00       ` David Miller
2010-03-22  4:28         ` Yinghai Lu
2010-03-22  4:33           ` David Miller
2010-03-22  9:28             ` Ingo Molnar
2010-03-22  9:28               ` Ingo Molnar
2010-03-22  9:28               ` Ingo Molnar
2010-03-22 11:30               ` Paul Mackerras
2010-03-22 13:05                 ` Ingo Molnar
2010-03-22 21:04                   ` Benjamin Herrenschmidt
2010-03-22 21:20                     ` Ingo Molnar
2010-03-22 21:52                       ` Benjamin Herrenschmidt
2010-03-22 22:14                         ` Yinghai Lu
2010-03-22 18:18               ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.cy Thomas Gleixner
2010-03-22 19:37                 ` Ingo Molnar
2010-03-22 20:07                   ` Yinghai Lu
2010-03-22 21:08                     ` Benjamin Herrenschmidt
2010-03-22 22:09                     ` Thomas Gleixner
2010-03-22 22:25                       ` Yinghai Lu
2010-03-22 22:53                         ` Thomas Gleixner
2010-03-22 23:41                           ` Yinghai Lu
2010-03-23  0:45                             ` Thomas Gleixner
2010-03-23  1:04                               ` Yinghai Lu
2010-03-23  1:36                                 ` Thomas Gleixner
2010-03-23  6:01                                   ` Yinghai Lu
2010-03-23  8:02                                     ` Ingo Molnar
2010-03-23  9:02                                       ` Yinghai Lu
2010-03-23  9:48                                         ` Ingo Molnar
2010-03-24  4:29                                           ` Benjamin Herrenschmidt
2010-03-24  4:44                                             ` Benjamin Herrenschmidt
2010-03-24  5:54                                               ` Yinghai Lu
2010-03-24  7:43                                                 ` Benjamin Herrenschmidt
2010-03-24 18:37                                                   ` Yinghai Lu
2010-03-24  9:00                                               ` Ingo Molnar
2010-03-24  9:32                                                 ` Benjamin Herrenschmidt
2010-03-24  9:32                                                   ` Benjamin Herrenschmidt
2010-03-24  4:24                                       ` Benjamin Herrenschmidt
2010-03-24  6:05                                         ` Yinghai Lu
2010-03-22 20:47               ` [PATCH 06/20] early_res: seperate common memmap func from e820.c to fw_memmap.c Benjamin Herrenschmidt
2010-03-22 20:57                 ` Ingo Molnar
2010-03-22 21:54                   ` Benjamin Herrenschmidt
2010-03-23  8:53                     ` Geert Uytterhoeven
2010-03-23  8:53                       ` Geert Uytterhoeven
2010-03-23 11:16                     ` Ingo Molnar
2010-03-24  4:50                       ` Benjamin Herrenschmidt
2010-03-24  5:47                       ` Kyle Moffett
2010-03-24  5:47                         ` Kyle Moffett
2010-03-22 21:57                   ` Paul Mackerras
2010-03-22 21:07                 ` Benjamin Herrenschmidt
2010-03-22 21:01               ` Benjamin Herrenschmidt
2010-03-22  5:12       ` Benjamin Herrenschmidt
2010-03-22  6:09         ` Yinghai Lu
2010-03-22  7:05           ` Eric W. Biederman
2010-03-21  7:13 ` [PATCH 07/20] irq: move some interrupt arch_* functions into struct irq_chip Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 08/20] x86: fix out of order of gsi - full Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 09/20] x86: set nr_irqs_gsi only in probe_nr_irqs_gsi Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 10/20] x86: kill smpboot_hooks.h Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 11/20] x86: use vector_desc instead of vector_irq Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 12/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- x86 and core Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 13/20] genericirq: change ack/mask in irq_chip to take irq_desc instead of irq -- other arch Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 14/20] genericirq: add set_irq_desc_chip/data Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 15/20] x86/iommu/dmar: update iommu/inter_remapping to use desc Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 16/20] x86: use num_processors for possible cpus Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 17/20] x86: make 32bit apic flat to physflat switch like 64bit Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 18/20] x86: remove arch_probe_nr_irqs Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 19/20] x86/pci: ioh new version read all at same time Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-22 16:16   ` Jesse Barnes
2010-03-22 16:16     ` Jesse Barnes
2010-03-22 16:16     ` Jesse Barnes
2010-03-22 19:32     ` Yinghai Lu
2010-03-21  7:13 ` [PATCH 20/20] x86/pci: add mmconf range into e820 for when it is from MSR with amd faml0h Yinghai Lu
2010-03-21  7:13   ` Yinghai Lu
2010-03-22  2:35 ` [PATCH 00/20] x86: early_res and irq_desc Benjamin Herrenschmidt
2010-03-22  3:26   ` 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.