diff -rupN linux-4.4/arch/powerpc/Kconfig linux-4.4-nemo/arch/powerpc/Kconfig
--- linux-4.4/arch/powerpc/Kconfig	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/Kconfig	2015-12-07 14:48:23.371987988 +0100
@@ -158,8 +155,6 @@ config PPC
 	select HAVE_PERF_EVENTS_NMI if PPC64
 	select EDAC_SUPPORT
 	select EDAC_ATOMIC_SCRUB
-	select ARCH_HAS_DMA_SET_COHERENT_MASK
-	select HAVE_ARCH_SECCOMP_FILTER
 
 config GENERIC_CSUM
 	def_bool CPU_LITTLE_ENDIAN
@@ -419,8 +414,7 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
 
 config KEXEC
 	bool "kexec system call"
-	depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E
-	select KEXEC_CORE
+	depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP))
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
@@ -520,6 +514,11 @@ config NODES_SPAN_OTHER_NODES
 	def_bool y
 	depends on NEED_MULTIPLE_NODES
 
+config PPC_HAS_HASH_64K
+	bool
+	depends on PPC64
+	default n
+
 config STDBINUTILS
 	bool "Using standard binutils settings"
 	depends on 44x
@@ -561,16 +560,16 @@ config PPC_4K_PAGES
 	bool "4k page size"
 
 config PPC_16K_PAGES
-	bool "16k page size"
-	depends on 44x || PPC_8xx
+	bool "16k page size" if 44x || PPC_8xx
 
 config PPC_64K_PAGES
-	bool "64k page size"
-	depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64)
+	bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64
+	depends on !PPC_FSL_BOOK3E
+	select PPC_HAS_HASH_64K if PPC_STD_MMU_64
 
 config PPC_256K_PAGES
-	bool "256k page size"
-	depends on 44x && !STDBINUTILS
+	bool "256k page size" if 44x
+	depends on !STDBINUTILS
 	help
 	  Make the page size 256k.
 
diff -rupN linux-4.4/arch/powerpc/kernel/dma.c linux-4.4-nemo/arch/powerpc/kernel/dma.c
--- linux-4.4/arch/powerpc/kernel/dma.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/kernel/dma.c	2015-12-07 14:49:38.098286892 +0100
@@ -16,7 +16,6 @@
 #include <asm/bug.h>
 #include <asm/machdep.h>
 #include <asm/swiotlb.h>
-#include <asm/iommu.h>
 
 /*
  * Generic direct DMA implementation
@@ -40,31 +39,9 @@ static u64 __maybe_unused get_pfn_limit(
 	return pfn;
 }
 
-static int dma_direct_dma_supported(struct device *dev, u64 mask)
-{
-#ifdef CONFIG_PPC64
-	u64 limit = get_dma_offset(dev) + (memblock_end_of_DRAM() - 1);
-
-	/* Limit fits in the mask, we are good */
-	if (mask >= limit)
-		return 1;
-
-#ifdef CONFIG_FSL_SOC
-	/* Freescale gets another chance via ZONE_DMA/ZONE_DMA32, however
-	 * that will have to be refined if/when they support iommus
-	 */
-	return 1;
-#endif
-	/* Sorry ... */
-	return 0;
-#else
-	return 1;
-#endif
-}
-
-void *__dma_direct_alloc_coherent(struct device *dev, size_t size,
-				  dma_addr_t *dma_handle, gfp_t flag,
-				  struct dma_attrs *attrs)
+void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, gfp_t flag,
+				struct dma_attrs *attrs)
 {
 	void *ret;
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -119,9 +96,9 @@ void *__dma_direct_alloc_coherent(struct
 #endif
 }
 
-void __dma_direct_free_coherent(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle,
-				struct dma_attrs *attrs)
+void dma_direct_free_coherent(struct device *dev, size_t size,
+			      void *vaddr, dma_addr_t dma_handle,
+			      struct dma_attrs *attrs)
 {
 #ifdef CONFIG_NOT_COHERENT_CACHE
 	__dma_free_coherent(size, vaddr);
@@ -130,51 +107,6 @@ void __dma_direct_free_coherent(struct d
 #endif
 }
 
-static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag,
-				       struct dma_attrs *attrs)
-{
-	struct iommu_table *iommu;
-
-	/* The coherent mask may be smaller than the real mask, check if
-	 * we can really use the direct ops
-	 */
-	if (dma_direct_dma_supported(dev, dev->coherent_dma_mask))
-		return __dma_direct_alloc_coherent(dev, size, dma_handle,
-						   flag, attrs);
-
-	/* Ok we can't ... do we have an iommu ? If not, fail */
-	iommu = get_iommu_table_base(dev);
-	if (!iommu)
-		return NULL;
-
-	/* Try to use the iommu */
-	return iommu_alloc_coherent(dev, iommu, size, dma_handle,
-				    dev->coherent_dma_mask, flag,
-				    dev_to_node(dev));
-}
-
-static void dma_direct_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle,
-				     struct dma_attrs *attrs)
-{
-	struct iommu_table *iommu;
-
-	/* See comments in dma_direct_alloc_coherent() */
-	if (dma_direct_dma_supported(dev, dev->coherent_dma_mask))
-		return __dma_direct_free_coherent(dev, size, vaddr, dma_handle,
-						  attrs);
-	/* Maybe we used an iommu ... */
-	iommu = get_iommu_table_base(dev);
-
-	/* If we hit that we should have never allocated in the first
-	 * place so how come we are freeing ?
-	 */
-	if (WARN_ON(!iommu))
-		return;
-	iommu_free_coherent(iommu, size, vaddr, dma_handle);
-}
-
 int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 			     void *cpu_addr, dma_addr_t handle, size_t size,
 			     struct dma_attrs *attrs)
@@ -215,6 +147,18 @@ static void dma_direct_unmap_sg(struct d
 {
 }
 
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PPC64
+	/* Could be improved so platforms can set the limit in case
+	 * they have limited DMA windows
+	 */
+	return mask >= get_dma_offset(dev) + (memblock_end_of_DRAM() - 1);
+#else
+	return 1;
+#endif
+}
+
 static u64 dma_direct_get_required_mask(struct device *dev)
 {
 	u64 end, mask;
@@ -286,25 +230,6 @@ struct dma_map_ops dma_direct_ops = {
 };
 EXPORT_SYMBOL(dma_direct_ops);
 
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
-	if (!dma_supported(dev, mask)) {
-		/*
-		 * We need to special case the direct DMA ops which can
-		 * support a fallback for coherent allocations. There
-		 * is no dma_op->set_coherent_mask() so we have to do
-		 * things the hard way:
-		 */
-		if (get_dma_ops(dev) != &dma_direct_ops ||
-		    get_iommu_table_base(dev) == NULL ||
-		    !dma_iommu_dma_supported(dev, mask))
-			return -EIO;
-	}
-	dev->coherent_dma_mask = mask;
-	return 0;
-}
-EXPORT_SYMBOL(dma_set_coherent_mask);
-
 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
 
 int __dma_set_mask(struct device *dev, u64 dma_mask)
 
diff -rupN linux-4.4/arch/powerpc/kernel/head_64.S linux-4.4-nemo/arch/powerpc/kernel/head_64.S
--- linux-4.4/arch/powerpc/kernel/head_64.S	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/kernel/head_64.S	2015-12-07 14:47:40.164815160 +0100
@@ -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.4/arch/powerpc/kernel/pci-common.c linux-4.4-nemo/arch/powerpc/kernel/pci-common.c
--- linux-4.4/arch/powerpc/kernel/pci-common.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/kernel/pci-common.c	2015-12-07 14:47:40.167815172 +0100
@@ -723,6 +723,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
 			 */
@@ -1182,6 +1195,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
@@ -1189,6 +1203,7 @@ static void pcibios_allocate_bus_resourc
 				 */
 				continue;
 			}
+#endif
 		}
 
 		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %pR, parent %p (%s)\n",
@@ -1607,8 +1622,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.4/arch/powerpc/kernel/setup-common.c linux-4.4-nemo/arch/powerpc/kernel/setup-common.c
--- linux-4.4/arch/powerpc/kernel/setup-common.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/kernel/setup-common.c	2015-12-07 14:47:40.168815176 +0100
@@ -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.4/arch/powerpc/platforms/pasemi/iommu.c linux-4.4-nemo/arch/powerpc/platforms/pasemi/iommu.c
--- linux-4.4/arch/powerpc/platforms/pasemi/iommu.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/platforms/pasemi/iommu.c	2015-12-07 14:47:40.169815180 +0100
@@ -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.4/arch/powerpc/platforms/pasemi/Kconfig linux-4.4-nemo/arch/powerpc/platforms/pasemi/Kconfig
--- linux-4.4/arch/powerpc/platforms/pasemi/Kconfig	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/platforms/pasemi/Kconfig	2015-12-07 14:47:40.169815180 +0100
@@ -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.4/arch/powerpc/platforms/pasemi/pci.c linux-4.4-nemo/arch/powerpc/platforms/pasemi/pci.c
--- linux-4.4/arch/powerpc/platforms/pasemi/pci.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/platforms/pasemi/pci.c	2015-12-07 14:47:40.170815184 +0100
@@ -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.4/arch/powerpc/platforms/pasemi/setup.c linux-4.4-nemo/arch/powerpc/platforms/pasemi/setup.c
--- linux-4.4/arch/powerpc/platforms/pasemi/setup.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/platforms/pasemi/setup.c	2015-12-07 14:47:40.172815192 +0100
@@ -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,56 @@ 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(struct irq_desc *desc)
+{
+	   struct irq_chip *chip = irq_desc_get_chip(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 */
+       chip->irq_eoi(&desc->irq_data);		
+}
+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 +308,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 +471,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
 
-	/* Publish OF platform devices for SDC and other non-PCI devices */
-	of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
+
+ 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);
+
+#ifdef CONFIG_PPC_PASEMI_SB600
+       platform_device_register_simple("rtc_cmos", -1, rtc_resource, 2);
+#endif
 
 	return 0;
 }
@@ -430,9 +525,13 @@ 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;
 }
 
+
 define_machine(pasemi) {
 	.name			= "PA Semi PWRficient",
 	.probe			= pas_probe,
@@ -445,4 +544,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.4/arch/powerpc/sysdev/i8259.c linux-4.4-nemo/arch/powerpc/sysdev/i8259.c
--- linux-4.4/arch/powerpc/sysdev/i8259.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/sysdev/i8259.c	2015-12-07 14:47:40.173815196 +0100
@@ -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)
@@ -231,6 +231,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);
@@ -261,8 +263,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) {
@@ -270,6 +276,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.4/arch/powerpc/sysdev/mpic.c linux-4.4-nemo/arch/powerpc/sysdev/mpic.c
--- linux-4.4/arch/powerpc/sysdev/mpic.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/arch/powerpc/sysdev/mpic.c	2015-12-07 14:47:40.175815204 +0100
@@ -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.4/drivers/ata/libata-sff.c linux-4.4-nemo/drivers/ata/libata-sff.c
--- linux-4.4/drivers/ata/libata-sff.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/ata/libata-sff.c	2015-12-07 14:47:40.178815216 +0100
@@ -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.4/drivers/ata/pata_atiixp.c linux-4.4-nemo/drivers/ata/pata_atiixp.c
--- linux-4.4/drivers/ata/pata_atiixp.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/ata/pata_atiixp.c	2015-12-07 14:47:40.179815220 +0100
@@ -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.4/drivers/ata/pata_of_platform.c linux-4.4-nemo/drivers/ata/pata_of_platform.c
--- linux-4.4/drivers/ata/pata_of_platform.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/ata/pata_of_platform.c	2015-12-07 14:47:40.180815224 +0100
@@ -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.4/drivers/gpu/drm/radeon/radeon_pm.c linux-4.4-nemo/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-4.4/drivers/gpu/drm/radeon/radeon_pm.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/gpu/drm/radeon/radeon_pm.c	2015-12-07 14:47:40.182815232 +0100
@@ -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);
@@ -1219,7 +1222,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 */
@@ -1270,7 +1273,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);
 	}
 }
@@ -1317,7 +1320,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);
 		}
 	}
@@ -1408,7 +1411,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.4/drivers/pci/pci.c linux-4.4-nemo/drivers/pci/pci.c
--- linux-4.4/drivers/pci/pci.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/pci/pci.c	2015-12-07 14:47:40.186815248 +0100
@@ -433,7 +433,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.4/drivers/pci/probe.c linux-4.4-nemo/drivers/pci/probe.c
--- linux-4.4/drivers/pci/probe.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/pci/probe.c	2015-12-07 14:47:40.188815256 +0100
@@ -365,7 +365,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;
@@ -1806,11 +1810,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.4/drivers/rtc/rtc-cmos.c linux-4.4-nemo/drivers/rtc/rtc-cmos.c
--- linux-4.4/drivers/rtc/rtc-cmos.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/drivers/rtc/rtc-cmos.c	2015-12-07 14:47:40.189815260 +0100
@@ -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.4/sound/pci/hda/patch_sigmatel.c linux-4.4-nemo/sound/pci/hda/patch_sigmatel.c
--- linux-4.4/sound/pci/hda/patch_sigmatel.c	2015-12-07 00:43:12.000000000 +0100
+++ linux-4.4-nemo/sound/pci/hda/patch_sigmatel.c	2015-12-07 14:47:40.194815280 +0100
@@ -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,
@@ -1360,6 +1361,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)
@@ -3883,6 +3901,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,
@@ -3939,6 +3961,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" },
 	{}
@@ -3977,6 +4000,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 */
@@ -5036,6 +5061,7 @@ static const struct hda_device_id snd_hd
 	HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
 	HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
 	HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
+	HDA_CODEC_ENTRY(0x83847638, "STAC92HD700", patch_stac927x),
 	HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
 	HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
 	HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
