Index: linux-irq-work/arch/powerpc/platforms/powermac/bootx_init.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/bootx_init.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/bootx_init.c	2006-07-02 19:45:01.000000000 +1000
@@ -162,6 +162,8 @@
 {
 	u32 val;
 
+	bootx_dt_add_prop("linux,bootx", NULL, 0, mem_end);
+
 	if (bootx_info->kernelParamsOffset) {
 		char *args = (char *)((unsigned long)bootx_info) +
 			bootx_info->kernelParamsOffset;
@@ -211,7 +213,7 @@
 
 	if (!strcmp(namep, "/chosen")) {
 		DBG(" detected /chosen ! adding properties names !\n");
-		bootx_dt_add_string("linux,platform", mem_end);
+		bootx_dt_add_string("linux,bootx", mem_end);
 		bootx_dt_add_string("linux,stdout-path", mem_end);
 		bootx_dt_add_string("linux,initrd-start", mem_end);
 		bootx_dt_add_string("linux,initrd-end", mem_end);
Index: linux-irq-work/arch/powerpc/platforms/powermac/pic.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/pic.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/pic.c	2006-07-02 19:46:06.000000000 +1000
@@ -65,13 +65,11 @@
 
 static DEFINE_SPINLOCK(pmac_pic_lock);
 
-#define GATWICK_IRQ_POOL_SIZE        10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
-
 #define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
 static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 static int pmac_irq_cascade = -1;
+static struct irq_host *pmac_pic_host;
 
 static void __pmac_retrigger(unsigned int irq_nr)
 {
@@ -86,18 +84,16 @@
 	}
 }
 
-static void pmac_mask_and_ack_irq(unsigned int irq_nr)
+static void pmac_mask_and_ack_irq(unsigned int virq)
 {
-        unsigned long bit = 1UL << (irq_nr & 0x1f);
-        int i = irq_nr >> 5;
+	unsigned int src = irq_map[virq].hwirq;
+        unsigned long bit = 1UL << (virq & 0x1f);
+        int i = virq >> 5;
         unsigned long flags;
 
-        if ((unsigned)irq_nr >= max_irqs)
-                return;
-
 	spin_lock_irqsave(&pmac_pic_lock, flags);
-        __clear_bit(irq_nr, ppc_cached_irq_mask);
-        if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts))
+        __clear_bit(src, ppc_cached_irq_mask);
+        if (__test_and_clear_bit(src, ppc_lost_interrupts))
                 atomic_dec(&ppc_n_lost_interrupts);
         out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
         out_le32(&pmac_irq_hw[i]->ack, bit);
@@ -110,17 +106,15 @@
 	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_ack_irq(unsigned int irq_nr)
+static void pmac_ack_irq(unsigned int virq)
 {
-        unsigned long bit = 1UL << (irq_nr & 0x1f);
-        int i = irq_nr >> 5;
+	unsigned int src = irq_map[virq].hwirq;
+        unsigned long bit = 1UL << (src & 0x1f);
+        int i = src >> 5;
         unsigned long flags;
 
-        if ((unsigned)irq_nr >= max_irqs)
-                return;
-
   	spin_lock_irqsave(&pmac_pic_lock, flags);
-	if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts))
+	if (__test_and_clear_bit(src, ppc_lost_interrupts))
                 atomic_dec(&ppc_n_lost_interrupts);
         out_le32(&pmac_irq_hw[i]->ack, bit);
         (void)in_le32(&pmac_irq_hw[i]->ack);
@@ -157,48 +151,51 @@
 /* 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 irq_nr)
+static unsigned int pmac_startup_irq(unsigned int virq)
 {
 	unsigned long flags;
-        unsigned long bit = 1UL << (irq_nr & 0x1f);
-        int i = irq_nr >> 5;
+	unsigned int src = irq_map[virq].hwirq;
+        unsigned long bit = 1UL << (src & 0x1f);
+        int i = src >> 5;
 
   	spin_lock_irqsave(&pmac_pic_lock, flags);
-	if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
+	if ((irq_desc[virq].status & IRQ_LEVEL) == 0)
 		out_le32(&pmac_irq_hw[i]->ack, bit);
-        __set_bit(irq_nr, ppc_cached_irq_mask);
-        __pmac_set_irq_mask(irq_nr, 0);
+        __set_bit(src, ppc_cached_irq_mask);
+        __pmac_set_irq_mask(src, 0);
   	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 
 	return 0;
 }
 
-static void pmac_mask_irq(unsigned int irq_nr)
+static void pmac_mask_irq(unsigned int virq)
 {
 	unsigned long flags;
+	unsigned int src = irq_map[virq].hwirq;
 
   	spin_lock_irqsave(&pmac_pic_lock, flags);
-        __clear_bit(irq_nr, ppc_cached_irq_mask);
-        __pmac_set_irq_mask(irq_nr, 0);
+        __clear_bit(src, ppc_cached_irq_mask);
+        __pmac_set_irq_mask(src, 0);
   	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static void pmac_unmask_irq(unsigned int irq_nr)
+static void pmac_unmask_irq(unsigned int virq)
 {
 	unsigned long flags;
+	unsigned int src = irq_map[virq].hwirq;
 
 	spin_lock_irqsave(&pmac_pic_lock, flags);
-	__set_bit(irq_nr, ppc_cached_irq_mask);
-        __pmac_set_irq_mask(irq_nr, 0);
+	__set_bit(src, ppc_cached_irq_mask);
+        __pmac_set_irq_mask(src, 0);
   	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
-static int pmac_retrigger(unsigned int irq_nr)
+static int pmac_retrigger(unsigned int virq)
 {
 	unsigned long flags;
 
   	spin_lock_irqsave(&pmac_pic_lock, flags);
-	__pmac_retrigger(irq_nr);
+	__pmac_retrigger(irq_map[virq].hwirq);
   	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	return 1;
 }
@@ -238,7 +235,7 @@
 	return rc;
 }
 
-static int pmac_get_irq(struct pt_regs *regs)
+static unsigned int pmac_pic_get_irq(struct pt_regs *regs)
 {
 	int irq;
 	unsigned long bits = 0;
@@ -250,7 +247,7 @@
        	/* IPI's are a hack on the powersurge -- Cort */
        	if ( smp_processor_id() != 0 ) {
 		psurge_smp_message_recv(regs);
-		return -2;	/* ignore, already handled */
+		return NO_IRQ_IGNORE;	/* ignore, already handled */
         }
 #endif /* CONFIG_SMP */
   	spin_lock_irqsave(&pmac_pic_lock, flags);
@@ -266,133 +263,9 @@
 		break;
 	}
   	spin_unlock_irqrestore(&pmac_pic_lock, flags);
-
-	return irq;
-}
-
-/* This routine will fix some missing interrupt values in the device tree
- * on the gatwick mac-io controller used by some PowerBooks
- *
- * Walking of OF nodes could use a bit more fixing up here, but it's not
- * very important as this is all boot time code on static portions of the
- * device-tree.
- *
- * However, the modifications done to "intrs" will have to be removed and
- * replaced with proper updates of the "interrupts" properties or
- * AAPL,interrupts, yet to be decided, once the dynamic parsing is there.
- */
-static void __init pmac_fix_gatwick_interrupts(struct device_node *gw,
-					       int irq_base)
-{
-	struct device_node *node;
-	int count;
-
-	memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
-	count = 0;
-	for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) {
-		/* Fix SCC */
-		if ((strcasecmp(node->name, "escc") == 0) && node->child) {
-			if (node->child->n_intrs < 3) {
-				node->child->intrs = &gatwick_int_pool[count];
-				count += 3;
-			}
-			node->child->n_intrs = 3;
-			node->child->intrs[0].line = 15+irq_base;
-			node->child->intrs[1].line =  4+irq_base;
-			node->child->intrs[2].line =  5+irq_base;
-			printk(KERN_INFO "irq: fixed SCC on gatwick"
-			       " (%d,%d,%d)\n",
-			       node->child->intrs[0].line,
-			       node->child->intrs[1].line,
-			       node->child->intrs[2].line);
-		}
-		/* Fix media-bay & left SWIM */
-		if (strcasecmp(node->name, "media-bay") == 0) {
-			struct device_node* ya_node;
-
-			if (node->n_intrs == 0)
-				node->intrs = &gatwick_int_pool[count++];
-			node->n_intrs = 1;
-			node->intrs[0].line = 29+irq_base;
-			printk(KERN_INFO "irq: fixed media-bay on gatwick"
-			       " (%d)\n", node->intrs[0].line);
-
-			ya_node = node->child;
-			while(ya_node) {
-				if (strcasecmp(ya_node->name, "floppy") == 0) {
-					if (ya_node->n_intrs < 2) {
-						ya_node->intrs = &gatwick_int_pool[count];
-						count += 2;
-					}
-					ya_node->n_intrs = 2;
-					ya_node->intrs[0].line = 19+irq_base;
-					ya_node->intrs[1].line =  1+irq_base;
-					printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
-						ya_node->intrs[0].line, ya_node->intrs[1].line);
-				}
-				if (strcasecmp(ya_node->name, "ata4") == 0) {
-					if (ya_node->n_intrs < 2) {
-						ya_node->intrs = &gatwick_int_pool[count];
-						count += 2;
-					}
-					ya_node->n_intrs = 2;
-					ya_node->intrs[0].line = 14+irq_base;
-					ya_node->intrs[1].line =  3+irq_base;
-					printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
-						ya_node->intrs[0].line, ya_node->intrs[1].line);
-				}
-				ya_node = ya_node->sibling;
-			}
-		}
-	}
-	if (count > 10) {
-		printk("WARNING !! Gatwick interrupt pool overflow\n");
-		printk("  GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
-		printk("              requested = %d\n", count);
-	}
-}
-
-/*
- * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
- * card which includes an ohare chip that acts as a second interrupt
- * controller.  If we find this second ohare, set it up and fix the
- * interrupt value in the device tree for the ethernet chip.
- */
-static void __init enable_second_ohare(struct device_node *np)
-{
-	unsigned char bus, devfn;
-	unsigned short cmd;
-	struct device_node *ether;
-
-	/* This code doesn't strictly belong here, it could be part of
-	 * either the PCI initialisation or the feature code. It's kept
-	 * here for historical reasons.
-	 */
-	if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
-		struct pci_controller* hose =
-			pci_find_hose_for_OF_device(np);
-		if (!hose) {
-			printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
-			return;
-		}
-		early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
-		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
-		cmd &= ~PCI_COMMAND_IO;
-		early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
-	}
-
-	/* Fix interrupt for the modem/ethernet combo controller. The number
-	 * in the device tree (27) is bogus (correct for the ethernet-only
-	 * board but not the combo ethernet/modem board).
-	 * The real interrupt is 28 on the second controller -> 28+32 = 60.
-	 */
-	ether = of_find_node_by_name(NULL, "pci1011,14");
-	if (ether && ether->n_intrs > 0) {
-		ether->intrs[0].line = 60;
-		printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
-		       ether->intrs[0].line);
-	}
-	of_node_put(ether);
+	if (unlikely(irq < 0))
+		return NO_IRQ;
+	return irq_linear_revmap(pmac_pic_host, irq);
 }
 
 #ifdef CONFIG_XMON
@@ -411,6 +284,50 @@
 	.name		= "cascade",
 };
 
+static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+	/* We match all, we don't always have a node anyway */
+	return 1;
+}
+
+static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
+			     irq_hw_number_t hw, unsigned int flags)
+{
+	struct irq_desc *desc = get_irq_desc(virq);
+	int level;
+
+	if (hw >= max_irqs)
+		return -EINVAL;
+
+	/* Mark level interrupts, set delayed disable for edge ones and set
+	 * handlers
+	 */
+	level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f)));
+	if (level)
+		desc->status |= IRQ_LEVEL;
+	else
+		desc->status |= IRQ_DELAYED_DISABLE;
+	set_irq_chip_and_handler(virq, &pmac_pic, level ?
+				 handle_level_irq : handle_edge_irq);
+	return 0;
+}
+
+static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+			       u32 *intspec, unsigned int intsize,
+			       irq_hw_number_t *out_hwirq,
+			       unsigned int *out_flags)
+
+{
+	*out_hwirq = *intspec;
+	return 0;
+}
+
+static struct irq_host_ops pmac_pic_host_ops = {
+	.match = pmac_pic_host_match,
+	.map = pmac_pic_host_map,
+	.xlate = pmac_pic_host_xlate,
+};
+
 static void __init pmac_pic_probe_oldstyle(void)
 {
         int i;
@@ -420,7 +337,7 @@
 	struct resource r;
 
 	/* Set our get_irq function */
-	ppc_md.get_irq = pmac_get_irq;
+	ppc_md.get_irq = pmac_pic_get_irq;
 
 	/*
 	 * Find the interrupt controller type & node
@@ -438,7 +355,6 @@
 		if (slave) {
 			max_irqs = 64;
 			level_mask[1] = OHARE_LEVEL_MASK;
-			enable_second_ohare(slave);
 		}
 	} else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
 		max_irqs = max_real_irqs = 64;
@@ -462,21 +378,18 @@
 			max_irqs = 128;
 			level_mask[2] = HEATHROW_LEVEL_MASK;
 			level_mask[3] = 0;
-			pmac_fix_gatwick_interrupts(slave, max_real_irqs);
 		}
 	}
 	BUG_ON(master == NULL);
 
-	/* Mark level interrupts and set handlers */
-	for (i = 0; i < max_irqs; i++) {
-		int level = !!(level_mask[i >> 5] & (1UL << (i & 0x1f)));
-		if (level)
-			irq_desc[i].status |= IRQ_LEVEL;
-		else
-			irq_desc[i].status |= IRQ_DELAYED_DISABLE;
-		set_irq_chip_and_handler(i, &pmac_pic, level ?
-					 handle_level_irq : handle_edge_irq);
-	}
+	/*
+	 * Allocate an irq host
+	 */
+	pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs,
+				       &pmac_pic_host_ops,
+				       max_irqs);
+	BUG_ON(pmac_pic_host == NULL);
+	irq_set_default_host(pmac_pic_host);
 
 	/* Get addresses of first controller if we have a node for it */
 	BUG_ON(of_address_to_resource(master, 0, &r));
@@ -503,7 +416,7 @@
 			pmac_irq_hw[i++] =
 				(volatile struct pmac_irq_hw __iomem *)
 				(addr + 0x10);
-		pmac_irq_cascade = slave->intrs[0].line;
+		pmac_irq_cascade = irq_of_parse_and_map(slave, 0);
 
 		printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
 		       " cascade: %d\n", slave->full_name,
@@ -516,12 +429,12 @@
 		out_le32(&pmac_irq_hw[i]->enable, 0);
 
 	/* Hookup cascade irq */
-	if (slave)
+	if (slave && pmac_irq_cascade != NO_IRQ)
 		setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
 
 	printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
 #ifdef CONFIG_XMON
-	setup_irq(20, &xmon_action);
+	setup_irq(irq_create_mapping(NULL, 20, 0), &xmon_action);
 #endif
 }
 #endif /* CONFIG_PPC32 */
@@ -544,12 +457,14 @@
 	int nmi_irq;
 
 	pswitch = of_find_node_by_name(NULL, "programmer-switch");
-	if (pswitch && pswitch->n_intrs) {
-		nmi_irq = pswitch->intrs[0].line;
-		mpic_irq_set_priority(nmi_irq, 9);
-		setup_irq(nmi_irq, &xmon_action);
+	if (pswitch) {
+		nmi_irq = irq_of_parse_and_map(pswitch, 0);
+		if (nmi_irq != NO_IRQ) {
+			mpic_irq_set_priority(nmi_irq, 9);
+			setup_irq(nmi_irq, &xmon_action);
+		}
+		of_node_put(pswitch);
 	}
-	of_node_put(pswitch);
 #endif	/* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
 }
 
@@ -654,6 +569,19 @@
 
 void __init pmac_pic_init(void)
 {
+	unsigned int flags = 0;
+
+	/* We configure the OF parsing based on our oldworld vs. newworld
+	 * platform type and wether we were booted by BootX.
+	 */
+#ifdef CONFIG_PPC32
+	if (!pmac_newworld)
+		flags |= OF_IMAP_OLDWORLD_MAC;
+	if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
+		flags |= OF_IMAP_NO_PHANDLE;
+	of_irq_map_init(flags);
+#endif /* CONFIG_PPC_32 */
+
 	/* We first try to detect Apple's new Core99 chipset, since mac-io
 	 * is quite different on those machines and contains an IBM MPIC2.
 	 */
@@ -676,6 +604,7 @@
 
 /* This used to be passed by the PMU driver but that link got
  * broken with the new driver model. We use this tweak for now...
+ * We really want to do things differently though...
  */
 static int pmacpic_find_viaint(void)
 {
@@ -689,7 +618,7 @@
 	np = of_find_node_by_name(NULL, "via-pmu");
 	if (np == NULL)
 		goto not_found;
-	viaint = np->intrs[0].line;
+	viaint = irq_of_parse_and_map(np, 0);;
 #endif /* CONFIG_ADB_PMU */
 
 not_found:
Index: linux-irq-work/arch/powerpc/platforms/powermac/nvram.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/nvram.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/nvram.c	2006-07-02 19:45:01.000000000 +1000
@@ -29,6 +29,8 @@
 #include <asm/machdep.h>
 #include <asm/nvram.h>
 
+#include "pmac.h"
+
 #define DEBUG
 
 #ifdef DEBUG
@@ -80,9 +82,6 @@
 // XXX Turn that into a sem
 static DEFINE_SPINLOCK(nv_lock);
 
-extern int pmac_newworld;
-extern int system_running;
-
 static int (*core99_write_bank)(int bank, u8* datas);
 static int (*core99_erase_bank)(int bank);
 
Index: linux-irq-work/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/pci.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/pci.c	2006-07-02 19:45:01.000000000 +1000
@@ -46,6 +46,8 @@
 static struct pci_controller *u3_agp;
 static struct pci_controller *u4_pcie;
 static struct pci_controller *u3_ht;
+#else
+static int has_second_ohare;
 #endif /* CONFIG_PPC64 */
 
 extern u8 pci_cache_line_size;
@@ -647,6 +649,33 @@
 	early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
 }
 
+static void __init init_second_ohare(void)
+{
+	struct device_node *np = of_find_node_by_name(NULL, "pci106b,7");
+	unsigned char bus, devfn;
+	unsigned short cmd;
+
+	if (np == NULL)
+		return;
+
+	/* This must run before we initialize the PICs since the second
+	 * ohare hosts a PIC that will be accessed there.
+	 */
+	if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
+		struct pci_controller* hose =
+			pci_find_hose_for_OF_device(np);
+		if (!hose) {
+			printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
+			return;
+		}
+		early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
+		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+		cmd &= ~PCI_COMMAND_IO;
+		early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
+	}
+	has_second_ohare = 1;
+}
+
 /*
  * Some Apple desktop machines have a NEC PD720100A USB2 controller
  * on the motherboard. Open Firmware, on these, will disable the
@@ -688,9 +717,6 @@
 			       " EHCI, fixing up...\n");
 			data &= ~1UL;
 			early_write_config_dword(hose, bus, devfn, 0xe4, data);
-			early_write_config_byte(hose, bus,
-						devfn | 2, PCI_INTERRUPT_LINE,
-				nec->intrs[0].line);
 		}
 	}
 }
@@ -962,8 +988,22 @@
 {
 	struct pci_dev* dev = NULL;
 
-	for_each_pci_dev(dev)
+	for_each_pci_dev(dev) {
+		/* Read interrupt from the device-tree */
 		pci_read_irq_line(dev);
+
+		/* Fixup interrupt for the modem/ethernet combo controller.
+		 * on machines with a second ohare chip.
+		 * The number in the device tree (27) is bogus (correct for
+		 * the ethernet-only board but not the combo ethernet/modem
+		 * board). The real interrupt is 28 on the second controller
+		 * -> 28+32 = 60.
+		 */
+		if (has_second_ohare &&
+		    dev->vendor == PCI_VENDOR_ID_DEC &&
+		    dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS)
+			dev->irq = irq_create_mapping(NULL, 60, 0);
+	}
 }
 
 #ifdef CONFIG_PPC64
@@ -1053,6 +1093,7 @@
 
 #else /* CONFIG_PPC64 */
 	init_p2pbridge();
+	init_second_ohare();
 	fixup_nec_usb2();
 
 	/* We are still having some issues with the Xserve G4, enabling
Index: linux-irq-work/arch/powerpc/platforms/powermac/pmac.h
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/pmac.h	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/pmac.h	2006-07-02 19:45:01.000000000 +1000
@@ -12,6 +12,8 @@
 
 struct rtc_time;
 
+extern int pmac_newworld;
+
 extern long pmac_time_init(void);
 extern unsigned long pmac_get_boot_time(void);
 extern void pmac_get_rtc_time(struct rtc_time *);
Index: linux-irq-work/drivers/macintosh/via-pmu.c
===================================================================
--- linux-irq-work.orig/drivers/macintosh/via-pmu.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/drivers/macintosh/via-pmu.c	2006-07-02 19:45:01.000000000 +1000
@@ -64,10 +64,6 @@
 #include <asm/backlight.h>
 #endif
 
-#ifdef CONFIG_PPC32
-#include <asm/open_pic.h>
-#endif
-
 #include "via-pmu-event.h"
 
 /* Some compile options */
Index: linux-irq-work/drivers/macintosh/macio_asic.c
===================================================================
--- linux-irq-work.orig/drivers/macintosh/macio_asic.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/drivers/macintosh/macio_asic.c	2006-07-02 19:45:01.000000000 +1000
@@ -280,49 +280,106 @@
 static int macio_resource_quirks(struct device_node *np, struct resource *res,
 				 int index)
 {
-	if (res->flags & IORESOURCE_MEM) {
-		/* Grand Central has too large resource 0 on some machines */
-		if (index == 0 && !strcmp(np->name, "gc"))
-			res->end = res->start + 0x1ffff;
-
-		/* Airport has bogus resource 2 */
-		if (index >= 2 && !strcmp(np->name, "radio"))
-			return 1;
+	/* Only quirks for memory resources for now */
+	if ((res->flags & IORESOURCE_MEM) == 0)
+		return 0;
+
+	/* Grand Central has too large resource 0 on some machines */
+	if (index == 0 && !strcmp(np->name, "gc"))
+		res->end = res->start + 0x1ffff;
+
+	/* Airport has bogus resource 2 */
+	if (index >= 2 && !strcmp(np->name, "radio"))
+		return 1;
 
 #ifndef CONFIG_PPC64
-		/* DBDMAs may have bogus sizes */
-		if ((res->start & 0x0001f000) == 0x00008000)
-			res->end = res->start + 0xff;
+	/* DBDMAs may have bogus sizes */
+	if ((res->start & 0x0001f000) == 0x00008000)
+		res->end = res->start + 0xff;
 #endif /* CONFIG_PPC64 */
 
-		/* ESCC parent eats child resources. We could have added a
-		 * level of hierarchy, but I don't really feel the need
-		 * for it
-		 */
-		if (!strcmp(np->name, "escc"))
-			return 1;
+	/* ESCC parent eats child resources. We could have added a
+	 * level of hierarchy, but I don't really feel the need
+	 * for it
+	 */
+	if (!strcmp(np->name, "escc"))
+		return 1;
 
-		/* ESCC has bogus resources >= 3 */
-		if (index >= 3 && !(strcmp(np->name, "ch-a") &&
-				    strcmp(np->name, "ch-b")))
-			return 1;
-
-		/* Media bay has too many resources, keep only first one */
-		if (index > 0 && !strcmp(np->name, "media-bay"))
-			return 1;
-
-		/* Some older IDE resources have bogus sizes */
-		if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
-		      strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
-			if (index == 0 && (res->end - res->start) > 0xfff)
-				res->end = res->start + 0xfff;
-			if (index == 1 && (res->end - res->start) > 0xff)
-				res->end = res->start + 0xff;
-		}
+	/* ESCC has bogus resources >= 3 */
+	if (index >= 3 && !(strcmp(np->name, "ch-a") &&
+			    strcmp(np->name, "ch-b")))
+		return 1;
+
+	/* Media bay has too many resources, keep only first one */
+	if (index > 0 && !strcmp(np->name, "media-bay"))
+		return 1;
+
+	/* Some older IDE resources have bogus sizes */
+	if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
+	      strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
+		if (index == 0 && (res->end - res->start) > 0xfff)
+			res->end = res->start + 0xfff;
+		if (index == 1 && (res->end - res->start) > 0xff)
+			res->end = res->start + 0xff;
 	}
 	return 0;
 }
 
+static void macio_create_fixup_irq(struct macio_dev *dev, int index,
+				   unsigned int line)
+{
+	unsigned int irq;
+
+	irq = irq_create_mapping(NULL, line, 0);
+	if (irq != NO_IRQ) {
+		dev->interrupt[index].start = irq;
+		dev->interrupt[index].flags = IORESOURCE_IRQ;
+		dev->interrupt[index].name = dev->ofdev.dev.bus_id;
+	}
+	if (dev->n_interrupts <= index)
+		dev->n_interrupts = index + 1;
+}
+
+static void macio_add_missing_resources(struct macio_dev *dev)
+{
+	struct device_node *np = dev->ofdev.node;
+	unsigned int irq_base;
+
+	/* Gatwick has some missing interrupts on child nodes */
+	if (dev->bus->chip->type != macio_gatwick)
+		return;
+	
+	/* irq_base is always 64 on gatwick. I have no cleaner way to get
+	 * that value from here at this point
+	 */
+	irq_base = 64;
+
+	/* Fix SCC */		
+	if (strcmp(np->name, "ch-a") == 0) {
+		macio_create_fixup_irq(dev, 0, 15 + irq_base);
+		macio_create_fixup_irq(dev, 1,  4 + irq_base);
+		macio_create_fixup_irq(dev, 2,  5 + irq_base);
+		printk(KERN_INFO "macio: fixed SCC irqs on gatwick\n");
+	}
+	
+	/* Fix media-bay */
+	if (strcmp(np->name, "media-bay") == 0) {
+		macio_create_fixup_irq(dev, 0, 29 + irq_base);
+		printk(KERN_INFO "macio: fixed media-bay irq on gatwick\n");
+	}
+
+	/* Fix left media bay childs */
+	if (dev->media_bay != NULL && strcmp(np->name, "floppy") == 0) {
+		macio_create_fixup_irq(dev, 0, 19 + irq_base);
+		macio_create_fixup_irq(dev, 1,  1 + irq_base);
+		printk(KERN_INFO "macio: fixed left floppy irqs\n");
+	}
+	if (dev->media_bay != NULL && strcasecmp(np->name, "ata4") == 0) {
+		macio_create_fixup_irq(dev, 0, 14 + irq_base);
+		macio_create_fixup_irq(dev, 0,  3 + irq_base);
+		printk(KERN_INFO "macio: fixed left ide irqs\n");
+	}	
+}
 
 static void macio_setup_interrupts(struct macio_dev *dev)
 {
@@ -441,6 +498,7 @@
 	/* Setup interrupts & resources */
 	macio_setup_interrupts(dev);
 	macio_setup_resources(dev, parent_res);
+	macio_add_missing_resources(dev);
 
 	/* Register with core */
 	if (of_device_register(&dev->ofdev) != 0) {
Index: linux-irq-work/drivers/macintosh/via-cuda.c
===================================================================
--- linux-irq-work.orig/drivers/macintosh/via-cuda.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/drivers/macintosh/via-cuda.c	2006-07-02 19:45:01.000000000 +1000
@@ -34,13 +34,6 @@
 static volatile unsigned char __iomem *via;
 static DEFINE_SPINLOCK(cuda_lock);
 
-#ifdef CONFIG_MAC
-#define CUDA_IRQ IRQ_MAC_ADB
-#define eieio()
-#else
-#define CUDA_IRQ vias->intrs[0].line
-#endif
-
 /* VIA registers - spaced 0x200 bytes apart */
 #define RS		0x200		/* skip between registers */
 #define B		0		/* B-side data */
@@ -189,11 +182,24 @@
 
 static int __init via_cuda_start(void)
 {
+    unsigned int irq;
+
     if (via == NULL)
 	return -ENODEV;
 
-    if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
-	printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);
+#ifdef CONFIG_MAC
+    irq = IRQ_MAC_ADB;
+#else /* CONFIG_MAC */
+    irq = irq_of_parse_and_map(vias, 0);
+    if (irq == NO_IRQ) {
+	printk(KERN_ERR "via-cuda: can't map interrupts for %s\n",
+	       vias->full_name);
+	return -ENODEV;
+    }
+#endif /* CONFIG_MAP */
+
+    if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
+	printk(KERN_ERR "via-cuda: can't request irq %d\n", irq);
 	return -EAGAIN;
     }
 
Index: linux-irq-work/drivers/net/mace.c
===================================================================
--- linux-irq-work.orig/drivers/net/mace.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/drivers/net/mace.c	2006-07-02 19:45:01.000000000 +1000
@@ -242,12 +242,12 @@
 	}
 	rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev);
 	if (rc) {
-		printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line);
+		printk(KERN_ERR "MACE: can't get irq %d\n", mp->tx_dma_intr);
 		goto err_free_irq;
 	}
 	rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev);
 	if (rc) {
-		printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line);
+		printk(KERN_ERR "MACE: can't get irq %d\n", mp->rx_dma_intr);
 		goto err_free_tx_irq;
 	}
 
Index: linux-irq-work/drivers/serial/pmac_zilog.c
===================================================================
--- linux-irq-work.orig/drivers/serial/pmac_zilog.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/drivers/serial/pmac_zilog.c	2006-07-02 19:45:01.000000000 +1000
@@ -1443,8 +1443,8 @@
 			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
 			goto no_dma;
 		}
-		uap->tx_dma_irq = np->intrs[1].line;
-		uap->rx_dma_irq = np->intrs[2].line;
+		uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
+		uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
 	}
 no_dma:
 
@@ -1491,7 +1491,7 @@
 	 * Init remaining bits of "port" structure
 	 */
 	uap->port.iotype = UPIO_MEM;
-	uap->port.irq = np->intrs[0].line;
+	uap->port.irq = irq_of_parse_and_map(np, 0);
 	uap->port.uartclk = ZS_CLOCK;
 	uap->port.fifosize = 1;
 	uap->port.ops = &pmz_pops;
Index: linux-irq-work/sound/oss/dmasound/dmasound_awacs.c
===================================================================
--- linux-irq-work.orig/sound/oss/dmasound/dmasound_awacs.c	2006-07-02 19:44:16.000000000 +1000
+++ linux-irq-work/sound/oss/dmasound/dmasound_awacs.c	2006-07-02 19:45:01.000000000 +1000
@@ -374,10 +374,7 @@
 		*gpio_pol = *pp;
 	else
 		*gpio_pol = 1;
-	if (np->n_intrs > 0)
-		return np->intrs[0].line;
-	
-	return 0;
+	return irq_of_parse_and_map(np, 0);
 }
 
 static inline void
@@ -2864,14 +2861,13 @@
 	 * other info if necessary (early AWACS we want to read chip ids)
 	 */
 
-	if (of_get_address(io, 2, NULL, NULL) == NULL || io->n_intrs < 3) {
+	if (of_get_address(io, 2, NULL, NULL) == NULL) {
 		/* OK - maybe we need to use the 'awacs' node (on earlier
 		 * machines).
 		 */
 		if (awacs_node) {
 			io = awacs_node ;
-			if (of_get_address(io, 2, NULL, NULL) == NULL ||
-			    io->n_intrs < 3) {
+			if (of_get_address(io, 2, NULL, NULL) == NULL) {
 				printk("dmasound_pmac: can't use %s\n",
 				       io->full_name);
 				return -ENODEV;
@@ -2940,9 +2936,9 @@
 	if (awacs_revision == AWACS_SCREAMER && awacs)
 		awacs_recalibrate();
 
-	awacs_irq = io->intrs[0].line;
-	awacs_tx_irq = io->intrs[1].line;
-	awacs_rx_irq = io->intrs[2].line;
+	awacs_irq = irq_of_parse_and_map(io, 0);
+	awacs_tx_irq = irq_of_parse_and_map(io, 1);
+	awacs_rx_irq = irq_of_parse_and_map(io, 2);
 
 	/* Hack for legacy crap that will be killed someday */
 	awacs_node = io;
