diff -rupN linux-4.3/arch/powerpc/kernel/head_64.S linux-4.3-nemo/arch/powerpc/kernel/head_64.S
--- linux-4.3/arch/powerpc/kernel/head_64.S	2015-09-04 08:22:42.647466797 +0200
+++ linux-4.3-nemo/arch/powerpc/kernel/head_64.S	2015-09-04 08:15:19.996156877 +0200
@@ -70,6 +70,13 @@ _GLOBAL(__start)
 	/* NOP this out unconditionally */
 BEGIN_FTR_SECTION
 	FIXUP_ENDIAN
+/* Hack for PWRficient platforms: Due to CFE(?) bug, the 64-bit
+ * word at 0x8 needs to be set to 0. Patch it up here once we're
+ * done executing it (we can be lazy and avoid invalidating
+ * icache)
+ */
+li     r0,0
+std    0,8(0)
 	b	__start_initialization_multiplatform
 END_FTR_SECTION(0, 1)
 
diff -rupN linux-4.3/arch/powerpc/kernel/pci-common.c linux-4.3-nemo/arch/powerpc/kernel/pci-common.c
--- linux-4.3/arch/powerpc/kernel/pci-common.c	2015-09-04 08:22:42.655466797 +0200
+++ linux-4.3-nemo/arch/powerpc/kernel/pci-common.c	2015-09-04 08:15:20.000158864 +0200
@@ -722,6 +722,19 @@ void pci_process_bridge_OF_ranges(struct
 				isa_io_base =
 					(unsigned long)hose->io_base_virt;
 #endif /* CONFIG_PPC32 */
+
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+                       /* Workaround for lack of device tree. New for kernel 3.17: range.cpu_addr instead of cpu_addr and range.size instead of size Ch. Zigotzky */
+                       if (primary) {
+                               __ioremap_at(range.cpu_addr, (void *)ISA_IO_BASE,
+                               range.size, _PAGE_NO_CACHE|_PAGE_GUARDED);
+                       hose->io_base_virt = (void *)_IO_BASE;
+		       /* _IO_BASE needs unsigned long long for the kernel 3.17 Ch. Zigotzky */
+                       printk("Initialised io_base_virt 0x%lx _IO_BASE 0x%llx\n", (unsigned long)hose->io_base_virt, (unsigned long long)_IO_BASE);
+                    }
+#endif
+
 			/* pci_io_size and io_base_phys always represent IO
 			 * space starting at 0 so we factor in pci_addr
 			 */
@@ -1175,6 +1188,7 @@ static void pcibios_allocate_bus_resourc
 				&ioport_resource : &iomem_resource;
 		else {
 			pr = pci_find_parent_resource(bus->self, res);
+#ifndef CONFIG_PPC_PASEMI_SB600
 			if (pr == res) {
 				/* this happens when the generic PCI
 				 * code (wrongly) decides that this
@@ -1182,6 +1196,7 @@ static void pcibios_allocate_bus_resourc
 				 */
 				continue;
 			}
+#endif
 		}
 
 		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %pR, parent %p (%s)\n",
@@ -1600,8 +1615,9 @@ void pcibios_scan_phb(struct pci_control
 	pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
 
 	/* Get some IO space for the new PHB */
+#ifndef CONFIG_PPC_PASEMI_SB600
 	pcibios_setup_phb_io_space(hose);
-
+#endif
 	/* Wire up PHB bus resources */
 	pcibios_setup_phb_resources(hose, &resources);
 
diff -rupN linux-4.3/arch/powerpc/kernel/setup-common.c linux-4.3-nemo/arch/powerpc/kernel/setup-common.c
--- linux-4.3/arch/powerpc/kernel/setup-common.c	2015-09-04 08:22:42.587466797 +0200
+++ linux-4.3-nemo/arch/powerpc/kernel/setup-common.c	2015-09-04 08:15:20.000158864 +0200
@@ -76,7 +76,15 @@ EXPORT_SYMBOL(ppc_md);
 struct machdep_calls *machine_id;
 EXPORT_SYMBOL(machine_id);
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+/* FIXME!!
+ * Current PASemi code does not correctly update the value of boot_cpuid
+ * As a temporary fix we use the default 0, which is known to work
+ */
+int boot_cpuid = 0;
+#else
 int boot_cpuid = -1;
+#endif
 EXPORT_SYMBOL_GPL(boot_cpuid);
 
 unsigned long klimit = (unsigned long) _end;
diff -rupN linux-4.3/arch/powerpc/platforms/pasemi/iommu.c linux-4.3-nemo/arch/powerpc/platforms/pasemi/iommu.c
--- linux-4.3/arch/powerpc/platforms/pasemi/iommu.c	2015-09-04 08:22:44.587466777 +0200
+++ linux-4.3-nemo/arch/powerpc/platforms/pasemi/iommu.c	2015-09-04 08:15:20.004160871 +0200
@@ -1,3 +1,9 @@
+/* This is a modified copy of
+* usr/src/linux-2.6.39.4/arch/powerpc/platforms/pasemi/iommu.c
+* The mod is on line 150
+* By Len Karpowicz <twotat2z@embarqmail.com
+*/
+
 /*
  * Copyright (C) 2005-2008, PA Semi, Inc
  *
@@ -147,8 +153,11 @@ static void iommu_table_iobmap_setup(voi
 	iommu_table_iobmap.it_page_shift = IOBMAP_PAGE_SHIFT;
 
 	/* it_size is in number of entries */
-	iommu_table_iobmap.it_size =
-		0x80000000 >> iommu_table_iobmap.it_page_shift;
+
+/* Note: changed 0x80000000 to 0x7FFFFFFF for SBLive! SB0220 */
+/* out of range problem on A-EON AmigaOne X1000 */
+       iommu_table_iobmap.it_size = 0x7FFFFFFF >> IOBMAP_PAGE_SHIFT;
+
 
 	/* Initialize the common IOMMU code */
 	iommu_table_iobmap.it_base = (unsigned long)iob_l2_base;
diff -rupN linux-4.3/arch/powerpc/platforms/pasemi/Kconfig linux-4.3-nemo/arch/powerpc/platforms/pasemi/Kconfig
--- linux-4.3/arch/powerpc/platforms/pasemi/Kconfig	2015-09-04 08:22:44.599466777 +0200
+++ linux-4.3-nemo/arch/powerpc/platforms/pasemi/Kconfig	2015-09-04 08:15:20.004160871 +0200
@@ -14,6 +14,13 @@ config PPC_PASEMI
 menu "PA Semi PWRficient options"
 	depends on PPC_PASEMI
 
+config PPC_PASEMI_SB600
+       bool "Nemo SB600 South Bridge Support"
+       depends on PPC_PASEMI
+       select PPC_I8259
+       help
+       Workarounds for the SB600 South Bridge.
+
 config PPC_PASEMI_IOMMU
 	bool "PA Semi IOMMU support"
 	depends on PPC_PASEMI
diff -rupN linux-4.3/arch/powerpc/platforms/pasemi/pci.c linux-4.3-nemo/arch/powerpc/platforms/pasemi/pci.c
--- linux-4.3/arch/powerpc/platforms/pasemi/pci.c	2015-09-04 08:22:44.599466777 +0200
+++ linux-4.3-nemo/arch/powerpc/platforms/pasemi/pci.c	2015-09-04 08:15:20.004160871 +0200
@@ -108,6 +108,69 @@ static int workaround_5945(struct pci_bu
 	return 1;
 }
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+static int sb600_bus = 5;
+static void __iomem *iob_mapbase = NULL;
+
+static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
+                             int offset, int len, u32 *val);
+
+static void sb600_set_flag(int bus)
+{
+    struct resource res;
+    struct device_node *dn;
+       struct pci_bus *busp;
+       u32 val;
+       int err;
+
+       if (sb600_bus == -1)
+       {
+               busp = pci_find_bus(0, 0);
+               pa_pxp_read_config(busp, PCI_DEVFN(17,0), PCI_SECONDARY_BUS, 1, &val);
+
+               sb600_bus = val;
+
+               printk(KERN_CRIT "NEMO SB600 on bus %d.\n",sb600_bus);
+       }
+
+       if (iob_mapbase == NULL)
+       {
+        dn = of_find_compatible_node(NULL, "io-bridge", "pasemi,1682m-iob");
+        if (!dn)
+        {
+               printk(KERN_CRIT "NEMO SB600 missing iob node\n");
+                       return;
+               }
+
+               err = of_address_to_resource(dn, 0, &res);
+        of_node_put(dn);
+
+               if (err)
+               {
+               printk(KERN_CRIT "NEMO SB600 missing resource\n");
+                       return;
+               }
+
+               printk(KERN_CRIT "NEMO SB600 IOB base %08lx\n",res.start);
+
+               iob_mapbase = ioremap(res.start + 0x100, 0x94);
+       }
+
+       if (iob_mapbase != NULL)
+       {
+               if (bus == sb600_bus)
+               {
+                       out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) | 0x800);
+               }
+               else
+               {
+                       out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) & ~0x800);
+               }
+       }
+}
+#endif
+
+
 static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
 			      int offset, int len, u32 *val)
 {
@@ -126,6 +189,10 @@ static int pa_pxp_read_config(struct pci
 
 	addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+       sb600_set_flag(bus->number);
+#endif
+
 	/*
 	 * Note: the caller has already checked that offset is
 	 * suitably aligned and that len is 1, 2 or 4.
diff -rupN linux-4.3/arch/powerpc/platforms/pasemi/setup.c linux-4.3-nemo/arch/powerpc/platforms/pasemi/setup.c
--- linux-4.3/arch/powerpc/platforms/pasemi/setup.c	2015-09-04 08:22:44.583466777 +0200
+++ linux-4.3-nemo/arch/powerpc/platforms/pasemi/setup.c	2015-09-04 08:15:20.076196906 +0200
@@ -34,6 +34,7 @@
 #include <asm/prom.h>
 #include <asm/iommu.h>
 #include <asm/machdep.h>
+#include <asm/i8259.h>
 #include <asm/mpic.h>
 #include <asm/smp.h>
 #include <asm/time.h>
@@ -72,6 +73,17 @@ static void pas_restart(char *cmd)
 		out_le32(reset_reg, 0x6000000);
 }
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+void pas_shutdown(void)
+{
+       /* (added by DStevens 19/06/13)
+          Set the PLD bit that makes the SB600 think the power button is being pressed */
+       void __iomem *pld_map = ioremap(0xf5000000,4096);
+       while (1)
+               out_8(pld_map+7,0x01);
+}
+#endif
+
 #ifdef CONFIG_SMP
 static arch_spinlock_t timebase_lock;
 static unsigned long timebase;
@@ -183,6 +195,55 @@ static int __init pas_setup_mce_regs(voi
 }
 machine_device_initcall(pasemi, pas_setup_mce_regs);
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+static unsigned sb600_irq_to_vector(int irq)
+{
+       switch(irq) {
+       case 3: return 216;
+       case 4: return 217;
+       case 5: return 218;
+       case 6: return 219;
+       case 7: return 220;
+       case 8: return 222;
+       case 9: return 212;
+       case 10: return 213;
+       case 11: return 214;
+       case 12: return 215;
+       case 14: return 221;
+       default: return 0;
+       }
+}
+
+static void sb600_8259_cascade(unsigned int irq, struct irq_data *desc)
+{
+       unsigned int cascade_irq = i8259_irq();
+       unsigned vector = sb600_irq_to_vector(cascade_irq);
+       if (vector > 0)
+               generic_handle_irq(vector);
+       outb(0x20, 0xA0);       /* Non-specific EOI */
+       outb(0x20, 0x20);       /* Non-specific EOI to cascade */
+       desc->chip->irq_eoi(desc);
+}
+extern void i8259_unmask_irq(struct irq_data *d);
+
+__init void sb600_8259_init(void)
+{
+       int gpio_virq;
+
+       // Connect legacy i8259 controller in SB600
+       printk("Init i8259\n");
+       i8259_init(NULL, 0);
+
+       gpio_virq = irq_create_mapping(NULL, 3);
+       irq_set_irq_type(gpio_virq, IRQ_TYPE_LEVEL_HIGH);
+       irq_set_chained_handler(gpio_virq, sb600_8259_cascade);
+       mpic_unmask_irq(irq_get_irq_data(gpio_virq));
+
+       // Initial mapping for RTC
+       irq_create_mapping(NULL, 222);
+}
+#endif
+
 static __init void pas_init_IRQ(void)
 {
 	struct device_node *np;
@@ -246,6 +307,12 @@ static __init void pas_init_IRQ(void)
 
 	of_node_put(mpic_node);
 	of_node_put(root);
+
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+       sb600_8259_init();
+#endif
+
 }
 
 static void __init pas_progress(char *s, unsigned short hex)
@@ -403,12 +470,39 @@ static const struct of_device_id pasemi_
 	{},
 };
 
-static int __init pasemi_publish_devices(void)
-{
-	pasemi_pcmcia_init();
+#ifdef CONFIG_PPC_PASEMI_SB600
+
+/*
+ This should come from OF tree. See sysdev/rtc_cmos_setup for details. Need to get i8259 supported correctly first, so that
+ as the standard support hard-codes IRQ 8.
+ */
+
+
+static struct resource rtc_resource[] = {{
+       .name = "rtc",
+       .start = 0x70,
+       .end = 0x71,
+       .flags = IORESOURCE_IO,
+}, {
+       .name = "rtc",
+       .start = 222,
+       .end = 222,
+       .flags = IORESOURCE_IRQ,
+}};
+
+#endif
+
+
+ static int __init pasemi_publish_devices(void)
+ {
+        pasemi_pcmcia_init();
+
+        /* Publish OF platform devices for SDC and other non-PCI devices */
+        of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
 
-	/* Publish OF platform devices for SDC and other non-PCI devices */
-	of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
+#ifdef CONFIG_PPC_PASEMI_SB600
+       platform_device_register_simple("rtc_cmos", -1, rtc_resource, 2);
+#endif
 
 	return 0;
 }
@@ -430,9 +524,20 @@ static int __init pas_probe(void)
 
 	alloc_iobmap_l2();
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+       pm_power_off              = pas_shutdown;         // Varisys provided a way to turn us off
+#endif
 	return 1;
 }
 
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+static int sb600_pci_probe_mode(struct pci_bus *bus)
+{
+       return PCI_PROBE_DEVTREE;
+}
+#endif
+
 define_machine(pasemi) {
 	.name			= "PA Semi PWRficient",
 	.probe			= pas_probe,
@@ -445,4 +550,7 @@ define_machine(pasemi) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= pas_progress,
 	.machine_check_exception = pas_machine_check_handler,
+#if 0 // def CONFIG_PPC_PASEMI_SB600
+       .pci_probe_mode = sb600_pci_probe_mode,
+#endif
 };
diff -rupN linux-4.3/arch/powerpc/sysdev/i8259.c linux-4.3-nemo/arch/powerpc/sysdev/i8259.c
--- linux-4.3/arch/powerpc/sysdev/i8259.c	2015-09-04 08:22:42.931466794 +0200
+++ linux-4.3-nemo/arch/powerpc/sysdev/i8259.c	2015-09-04 08:15:20.080198902 +0200
@@ -103,11 +103,11 @@ static void i8259_set_irq_mask(int irq_n
 	outb(cached_21,0x21);
 }
 
-static void i8259_mask_irq(struct irq_data *d)
+void i8259_mask_irq(struct irq_data *d)
 {
 	unsigned long flags;
 
-	pr_debug("i8259_mask_irq(%d)\n", d->irq);
+	printk("i8259_mask_irq(%d)\n", d->irq);
 
 	raw_spin_lock_irqsave(&i8259_lock, flags);
 	if (d->irq < 8)
@@ -118,11 +118,11 @@ static void i8259_mask_irq(struct irq_da
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
-static void i8259_unmask_irq(struct irq_data *d)
+void i8259_unmask_irq(struct irq_data *d)
 {
 	unsigned long flags;
 
-	pr_debug("i8259_unmask_irq(%d)\n", d->irq);
+	printk("i8259_unmask_irq(%d)\n", d->irq);
 
 	raw_spin_lock_irqsave(&i8259_lock, flags);
 	if (d->irq < 8)
@@ -230,6 +230,8 @@ void i8259_init(struct device_node *node
 	/* initialize the controller */
 	raw_spin_lock_irqsave(&i8259_lock, flags);
 
+	printk("About to write to i8259\n");
+
 	/* Mask all first */
 	outb(0xff, 0xA1);
 	outb(0xff, 0x21);
@@ -260,8 +262,12 @@ void i8259_init(struct device_node *node
 	outb(cached_A1, 0xA1);
 	outb(cached_21, 0x21);
 
+	printk("Done write to i8259\n");
+
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
+#ifndef CONFIG_PPC_PASEMI_SB600
+
 	/* create a legacy host */
 	i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
 	if (i8259_host == NULL) {
@@ -269,6 +275,8 @@ void i8259_init(struct device_node *node
 		return;
 	}
 
+#endif
+
 	/* reserve our resources */
 	/* XXX should we continue doing that ? it seems to cause problems
 	 * with further requesting of PCI IO resources for that range...
diff -rupN linux-4.3/arch/powerpc/sysdev/mpic.c linux-4.3-nemo/arch/powerpc/sysdev/mpic.c
--- linux-4.3/arch/powerpc/sysdev/mpic.c	2015-09-04 08:22:42.935466794 +0200
+++ linux-4.3-nemo/arch/powerpc/sysdev/mpic.c	2015-09-04 08:15:20.088202895 +0200
@@ -661,6 +661,56 @@ static inline void mpic_eoi(struct mpic
  * Linux descriptor level callbacks
  */
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+
+static int sb600_vector_to_irq(unsigned vector)
+{
+       switch(vector) {
+       case 212: return 9;
+       case 213: return 10;
+       case 214: return 11;
+       case 215: return 12;
+       case 216: return 3;
+       case 217: return 4;
+       case 218: return 5;
+       case 219: return 6;
+       case 220: return 7;
+       case 221: return 14;
+       case 222: return 8;
+       default: return -1;
+       }
+}
+
+extern void i8259_mask_irq(struct irq_data *d);
+extern void i8259_unmask_irq(struct irq_data *d);
+
+int sb600_unmask_irq(unsigned irq)
+{
+       int vector = sb600_vector_to_irq(irq);
+       if (vector >= 0) {
+               i8259_unmask_irq(irq_get_irq_data(vector));
+               return 1;
+       } else
+               return 0;
+}
+
+int sb600_mask_irq(unsigned irq)
+{
+       int vector = sb600_vector_to_irq(irq);
+       if (vector >= 0) {
+               i8259_mask_irq(irq_get_irq_data(vector));
+               return 1;
+       } else
+               return 0;
+}
+
+int sb600_end_irq(unsigned irq)
+{
+       int vector = sb600_vector_to_irq(irq);
+       return (vector >= 0);
+}
+
+#endif
 
 void mpic_unmask_irq(struct irq_data *d)
 {
@@ -668,7 +718,12 @@ void mpic_unmask_irq(struct irq_data *d)
 	struct mpic *mpic = mpic_from_irq_data(d);
 	unsigned int src = irqd_to_hwirq(d);
 
-	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
+#ifdef CONFIG_PPC_PASEMI_SB600
+       if (sb600_unmask_irq(src))
+               return;
+#endif
+
+       DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
 	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
 		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
@@ -689,7 +744,12 @@ void mpic_mask_irq(struct irq_data *d)
 	struct mpic *mpic = mpic_from_irq_data(d);
 	unsigned int src = irqd_to_hwirq(d);
 
-	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
+#ifdef CONFIG_PPC_PASEMI_SB600
+       if (sb600_mask_irq(src))
+               return;
+#endif
+
+       DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
 	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
 		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
@@ -709,6 +769,14 @@ void mpic_end_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+       unsigned int src = irqd_to_hwirq(d);
+
+       if (src >= 212 && src <= 222)
+               return;
+#endif
+
+
 #ifdef DEBUG_IRQ
 	DBG("%s: end_irq: %d\n", mpic->name, d->irq);
 #endif
diff -rupN linux-4.3/drivers/ata/libata-sff.c linux-4.3-nemo/drivers/ata/libata-sff.c
--- linux-4.3/drivers/ata/libata-sff.c	2015-09-04 08:22:16.587467062 +0200
+++ linux-4.3-nemo/drivers/ata/libata-sff.c	2015-09-04 08:15:20.172244897 +0200
@@ -2438,9 +2438,9 @@ int ata_pci_sff_activate_host(struct ata
 	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		u8 tmp8, mask;
 
-		/* TODO: What if one channel is in native mode ... */
+		/* Don't look at dummy ports in the mask */	
 		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
-		mask = (1 << 2) | (1 << 0);
+		mask = (! ata_port_is_dummy(host->ports[1]) << 2) | (! ata_port_is_dummy(host->ports[0]) << 0);	
 		if ((tmp8 & mask) != mask)
 			legacy_mode = 1;
 	}
diff -rupN linux-4.3/drivers/ata/pata_atiixp.c linux-4.3-nemo/drivers/ata/pata_atiixp.c
--- linux-4.3/drivers/ata/pata_atiixp.c	2015-09-04 08:22:16.703467060 +0200
+++ linux-4.3-nemo/drivers/ata/pata_atiixp.c	2015-09-04 08:15:20.256286896 +0200
@@ -278,6 +278,11 @@ static int atiixp_init_one(struct pci_de
 	};
 	const struct ata_port_info *ppi[] = { &info, &info };
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+       // Second port not wired on SB600, and config bit cannot be set by BIOS
+       ppi[1] = &ata_dummy_port_info;
+#endif
+
 	return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL,
 				      ATA_HOST_PARALLEL_SCAN);
 }
diff -rupN linux-4.3/drivers/ata/pata_of_platform.c linux-4.3-nemo/drivers/ata/pata_of_platform.c
--- linux-4.3/drivers/ata/pata_of_platform.c	2015-09-04 08:22:16.751467060 +0200
+++ linux-4.3-nemo/drivers/ata/pata_of_platform.c	2015-09-04 08:15:20.280298896 +0200
@@ -41,14 +41,36 @@ static int pata_of_platform_probe(struct
 		return -EINVAL;
 	}
 
-	ret = of_address_to_resource(dn, 1, &ctl_res);
-	if (ret) {
-		dev_err(&ofdev->dev, "can't get CTL address from "
-			"device tree\n");
-		return -EINVAL;
+	if (of_device_is_compatible(dn, "electra-ide")) {
+		/* Altstatus is really at offset 0x3f6 from the primary window
+		 * on electra-ide. Adjust ctl_res and io_res accordingly.
+		 */
+		ctl_res = io_res;
+		ctl_res.start = ctl_res.start+0x3f6;
+		io_res.end = ctl_res.start-1;
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+       } else if (of_device_is_compatible(dn, "electra-cf")) {
+               /* Task regs are at 0x800, with alt status @ 0x80e in the primary window
+                * on electra-cf. Adjust ctl_res and io_res accordingly.
+                */
+               ctl_res = io_res;
+               io_res.start += 0x800;
+               ctl_res.start = ctl_res.start + 0x80e;
+               io_res.end = ctl_res.start-1;
+#endif
+	} else {
+		ret = of_address_to_resource(dn, 1, &ctl_res);
+		if (ret) {
+			dev_err(&ofdev->dev, "can't get CTL address from "
+				"device tree\n");
+			return -EINVAL;
+		}
 	}
 
 	irq_res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0);
+	if (irq_res)
+		irq_res->flags = 0;
 
 	prop = of_get_property(dn, "reg-shift", NULL);
 	if (prop)
@@ -65,6 +87,11 @@ static int pata_of_platform_probe(struct
 		dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
 	}
 
+#ifdef CONFIG_PPC_PASEMI_SB600
+       irq_res = 0;                    // force irq off (doesn't seem to work)
+#endif
+
+
 	pio_mask = 1 << pio_mode;
 	pio_mask |= (1 << pio_mode) - 1;
 
@@ -74,7 +101,11 @@ static int pata_of_platform_probe(struct
 
 static struct of_device_id pata_of_platform_match[] = {
 	{ .compatible = "ata-generic", },
-	{ },
+	{ .compatible = "electra-ide", },
+#ifdef CONFIG_PPC_PASEMI_SB600
+       { .compatible = "electra-cf",},
+#endif
+	{},
 };
 MODULE_DEVICE_TABLE(of, pata_of_platform_match);
 
diff -rupN linux-4.3/drivers/gpu/drm/radeon/radeon_pm.c linux-4.3-nemo/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-4.3/drivers/gpu/drm/radeon/radeon_pm.c	2015-09-04 08:22:12.139467107 +0200
+++ linux-4.3-nemo/drivers/gpu/drm/radeon/radeon_pm.c	2015-09-04 08:15:20.360338896 +0200
@@ -226,7 +226,10 @@ static void radeon_set_power_state(struc
 		/* set memory clock */
 		if (rdev->asic->pm.set_memory_clock && (mclk != rdev->pm.current_mclk)) {
 			radeon_pm_debug_check_in_vbl(rdev, false);
+               /* D.Stevens 2012 for the A-EON AmigaOne X1000: Setting memory clock only works on CAICOS and 6570, don't set for anything else (We ignore 6570 here */
+               if (rdev->family == CHIP_CAICOS) {
 			radeon_set_memory_clock(rdev, mclk);
+               }
 			radeon_pm_debug_check_in_vbl(rdev, true);
 			rdev->pm.current_mclk = mclk;
 			DRM_DEBUG_DRIVER("Setting: m: %d\n", mclk);
@@ -1220,7 +1223,7 @@ static void radeon_pm_resume_old(struct
 						SET_VOLTAGE_TYPE_ASIC_VDDCI);
 		if (rdev->pm.default_sclk)
 			radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-		if (rdev->pm.default_mclk)
+		if (rdev->pm.default_mclk && (rdev->family == CHIP_CAICOS))     /* Fix for PPC systems HD6000 >6570 by A-EON Core Linux Support Team */	
 			radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
 	}
 	/* asic init will reset the default power state */
@@ -1271,7 +1274,7 @@ dpm_resume_fail:
 						SET_VOLTAGE_TYPE_ASIC_VDDCI);
 		if (rdev->pm.default_sclk)
 			radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-		if (rdev->pm.default_mclk)
+		if (rdev->pm.default_mclk && (rdev->family == CHIP_CAICOS))     /* Fix for PPC & > HD6570 by A-EON Linux Core Support Team */	
 			radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
 	}
 }
@@ -1318,7 +1321,7 @@ static int radeon_pm_init_old(struct rad
 							SET_VOLTAGE_TYPE_ASIC_VDDCI);
 			if (rdev->pm.default_sclk)
 				radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-			if (rdev->pm.default_mclk)
+			if (rdev->pm.default_mclk && (rdev->family == CHIP_CAICOS))     // D.Stevens 2013: fix for >HD6570 on PPC	
 				radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
 		}
 	}
@@ -1431,7 +1434,7 @@ dpm_failed:
 						SET_VOLTAGE_TYPE_ASIC_VDDCI);
 		if (rdev->pm.default_sclk)
 			radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-		if (rdev->pm.default_mclk)
+		if (rdev->pm.default_mclk && (rdev->family == CHIP_CAICOS))  // D.Stevens 2013: Fix for >HD6570 on ppc	
 			radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
 	}
 	DRM_ERROR("radeon: dpm initialization failed\n");
diff -rupN linux-4.3/drivers/pci/pci.c linux-4.3-nemo/drivers/pci/pci.c
--- linux-4.3/drivers/pci/pci.c	2015-09-04 08:21:32.587467508 +0200
+++ linux-4.3-nemo/drivers/pci/pci.c	2015-09-04 08:15:20.380348895 +0200
@@ -432,7 +432,16 @@ struct resource *pci_find_parent_resourc
 	pci_bus_for_each_resource(bus, r, i) {
 		if (!r)
 			continue;
+#ifdef CONFIG_PPC_PASEMI_SB600
+	/* The new code here checks for resources that are not allocated, and no longer
+	 * returns these, however the SB600 code uses this feature to allocate IO ranges
+	 * in the ISA map, and this breaks booting on the AmigaOneX1000.
+	 * Temporary fix to get the kernel working, remove the resource allocated check.
+	 */
+		if (resource_contains(r, res)) {
+#else
 		if (res->start && resource_contains(r, res)) {
+#endif
 
 			/*
 			 * If the window is prefetchable but the BAR is
diff -rupN linux-4.3/drivers/pci/probe.c linux-4.3-nemo/drivers/pci/probe.c
--- linux-4.3/drivers/pci/probe.c	2015-09-04 08:21:32.595467508 +0200
+++ linux-4.3-nemo/drivers/pci/probe.c	2015-09-04 08:15:20.388352895 +0200
@@ -363,7 +363,11 @@ static void pci_read_bridge_io(struct pc
 		limit |= ((unsigned long) io_limit_hi << 16);
 	}
 
-	if (base <= limit) {
+       if (base <= limit
+       #ifdef CONFIG_PPC_PASEMI_SB600
+               || child->busn_res.start == 5
+       #endif
+              ) {
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
 		region.start = base;
 		region.end = limit + io_granularity - 1;
@@ -1739,11 +1743,14 @@ static int only_one_child(struct pci_bus
 
 	if (!parent || !pci_is_pcie(parent))
 		return 0;
+	#ifndef CONFIG_PPC_PASEMI_SB600
+	// SB600 has non-zero devices on non-root bus.
 	if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
 		return 1;
 	if (parent->has_secondary_link &&
 	    !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
 		return 1;
+	#endif
 	return 0;
 }
 
diff -rupN linux-4.3/drivers/rtc/rtc-cmos.c linux-4.3-nemo/drivers/rtc/rtc-cmos.c
--- linux-4.3/drivers/rtc/rtc-cmos.c	2015-09-04 08:21:50.707467324 +0200
+++ linux-4.3-nemo/drivers/rtc/rtc-cmos.c	2015-09-04 08:15:20.468392894 +0200
@@ -242,6 +242,13 @@ static int cmos_read_alarm(struct device
 	}
 
 	rtc_control = CMOS_READ(RTC_CONTROL);
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+       // Nemo BIOS does not init RTC
+       rtc_control = rtc_control | RTC_24H;
+       CMOS_WRITE(rtc_control, RTC_CONTROL);
+#endif
+
 	spin_unlock_irq(&rtc_lock);
 
 	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
diff -rupN linux-4.3/include/linux/irqdesc.h linux-4.3-nemo/include/linux/irqdesc.h
--- linux-4.3/include/linux/irqdesc.h	2015-09-04 08:20:31.723939735 +0200
+++ linux-4.3-nemo/include/linux/irqdesc.h	2015-09-04 08:15:20.548432893 +0200
@@ -3,6 +3,9 @@
 
 /*
  * Core internal functions to deal with irq descriptors
+ *
+ * This include will move to kernel/irq once we cleaned up the tree.
+ * For now it's included from <linux/irq.h>
  */
 
 struct irq_affinity_notify;
@@ -14,7 +17,7 @@ struct pt_regs;
 
 /**
  * struct irq_desc - interrupt descriptor
- * @irq_common_data:	per irq and chip data passed down to chip functions
+ * @irq_data:		per irq and chip data passed down to chip functions
  * @kstat_irqs:		irq stats per cpu
  * @handle_irq:		highlevel irq-events handler
  * @preflow_handler:	handler called before the flow handler (currently used by sparc)
@@ -44,7 +47,6 @@ struct pt_regs;
  * @name:		flow handler name for /proc/interrupts output
  */
 struct irq_desc {
-	struct irq_common_data	irq_common_data;
 	struct irq_data		irq_data;
 	unsigned int __percpu	*kstat_irqs;
 	irq_flow_handler_t	handle_irq;
@@ -96,20 +98,6 @@ static inline void irq_unlock_sparse(voi
 extern struct irq_desc irq_desc[NR_IRQS];
 #endif
 
-static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
-{
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
-	return irq_to_desc(data->irq);
-#else
-	return container_of(data, struct irq_desc, irq_data);
-#endif
-}
-
-static inline unsigned int irq_desc_get_irq(struct irq_desc *desc)
-{
-	return desc->irq_data.irq;
-}
-
 static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
 {
 	return &desc->irq_data;
@@ -199,47 +187,6 @@ __irq_set_chip_handler_name_locked(unsig
 	desc->name = name;
 }
 
-/**
- * irq_set_handler_locked - Set irq handler from a locked region
- * @data:	Pointer to the irq_data structure which identifies the irq
- * @handler:	Flow control handler function for this interrupt
- *
- * Sets the handler in the irq descriptor associated to @data.
- *
- * Must be called with irq_desc locked and valid parameters. Typical
- * call site is the irq_set_type() callback.
- */
-static inline void irq_set_handler_locked(struct irq_data *data,
-					  irq_flow_handler_t handler)
-{
-	struct irq_desc *desc = irq_data_to_desc(data);
-
-	desc->handle_irq = handler;
-}
-
-/**
- * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region
- * @data:	Pointer to the irq_data structure for which the chip is set
- * @chip:	Pointer to the new irq chip
- * @handler:	Flow control handler function for this interrupt
- * @name:	Name of the interrupt
- *
- * Replace the irq chip at the proper hierarchy level in @data and
- * sets the handler and name in the associated irq descriptor.
- *
- * Must be called with irq_desc locked and valid parameters.
- */
-static inline void
-irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip,
-				 irq_flow_handler_t handler, const char *name)
-{
-	struct irq_desc *desc = irq_data_to_desc(data);
-
-	desc->handle_irq = handler;
-	desc->name = name;
-	data->chip = chip;
-}
-
 static inline int irq_balancing_disabled(unsigned int irq)
 {
 	struct irq_desc *desc;
diff -rupN linux-4.3/include/linux/irq.h linux-4.3-nemo/include/linux/irq.h
--- linux-4.3/include/linux/irq.h	2015-09-04 08:20:29.054605761 +0200
+++ linux-4.3-nemo/include/linux/irq.h	2015-09-04 08:15:20.568442895 +0200
@@ -126,21 +126,13 @@ struct msi_desc;
 struct irq_domain;
 
 /**
- * struct irq_common_data - per irq data shared by all irqchips
- * @state_use_accessors: status information for irq chip functions.
- *			Use accessor functions to deal with it
- */
-struct irq_common_data {
-	unsigned int		state_use_accessors;
-};
-
-/**
- * struct irq_data - per irq chip data passed down to chip functions
+ * struct irq_data - per irq and irq chip data passed down to chip functions
  * @mask:		precomputed bitmask for accessing the chip registers
  * @irq:		interrupt number
  * @hwirq:		hardware interrupt number, local to the interrupt domain
  * @node:		node index useful for balancing
- * @common:		point to data shared by all irqchips
+ * @state_use_accessors: status information for irq chip functions.
+ *			Use accessor functions to deal with it
  * @chip:		low level interrupt hardware access
  * @domain:		Interrupt translation domain; responsible for mapping
  *			between hwirq number and linux irq number.
@@ -161,7 +153,7 @@ struct irq_data {
 	unsigned int		irq;
 	unsigned long		hwirq;
 	unsigned int		node;
-	struct irq_common_data	*common;
+	unsigned int		state_use_accessors;
 	struct irq_chip		*chip;
 	struct irq_domain	*domain;
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -174,7 +166,7 @@ struct irq_data {
 };
 
 /*
- * Bit masks for irq_common_data.state_use_accessors
+ * Bit masks for irq_data.state
  *
  * IRQD_TRIGGER_MASK		- Mask for the trigger type bits
  * IRQD_SETAFFINITY_PENDING	- Affinity setting is pending
@@ -206,36 +198,34 @@ enum {
 	IRQD_WAKEUP_ARMED		= (1 << 19),
 };
 
-#define __irqd_to_state(d)		((d)->common->state_use_accessors)
-
 static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
+	return d->state_use_accessors & IRQD_SETAFFINITY_PENDING;
 }
 
 static inline bool irqd_is_per_cpu(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_PER_CPU;
+	return d->state_use_accessors & IRQD_PER_CPU;
 }
 
 static inline bool irqd_can_balance(struct irq_data *d)
 {
-	return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
+	return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING));
 }
 
 static inline bool irqd_affinity_was_set(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_AFFINITY_SET;
+	return d->state_use_accessors & IRQD_AFFINITY_SET;
 }
 
 static inline void irqd_mark_affinity_was_set(struct irq_data *d)
 {
-	__irqd_to_state(d) |= IRQD_AFFINITY_SET;
+	d->state_use_accessors |= IRQD_AFFINITY_SET;
 }
 
 static inline u32 irqd_get_trigger_type(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
+	return d->state_use_accessors & IRQD_TRIGGER_MASK;
 }
 
 /*
@@ -243,43 +233,43 @@ static inline u32 irqd_get_trigger_type(
  */
 static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
 {
-	__irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
-	__irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
+	d->state_use_accessors &= ~IRQD_TRIGGER_MASK;
+	d->state_use_accessors |= type & IRQD_TRIGGER_MASK;
 }
 
 static inline bool irqd_is_level_type(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_LEVEL;
+	return d->state_use_accessors & IRQD_LEVEL;
 }
 
 static inline bool irqd_is_wakeup_set(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
+	return d->state_use_accessors & IRQD_WAKEUP_STATE;
 }
 
 static inline bool irqd_can_move_in_process_context(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
+	return d->state_use_accessors & IRQD_MOVE_PCNTXT;
 }
 
 static inline bool irqd_irq_disabled(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
+	return d->state_use_accessors & IRQD_IRQ_DISABLED;
 }
 
 static inline bool irqd_irq_masked(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_IRQ_MASKED;
+	return d->state_use_accessors & IRQD_IRQ_MASKED;
 }
 
 static inline bool irqd_irq_inprogress(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
+	return d->state_use_accessors & IRQD_IRQ_INPROGRESS;
 }
 
 static inline bool irqd_is_wakeup_armed(struct irq_data *d)
 {
-	return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
+	return d->state_use_accessors & IRQD_WAKEUP_ARMED;
 }
 
 
@@ -290,12 +280,12 @@ static inline bool irqd_is_wakeup_armed(
  */
 static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
 {
-	__irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
+	d->state_use_accessors |= IRQD_IRQ_INPROGRESS;
 }
 
 static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
 {
-	__irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
+	d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
 }
 
 static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -324,10 +314,8 @@ static inline irq_hw_number_t irqd_to_hw
  * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
  * @irq_cpu_online:	configure an interrupt source for a secondary CPU
  * @irq_cpu_offline:	un-configure an interrupt source for a secondary CPU
- * @irq_suspend:	function called from core code on suspend once per
- *			chip, when one or more interrupts are installed
- * @irq_resume:		function called from core code on resume once per chip,
- *			when one ore more interrupts are installed
+ * @irq_suspend:	function called from core code on suspend once per chip
+ * @irq_resume:		function called from core code on resume once per chip
  * @irq_pm_shutdown:	function called from core code on shutdown once per chip
  * @irq_calc_mask:	Optional function to set irq_data.mask for special cases
  * @irq_print_chip:	optional to print special chip info in show_interrupts
@@ -339,7 +327,6 @@ static inline irq_hw_number_t irqd_to_hw
  * @irq_write_msi_msg:	optional to write message content for MSI
  * @irq_get_irqchip_state:	return the internal state of an interrupt
  * @irq_set_irqchip_state:	set the internal state of a interrupt
- * @irq_set_vcpu_affinity:	optional to target a vCPU in a virtual machine
  * @flags:		chip specific flags
  */
 struct irq_chip {
@@ -382,8 +369,6 @@ struct irq_chip {
 	int		(*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state);
 	int		(*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state);
 
-	int		(*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info);
-
 	unsigned long	flags;
 };
 
@@ -409,6 +394,7 @@ enum {
 	IRQCHIP_EOI_THREADED		= (1 <<  6),
 };
 
+/* This include will go away once we isolated irq_desc usage to core code */
 #include <linux/irqdesc.h>
 
 /*
@@ -436,7 +422,6 @@ extern void irq_cpu_online(void);
 extern void irq_cpu_offline(void);
 extern int irq_set_affinity_locked(struct irq_data *data,
 				   const struct cpumask *cpumask, bool force);
-extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
 void irq_move_irq(struct irq_data *data);
@@ -473,8 +458,6 @@ extern void handle_nested_irq(unsigned i
 
 extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
-extern void irq_chip_enable_parent(struct irq_data *data);
-extern void irq_chip_disable_parent(struct irq_data *data);
 extern void irq_chip_ack_parent(struct irq_data *data);
 extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
 extern void irq_chip_mask_parent(struct irq_data *data);
@@ -484,13 +467,11 @@ extern int irq_chip_set_affinity_parent(
 					const struct cpumask *dest,
 					bool force);
 extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
-extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
-					     void *vcpu_info);
-extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
 #endif
 
 /* Handling of unhandled and spurious interrupts: */
-extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
+extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
+			   irqreturn_t action_ret);
 
 
 /* Enable/disable irq debugging output: */
@@ -536,15 +517,6 @@ irq_set_chained_handler(unsigned int irq
 	__irq_set_handler(irq, handle, 1, NULL);
 }
 
-/*
- * Set a highlevel chained flow handler and its data for a given IRQ.
- * (a chained handler is automatically enabled and set to
- *  IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
- */
-void
-irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
-				 void *data);
-
 void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
 
 static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
@@ -641,7 +613,7 @@ static inline struct msi_desc *irq_get_m
 	return d ? d->msi_desc : NULL;
 }
 
-static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d)
+static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
 {
 	return d->msi_desc;
 }
@@ -652,23 +624,6 @@ static inline u32 irq_get_trigger_type(u
 	return d ? irqd_get_trigger_type(d) : 0;
 }
 
-static inline int irq_data_get_node(struct irq_data *d)
-{
-	return d->node;
-}
-
-static inline struct cpumask *irq_get_affinity_mask(int irq)
-{
-	struct irq_data *d = irq_get_irq_data(irq);
-
-	return d ? d->affinity : NULL;
-}
-
-static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
-{
-	return d->affinity;
-}
-
 unsigned int arch_dynirq_lower_bound(unsigned int from);
 
 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
@@ -763,12 +718,6 @@ struct irq_chip_type {
  * @reg_base:		Register base address (virtual)
  * @reg_readl:		Alternate I/O accessor (defaults to readl if NULL)
  * @reg_writel:		Alternate I/O accessor (defaults to writel if NULL)
- * @suspend:		Function called from core code on suspend once per
- *			chip; can be useful instead of irq_chip::suspend to
- *			handle chip details even when no interrupts are in use
- * @resume:		Function called from core code on resume once per chip;
- *			can be useful instead of irq_chip::suspend to handle
- *			chip details even when no interrupts are in use
  * @irq_base:		Interrupt base nr for this chip
  * @irq_cnt:		Number of interrupts handled by this chip
  * @mask_cache:		Cached mask register shared between all chip types
@@ -795,8 +744,6 @@ struct irq_chip_generic {
 	void __iomem		*reg_base;
 	u32			(*reg_readl)(void __iomem *addr);
 	void			(*reg_writel)(u32 val, void __iomem *addr);
-	void			(*suspend)(struct irq_chip_generic *gc);
-	void			(*resume)(struct irq_chip_generic *gc);
 	unsigned int		irq_base;
 	unsigned int		irq_cnt;
 	u32			mask_cache;
diff -rupN linux-4.3/kernel/irq/chip.c linux-4.3-nemo/kernel/irq/chip.c
--- linux-4.3/kernel/irq/chip.c	2015-09-04 08:20:35.049601728 +0200
+++ linux-4.3-nemo/kernel/irq/chip.c	2015-09-04 08:15:20.632474892 +0200
@@ -63,7 +63,7 @@ int irq_set_irq_type(unsigned int irq, u
 		return -EINVAL;
 
 	type &= IRQ_TYPE_SENSE_MASK;
-	ret = __irq_set_trigger(desc, type);
+	ret = __irq_set_trigger(desc, irq, type);
 	irq_put_desc_busunlock(desc, flags);
 	return ret;
 }
@@ -187,7 +187,7 @@ int irq_startup(struct irq_desc *desc, b
 		irq_enable(desc);
 	}
 	if (resend)
-		check_irq_resend(desc);
+		check_irq_resend(desc, desc->irq_data.irq);
 	return ret;
 }
 
@@ -315,7 +315,7 @@ void handle_nested_irq(unsigned int irq)
 	raw_spin_lock_irq(&desc->lock);
 
 	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	action = desc->action;
 	if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
@@ -328,7 +328,7 @@ void handle_nested_irq(unsigned int irq)
 
 	action_ret = action->thread_fn(action->irq, action->dev_id);
 	if (!noirqdebug)
-		note_interrupt(desc, action_ret);
+		note_interrupt(irq, desc, action_ret);
 
 	raw_spin_lock_irq(&desc->lock);
 	irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
@@ -391,7 +391,7 @@ handle_simple_irq(unsigned int irq, stru
 		goto out_unlock;
 
 	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
 		desc->istate |= IRQS_PENDING;
@@ -443,7 +443,7 @@ handle_level_irq(unsigned int irq, struc
 		goto out_unlock;
 
 	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/*
 	 * If its disabled or no action available
@@ -515,7 +515,7 @@ handle_fasteoi_irq(unsigned int irq, str
 		goto out;
 
 	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/*
 	 * If its disabled or no action available
@@ -583,7 +583,7 @@ handle_edge_irq(unsigned int irq, struct
 		goto out_unlock;
 	}
 
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/* Start handling the irq */
 	desc->irq_data.chip->irq_ack(&desc->irq_data);
@@ -646,7 +646,7 @@ void handle_edge_eoi_irq(unsigned int ir
 		goto out_eoi;
 	}
 
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	do {
 		if (unlikely(!desc->action))
@@ -675,7 +675,7 @@ handle_percpu_irq(unsigned int irq, stru
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
@@ -705,7 +705,7 @@ void handle_percpu_devid_irq(unsigned in
 	void *dev_id = raw_cpu_ptr(action->percpu_dev_id);
 	irqreturn_t res;
 
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
@@ -719,9 +719,15 @@ void handle_percpu_devid_irq(unsigned in
 }
 
 void
-__irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
-		     int is_chained, const char *name)
+__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+		  const char *name)
 {
+	unsigned long flags;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
+
+	if (!desc)
+		return;
+
 	if (!handle) {
 		handle = handle_bad_irq;
 	} else {
@@ -743,13 +749,13 @@ __irq_do_set_handler(struct irq_desc *de
 			 * right away.
 			 */
 			if (WARN_ON(is_chained))
-				return;
+				goto out;
 			/* Try the parent */
 			irq_data = irq_data->parent_data;
 		}
 #endif
 		if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip))
-			return;
+			goto out;
 	}
 
 	/* Uninstall? */
@@ -768,41 +774,12 @@ __irq_do_set_handler(struct irq_desc *de
 		irq_settings_set_nothread(desc);
 		irq_startup(desc, true);
 	}
-}
-
-void
-__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
-		  const char *name)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
-	if (!desc)
-		return;
-
-	__irq_do_set_handler(desc, handle, is_chained, name);
+out:
 	irq_put_desc_busunlock(desc, flags);
 }
 EXPORT_SYMBOL_GPL(__irq_set_handler);
 
 void
-irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
-				 void *data)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
-	if (!desc)
-		return;
-
-	__irq_do_set_handler(desc, handle, 1, NULL);
-	desc->irq_data.handler_data = data;
-
-	irq_put_desc_busunlock(desc, flags);
-}
-EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
-
-void
 irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
 			      irq_flow_handler_t handle, const char *name)
 {
@@ -899,34 +876,6 @@ void irq_cpu_offline(void)
 
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
 /**
- * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
- * NULL)
- * @data:	Pointer to interrupt specific data
- */
-void irq_chip_enable_parent(struct irq_data *data)
-{
-	data = data->parent_data;
-	if (data->chip->irq_enable)
-		data->chip->irq_enable(data);
-	else
-		data->chip->irq_unmask(data);
-}
-
-/**
- * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
- * NULL)
- * @data:	Pointer to interrupt specific data
- */
-void irq_chip_disable_parent(struct irq_data *data)
-{
-	data = data->parent_data;
-	if (data->chip->irq_disable)
-		data->chip->irq_disable(data);
-	else
-		data->chip->irq_mask(data);
-}
-
-/**
  * irq_chip_ack_parent - Acknowledge the parent interrupt
  * @data:	Pointer to interrupt specific data
  */
@@ -985,23 +934,6 @@ int irq_chip_set_affinity_parent(struct
 }
 
 /**
- * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
- * @data:	Pointer to interrupt specific data
- * @type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
- *
- * Conditional, as the underlying parent chip might not implement it.
- */
-int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
-{
-	data = data->parent_data;
-
-	if (data->chip->irq_set_type)
-		return data->chip->irq_set_type(data, type);
-
-	return -ENOSYS;
-}
-
-/**
  * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware
  * @data:	Pointer to interrupt specific data
  *
@@ -1014,20 +946,6 @@ int irq_chip_retrigger_hierarchy(struct
 		if (data->chip && data->chip->irq_retrigger)
 			return data->chip->irq_retrigger(data);
 
-	return 0;
-}
-
-/**
- * irq_chip_set_vcpu_affinity_parent - Set vcpu affinity on the parent interrupt
- * @data:	Pointer to interrupt specific data
- * @vcpu_info:	The vcpu affinity information
- */
-int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info)
-{
-	data = data->parent_data;
-	if (data->chip->irq_set_vcpu_affinity)
-		return data->chip->irq_set_vcpu_affinity(data, vcpu_info);
-
 	return -ENOSYS;
 }
 
diff -rupN linux-4.3/kernel/irq/handle.c linux-4.3-nemo/kernel/irq/handle.c
--- linux-4.3/kernel/irq/handle.c	2015-09-04 08:20:35.041597782 +0200
+++ linux-4.3-nemo/kernel/irq/handle.c	2015-09-04 08:15:20.632474892 +0200
@@ -30,7 +30,7 @@
 void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 {
 	print_irq_desc(irq, desc);
-	kstat_incr_irqs_this_cpu(desc);
+	kstat_incr_irqs_this_cpu(irq, desc);
 	ack_bad_irq(irq);
 }
 
@@ -176,7 +176,7 @@ handle_irq_event_percpu(struct irq_desc
 	add_interrupt_randomness(irq, flags);
 
 	if (!noirqdebug)
-		note_interrupt(desc, retval);
+		note_interrupt(irq, desc, retval);
 	return retval;
 }
 
diff -rupN linux-4.3/kernel/irq/internals.h linux-4.3-nemo/kernel/irq/internals.h
--- linux-4.3/kernel/irq/internals.h	2015-09-04 08:20:35.145649699 +0200
+++ linux-4.3-nemo/kernel/irq/internals.h	2015-09-04 08:15:20.640478892 +0200
@@ -59,9 +59,12 @@ enum {
 #include "debug.h"
 #include "settings.h"
 
-extern int __irq_set_trigger(struct irq_desc *desc, unsigned long flags);
-extern void __disable_irq(struct irq_desc *desc);
-extern void __enable_irq(struct irq_desc *desc);
+#define irq_data_to_desc(data)	container_of(data, struct irq_desc, irq_data)
+
+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);
+extern void __enable_irq(struct irq_desc *desc, unsigned int irq);
 
 extern int irq_startup(struct irq_desc *desc, bool resend);
 extern void irq_shutdown(struct irq_desc *desc);
@@ -75,8 +78,12 @@ extern void unmask_threaded_irq(struct i
 
 #ifdef CONFIG_SPARSE_IRQ
 static inline void irq_mark_irq(unsigned int irq) { }
+extern void irq_lock_sparse(void);
+extern void irq_unlock_sparse(void);
 #else
 extern void irq_mark_irq(unsigned int irq);
+static inline void irq_lock_sparse(void) { }
+static inline void irq_unlock_sparse(void) { }
 #endif
 
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
@@ -85,7 +92,7 @@ irqreturn_t handle_irq_event_percpu(stru
 irqreturn_t handle_irq_event(struct irq_desc *desc);
 
 /* Resending of interrupts :*/
-void check_irq_resend(struct irq_desc *desc);
+void check_irq_resend(struct irq_desc *desc, unsigned int irq);
 bool irq_wait_for_poll(struct irq_desc *desc);
 void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action);
 
@@ -163,40 +170,35 @@ irq_put_desc_unlock(struct irq_desc *des
  */
 static inline void irqd_set_move_pending(struct irq_data *d)
 {
-	__irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
+	d->state_use_accessors |= IRQD_SETAFFINITY_PENDING;
 }
 
 static inline void irqd_clr_move_pending(struct irq_data *d)
 {
-	__irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
+	d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING;
 }
 
 static inline void irqd_clear(struct irq_data *d, unsigned int mask)
 {
-	__irqd_to_state(d) &= ~mask;
+	d->state_use_accessors &= ~mask;
 }
 
 static inline void irqd_set(struct irq_data *d, unsigned int mask)
 {
-	__irqd_to_state(d) |= mask;
+	d->state_use_accessors |= mask;
 }
 
 static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
 {
-	return __irqd_to_state(d) & mask;
+	return d->state_use_accessors & mask;
 }
 
-static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc)
+static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
 {
 	__this_cpu_inc(*desc->kstat_irqs);
 	__this_cpu_inc(kstat.irqs_sum);
 }
 
-static inline int irq_desc_get_node(struct irq_desc *desc)
-{
-	return irq_data_get_node(&desc->irq_data);
-}
-
 #ifdef CONFIG_PM_SLEEP
 bool irq_pm_check_wakeup(struct irq_desc *desc);
 void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff -rupN linux-4.3/kernel/irq/irqdesc.c linux-4.3-nemo/kernel/irq/irqdesc.c
--- linux-4.3/kernel/irq/irqdesc.c	2015-09-04 08:20:35.141647704 +0200
+++ linux-4.3-nemo/kernel/irq/irqdesc.c	2015-09-04 08:15:20.644480893 +0200
@@ -59,10 +59,16 @@ static void desc_smp_init(struct irq_des
 #endif
 }
 
+static inline int desc_node(struct irq_desc *desc)
+{
+	return desc->irq_data.node;
+}
+
 #else
 static inline int
 alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
 static inline void desc_smp_init(struct irq_desc *desc, int node) { }
+static inline int desc_node(struct irq_desc *desc) { return 0; }
 #endif
 
 static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
@@ -70,7 +76,6 @@ static void desc_set_defaults(unsigned i
 {
 	int cpu;
 
-	desc->irq_data.common = &desc->irq_common_data;
 	desc->irq_data.irq = irq;
 	desc->irq_data.chip = &no_irq_chip;
 	desc->irq_data.chip_data = NULL;
@@ -294,7 +299,7 @@ static void free_desc(unsigned int irq)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
+	desc_set_defaults(irq, desc, desc_node(desc), NULL);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -582,7 +587,7 @@ int irq_set_percpu_devid(unsigned int ir
 
 void kstat_incr_irq_this_cpu(unsigned int irq)
 {
-	kstat_incr_irqs_this_cpu(irq_to_desc(irq));
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 }
 
 /**
@@ -614,7 +619,7 @@ unsigned int kstat_irqs(unsigned int irq
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	int cpu;
-	unsigned int sum = 0;
+	int sum = 0;
 
 	if (!desc || !desc->kstat_irqs)
 		return 0;
@@ -634,7 +639,7 @@ unsigned int kstat_irqs(unsigned int irq
  */
 unsigned int kstat_irqs_usr(unsigned int irq)
 {
-	unsigned int sum;
+	int sum;
 
 	irq_lock_sparse();
 	sum = kstat_irqs(irq);
diff -rupN linux-4.3/kernel/irq/irqdomain.c linux-4.3-nemo/kernel/irq/irqdomain.c
--- linux-4.3/kernel/irq/irqdomain.c	2015-09-04 08:20:35.057605687 +0200
+++ linux-4.3-nemo/kernel/irq/irqdomain.c	2015-09-04 08:15:20.652484892 +0200
@@ -838,12 +838,10 @@ static struct irq_data *irq_domain_inser
 {
 	struct irq_data *irq_data;
 
-	irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
-				irq_data_get_node(child));
+	irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node);
 	if (irq_data) {
 		child->parent_data = irq_data;
 		irq_data->irq = child->irq;
-		irq_data->common = child->common;
 		irq_data->node = child->node;
 		irq_data->domain = domain;
 	}
@@ -1242,27 +1240,6 @@ struct irq_data *irq_domain_get_irq_data
 	return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
 }
 
-/**
- * irq_domain_set_info - Set the complete data for a @virq in @domain
- * @domain:		Interrupt domain to match
- * @virq:		IRQ number
- * @hwirq:		The hardware interrupt number
- * @chip:		The associated interrupt chip
- * @chip_data:		The associated interrupt chip data
- * @handler:		The interrupt flow handler
- * @handler_data:	The interrupt flow handler data
- * @handler_name:	The interrupt handler name
- */
-void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
-			 irq_hw_number_t hwirq, struct irq_chip *chip,
-			 void *chip_data, irq_flow_handler_t handler,
-			 void *handler_data, const char *handler_name)
-{
-	irq_set_chip_and_handler_name(virq, chip, handler, handler_name);
-	irq_set_chip_data(virq, chip_data);
-	irq_set_handler_data(virq, handler_data);
-}
-
 static void irq_domain_check_hierarchy(struct irq_domain *domain)
 {
 }
diff -rupN linux-4.3/kernel/irq/manage.c linux-4.3-nemo/kernel/irq/manage.c
--- linux-4.3/kernel/irq/manage.c	2015-09-04 08:20:34.941547706 +0200
+++ linux-4.3-nemo/kernel/irq/manage.c	2015-09-04 08:15:20.708512892 +0200
@@ -115,14 +115,6 @@ EXPORT_SYMBOL(synchronize_irq);
 #ifdef CONFIG_SMP
 cpumask_var_t irq_default_affinity;
 
-static int __irq_can_set_affinity(struct irq_desc *desc)
-{
-	if (!desc || !irqd_can_balance(&desc->irq_data) ||
-	    !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity)
-		return 0;
-	return 1;
-}
-
 /**
  *	irq_can_set_affinity - Check if the affinity of a given irq can be set
  *	@irq:		Interrupt to check
@@ -130,7 +122,13 @@ static int __irq_can_set_affinity(struct
  */
 int irq_can_set_affinity(unsigned int irq)
 {
-	return __irq_can_set_affinity(irq_to_desc(irq));
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	if (!desc || !irqd_can_balance(&desc->irq_data) ||
+	    !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity)
+		return 0;
+
+	return 1;
 }
 
 /**
@@ -258,37 +256,6 @@ int irq_set_affinity_hint(unsigned int i
 }
 EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
 
-/**
- *	irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
- *	@irq: interrupt number to set affinity
- *	@vcpu_info: vCPU specific data
- *
- *	This function uses the vCPU specific data to set the vCPU
- *	affinity for an irq. The vCPU specific data is passed from
- *	outside, such as KVM. One example code path is as below:
- *	KVM -> IOMMU -> irq_set_vcpu_affinity().
- */
-int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
-{
-	unsigned long flags;
-	struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-	struct irq_data *data;
-	struct irq_chip *chip;
-	int ret = -ENOSYS;
-
-	if (!desc)
-		return -EINVAL;
-
-	data = irq_desc_get_irq_data(desc);
-	chip = irq_data_get_irq_chip(data);
-	if (chip && chip->irq_set_vcpu_affinity)
-		ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
-	irq_put_desc_unlock(desc, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(irq_set_vcpu_affinity);
-
 static void irq_affinity_notify(struct work_struct *work)
 {
 	struct irq_affinity_notify *notify =
@@ -361,13 +328,14 @@ EXPORT_SYMBOL_GPL(irq_set_affinity_notif
 /*
  * Generic version of the affinity autoselector.
  */
-static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
+static int
+setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
 {
 	struct cpumask *set = irq_default_affinity;
-	int node = irq_desc_get_node(desc);
+	int node = desc->irq_data.node;
 
 	/* Excludes PER_CPU and NO_BALANCE interrupts */
-	if (!__irq_can_set_affinity(desc))
+	if (!irq_can_set_affinity(irq))
 		return 0;
 
 	/*
@@ -394,10 +362,10 @@ static int setup_affinity(struct irq_des
 	return 0;
 }
 #else
-/* Wrapper for ALPHA specific affinity selector magic */
-static inline int setup_affinity(struct irq_desc *d, struct cpumask *mask)
+static inline int
+setup_affinity(unsigned int irq, struct irq_desc *d, struct cpumask *mask)
 {
-	return irq_select_affinity(irq_desc_get_irq(d));
+	return irq_select_affinity(irq);
 }
 #endif
 
@@ -411,20 +379,20 @@ int irq_select_affinity_usr(unsigned int
 	int ret;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	ret = setup_affinity(desc, mask);
+	ret = setup_affinity(irq, desc, mask);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return ret;
 }
 
 #else
 static inline int
-setup_affinity(struct irq_desc *desc, struct cpumask *mask)
+setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
 {
 	return 0;
 }
 #endif
 
-void __disable_irq(struct irq_desc *desc)
+void __disable_irq(struct irq_desc *desc, unsigned int irq)
 {
 	if (!desc->depth++)
 		irq_disable(desc);
@@ -437,7 +405,7 @@ static int __disable_irq_nosync(unsigned
 
 	if (!desc)
 		return -EINVAL;
-	__disable_irq(desc);
+	__disable_irq(desc, irq);
 	irq_put_desc_busunlock(desc, flags);
 	return 0;
 }
@@ -504,13 +472,12 @@ bool disable_hardirq(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(disable_hardirq);
 
-void __enable_irq(struct irq_desc *desc)
+void __enable_irq(struct irq_desc *desc, unsigned int irq)
 {
 	switch (desc->depth) {
 	case 0:
  err_out:
-		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n",
-		     irq_desc_get_irq(desc));
+		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
 		break;
 	case 1: {
 		if (desc->istate & IRQS_SUSPENDED)
@@ -518,7 +485,7 @@ void __enable_irq(struct irq_desc *desc)
 		/* Prevent probing on this irq: */
 		irq_settings_set_noprobe(desc);
 		irq_enable(desc);
-		check_irq_resend(desc);
+		check_irq_resend(desc, irq);
 		/* fall-through */
 	}
 	default:
@@ -548,7 +515,7 @@ void enable_irq(unsigned int irq)
 		 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
 		goto out;
 
-	__enable_irq(desc);
+	__enable_irq(desc, irq);
 out:
 	irq_put_desc_busunlock(desc, flags);
 }
@@ -639,7 +606,8 @@ int can_request_irq(unsigned int irq, un
 	return canrequest;
 }
 
-int __irq_set_trigger(struct irq_desc *desc, unsigned long flags)
+int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
+		      unsigned long flags)
 {
 	struct irq_chip *chip = desc->irq_data.chip;
 	int ret, unmask = 0;
@@ -649,8 +617,7 @@ int __irq_set_trigger(struct irq_desc *d
 		 * IRQF_TRIGGER_* but the PIC does not support multiple
 		 * flow-types?
 		 */
-		pr_debug("No set_type function for IRQ %d (%s)\n",
-			 irq_desc_get_irq(desc),
+		pr_debug("No set_type function for IRQ %d (%s)\n", irq,
 			 chip ? (chip->name ? : "unknown") : "unknown");
 		return 0;
 	}
@@ -687,7 +654,7 @@ int __irq_set_trigger(struct irq_desc *d
 		break;
 	default:
 		pr_err("Setting trigger mode %lu for irq %u failed (%pF)\n",
-		       flags, irq_desc_get_irq(desc), chip->irq_set_type);
+		       flags, irq, chip->irq_set_type);
 	}
 	if (unmask)
 		unmask_irq(desc);
@@ -1223,8 +1190,8 @@ __setup_irq(unsigned int irq, struct irq
 
 		/* Setup the type (level, edge polarity) if configured: */
 		if (new->flags & IRQF_TRIGGER_MASK) {
-			ret = __irq_set_trigger(desc,
-						new->flags & IRQF_TRIGGER_MASK);
+			ret = __irq_set_trigger(desc, irq,
+					new->flags & IRQF_TRIGGER_MASK);
 
 			if (ret)
 				goto out_mask;
@@ -1255,7 +1222,7 @@ __setup_irq(unsigned int irq, struct irq
 		}
 
 		/* Set default affinity mask once everything is setup */
-		setup_affinity(desc, mask);
+		setup_affinity(irq, desc, mask);
 
 	} else if (new->flags & IRQF_TRIGGER_MASK) {
 		unsigned int nmsk = new->flags & IRQF_TRIGGER_MASK;
@@ -1282,7 +1249,7 @@ __setup_irq(unsigned int irq, struct irq
 	 */
 	if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) {
 		desc->istate &= ~IRQS_SPURIOUS_DISABLED;
-		__enable_irq(desc);
+		__enable_irq(desc, irq);
 	}
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -1652,7 +1619,7 @@ void enable_percpu_irq(unsigned int irq,
 	if (type != IRQ_TYPE_NONE) {
 		int ret;
 
-		ret = __irq_set_trigger(desc, type);
+		ret = __irq_set_trigger(desc, irq, type);
 
 		if (ret) {
 			WARN(1, "failed to set type for IRQ%d\n", irq);
@@ -1877,7 +1844,6 @@ int irq_get_irqchip_state(unsigned int i
 	irq_put_desc_busunlock(desc, flags);
 	return err;
 }
-EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
 
 /**
  *	irq_set_irqchip_state - set the state of a forwarded interrupt.
@@ -1923,4 +1889,3 @@ int irq_set_irqchip_state(unsigned int i
 	irq_put_desc_busunlock(desc, flags);
 	return err;
 }
-EXPORT_SYMBOL_GPL(irq_set_irqchip_state);
diff -rupN linux-4.3/kernel/irq/proc.c linux-4.3-nemo/kernel/irq/proc.c
--- linux-4.3/kernel/irq/proc.c	2015-09-04 08:20:34.901527698 +0200
+++ linux-4.3-nemo/kernel/irq/proc.c	2015-09-04 08:15:20.716516892 +0200
@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq
 {
 	struct irq_desc *desc = irq_to_desc((long) m->private);
 
-	seq_printf(m, "%d\n", irq_desc_get_node(desc));
+	seq_printf(m, "%d\n", desc->irq_data.node);
 	return 0;
 }
 
diff -rupN linux-4.3/kernel/irq/resend.c linux-4.3-nemo/kernel/irq/resend.c
--- linux-4.3/kernel/irq/resend.c	2015-09-04 08:20:35.145649699 +0200
+++ linux-4.3-nemo/kernel/irq/resend.c	2015-09-04 08:15:20.720518892 +0200
@@ -53,7 +53,7 @@ static DECLARE_TASKLET(resend_tasklet, r
  *
  * Is called with interrupts disabled and desc->lock held.
  */
-void check_irq_resend(struct irq_desc *desc)
+void check_irq_resend(struct irq_desc *desc, unsigned int irq)
 {
 	/*
 	 * We do not resend level type interrupts. Level type
@@ -74,8 +74,6 @@ void check_irq_resend(struct irq_desc *d
 		if (!desc->irq_data.chip->irq_retrigger ||
 		    !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) {
 #ifdef CONFIG_HARDIRQS_SW_RESEND
-			unsigned int irq = irq_desc_get_irq(desc);
-
 			/*
 			 * If the interrupt is running in the thread
 			 * context of the parent irq we need to be
diff -rupN linux-4.3/kernel/irq/spurious.c linux-4.3-nemo/kernel/irq/spurious.c
--- linux-4.3/kernel/irq/spurious.c	2015-09-04 08:20:35.041597782 +0200
+++ linux-4.3-nemo/kernel/irq/spurious.c	2015-09-04 08:15:20.724520891 +0200
@@ -60,7 +60,7 @@ bool irq_wait_for_poll(struct irq_desc *
 /*
  * Recovery handler for misrouted interrupts.
  */
-static int try_one_irq(struct irq_desc *desc, bool force)
+static int try_one_irq(int irq, struct irq_desc *desc, bool force)
 {
 	irqreturn_t ret = IRQ_NONE;
 	struct irqaction *action;
@@ -133,7 +133,7 @@ static int misrouted_irq(int irq)
 		if (i == irq)	/* Already tried */
 			continue;
 
-		if (try_one_irq(desc, false))
+		if (try_one_irq(i, desc, false))
 			ok = 1;
 	}
 out:
@@ -164,7 +164,7 @@ static void poll_spurious_irqs(unsigned
 			continue;
 
 		local_irq_disable();
-		try_one_irq(desc, true);
+		try_one_irq(i, desc, true);
 		local_irq_enable();
 	}
 out:
@@ -188,9 +188,10 @@ static inline int bad_action_ret(irqretu
  * (The other 100-of-100,000 interrupts may have been a correctly
  *  functioning device sharing an IRQ with the failing one)
  */
-static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
+static void
+__report_bad_irq(unsigned int irq, struct irq_desc *desc,
+		 irqreturn_t action_ret)
 {
-	unsigned int irq = irq_desc_get_irq(desc);
 	struct irqaction *action;
 	unsigned long flags;
 
@@ -223,13 +224,14 @@ static void __report_bad_irq(struct irq_
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-static void report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
+static void
+report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
 {
 	static int count = 100;
 
 	if (count > 0) {
 		count--;
-		__report_bad_irq(desc, action_ret);
+		__report_bad_irq(irq, desc, action_ret);
 	}
 }
 
@@ -270,16 +272,15 @@ try_misrouted_irq(unsigned int irq, stru
 
 #define SPURIOUS_DEFERRED	0x80000000
 
-void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret)
+void note_interrupt(unsigned int irq, struct irq_desc *desc,
+		    irqreturn_t action_ret)
 {
-	unsigned int irq;
-
 	if (desc->istate & IRQS_POLL_INPROGRESS ||
 	    irq_settings_is_polled(desc))
 		return;
 
 	if (bad_action_ret(action_ret)) {
-		report_bad_irq(desc, action_ret);
+		report_bad_irq(irq, desc, action_ret);
 		return;
 	}
 
@@ -397,7 +398,6 @@ void note_interrupt(struct irq_desc *des
 		desc->last_unhandled = jiffies;
 	}
 
-	irq = irq_desc_get_irq(desc);
 	if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {
 		int ok = misrouted_irq(irq);
 		if (action_ret == IRQ_NONE)
@@ -413,7 +413,7 @@ void note_interrupt(struct irq_desc *des
 		/*
 		 * The interrupt is stuck
 		 */
-		__report_bad_irq(desc, action_ret);
+		__report_bad_irq(irq, desc, action_ret);
 		/*
 		 * Now kill the IRQ
 		 */
diff -rupN linux-4.3/sound/pci/hda/patch_sigmatel.c linux-4.3-nemo/sound/pci/hda/patch_sigmatel.c
--- linux-4.3/sound/pci/hda/patch_sigmatel.c	2015-09-04 08:21:07.874005367 +0200
+++ linux-4.3-nemo/sound/pci/hda/patch_sigmatel.c	2015-09-04 08:15:20.792554891 +0200
@@ -166,6 +166,7 @@ enum {
 	STAC_D965_VERBS,
 	STAC_DELL_3ST,
 	STAC_DELL_BIOS,
+	STAC_NEMO_DEFAULT,
 	STAC_DELL_BIOS_AMIC,
 	STAC_DELL_BIOS_SPDIF,
 	STAC_927X_DELL_DMIC,
@@ -1359,6 +1360,23 @@ static const struct hda_pintbl oqo9200_p
 	{}
 };
 
+static const struct hda_pintbl nemo_pin_configs[] = {
+   { 0x0a, 0x02214020 },
+   { 0x0b, 0x02A19080 },
+   { 0x0c, 0x0181304E },
+   { 0x0d, 0x01014010 },
+   { 0x0e, 0x01A19040 },
+   { 0x0f, 0x01011012 },
+   { 0x10, 0x01016011 },
+   { 0x11, 0x01012014 },
+   { 0x12, 0x103301F0 },
+   { 0x13, 0x00000000 },
+   { 0x14, 0x00000000 },
+   { 0x21, 0x01442170 },
+   { 0x22, 0x00000000 },
+   { 0x23, 0x00000000 },
+   {}
+};
 
 static void stac9200_fixup_panasonic(struct hda_codec *codec,
 				     const struct hda_fixup *fix, int action)
@@ -3869,6 +3887,10 @@ static const struct hda_fixup stac927x_f
 		.type = HDA_FIXUP_PINS,
 		.v.pins = d965_5st_no_fp_pin_configs,
 	},
+	[STAC_NEMO_DEFAULT] = {
+       		.type = HDA_FIXUP_PINS,
+		.v.pins = nemo_pin_configs,
+	},
 	[STAC_DELL_3ST] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = dell_3st_pin_configs,
@@ -3925,6 +3947,7 @@ static const struct hda_model_fixup stac
 	{ .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
 	{ .id = STAC_DELL_3ST, .name = "dell-3stack" },
 	{ .id = STAC_DELL_BIOS, .name = "dell-bios" },
+	{ .id = STAC_NEMO_DEFAULT, .name = "nemo-default" },	
 	{ .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
 	{ .id = STAC_927X_VOLKNOB, .name = "volknob" },
 	{}
@@ -3963,6 +3986,8 @@ static const struct snd_pci_quirk stac92
 			   "Intel D965", STAC_D965_5ST),
 	SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
 			   "Intel D965", STAC_D965_5ST),
+	/* Nemo */
+	SND_PCI_QUIRK(0x1888, 0x1000, "AmigaOne X1000", STAC_NEMO_DEFAULT),
 	/* volume-knob fixes */
 	SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
 	{} /* terminator */
@@ -5018,6 +5043,7 @@ static const struct hda_codec_preset snd
  	{ .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
  	{ .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
  	{ .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
+	{ .id = 0x83847638, .name = "STAC92HD700", .patch = patch_stac927x },
  	{ .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
  	{ .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
  	{ .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
