Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "The MIPS bits for 3.8.  This also includes a bunch fixes that were
  sitting in the linux-mips.org git tree for a long time.  This pull
  request contains updates to several OCTEON drivers and the board
  support code for BCM47XX, BCM63XX, XLP, XLR, XLS, lantiq, Loongson1B,
  updates to the SSB bus support, MIPS kexec code and adds support for
  kdump.

  When pulling this, there are two expected merge conflicts in
  include/linux/bcma/bcma_driver_chipcommon.h which are trivial to
  resolve, just remove the conflict markers and keep both alternatives."

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (90 commits)
  MIPS: PMC-Sierra Yosemite: Remove support.
  VIDEO: Newport Fix console crashes
  MIPS: wrppmc: Fix build of PCI code.
  MIPS: IP22/IP28: Fix build of EISA code.
  MIPS: RB532: Fix build of prom code.
  MIPS: PowerTV: Fix build.
  MIPS: IP27: Correct fucked grammar in ops-bridge.c
  MIPS: Highmem: Fix build error if CONFIG_DEBUG_HIGHMEM is disabled
  MIPS: Fix potencial corruption
  MIPS: Fix for warning from FPU emulation code
  MIPS: Handle COP3 Unusable exception as COP1X for FP emulation
  MIPS: Fix poweroff failure when HOTPLUG_CPU configured.
  MIPS: MT: Fix build with CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
  MIPS: Remove unused smvp.h
  MIPS/EDAC: Improve OCTEON EDAC support.
  MIPS: OCTEON: Add definitions for OCTEON memory contoller registers.
  MIPS: OCTEON: Add OCTEON family definitions to octeon-model.h
  ata: pata_octeon_cf: Use correct byte order for DMA in when built little-endian.
  MIPS/OCTEON/ata: Convert pata_octeon_cf.c to use device tree.
  MIPS: Remove usage of CEVT_R4K_LIB config option.
  ...
diff --git a/MAINTAINERS b/MAINTAINERS
index a6be3e8..ff24a96 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2751,6 +2751,15 @@
 S:	Maintained
 F:	drivers/edac/amd64_edac*
 
+EDAC-CAVIUM
+M:	Ralf Baechle <ralf@linux-mips.org>
+M:	David Daney <david.daney@cavium.com>
+L:	linux-edac@vger.kernel.org
+L:	linux-mips@linux-mips.org
+W:	bluesmoke.sourceforge.net
+S:	Supported
+F:	drivers/edac/octeon_edac*
+
 EDAC-E752X
 M:	Mark Gross <mark.gross@intel.com>
 M:	Doug Thompson <dougthompson@xmission.com>
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4183e62..d971d15 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -19,6 +19,7 @@
 	select HAVE_KRETPROBES
 	select HAVE_DEBUG_KMEMLEAK
 	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	select RTC_LIB if !MACH_LOONGSON
 	select GENERIC_ATOMIC64 if !64BIT
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
@@ -55,8 +56,8 @@
 config MIPS_ALCHEMY
 	bool "Alchemy processor based machines"
 	select 64BIT_PHYS_ADDR
-	select CEVT_R4K_LIB
-	select CSRC_R4K_LIB
+	select CEVT_R4K
+	select CSRC_R4K
 	select IRQ_CPU
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -107,16 +108,16 @@
 
 config BCM47XX
 	bool "Broadcom BCM47XX based boards"
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select CEVT_R4K
 	select CSRC_R4K
 	select DMA_NONCOHERENT
+	select FW_CFE
 	select HW_HAS_PCI
 	select IRQ_CPU
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-	select GENERIC_GPIO
 	select SYS_HAS_EARLY_PRINTK
-	select CFE
 	help
 	 Support for BCM47XX based boards
 
@@ -193,8 +194,8 @@
 
 config MACH_JAZZ
 	bool "Jazz family of machines"
-	select ARC
-	select ARC32
+	select FW_ARC
+	select FW_ARC32
 	select ARCH_MAY_HAVE_PC_FDC
 	select CEVT_R4K
 	select CSRC_R4K
@@ -417,27 +418,6 @@
 	  of integrated peripherals, interfaces and DSPs in addition to
 	  a variety of MIPS cores.
 
-config PMC_YOSEMITE
-	bool "PMC-Sierra Yosemite eval board"
-	select CEVT_R4K
-	select CSRC_R4K
-	select DMA_COHERENT
-	select HW_HAS_PCI
-	select IRQ_CPU
-	select IRQ_CPU_RM7K
-	select IRQ_CPU_RM9K
-	select SWAP_IO_SPACE
-	select SYS_HAS_CPU_RM9000
-	select SYS_HAS_EARLY_PRINTK
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL
-	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_HIGHMEM
-	select SYS_SUPPORTS_SMP
-	help
-	  Yosemite is an evaluation board for the RM9000x2 processor
-	  manufactured by PMC-Sierra.
-
 config POWERTV
 	bool "Cisco PowerTV"
 	select BOOT_ELF32
@@ -458,8 +438,8 @@
 
 config SGI_IP22
 	bool "SGI IP22 (Indy/Indigo2)"
-	select ARC
-	select ARC32
+	select FW_ARC
+	select FW_ARC32
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
@@ -498,8 +478,8 @@
 
 config SGI_IP27
 	bool "SGI IP27 (Origin200/2000)"
-	select ARC
-	select ARC64
+	select FW_ARC
+	select FW_ARC64
 	select BOOT_ELF64
 	select DEFAULT_SGI_PARTITION
 	select DMA_COHERENT
@@ -519,8 +499,8 @@
 config SGI_IP28
 	bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
-	select ARC
-	select ARC64
+	select FW_ARC
+	select FW_ARC64
 	select BOOT_ELF64
 	select CEVT_R4K
 	select CSRC_R4K
@@ -555,8 +535,8 @@
 
 config SGI_IP32
 	bool "SGI IP32 (O2)"
-	select ARC
-	select ARC32
+	select FW_ARC
+	select FW_ARC32
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
@@ -674,8 +654,8 @@
 
 config SNI_RM
 	bool "SNI RM200/300/400"
-	select ARC if CPU_LITTLE_ENDIAN
-	select ARC32 if CPU_LITTLE_ENDIAN
+	select FW_ARC if CPU_LITTLE_ENDIAN
+	select FW_ARC32 if CPU_LITTLE_ENDIAN
 	select SNIPROM if CPU_BIG_ENDIAN
 	select ARCH_MAY_HAVE_PC_FDC
 	select BOOT_ELF32
@@ -776,6 +756,7 @@
 	select DMA_COHERENT
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select EDAC_SUPPORT
 	select SYS_SUPPORTS_HOTPLUG_CPU
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_HAS_CPU_CAVIUM_OCTEON
@@ -819,7 +800,7 @@
 	select CSRC_R4K
 	select IRQ_CPU
 	select ARCH_SUPPORTS_MSI
-	select ZONE_DMA if 64BIT
+	select ZONE_DMA32 if 64BIT
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
 	select USB_ARCH_HAS_OHCI if USB_SUPPORT
@@ -847,7 +828,7 @@
 	select CEVT_R4K
 	select CSRC_R4K
 	select IRQ_CPU
-	select ZONE_DMA if 64BIT
+	select ZONE_DMA32 if 64BIT
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
 	select USE_OF
@@ -908,7 +889,7 @@
 #
 # Select some configuration options automatically based on user selections.
 #
-config ARC
+config FW_ARC
 	bool
 
 config ARCH_MAY_HAVE_PC_FDC
@@ -926,11 +907,7 @@
 config CEVT_GT641XX
 	bool
 
-config CEVT_R4K_LIB
-	bool
-
 config CEVT_R4K
-	select CEVT_R4K_LIB
 	bool
 
 config CEVT_SB1250
@@ -948,11 +925,7 @@
 config CSRC_POWERTV
 	bool
 
-config CSRC_R4K_LIB
-	bool
-
 config CSRC_R4K
-	select CSRC_R4K_LIB
 	bool
 
 config CSRC_SB1250
@@ -963,7 +936,7 @@
 	select ARCH_REQUIRE_GPIOLIB
 	bool
 
-config CFE
+config FW_CFE
 	bool
 
 config ARCH_DMA_ADDR_T_64BIT
@@ -1079,15 +1052,15 @@
 	depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
 	default y
 
+config MIPS_HUGE_TLB_SUPPORT
+	def_bool HUGETLB_PAGE || TRANSPARENT_HUGEPAGE
+
 config IRQ_CPU
 	bool
 
 config IRQ_CPU_RM7K
 	bool
 
-config IRQ_CPU_RM9K
-	bool
-
 config IRQ_MSP_SLP
 	bool
 
@@ -1112,10 +1085,6 @@
 config NO_EXCEPT_FILL
 	bool
 
-config MIPS_RM9122
-	bool
-	select SERIAL_RM9000
-
 config SOC_EMMA2RH
 	bool
 	select CEVT_R4K
@@ -1161,9 +1130,6 @@
 config SWAP_IO_SPACE
 	bool
 
-config SERIAL_RM9000
-	bool
-
 config SGI_HAS_INDYDOG
 	bool
 
@@ -1185,7 +1151,7 @@
 config DEFAULT_SGI_PARTITION
 	bool
 
-config ARC32
+config FW_ARC32
 	bool
 
 config SNIPROM
@@ -1218,7 +1184,7 @@
 	depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
 	default y
 
-config ARC64
+config FW_ARC64
 	bool
 
 config BOOT_ELF64
@@ -1370,6 +1336,7 @@
 	depends on SYS_HAS_CPU_R4X00
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  MIPS Technologies R4000-series processors other than 4300, including
 	  the R4000, R4400, R4600, and 4700.
@@ -1380,12 +1347,14 @@
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 
 config CPU_R5000
 	bool "R5000"
 	depends on SYS_HAS_CPU_R5000
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  MIPS Technologies R5000-series processors other than the Nevada.
 
@@ -1394,6 +1363,7 @@
 	depends on SYS_HAS_CPU_R5432
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 
 config CPU_R5500
 	bool "R5500"
@@ -1419,6 +1389,7 @@
 	depends on SYS_HAS_CPU_NEVADA
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  QED / PMC-Sierra RM52xx-series ("Nevada") processors.
 
@@ -1439,6 +1410,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  MIPS Technologies R10000-series processors.
 
@@ -1449,15 +1421,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
-
-config CPU_RM9000
-	bool "RM9000"
-	depends on SYS_HAS_CPU_RM9000
-	select CPU_HAS_PREFETCH
-	select CPU_SUPPORTS_32BIT_KERNEL
-	select CPU_SUPPORTS_64BIT_KERNEL
-	select CPU_SUPPORTS_HIGHMEM
-	select WEAK_ORDERING
+	select CPU_SUPPORTS_HUGEPAGES
 
 config CPU_SB1
 	bool "SB1"
@@ -1465,6 +1429,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	select WEAK_ORDERING
 
 config CPU_CAVIUM_OCTEON
@@ -1528,9 +1493,9 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	select WEAK_ORDERING
 	select WEAK_REORDERING_BEYOND_LLSC
-	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  Netlogic Microsystems XLR/XLS processors.
 
@@ -1544,6 +1509,7 @@
 	select WEAK_ORDERING
 	select WEAK_REORDERING_BEYOND_LLSC
 	select CPU_HAS_PREFETCH
+	select CPU_MIPSR2
 	help
 	  Netlogic Microsystems XLP processors.
 endchoice
@@ -1591,6 +1557,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 
 config CPU_LOONGSON1
 	bool
@@ -1675,9 +1642,6 @@
 config SYS_HAS_CPU_RM7000
 	bool
 
-config SYS_HAS_CPU_RM9000
-	bool
-
 config SYS_HAS_CPU_SB1
 	bool
 
@@ -1757,7 +1721,7 @@
 	bool
 config MIPS_PGD_C0_CONTEXT
 	bool
-	default y if 64BIT && CPU_MIPSR2
+	default y if 64BIT && CPU_MIPSR2 && !CPU_XLP
 
 #
 # Set to y for ptrace access to watch registers.
@@ -2188,7 +2152,7 @@
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)
+	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
@@ -2366,6 +2330,29 @@
 	  support.  As of this writing the exact hardware interface is
 	  strongly in flux, so no good recommendation can be made.
 
+config CRASH_DUMP
+	  bool "Kernel crash dumps"
+	  help
+	  Generate crash dump after being started by kexec.
+	  This should be normally only set in special crash dump kernels
+	  which are loaded in the main kernel with kexec-tools into
+	  a specially reserved region and then later executed after
+	  a crash by kdump/kexec. The crash dump kernel must be compiled
+	  to a memory address not used by the main kernel or firmware using
+	  PHYSICAL_START.
+
+config PHYSICAL_START
+	  hex "Physical address where the kernel is loaded"
+	  default "0xffffffff84000000" if 64BIT
+	  default "0x84000000" if 32BIT
+	  depends on CRASH_DUMP
+	  help
+	  This gives the CKSEG0 or KSEG0 address where the kernel is loaded.
+	  If you plan to use kernel for capturing the crash dump change
+	  this value to start of the reserved region (the "X" value as
+	  specified in the "crashkernel=YM@XM" command line boot parameter
+	  passed to the panic-ed kernel).
+
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
@@ -2572,6 +2559,8 @@
 
 source "drivers/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/mips/Kconfig.debug"
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 654b1ad..f2dfd40 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -145,8 +145,6 @@
 			-Wa,--trap
 cflags-$(CONFIG_CPU_RM7000)	+= $(call cc-option,-march=rm7000,-march=r5000) \
 			-Wa,--trap
-cflags-$(CONFIG_CPU_RM9000)	+= $(call cc-option,-march=rm9000,-march=r5000) \
-			-Wa,--trap
 cflags-$(CONFIG_CPU_SB1)	+= $(call cc-option,-march=sb1,-march=r5000) \
 			-Wa,--trap
 cflags-$(CONFIG_CPU_R8000)	+= -march=r8000 -Wa,--trap
@@ -173,9 +171,9 @@
 #
 # Firmware support
 #
-libs-$(CONFIG_ARC)		+= arch/mips/fw/arc/
-libs-$(CONFIG_CFE)		+= arch/mips/fw/cfe/
-libs-$(CONFIG_SNIPROM)		+= arch/mips/fw/sni/
+libs-$(CONFIG_FW_ARC)		+= arch/mips/fw/arc/
+libs-$(CONFIG_FW_CFE)		+= arch/mips/fw/cfe/
+libs-$(CONFIG_FW_SNIPROM)	+= arch/mips/fw/sni/
 libs-y				+= arch/mips/fw/lib/
 
 #
@@ -192,6 +190,10 @@
 #
 include $(srctree)/arch/mips/Kbuild.platforms
 
+ifdef CONFIG_PHYSICAL_START
+load-y                                  = $(CONFIG_PHYSICAL_START)
+endif
+
 cflags-y			+= -I$(srctree)/arch/mips/include/asm/mach-generic
 drivers-$(CONFIG_PCI)		+= arch/mips/pci/
 
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 1bbc24b..7477fd21 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -202,8 +202,11 @@
 	.end	= 0x107fffff,
 };
 
+static const char *ar7_probe_types[] = { "ar7part", NULL };
+
 static struct physmap_flash_data physmap_flash_data = {
 	.width	= 2,
+	.part_probe_types = ar7_probe_types,
 };
 
 static struct platform_device physmap_flash = {
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index b311be4..d7af29f 100644
--- a/arch/mips/bcm47xx/Kconfig
+++ b/arch/mips/bcm47xx/Kconfig
@@ -9,6 +9,7 @@
 	select SSB_EMBEDDED
 	select SSB_B43_PCI_BRIDGE if PCI
 	select SSB_PCICORE_HOSTMODE if PCI
+	select SSB_DRIVER_GPIO
 	default y
 	help
 	 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@@ -23,6 +24,7 @@
 	select BCMA_DRIVER_MIPS
 	select BCMA_HOST_PCI if PCI
 	select BCMA_DRIVER_PCI_HOSTMODE if PCI
+	select BCMA_DRIVER_GPIO
 	default y
 	help
 	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index 4389de1..1a3567f 100644
--- a/arch/mips/bcm47xx/Makefile
+++ b/arch/mips/bcm47xx/Makefile
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
+obj-y 				+= irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
 obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
deleted file mode 100644
index 5ebdf62..0000000
--- a/arch/mips/bcm47xx/gpio.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
- */
-
-#include <linux/export.h>
-#include <linux/ssb/ssb.h>
-#include <linux/ssb/ssb_driver_chipcommon.h>
-#include <linux/ssb/ssb_driver_extif.h>
-#include <asm/mach-bcm47xx/bcm47xx.h>
-#include <asm/mach-bcm47xx/gpio.h>
-
-#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
-static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
-#else
-static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
-#endif
-
-int gpio_request(unsigned gpio, const char *tag)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
-		    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-			return -EINVAL;
-
-		if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
-		    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-			return -EINVAL;
-
-		if (test_and_set_bit(gpio, gpio_in_use))
-			return -EBUSY;
-
-		return 0;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
-			return -EINVAL;
-
-		if (test_and_set_bit(gpio, gpio_in_use))
-			return -EBUSY;
-
-		return 0;
-#endif
-	}
-	return -EINVAL;
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned gpio)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
-		    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-			return;
-
-		if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
-		    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-			return;
-
-		clear_bit(gpio, gpio_in_use);
-		return;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
-			return;
-
-		clear_bit(gpio, gpio_in_use);
-		return;
-#endif
-	}
-}
-EXPORT_SYMBOL(gpio_free);
-
-int gpio_to_irq(unsigned gpio)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
-			return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
-		else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
-			return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
-		else
-			return -EINVAL;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
-#endif
-	}
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(gpio_to_irq);
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index f6e9063..8c155af 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
  *  Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -27,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/smp.h>
 #include <asm/bootinfo.h>
 #include <asm/fw/cfe/cfe_api.h>
 #include <asm/fw/cfe/cfe_error.h>
@@ -127,6 +129,8 @@
 {
 	unsigned long mem;
 	unsigned long max;
+	unsigned long off;
+	struct cpuinfo_mips *c = &current_cpu_data;
 
 	/* Figure out memory size by finding aliases.
 	 *
@@ -143,18 +147,26 @@
 	 * max contains the biggest possible address supported by the platform.
 	 * If the method wants to try something above we assume 128MB ram.
 	 */
-	max = ((unsigned long)(prom_init) | ((128 << 20) - 1));
+	off = (unsigned long)prom_init;
+	max = off | ((128 << 20) - 1);
 	for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
-		if (((unsigned long)(prom_init) + mem) > max) {
+		if ((off + mem) > max) {
 			mem = (128 << 20);
 			printk(KERN_DEBUG "assume 128MB RAM\n");
 			break;
 		}
-		if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
-		    *(unsigned long *)(prom_init))
+		if (!memcmp(prom_init, prom_init + mem, 32))
 			break;
 	}
 
+	/* Ignoring the last page when ddr size is 128M. Cached
+	 * accesses to last page is causing the processor to prefetch
+	 * using address above 128M stepping out of the ddr address
+	 * space.
+	 */
+	if (c->cputype == CPU_74K && (mem == (128  << 20)))
+		mem -= 0x1000;
+
 	add_memory_region(0, mem, BOOT_MEM_RAM);
 }
 
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 95bf4d7..4d54b58 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -94,7 +94,7 @@
 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 			 bus->host_pci->bus->number + 1,
 			 PCI_SLOT(bus->host_pci->devfn));
-		bcm47xx_fill_sprom(out, prefix);
+		bcm47xx_fill_sprom(out, prefix, false);
 		return 0;
 	} else {
 		printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
@@ -113,7 +113,7 @@
 	bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
 
 	memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
-	bcm47xx_fill_sprom(&iv->sprom, NULL);
+	bcm47xx_fill_sprom(&iv->sprom, NULL, false);
 
 	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
@@ -165,16 +165,17 @@
 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 			 bus->host_pci->bus->number + 1,
 			 PCI_SLOT(bus->host_pci->devfn));
-		bcm47xx_fill_sprom(out, prefix);
+		bcm47xx_fill_sprom(out, prefix, false);
 		return 0;
 	case BCMA_HOSTTYPE_SOC:
 		memset(out, 0, sizeof(struct ssb_sprom));
-		bcm47xx_fill_sprom_ethernet(out, NULL);
 		core = bcma_find_core(bus, BCMA_CORE_80211);
 		if (core) {
 			snprintf(prefix, sizeof(prefix), "sb/%u/",
 				 core->core_index);
-			bcm47xx_fill_sprom(out, prefix);
+			bcm47xx_fill_sprom(out, prefix, true);
+		} else {
+			bcm47xx_fill_sprom(out, NULL, false);
 		}
 		return 0;
 	default:
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index d3a8897..289cc0a 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -42,25 +42,39 @@
 		snprintf(buf, len, "%s", name);
 }
 
+static int get_nvram_var(const char *prefix, const char *postfix,
+			 const char *name, char *buf, int len, bool fallback)
+{
+	char key[40];
+	int err;
+
+	create_key(prefix, postfix, name, key, sizeof(key));
+
+	err = nvram_getenv(key, buf, len);
+	if (fallback && err == NVRAM_ERR_ENVNOTFOUND && prefix) {
+		create_key(NULL, postfix, name, key, sizeof(key));
+		err = nvram_getenv(key, buf, len);
+	}
+	return err;
+}
+
 #define NVRAM_READ_VAL(type)						\
 static void nvram_read_ ## type (const char *prefix,			\
 				 const char *postfix, const char *name,	\
-				 type *val, type allset)		\
+				 type *val, type allset, bool fallback)	\
 {									\
 	char buf[100];							\
-	char key[40];							\
 	int err;							\
 	type var;							\
 									\
-	create_key(prefix, postfix, name, key, sizeof(key));		\
-									\
-	err = nvram_getenv(key, buf, sizeof(buf));			\
+	err = get_nvram_var(prefix, postfix, name, buf, sizeof(buf),	\
+			    fallback);					\
 	if (err < 0)							\
 		return;							\
 	err = kstrto ## type (buf, 0, &var);				\
 	if (err) {							\
-		pr_warn("can not parse nvram name %s with value %s"	\
-			" got %i", key, buf, err);			\
+		pr_warn("can not parse nvram name %s%s%s with value %s got %i\n",	\
+			prefix, name, postfix, buf, err);		\
 		return;							\
 	}								\
 	if (allset && var == allset)					\
@@ -76,22 +90,19 @@
 #undef NVRAM_READ_VAL
 
 static void nvram_read_u32_2(const char *prefix, const char *name,
-			     u16 *val_lo, u16 *val_hi)
+			     u16 *val_lo, u16 *val_hi, bool fallback)
 {
 	char buf[100];
-	char key[40];
 	int err;
 	u32 val;
 
-	create_key(prefix, NULL, name, key, sizeof(key));
-
-	err = nvram_getenv(key, buf, sizeof(buf));
+	err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
 	if (err < 0)
 		return;
 	err = kstrtou32(buf, 0, &val);
 	if (err) {
-		pr_warn("can not parse nvram name %s with value %s got %i",
-			key, buf, err);
+		pr_warn("can not parse nvram name %s%s with value %s got %i\n",
+			prefix, name, buf, err);
 		return;
 	}
 	*val_lo = (val & 0x0000FFFFU);
@@ -99,22 +110,20 @@
 }
 
 static void nvram_read_leddc(const char *prefix, const char *name,
-			     u8 *leddc_on_time, u8 *leddc_off_time)
+			     u8 *leddc_on_time, u8 *leddc_off_time,
+			     bool fallback)
 {
 	char buf[100];
-	char key[40];
 	int err;
 	u32 val;
 
-	create_key(prefix, NULL, name, key, sizeof(key));
-
-	err = nvram_getenv(key, buf, sizeof(buf));
+	err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
 	if (err < 0)
 		return;
 	err = kstrtou32(buf, 0, &val);
 	if (err) {
-		pr_warn("can not parse nvram name %s with value %s got %i",
-			key, buf, err);
+		pr_warn("can not parse nvram name %s%s with value %s got %i\n",
+			prefix, name, buf, err);
 		return;
 	}
 
@@ -126,355 +135,435 @@
 }
 
 static void nvram_read_macaddr(const char *prefix, const char *name,
-			       u8 (*val)[6])
+			       u8 (*val)[6], bool fallback)
 {
 	char buf[100];
-	char key[40];
 	int err;
 
-	create_key(prefix, NULL, name, key, sizeof(key));
-
-	err = nvram_getenv(key, buf, sizeof(buf));
+	err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
 	if (err < 0)
 		return;
+
 	nvram_parse_macaddr(buf, *val);
 }
 
 static void nvram_read_alpha2(const char *prefix, const char *name,
-			     char (*val)[2])
+			     char (*val)[2], bool fallback)
 {
 	char buf[10];
-	char key[40];
 	int err;
 
-	create_key(prefix, NULL, name, key, sizeof(key));
-
-	err = nvram_getenv(key, buf, sizeof(buf));
+	err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
 	if (err < 0)
 		return;
 	if (buf[0] == '0')
 		return;
 	if (strlen(buf) > 2) {
-		pr_warn("alpha2 is too long %s", buf);
+		pr_warn("alpha2 is too long %s\n", buf);
 		return;
 	}
 	memcpy(val, buf, sizeof(val));
 }
 
 static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
-					const char *prefix)
+					const char *prefix, bool fallback)
 {
-	nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0);
-	if (!sprom->board_rev)
-		nvram_read_u16(NULL, NULL, "boardrev", &sprom->board_rev, 0);
-	nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0);
-	nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff);
-	nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff);
-	nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff);
-	nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff);
-	nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0);
-	nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0);
-	nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0);
-	nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0);
-	nvram_read_alpha2(prefix, "ccode", &sprom->alpha2);
+	nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback);
+	nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback);
+	nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback);
+	nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff, fallback);
+	nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0,
+		      fallback);
+	nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0,
+		      fallback);
+	nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0,
+		      fallback);
+	nvram_read_alpha2(prefix, "ccode", &sprom->alpha2, fallback);
 }
 
 static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
-				      const char *prefix)
+				      const char *prefix, bool fallback)
 {
-	nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0);
-	nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0);
-	nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0);
-	nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0);
-	nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0);
-	nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0);
-	nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0);
-	nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0);
-	nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0);
-	nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0);
+	nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0, fallback);
+	nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0, fallback);
+	nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0,
+		      fallback);
+	nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0, fallback);
+	nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0, fallback);
+	nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0, fallback);
 }
 
-static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix,
+				  bool fallback)
 {
-	nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0);
-	nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0);
+	nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0,
+		       fallback);
+	nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0, fallback);
 }
 
 static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom,
-				     const char *prefix)
+				     const char *prefix, bool fallback)
 {
-	nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0);
-	nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0);
-	nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0);
-	nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0);
-	nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0);
-	nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0);
-	nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0);
-	nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0);
-	nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0);
+	nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0, fallback);
+	nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0, fallback);
+	nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0,
+		      fallback);
 }
 
-static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix,
+				    bool fallback)
 {
-	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
-			 &sprom->boardflags_hi);
-	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+	nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0, fallback);
+	nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0, fallback);
+	nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0, fallback);
+	nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0, fallback);
 }
 
-static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix,
+				  bool fallback)
 {
-	nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0);
-	nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0);
-	nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0);
-	nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0);
-	nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0);
-	nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0);
-	nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0);
-	nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0);
-	nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0);
-	nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0);
-	nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0);
-	nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0);
-	nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0);
-	nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0);
-}
-
-static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix)
-{
-	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
-			 &sprom->boardflags_hi);
-	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
-	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
+	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
 	nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
-			 &sprom->leddc_off_time);
+			 &sprom->leddc_off_time, fallback);
 }
 
 static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
-				     const char *prefix)
+				     const char *prefix, bool fallback)
 {
-	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
-			 &sprom->boardflags_hi);
-	nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
-			 &sprom->boardflags2_hi);
-	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
-	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
-	nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0);
-	nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0);
-	nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf);
-	nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf);
-	nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff);
+	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
+	nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0,
+		      fallback);
+	nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf, fallback);
+	nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf, fallback);
+	nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff,
+		      fallback);
 	nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
-			 &sprom->leddc_off_time);
+			 &sprom->leddc_off_time, fallback);
 }
 
-static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix,
+				    bool fallback)
 {
-	nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0);
-	nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0);
-	nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0);
-	nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0);
-	nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0);
-	nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0);
-	nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0);
-	nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0);
-	nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0);
-	nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0);
-	nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0);
-	nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0);
-	nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0);
+	nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0, fallback);
+	nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0, fallback);
+	nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0, fallback);
+	nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0, fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0,
+		       fallback);
 }
 
-static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix,
+				   bool fallback)
 {
-	nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0);
-	nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0);
-	nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0);
-	nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0);
-	nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0);
-	nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0);
-	nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0);
-	nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0);
-	nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0);
+	nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0,
+		      fallback);
 }
 
-static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix,
+				   bool fallback)
 {
-	nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0);
+	nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "extpagain2g",
-		      &sprom->fem.ghz2.extpa_gain, 0);
+		      &sprom->fem.ghz2.extpa_gain, 0, fallback);
 	nvram_read_u8(prefix, NULL, "pdetrange2g",
-		      &sprom->fem.ghz2.pdet_range, 0);
-	nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0);
-	nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0);
-	nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0);
+		      &sprom->fem.ghz2.pdet_range, 0, fallback);
+	nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "extpagain5g",
-		      &sprom->fem.ghz5.extpa_gain, 0);
+		      &sprom->fem.ghz5.extpa_gain, 0, fallback);
 	nvram_read_u8(prefix, NULL, "pdetrange5g",
-		      &sprom->fem.ghz5.pdet_range, 0);
-	nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0);
-	nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0);
-	nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0);
-	nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0);
-	nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0);
-	nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0);
+		      &sprom->fem.ghz5.pdet_range, 0, fallback);
+	nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0,
+		      fallback);
+	nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0,
+		       fallback);
+	nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "tempsense_slope",
-		      &sprom->tempsense_slope, 0);
-	nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0);
+		      &sprom->tempsense_slope, 0, fallback);
+	nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0,
+		       fallback);
 	nvram_read_u8(prefix, NULL, "tempsense_option",
-		      &sprom->tempsense_option, 0);
+		      &sprom->tempsense_option, 0, fallback);
 	nvram_read_u8(prefix, NULL, "freqoffset_corr",
-		      &sprom->freqoffset_corr, 0);
-	nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0);
-	nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0);
-	nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0);
-	nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0);
+		      &sprom->freqoffset_corr, 0, fallback);
+	nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0, fallback);
 	nvram_read_u8(prefix, NULL, "phycal_tempdelta",
-		      &sprom->phycal_tempdelta, 0);
-	nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0);
+		      &sprom->phycal_tempdelta, 0, fallback);
+	nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "temps_hysteresis",
-		      &sprom->temps_hysteresis, 0);
-	nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0);
-	nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0);
+		      &sprom->temps_hysteresis, 0, fallback);
+	nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr2ga0",
-		      &sprom->rxgainerr2ga[0], 0);
+		      &sprom->rxgainerr2ga[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr2ga1",
-		      &sprom->rxgainerr2ga[1], 0);
+		      &sprom->rxgainerr2ga[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr2ga2",
-		      &sprom->rxgainerr2ga[2], 0);
+		      &sprom->rxgainerr2ga[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gla0",
-		      &sprom->rxgainerr5gla[0], 0);
+		      &sprom->rxgainerr5gla[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gla1",
-		      &sprom->rxgainerr5gla[1], 0);
+		      &sprom->rxgainerr5gla[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gla2",
-		      &sprom->rxgainerr5gla[2], 0);
+		      &sprom->rxgainerr5gla[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gma0",
-		      &sprom->rxgainerr5gma[0], 0);
+		      &sprom->rxgainerr5gma[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gma1",
-		      &sprom->rxgainerr5gma[1], 0);
+		      &sprom->rxgainerr5gma[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gma2",
-		      &sprom->rxgainerr5gma[2], 0);
+		      &sprom->rxgainerr5gma[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gha0",
-		      &sprom->rxgainerr5gha[0], 0);
+		      &sprom->rxgainerr5gha[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gha1",
-		      &sprom->rxgainerr5gha[1], 0);
+		      &sprom->rxgainerr5gha[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gha2",
-		      &sprom->rxgainerr5gha[2], 0);
+		      &sprom->rxgainerr5gha[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gua0",
-		      &sprom->rxgainerr5gua[0], 0);
+		      &sprom->rxgainerr5gua[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gua1",
-		      &sprom->rxgainerr5gua[1], 0);
+		      &sprom->rxgainerr5gua[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "rxgainerr5gua2",
-		      &sprom->rxgainerr5gua[2], 0);
-	nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0);
-	nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0);
-	nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0);
+		      &sprom->rxgainerr5gua[2], 0, fallback);
+	nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0,
+		      fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gla0",
-		      &sprom->noiselvl5gla[0], 0);
+		      &sprom->noiselvl5gla[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gla1",
-		      &sprom->noiselvl5gla[1], 0);
+		      &sprom->noiselvl5gla[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gla2",
-		      &sprom->noiselvl5gla[2], 0);
+		      &sprom->noiselvl5gla[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gma0",
-		      &sprom->noiselvl5gma[0], 0);
+		      &sprom->noiselvl5gma[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gma1",
-		      &sprom->noiselvl5gma[1], 0);
+		      &sprom->noiselvl5gma[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gma2",
-		      &sprom->noiselvl5gma[2], 0);
+		      &sprom->noiselvl5gma[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gha0",
-		      &sprom->noiselvl5gha[0], 0);
+		      &sprom->noiselvl5gha[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gha1",
-		      &sprom->noiselvl5gha[1], 0);
+		      &sprom->noiselvl5gha[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gha2",
-		      &sprom->noiselvl5gha[2], 0);
+		      &sprom->noiselvl5gha[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gua0",
-		      &sprom->noiselvl5gua[0], 0);
+		      &sprom->noiselvl5gua[0], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gua1",
-		      &sprom->noiselvl5gua[1], 0);
+		      &sprom->noiselvl5gua[1], 0, fallback);
 	nvram_read_u8(prefix, NULL, "noiselvl5gua2",
-		      &sprom->noiselvl5gua[2], 0);
+		      &sprom->noiselvl5gua[2], 0, fallback);
 	nvram_read_u8(prefix, NULL, "pcieingress_war",
-		      &sprom->pcieingress_war, 0);
+		      &sprom->pcieingress_war, 0, fallback);
 }
 
-static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix,
+				  bool fallback)
 {
-	nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0);
-	nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0);
+	nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0,
+		       fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw202gpo",
-		       &sprom->legofdmbw202gpo, 0);
+		       &sprom->legofdmbw202gpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo",
-		       &sprom->legofdmbw20ul2gpo, 0);
+		       &sprom->legofdmbw20ul2gpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw205glpo",
-		       &sprom->legofdmbw205glpo, 0);
+		       &sprom->legofdmbw205glpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo",
-		       &sprom->legofdmbw20ul5glpo, 0);
+		       &sprom->legofdmbw20ul5glpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw205gmpo",
-		       &sprom->legofdmbw205gmpo, 0);
+		       &sprom->legofdmbw205gmpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo",
-		       &sprom->legofdmbw20ul5gmpo, 0);
+		       &sprom->legofdmbw20ul5gmpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw205ghpo",
-		       &sprom->legofdmbw205ghpo, 0);
+		       &sprom->legofdmbw205ghpo, 0, fallback);
 	nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo",
-		       &sprom->legofdmbw20ul5ghpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0);
+		       &sprom->legofdmbw20ul5ghpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0,
+		       fallback);
 	nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo",
-		       &sprom->mcsbw20ul5glpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0);
+		       &sprom->mcsbw20ul5glpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0,
+		       fallback);
 	nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo",
-		       &sprom->mcsbw20ul5gmpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0);
+		       &sprom->mcsbw20ul5gmpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0,
+		       fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0,
+		       fallback);
 	nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo",
-		       &sprom->mcsbw20ul5ghpo, 0);
-	nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0);
-	nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0);
+		       &sprom->mcsbw20ul5ghpo, 0, fallback);
+	nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0, fallback);
 	nvram_read_u16(prefix, NULL, "legofdm40duppo",
-		       &sprom->legofdm40duppo, 0);
-	nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0);
-	nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0);
+		       &sprom->legofdm40duppo, 0, fallback);
+	nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0, fallback);
+	nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0, fallback);
 }
 
 static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
-					  const char *prefix)
+					  const char *prefix, bool fallback)
 {
 	char postfix[2];
 	int i;
@@ -483,46 +572,46 @@
 		struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
 		snprintf(postfix, sizeof(postfix), "%i", i);
 		nvram_read_u8(prefix, postfix, "maxp2ga",
-			      &pwr_info->maxpwr_2g, 0);
+			      &pwr_info->maxpwr_2g, 0, fallback);
 		nvram_read_u8(prefix, postfix, "itt2ga",
-			      &pwr_info->itssi_2g, 0);
+			      &pwr_info->itssi_2g, 0, fallback);
 		nvram_read_u8(prefix, postfix, "itt5ga",
-			      &pwr_info->itssi_5g, 0);
+			      &pwr_info->itssi_5g, 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa2gw0a",
-			       &pwr_info->pa_2g[0], 0);
+			       &pwr_info->pa_2g[0], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa2gw1a",
-			       &pwr_info->pa_2g[1], 0);
+			       &pwr_info->pa_2g[1], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa2gw2a",
-			       &pwr_info->pa_2g[2], 0);
+			       &pwr_info->pa_2g[2], 0, fallback);
 		nvram_read_u8(prefix, postfix, "maxp5ga",
-			      &pwr_info->maxpwr_5g, 0);
+			      &pwr_info->maxpwr_5g, 0, fallback);
 		nvram_read_u8(prefix, postfix, "maxp5gha",
-			      &pwr_info->maxpwr_5gh, 0);
+			      &pwr_info->maxpwr_5gh, 0, fallback);
 		nvram_read_u8(prefix, postfix, "maxp5gla",
-			      &pwr_info->maxpwr_5gl, 0);
+			      &pwr_info->maxpwr_5gl, 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5gw0a",
-			       &pwr_info->pa_5g[0], 0);
+			       &pwr_info->pa_5g[0], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5gw1a",
-			       &pwr_info->pa_5g[1], 0);
+			       &pwr_info->pa_5g[1], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5gw2a",
-			       &pwr_info->pa_5g[2], 0);
+			       &pwr_info->pa_5g[2], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5glw0a",
-			       &pwr_info->pa_5gl[0], 0);
+			       &pwr_info->pa_5gl[0], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5glw1a",
-			       &pwr_info->pa_5gl[1], 0);
+			       &pwr_info->pa_5gl[1], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5glw2a",
-			       &pwr_info->pa_5gl[2], 0);
+			       &pwr_info->pa_5gl[2], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5ghw0a",
-			       &pwr_info->pa_5gh[0], 0);
+			       &pwr_info->pa_5gh[0], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5ghw1a",
-			       &pwr_info->pa_5gh[1], 0);
+			       &pwr_info->pa_5gh[1], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5ghw2a",
-			       &pwr_info->pa_5gh[2], 0);
+			       &pwr_info->pa_5gh[2], 0, fallback);
 	}
 }
 
 static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
-					const char *prefix)
+					const char *prefix, bool fallback)
 {
 	char postfix[2];
 	int i;
@@ -531,91 +620,112 @@
 		struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
 		snprintf(postfix, sizeof(postfix), "%i", i);
 		nvram_read_u16(prefix, postfix, "pa2gw3a",
-			       &pwr_info->pa_2g[3], 0);
+			       &pwr_info->pa_2g[3], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5gw3a",
-			       &pwr_info->pa_5g[3], 0);
+			       &pwr_info->pa_5g[3], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5glw3a",
-			       &pwr_info->pa_5gl[3], 0);
+			       &pwr_info->pa_5gl[3], 0, fallback);
 		nvram_read_u16(prefix, postfix, "pa5ghw3a",
-			       &pwr_info->pa_5gh[3], 0);
+			       &pwr_info->pa_5gh[3], 0, fallback);
 	}
 }
 
-void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
+					const char *prefix, bool fallback)
 {
-	nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac);
-	nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0);
-	nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0);
+	nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac, fallback);
+	nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0,
+		      fallback);
 
-	nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac);
-	nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0);
-	nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0);
+	nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac, fallback);
+	nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0,
+		      fallback);
+	nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0,
+		      fallback);
 
-	nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac);
-	nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac);
+	nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac, fallback);
+	nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac, fallback);
 }
 
-void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
+static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
+				    bool fallback)
 {
-	bcm47xx_fill_sprom_ethernet(sprom, prefix);
+	nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0,
+		       fallback);
+	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0,
+		       fallback);
+	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+			 &sprom->boardflags_hi, fallback);
+	nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
+			 &sprom->boardflags2_hi, fallback);
+}
 
-	nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0);
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
+			bool fallback)
+{
+	bcm47xx_fill_sprom_ethernet(sprom, prefix, fallback);
+	bcm47xx_fill_board_data(sprom, prefix, fallback);
+
+	nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback);
 
 	switch (sprom->revision) {
 	case 1:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r1(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
 		break;
 	case 2:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r2389(sprom, prefix);
-		bcm47xx_fill_sprom_r2(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
 		break;
 	case 3:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r2389(sprom, prefix);
-		bcm47xx_fill_sprom_r389(sprom, prefix);
-		bcm47xx_fill_sprom_r3(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r3(sprom, prefix, fallback);
 		break;
 	case 4:
 	case 5:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r4589(sprom, prefix);
-		bcm47xx_fill_sprom_r458(sprom, prefix);
-		bcm47xx_fill_sprom_r45(sprom, prefix);
-		bcm47xx_fill_sprom_path_r4589(sprom, prefix);
-		bcm47xx_fill_sprom_path_r45(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r45(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback);
 		break;
 	case 8:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r2389(sprom, prefix);
-		bcm47xx_fill_sprom_r389(sprom, prefix);
-		bcm47xx_fill_sprom_r4589(sprom, prefix);
-		bcm47xx_fill_sprom_r458(sprom, prefix);
-		bcm47xx_fill_sprom_r89(sprom, prefix);
-		bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
 		break;
 	case 9:
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r2389(sprom, prefix);
-		bcm47xx_fill_sprom_r389(sprom, prefix);
-		bcm47xx_fill_sprom_r4589(sprom, prefix);
-		bcm47xx_fill_sprom_r89(sprom, prefix);
-		bcm47xx_fill_sprom_r9(sprom, prefix);
-		bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r9(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
 		break;
 	default:
 		pr_warn("Unsupported SPROM revision %d detected. Will extract"
 			" v1\n", sprom->revision);
 		sprom->revision = 1;
-		bcm47xx_fill_sprom_r1234589(sprom, prefix);
-		bcm47xx_fill_sprom_r12389(sprom, prefix);
-		bcm47xx_fill_sprom_r1(sprom, prefix);
+		bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
+		bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
 	}
 }
 
@@ -623,11 +733,12 @@
 void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
 				const char *prefix)
 {
-	nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0);
+	nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
+		       true);
 	if (!boardinfo->vendor)
 		boardinfo->vendor = SSB_BOARDVENDOR_BCM;
 
-	nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0);
+	nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
 }
 #endif
 
@@ -635,10 +746,11 @@
 void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
 				 const char *prefix)
 {
-	nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0);
+	nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
+		       true);
 	if (!boardinfo->vendor)
 		boardinfo->vendor = SSB_BOARDVENDOR_BCM;
 
-	nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0);
+	nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
 }
 #endif
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
index e80d585..9d111e8 100644
--- a/arch/mips/bcm47xx/wgt634u.c
+++ b/arch/mips/bcm47xx/wgt634u.c
@@ -11,6 +11,7 @@
 #include <linux/leds.h>
 #include <linux/mtd/physmap.h>
 #include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_embedded.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/gpio.h>
@@ -116,7 +117,8 @@
 
 	/* Interrupt are level triggered, revert the interrupt polarity
 	   to clear the interrupt. */
-	gpio_polarity(WGT634U_GPIO_RESET, state);
+	ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << WGT634U_GPIO_RESET,
+			  state ? 1 << WGT634U_GPIO_RESET : 0);
 
 	if (!state) {
 		printk(KERN_INFO "Reset button pressed");
@@ -150,7 +152,9 @@
 				 gpio_interrupt, IRQF_SHARED,
 				 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
 			gpio_direction_input(WGT634U_GPIO_RESET);
-			gpio_intmask(WGT634U_GPIO_RESET, 1);
+			ssb_gpio_intmask(&bcm47xx_bus.ssb,
+					 1 << WGT634U_GPIO_RESET,
+					 1 << WGT634U_GPIO_RESET);
 			ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
 					    SSB_CHIPCO_IRQ_GPIO,
 					    SSB_CHIPCO_IRQ_GPIO);
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 9bbb30a..ac28073 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,7 @@
-obj-y		+= clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
-		   dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
-		   dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o
+obj-y		+= clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
+		   setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
+		   dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
+		   dev-usb-usbd.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-y		+= boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 1cd4d73..73be9b3 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -18,6 +18,7 @@
 #include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
+#include <bcm63xx_nvram.h>
 #include <bcm63xx_dev_pci.h>
 #include <bcm63xx_dev_enet.h>
 #include <bcm63xx_dev_dsp.h>
@@ -29,8 +30,6 @@
 
 #define PFX	"board_bcm963xx: "
 
-static struct bcm963xx_nvram nvram;
-static unsigned int mac_addr_used;
 static struct board_info board;
 
 /*
@@ -716,50 +715,14 @@
 }
 
 /*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-	u8 *oui;
-	int count;
-
-	if (mac_addr_used >= nvram.mac_addr_count) {
-		printk(KERN_ERR PFX "not enough mac address\n");
-		return -ENODEV;
-	}
-
-	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-	oui = mac + ETH_ALEN/2 - 1;
-	count = mac_addr_used;
-
-	while (count--) {
-		u8 *p = mac + ETH_ALEN - 1;
-
-		do {
-			(*p)++;
-			if (*p != 0)
-				break;
-			p--;
-		} while (p != oui);
-
-		if (p == oui) {
-			printk(KERN_ERR PFX "unable to fetch mac address\n");
-			return -ENODEV;
-		}
-	}
-
-	mac_addr_used++;
-	return 0;
-}
-
-/*
  * early init callback, read nvram data from flash and checksum it
  */
 void __init board_prom_init(void)
 {
-	unsigned int check_len, i;
-	u8 *boot_addr, *cfe, *p;
+	unsigned int i;
+	u8 *boot_addr, *cfe;
 	char cfe_version[32];
+	char *board_name;
 	u32 val;
 
 	/* read base address of boot chip select (0)
@@ -782,27 +745,15 @@
 		strcpy(cfe_version, "unknown");
 	printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
 
-	/* extract nvram data */
-	memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
-
-	/* check checksum before using data */
-	if (nvram.version <= 4)
-		check_len = offsetof(struct bcm963xx_nvram, checksum_old);
-	else
-		check_len = sizeof(nvram);
-	val = 0;
-	p = (u8 *)&nvram;
-	while (check_len--)
-		val += *p;
-	if (val) {
+	if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
 		printk(KERN_ERR PFX "invalid nvram checksum\n");
 		return;
 	}
 
+	board_name = bcm63xx_nvram_get_name();
 	/* find board by name */
 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
-		if (strncmp(nvram.name, bcm963xx_boards[i]->name,
-			    sizeof(nvram.name)))
+		if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
 			continue;
 		/* copy, board desc array is marked initdata */
 		memcpy(&board, bcm963xx_boards[i], sizeof(board));
@@ -812,7 +763,7 @@
 	/* bail out if board is not found, will complain later */
 	if (!board.name[0]) {
 		char name[17];
-		memcpy(name, nvram.name, 16);
+		memcpy(name, board_name, 16);
 		name[16] = 0;
 		printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
 		       name);
@@ -890,11 +841,11 @@
 		bcm63xx_pcmcia_register();
 
 	if (board.has_enet0 &&
-	    !board_get_mac_address(board.enet0.mac_addr))
+	    !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
 		bcm63xx_enet_register(0, &board.enet0);
 
 	if (board.has_enet1 &&
-	    !board_get_mac_address(board.enet1.mac_addr))
+	    !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
 		bcm63xx_enet_register(1, &board.enet1);
 
 	if (board.has_usbd)
@@ -907,7 +858,7 @@
 	 * do this after registering enet devices
 	 */
 #ifdef CONFIG_SSB_PCIHOST
-	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+	if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
 		if (ssb_arch_register_fallback_sprom(
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index dff79ab..b9e948d 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -14,6 +14,7 @@
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_regs.h>
+#include <bcm63xx_reset.h>
 #include <bcm63xx_clk.h>
 
 static DEFINE_MUTEX(clocks_mutex);
@@ -124,15 +125,10 @@
 			CKCTL_6368_SWPKT_USB_EN |
 			CKCTL_6368_SWPKT_SAR_EN, enable);
 	if (enable) {
-		u32 val;
-
 		/* reset switch core afer clock change */
-		val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
-		val &= ~SOFTRESET_6368_ENETSW_MASK;
-		bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
 		msleep(10);
-		val |= SOFTRESET_6368_ENETSW_MASK;
-		bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+		bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
 		msleep(10);
 	}
 }
@@ -222,15 +218,10 @@
 			CKCTL_6368_SWPKT_SAR_EN, enable);
 
 	if (enable) {
-		u32 val;
-
 		/* reset sar core afer clock change */
-		val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
-		val &= ~SOFTRESET_6368_SAR_MASK;
-		bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
 		mdelay(1);
-		val |= SOFTRESET_6368_SAR_MASK;
-		bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+		bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
 		mdelay(1);
 	}
 }
@@ -253,6 +244,19 @@
 };
 
 /*
+ * PCIe clock
+ */
+
+static void pcie_set(struct clk *clk, int enable)
+{
+	bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
+}
+
+static struct clk clk_pcie = {
+	.set	= pcie_set,
+};
+
+/*
  * Internal peripheral clock
  */
 static struct clk clk_periph = {
@@ -313,6 +317,8 @@
 		return &clk_pcm;
 	if (BCMCPU_IS_6368() && !strcmp(id, "ipsec"))
 		return &clk_ipsec;
+	if (BCMCPU_IS_6328() && !strcmp(id, "pcie"))
+		return &clk_pcie;
 	return ERR_PTR(-ENOENT);
 }
 
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c
new file mode 100644
index 0000000..6206116
--- /dev/null
+++ b/arch/mips/bcm63xx/nvram.c
@@ -0,0 +1,107 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
+
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/if_ether.h>
+
+#include <bcm63xx_nvram.h>
+
+/*
+ * nvram structure
+ */
+struct bcm963xx_nvram {
+	u32	version;
+	u8	reserved1[256];
+	u8	name[16];
+	u32	main_tp_number;
+	u32	psi_size;
+	u32	mac_addr_count;
+	u8	mac_addr_base[ETH_ALEN];
+	u8	reserved2[2];
+	u32	checksum_old;
+	u8	reserved3[720];
+	u32	checksum_high;
+};
+
+static struct bcm963xx_nvram nvram;
+static int mac_addr_used;
+
+int __init bcm63xx_nvram_init(void *addr)
+{
+	unsigned int check_len;
+	u32 crc, expected_crc;
+
+	/* extract nvram data */
+	memcpy(&nvram, addr, sizeof(nvram));
+
+	/* check checksum before using data */
+	if (nvram.version <= 4) {
+		check_len = offsetof(struct bcm963xx_nvram, reserved3);
+		expected_crc = nvram.checksum_old;
+		nvram.checksum_old = 0;
+	} else {
+		check_len = sizeof(nvram);
+		expected_crc = nvram.checksum_high;
+		nvram.checksum_high = 0;
+	}
+
+	crc = crc32_le(~0, (u8 *)&nvram, check_len);
+
+	if (crc != expected_crc)
+		return -EINVAL;
+
+	return 0;
+}
+
+u8 *bcm63xx_nvram_get_name(void)
+{
+	return nvram.name;
+}
+EXPORT_SYMBOL(bcm63xx_nvram_get_name);
+
+int bcm63xx_nvram_get_mac_address(u8 *mac)
+{
+	u8 *oui;
+	int count;
+
+	if (mac_addr_used >= nvram.mac_addr_count) {
+		pr_err("not enough mac addresses\n");
+		return -ENODEV;
+	}
+
+	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+	oui = mac + ETH_ALEN/2 - 1;
+	count = mac_addr_used;
+
+	while (count--) {
+		u8 *p = mac + ETH_ALEN - 1;
+
+		do {
+			(*p)++;
+			if (*p != 0)
+				break;
+			p--;
+		} while (p != oui);
+
+		if (p == oui) {
+			pr_err("unable to fetch mac address\n");
+			return -ENODEV;
+		}
+	}
+
+	mac_addr_used++;
+	return 0;
+}
+EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c
new file mode 100644
index 0000000..68a31bb
--- /dev/null
+++ b/arch/mips/bcm63xx/reset.c
@@ -0,0 +1,223 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_reset.h>
+
+#define __GEN_RESET_BITS_TABLE(__cpu)					\
+	[BCM63XX_RESET_SPI]		= BCM## __cpu ##_RESET_SPI,	\
+	[BCM63XX_RESET_ENET]		= BCM## __cpu ##_RESET_ENET,	\
+	[BCM63XX_RESET_USBH]		= BCM## __cpu ##_RESET_USBH,	\
+	[BCM63XX_RESET_USBD]		= BCM## __cpu ##_RESET_USBD,	\
+	[BCM63XX_RESET_DSL]		= BCM## __cpu ##_RESET_DSL,	\
+	[BCM63XX_RESET_SAR]		= BCM## __cpu ##_RESET_SAR,	\
+	[BCM63XX_RESET_EPHY]		= BCM## __cpu ##_RESET_EPHY,	\
+	[BCM63XX_RESET_ENETSW]		= BCM## __cpu ##_RESET_ENETSW,	\
+	[BCM63XX_RESET_PCM]		= BCM## __cpu ##_RESET_PCM,	\
+	[BCM63XX_RESET_MPI]		= BCM## __cpu ##_RESET_MPI,	\
+	[BCM63XX_RESET_PCIE]		= BCM## __cpu ##_RESET_PCIE,	\
+	[BCM63XX_RESET_PCIE_EXT]	= BCM## __cpu ##_RESET_PCIE_EXT,
+
+#define BCM6328_RESET_SPI	SOFTRESET_6328_SPI_MASK
+#define BCM6328_RESET_ENET	0
+#define BCM6328_RESET_USBH	SOFTRESET_6328_USBH_MASK
+#define BCM6328_RESET_USBD	SOFTRESET_6328_USBS_MASK
+#define BCM6328_RESET_DSL	0
+#define BCM6328_RESET_SAR	SOFTRESET_6328_SAR_MASK
+#define BCM6328_RESET_EPHY	SOFTRESET_6328_EPHY_MASK
+#define BCM6328_RESET_ENETSW	SOFTRESET_6328_ENETSW_MASK
+#define BCM6328_RESET_PCM	SOFTRESET_6328_PCM_MASK
+#define BCM6328_RESET_MPI	0
+#define BCM6328_RESET_PCIE	\
+				(SOFTRESET_6328_PCIE_MASK |		\
+				 SOFTRESET_6328_PCIE_CORE_MASK |	\
+				 SOFTRESET_6328_PCIE_HARD_MASK)
+#define BCM6328_RESET_PCIE_EXT	SOFTRESET_6328_PCIE_EXT_MASK
+
+#define BCM6338_RESET_SPI	SOFTRESET_6338_SPI_MASK
+#define BCM6338_RESET_ENET	SOFTRESET_6338_ENET_MASK
+#define BCM6338_RESET_USBH	SOFTRESET_6338_USBH_MASK
+#define BCM6338_RESET_USBD	SOFTRESET_6338_USBS_MASK
+#define BCM6338_RESET_DSL	SOFTRESET_6338_ADSL_MASK
+#define BCM6338_RESET_SAR	SOFTRESET_6338_SAR_MASK
+#define BCM6338_RESET_EPHY	0
+#define BCM6338_RESET_ENETSW	0
+#define BCM6338_RESET_PCM	0
+#define BCM6338_RESET_MPI	0
+#define BCM6338_RESET_PCIE	0
+#define BCM6338_RESET_PCIE_EXT	0
+
+#define BCM6348_RESET_SPI	SOFTRESET_6348_SPI_MASK
+#define BCM6348_RESET_ENET	SOFTRESET_6348_ENET_MASK
+#define BCM6348_RESET_USBH	SOFTRESET_6348_USBH_MASK
+#define BCM6348_RESET_USBD	SOFTRESET_6348_USBS_MASK
+#define BCM6348_RESET_DSL	SOFTRESET_6348_ADSL_MASK
+#define BCM6348_RESET_SAR	SOFTRESET_6348_SAR_MASK
+#define BCM6348_RESET_EPHY	0
+#define BCM6348_RESET_ENETSW	0
+#define BCM6348_RESET_PCM	0
+#define BCM6348_RESET_MPI	0
+#define BCM6348_RESET_PCIE	0
+#define BCM6348_RESET_PCIE_EXT	0
+
+#define BCM6358_RESET_SPI	SOFTRESET_6358_SPI_MASK
+#define BCM6358_RESET_ENET	SOFTRESET_6358_ENET_MASK
+#define BCM6358_RESET_USBH	SOFTRESET_6358_USBH_MASK
+#define BCM6358_RESET_USBD	0
+#define BCM6358_RESET_DSL	SOFTRESET_6358_ADSL_MASK
+#define BCM6358_RESET_SAR	SOFTRESET_6358_SAR_MASK
+#define BCM6358_RESET_EPHY	SOFTRESET_6358_EPHY_MASK
+#define BCM6358_RESET_ENETSW	0
+#define BCM6358_RESET_PCM	SOFTRESET_6358_PCM_MASK
+#define BCM6358_RESET_MPI	SOFTRESET_6358_MPI_MASK
+#define BCM6358_RESET_PCIE	0
+#define BCM6358_RESET_PCIE_EXT	0
+
+#define BCM6368_RESET_SPI	SOFTRESET_6368_SPI_MASK
+#define BCM6368_RESET_ENET	0
+#define BCM6368_RESET_USBH	SOFTRESET_6368_USBH_MASK
+#define BCM6368_RESET_USBD	SOFTRESET_6368_USBS_MASK
+#define BCM6368_RESET_DSL	0
+#define BCM6368_RESET_SAR	SOFTRESET_6368_SAR_MASK
+#define BCM6368_RESET_EPHY	SOFTRESET_6368_EPHY_MASK
+#define BCM6368_RESET_ENETSW	0
+#define BCM6368_RESET_PCM	SOFTRESET_6368_PCM_MASK
+#define BCM6368_RESET_MPI	SOFTRESET_6368_MPI_MASK
+#define BCM6368_RESET_PCIE	0
+#define BCM6368_RESET_PCIE_EXT	0
+
+#ifdef BCMCPU_RUNTIME_DETECT
+
+/*
+ * core reset bits
+ */
+static const u32 bcm6328_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6328)
+};
+
+static const u32 bcm6338_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6338)
+};
+
+static const u32 bcm6348_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6348)
+};
+
+static const u32 bcm6358_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6358)
+};
+
+static const u32 bcm6368_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6368)
+};
+
+const u32 *bcm63xx_reset_bits;
+static int reset_reg;
+
+static int __init bcm63xx_reset_bits_init(void)
+{
+	if (BCMCPU_IS_6328()) {
+		reset_reg = PERF_SOFTRESET_6328_REG;
+		bcm63xx_reset_bits = bcm6328_reset_bits;
+	} else if (BCMCPU_IS_6338()) {
+		reset_reg = PERF_SOFTRESET_REG;
+		bcm63xx_reset_bits = bcm6338_reset_bits;
+	} else if (BCMCPU_IS_6348()) {
+		reset_reg = PERF_SOFTRESET_REG;
+		bcm63xx_reset_bits = bcm6348_reset_bits;
+	} else if (BCMCPU_IS_6358()) {
+		reset_reg = PERF_SOFTRESET_6358_REG;
+		bcm63xx_reset_bits = bcm6358_reset_bits;
+	} else if (BCMCPU_IS_6368()) {
+		reset_reg = PERF_SOFTRESET_6368_REG;
+		bcm63xx_reset_bits = bcm6368_reset_bits;
+	}
+
+	return 0;
+}
+#else
+
+#ifdef CONFIG_BCM63XX_CPU_6328
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6328)
+};
+#define reset_reg PERF_SOFTRESET_6328_REG
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6338
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6338)
+};
+#define reset_reg PERF_SOFTRESET_REG
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6345
+static const u32 bcm63xx_reset_bits[] = { };
+#define reset_reg 0
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6348
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6348)
+};
+#define reset_reg PERF_SOFTRESET_REG
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6358)
+};
+#define reset_reg PERF_SOFTRESET_6358_REG
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6368
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(6368)
+};
+#define reset_reg PERF_SOFTRESET_6368_REG
+#endif
+
+static int __init bcm63xx_reset_bits_init(void) { return 0; }
+#endif
+
+static DEFINE_SPINLOCK(reset_mutex);
+
+static void __bcm63xx_core_set_reset(u32 mask, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (!mask)
+		return;
+
+	spin_lock_irqsave(&reset_mutex, flags);
+	val = bcm_perf_readl(reset_reg);
+
+	if (enable)
+		val &= ~mask;
+	else
+		val |= mask;
+
+	bcm_perf_writel(val, reset_reg);
+	spin_unlock_irqrestore(&reset_mutex, flags);
+}
+
+void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset)
+{
+	__bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset);
+}
+EXPORT_SYMBOL(bcm63xx_core_set_reset);
+
+postcore_initcall(bcm63xx_reset_bits_init);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
index fdf5f19..6d5ddbc 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
@@ -688,3 +688,8 @@
 		cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
 	return addr_allocated;
 }
+
+struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void)
+{
+	return cvmx_bootmem_desc;
+}
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
index e44a55b..237e5b1 100644
--- a/arch/mips/cavium-octeon/flash_setup.c
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -51,7 +51,8 @@
 		flash_map.name = "phys_mapped_flash";
 		flash_map.phys = region_cfg.s.base << 16;
 		flash_map.size = 0x1fc00000 - flash_map.phys;
-		flash_map.bankwidth = 1;
+		/* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */
+		flash_map.bankwidth = region_cfg.s.width + 1;
 		flash_map.virt = ioremap(flash_map.phys, flash_map.size);
 		pr_notice("Bootbus flash: Setting flash for %luMB flash at "
 			  "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 02b15ee..46f5dbc 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -1266,7 +1266,6 @@
 		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52);
 
 	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56);
-	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63);
 
 	/* CIU_1 */
 	for (i = 0; i < 16; i++)
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
index db478db..0ba0eb9 100644
--- a/arch/mips/cavium-octeon/octeon-memcpy.S
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -79,11 +79,6 @@
 /*
  * Only on the 64-bit kernel we can made use of 64-bit registers.
  */
-#ifdef CONFIG_64BIT
-#define USE_DOUBLE
-#endif
-
-#ifdef USE_DOUBLE
 
 #define LOAD   ld
 #define LOADL  ldl
@@ -119,26 +114,6 @@
 #define t6	$14
 #define t7	$15
 
-#else
-
-#define LOAD   lw
-#define LOADL  lwl
-#define LOADR  lwr
-#define STOREL swl
-#define STORER swr
-#define STORE  sw
-#define ADD    addu
-#define SUB    subu
-#define SRL    srl
-#define SLL    sll
-#define SRA    sra
-#define SLLV   sllv
-#define SRLV   srlv
-#define NBYTES 4
-#define LOG_NBYTES 2
-
-#endif /* USE_DOUBLE */
-
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 #define LDFIRST LOADR
 #define LDREST  LOADL
@@ -395,12 +370,10 @@
 
 	COPY_BYTE(0)
 	COPY_BYTE(1)
-#ifdef USE_DOUBLE
 	COPY_BYTE(2)
 	COPY_BYTE(3)
 	COPY_BYTE(4)
 	COPY_BYTE(5)
-#endif
 EXC(	lb	t0, NBYTES-2(src), l_exc)
 	SUB	len, len, 1
 	jr	ra
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 0938df1..3c1b625 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -24,108 +24,6 @@
 #include <asm/octeon/cvmx-helper.h>
 #include <asm/octeon/cvmx-helper-board.h>
 
-static struct octeon_cf_data octeon_cf_data;
-
-static int __init octeon_cf_device_init(void)
-{
-	union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
-	unsigned long base_ptr, region_base, region_size;
-	struct platform_device *pd;
-	struct resource cf_resources[3];
-	unsigned int num_resources;
-	int i;
-	int ret = 0;
-
-	/* Setup octeon-cf platform device if present. */
-	base_ptr = 0;
-	if (octeon_bootinfo->major_version == 1
-		&& octeon_bootinfo->minor_version >= 1) {
-		if (octeon_bootinfo->compact_flash_common_base_addr)
-			base_ptr =
-				octeon_bootinfo->compact_flash_common_base_addr;
-	} else {
-		base_ptr = 0x1d000800;
-	}
-
-	if (!base_ptr)
-		return ret;
-
-	/* Find CS0 region. */
-	for (i = 0; i < 8; i++) {
-		mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
-		region_base = mio_boot_reg_cfg.s.base << 16;
-		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-		if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
-		    && base_ptr < region_base + region_size)
-			break;
-	}
-	if (i >= 7) {
-		/* i and i + 1 are CS0 and CS1, both must be less than 8. */
-		goto out;
-	}
-	octeon_cf_data.base_region = i;
-	octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
-	octeon_cf_data.base_region_bias = base_ptr - region_base;
-	memset(cf_resources, 0, sizeof(cf_resources));
-	num_resources = 0;
-	cf_resources[num_resources].flags	= IORESOURCE_MEM;
-	cf_resources[num_resources].start	= region_base;
-	cf_resources[num_resources].end	= region_base + region_size - 1;
-	num_resources++;
-
-
-	if (!(base_ptr & 0xfffful)) {
-		/*
-		 * Boot loader signals availability of DMA (true_ide
-		 * mode) by setting low order bits of base_ptr to
-		 * zero.
-		 */
-
-		/* Assume that CS1 immediately follows. */
-		mio_boot_reg_cfg.u64 =
-			cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
-		region_base = mio_boot_reg_cfg.s.base << 16;
-		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-		if (!mio_boot_reg_cfg.s.en)
-			goto out;
-
-		cf_resources[num_resources].flags	= IORESOURCE_MEM;
-		cf_resources[num_resources].start	= region_base;
-		cf_resources[num_resources].end	= region_base + region_size - 1;
-		num_resources++;
-
-		octeon_cf_data.dma_engine = 0;
-		cf_resources[num_resources].flags	= IORESOURCE_IRQ;
-		cf_resources[num_resources].start	= OCTEON_IRQ_BOOTDMA;
-		cf_resources[num_resources].end	= OCTEON_IRQ_BOOTDMA;
-		num_resources++;
-	} else {
-		octeon_cf_data.dma_engine = -1;
-	}
-
-	pd = platform_device_alloc("pata_octeon_cf", -1);
-	if (!pd) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	pd->dev.platform_data = &octeon_cf_data;
-
-	ret = platform_device_add_resources(pd, cf_resources, num_resources);
-	if (ret)
-		goto fail;
-
-	ret = platform_device_add(pd);
-	if (ret)
-		goto fail;
-
-	return ret;
-fail:
-	platform_device_put(pd);
-out:
-	return ret;
-}
-device_initcall(octeon_cf_device_init);
-
 /* Octeon Random Number Generator.  */
 static int __init octeon_rng_device_init(void)
 {
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 04dd8ff..d7e0a09 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -4,9 +4,11 @@
  * for more details.
  *
  * Copyright (C) 2004-2007 Cavium Networks
- * Copyright (C) 2008 Wind River Systems
+ * Copyright (C) 2008, 2009 Wind River Systems
+ *   written by Ralf Baechle <ralf@linux-mips.org>
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/export.h>
@@ -23,6 +25,7 @@
 #include <linux/serial_8250.h>
 #include <linux/of_fdt.h>
 #include <linux/libfdt.h>
+#include <linux/kexec.h>
 
 #include <asm/processor.h>
 #include <asm/reboot.h>
@@ -56,11 +59,208 @@
 struct cvmx_bootinfo *octeon_bootinfo;
 EXPORT_SYMBOL(octeon_bootinfo);
 
+static unsigned long long RESERVE_LOW_MEM = 0ull;
+#ifdef CONFIG_KEXEC
+#ifdef CONFIG_SMP
+/*
+ * Wait for relocation code is prepared and send
+ * secondary CPUs to spin until kernel is relocated.
+ */
+static void octeon_kexec_smp_down(void *ignored)
+{
+	int cpu = smp_processor_id();
+
+	local_irq_disable();
+	set_cpu_online(cpu, false);
+	while (!atomic_read(&kexec_ready_to_reboot))
+		cpu_relax();
+
+	asm volatile (
+	"	sync						\n"
+	"	synci	($0)					\n");
+
+	relocated_kexec_smp_wait(NULL);
+}
+#endif
+
+#define OCTEON_DDR0_BASE    (0x0ULL)
+#define OCTEON_DDR0_SIZE    (0x010000000ULL)
+#define OCTEON_DDR1_BASE    (0x410000000ULL)
+#define OCTEON_DDR1_SIZE    (0x010000000ULL)
+#define OCTEON_DDR2_BASE    (0x020000000ULL)
+#define OCTEON_DDR2_SIZE    (0x3e0000000ULL)
+#define OCTEON_MAX_PHY_MEM_SIZE (16*1024*1024*1024ULL)
+
+static struct kimage *kimage_ptr;
+
+static void kexec_bootmem_init(uint64_t mem_size, uint32_t low_reserved_bytes)
+{
+	int64_t addr;
+	struct cvmx_bootmem_desc *bootmem_desc;
+
+	bootmem_desc = cvmx_bootmem_get_desc();
+
+	if (mem_size > OCTEON_MAX_PHY_MEM_SIZE) {
+		mem_size = OCTEON_MAX_PHY_MEM_SIZE;
+		pr_err("Error: requested memory too large,"
+		       "truncating to maximum size\n");
+	}
+
+	bootmem_desc->major_version = CVMX_BOOTMEM_DESC_MAJ_VER;
+	bootmem_desc->minor_version = CVMX_BOOTMEM_DESC_MIN_VER;
+
+	addr = (OCTEON_DDR0_BASE + RESERVE_LOW_MEM + low_reserved_bytes);
+	bootmem_desc->head_addr = 0;
+
+	if (mem_size <= OCTEON_DDR0_SIZE) {
+		__cvmx_bootmem_phy_free(addr,
+				mem_size - RESERVE_LOW_MEM -
+				low_reserved_bytes, 0);
+		return;
+	}
+
+	__cvmx_bootmem_phy_free(addr,
+			OCTEON_DDR0_SIZE - RESERVE_LOW_MEM -
+			low_reserved_bytes, 0);
+
+	mem_size -= OCTEON_DDR0_SIZE;
+
+	if (mem_size > OCTEON_DDR1_SIZE) {
+		__cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, OCTEON_DDR1_SIZE, 0);
+		__cvmx_bootmem_phy_free(OCTEON_DDR2_BASE,
+				mem_size - OCTEON_DDR1_SIZE, 0);
+	} else
+		__cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, mem_size, 0);
+}
+
+static int octeon_kexec_prepare(struct kimage *image)
+{
+	int i;
+	char *bootloader = "kexec";
+
+	octeon_boot_desc_ptr->argc = 0;
+	for (i = 0; i < image->nr_segments; i++) {
+		if (!strncmp(bootloader, (char *)image->segment[i].buf,
+				strlen(bootloader))) {
+			/*
+			 * convert command line string to array
+			 * of parameters (as bootloader does).
+			 */
+			int argc = 0, offt;
+			char *str = (char *)image->segment[i].buf;
+			char *ptr = strchr(str, ' ');
+			while (ptr && (OCTEON_ARGV_MAX_ARGS > argc)) {
+				*ptr = '\0';
+				if (ptr[1] != ' ') {
+					offt = (int)(ptr - str + 1);
+					octeon_boot_desc_ptr->argv[argc] =
+						image->segment[i].mem + offt;
+					argc++;
+				}
+				ptr = strchr(ptr + 1, ' ');
+			}
+			octeon_boot_desc_ptr->argc = argc;
+			break;
+		}
+	}
+
+	/*
+	 * Information about segments will be needed during pre-boot memory
+	 * initialization.
+	 */
+	kimage_ptr = image;
+	return 0;
+}
+
+static void octeon_generic_shutdown(void)
+{
+	int cpu, i;
+	struct cvmx_bootmem_desc *bootmem_desc;
+	void *named_block_array_ptr;
+
+	bootmem_desc = cvmx_bootmem_get_desc();
+	named_block_array_ptr =
+		cvmx_phys_to_ptr(bootmem_desc->named_block_array_addr);
+
+#ifdef CONFIG_SMP
+	/* disable watchdogs */
+	for_each_online_cpu(cpu)
+		cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
+#else
+	cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+#endif
+	if (kimage_ptr != kexec_crash_image) {
+		memset(named_block_array_ptr,
+			0x0,
+			CVMX_BOOTMEM_NUM_NAMED_BLOCKS *
+			sizeof(struct cvmx_bootmem_named_block_desc));
+		/*
+		 * Mark all memory (except low 0x100000 bytes) as free.
+		 * It is the same thing that bootloader does.
+		 */
+		kexec_bootmem_init(octeon_bootinfo->dram_size*1024ULL*1024ULL,
+				0x100000);
+		/*
+		 * Allocate all segments to avoid their corruption during boot.
+		 */
+		for (i = 0; i < kimage_ptr->nr_segments; i++)
+			cvmx_bootmem_alloc_address(
+				kimage_ptr->segment[i].memsz + 2*PAGE_SIZE,
+				kimage_ptr->segment[i].mem - PAGE_SIZE,
+				PAGE_SIZE);
+	} else {
+		/*
+		 * Do not mark all memory as free. Free only named sections
+		 * leaving the rest of memory unchanged.
+		 */
+		struct cvmx_bootmem_named_block_desc *ptr =
+			(struct cvmx_bootmem_named_block_desc *)
+			named_block_array_ptr;
+
+		for (i = 0; i < bootmem_desc->named_block_num_blocks; i++)
+			if (ptr[i].size)
+				cvmx_bootmem_free_named(ptr[i].name);
+	}
+	kexec_args[2] = 1UL; /* running on octeon_main_processor */
+	kexec_args[3] = (unsigned long)octeon_boot_desc_ptr;
+#ifdef CONFIG_SMP
+	secondary_kexec_args[2] = 0UL; /* running on secondary cpu */
+	secondary_kexec_args[3] = (unsigned long)octeon_boot_desc_ptr;
+#endif
+}
+
+static void octeon_shutdown(void)
+{
+	octeon_generic_shutdown();
+#ifdef CONFIG_SMP
+	smp_call_function(octeon_kexec_smp_down, NULL, 0);
+	smp_wmb();
+	while (num_online_cpus() > 1) {
+		cpu_relax();
+		mdelay(1);
+	}
+#endif
+}
+
+static void octeon_crash_shutdown(struct pt_regs *regs)
+{
+	octeon_generic_shutdown();
+	default_machine_crash_shutdown(regs);
+}
+
+#endif /* CONFIG_KEXEC */
+
 #ifdef CONFIG_CAVIUM_RESERVE32
 uint64_t octeon_reserve32_memory;
 EXPORT_SYMBOL(octeon_reserve32_memory);
 #endif
 
+#ifdef CONFIG_KEXEC
+/* crashkernel cmdline parameter is parsed _after_ memory setup
+ * we also parse it here (workaround for EHB5200) */
+static uint64_t crashk_size, crashk_base;
+#endif
+
 static int octeon_uart;
 
 extern asmlinkage void handle_int(void);
@@ -415,6 +615,8 @@
 void __init prom_init(void)
 {
 	struct cvmx_sysinfo *sysinfo;
+	const char *arg;
+	char *p;
 	int i;
 	int argc;
 #ifdef CONFIG_CAVIUM_RESERVE32
@@ -566,6 +768,15 @@
 	if (octeon_is_simulation())
 		MAX_MEMORY = 64ull << 20;
 
+	arg = strstr(arcs_cmdline, "mem=");
+	if (arg) {
+		MAX_MEMORY = memparse(arg + 4, &p);
+		if (MAX_MEMORY == 0)
+			MAX_MEMORY = 32ull << 30;
+		if (*p == '@')
+			RESERVE_LOW_MEM = memparse(p + 1, &p);
+	}
+
 	arcs_cmdline[0] = 0;
 	argc = octeon_boot_desc_ptr->argc;
 	for (i = 0; i < argc; i++) {
@@ -573,16 +784,30 @@
 			cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
 		if ((strncmp(arg, "MEM=", 4) == 0) ||
 		    (strncmp(arg, "mem=", 4) == 0)) {
-			sscanf(arg + 4, "%llu", &MAX_MEMORY);
-			MAX_MEMORY <<= 20;
+			MAX_MEMORY = memparse(arg + 4, &p);
 			if (MAX_MEMORY == 0)
 				MAX_MEMORY = 32ull << 30;
+			if (*p == '@')
+				RESERVE_LOW_MEM = memparse(p + 1, &p);
 		} else if (strcmp(arg, "ecc_verbose") == 0) {
 #ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
 			__cvmx_interrupt_ecc_report_single_bit_errors = 1;
 			pr_notice("Reporting of single bit ECC errors is "
 				  "turned on\n");
 #endif
+#ifdef CONFIG_KEXEC
+		} else if (strncmp(arg, "crashkernel=", 12) == 0) {
+			crashk_size = memparse(arg+12, &p);
+			if (*p == '@')
+				crashk_base = memparse(p+1, &p);
+			strcat(arcs_cmdline, " ");
+			strcat(arcs_cmdline, arg);
+			/*
+			 * To do: switch parsing to new style, something like:
+			 * parse_crashkernel(arg, sysinfo->system_dram_size,
+			 * 		  &crashk_size, &crashk_base);
+			 */
+#endif
 		} else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
 			   sizeof(arcs_cmdline) - 1) {
 			strcat(arcs_cmdline, " ");
@@ -617,11 +842,18 @@
 	_machine_restart = octeon_restart;
 	_machine_halt = octeon_halt;
 
+#ifdef CONFIG_KEXEC
+	_machine_kexec_shutdown = octeon_shutdown;
+	_machine_crash_shutdown = octeon_crash_shutdown;
+	_machine_kexec_prepare = octeon_kexec_prepare;
+#endif
+
 	octeon_user_io_init();
 	register_smp_ops(&octeon_smp_ops);
 }
 
 /* Exclude a single page from the regions obtained in plat_mem_setup. */
+#ifndef CONFIG_CRASH_DUMP
 static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size)
 {
 	if (addr > *mem && addr < *mem + *size) {
@@ -636,14 +868,21 @@
 		*size -= PAGE_SIZE;
 	}
 }
+#endif /* CONFIG_CRASH_DUMP */
 
 void __init plat_mem_setup(void)
 {
 	uint64_t mem_alloc_size;
 	uint64_t total;
+	uint64_t crashk_end;
+#ifndef CONFIG_CRASH_DUMP
 	int64_t memory;
+	uint64_t kernel_start;
+	uint64_t kernel_size;
+#endif
 
 	total = 0;
+	crashk_end = 0;
 
 	/*
 	 * The Mips memory init uses the first memory location for
@@ -656,6 +895,17 @@
 	if (mem_alloc_size > MAX_MEMORY)
 		mem_alloc_size = MAX_MEMORY;
 
+/* Crashkernel ignores bootmem list. It relies on mem=X@Y option */
+#ifdef CONFIG_CRASH_DUMP
+	add_memory_region(RESERVE_LOW_MEM, MAX_MEMORY, BOOT_MEM_RAM);
+	total += MAX_MEMORY;
+#else
+#ifdef CONFIG_KEXEC
+	if (crashk_size > 0) {
+		add_memory_region(crashk_base, crashk_size, BOOT_MEM_RAM);
+		crashk_end = crashk_base + crashk_size;
+	}
+#endif
 	/*
 	 * When allocating memory, we want incrementing addresses from
 	 * bootmem_alloc so the code in add_memory_region can merge
@@ -664,22 +914,15 @@
 	cvmx_bootmem_lock();
 	while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
 		&& (total < MAX_MEMORY)) {
-#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR)
 		memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
 						__pa_symbol(&__init_end), -1,
 						0x100000,
 						CVMX_BOOTMEM_FLAG_NO_LOCKING);
-#elif defined(CONFIG_HIGHMEM)
-		memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31,
-						0x100000,
-						CVMX_BOOTMEM_FLAG_NO_LOCKING);
-#else
-		memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20,
-						0x100000,
-						CVMX_BOOTMEM_FLAG_NO_LOCKING);
-#endif
 		if (memory >= 0) {
 			u64 size = mem_alloc_size;
+#ifdef CONFIG_KEXEC
+			uint64_t end;
+#endif
 
 			/*
 			 * exclude a page at the beginning and end of
@@ -692,20 +935,67 @@
 			memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE +
 					    CVMX_PCIE_BAR1_PHYS_SIZE,
 					    &memory, &size);
+#ifdef CONFIG_KEXEC
+			end = memory + mem_alloc_size;
 
 			/*
-			 * This function automatically merges address
-			 * regions next to each other if they are
-			 * received in incrementing order.
+			 * This function automatically merges address regions
+			 * next to each other if they are received in
+			 * incrementing order
 			 */
-			if (size)
-				add_memory_region(memory, size, BOOT_MEM_RAM);
+			if (memory < crashk_base && end >  crashk_end) {
+				/* region is fully in */
+				add_memory_region(memory,
+						  crashk_base - memory,
+						  BOOT_MEM_RAM);
+				total += crashk_base - memory;
+				add_memory_region(crashk_end,
+						  end - crashk_end,
+						  BOOT_MEM_RAM);
+				total += end - crashk_end;
+				continue;
+			}
+
+			if (memory >= crashk_base && end <= crashk_end)
+				/*
+				 * Entire memory region is within the new
+				 *  kernel's memory, ignore it.
+				 */
+				continue;
+
+			if (memory > crashk_base && memory < crashk_end &&
+			    end > crashk_end) {
+				/*
+				 * Overlap with the beginning of the region,
+				 * reserve the beginning.
+				  */
+				mem_alloc_size -= crashk_end - memory;
+				memory = crashk_end;
+			} else if (memory < crashk_base && end > crashk_base &&
+				   end < crashk_end)
+				/*
+				 * Overlap with the beginning of the region,
+				 * chop of end.
+				 */
+				mem_alloc_size -= end - crashk_base;
+#endif
+			add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
 			total += mem_alloc_size;
+			/* Recovering mem_alloc_size */
+			mem_alloc_size = 4 << 20;
 		} else {
 			break;
 		}
 	}
 	cvmx_bootmem_unlock();
+	/* Add the memory region for the kernel. */
+	kernel_start = (unsigned long) _text;
+	kernel_size = ALIGN(_end - _text, 0x100000);
+
+	/* Adjust for physical offset. */
+	kernel_start &= ~0xffffffff80000000ULL;
+	add_memory_region(kernel_start, kernel_size, BOOT_MEM_RAM);
+#endif /* CONFIG_CRASH_DUMP */
 
 #ifdef CONFIG_CAVIUM_RESERVE32
 	/*
@@ -821,3 +1111,51 @@
 	}
 	unflatten_device_tree();
 }
+
+static int __initdata disable_octeon_edac_p;
+
+static int __init disable_octeon_edac(char *str)
+{
+	disable_octeon_edac_p = 1;
+	return 0;
+}
+early_param("disable_octeon_edac", disable_octeon_edac);
+
+static char *edac_device_names[] = {
+	"octeon_l2c_edac",
+	"octeon_pc_edac",
+};
+
+static int __init edac_devinit(void)
+{
+	struct platform_device *dev;
+	int i, err = 0;
+	int num_lmc;
+	char *name;
+
+	if (disable_octeon_edac_p)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(edac_device_names); i++) {
+		name = edac_device_names[i];
+		dev = platform_device_register_simple(name, -1, NULL, 0);
+		if (IS_ERR(dev)) {
+			pr_err("Registation of %s failed!\n", name);
+			err = PTR_ERR(dev);
+		}
+	}
+
+	num_lmc = OCTEON_IS_MODEL(OCTEON_CN68XX) ? 4 :
+		(OCTEON_IS_MODEL(OCTEON_CN56XX) ? 2 : 1);
+	for (i = 0; i < num_lmc; i++) {
+		dev = platform_device_register_simple("octeon_lmc_edac",
+						      i, NULL, 0);
+		if (IS_ERR(dev)) {
+			pr_err("Registation of octeon_lmc_edac %d failed!\n", i);
+			err = PTR_ERR(dev);
+		}
+	}
+
+	return err;
+}
+device_initcall(edac_devinit);
diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig
new file mode 100644
index 0000000..ea87d43
--- /dev/null
+++ b/arch/mips/configs/ath79_defconfig
@@ -0,0 +1,111 @@
+CONFIG_ATH79=y
+CONFIG_ATH79_MACH_AP121=y
+CONFIG_ATH79_MACH_AP81=y
+CONFIG_ATH79_MACH_DB120=y
+CONFIG_ATH79_MACH_PB44=y
+CONFIG_ATH79_MACH_UBNT_XM=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+CONFIG_RD_LZMA=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_PACKET_ENGINE is not set
+CONFIG_ATH_COMMON=m
+CONFIG_ATH9K=m
+CONFIG_ATH9K_AHB=y
+CONFIG_INPUT=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO_POLLED=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_AR933X=y
+CONFIG_SERIAL_AR933X_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATH79=y
+CONFIG_SPI_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCF857X=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ATH79_WDT=y
+# CONFIG_VGA_ARB is not set
+# CONFIG_HID is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_ITU_T=m
diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig
index 75165df..014ba4b 100644
--- a/arch/mips/configs/cavium_octeon_defconfig
+++ b/arch/mips/configs/cavium_octeon_defconfig
@@ -1,7 +1,11 @@
 CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
+CONFIG_CAVIUM_CN63XXP1=y
 CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
 CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_HZ_100=y
 CONFIG_PREEMPT=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
@@ -11,16 +15,15 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
@@ -42,22 +45,68 @@
 CONFIG_IP_PIMSM_V2=y
 CONFIG_SYN_COOKIES=y
 # CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_OF_PARTS is not set
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SLRAM=y
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
-# CONFIG_MISC_DEVICES is not set
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_PATA_OCTEON_CF=y
+CONFIG_SATA_SIL=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_TOSHIBA is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_BCM87XX_PHY=y
+# CONFIG_WLAN is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
@@ -66,24 +115,39 @@
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_OCTEON=y
+CONFIG_SPI=y
+CONFIG_SPI_OCTEON=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_STAGING=y
+CONFIG_OCTEON_ETHERNET=y
+# CONFIG_NET_VENDOR_SILICOM is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
-# CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_NLS=y
+CONFIG_HUGETLBFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_SCHED_DEBUG is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_EARLY_PRINTK is not set
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 CONFIG_CRYPTO_CBC=y
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
deleted file mode 100644
index f72d305..0000000
--- a/arch/mips/configs/yosemite_defconfig
+++ /dev/null
@@ -1,94 +0,0 @@
-CONFIG_PMC_YOSEMITE=y
-CONFIG_HIGHMEM=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_HZ_1000=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_PCI=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETWORK_SECMARK=y
-CONFIG_FW_LOADER=m
-CONFIG_CONNECTOR=m
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_ATA_OVER_ETH=m
-CONFIG_SGI_IOC4=m
-CONFIG_RAID_ATTRS=m
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=m
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_QLA3XXX=m
-CONFIG_CHELSIO_T3=m
-CONFIG_NETXEN_NIC=m
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FUSE_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/mips/fw/sni/Makefile b/arch/mips/fw/sni/Makefile
index d9740a3..3f01dd3 100644
--- a/arch/mips/fw/sni/Makefile
+++ b/arch/mips/fw/sni/Makefile
@@ -2,4 +2,4 @@
 # Makefile for the SNI prom monitor routines under Linux.
 #
 
-lib-$(CONFIG_SNIPROM)	+= sniprom.o
+lib-$(CONFIG_FW_SNIPROM)	+= sniprom.o
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 52c4e91..90112ad 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -243,9 +243,9 @@
 	 */
 	CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
 	CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650,
-	CPU_R4700, CPU_R5000, CPU_R5000A, CPU_R5500, CPU_NEVADA, CPU_R5432,
-	CPU_R10000, CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121,
-	CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
+	CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
+	CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122,
+	CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
 	CPU_SR71000, CPU_RM9000, CPU_TX49XX,
 
 	/*
diff --git a/arch/mips/include/asm/fw/arc/types.h b/arch/mips/include/asm/fw/arc/types.h
index b9adcd6f..2b11f87 100644
--- a/arch/mips/include/asm/fw/arc/types.h
+++ b/arch/mips/include/asm/fw/arc/types.h
@@ -10,7 +10,7 @@
 #define _ASM_ARC_TYPES_H
 
 
-#ifdef CONFIG_ARC32
+#ifdef CONFIG_FW_ARC32
 
 typedef char		CHAR;
 typedef short		SHORT;
@@ -33,9 +33,9 @@
 typedef LONG		_PULONG;
 typedef LONG		_PVOID;
 
-#endif /* CONFIG_ARC32 */
+#endif /* CONFIG_FW_ARC32 */
 
-#ifdef CONFIG_ARC64
+#ifdef CONFIG_FW_ARC64
 
 typedef char		CHAR;
 typedef short		SHORT;
@@ -57,7 +57,7 @@
 typedef ULONG		*_PULONG;
 typedef VOID		*_PVOID;
 
-#endif /* CONFIG_ARC64  */
+#endif /* CONFIG_FW_ARC64  */
 
 typedef CHAR		*PCHAR;
 typedef SHORT		*PSHORT;
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index b4c20e4..f0324e9 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -161,31 +161,6 @@
 	)
 #define instruction_hazard() do { } while (0)
 
-#elif defined(CONFIG_CPU_RM9000)
-
-/*
- * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
- * use of the JTLB for instructions should not occur for 4 cpu cycles and use
- * for data translations should not occur for 3 cpu cycles.
- */
-
-ASMMACRO(mtc0_tlbw_hazard,
-	 _ssnop; _ssnop; _ssnop; _ssnop
-	)
-ASMMACRO(tlbw_use_hazard,
-	 _ssnop; _ssnop; _ssnop; _ssnop
-	)
-ASMMACRO(tlb_probe_hazard,
-	 _ssnop; _ssnop; _ssnop; _ssnop
-	)
-ASMMACRO(irq_enable_hazard,
-	)
-ASMMACRO(irq_disable_hazard,
-	)
-ASMMACRO(back_to_back_c0_hazard,
-	)
-#define instruction_hazard() do { } while (0)
-
 #elif defined(CONFIG_CPU_SB1)
 
 /*
diff --git a/arch/mips/include/asm/kexec.h b/arch/mips/include/asm/kexec.h
index 4314892..ee25ebb 100644
--- a/arch/mips/include/asm/kexec.h
+++ b/arch/mips/include/asm/kexec.h
@@ -9,22 +9,43 @@
 #ifndef _MIPS_KEXEC
 # define _MIPS_KEXEC
 
+#include <asm/stacktrace.h>
+
 /* Maximum physical address we can use pages from */
 #define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000)
 /* Maximum address we can reach in physical address mode */
 #define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000)
  /* Maximum address we can use for the control code buffer */
 #define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000)
-
-#define KEXEC_CONTROL_PAGE_SIZE 4096
+/* Reserve 3*4096 bytes for board-specific info */
+#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096)
 
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_MIPS
+#define MAX_NOTE_BYTES 1024
 
 static inline void crash_setup_regs(struct pt_regs *newregs,
 				    struct pt_regs *oldregs)
 {
-	/* Dummy implementation for now */
+	if (oldregs)
+		memcpy(newregs, oldregs, sizeof(*newregs));
+	else
+		prepare_frametrace(newregs);
 }
 
+#ifdef CONFIG_KEXEC
+struct kimage;
+extern unsigned long kexec_args[4];
+extern int (*_machine_kexec_prepare)(struct kimage *);
+extern void (*_machine_kexec_shutdown)(void);
+extern void (*_machine_crash_shutdown)(struct pt_regs *regs);
+extern void default_machine_crash_shutdown(struct pt_regs *regs);
+#ifdef CONFIG_SMP
+extern const unsigned char kexec_smp_wait[];
+extern unsigned long secondary_kexec_args[4];
+extern void (*relocated_kexec_smp_wait) (void *);
+extern atomic_t kexec_ready_to_reboot;
+#endif
+#endif
+
 #endif /* !_MIPS_KEXEC */
diff --git a/arch/mips/include/asm/mach-ar7/war.h b/arch/mips/include/asm/mach-ar7/war.h
index f4862b5..99071e5 100644
--- a/arch/mips/include/asm/mach-ar7/war.h
+++ b/arch/mips/include/asm/mach-ar7/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
index 323d9f1..0bb3090 100644
--- a/arch/mips/include/asm/mach-ath79/war.h
+++ b/arch/mips/include/asm/mach-ath79/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-au1x00/war.h b/arch/mips/include/asm/mach-au1x00/war.h
index dd57d03..72e260d 100644
--- a/arch/mips/include/asm/mach-au1x00/war.h
+++ b/arch/mips/include/asm/mach-au1x00/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index 26fdaf4..cc7563b 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -44,8 +44,8 @@
 extern union bcm47xx_bus bcm47xx_bus;
 extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
-void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
-void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
+			bool fallback);
 
 #ifdef CONFIG_BCM47XX_SSB
 void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 2ef17e8..90daefa 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -1,155 +1,17 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
- */
+#ifndef __ASM_MIPS_MACH_BCM47XX_GPIO_H
+#define __ASM_MIPS_MACH_BCM47XX_GPIO_H
 
-#ifndef __BCM47XX_GPIO_H
-#define __BCM47XX_GPIO_H
+#include <asm-generic/gpio.h>
 
-#include <linux/ssb/ssb_embedded.h>
-#include <linux/bcma/bcma.h>
-#include <asm/mach-bcm47xx/bcm47xx.h>
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
 
-#define BCM47XX_EXTIF_GPIO_LINES	5
-#define BCM47XX_CHIPCO_GPIO_LINES	16
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
 
-extern int gpio_request(unsigned gpio, const char *label);
-extern void gpio_free(unsigned gpio);
-extern int gpio_to_irq(unsigned gpio);
-
-static inline int gpio_get_value(unsigned gpio)
+static inline int irq_to_gpio(unsigned int irq)
 {
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
-					   1 << gpio);
-#endif
-	}
 	return -EINVAL;
 }
 
-#define gpio_get_value_cansleep	gpio_get_value
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
-			     value ? 1 << gpio : 0);
-		return;
 #endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
-				     value ? 1 << gpio : 0);
-		return;
-#endif
-	}
-}
-
-#define gpio_set_value_cansleep gpio_set_value
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-	return 0;
-}
-
-static inline int gpio_is_valid(unsigned gpio)
-{
-	return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
-}
-
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
-		return 0;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
-				       0);
-		return 0;
-#endif
-	}
-	return -EINVAL;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		/* first set the gpio out value */
-		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
-			     value ? 1 << gpio : 0);
-		/* then set the gpio mode */
-		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
-		return 0;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		/* first set the gpio out value */
-		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
-				     value ? 1 << gpio : 0);
-		/* then set the gpio mode */
-		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
-				       1 << gpio);
-		return 0;
-#endif
-	}
-	return -EINVAL;
-}
-
-static inline int gpio_intmask(unsigned gpio, int value)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
-				 value ? 1 << gpio : 0);
-		return 0;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
-					 1 << gpio, value ? 1 << gpio : 0);
-		return 0;
-#endif
-	}
-	return -EINVAL;
-}
-
-static inline int gpio_polarity(unsigned gpio, int value)
-{
-	switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-	case BCM47XX_BUS_TYPE_SSB:
-		ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
-				  value ? 1 << gpio : 0);
-		return 0;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-	case BCM47XX_BUS_TYPE_BCMA:
-		bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
-					  1 << gpio, value ? 1 << gpio : 0);
-		return 0;
-#endif
-	}
-	return -EINVAL;
-}
-
-
-#endif /* __BCM47XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/war.h b/arch/mips/include/asm/mach-bcm47xx/war.h
index 87cd465..a3d2f44 100644
--- a/arch/mips/include/asm/mach-bcm47xx/war.h
+++ b/arch/mips/include/asm/mach-bcm47xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
new file mode 100644
index 0000000..62d6a3b
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
@@ -0,0 +1,35 @@
+#ifndef BCM63XX_NVRAM_H
+#define BCM63XX_NVRAM_H
+
+#include <linux/types.h>
+
+/**
+ * bcm63xx_nvram_init() - initializes nvram
+ * @nvram:	address of the nvram data
+ *
+ * Initialized the local nvram copy from the target address and checks
+ * its checksum.
+ *
+ * Returns 0 on success.
+ */
+int __init bcm63xx_nvram_init(void *nvram);
+
+/**
+ * bcm63xx_nvram_get_name() - returns the board name according to nvram
+ *
+ * Returns the board name field from nvram. Note that it might not be
+ * null terminated if it is exactly 16 bytes long.
+ */
+u8 *bcm63xx_nvram_get_name(void);
+
+/**
+ * bcm63xx_nvram_get_mac_address() - register & return a new mac address
+ * @mac:	pointer to array for allocated mac
+ *
+ * Registers and returns a mac address from the allocated macs from nvram.
+ *
+ * Returns 0 on success.
+ */
+int bcm63xx_nvram_get_mac_address(u8 *mac);
+
+#endif /* BCM63XX_NVRAM_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index 12963d0..c3eeb90 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -53,13 +53,18 @@
 					CKCTL_6338_SAR_EN |		\
 					CKCTL_6338_SPI_EN)
 
-#define CKCTL_6345_CPU_EN		(1 << 0)
-#define CKCTL_6345_BUS_EN		(1 << 1)
-#define CKCTL_6345_EBI_EN		(1 << 2)
-#define CKCTL_6345_UART_EN		(1 << 3)
-#define CKCTL_6345_ADSLPHY_EN		(1 << 4)
-#define CKCTL_6345_ENET_EN		(1 << 7)
-#define CKCTL_6345_USBH_EN		(1 << 8)
+/* BCM6345 clock bits are shifted by 16 on the left, because of the test
+ * control register which is 16-bits wide. That way we do not have any
+ * specific BCM6345 code for handling clocks, and writing 0 to the test
+ * control register is fine.
+ */
+#define CKCTL_6345_CPU_EN		(1 << 16)
+#define CKCTL_6345_BUS_EN		(1 << 17)
+#define CKCTL_6345_EBI_EN		(1 << 18)
+#define CKCTL_6345_UART_EN		(1 << 19)
+#define CKCTL_6345_ADSLPHY_EN		(1 << 20)
+#define CKCTL_6345_ENET_EN		(1 << 23)
+#define CKCTL_6345_USBH_EN		(1 << 24)
 
 #define CKCTL_6345_ALL_SAFE_EN		(CKCTL_6345_ENET_EN |	\
 					CKCTL_6345_USBH_EN |	\
@@ -191,6 +196,7 @@
 /* Soft Reset register */
 #define PERF_SOFTRESET_REG		0x28
 #define PERF_SOFTRESET_6328_REG		0x10
+#define PERF_SOFTRESET_6358_REG		0x34
 #define PERF_SOFTRESET_6368_REG		0x10
 
 #define SOFTRESET_6328_SPI_MASK		(1 << 0)
@@ -244,6 +250,15 @@
 				  SOFTRESET_6348_ACLC_MASK |		\
 				  SOFTRESET_6348_ADSLMIPSPLL_MASK)
 
+#define SOFTRESET_6358_SPI_MASK		(1 << 0)
+#define SOFTRESET_6358_ENET_MASK	(1 << 2)
+#define SOFTRESET_6358_MPI_MASK		(1 << 3)
+#define SOFTRESET_6358_EPHY_MASK	(1 << 6)
+#define SOFTRESET_6358_SAR_MASK		(1 << 7)
+#define SOFTRESET_6358_USBH_MASK	(1 << 12)
+#define SOFTRESET_6358_PCM_MASK		(1 << 13)
+#define SOFTRESET_6358_ADSL_MASK	(1 << 14)
+
 #define SOFTRESET_6368_SPI_MASK		(1 << 0)
 #define SOFTRESET_6368_MPI_MASK		(1 << 3)
 #define SOFTRESET_6368_EPHY_MASK	(1 << 6)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h
new file mode 100644
index 0000000..3a6eb9c
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h
@@ -0,0 +1,21 @@
+#ifndef __BCM63XX_RESET_H
+#define __BCM63XX_RESET_H
+
+enum bcm63xx_core_reset {
+	BCM63XX_RESET_SPI,
+	BCM63XX_RESET_ENET,
+	BCM63XX_RESET_USBH,
+	BCM63XX_RESET_USBD,
+	BCM63XX_RESET_SAR,
+	BCM63XX_RESET_DSL,
+	BCM63XX_RESET_EPHY,
+	BCM63XX_RESET_ENETSW,
+	BCM63XX_RESET_PCM,
+	BCM63XX_RESET_MPI,
+	BCM63XX_RESET_PCIE,
+	BCM63XX_RESET_PCIE_EXT,
+};
+
+void bcm63xx_core_set_reset(enum bcm63xx_core_reset, int reset);
+
+#endif
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
index b0dd4bb..682bcf3 100644
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -15,23 +15,6 @@
 #define BCM963XX_NVRAM_OFFSET		0x580
 
 /*
- * nvram structure
- */
-struct bcm963xx_nvram {
-	u32	version;
-	u8	reserved1[256];
-	u8	name[16];
-	u32	main_tp_number;
-	u32	psi_size;
-	u32	mac_addr_count;
-	u8	mac_addr_base[6];
-	u8	reserved2[2];
-	u32	checksum_old;
-	u8	reserved3[720];
-	u32	checksum_high;
-};
-
-/*
  * board definition
  */
 struct board_info {
diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h
index 8e3f3fd..05ee867 100644
--- a/arch/mips/include/asm/mach-bcm63xx/war.h
+++ b/arch/mips/include/asm/mach-bcm63xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index ff0d490..502bb18 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -42,7 +42,6 @@
 	OCTEON_IRQ_TIMER3,
 	OCTEON_IRQ_USB0,
 	OCTEON_IRQ_USB1,
-	OCTEON_IRQ_BOOTDMA,
 #ifndef CONFIG_PCI_MSI
 	OCTEON_IRQ_LAST = 127
 #endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h
index c4712d7..eb72b35 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/war.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/war.h
@@ -18,7 +18,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-cobalt/war.h b/arch/mips/include/asm/mach-cobalt/war.h
index 97884fd..34ae404 100644
--- a/arch/mips/include/asm/mach-cobalt/war.h
+++ b/arch/mips/include/asm/mach-cobalt/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-dec/war.h b/arch/mips/include/asm/mach-dec/war.h
index ca5e2ef..d29996f 100644
--- a/arch/mips/include/asm/mach-dec/war.h
+++ b/arch/mips/include/asm/mach-dec/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-emma2rh/war.h b/arch/mips/include/asm/mach-emma2rh/war.h
index b660a4c..79ae82d 100644
--- a/arch/mips/include/asm/mach-emma2rh/war.h
+++ b/arch/mips/include/asm/mach-emma2rh/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h
index 70d9a25..e014264 100644
--- a/arch/mips/include/asm/mach-generic/irq.h
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -34,12 +34,6 @@
 #endif
 #endif
 
-#ifdef CONFIG_IRQ_CPU_RM9K
-#ifndef RM9K_CPU_IRQ_BASE
-#define RM9K_CPU_IRQ_BASE (MIPS_CPU_IRQ_BASE+12)
-#endif
-#endif
-
 #endif /* CONFIG_IRQ_CPU */
 
 #endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h
index a44fa96..fba6405 100644
--- a/arch/mips/include/asm/mach-ip22/war.h
+++ b/arch/mips/include/asm/mach-ip22/war.h
@@ -21,7 +21,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-ip27/war.h b/arch/mips/include/asm/mach-ip27/war.h
index e2ddcc9..4ee0e4b 100644
--- a/arch/mips/include/asm/mach-ip27/war.h
+++ b/arch/mips/include/asm/mach-ip27/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			1
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-ip28/war.h b/arch/mips/include/asm/mach-ip28/war.h
index a1baafa..4821c7b 100644
--- a/arch/mips/include/asm/mach-ip28/war.h
+++ b/arch/mips/include/asm/mach-ip28/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			1
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-ip32/war.h b/arch/mips/include/asm/mach-ip32/war.h
index d194056..7237a93 100644
--- a/arch/mips/include/asm/mach-ip32/war.h
+++ b/arch/mips/include/asm/mach-ip32/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR   1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-jazz/war.h b/arch/mips/include/asm/mach-jazz/war.h
index 6158ee8..5b18b9a 100644
--- a/arch/mips/include/asm/mach-jazz/war.h
+++ b/arch/mips/include/asm/mach-jazz/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
index 3a5bc17..9b511d3 100644
--- a/arch/mips/include/asm/mach-jz4740/war.h
+++ b/arch/mips/include/asm/mach-jz4740/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h
index 01b08ef..b6c568c 100644
--- a/arch/mips/include/asm/mach-lantiq/war.h
+++ b/arch/mips/include/asm/mach-lantiq/war.h
@@ -16,7 +16,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR        0
 #define MIPS_CACHE_SYNC_WAR             0
 #define TX49XX_ICACHE_INDEX_INV_WAR     0
-#define RM9000_CDEX_SMP_WAR             0
 #define ICACHE_REFILLS_WORKAROUND_WAR   0
 #define R10000_LLSC_WAR                 0
 #define MIPS34K_MISSED_ITLB_WAR         0
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index 6a2df70..133336b 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -82,6 +82,9 @@
 #define LTQ_MPS_BASE_ADDR	(KSEG1 + 0x1F107000)
 #define LTQ_MPS_CHIPID		((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
 
+/* allow booting xrx200 phys */
+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr);
+
 /* request a non-gpio and set the PIO config */
 #define PMU_PPE			 BIT(13)
 extern void ltq_pmu_enable(unsigned int module);
diff --git a/arch/mips/include/asm/mach-lasat/war.h b/arch/mips/include/asm/mach-lasat/war.h
index bb1e032..741ae72 100644
--- a/arch/mips/include/asm/mach-lasat/war.h
+++ b/arch/mips/include/asm/mach-lasat/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h
index 4b971c3..f2570df 100644
--- a/arch/mips/include/asm/mach-loongson/war.h
+++ b/arch/mips/include/asm/mach-loongson/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h
index 2f17161..718a122 100644
--- a/arch/mips/include/asm/mach-loongson1/platform.h
+++ b/arch/mips/include/asm/mach-loongson1/platform.h
@@ -18,6 +18,7 @@
 extern struct platform_device ls1x_ehci_device;
 extern struct platform_device ls1x_rtc_device;
 
-void ls1x_serial_setup(void);
+extern void __init ls1x_clk_init(void);
+extern void __init ls1x_serial_setup(struct platform_device *pdev);
 
 #endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h
index 8efa7fb..a81fa3d 100644
--- a/arch/mips/include/asm/mach-loongson1/regs-clk.h
+++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h
@@ -20,14 +20,15 @@
 
 /* Clock PLL Divisor Register Bits */
 #define DIV_DC_EN			(0x1 << 31)
-#define DIV_DC				(0x1f << 26)
 #define DIV_CPU_EN			(0x1 << 25)
-#define DIV_CPU				(0x1f << 20)
 #define DIV_DDR_EN			(0x1 << 19)
-#define DIV_DDR				(0x1f << 14)
 
 #define DIV_DC_SHIFT			26
 #define DIV_CPU_SHIFT			20
 #define DIV_DDR_SHIFT			14
 
+#define DIV_DC_WIDTH			5
+#define DIV_CPU_WIDTH			5
+#define DIV_DDR_WIDTH			5
+
 #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
diff --git a/arch/mips/include/asm/mach-loongson1/war.h b/arch/mips/include/asm/mach-loongson1/war.h
index e3680a8..8fb50d0 100644
--- a/arch/mips/include/asm/mach-loongson1/war.h
+++ b/arch/mips/include/asm/mach-loongson1/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-malta/war.h b/arch/mips/include/asm/mach-malta/war.h
index 7c6931d..d068fc4 100644
--- a/arch/mips/include/asm/mach-malta/war.h
+++ b/arch/mips/include/asm/mach-malta/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	1
 #define MIPS_CACHE_SYNC_WAR		1
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-netlogic/irq.h b/arch/mips/include/asm/mach-netlogic/irq.h
index b590245..868ed8a 100644
--- a/arch/mips/include/asm/mach-netlogic/irq.h
+++ b/arch/mips/include/asm/mach-netlogic/irq.h
@@ -8,7 +8,9 @@
 #ifndef __ASM_NETLOGIC_IRQ_H
 #define __ASM_NETLOGIC_IRQ_H
 
-#define NR_IRQS			64
+#include <asm/mach-netlogic/multi-node.h>
+#define NR_IRQS			(64 * NLM_NR_NODES)
+
 #define MIPS_CPU_IRQ_BASE	0
 
 #endif /* __ASM_NETLOGIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-netlogic/multi-node.h b/arch/mips/include/asm/mach-netlogic/multi-node.h
new file mode 100644
index 0000000..d62fc77
--- /dev/null
+++ b/arch/mips/include/asm/mach-netlogic/multi-node.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NETLOGIC_MULTI_NODE_H_
+#define _NETLOGIC_MULTI_NODE_H_
+
+#ifndef CONFIG_NLM_MULTINODE
+#define NLM_NR_NODES		1
+#else
+#if defined(CONFIG_NLM_MULTINODE_2)
+#define NLM_NR_NODES		2
+#elif defined(CONFIG_NLM_MULTINODE_4)
+#define NLM_NR_NODES		4
+#else
+#define NLM_NR_NODES		1
+#endif
+#endif
+
+#define NLM_CORES_PER_NODE	8
+#define NLM_THREADS_PER_CORE	4
+#define NLM_CPUS_PER_NODE	(NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE)
+
+#endif
diff --git a/arch/mips/include/asm/mach-netlogic/war.h b/arch/mips/include/asm/mach-netlogic/war.h
index 22da893..2c72168 100644
--- a/arch/mips/include/asm/mach-netlogic/war.h
+++ b/arch/mips/include/asm/mach-netlogic/war.h
@@ -18,7 +18,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h
index 82cd1e9..edaa06d 100644
--- a/arch/mips/include/asm/mach-pnx833x/war.h
+++ b/arch/mips/include/asm/mach-pnx833x/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-pnx8550/war.h b/arch/mips/include/asm/mach-pnx8550/war.h
index d0458dd..de8894c 100644
--- a/arch/mips/include/asm/mach-pnx8550/war.h
+++ b/arch/mips/include/asm/mach-pnx8550/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h
index 7ac05ec..c5651c8 100644
--- a/arch/mips/include/asm/mach-powertv/war.h
+++ b/arch/mips/include/asm/mach-powertv/war.h
@@ -20,7 +20,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	1
 #define MIPS_CACHE_SYNC_WAR		1
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-rc32434/war.h b/arch/mips/include/asm/mach-rc32434/war.h
index 3ddf187..1bfd489a 100644
--- a/arch/mips/include/asm/mach-rc32434/war.h
+++ b/arch/mips/include/asm/mach-rc32434/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	1
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-rm/war.h b/arch/mips/include/asm/mach-rm/war.h
index 948d312..a3dde98 100644
--- a/arch/mips/include/asm/mach-rm/war.h
+++ b/arch/mips/include/asm/mach-rm/war.h
@@ -21,7 +21,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-sead3/war.h b/arch/mips/include/asm/mach-sead3/war.h
index 7c6931d..d068fc4 100644
--- a/arch/mips/include/asm/mach-sead3/war.h
+++ b/arch/mips/include/asm/mach-sead3/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	1
 #define MIPS_CACHE_SYNC_WAR		1
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h
index 743385d..176f5b3 100644
--- a/arch/mips/include/asm/mach-sibyte/war.h
+++ b/arch/mips/include/asm/mach-sibyte/war.h
@@ -33,7 +33,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-tx39xx/war.h b/arch/mips/include/asm/mach-tx39xx/war.h
index 4338146..6a52e65 100644
--- a/arch/mips/include/asm/mach-tx39xx/war.h
+++ b/arch/mips/include/asm/mach-tx39xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-tx49xx/war.h b/arch/mips/include/asm/mach-tx49xx/war.h
index 39b5d11..a8e2c58 100644
--- a/arch/mips/include/asm/mach-tx49xx/war.h
+++ b/arch/mips/include/asm/mach-tx49xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	1
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-vr41xx/war.h b/arch/mips/include/asm/mach-vr41xx/war.h
index 56a3892..ffe31e7 100644
--- a/arch/mips/include/asm/mach-vr41xx/war.h
+++ b/arch/mips/include/asm/mach-vr41xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-wrppmc/war.h b/arch/mips/include/asm/mach-wrppmc/war.h
index ac48629..e86084c 100644
--- a/arch/mips/include/asm/mach-wrppmc/war.h
+++ b/arch/mips/include/asm/mach-wrppmc/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
diff --git a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
deleted file mode 100644
index 56bdd32..0000000
--- a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
- */
-#ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H
-
-/*
- * Momentum Jaguar ATX always has the RM9000 processor.
- */
-#define cpu_has_watch		1
-#define cpu_has_mips16		0
-#define cpu_has_divec		0
-#define cpu_has_vce		0
-#define cpu_has_cache_cdex_p	0
-#define cpu_has_cache_cdex_s	0
-#define cpu_has_prefetch	1
-#define cpu_has_mcheck		0
-#define cpu_has_ejtag		0
-
-#define cpu_has_llsc		1
-#define cpu_has_vtag_icache	0
-#define cpu_has_dc_aliases	0
-#define cpu_has_ic_fills_f_dc	0
-#define cpu_has_dsp		0
-#define cpu_has_dsp2		0
-#define cpu_has_mipsmt		0
-#define cpu_has_userlocal	0
-#define cpu_icache_snoops_remote_store	0
-
-#define cpu_has_nofpuex		0
-#define cpu_has_64bits		1
-
-#define cpu_has_inclusive_pcaches	0
-
-#define cpu_dcache_line_size()	32
-#define cpu_icache_line_size()	32
-#define cpu_scache_line_size()	32
-
-#define cpu_has_mips32r1	0
-#define cpu_has_mips32r2	0
-#define cpu_has_mips64r1	0
-#define cpu_has_mips64r2	0
-
-#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-yosemite/war.h b/arch/mips/include/asm/mach-yosemite/war.h
deleted file mode 100644
index e5c6d53..0000000
--- a/arch/mips/include/asm/mach-yosemite/war.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_YOSEMITE_WAR_H
-#define __ASM_MIPS_MACH_YOSEMITE_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR	0
-#define R4600_V1_HIT_CACHEOP_WAR	0
-#define R4600_V2_HIT_CACHEOP_WAR	0
-#define R5432_CP0_INTERRUPT_WAR		0
-#define BCM1250_M3_WAR			0
-#define SIBYTE_1956_WAR			0
-#define MIPS4K_ICACHE_REFILL_WAR	0
-#define MIPS_CACHE_SYNC_WAR		0
-#define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		1
-#define ICACHE_REFILLS_WORKAROUND_WAR	1
-#define R10000_LLSC_WAR			0
-#define MIPS34K_MISSED_ITLB_WAR		0
-
-#endif /* __ASM_MIPS_MACH_YOSEMITE_WAR_H */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index eb74289..7e4e6f8 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -240,7 +240,7 @@
 #define PM_HUGE_MASK	PM_64M
 #elif defined(CONFIG_PAGE_SIZE_64KB)
 #define PM_HUGE_MASK	PM_256M
-#elif defined(CONFIG_HUGETLB_PAGE)
+#elif defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
 #error Bad page size configuration for hugetlbfs!
 #endif
 
@@ -977,10 +977,6 @@
 #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
 #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
 
-/* RM9000 PerfControl performance counter control register */
-#define read_c0_perfcontrol()	__read_32bit_c0_register($22, 0)
-#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
-
 #define read_c0_diag()		__read_32bit_c0_register($22, 0)
 #define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
 
@@ -1033,10 +1029,6 @@
 #define read_c0_perfcntr3_64()	__read_64bit_c0_register($25, 7)
 #define write_c0_perfcntr3_64(val) __write_64bit_c0_register($25, 7, val)
 
-/* RM9000 PerfCount performance counter register */
-#define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
-#define write_c0_perfcount(val)	__write_64bit_c0_register($25, 0, val)
-
 #define read_c0_ecc()		__read_32bit_c0_register($26, 0)
 #define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
 
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 9b02cfb..45cfa1a 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -72,12 +72,6 @@
 #define ASID_INC	0x10
 #define ASID_MASK	0xff0
 
-#elif defined(CONFIG_CPU_RM9000)
-
-#define ASID_INC	0x1
-#define ASID_MASK	0xfff
-
-/* SMTC/34K debug hack - but maybe we'll keep it */
 #elif defined(CONFIG_MIPS_MT_SMTC)
 
 #define ASID_INC	0x1
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 26137da..44b705d 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -120,8 +120,6 @@
 #define MODULE_PROC_FAMILY "R10000 "
 #elif defined CONFIG_CPU_RM7000
 #define MODULE_PROC_FAMILY "RM7000 "
-#elif defined CONFIG_CPU_RM9000
-#define MODULE_PROC_FAMILY "RM9000 "
 #elif defined CONFIG_CPU_SB1
 #define MODULE_PROC_FAMILY "SB1 "
 #elif defined CONFIG_CPU_LOONGSON1
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
index fdd2f44..42bfd5f 100644
--- a/arch/mips/include/asm/netlogic/common.h
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -45,15 +45,19 @@
 #define	BOOT_NMI_HANDLER	8
 
 #ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+#include <asm/mach-netlogic/multi-node.h>
+
 struct irq_desc;
-extern struct plat_smp_ops nlm_smp_ops;
-extern char nlm_reset_entry[], nlm_reset_entry_end[];
 void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
-void nlm_smp_irq_init(void);
+void nlm_smp_irq_init(int hwcpuid);
 void nlm_boot_secondary_cpus(void);
-int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
+int nlm_wakeup_secondary_cpus(void);
 void nlm_rmiboot_preboot(void);
+void nlm_percpu_init(int hwcpuid);
 
 static inline void
 nlm_set_nmi_handler(void *handler)
@@ -68,9 +72,42 @@
  * Misc.
  */
 unsigned int nlm_get_cpu_frequency(void);
+void nlm_node_init(int node);
+extern struct plat_smp_ops nlm_smp_ops;
+extern char nlm_reset_entry[], nlm_reset_entry_end[];
 
-extern unsigned long nlm_common_ebase;
-extern int nlm_threads_per_core;
-extern uint32_t nlm_cpumask, nlm_coremask;
+extern unsigned int nlm_threads_per_core;
+extern cpumask_t nlm_cpumask;
+
+struct nlm_soc_info {
+	unsigned long coremask;	/* cores enabled on the soc */
+	unsigned long ebase;
+	uint64_t irqmask;
+	uint64_t sysbase;	/* only for XLP */
+	uint64_t picbase;
+	spinlock_t piclock;
+};
+
+#define	nlm_get_node(i)		(&nlm_nodes[i])
+#ifdef CONFIG_CPU_XLR
+#define	nlm_current_node()	(&nlm_nodes[0])
+#else
+#define nlm_current_node()	(&nlm_nodes[nlm_nodeid()])
+#endif
+
+struct irq_data;
+uint64_t nlm_pci_irqmask(int node);
+void nlm_set_pic_extra_ack(int node, int irq,  void (*xack)(struct irq_data *));
+
+/*
+ * The NR_IRQs is divided between nodes, each of them has a separate irq space
+ */
+static inline int nlm_irq_to_xirq(int node, int irq)
+{
+	return node * NR_IRQS / NLM_NR_NODES + irq;
+}
+
+extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
+extern int nlm_cpu_ready[];
 #endif
 #endif /* _NETLOGIC_COMMON_H_ */
diff --git a/arch/mips/include/asm/netlogic/interrupt.h b/arch/mips/include/asm/netlogic/interrupt.h
index a85aadb..ed5993d 100644
--- a/arch/mips/include/asm/netlogic/interrupt.h
+++ b/arch/mips/include/asm/netlogic/interrupt.h
@@ -39,7 +39,7 @@
 
 #define IRQ_IPI_SMP_FUNCTION	3
 #define IRQ_IPI_SMP_RESCHEDULE	4
-#define IRQ_MSGRING		6
+#define IRQ_FMN			5
 #define IRQ_TIMER		7
 
 #endif
diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h
index 8c53d0b..32ba6d9 100644
--- a/arch/mips/include/asm/netlogic/mips-extns.h
+++ b/arch/mips/include/asm/netlogic/mips-extns.h
@@ -73,4 +73,146 @@
 	return __read_32bit_c0_register($15, 1) & 0x3ff;
 }
 
+static inline int nlm_nodeid(void)
+{
+	return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
+}
+
+static inline unsigned int nlm_core_id(void)
+{
+	return (read_c0_ebase() & 0x1c) >> 2;
+}
+
+static inline unsigned int nlm_thread_id(void)
+{
+	return read_c0_ebase() & 0x3;
+}
+
+#define __read_64bit_c2_split(source, sel)				\
+({									\
+	unsigned long long __val;					\
+	unsigned long __flags;						\
+									\
+	local_irq_save(__flags);					\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc2\t%M0, " #source "\n\t"			\
+			"dsll\t%L0, %M0, 32\n\t"			\
+			"dsra\t%M0, %M0, 32\n\t"			\
+			"dsra\t%L0, %L0, 32\n\t"			\
+			".set\tmips0\n\t"				\
+			: "=r" (__val));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc2\t%M0, " #source ", " #sel "\n\t"		\
+			"dsll\t%L0, %M0, 32\n\t"			\
+			"dsra\t%M0, %M0, 32\n\t"			\
+			"dsra\t%L0, %L0, 32\n\t"			\
+			".set\tmips0\n\t"				\
+			: "=r" (__val));				\
+	local_irq_restore(__flags);					\
+									\
+	__val;								\
+})
+
+#define __write_64bit_c2_split(source, sel, val)			\
+do {									\
+	unsigned long __flags;						\
+									\
+	local_irq_save(__flags);					\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dsll\t%L0, %L0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsll\t%M0, %M0, 32\n\t"			\
+			"or\t%L0, %L0, %M0\n\t"				\
+			"dmtc2\t%L0, " #source "\n\t"			\
+			".set\tmips0\n\t"				\
+			: : "r" (val));					\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dsll\t%L0, %L0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsll\t%M0, %M0, 32\n\t"			\
+			"or\t%L0, %L0, %M0\n\t"				\
+			"dmtc2\t%L0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: : "r" (val));					\
+	local_irq_restore(__flags);					\
+} while (0)
+
+#define __read_32bit_c2_register(source, sel)				\
+({ uint32_t __res;							\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mfc2\t%0, " #source "\n\t"			\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mfc2\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	__res;								\
+})
+
+#define __read_64bit_c2_register(source, sel)				\
+({ unsigned long long __res;						\
+	if (sizeof(unsigned long) == 4)					\
+		__res = __read_64bit_c2_split(source, sel);		\
+	else if (sel == 0)						\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc2\t%0, " #source "\n\t"			\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmfc2\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	__res;								\
+})
+
+#define __write_64bit_c2_register(register, sel, value)			\
+do {									\
+	if (sizeof(unsigned long) == 4)					\
+		__write_64bit_c2_split(register, sel, value);		\
+	else if (sel == 0)						\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmtc2\t%z0, " #register "\n\t"			\
+			".set\tmips0\n\t"				\
+			: : "Jr" (value));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dmtc2\t%z0, " #register ", " #sel "\n\t"	\
+			".set\tmips0\n\t"				\
+			: : "Jr" (value));				\
+} while (0)
+
+#define __write_32bit_c2_register(reg, sel, value)			\
+({									\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mtc2\t%z0, " #reg "\n\t"			\
+			".set\tmips0\n\t"				\
+			: : "Jr" (value));				\
+	else								\
+		__asm__ __volatile__(                                   \
+			".set\tmips32\n\t"				\
+			"mtc2\t%z0, " #reg ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: : "Jr" (value));				\
+})
+
 #endif /*_ASM_NLM_MIPS_EXTS_H */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
index ad8b802..b2e53a5 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
@@ -273,36 +273,16 @@
 	return nlm_read_pic_reg(base, PIC_IRT(irt_index));
 }
 
-static inline uint64_t
-nlm_pic_read_control(uint64_t base)
-{
-	return nlm_read_pic_reg(base, PIC_CTRL);
-}
-
-static inline void
-nlm_pic_write_control(uint64_t base, uint64_t control)
-{
-	nlm_write_pic_reg(base, PIC_CTRL, control);
-}
-
-static inline void
-nlm_pic_update_control(uint64_t base, uint64_t control)
-{
-	uint64_t val;
-
-	val = nlm_read_pic_reg(base, PIC_CTRL);
-	nlm_write_pic_reg(base, PIC_CTRL, control | val);
-}
-
 static inline void
 nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu)
 {
 	uint64_t val;
 
 	val = nlm_read_pic_reg(base, PIC_IRT(irt));
-	val |= cpu & 0xf;
-	if (cpu > 15)
-		val |= 1 << 16;
+	/* clear cpuset and mask */
+	val &= ~((0x7ull << 16) | 0xffff);
+	/* set DB, cpuset and cpumask */
+	val |= (1 << 19) | ((cpu >> 4) << 16) | (1 << (cpu & 0xf));
 	nlm_write_pic_reg(base, PIC_IRT(irt), val);
 }
 
@@ -369,7 +349,7 @@
 static inline void
 nlm_pic_disable_irt(uint64_t base, int irt)
 {
-	uint32_t reg;
+	uint64_t reg;
 
 	reg = nlm_read_pic_reg(base, PIC_IRT(irt));
 	nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31));
@@ -379,15 +359,9 @@
 nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
 {
 	uint64_t ipi;
-	int	node, ncpu;
 
-	node = hwt / 32;
-	ncpu = hwt & 0x1f;
-	ipi = ((uint64_t)nmi << 31) | (irq << 20) | (node << 17) |
-		(1 << (ncpu & 0xf));
-	if (ncpu > 15)
-		ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */
-
+	ipi = (nmi << 31) | (irq << 20);
+	ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */
 	nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
 }
 
@@ -404,12 +378,10 @@
 static inline void
 nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
 {
-	nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, 0);
+	nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt);
 }
 
-extern uint64_t nlm_pic_base;
 int nlm_irq_to_irt(int irq);
-int nlm_irt_to_irq(int irt);
 
 #endif /* __ASSEMBLY__ */
 #endif /* _NLM_HAL_PIC_H */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
index 21432f7..258e8cc 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/sys.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
@@ -124,6 +124,5 @@
 #define	nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
 #define	nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
-extern uint64_t nlm_sys_base;
 #endif
 #endif
diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h
new file mode 100644
index 0000000..68d5167
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/fmn.h
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NLM_FMN_H_
+#define _NLM_FMN_H_
+
+#include <asm/netlogic/mips-extns.h> /* for COP2 access */
+
+/* Station IDs */
+#define	FMN_STNID_CPU0			0x00
+#define	FMN_STNID_CPU1			0x08
+#define	FMN_STNID_CPU2			0x10
+#define	FMN_STNID_CPU3			0x18
+#define	FMN_STNID_CPU4			0x20
+#define	FMN_STNID_CPU5			0x28
+#define	FMN_STNID_CPU6			0x30
+#define	FMN_STNID_CPU7			0x38
+
+#define	FMN_STNID_XGS0_TX		64
+#define	FMN_STNID_XMAC0_00_TX		64
+#define	FMN_STNID_XMAC0_01_TX		65
+#define	FMN_STNID_XMAC0_02_TX		66
+#define	FMN_STNID_XMAC0_03_TX		67
+#define	FMN_STNID_XMAC0_04_TX		68
+#define	FMN_STNID_XMAC0_05_TX		69
+#define	FMN_STNID_XMAC0_06_TX		70
+#define	FMN_STNID_XMAC0_07_TX		71
+#define	FMN_STNID_XMAC0_08_TX		72
+#define	FMN_STNID_XMAC0_09_TX		73
+#define	FMN_STNID_XMAC0_10_TX		74
+#define	FMN_STNID_XMAC0_11_TX		75
+#define	FMN_STNID_XMAC0_12_TX		76
+#define	FMN_STNID_XMAC0_13_TX		77
+#define	FMN_STNID_XMAC0_14_TX		78
+#define	FMN_STNID_XMAC0_15_TX		79
+
+#define	FMN_STNID_XGS1_TX		80
+#define	FMN_STNID_XMAC1_00_TX		80
+#define	FMN_STNID_XMAC1_01_TX		81
+#define	FMN_STNID_XMAC1_02_TX		82
+#define	FMN_STNID_XMAC1_03_TX		83
+#define	FMN_STNID_XMAC1_04_TX		84
+#define	FMN_STNID_XMAC1_05_TX		85
+#define	FMN_STNID_XMAC1_06_TX		86
+#define	FMN_STNID_XMAC1_07_TX		87
+#define	FMN_STNID_XMAC1_08_TX		88
+#define	FMN_STNID_XMAC1_09_TX		89
+#define	FMN_STNID_XMAC1_10_TX		90
+#define	FMN_STNID_XMAC1_11_TX		91
+#define	FMN_STNID_XMAC1_12_TX		92
+#define	FMN_STNID_XMAC1_13_TX		93
+#define	FMN_STNID_XMAC1_14_TX		94
+#define	FMN_STNID_XMAC1_15_TX		95
+
+#define	FMN_STNID_GMAC			96
+#define	FMN_STNID_GMACJFR_0		96
+#define	FMN_STNID_GMACRFR_0		97
+#define	FMN_STNID_GMACTX0		98
+#define	FMN_STNID_GMACTX1		99
+#define	FMN_STNID_GMACTX2		100
+#define	FMN_STNID_GMACTX3		101
+#define	FMN_STNID_GMACJFR_1		102
+#define	FMN_STNID_GMACRFR_1		103
+
+#define	FMN_STNID_DMA			104
+#define	FMN_STNID_DMA_0			104
+#define	FMN_STNID_DMA_1			105
+#define	FMN_STNID_DMA_2			106
+#define	FMN_STNID_DMA_3			107
+
+#define	FMN_STNID_XGS0FR		112
+#define	FMN_STNID_XMAC0JFR		112
+#define	FMN_STNID_XMAC0RFR		113
+
+#define	FMN_STNID_XGS1FR		114
+#define	FMN_STNID_XMAC1JFR		114
+#define	FMN_STNID_XMAC1RFR		115
+#define	FMN_STNID_SEC			120
+#define	FMN_STNID_SEC0			120
+#define	FMN_STNID_SEC1			121
+#define	FMN_STNID_SEC2			122
+#define	FMN_STNID_SEC3			123
+#define	FMN_STNID_PK0			124
+#define	FMN_STNID_SEC_RSA		124
+#define	FMN_STNID_SEC_RSVD0		125
+#define	FMN_STNID_SEC_RSVD1		126
+#define	FMN_STNID_SEC_RSVD2		127
+
+#define	FMN_STNID_GMAC1			80
+#define	FMN_STNID_GMAC1_FR_0		81
+#define	FMN_STNID_GMAC1_TX0		82
+#define	FMN_STNID_GMAC1_TX1		83
+#define	FMN_STNID_GMAC1_TX2		84
+#define	FMN_STNID_GMAC1_TX3		85
+#define	FMN_STNID_GMAC1_FR_1		87
+#define	FMN_STNID_GMAC0			96
+#define	FMN_STNID_GMAC0_FR_0		97
+#define	FMN_STNID_GMAC0_TX0		98
+#define	FMN_STNID_GMAC0_TX1		99
+#define	FMN_STNID_GMAC0_TX2		100
+#define	FMN_STNID_GMAC0_TX3		101
+#define	FMN_STNID_GMAC0_FR_1		103
+#define	FMN_STNID_CMP_0			108
+#define	FMN_STNID_CMP_1			109
+#define	FMN_STNID_CMP_2			110
+#define	FMN_STNID_CMP_3			111
+#define	FMN_STNID_PCIE_0		116
+#define	FMN_STNID_PCIE_1		117
+#define	FMN_STNID_PCIE_2		118
+#define	FMN_STNID_PCIE_3		119
+#define	FMN_STNID_XLS_PK0		121
+
+#define nlm_read_c2_cc0(s)		__read_32bit_c2_register($16, s)
+#define nlm_read_c2_cc1(s)		__read_32bit_c2_register($17, s)
+#define nlm_read_c2_cc2(s)		__read_32bit_c2_register($18, s)
+#define nlm_read_c2_cc3(s)		__read_32bit_c2_register($19, s)
+#define nlm_read_c2_cc4(s)		__read_32bit_c2_register($20, s)
+#define nlm_read_c2_cc5(s)		__read_32bit_c2_register($21, s)
+#define nlm_read_c2_cc6(s)		__read_32bit_c2_register($22, s)
+#define nlm_read_c2_cc7(s)		__read_32bit_c2_register($23, s)
+#define nlm_read_c2_cc8(s)		__read_32bit_c2_register($24, s)
+#define nlm_read_c2_cc9(s)		__read_32bit_c2_register($25, s)
+#define nlm_read_c2_cc10(s)		__read_32bit_c2_register($26, s)
+#define nlm_read_c2_cc11(s)		__read_32bit_c2_register($27, s)
+#define nlm_read_c2_cc12(s)		__read_32bit_c2_register($28, s)
+#define nlm_read_c2_cc13(s)		__read_32bit_c2_register($29, s)
+#define nlm_read_c2_cc14(s)		__read_32bit_c2_register($30, s)
+#define nlm_read_c2_cc15(s)		__read_32bit_c2_register($31, s)
+
+#define nlm_write_c2_cc0(s, v)		__write_32bit_c2_register($16, s, v)
+#define nlm_write_c2_cc1(s, v)		__write_32bit_c2_register($17, s, v)
+#define nlm_write_c2_cc2(s, v)		__write_32bit_c2_register($18, s, v)
+#define nlm_write_c2_cc3(s, v)		__write_32bit_c2_register($19, s, v)
+#define nlm_write_c2_cc4(s, v)		__write_32bit_c2_register($20, s, v)
+#define nlm_write_c2_cc5(s, v)		__write_32bit_c2_register($21, s, v)
+#define nlm_write_c2_cc6(s, v)		__write_32bit_c2_register($22, s, v)
+#define nlm_write_c2_cc7(s, v)		__write_32bit_c2_register($23, s, v)
+#define nlm_write_c2_cc8(s, v)		__write_32bit_c2_register($24, s, v)
+#define nlm_write_c2_cc9(s, v)		__write_32bit_c2_register($25, s, v)
+#define nlm_write_c2_cc10(s, v)		__write_32bit_c2_register($26, s, v)
+#define nlm_write_c2_cc11(s, v)		__write_32bit_c2_register($27, s, v)
+#define nlm_write_c2_cc12(s, v)		__write_32bit_c2_register($28, s, v)
+#define nlm_write_c2_cc13(s, v)		__write_32bit_c2_register($29, s, v)
+#define nlm_write_c2_cc14(s, v)		__write_32bit_c2_register($30, s, v)
+#define nlm_write_c2_cc15(s, v)		__write_32bit_c2_register($31, s, v)
+
+#define	nlm_read_c2_status(sel)		__read_32bit_c2_register($2, 0)
+#define	nlm_read_c2_config()		__read_32bit_c2_register($3, 0)
+#define	nlm_write_c2_config(v)		__write_32bit_c2_register($3, 0, v)
+#define	nlm_read_c2_bucksize(b)		__read_32bit_c2_register($4, b)
+#define	nlm_write_c2_bucksize(b, v)	__write_32bit_c2_register($4, b, v)
+
+#define	nlm_read_c2_rx_msg0()		__read_64bit_c2_register($1, 0)
+#define	nlm_read_c2_rx_msg1()		__read_64bit_c2_register($1, 1)
+#define	nlm_read_c2_rx_msg2()		__read_64bit_c2_register($1, 2)
+#define	nlm_read_c2_rx_msg3()		__read_64bit_c2_register($1, 3)
+
+#define	nlm_write_c2_tx_msg0(v)		__write_64bit_c2_register($0, 0, v)
+#define	nlm_write_c2_tx_msg1(v)		__write_64bit_c2_register($0, 1, v)
+#define	nlm_write_c2_tx_msg2(v)		__write_64bit_c2_register($0, 2, v)
+#define	nlm_write_c2_tx_msg3(v)		__write_64bit_c2_register($0, 3, v)
+
+#define	FMN_STN_RX_QSIZE		256
+#define	FMN_NSTATIONS			128
+#define	FMN_CORE_NBUCKETS		8
+
+static inline void nlm_msgsnd(unsigned int stid)
+{
+	__asm__ volatile (
+	    ".set	push\n"
+	    ".set	noreorder\n"
+	    ".set	noat\n"
+	    "move	$1, %0\n"
+	    "c2		0x10001\n"	/* msgsnd $1 */
+	    ".set	pop\n"
+	    : : "r" (stid) : "$1"
+	);
+}
+
+static inline void nlm_msgld(unsigned int pri)
+{
+	__asm__ volatile (
+	    ".set	push\n"
+	    ".set	noreorder\n"
+	    ".set	noat\n"
+	    "move	$1, %0\n"
+	    "c2		0x10002\n"    /* msgld $1 */
+	    ".set	pop\n"
+	    : : "r" (pri) : "$1"
+	);
+}
+
+static inline void nlm_msgwait(unsigned int mask)
+{
+	__asm__ volatile (
+	    ".set	push\n"
+	    ".set	noreorder\n"
+	    ".set	noat\n"
+	    "move	$8, %0\n"
+	    "c2		0x10003\n"    /* msgwait $1 */
+	    ".set	pop\n"
+	    : : "r" (mask) : "$1"
+	);
+}
+
+/*
+ * Disable interrupts and enable COP2 access
+ */
+static inline uint32_t nlm_cop2_enable(void)
+{
+	uint32_t sr = read_c0_status();
+
+	write_c0_status((sr & ~ST0_IE) | ST0_CU2);
+	return sr;
+}
+
+static inline void nlm_cop2_restore(uint32_t sr)
+{
+	write_c0_status(sr);
+}
+
+static inline void nlm_fmn_setup_intr(int irq, unsigned int tmask)
+{
+	uint32_t config;
+
+	config = (1 << 24)	/* interrupt water mark - 1 msg */
+		| (irq << 16)	/* irq */
+		| (tmask << 8)	/* thread mask */
+		| 0x2;		/* enable watermark intr, disable empty intr */
+	nlm_write_c2_config(config);
+}
+
+struct nlm_fmn_msg {
+	uint64_t msg0;
+	uint64_t msg1;
+	uint64_t msg2;
+	uint64_t msg3;
+};
+
+static inline int nlm_fmn_send(unsigned int size, unsigned int code,
+		unsigned int stid, struct nlm_fmn_msg *msg)
+{
+	unsigned int dest;
+	uint32_t status;
+	int i;
+
+	/*
+	 * Make sure that all the writes pending at the cpu are flushed.
+	 * Any writes pending on CPU will not be see by devices. L1/L2
+	 * caches are coherent with IO, so no cache flush needed.
+	 */
+	__asm __volatile("sync");
+
+	/* Load TX message buffers */
+	nlm_write_c2_tx_msg0(msg->msg0);
+	nlm_write_c2_tx_msg1(msg->msg1);
+	nlm_write_c2_tx_msg2(msg->msg2);
+	nlm_write_c2_tx_msg3(msg->msg3);
+	dest = ((size - 1) << 16) | (code << 8) | stid;
+
+	/*
+	 * Retry a few times on credit fail, this should be a
+	 * transient condition, unless there is a configuration
+	 * failure, or the receiver is stuck.
+	 */
+	for (i = 0; i < 8; i++) {
+		nlm_msgsnd(dest);
+		status = nlm_read_c2_status(0);
+		if ((status & 0x2) == 1)
+			pr_info("Send pending fail!\n");
+		if ((status & 0x4) == 0)
+			return 0;
+	}
+
+	/* If there is a credit failure, return error */
+	return status & 0x06;
+}
+
+static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid,
+		struct nlm_fmn_msg *msg)
+{
+	uint32_t status, tmp;
+
+	nlm_msgld(bucket);
+
+	/* wait for load pending to clear */
+	do {
+		status = nlm_read_c2_status(1);
+	} while ((status & 0x08) != 0);
+
+	/* receive error bits */
+	tmp = status & 0x30;
+	if (tmp != 0)
+		return tmp;
+
+	*size = ((status & 0xc0) >> 6) + 1;
+	*code = (status & 0xff00) >> 8;
+	*stid = (status & 0x7f0000) >> 16;
+	msg->msg0 = nlm_read_c2_rx_msg0();
+	msg->msg1 = nlm_read_c2_rx_msg1();
+	msg->msg2 = nlm_read_c2_rx_msg2();
+	msg->msg3 = nlm_read_c2_rx_msg3();
+
+	return 0;
+}
+
+struct xlr_fmn_info {
+	int num_buckets;
+	int start_stn_id;
+	int end_stn_id;
+	int credit_config[128];
+};
+
+struct xlr_board_fmn_config {
+	int bucket_size[128];		/* size of buckets for all stations */
+	struct xlr_fmn_info cpu[8];
+	struct xlr_fmn_info gmac[2];
+	struct xlr_fmn_info dma;
+	struct xlr_fmn_info cmp;
+	struct xlr_fmn_info sae;
+	struct xlr_fmn_info xgmac[2];
+};
+
+extern int nlm_register_fmn_handler(int start, int end,
+	void (*fn)(int, int, int, int, struct nlm_fmn_msg *, void *),
+	void *arg);
+extern void xlr_percpu_fmn_init(void);
+extern void nlm_setup_fmn_irq(void);
+extern void xlr_board_info_setup(void);
+
+extern struct xlr_board_fmn_config xlr_board_fmn_config;
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h
index 868013e..9a691b1 100644
--- a/arch/mips/include/asm/netlogic/xlr/pic.h
+++ b/arch/mips/include/asm/netlogic/xlr/pic.h
@@ -258,7 +258,5 @@
 	nlm_write_reg(base, PIC_IRT_1(irt),
 		(1 << 30) | (1 << 6) | irq);
 }
-
-extern uint64_t nlm_pic_base;
 #endif
 #endif /* _ASM_NLM_XLR_PIC_H */
diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h
index ff4a17b..c1667e0 100644
--- a/arch/mips/include/asm/netlogic/xlr/xlr.h
+++ b/arch/mips/include/asm/netlogic/xlr/xlr.h
@@ -51,10 +51,8 @@
 	return ((prid & 0xf000) == 0x4000);
 }
 
-/*
- *  XLR chip types
- */
- /* The XLS product line has chip versions 0x[48c]? */
+/*  XLR chip types */
+/* The XLS product line has chip versions 0x[48c]? */
 static inline unsigned int nlm_chip_is_xls(void)
 {
 	uint32_t prid = read_c0_prid();
diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h
index 877845b..42db2be 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
@@ -370,4 +370,6 @@
  */
 void cvmx_bootmem_unlock(void);
 
+extern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void);
+
 #endif /*   __CVMX_BOOTMEM_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h b/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h
new file mode 100644
index 0000000..36f5107
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h
@@ -0,0 +1,3457 @@
+/***********************license start***************
+ * Author: Cavium Inc.
+ *
+ * Contact: support@cavium.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2012 Cavium Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Inc. for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_LMCX_DEFS_H__
+#define __CVMX_LMCX_DEFS_H__
+
+#define CVMX_LMCX_BIST_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000F0ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_BIST_RESULT(block_id) (CVMX_ADD_IO_SEG(0x00011800880000F8ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_CHAR_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000220ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CHAR_MASK0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000228ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CHAR_MASK1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000230ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CHAR_MASK2(block_id) (CVMX_ADD_IO_SEG(0x0001180088000238ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CHAR_MASK3(block_id) (CVMX_ADD_IO_SEG(0x0001180088000240ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CHAR_MASK4(block_id) (CVMX_ADD_IO_SEG(0x0001180088000318ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_COMP_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000028ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_COMP_CTL2(block_id) (CVMX_ADD_IO_SEG(0x00011800880001B8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CONFIG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000188ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CONTROL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000190ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000010ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000090ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DCLK_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001E0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_DCLK_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000070ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DCLK_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000068ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DCLK_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000B8ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DDR2_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000018ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DDR_PLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000258ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_DELAY_CFG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000088ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DIMMX_PARAMS(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000270ull) + (((offset) & 1) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_LMCX_DIMM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000310ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_DLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000C0ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_DLL_CTL2(block_id) (CVMX_ADD_IO_SEG(0x00011800880001C8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_DLL_CTL3(block_id) (CVMX_ADD_IO_SEG(0x0001180088000218ull) + ((block_id) & 3) * 0x1000000ull)
+static inline uint64_t CVMX_LMCX_DUAL_MEMCFG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull;
+}
+
+static inline uint64_t CVMX_LMCX_ECC_SYND(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull;
+}
+
+static inline uint64_t CVMX_LMCX_FADR(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull;
+}
+
+#define CVMX_LMCX_IFB_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001D0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_IFB_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000050ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_IFB_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000048ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_INT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001F0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_INT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800880001E8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_MEM_CFG0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000000ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_MEM_CFG1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000008ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_MODEREG_PARAMS0(block_id) (CVMX_ADD_IO_SEG(0x00011800880001A8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_MODEREG_PARAMS1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000260ull) + ((block_id) & 3) * 0x1000000ull)
+static inline uint64_t CVMX_LMCX_NXM(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull;
+}
+
+#define CVMX_LMCX_OPS_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001D8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_OPS_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000060ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_OPS_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000058ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_PHY_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000210ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_PLL_BWCTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000040ull))
+#define CVMX_LMCX_PLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000A8ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_PLL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800880000B0ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_READ_LEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000140ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_READ_LEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000148ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_READ_LEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000100ull) + (((offset) & 3) + ((block_id) & 1) * 0xC000000ull) * 8)
+#define CVMX_LMCX_RESET_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000180ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_RLEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880002A0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_RLEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x00011800880002A8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_RLEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000280ull) + (((offset) & 3) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_LMCX_RODT_COMP_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000A0ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_RODT_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000078ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_RODT_MASK(block_id) (CVMX_ADD_IO_SEG(0x0001180088000268ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_SCRAMBLED_FADR(block_id) (CVMX_ADD_IO_SEG(0x0001180088000330ull))
+#define CVMX_LMCX_SCRAMBLE_CFG0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000320ull))
+#define CVMX_LMCX_SCRAMBLE_CFG1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000328ull))
+#define CVMX_LMCX_SLOT_CTL0(block_id) (CVMX_ADD_IO_SEG(0x00011800880001F8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_SLOT_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000200ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_SLOT_CTL2(block_id) (CVMX_ADD_IO_SEG(0x0001180088000208ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_TIMING_PARAMS0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000198ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_TIMING_PARAMS1(block_id) (CVMX_ADD_IO_SEG(0x00011800880001A0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_TRO_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000248ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_TRO_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180088000250ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_WLEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000300ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_WLEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000308ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_LMCX_WLEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800880002B0ull) + (((offset) & 3) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_LMCX_WODT_CTL0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000030ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_WODT_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000080ull) + ((block_id) & 1) * 0x60000000ull)
+#define CVMX_LMCX_WODT_MASK(block_id) (CVMX_ADD_IO_SEG(0x00011800880001B0ull) + ((block_id) & 3) * 0x1000000ull)
+
+union cvmx_lmcx_bist_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_bist_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t start:1;
+#else
+		uint64_t start:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_lmcx_bist_ctl_s cn50xx;
+	struct cvmx_lmcx_bist_ctl_s cn52xx;
+	struct cvmx_lmcx_bist_ctl_s cn52xxp1;
+	struct cvmx_lmcx_bist_ctl_s cn56xx;
+	struct cvmx_lmcx_bist_ctl_s cn56xxp1;
+};
+
+union cvmx_lmcx_bist_result {
+	uint64_t u64;
+	struct cvmx_lmcx_bist_result_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t csrd2e:1;
+		uint64_t csre2d:1;
+		uint64_t mwf:1;
+		uint64_t mwd:3;
+		uint64_t mwc:1;
+		uint64_t mrf:1;
+		uint64_t mrd:3;
+#else
+		uint64_t mrd:3;
+		uint64_t mrf:1;
+		uint64_t mwc:1;
+		uint64_t mwd:3;
+		uint64_t mwf:1;
+		uint64_t csre2d:1;
+		uint64_t csrd2e:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} s;
+	struct cvmx_lmcx_bist_result_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t mwf:1;
+		uint64_t mwd:3;
+		uint64_t mwc:1;
+		uint64_t mrf:1;
+		uint64_t mrd:3;
+#else
+		uint64_t mrd:3;
+		uint64_t mrf:1;
+		uint64_t mwc:1;
+		uint64_t mwd:3;
+		uint64_t mwf:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn50xx;
+	struct cvmx_lmcx_bist_result_s cn52xx;
+	struct cvmx_lmcx_bist_result_s cn52xxp1;
+	struct cvmx_lmcx_bist_result_s cn56xx;
+	struct cvmx_lmcx_bist_result_s cn56xxp1;
+};
+
+union cvmx_lmcx_char_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_char_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_44_63:20;
+		uint64_t dr:1;
+		uint64_t skew_on:1;
+		uint64_t en:1;
+		uint64_t sel:1;
+		uint64_t prog:8;
+		uint64_t prbs:32;
+#else
+		uint64_t prbs:32;
+		uint64_t prog:8;
+		uint64_t sel:1;
+		uint64_t en:1;
+		uint64_t skew_on:1;
+		uint64_t dr:1;
+		uint64_t reserved_44_63:20;
+#endif
+	} s;
+	struct cvmx_lmcx_char_ctl_s cn61xx;
+	struct cvmx_lmcx_char_ctl_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_42_63:22;
+		uint64_t en:1;
+		uint64_t sel:1;
+		uint64_t prog:8;
+		uint64_t prbs:32;
+#else
+		uint64_t prbs:32;
+		uint64_t prog:8;
+		uint64_t sel:1;
+		uint64_t en:1;
+		uint64_t reserved_42_63:22;
+#endif
+	} cn63xx;
+	struct cvmx_lmcx_char_ctl_cn63xx cn63xxp1;
+	struct cvmx_lmcx_char_ctl_s cn66xx;
+	struct cvmx_lmcx_char_ctl_s cn68xx;
+	struct cvmx_lmcx_char_ctl_cn63xx cn68xxp1;
+	struct cvmx_lmcx_char_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_char_mask0 {
+	uint64_t u64;
+	struct cvmx_lmcx_char_mask0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mask:64;
+#else
+		uint64_t mask:64;
+#endif
+	} s;
+	struct cvmx_lmcx_char_mask0_s cn61xx;
+	struct cvmx_lmcx_char_mask0_s cn63xx;
+	struct cvmx_lmcx_char_mask0_s cn63xxp1;
+	struct cvmx_lmcx_char_mask0_s cn66xx;
+	struct cvmx_lmcx_char_mask0_s cn68xx;
+	struct cvmx_lmcx_char_mask0_s cn68xxp1;
+	struct cvmx_lmcx_char_mask0_s cnf71xx;
+};
+
+union cvmx_lmcx_char_mask1 {
+	uint64_t u64;
+	struct cvmx_lmcx_char_mask1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t mask:8;
+#else
+		uint64_t mask:8;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_lmcx_char_mask1_s cn61xx;
+	struct cvmx_lmcx_char_mask1_s cn63xx;
+	struct cvmx_lmcx_char_mask1_s cn63xxp1;
+	struct cvmx_lmcx_char_mask1_s cn66xx;
+	struct cvmx_lmcx_char_mask1_s cn68xx;
+	struct cvmx_lmcx_char_mask1_s cn68xxp1;
+	struct cvmx_lmcx_char_mask1_s cnf71xx;
+};
+
+union cvmx_lmcx_char_mask2 {
+	uint64_t u64;
+	struct cvmx_lmcx_char_mask2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mask:64;
+#else
+		uint64_t mask:64;
+#endif
+	} s;
+	struct cvmx_lmcx_char_mask2_s cn61xx;
+	struct cvmx_lmcx_char_mask2_s cn63xx;
+	struct cvmx_lmcx_char_mask2_s cn63xxp1;
+	struct cvmx_lmcx_char_mask2_s cn66xx;
+	struct cvmx_lmcx_char_mask2_s cn68xx;
+	struct cvmx_lmcx_char_mask2_s cn68xxp1;
+	struct cvmx_lmcx_char_mask2_s cnf71xx;
+};
+
+union cvmx_lmcx_char_mask3 {
+	uint64_t u64;
+	struct cvmx_lmcx_char_mask3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t mask:8;
+#else
+		uint64_t mask:8;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_lmcx_char_mask3_s cn61xx;
+	struct cvmx_lmcx_char_mask3_s cn63xx;
+	struct cvmx_lmcx_char_mask3_s cn63xxp1;
+	struct cvmx_lmcx_char_mask3_s cn66xx;
+	struct cvmx_lmcx_char_mask3_s cn68xx;
+	struct cvmx_lmcx_char_mask3_s cn68xxp1;
+	struct cvmx_lmcx_char_mask3_s cnf71xx;
+};
+
+union cvmx_lmcx_char_mask4 {
+	uint64_t u64;
+	struct cvmx_lmcx_char_mask4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t reset_n_mask:1;
+		uint64_t a_mask:16;
+		uint64_t ba_mask:3;
+		uint64_t we_n_mask:1;
+		uint64_t cas_n_mask:1;
+		uint64_t ras_n_mask:1;
+		uint64_t odt1_mask:2;
+		uint64_t odt0_mask:2;
+		uint64_t cs1_n_mask:2;
+		uint64_t cs0_n_mask:2;
+		uint64_t cke_mask:2;
+#else
+		uint64_t cke_mask:2;
+		uint64_t cs0_n_mask:2;
+		uint64_t cs1_n_mask:2;
+		uint64_t odt0_mask:2;
+		uint64_t odt1_mask:2;
+		uint64_t ras_n_mask:1;
+		uint64_t cas_n_mask:1;
+		uint64_t we_n_mask:1;
+		uint64_t ba_mask:3;
+		uint64_t a_mask:16;
+		uint64_t reset_n_mask:1;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_lmcx_char_mask4_s cn61xx;
+	struct cvmx_lmcx_char_mask4_s cn63xx;
+	struct cvmx_lmcx_char_mask4_s cn63xxp1;
+	struct cvmx_lmcx_char_mask4_s cn66xx;
+	struct cvmx_lmcx_char_mask4_s cn68xx;
+	struct cvmx_lmcx_char_mask4_s cn68xxp1;
+	struct cvmx_lmcx_char_mask4_s cnf71xx;
+};
+
+union cvmx_lmcx_comp_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_comp_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t nctl_csr:4;
+		uint64_t nctl_clk:4;
+		uint64_t nctl_cmd:4;
+		uint64_t nctl_dat:4;
+		uint64_t pctl_csr:4;
+		uint64_t pctl_clk:4;
+		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t pctl_clk:4;
+		uint64_t pctl_csr:4;
+		uint64_t nctl_dat:4;
+		uint64_t nctl_cmd:4;
+		uint64_t nctl_clk:4;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_comp_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t nctl_csr:4;
+		uint64_t nctl_clk:4;
+		uint64_t nctl_cmd:4;
+		uint64_t nctl_dat:4;
+		uint64_t pctl_csr:4;
+		uint64_t pctl_clk:4;
+		uint64_t pctl_cmd:4;
+		uint64_t pctl_dat:4;
+#else
+		uint64_t pctl_dat:4;
+		uint64_t pctl_cmd:4;
+		uint64_t pctl_clk:4;
+		uint64_t pctl_csr:4;
+		uint64_t nctl_dat:4;
+		uint64_t nctl_cmd:4;
+		uint64_t nctl_clk:4;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_comp_ctl_cn30xx cn31xx;
+	struct cvmx_lmcx_comp_ctl_cn30xx cn38xx;
+	struct cvmx_lmcx_comp_ctl_cn30xx cn38xxp2;
+	struct cvmx_lmcx_comp_ctl_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_20_27:8;
+		uint64_t nctl_dat:4;
+		uint64_t pctl_csr:4;
+		uint64_t reserved_5_11:7;
+		uint64_t pctl_dat:5;
+#else
+		uint64_t pctl_dat:5;
+		uint64_t reserved_5_11:7;
+		uint64_t pctl_csr:4;
+		uint64_t nctl_dat:4;
+		uint64_t reserved_20_27:8;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn50xx;
+	struct cvmx_lmcx_comp_ctl_cn50xx cn52xx;
+	struct cvmx_lmcx_comp_ctl_cn50xx cn52xxp1;
+	struct cvmx_lmcx_comp_ctl_cn50xx cn56xx;
+	struct cvmx_lmcx_comp_ctl_cn50xx cn56xxp1;
+	struct cvmx_lmcx_comp_ctl_cn50xx cn58xx;
+	struct cvmx_lmcx_comp_ctl_cn58xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_20_27:8;
+		uint64_t nctl_dat:4;
+		uint64_t pctl_csr:4;
+		uint64_t reserved_4_11:8;
+		uint64_t pctl_dat:4;
+#else
+		uint64_t pctl_dat:4;
+		uint64_t reserved_4_11:8;
+		uint64_t pctl_csr:4;
+		uint64_t nctl_dat:4;
+		uint64_t reserved_20_27:8;
+		uint64_t nctl_csr:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn58xxp1;
+};
+
+union cvmx_lmcx_comp_ctl2 {
+	uint64_t u64;
+	struct cvmx_lmcx_comp_ctl2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t ddr__ptune:4;
+		uint64_t ddr__ntune:4;
+		uint64_t m180:1;
+		uint64_t byp:1;
+		uint64_t ptune:4;
+		uint64_t ntune:4;
+		uint64_t rodt_ctl:4;
+		uint64_t cmd_ctl:4;
+		uint64_t ck_ctl:4;
+		uint64_t dqx_ctl:4;
+#else
+		uint64_t dqx_ctl:4;
+		uint64_t ck_ctl:4;
+		uint64_t cmd_ctl:4;
+		uint64_t rodt_ctl:4;
+		uint64_t ntune:4;
+		uint64_t ptune:4;
+		uint64_t byp:1;
+		uint64_t m180:1;
+		uint64_t ddr__ntune:4;
+		uint64_t ddr__ptune:4;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_lmcx_comp_ctl2_s cn61xx;
+	struct cvmx_lmcx_comp_ctl2_s cn63xx;
+	struct cvmx_lmcx_comp_ctl2_s cn63xxp1;
+	struct cvmx_lmcx_comp_ctl2_s cn66xx;
+	struct cvmx_lmcx_comp_ctl2_s cn68xx;
+	struct cvmx_lmcx_comp_ctl2_s cn68xxp1;
+	struct cvmx_lmcx_comp_ctl2_s cnf71xx;
+};
+
+union cvmx_lmcx_config {
+	uint64_t u64;
+	struct cvmx_lmcx_config_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_61_63:3;
+		uint64_t mode32b:1;
+		uint64_t scrz:1;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t init_status:4;
+		uint64_t mirrmask:4;
+		uint64_t rankmask:4;
+		uint64_t rank_ena:1;
+		uint64_t sref_with_dll:1;
+		uint64_t early_dqx:1;
+		uint64_t sequence:3;
+		uint64_t ref_zqcs_int:19;
+		uint64_t reset:1;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t pbank_lsb:4;
+		uint64_t row_lsb:3;
+		uint64_t ecc_ena:1;
+		uint64_t init_start:1;
+#else
+		uint64_t init_start:1;
+		uint64_t ecc_ena:1;
+		uint64_t row_lsb:3;
+		uint64_t pbank_lsb:4;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reset:1;
+		uint64_t ref_zqcs_int:19;
+		uint64_t sequence:3;
+		uint64_t early_dqx:1;
+		uint64_t sref_with_dll:1;
+		uint64_t rank_ena:1;
+		uint64_t rankmask:4;
+		uint64_t mirrmask:4;
+		uint64_t init_status:4;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t scrz:1;
+		uint64_t mode32b:1;
+		uint64_t reserved_61_63:3;
+#endif
+	} s;
+	struct cvmx_lmcx_config_s cn61xx;
+	struct cvmx_lmcx_config_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_59_63:5;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t init_status:4;
+		uint64_t mirrmask:4;
+		uint64_t rankmask:4;
+		uint64_t rank_ena:1;
+		uint64_t sref_with_dll:1;
+		uint64_t early_dqx:1;
+		uint64_t sequence:3;
+		uint64_t ref_zqcs_int:19;
+		uint64_t reset:1;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t pbank_lsb:4;
+		uint64_t row_lsb:3;
+		uint64_t ecc_ena:1;
+		uint64_t init_start:1;
+#else
+		uint64_t init_start:1;
+		uint64_t ecc_ena:1;
+		uint64_t row_lsb:3;
+		uint64_t pbank_lsb:4;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reset:1;
+		uint64_t ref_zqcs_int:19;
+		uint64_t sequence:3;
+		uint64_t early_dqx:1;
+		uint64_t sref_with_dll:1;
+		uint64_t rank_ena:1;
+		uint64_t rankmask:4;
+		uint64_t mirrmask:4;
+		uint64_t init_status:4;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t reserved_59_63:5;
+#endif
+	} cn63xx;
+	struct cvmx_lmcx_config_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_55_63:9;
+		uint64_t init_status:4;
+		uint64_t mirrmask:4;
+		uint64_t rankmask:4;
+		uint64_t rank_ena:1;
+		uint64_t sref_with_dll:1;
+		uint64_t early_dqx:1;
+		uint64_t sequence:3;
+		uint64_t ref_zqcs_int:19;
+		uint64_t reset:1;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t pbank_lsb:4;
+		uint64_t row_lsb:3;
+		uint64_t ecc_ena:1;
+		uint64_t init_start:1;
+#else
+		uint64_t init_start:1;
+		uint64_t ecc_ena:1;
+		uint64_t row_lsb:3;
+		uint64_t pbank_lsb:4;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reset:1;
+		uint64_t ref_zqcs_int:19;
+		uint64_t sequence:3;
+		uint64_t early_dqx:1;
+		uint64_t sref_with_dll:1;
+		uint64_t rank_ena:1;
+		uint64_t rankmask:4;
+		uint64_t mirrmask:4;
+		uint64_t init_status:4;
+		uint64_t reserved_55_63:9;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_config_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_60_63:4;
+		uint64_t scrz:1;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t init_status:4;
+		uint64_t mirrmask:4;
+		uint64_t rankmask:4;
+		uint64_t rank_ena:1;
+		uint64_t sref_with_dll:1;
+		uint64_t early_dqx:1;
+		uint64_t sequence:3;
+		uint64_t ref_zqcs_int:19;
+		uint64_t reset:1;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t pbank_lsb:4;
+		uint64_t row_lsb:3;
+		uint64_t ecc_ena:1;
+		uint64_t init_start:1;
+#else
+		uint64_t init_start:1;
+		uint64_t ecc_ena:1;
+		uint64_t row_lsb:3;
+		uint64_t pbank_lsb:4;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reset:1;
+		uint64_t ref_zqcs_int:19;
+		uint64_t sequence:3;
+		uint64_t early_dqx:1;
+		uint64_t sref_with_dll:1;
+		uint64_t rank_ena:1;
+		uint64_t rankmask:4;
+		uint64_t mirrmask:4;
+		uint64_t init_status:4;
+		uint64_t early_unload_d0_r0:1;
+		uint64_t early_unload_d0_r1:1;
+		uint64_t early_unload_d1_r0:1;
+		uint64_t early_unload_d1_r1:1;
+		uint64_t scrz:1;
+		uint64_t reserved_60_63:4;
+#endif
+	} cn66xx;
+	struct cvmx_lmcx_config_cn63xx cn68xx;
+	struct cvmx_lmcx_config_cn63xx cn68xxp1;
+	struct cvmx_lmcx_config_s cnf71xx;
+};
+
+union cvmx_lmcx_control {
+	uint64_t u64;
+	struct cvmx_lmcx_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t scramble_ena:1;
+		uint64_t thrcnt:12;
+		uint64_t persub:8;
+		uint64_t thrmax:4;
+		uint64_t crm_cnt:5;
+		uint64_t crm_thr:5;
+		uint64_t crm_max:5;
+		uint64_t rodt_bprch:1;
+		uint64_t wodt_bprch:1;
+		uint64_t bprch:2;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t nxm_write_en:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t inorder_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t throttle_rd:1;
+		uint64_t fprch2:2;
+		uint64_t pocas:1;
+		uint64_t ddr2t:1;
+		uint64_t bwcnt:1;
+		uint64_t rdimm_ena:1;
+#else
+		uint64_t rdimm_ena:1;
+		uint64_t bwcnt:1;
+		uint64_t ddr2t:1;
+		uint64_t pocas:1;
+		uint64_t fprch2:2;
+		uint64_t throttle_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t inorder_wr:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t nxm_write_en:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t bprch:2;
+		uint64_t wodt_bprch:1;
+		uint64_t rodt_bprch:1;
+		uint64_t crm_max:5;
+		uint64_t crm_thr:5;
+		uint64_t crm_cnt:5;
+		uint64_t thrmax:4;
+		uint64_t persub:8;
+		uint64_t thrcnt:12;
+		uint64_t scramble_ena:1;
+#endif
+	} s;
+	struct cvmx_lmcx_control_s cn61xx;
+	struct cvmx_lmcx_control_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t rodt_bprch:1;
+		uint64_t wodt_bprch:1;
+		uint64_t bprch:2;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t nxm_write_en:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t inorder_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t throttle_rd:1;
+		uint64_t fprch2:2;
+		uint64_t pocas:1;
+		uint64_t ddr2t:1;
+		uint64_t bwcnt:1;
+		uint64_t rdimm_ena:1;
+#else
+		uint64_t rdimm_ena:1;
+		uint64_t bwcnt:1;
+		uint64_t ddr2t:1;
+		uint64_t pocas:1;
+		uint64_t fprch2:2;
+		uint64_t throttle_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t inorder_wr:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t nxm_write_en:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t bprch:2;
+		uint64_t wodt_bprch:1;
+		uint64_t rodt_bprch:1;
+		uint64_t reserved_24_63:40;
+#endif
+	} cn63xx;
+	struct cvmx_lmcx_control_cn63xx cn63xxp1;
+	struct cvmx_lmcx_control_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t scramble_ena:1;
+		uint64_t reserved_24_62:39;
+		uint64_t rodt_bprch:1;
+		uint64_t wodt_bprch:1;
+		uint64_t bprch:2;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t nxm_write_en:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t inorder_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t throttle_rd:1;
+		uint64_t fprch2:2;
+		uint64_t pocas:1;
+		uint64_t ddr2t:1;
+		uint64_t bwcnt:1;
+		uint64_t rdimm_ena:1;
+#else
+		uint64_t rdimm_ena:1;
+		uint64_t bwcnt:1;
+		uint64_t ddr2t:1;
+		uint64_t pocas:1;
+		uint64_t fprch2:2;
+		uint64_t throttle_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t inorder_wr:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t nxm_write_en:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t bprch:2;
+		uint64_t wodt_bprch:1;
+		uint64_t rodt_bprch:1;
+		uint64_t reserved_24_62:39;
+		uint64_t scramble_ena:1;
+#endif
+	} cn66xx;
+	struct cvmx_lmcx_control_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_63_63:1;
+		uint64_t thrcnt:12;
+		uint64_t persub:8;
+		uint64_t thrmax:4;
+		uint64_t crm_cnt:5;
+		uint64_t crm_thr:5;
+		uint64_t crm_max:5;
+		uint64_t rodt_bprch:1;
+		uint64_t wodt_bprch:1;
+		uint64_t bprch:2;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t nxm_write_en:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t inorder_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t throttle_rd:1;
+		uint64_t fprch2:2;
+		uint64_t pocas:1;
+		uint64_t ddr2t:1;
+		uint64_t bwcnt:1;
+		uint64_t rdimm_ena:1;
+#else
+		uint64_t rdimm_ena:1;
+		uint64_t bwcnt:1;
+		uint64_t ddr2t:1;
+		uint64_t pocas:1;
+		uint64_t fprch2:2;
+		uint64_t throttle_rd:1;
+		uint64_t throttle_wr:1;
+		uint64_t inorder_rd:1;
+		uint64_t inorder_wr:1;
+		uint64_t elev_prio_dis:1;
+		uint64_t nxm_write_en:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t auto_dclkdis:1;
+		uint64_t int_zqcs_dis:1;
+		uint64_t ext_zqcs_dis:1;
+		uint64_t bprch:2;
+		uint64_t wodt_bprch:1;
+		uint64_t rodt_bprch:1;
+		uint64_t crm_max:5;
+		uint64_t crm_thr:5;
+		uint64_t crm_cnt:5;
+		uint64_t thrmax:4;
+		uint64_t persub:8;
+		uint64_t thrcnt:12;
+		uint64_t reserved_63_63:1;
+#endif
+	} cn68xx;
+	struct cvmx_lmcx_control_cn68xx cn68xxp1;
+	struct cvmx_lmcx_control_cn66xx cnf71xx;
+};
+
+union cvmx_lmcx_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t pll_div2:1;
+		uint64_t pll_bypass:1;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t reserved_10_11:2;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t reserved_10_11:2;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t pll_bypass:1;
+		uint64_t pll_div2:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t pll_div2:1;
+		uint64_t pll_bypass:1;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t dreset:1;
+		uint64_t mode32b:1;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t mode32b:1;
+		uint64_t dreset:1;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t pll_bypass:1;
+		uint64_t pll_div2:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_ctl_cn30xx cn31xx;
+	struct cvmx_lmcx_ctl_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t reserved_16_17:2;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t set_zero:1;
+		uint64_t mode128b:1;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t mode128b:1;
+		uint64_t set_zero:1;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t reserved_16_17:2;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn38xx;
+	struct cvmx_lmcx_ctl_cn38xx cn38xxp2;
+	struct cvmx_lmcx_ctl_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t reserved_17_17:1;
+		uint64_t pll_bypass:1;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t dreset:1;
+		uint64_t mode32b:1;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t mode32b:1;
+		uint64_t dreset:1;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t pll_bypass:1;
+		uint64_t reserved_17_17:1;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn50xx;
+	struct cvmx_lmcx_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t reserved_16_17:2;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t dreset:1;
+		uint64_t mode32b:1;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t mode32b:1;
+		uint64_t dreset:1;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t reserved_16_17:2;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn52xx;
+	struct cvmx_lmcx_ctl_cn52xx cn52xxp1;
+	struct cvmx_lmcx_ctl_cn52xx cn56xx;
+	struct cvmx_lmcx_ctl_cn52xx cn56xxp1;
+	struct cvmx_lmcx_ctl_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:4;
+		uint64_t ddr__pctl:4;
+		uint64_t slow_scf:1;
+		uint64_t xor_bank:1;
+		uint64_t max_write_batch:4;
+		uint64_t reserved_16_17:2;
+		uint64_t rdimm_ena:1;
+		uint64_t r2r_slot:1;
+		uint64_t inorder_mwf:1;
+		uint64_t inorder_mrf:1;
+		uint64_t dreset:1;
+		uint64_t mode128b:1;
+		uint64_t fprch2:1;
+		uint64_t bprch:1;
+		uint64_t sil_lat:2;
+		uint64_t tskw:2;
+		uint64_t qs_dic:2;
+		uint64_t dic:2;
+#else
+		uint64_t dic:2;
+		uint64_t qs_dic:2;
+		uint64_t tskw:2;
+		uint64_t sil_lat:2;
+		uint64_t bprch:1;
+		uint64_t fprch2:1;
+		uint64_t mode128b:1;
+		uint64_t dreset:1;
+		uint64_t inorder_mrf:1;
+		uint64_t inorder_mwf:1;
+		uint64_t r2r_slot:1;
+		uint64_t rdimm_ena:1;
+		uint64_t reserved_16_17:2;
+		uint64_t max_write_batch:4;
+		uint64_t xor_bank:1;
+		uint64_t slow_scf:1;
+		uint64_t ddr__pctl:4;
+		uint64_t ddr__nctl:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn58xx;
+	struct cvmx_lmcx_ctl_cn58xx cn58xxp1;
+};
+
+union cvmx_lmcx_ctl1 {
+	uint64_t u64;
+	struct cvmx_lmcx_ctl1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t sequence:3;
+		uint64_t sil_mode:1;
+		uint64_t dcc_enable:1;
+		uint64_t reserved_2_7:6;
+		uint64_t data_layout:2;
+#else
+		uint64_t data_layout:2;
+		uint64_t reserved_2_7:6;
+		uint64_t dcc_enable:1;
+		uint64_t sil_mode:1;
+		uint64_t sequence:3;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} s;
+	struct cvmx_lmcx_ctl1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t data_layout:2;
+#else
+		uint64_t data_layout:2;
+		uint64_t reserved_2_63:62;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_ctl1_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t sil_mode:1;
+		uint64_t dcc_enable:1;
+		uint64_t reserved_2_7:6;
+		uint64_t data_layout:2;
+#else
+		uint64_t data_layout:2;
+		uint64_t reserved_2_7:6;
+		uint64_t dcc_enable:1;
+		uint64_t sil_mode:1;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn50xx;
+	struct cvmx_lmcx_ctl1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t ecc_adr:1;
+		uint64_t forcewrite:4;
+		uint64_t idlepower:3;
+		uint64_t sequence:3;
+		uint64_t sil_mode:1;
+		uint64_t dcc_enable:1;
+		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t dcc_enable:1;
+		uint64_t sil_mode:1;
+		uint64_t sequence:3;
+		uint64_t idlepower:3;
+		uint64_t forcewrite:4;
+		uint64_t ecc_adr:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} cn52xx;
+	struct cvmx_lmcx_ctl1_cn52xx cn52xxp1;
+	struct cvmx_lmcx_ctl1_cn52xx cn56xx;
+	struct cvmx_lmcx_ctl1_cn52xx cn56xxp1;
+	struct cvmx_lmcx_ctl1_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t sil_mode:1;
+		uint64_t dcc_enable:1;
+		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t dcc_enable:1;
+		uint64_t sil_mode:1;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn58xx;
+	struct cvmx_lmcx_ctl1_cn58xx cn58xxp1;
+};
+
+union cvmx_lmcx_dclk_cnt {
+	uint64_t u64;
+	struct cvmx_lmcx_dclk_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dclkcnt:64;
+#else
+		uint64_t dclkcnt:64;
+#endif
+	} s;
+	struct cvmx_lmcx_dclk_cnt_s cn61xx;
+	struct cvmx_lmcx_dclk_cnt_s cn63xx;
+	struct cvmx_lmcx_dclk_cnt_s cn63xxp1;
+	struct cvmx_lmcx_dclk_cnt_s cn66xx;
+	struct cvmx_lmcx_dclk_cnt_s cn68xx;
+	struct cvmx_lmcx_dclk_cnt_s cn68xxp1;
+	struct cvmx_lmcx_dclk_cnt_s cnf71xx;
+};
+
+union cvmx_lmcx_dclk_cnt_hi {
+	uint64_t u64;
+	struct cvmx_lmcx_dclk_cnt_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t dclkcnt_hi:32;
+#else
+		uint64_t dclkcnt_hi:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn30xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn31xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn38xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn38xxp2;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn50xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn52xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn52xxp1;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn56xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn56xxp1;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn58xx;
+	struct cvmx_lmcx_dclk_cnt_hi_s cn58xxp1;
+};
+
+union cvmx_lmcx_dclk_cnt_lo {
+	uint64_t u64;
+	struct cvmx_lmcx_dclk_cnt_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t dclkcnt_lo:32;
+#else
+		uint64_t dclkcnt_lo:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn30xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn31xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn38xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn38xxp2;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn50xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn52xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn52xxp1;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn56xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn56xxp1;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn58xx;
+	struct cvmx_lmcx_dclk_cnt_lo_s cn58xxp1;
+};
+
+union cvmx_lmcx_dclk_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_dclk_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t off90_ena:1;
+		uint64_t dclk90_byp:1;
+		uint64_t dclk90_ld:1;
+		uint64_t dclk90_vlu:5;
+#else
+		uint64_t dclk90_vlu:5;
+		uint64_t dclk90_ld:1;
+		uint64_t dclk90_byp:1;
+		uint64_t off90_ena:1;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_lmcx_dclk_ctl_s cn56xx;
+	struct cvmx_lmcx_dclk_ctl_s cn56xxp1;
+};
+
+union cvmx_lmcx_ddr2_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_ddr2_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t bank8:1;
+		uint64_t burst8:1;
+		uint64_t addlat:3;
+		uint64_t pocas:1;
+		uint64_t bwcnt:1;
+		uint64_t twr:3;
+		uint64_t silo_hc:1;
+		uint64_t ddr_eof:4;
+		uint64_t tfaw:5;
+		uint64_t crip_mode:1;
+		uint64_t ddr2t:1;
+		uint64_t odt_ena:1;
+		uint64_t qdll_ena:1;
+		uint64_t dll90_vlu:5;
+		uint64_t dll90_byp:1;
+		uint64_t rdqs:1;
+		uint64_t ddr2:1;
+#else
+		uint64_t ddr2:1;
+		uint64_t rdqs:1;
+		uint64_t dll90_byp:1;
+		uint64_t dll90_vlu:5;
+		uint64_t qdll_ena:1;
+		uint64_t odt_ena:1;
+		uint64_t ddr2t:1;
+		uint64_t crip_mode:1;
+		uint64_t tfaw:5;
+		uint64_t ddr_eof:4;
+		uint64_t silo_hc:1;
+		uint64_t twr:3;
+		uint64_t bwcnt:1;
+		uint64_t pocas:1;
+		uint64_t addlat:3;
+		uint64_t burst8:1;
+		uint64_t bank8:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ddr2_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t bank8:1;
+		uint64_t burst8:1;
+		uint64_t addlat:3;
+		uint64_t pocas:1;
+		uint64_t bwcnt:1;
+		uint64_t twr:3;
+		uint64_t silo_hc:1;
+		uint64_t ddr_eof:4;
+		uint64_t tfaw:5;
+		uint64_t crip_mode:1;
+		uint64_t ddr2t:1;
+		uint64_t odt_ena:1;
+		uint64_t qdll_ena:1;
+		uint64_t dll90_vlu:5;
+		uint64_t dll90_byp:1;
+		uint64_t reserved_1_1:1;
+		uint64_t ddr2:1;
+#else
+		uint64_t ddr2:1;
+		uint64_t reserved_1_1:1;
+		uint64_t dll90_byp:1;
+		uint64_t dll90_vlu:5;
+		uint64_t qdll_ena:1;
+		uint64_t odt_ena:1;
+		uint64_t ddr2t:1;
+		uint64_t crip_mode:1;
+		uint64_t tfaw:5;
+		uint64_t ddr_eof:4;
+		uint64_t silo_hc:1;
+		uint64_t twr:3;
+		uint64_t bwcnt:1;
+		uint64_t pocas:1;
+		uint64_t addlat:3;
+		uint64_t burst8:1;
+		uint64_t bank8:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_ddr2_ctl_cn30xx cn31xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn38xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn38xxp2;
+	struct cvmx_lmcx_ddr2_ctl_s cn50xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn52xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn52xxp1;
+	struct cvmx_lmcx_ddr2_ctl_s cn56xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn56xxp1;
+	struct cvmx_lmcx_ddr2_ctl_s cn58xx;
+	struct cvmx_lmcx_ddr2_ctl_s cn58xxp1;
+};
+
+union cvmx_lmcx_ddr_pll_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_ddr_pll_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_27_63:37;
+		uint64_t jtg_test_mode:1;
+		uint64_t dfm_div_reset:1;
+		uint64_t dfm_ps_en:3;
+		uint64_t ddr_div_reset:1;
+		uint64_t ddr_ps_en:3;
+		uint64_t diffamp:4;
+		uint64_t cps:3;
+		uint64_t cpb:3;
+		uint64_t reset_n:1;
+		uint64_t clkf:7;
+#else
+		uint64_t clkf:7;
+		uint64_t reset_n:1;
+		uint64_t cpb:3;
+		uint64_t cps:3;
+		uint64_t diffamp:4;
+		uint64_t ddr_ps_en:3;
+		uint64_t ddr_div_reset:1;
+		uint64_t dfm_ps_en:3;
+		uint64_t dfm_div_reset:1;
+		uint64_t jtg_test_mode:1;
+		uint64_t reserved_27_63:37;
+#endif
+	} s;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn61xx;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn63xx;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn63xxp1;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn66xx;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn68xx;
+	struct cvmx_lmcx_ddr_pll_ctl_s cn68xxp1;
+	struct cvmx_lmcx_ddr_pll_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_delay_cfg {
+	uint64_t u64;
+	struct cvmx_lmcx_delay_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t dq:5;
+		uint64_t cmd:5;
+		uint64_t clk:5;
+#else
+		uint64_t clk:5;
+		uint64_t cmd:5;
+		uint64_t dq:5;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_lmcx_delay_cfg_s cn30xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_14_63:50;
+		uint64_t dq:4;
+		uint64_t reserved_9_9:1;
+		uint64_t cmd:4;
+		uint64_t reserved_4_4:1;
+		uint64_t clk:4;
+#else
+		uint64_t clk:4;
+		uint64_t reserved_4_4:1;
+		uint64_t cmd:4;
+		uint64_t reserved_9_9:1;
+		uint64_t dq:4;
+		uint64_t reserved_14_63:50;
+#endif
+	} cn38xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn50xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn52xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn52xxp1;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn56xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn56xxp1;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn58xx;
+	struct cvmx_lmcx_delay_cfg_cn38xx cn58xxp1;
+};
+
+union cvmx_lmcx_dimmx_params {
+	uint64_t u64;
+	struct cvmx_lmcx_dimmx_params_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rc15:4;
+		uint64_t rc14:4;
+		uint64_t rc13:4;
+		uint64_t rc12:4;
+		uint64_t rc11:4;
+		uint64_t rc10:4;
+		uint64_t rc9:4;
+		uint64_t rc8:4;
+		uint64_t rc7:4;
+		uint64_t rc6:4;
+		uint64_t rc5:4;
+		uint64_t rc4:4;
+		uint64_t rc3:4;
+		uint64_t rc2:4;
+		uint64_t rc1:4;
+		uint64_t rc0:4;
+#else
+		uint64_t rc0:4;
+		uint64_t rc1:4;
+		uint64_t rc2:4;
+		uint64_t rc3:4;
+		uint64_t rc4:4;
+		uint64_t rc5:4;
+		uint64_t rc6:4;
+		uint64_t rc7:4;
+		uint64_t rc8:4;
+		uint64_t rc9:4;
+		uint64_t rc10:4;
+		uint64_t rc11:4;
+		uint64_t rc12:4;
+		uint64_t rc13:4;
+		uint64_t rc14:4;
+		uint64_t rc15:4;
+#endif
+	} s;
+	struct cvmx_lmcx_dimmx_params_s cn61xx;
+	struct cvmx_lmcx_dimmx_params_s cn63xx;
+	struct cvmx_lmcx_dimmx_params_s cn63xxp1;
+	struct cvmx_lmcx_dimmx_params_s cn66xx;
+	struct cvmx_lmcx_dimmx_params_s cn68xx;
+	struct cvmx_lmcx_dimmx_params_s cn68xxp1;
+	struct cvmx_lmcx_dimmx_params_s cnf71xx;
+};
+
+union cvmx_lmcx_dimm_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_dimm_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_46_63:18;
+		uint64_t parity:1;
+		uint64_t tcws:13;
+		uint64_t dimm1_wmask:16;
+		uint64_t dimm0_wmask:16;
+#else
+		uint64_t dimm0_wmask:16;
+		uint64_t dimm1_wmask:16;
+		uint64_t tcws:13;
+		uint64_t parity:1;
+		uint64_t reserved_46_63:18;
+#endif
+	} s;
+	struct cvmx_lmcx_dimm_ctl_s cn61xx;
+	struct cvmx_lmcx_dimm_ctl_s cn63xx;
+	struct cvmx_lmcx_dimm_ctl_s cn63xxp1;
+	struct cvmx_lmcx_dimm_ctl_s cn66xx;
+	struct cvmx_lmcx_dimm_ctl_s cn68xx;
+	struct cvmx_lmcx_dimm_ctl_s cn68xxp1;
+	struct cvmx_lmcx_dimm_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_dll_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_dll_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t dreset:1;
+		uint64_t dll90_byp:1;
+		uint64_t dll90_ena:1;
+		uint64_t dll90_vlu:5;
+#else
+		uint64_t dll90_vlu:5;
+		uint64_t dll90_ena:1;
+		uint64_t dll90_byp:1;
+		uint64_t dreset:1;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_lmcx_dll_ctl_s cn52xx;
+	struct cvmx_lmcx_dll_ctl_s cn52xxp1;
+	struct cvmx_lmcx_dll_ctl_s cn56xx;
+	struct cvmx_lmcx_dll_ctl_s cn56xxp1;
+};
+
+union cvmx_lmcx_dll_ctl2 {
+	uint64_t u64;
+	struct cvmx_lmcx_dll_ctl2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t intf_en:1;
+		uint64_t dll_bringup:1;
+		uint64_t dreset:1;
+		uint64_t quad_dll_ena:1;
+		uint64_t byp_sel:4;
+		uint64_t byp_setting:8;
+#else
+		uint64_t byp_setting:8;
+		uint64_t byp_sel:4;
+		uint64_t quad_dll_ena:1;
+		uint64_t dreset:1;
+		uint64_t dll_bringup:1;
+		uint64_t intf_en:1;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_lmcx_dll_ctl2_s cn61xx;
+	struct cvmx_lmcx_dll_ctl2_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t dll_bringup:1;
+		uint64_t dreset:1;
+		uint64_t quad_dll_ena:1;
+		uint64_t byp_sel:4;
+		uint64_t byp_setting:8;
+#else
+		uint64_t byp_setting:8;
+		uint64_t byp_sel:4;
+		uint64_t quad_dll_ena:1;
+		uint64_t dreset:1;
+		uint64_t dll_bringup:1;
+		uint64_t reserved_15_63:49;
+#endif
+	} cn63xx;
+	struct cvmx_lmcx_dll_ctl2_cn63xx cn63xxp1;
+	struct cvmx_lmcx_dll_ctl2_cn63xx cn66xx;
+	struct cvmx_lmcx_dll_ctl2_s cn68xx;
+	struct cvmx_lmcx_dll_ctl2_s cn68xxp1;
+	struct cvmx_lmcx_dll_ctl2_s cnf71xx;
+};
+
+union cvmx_lmcx_dll_ctl3 {
+	uint64_t u64;
+	struct cvmx_lmcx_dll_ctl3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_41_63:23;
+		uint64_t dclk90_fwd:1;
+		uint64_t ddr_90_dly_byp:1;
+		uint64_t dclk90_recal_dis:1;
+		uint64_t dclk90_byp_sel:1;
+		uint64_t dclk90_byp_setting:8;
+		uint64_t dll_fast:1;
+		uint64_t dll90_setting:8;
+		uint64_t fine_tune_mode:1;
+		uint64_t dll_mode:1;
+		uint64_t dll90_byte_sel:4;
+		uint64_t offset_ena:1;
+		uint64_t load_offset:1;
+		uint64_t mode_sel:2;
+		uint64_t byte_sel:4;
+		uint64_t offset:6;
+#else
+		uint64_t offset:6;
+		uint64_t byte_sel:4;
+		uint64_t mode_sel:2;
+		uint64_t load_offset:1;
+		uint64_t offset_ena:1;
+		uint64_t dll90_byte_sel:4;
+		uint64_t dll_mode:1;
+		uint64_t fine_tune_mode:1;
+		uint64_t dll90_setting:8;
+		uint64_t dll_fast:1;
+		uint64_t dclk90_byp_setting:8;
+		uint64_t dclk90_byp_sel:1;
+		uint64_t dclk90_recal_dis:1;
+		uint64_t ddr_90_dly_byp:1;
+		uint64_t dclk90_fwd:1;
+		uint64_t reserved_41_63:23;
+#endif
+	} s;
+	struct cvmx_lmcx_dll_ctl3_s cn61xx;
+	struct cvmx_lmcx_dll_ctl3_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t dll_fast:1;
+		uint64_t dll90_setting:8;
+		uint64_t fine_tune_mode:1;
+		uint64_t dll_mode:1;
+		uint64_t dll90_byte_sel:4;
+		uint64_t offset_ena:1;
+		uint64_t load_offset:1;
+		uint64_t mode_sel:2;
+		uint64_t byte_sel:4;
+		uint64_t offset:6;
+#else
+		uint64_t offset:6;
+		uint64_t byte_sel:4;
+		uint64_t mode_sel:2;
+		uint64_t load_offset:1;
+		uint64_t offset_ena:1;
+		uint64_t dll90_byte_sel:4;
+		uint64_t dll_mode:1;
+		uint64_t fine_tune_mode:1;
+		uint64_t dll90_setting:8;
+		uint64_t dll_fast:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn63xx;
+	struct cvmx_lmcx_dll_ctl3_cn63xx cn63xxp1;
+	struct cvmx_lmcx_dll_ctl3_cn63xx cn66xx;
+	struct cvmx_lmcx_dll_ctl3_s cn68xx;
+	struct cvmx_lmcx_dll_ctl3_s cn68xxp1;
+	struct cvmx_lmcx_dll_ctl3_s cnf71xx;
+};
+
+union cvmx_lmcx_dual_memcfg {
+	uint64_t u64;
+	struct cvmx_lmcx_dual_memcfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t bank8:1;
+		uint64_t row_lsb:3;
+		uint64_t reserved_8_15:8;
+		uint64_t cs_mask:8;
+#else
+		uint64_t cs_mask:8;
+		uint64_t reserved_8_15:8;
+		uint64_t row_lsb:3;
+		uint64_t bank8:1;
+		uint64_t reserved_20_63:44;
+#endif
+	} s;
+	struct cvmx_lmcx_dual_memcfg_s cn50xx;
+	struct cvmx_lmcx_dual_memcfg_s cn52xx;
+	struct cvmx_lmcx_dual_memcfg_s cn52xxp1;
+	struct cvmx_lmcx_dual_memcfg_s cn56xx;
+	struct cvmx_lmcx_dual_memcfg_s cn56xxp1;
+	struct cvmx_lmcx_dual_memcfg_s cn58xx;
+	struct cvmx_lmcx_dual_memcfg_s cn58xxp1;
+	struct cvmx_lmcx_dual_memcfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_19_63:45;
+		uint64_t row_lsb:3;
+		uint64_t reserved_8_15:8;
+		uint64_t cs_mask:8;
+#else
+		uint64_t cs_mask:8;
+		uint64_t reserved_8_15:8;
+		uint64_t row_lsb:3;
+		uint64_t reserved_19_63:45;
+#endif
+	} cn61xx;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cn63xx;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cn63xxp1;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cn66xx;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cn68xx;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cn68xxp1;
+	struct cvmx_lmcx_dual_memcfg_cn61xx cnf71xx;
+};
+
+union cvmx_lmcx_ecc_synd {
+	uint64_t u64;
+	struct cvmx_lmcx_ecc_synd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t mrdsyn3:8;
+		uint64_t mrdsyn2:8;
+		uint64_t mrdsyn1:8;
+		uint64_t mrdsyn0:8;
+#else
+		uint64_t mrdsyn0:8;
+		uint64_t mrdsyn1:8;
+		uint64_t mrdsyn2:8;
+		uint64_t mrdsyn3:8;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ecc_synd_s cn30xx;
+	struct cvmx_lmcx_ecc_synd_s cn31xx;
+	struct cvmx_lmcx_ecc_synd_s cn38xx;
+	struct cvmx_lmcx_ecc_synd_s cn38xxp2;
+	struct cvmx_lmcx_ecc_synd_s cn50xx;
+	struct cvmx_lmcx_ecc_synd_s cn52xx;
+	struct cvmx_lmcx_ecc_synd_s cn52xxp1;
+	struct cvmx_lmcx_ecc_synd_s cn56xx;
+	struct cvmx_lmcx_ecc_synd_s cn56xxp1;
+	struct cvmx_lmcx_ecc_synd_s cn58xx;
+	struct cvmx_lmcx_ecc_synd_s cn58xxp1;
+	struct cvmx_lmcx_ecc_synd_s cn61xx;
+	struct cvmx_lmcx_ecc_synd_s cn63xx;
+	struct cvmx_lmcx_ecc_synd_s cn63xxp1;
+	struct cvmx_lmcx_ecc_synd_s cn66xx;
+	struct cvmx_lmcx_ecc_synd_s cn68xx;
+	struct cvmx_lmcx_ecc_synd_s cn68xxp1;
+	struct cvmx_lmcx_ecc_synd_s cnf71xx;
+};
+
+union cvmx_lmcx_fadr {
+	uint64_t u64;
+	struct cvmx_lmcx_fadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
+	} s;
+	struct cvmx_lmcx_fadr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t fdimm:2;
+		uint64_t fbunk:1;
+		uint64_t fbank:3;
+		uint64_t frow:14;
+		uint64_t fcol:12;
+#else
+		uint64_t fcol:12;
+		uint64_t frow:14;
+		uint64_t fbank:3;
+		uint64_t fbunk:1;
+		uint64_t fdimm:2;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_fadr_cn30xx cn31xx;
+	struct cvmx_lmcx_fadr_cn30xx cn38xx;
+	struct cvmx_lmcx_fadr_cn30xx cn38xxp2;
+	struct cvmx_lmcx_fadr_cn30xx cn50xx;
+	struct cvmx_lmcx_fadr_cn30xx cn52xx;
+	struct cvmx_lmcx_fadr_cn30xx cn52xxp1;
+	struct cvmx_lmcx_fadr_cn30xx cn56xx;
+	struct cvmx_lmcx_fadr_cn30xx cn56xxp1;
+	struct cvmx_lmcx_fadr_cn30xx cn58xx;
+	struct cvmx_lmcx_fadr_cn30xx cn58xxp1;
+	struct cvmx_lmcx_fadr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_36_63:28;
+		uint64_t fdimm:2;
+		uint64_t fbunk:1;
+		uint64_t fbank:3;
+		uint64_t frow:16;
+		uint64_t fcol:14;
+#else
+		uint64_t fcol:14;
+		uint64_t frow:16;
+		uint64_t fbank:3;
+		uint64_t fbunk:1;
+		uint64_t fdimm:2;
+		uint64_t reserved_36_63:28;
+#endif
+	} cn61xx;
+	struct cvmx_lmcx_fadr_cn61xx cn63xx;
+	struct cvmx_lmcx_fadr_cn61xx cn63xxp1;
+	struct cvmx_lmcx_fadr_cn61xx cn66xx;
+	struct cvmx_lmcx_fadr_cn61xx cn68xx;
+	struct cvmx_lmcx_fadr_cn61xx cn68xxp1;
+	struct cvmx_lmcx_fadr_cn61xx cnf71xx;
+};
+
+union cvmx_lmcx_ifb_cnt {
+	uint64_t u64;
+	struct cvmx_lmcx_ifb_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t ifbcnt:64;
+#else
+		uint64_t ifbcnt:64;
+#endif
+	} s;
+	struct cvmx_lmcx_ifb_cnt_s cn61xx;
+	struct cvmx_lmcx_ifb_cnt_s cn63xx;
+	struct cvmx_lmcx_ifb_cnt_s cn63xxp1;
+	struct cvmx_lmcx_ifb_cnt_s cn66xx;
+	struct cvmx_lmcx_ifb_cnt_s cn68xx;
+	struct cvmx_lmcx_ifb_cnt_s cn68xxp1;
+	struct cvmx_lmcx_ifb_cnt_s cnf71xx;
+};
+
+union cvmx_lmcx_ifb_cnt_hi {
+	uint64_t u64;
+	struct cvmx_lmcx_ifb_cnt_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ifbcnt_hi:32;
+#else
+		uint64_t ifbcnt_hi:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn30xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn31xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn38xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn38xxp2;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn50xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn52xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn52xxp1;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn56xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn56xxp1;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn58xx;
+	struct cvmx_lmcx_ifb_cnt_hi_s cn58xxp1;
+};
+
+union cvmx_lmcx_ifb_cnt_lo {
+	uint64_t u64;
+	struct cvmx_lmcx_ifb_cnt_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ifbcnt_lo:32;
+#else
+		uint64_t ifbcnt_lo:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn30xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn31xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn38xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn38xxp2;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn50xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn52xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn52xxp1;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn56xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn56xxp1;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn58xx;
+	struct cvmx_lmcx_ifb_cnt_lo_s cn58xxp1;
+};
+
+union cvmx_lmcx_int {
+	uint64_t u64;
+	struct cvmx_lmcx_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t ded_err:4;
+		uint64_t sec_err:4;
+		uint64_t nxm_wr_err:1;
+#else
+		uint64_t nxm_wr_err:1;
+		uint64_t sec_err:4;
+		uint64_t ded_err:4;
+		uint64_t reserved_9_63:55;
+#endif
+	} s;
+	struct cvmx_lmcx_int_s cn61xx;
+	struct cvmx_lmcx_int_s cn63xx;
+	struct cvmx_lmcx_int_s cn63xxp1;
+	struct cvmx_lmcx_int_s cn66xx;
+	struct cvmx_lmcx_int_s cn68xx;
+	struct cvmx_lmcx_int_s cn68xxp1;
+	struct cvmx_lmcx_int_s cnf71xx;
+};
+
+union cvmx_lmcx_int_en {
+	uint64_t u64;
+	struct cvmx_lmcx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t intr_ded_ena:1;
+		uint64_t intr_sec_ena:1;
+		uint64_t intr_nxm_wr_ena:1;
+#else
+		uint64_t intr_nxm_wr_ena:1;
+		uint64_t intr_sec_ena:1;
+		uint64_t intr_ded_ena:1;
+		uint64_t reserved_3_63:61;
+#endif
+	} s;
+	struct cvmx_lmcx_int_en_s cn61xx;
+	struct cvmx_lmcx_int_en_s cn63xx;
+	struct cvmx_lmcx_int_en_s cn63xxp1;
+	struct cvmx_lmcx_int_en_s cn66xx;
+	struct cvmx_lmcx_int_en_s cn68xx;
+	struct cvmx_lmcx_int_en_s cn68xxp1;
+	struct cvmx_lmcx_int_en_s cnf71xx;
+};
+
+union cvmx_lmcx_mem_cfg0 {
+	uint64_t u64;
+	struct cvmx_lmcx_mem_cfg0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t reset:1;
+		uint64_t silo_qc:1;
+		uint64_t bunk_ena:1;
+		uint64_t ded_err:4;
+		uint64_t sec_err:4;
+		uint64_t intr_ded_ena:1;
+		uint64_t intr_sec_ena:1;
+		uint64_t tcl:4;
+		uint64_t ref_int:6;
+		uint64_t pbank_lsb:4;
+		uint64_t row_lsb:3;
+		uint64_t ecc_ena:1;
+		uint64_t init_start:1;
+#else
+		uint64_t init_start:1;
+		uint64_t ecc_ena:1;
+		uint64_t row_lsb:3;
+		uint64_t pbank_lsb:4;
+		uint64_t ref_int:6;
+		uint64_t tcl:4;
+		uint64_t intr_sec_ena:1;
+		uint64_t intr_ded_ena:1;
+		uint64_t sec_err:4;
+		uint64_t ded_err:4;
+		uint64_t bunk_ena:1;
+		uint64_t silo_qc:1;
+		uint64_t reset:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_mem_cfg0_s cn30xx;
+	struct cvmx_lmcx_mem_cfg0_s cn31xx;
+	struct cvmx_lmcx_mem_cfg0_s cn38xx;
+	struct cvmx_lmcx_mem_cfg0_s cn38xxp2;
+	struct cvmx_lmcx_mem_cfg0_s cn50xx;
+	struct cvmx_lmcx_mem_cfg0_s cn52xx;
+	struct cvmx_lmcx_mem_cfg0_s cn52xxp1;
+	struct cvmx_lmcx_mem_cfg0_s cn56xx;
+	struct cvmx_lmcx_mem_cfg0_s cn56xxp1;
+	struct cvmx_lmcx_mem_cfg0_s cn58xx;
+	struct cvmx_lmcx_mem_cfg0_s cn58xxp1;
+};
+
+union cvmx_lmcx_mem_cfg1 {
+	uint64_t u64;
+	struct cvmx_lmcx_mem_cfg1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t comp_bypass:1;
+		uint64_t trrd:3;
+		uint64_t caslat:3;
+		uint64_t tmrd:3;
+		uint64_t trfc:5;
+		uint64_t trp:4;
+		uint64_t twtr:4;
+		uint64_t trcd:4;
+		uint64_t tras:5;
+#else
+		uint64_t tras:5;
+		uint64_t trcd:4;
+		uint64_t twtr:4;
+		uint64_t trp:4;
+		uint64_t trfc:5;
+		uint64_t tmrd:3;
+		uint64_t caslat:3;
+		uint64_t trrd:3;
+		uint64_t comp_bypass:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_mem_cfg1_s cn30xx;
+	struct cvmx_lmcx_mem_cfg1_s cn31xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_31_63:33;
+		uint64_t trrd:3;
+		uint64_t caslat:3;
+		uint64_t tmrd:3;
+		uint64_t trfc:5;
+		uint64_t trp:4;
+		uint64_t twtr:4;
+		uint64_t trcd:4;
+		uint64_t tras:5;
+#else
+		uint64_t tras:5;
+		uint64_t trcd:4;
+		uint64_t twtr:4;
+		uint64_t trp:4;
+		uint64_t trfc:5;
+		uint64_t tmrd:3;
+		uint64_t caslat:3;
+		uint64_t trrd:3;
+		uint64_t reserved_31_63:33;
+#endif
+	} cn38xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn38xxp2;
+	struct cvmx_lmcx_mem_cfg1_s cn50xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn52xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn52xxp1;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn56xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn56xxp1;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn58xx;
+	struct cvmx_lmcx_mem_cfg1_cn38xx cn58xxp1;
+};
+
+union cvmx_lmcx_modereg_params0 {
+	uint64_t u64;
+	struct cvmx_lmcx_modereg_params0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t ppd:1;
+		uint64_t wrp:3;
+		uint64_t dllr:1;
+		uint64_t tm:1;
+		uint64_t rbt:1;
+		uint64_t cl:4;
+		uint64_t bl:2;
+		uint64_t qoff:1;
+		uint64_t tdqs:1;
+		uint64_t wlev:1;
+		uint64_t al:2;
+		uint64_t dll:1;
+		uint64_t mpr:1;
+		uint64_t mprloc:2;
+		uint64_t cwl:3;
+#else
+		uint64_t cwl:3;
+		uint64_t mprloc:2;
+		uint64_t mpr:1;
+		uint64_t dll:1;
+		uint64_t al:2;
+		uint64_t wlev:1;
+		uint64_t tdqs:1;
+		uint64_t qoff:1;
+		uint64_t bl:2;
+		uint64_t cl:4;
+		uint64_t rbt:1;
+		uint64_t tm:1;
+		uint64_t dllr:1;
+		uint64_t wrp:3;
+		uint64_t ppd:1;
+		uint64_t reserved_25_63:39;
+#endif
+	} s;
+	struct cvmx_lmcx_modereg_params0_s cn61xx;
+	struct cvmx_lmcx_modereg_params0_s cn63xx;
+	struct cvmx_lmcx_modereg_params0_s cn63xxp1;
+	struct cvmx_lmcx_modereg_params0_s cn66xx;
+	struct cvmx_lmcx_modereg_params0_s cn68xx;
+	struct cvmx_lmcx_modereg_params0_s cn68xxp1;
+	struct cvmx_lmcx_modereg_params0_s cnf71xx;
+};
+
+union cvmx_lmcx_modereg_params1 {
+	uint64_t u64;
+	struct cvmx_lmcx_modereg_params1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t rtt_nom_11:3;
+		uint64_t dic_11:2;
+		uint64_t rtt_wr_11:2;
+		uint64_t srt_11:1;
+		uint64_t asr_11:1;
+		uint64_t pasr_11:3;
+		uint64_t rtt_nom_10:3;
+		uint64_t dic_10:2;
+		uint64_t rtt_wr_10:2;
+		uint64_t srt_10:1;
+		uint64_t asr_10:1;
+		uint64_t pasr_10:3;
+		uint64_t rtt_nom_01:3;
+		uint64_t dic_01:2;
+		uint64_t rtt_wr_01:2;
+		uint64_t srt_01:1;
+		uint64_t asr_01:1;
+		uint64_t pasr_01:3;
+		uint64_t rtt_nom_00:3;
+		uint64_t dic_00:2;
+		uint64_t rtt_wr_00:2;
+		uint64_t srt_00:1;
+		uint64_t asr_00:1;
+		uint64_t pasr_00:3;
+#else
+		uint64_t pasr_00:3;
+		uint64_t asr_00:1;
+		uint64_t srt_00:1;
+		uint64_t rtt_wr_00:2;
+		uint64_t dic_00:2;
+		uint64_t rtt_nom_00:3;
+		uint64_t pasr_01:3;
+		uint64_t asr_01:1;
+		uint64_t srt_01:1;
+		uint64_t rtt_wr_01:2;
+		uint64_t dic_01:2;
+		uint64_t rtt_nom_01:3;
+		uint64_t pasr_10:3;
+		uint64_t asr_10:1;
+		uint64_t srt_10:1;
+		uint64_t rtt_wr_10:2;
+		uint64_t dic_10:2;
+		uint64_t rtt_nom_10:3;
+		uint64_t pasr_11:3;
+		uint64_t asr_11:1;
+		uint64_t srt_11:1;
+		uint64_t rtt_wr_11:2;
+		uint64_t dic_11:2;
+		uint64_t rtt_nom_11:3;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_lmcx_modereg_params1_s cn61xx;
+	struct cvmx_lmcx_modereg_params1_s cn63xx;
+	struct cvmx_lmcx_modereg_params1_s cn63xxp1;
+	struct cvmx_lmcx_modereg_params1_s cn66xx;
+	struct cvmx_lmcx_modereg_params1_s cn68xx;
+	struct cvmx_lmcx_modereg_params1_s cn68xxp1;
+	struct cvmx_lmcx_modereg_params1_s cnf71xx;
+};
+
+union cvmx_lmcx_nxm {
+	uint64_t u64;
+	struct cvmx_lmcx_nxm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_40_63:24;
+		uint64_t mem_msb_d3_r1:4;
+		uint64_t mem_msb_d3_r0:4;
+		uint64_t mem_msb_d2_r1:4;
+		uint64_t mem_msb_d2_r0:4;
+		uint64_t mem_msb_d1_r1:4;
+		uint64_t mem_msb_d1_r0:4;
+		uint64_t mem_msb_d0_r1:4;
+		uint64_t mem_msb_d0_r0:4;
+		uint64_t cs_mask:8;
+#else
+		uint64_t cs_mask:8;
+		uint64_t mem_msb_d0_r0:4;
+		uint64_t mem_msb_d0_r1:4;
+		uint64_t mem_msb_d1_r0:4;
+		uint64_t mem_msb_d1_r1:4;
+		uint64_t mem_msb_d2_r0:4;
+		uint64_t mem_msb_d2_r1:4;
+		uint64_t mem_msb_d3_r0:4;
+		uint64_t mem_msb_d3_r1:4;
+		uint64_t reserved_40_63:24;
+#endif
+	} s;
+	struct cvmx_lmcx_nxm_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t cs_mask:8;
+#else
+		uint64_t cs_mask:8;
+		uint64_t reserved_8_63:56;
+#endif
+	} cn52xx;
+	struct cvmx_lmcx_nxm_cn52xx cn56xx;
+	struct cvmx_lmcx_nxm_cn52xx cn58xx;
+	struct cvmx_lmcx_nxm_s cn61xx;
+	struct cvmx_lmcx_nxm_s cn63xx;
+	struct cvmx_lmcx_nxm_s cn63xxp1;
+	struct cvmx_lmcx_nxm_s cn66xx;
+	struct cvmx_lmcx_nxm_s cn68xx;
+	struct cvmx_lmcx_nxm_s cn68xxp1;
+	struct cvmx_lmcx_nxm_s cnf71xx;
+};
+
+union cvmx_lmcx_ops_cnt {
+	uint64_t u64;
+	struct cvmx_lmcx_ops_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t opscnt:64;
+#else
+		uint64_t opscnt:64;
+#endif
+	} s;
+	struct cvmx_lmcx_ops_cnt_s cn61xx;
+	struct cvmx_lmcx_ops_cnt_s cn63xx;
+	struct cvmx_lmcx_ops_cnt_s cn63xxp1;
+	struct cvmx_lmcx_ops_cnt_s cn66xx;
+	struct cvmx_lmcx_ops_cnt_s cn68xx;
+	struct cvmx_lmcx_ops_cnt_s cn68xxp1;
+	struct cvmx_lmcx_ops_cnt_s cnf71xx;
+};
+
+union cvmx_lmcx_ops_cnt_hi {
+	uint64_t u64;
+	struct cvmx_lmcx_ops_cnt_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t opscnt_hi:32;
+#else
+		uint64_t opscnt_hi:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ops_cnt_hi_s cn30xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn31xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn38xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn38xxp2;
+	struct cvmx_lmcx_ops_cnt_hi_s cn50xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn52xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn52xxp1;
+	struct cvmx_lmcx_ops_cnt_hi_s cn56xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn56xxp1;
+	struct cvmx_lmcx_ops_cnt_hi_s cn58xx;
+	struct cvmx_lmcx_ops_cnt_hi_s cn58xxp1;
+};
+
+union cvmx_lmcx_ops_cnt_lo {
+	uint64_t u64;
+	struct cvmx_lmcx_ops_cnt_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t opscnt_lo:32;
+#else
+		uint64_t opscnt_lo:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_ops_cnt_lo_s cn30xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn31xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn38xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn38xxp2;
+	struct cvmx_lmcx_ops_cnt_lo_s cn50xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn52xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn52xxp1;
+	struct cvmx_lmcx_ops_cnt_lo_s cn56xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn56xxp1;
+	struct cvmx_lmcx_ops_cnt_lo_s cn58xx;
+	struct cvmx_lmcx_ops_cnt_lo_s cn58xxp1;
+};
+
+union cvmx_lmcx_phy_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_phy_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t rx_always_on:1;
+		uint64_t lv_mode:1;
+		uint64_t ck_tune1:1;
+		uint64_t ck_dlyout1:4;
+		uint64_t ck_tune0:1;
+		uint64_t ck_dlyout0:4;
+		uint64_t loopback:1;
+		uint64_t loopback_pos:1;
+		uint64_t ts_stagger:1;
+#else
+		uint64_t ts_stagger:1;
+		uint64_t loopback_pos:1;
+		uint64_t loopback:1;
+		uint64_t ck_dlyout0:4;
+		uint64_t ck_tune0:1;
+		uint64_t ck_dlyout1:4;
+		uint64_t ck_tune1:1;
+		uint64_t lv_mode:1;
+		uint64_t rx_always_on:1;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_lmcx_phy_ctl_s cn61xx;
+	struct cvmx_lmcx_phy_ctl_s cn63xx;
+	struct cvmx_lmcx_phy_ctl_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_14_63:50;
+		uint64_t lv_mode:1;
+		uint64_t ck_tune1:1;
+		uint64_t ck_dlyout1:4;
+		uint64_t ck_tune0:1;
+		uint64_t ck_dlyout0:4;
+		uint64_t loopback:1;
+		uint64_t loopback_pos:1;
+		uint64_t ts_stagger:1;
+#else
+		uint64_t ts_stagger:1;
+		uint64_t loopback_pos:1;
+		uint64_t loopback:1;
+		uint64_t ck_dlyout0:4;
+		uint64_t ck_tune0:1;
+		uint64_t ck_dlyout1:4;
+		uint64_t ck_tune1:1;
+		uint64_t lv_mode:1;
+		uint64_t reserved_14_63:50;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_phy_ctl_s cn66xx;
+	struct cvmx_lmcx_phy_ctl_s cn68xx;
+	struct cvmx_lmcx_phy_ctl_s cn68xxp1;
+	struct cvmx_lmcx_phy_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_pll_bwctl {
+	uint64_t u64;
+	struct cvmx_lmcx_pll_bwctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t bwupd:1;
+		uint64_t bwctl:4;
+#else
+		uint64_t bwctl:4;
+		uint64_t bwupd:1;
+		uint64_t reserved_5_63:59;
+#endif
+	} s;
+	struct cvmx_lmcx_pll_bwctl_s cn30xx;
+	struct cvmx_lmcx_pll_bwctl_s cn31xx;
+	struct cvmx_lmcx_pll_bwctl_s cn38xx;
+	struct cvmx_lmcx_pll_bwctl_s cn38xxp2;
+};
+
+union cvmx_lmcx_pll_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_pll_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_30_63:34;
+		uint64_t bypass:1;
+		uint64_t fasten_n:1;
+		uint64_t div_reset:1;
+		uint64_t reset_n:1;
+		uint64_t clkf:12;
+		uint64_t clkr:6;
+		uint64_t reserved_6_7:2;
+		uint64_t en16:1;
+		uint64_t en12:1;
+		uint64_t en8:1;
+		uint64_t en6:1;
+		uint64_t en4:1;
+		uint64_t en2:1;
+#else
+		uint64_t en2:1;
+		uint64_t en4:1;
+		uint64_t en6:1;
+		uint64_t en8:1;
+		uint64_t en12:1;
+		uint64_t en16:1;
+		uint64_t reserved_6_7:2;
+		uint64_t clkr:6;
+		uint64_t clkf:12;
+		uint64_t reset_n:1;
+		uint64_t div_reset:1;
+		uint64_t fasten_n:1;
+		uint64_t bypass:1;
+		uint64_t reserved_30_63:34;
+#endif
+	} s;
+	struct cvmx_lmcx_pll_ctl_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t fasten_n:1;
+		uint64_t div_reset:1;
+		uint64_t reset_n:1;
+		uint64_t clkf:12;
+		uint64_t clkr:6;
+		uint64_t reserved_6_7:2;
+		uint64_t en16:1;
+		uint64_t en12:1;
+		uint64_t en8:1;
+		uint64_t en6:1;
+		uint64_t en4:1;
+		uint64_t en2:1;
+#else
+		uint64_t en2:1;
+		uint64_t en4:1;
+		uint64_t en6:1;
+		uint64_t en8:1;
+		uint64_t en12:1;
+		uint64_t en16:1;
+		uint64_t reserved_6_7:2;
+		uint64_t clkr:6;
+		uint64_t clkf:12;
+		uint64_t reset_n:1;
+		uint64_t div_reset:1;
+		uint64_t fasten_n:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn50xx;
+	struct cvmx_lmcx_pll_ctl_s cn52xx;
+	struct cvmx_lmcx_pll_ctl_s cn52xxp1;
+	struct cvmx_lmcx_pll_ctl_cn50xx cn56xx;
+	struct cvmx_lmcx_pll_ctl_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_28_63:36;
+		uint64_t div_reset:1;
+		uint64_t reset_n:1;
+		uint64_t clkf:12;
+		uint64_t clkr:6;
+		uint64_t reserved_6_7:2;
+		uint64_t en16:1;
+		uint64_t en12:1;
+		uint64_t en8:1;
+		uint64_t en6:1;
+		uint64_t en4:1;
+		uint64_t en2:1;
+#else
+		uint64_t en2:1;
+		uint64_t en4:1;
+		uint64_t en6:1;
+		uint64_t en8:1;
+		uint64_t en12:1;
+		uint64_t en16:1;
+		uint64_t reserved_6_7:2;
+		uint64_t clkr:6;
+		uint64_t clkf:12;
+		uint64_t reset_n:1;
+		uint64_t div_reset:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn56xxp1;
+	struct cvmx_lmcx_pll_ctl_cn56xxp1 cn58xx;
+	struct cvmx_lmcx_pll_ctl_cn56xxp1 cn58xxp1;
+};
+
+union cvmx_lmcx_pll_status {
+	uint64_t u64;
+	struct cvmx_lmcx_pll_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ddr__nctl:5;
+		uint64_t ddr__pctl:5;
+		uint64_t reserved_2_21:20;
+		uint64_t rfslip:1;
+		uint64_t fbslip:1;
+#else
+		uint64_t fbslip:1;
+		uint64_t rfslip:1;
+		uint64_t reserved_2_21:20;
+		uint64_t ddr__pctl:5;
+		uint64_t ddr__nctl:5;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_pll_status_s cn50xx;
+	struct cvmx_lmcx_pll_status_s cn52xx;
+	struct cvmx_lmcx_pll_status_s cn52xxp1;
+	struct cvmx_lmcx_pll_status_s cn56xx;
+	struct cvmx_lmcx_pll_status_s cn56xxp1;
+	struct cvmx_lmcx_pll_status_s cn58xx;
+	struct cvmx_lmcx_pll_status_cn58xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t rfslip:1;
+		uint64_t fbslip:1;
+#else
+		uint64_t fbslip:1;
+		uint64_t rfslip:1;
+		uint64_t reserved_2_63:62;
+#endif
+	} cn58xxp1;
+};
+
+union cvmx_lmcx_read_level_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_read_level_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_44_63:20;
+		uint64_t rankmask:4;
+		uint64_t pattern:8;
+		uint64_t row:16;
+		uint64_t col:12;
+		uint64_t reserved_3_3:1;
+		uint64_t bnk:3;
+#else
+		uint64_t bnk:3;
+		uint64_t reserved_3_3:1;
+		uint64_t col:12;
+		uint64_t row:16;
+		uint64_t pattern:8;
+		uint64_t rankmask:4;
+		uint64_t reserved_44_63:20;
+#endif
+	} s;
+	struct cvmx_lmcx_read_level_ctl_s cn52xx;
+	struct cvmx_lmcx_read_level_ctl_s cn52xxp1;
+	struct cvmx_lmcx_read_level_ctl_s cn56xx;
+	struct cvmx_lmcx_read_level_ctl_s cn56xxp1;
+};
+
+union cvmx_lmcx_read_level_dbg {
+	uint64_t u64;
+	struct cvmx_lmcx_read_level_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t bitmask:16;
+		uint64_t reserved_4_15:12;
+		uint64_t byte:4;
+#else
+		uint64_t byte:4;
+		uint64_t reserved_4_15:12;
+		uint64_t bitmask:16;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_read_level_dbg_s cn52xx;
+	struct cvmx_lmcx_read_level_dbg_s cn52xxp1;
+	struct cvmx_lmcx_read_level_dbg_s cn56xx;
+	struct cvmx_lmcx_read_level_dbg_s cn56xxp1;
+};
+
+union cvmx_lmcx_read_level_rankx {
+	uint64_t u64;
+	struct cvmx_lmcx_read_level_rankx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_38_63:26;
+		uint64_t status:2;
+		uint64_t byte8:4;
+		uint64_t byte7:4;
+		uint64_t byte6:4;
+		uint64_t byte5:4;
+		uint64_t byte4:4;
+		uint64_t byte3:4;
+		uint64_t byte2:4;
+		uint64_t byte1:4;
+		uint64_t byte0:4;
+#else
+		uint64_t byte0:4;
+		uint64_t byte1:4;
+		uint64_t byte2:4;
+		uint64_t byte3:4;
+		uint64_t byte4:4;
+		uint64_t byte5:4;
+		uint64_t byte6:4;
+		uint64_t byte7:4;
+		uint64_t byte8:4;
+		uint64_t status:2;
+		uint64_t reserved_38_63:26;
+#endif
+	} s;
+	struct cvmx_lmcx_read_level_rankx_s cn52xx;
+	struct cvmx_lmcx_read_level_rankx_s cn52xxp1;
+	struct cvmx_lmcx_read_level_rankx_s cn56xx;
+	struct cvmx_lmcx_read_level_rankx_s cn56xxp1;
+};
+
+union cvmx_lmcx_reset_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_reset_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t ddr3psv:1;
+		uint64_t ddr3psoft:1;
+		uint64_t ddr3pwarm:1;
+		uint64_t ddr3rst:1;
+#else
+		uint64_t ddr3rst:1;
+		uint64_t ddr3pwarm:1;
+		uint64_t ddr3psoft:1;
+		uint64_t ddr3psv:1;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_lmcx_reset_ctl_s cn61xx;
+	struct cvmx_lmcx_reset_ctl_s cn63xx;
+	struct cvmx_lmcx_reset_ctl_s cn63xxp1;
+	struct cvmx_lmcx_reset_ctl_s cn66xx;
+	struct cvmx_lmcx_reset_ctl_s cn68xx;
+	struct cvmx_lmcx_reset_ctl_s cn68xxp1;
+	struct cvmx_lmcx_reset_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_rlevel_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_rlevel_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t delay_unload_3:1;
+		uint64_t delay_unload_2:1;
+		uint64_t delay_unload_1:1;
+		uint64_t delay_unload_0:1;
+		uint64_t bitmask:8;
+		uint64_t or_dis:1;
+		uint64_t offset_en:1;
+		uint64_t offset:4;
+		uint64_t byte:4;
+#else
+		uint64_t byte:4;
+		uint64_t offset:4;
+		uint64_t offset_en:1;
+		uint64_t or_dis:1;
+		uint64_t bitmask:8;
+		uint64_t delay_unload_0:1;
+		uint64_t delay_unload_1:1;
+		uint64_t delay_unload_2:1;
+		uint64_t delay_unload_3:1;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_lmcx_rlevel_ctl_s cn61xx;
+	struct cvmx_lmcx_rlevel_ctl_s cn63xx;
+	struct cvmx_lmcx_rlevel_ctl_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t offset_en:1;
+		uint64_t offset:4;
+		uint64_t byte:4;
+#else
+		uint64_t byte:4;
+		uint64_t offset:4;
+		uint64_t offset_en:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_rlevel_ctl_s cn66xx;
+	struct cvmx_lmcx_rlevel_ctl_s cn68xx;
+	struct cvmx_lmcx_rlevel_ctl_s cn68xxp1;
+	struct cvmx_lmcx_rlevel_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_rlevel_dbg {
+	uint64_t u64;
+	struct cvmx_lmcx_rlevel_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bitmask:64;
+#else
+		uint64_t bitmask:64;
+#endif
+	} s;
+	struct cvmx_lmcx_rlevel_dbg_s cn61xx;
+	struct cvmx_lmcx_rlevel_dbg_s cn63xx;
+	struct cvmx_lmcx_rlevel_dbg_s cn63xxp1;
+	struct cvmx_lmcx_rlevel_dbg_s cn66xx;
+	struct cvmx_lmcx_rlevel_dbg_s cn68xx;
+	struct cvmx_lmcx_rlevel_dbg_s cn68xxp1;
+	struct cvmx_lmcx_rlevel_dbg_s cnf71xx;
+};
+
+union cvmx_lmcx_rlevel_rankx {
+	uint64_t u64;
+	struct cvmx_lmcx_rlevel_rankx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t status:2;
+		uint64_t byte8:6;
+		uint64_t byte7:6;
+		uint64_t byte6:6;
+		uint64_t byte5:6;
+		uint64_t byte4:6;
+		uint64_t byte3:6;
+		uint64_t byte2:6;
+		uint64_t byte1:6;
+		uint64_t byte0:6;
+#else
+		uint64_t byte0:6;
+		uint64_t byte1:6;
+		uint64_t byte2:6;
+		uint64_t byte3:6;
+		uint64_t byte4:6;
+		uint64_t byte5:6;
+		uint64_t byte6:6;
+		uint64_t byte7:6;
+		uint64_t byte8:6;
+		uint64_t status:2;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_lmcx_rlevel_rankx_s cn61xx;
+	struct cvmx_lmcx_rlevel_rankx_s cn63xx;
+	struct cvmx_lmcx_rlevel_rankx_s cn63xxp1;
+	struct cvmx_lmcx_rlevel_rankx_s cn66xx;
+	struct cvmx_lmcx_rlevel_rankx_s cn68xx;
+	struct cvmx_lmcx_rlevel_rankx_s cn68xxp1;
+	struct cvmx_lmcx_rlevel_rankx_s cnf71xx;
+};
+
+union cvmx_lmcx_rodt_comp_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_rodt_comp_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t enable:1;
+		uint64_t reserved_12_15:4;
+		uint64_t nctl:4;
+		uint64_t reserved_5_7:3;
+		uint64_t pctl:5;
+#else
+		uint64_t pctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t nctl:4;
+		uint64_t reserved_12_15:4;
+		uint64_t enable:1;
+		uint64_t reserved_17_63:47;
+#endif
+	} s;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn50xx;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn52xx;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn52xxp1;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn56xx;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn56xxp1;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn58xx;
+	struct cvmx_lmcx_rodt_comp_ctl_s cn58xxp1;
+};
+
+union cvmx_lmcx_rodt_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_rodt_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t rodt_hi3:4;
+		uint64_t rodt_hi2:4;
+		uint64_t rodt_hi1:4;
+		uint64_t rodt_hi0:4;
+		uint64_t rodt_lo3:4;
+		uint64_t rodt_lo2:4;
+		uint64_t rodt_lo1:4;
+		uint64_t rodt_lo0:4;
+#else
+		uint64_t rodt_lo0:4;
+		uint64_t rodt_lo1:4;
+		uint64_t rodt_lo2:4;
+		uint64_t rodt_lo3:4;
+		uint64_t rodt_hi0:4;
+		uint64_t rodt_hi1:4;
+		uint64_t rodt_hi2:4;
+		uint64_t rodt_hi3:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_rodt_ctl_s cn30xx;
+	struct cvmx_lmcx_rodt_ctl_s cn31xx;
+	struct cvmx_lmcx_rodt_ctl_s cn38xx;
+	struct cvmx_lmcx_rodt_ctl_s cn38xxp2;
+	struct cvmx_lmcx_rodt_ctl_s cn50xx;
+	struct cvmx_lmcx_rodt_ctl_s cn52xx;
+	struct cvmx_lmcx_rodt_ctl_s cn52xxp1;
+	struct cvmx_lmcx_rodt_ctl_s cn56xx;
+	struct cvmx_lmcx_rodt_ctl_s cn56xxp1;
+	struct cvmx_lmcx_rodt_ctl_s cn58xx;
+	struct cvmx_lmcx_rodt_ctl_s cn58xxp1;
+};
+
+union cvmx_lmcx_rodt_mask {
+	uint64_t u64;
+	struct cvmx_lmcx_rodt_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rodt_d3_r1:8;
+		uint64_t rodt_d3_r0:8;
+		uint64_t rodt_d2_r1:8;
+		uint64_t rodt_d2_r0:8;
+		uint64_t rodt_d1_r1:8;
+		uint64_t rodt_d1_r0:8;
+		uint64_t rodt_d0_r1:8;
+		uint64_t rodt_d0_r0:8;
+#else
+		uint64_t rodt_d0_r0:8;
+		uint64_t rodt_d0_r1:8;
+		uint64_t rodt_d1_r0:8;
+		uint64_t rodt_d1_r1:8;
+		uint64_t rodt_d2_r0:8;
+		uint64_t rodt_d2_r1:8;
+		uint64_t rodt_d3_r0:8;
+		uint64_t rodt_d3_r1:8;
+#endif
+	} s;
+	struct cvmx_lmcx_rodt_mask_s cn61xx;
+	struct cvmx_lmcx_rodt_mask_s cn63xx;
+	struct cvmx_lmcx_rodt_mask_s cn63xxp1;
+	struct cvmx_lmcx_rodt_mask_s cn66xx;
+	struct cvmx_lmcx_rodt_mask_s cn68xx;
+	struct cvmx_lmcx_rodt_mask_s cn68xxp1;
+	struct cvmx_lmcx_rodt_mask_s cnf71xx;
+};
+
+union cvmx_lmcx_scramble_cfg0 {
+	uint64_t u64;
+	struct cvmx_lmcx_scramble_cfg0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t key:64;
+#else
+		uint64_t key:64;
+#endif
+	} s;
+	struct cvmx_lmcx_scramble_cfg0_s cn61xx;
+	struct cvmx_lmcx_scramble_cfg0_s cn66xx;
+	struct cvmx_lmcx_scramble_cfg0_s cnf71xx;
+};
+
+union cvmx_lmcx_scramble_cfg1 {
+	uint64_t u64;
+	struct cvmx_lmcx_scramble_cfg1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t key:64;
+#else
+		uint64_t key:64;
+#endif
+	} s;
+	struct cvmx_lmcx_scramble_cfg1_s cn61xx;
+	struct cvmx_lmcx_scramble_cfg1_s cn66xx;
+	struct cvmx_lmcx_scramble_cfg1_s cnf71xx;
+};
+
+union cvmx_lmcx_scrambled_fadr {
+	uint64_t u64;
+	struct cvmx_lmcx_scrambled_fadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_36_63:28;
+		uint64_t fdimm:2;
+		uint64_t fbunk:1;
+		uint64_t fbank:3;
+		uint64_t frow:16;
+		uint64_t fcol:14;
+#else
+		uint64_t fcol:14;
+		uint64_t frow:16;
+		uint64_t fbank:3;
+		uint64_t fbunk:1;
+		uint64_t fdimm:2;
+		uint64_t reserved_36_63:28;
+#endif
+	} s;
+	struct cvmx_lmcx_scrambled_fadr_s cn61xx;
+	struct cvmx_lmcx_scrambled_fadr_s cn66xx;
+	struct cvmx_lmcx_scrambled_fadr_s cnf71xx;
+};
+
+union cvmx_lmcx_slot_ctl0 {
+	uint64_t u64;
+	struct cvmx_lmcx_slot_ctl0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t w2w_init:6;
+		uint64_t w2r_init:6;
+		uint64_t r2w_init:6;
+		uint64_t r2r_init:6;
+#else
+		uint64_t r2r_init:6;
+		uint64_t r2w_init:6;
+		uint64_t w2r_init:6;
+		uint64_t w2w_init:6;
+		uint64_t reserved_24_63:40;
+#endif
+	} s;
+	struct cvmx_lmcx_slot_ctl0_s cn61xx;
+	struct cvmx_lmcx_slot_ctl0_s cn63xx;
+	struct cvmx_lmcx_slot_ctl0_s cn63xxp1;
+	struct cvmx_lmcx_slot_ctl0_s cn66xx;
+	struct cvmx_lmcx_slot_ctl0_s cn68xx;
+	struct cvmx_lmcx_slot_ctl0_s cn68xxp1;
+	struct cvmx_lmcx_slot_ctl0_s cnf71xx;
+};
+
+union cvmx_lmcx_slot_ctl1 {
+	uint64_t u64;
+	struct cvmx_lmcx_slot_ctl1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t w2w_xrank_init:6;
+		uint64_t w2r_xrank_init:6;
+		uint64_t r2w_xrank_init:6;
+		uint64_t r2r_xrank_init:6;
+#else
+		uint64_t r2r_xrank_init:6;
+		uint64_t r2w_xrank_init:6;
+		uint64_t w2r_xrank_init:6;
+		uint64_t w2w_xrank_init:6;
+		uint64_t reserved_24_63:40;
+#endif
+	} s;
+	struct cvmx_lmcx_slot_ctl1_s cn61xx;
+	struct cvmx_lmcx_slot_ctl1_s cn63xx;
+	struct cvmx_lmcx_slot_ctl1_s cn63xxp1;
+	struct cvmx_lmcx_slot_ctl1_s cn66xx;
+	struct cvmx_lmcx_slot_ctl1_s cn68xx;
+	struct cvmx_lmcx_slot_ctl1_s cn68xxp1;
+	struct cvmx_lmcx_slot_ctl1_s cnf71xx;
+};
+
+union cvmx_lmcx_slot_ctl2 {
+	uint64_t u64;
+	struct cvmx_lmcx_slot_ctl2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t w2w_xdimm_init:6;
+		uint64_t w2r_xdimm_init:6;
+		uint64_t r2w_xdimm_init:6;
+		uint64_t r2r_xdimm_init:6;
+#else
+		uint64_t r2r_xdimm_init:6;
+		uint64_t r2w_xdimm_init:6;
+		uint64_t w2r_xdimm_init:6;
+		uint64_t w2w_xdimm_init:6;
+		uint64_t reserved_24_63:40;
+#endif
+	} s;
+	struct cvmx_lmcx_slot_ctl2_s cn61xx;
+	struct cvmx_lmcx_slot_ctl2_s cn63xx;
+	struct cvmx_lmcx_slot_ctl2_s cn63xxp1;
+	struct cvmx_lmcx_slot_ctl2_s cn66xx;
+	struct cvmx_lmcx_slot_ctl2_s cn68xx;
+	struct cvmx_lmcx_slot_ctl2_s cn68xxp1;
+	struct cvmx_lmcx_slot_ctl2_s cnf71xx;
+};
+
+union cvmx_lmcx_timing_params0 {
+	uint64_t u64;
+	struct cvmx_lmcx_timing_params0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t trp_ext:1;
+		uint64_t tcksre:4;
+		uint64_t trp:4;
+		uint64_t tzqinit:4;
+		uint64_t tdllk:4;
+		uint64_t tmod:4;
+		uint64_t tmrd:4;
+		uint64_t txpr:4;
+		uint64_t tcke:4;
+		uint64_t tzqcs:4;
+		uint64_t tckeon:10;
+#else
+		uint64_t tckeon:10;
+		uint64_t tzqcs:4;
+		uint64_t tcke:4;
+		uint64_t txpr:4;
+		uint64_t tmrd:4;
+		uint64_t tmod:4;
+		uint64_t tdllk:4;
+		uint64_t tzqinit:4;
+		uint64_t trp:4;
+		uint64_t tcksre:4;
+		uint64_t trp_ext:1;
+		uint64_t reserved_47_63:17;
+#endif
+	} s;
+	struct cvmx_lmcx_timing_params0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t trp_ext:1;
+		uint64_t tcksre:4;
+		uint64_t trp:4;
+		uint64_t tzqinit:4;
+		uint64_t tdllk:4;
+		uint64_t tmod:4;
+		uint64_t tmrd:4;
+		uint64_t txpr:4;
+		uint64_t tcke:4;
+		uint64_t tzqcs:4;
+		uint64_t reserved_0_9:10;
+#else
+		uint64_t reserved_0_9:10;
+		uint64_t tzqcs:4;
+		uint64_t tcke:4;
+		uint64_t txpr:4;
+		uint64_t tmrd:4;
+		uint64_t tmod:4;
+		uint64_t tdllk:4;
+		uint64_t tzqinit:4;
+		uint64_t trp:4;
+		uint64_t tcksre:4;
+		uint64_t trp_ext:1;
+		uint64_t reserved_47_63:17;
+#endif
+	} cn61xx;
+	struct cvmx_lmcx_timing_params0_cn61xx cn63xx;
+	struct cvmx_lmcx_timing_params0_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_46_63:18;
+		uint64_t tcksre:4;
+		uint64_t trp:4;
+		uint64_t tzqinit:4;
+		uint64_t tdllk:4;
+		uint64_t tmod:4;
+		uint64_t tmrd:4;
+		uint64_t txpr:4;
+		uint64_t tcke:4;
+		uint64_t tzqcs:4;
+		uint64_t tckeon:10;
+#else
+		uint64_t tckeon:10;
+		uint64_t tzqcs:4;
+		uint64_t tcke:4;
+		uint64_t txpr:4;
+		uint64_t tmrd:4;
+		uint64_t tmod:4;
+		uint64_t tdllk:4;
+		uint64_t tzqinit:4;
+		uint64_t trp:4;
+		uint64_t tcksre:4;
+		uint64_t reserved_46_63:18;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_timing_params0_cn61xx cn66xx;
+	struct cvmx_lmcx_timing_params0_cn61xx cn68xx;
+	struct cvmx_lmcx_timing_params0_cn61xx cn68xxp1;
+	struct cvmx_lmcx_timing_params0_cn61xx cnf71xx;
+};
+
+union cvmx_lmcx_timing_params1 {
+	uint64_t u64;
+	struct cvmx_lmcx_timing_params1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t tras_ext:1;
+		uint64_t txpdll:5;
+		uint64_t tfaw:5;
+		uint64_t twldqsen:4;
+		uint64_t twlmrd:4;
+		uint64_t txp:3;
+		uint64_t trrd:3;
+		uint64_t trfc:5;
+		uint64_t twtr:4;
+		uint64_t trcd:4;
+		uint64_t tras:5;
+		uint64_t tmprr:4;
+#else
+		uint64_t tmprr:4;
+		uint64_t tras:5;
+		uint64_t trcd:4;
+		uint64_t twtr:4;
+		uint64_t trfc:5;
+		uint64_t trrd:3;
+		uint64_t txp:3;
+		uint64_t twlmrd:4;
+		uint64_t twldqsen:4;
+		uint64_t tfaw:5;
+		uint64_t txpdll:5;
+		uint64_t tras_ext:1;
+		uint64_t reserved_47_63:17;
+#endif
+	} s;
+	struct cvmx_lmcx_timing_params1_s cn61xx;
+	struct cvmx_lmcx_timing_params1_s cn63xx;
+	struct cvmx_lmcx_timing_params1_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_46_63:18;
+		uint64_t txpdll:5;
+		uint64_t tfaw:5;
+		uint64_t twldqsen:4;
+		uint64_t twlmrd:4;
+		uint64_t txp:3;
+		uint64_t trrd:3;
+		uint64_t trfc:5;
+		uint64_t twtr:4;
+		uint64_t trcd:4;
+		uint64_t tras:5;
+		uint64_t tmprr:4;
+#else
+		uint64_t tmprr:4;
+		uint64_t tras:5;
+		uint64_t trcd:4;
+		uint64_t twtr:4;
+		uint64_t trfc:5;
+		uint64_t trrd:3;
+		uint64_t txp:3;
+		uint64_t twlmrd:4;
+		uint64_t twldqsen:4;
+		uint64_t tfaw:5;
+		uint64_t txpdll:5;
+		uint64_t reserved_46_63:18;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_timing_params1_s cn66xx;
+	struct cvmx_lmcx_timing_params1_s cn68xx;
+	struct cvmx_lmcx_timing_params1_s cn68xxp1;
+	struct cvmx_lmcx_timing_params1_s cnf71xx;
+};
+
+union cvmx_lmcx_tro_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_tro_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t rclk_cnt:32;
+		uint64_t treset:1;
+#else
+		uint64_t treset:1;
+		uint64_t rclk_cnt:32;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_lmcx_tro_ctl_s cn61xx;
+	struct cvmx_lmcx_tro_ctl_s cn63xx;
+	struct cvmx_lmcx_tro_ctl_s cn63xxp1;
+	struct cvmx_lmcx_tro_ctl_s cn66xx;
+	struct cvmx_lmcx_tro_ctl_s cn68xx;
+	struct cvmx_lmcx_tro_ctl_s cn68xxp1;
+	struct cvmx_lmcx_tro_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_tro_stat {
+	uint64_t u64;
+	struct cvmx_lmcx_tro_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ring_cnt:32;
+#else
+		uint64_t ring_cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_tro_stat_s cn61xx;
+	struct cvmx_lmcx_tro_stat_s cn63xx;
+	struct cvmx_lmcx_tro_stat_s cn63xxp1;
+	struct cvmx_lmcx_tro_stat_s cn66xx;
+	struct cvmx_lmcx_tro_stat_s cn68xx;
+	struct cvmx_lmcx_tro_stat_s cn68xxp1;
+	struct cvmx_lmcx_tro_stat_s cnf71xx;
+};
+
+union cvmx_lmcx_wlevel_ctl {
+	uint64_t u64;
+	struct cvmx_lmcx_wlevel_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t rtt_nom:3;
+		uint64_t bitmask:8;
+		uint64_t or_dis:1;
+		uint64_t sset:1;
+		uint64_t lanemask:9;
+#else
+		uint64_t lanemask:9;
+		uint64_t sset:1;
+		uint64_t or_dis:1;
+		uint64_t bitmask:8;
+		uint64_t rtt_nom:3;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_lmcx_wlevel_ctl_s cn61xx;
+	struct cvmx_lmcx_wlevel_ctl_s cn63xx;
+	struct cvmx_lmcx_wlevel_ctl_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t sset:1;
+		uint64_t lanemask:9;
+#else
+		uint64_t lanemask:9;
+		uint64_t sset:1;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn63xxp1;
+	struct cvmx_lmcx_wlevel_ctl_s cn66xx;
+	struct cvmx_lmcx_wlevel_ctl_s cn68xx;
+	struct cvmx_lmcx_wlevel_ctl_s cn68xxp1;
+	struct cvmx_lmcx_wlevel_ctl_s cnf71xx;
+};
+
+union cvmx_lmcx_wlevel_dbg {
+	uint64_t u64;
+	struct cvmx_lmcx_wlevel_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t bitmask:8;
+		uint64_t byte:4;
+#else
+		uint64_t byte:4;
+		uint64_t bitmask:8;
+		uint64_t reserved_12_63:52;
+#endif
+	} s;
+	struct cvmx_lmcx_wlevel_dbg_s cn61xx;
+	struct cvmx_lmcx_wlevel_dbg_s cn63xx;
+	struct cvmx_lmcx_wlevel_dbg_s cn63xxp1;
+	struct cvmx_lmcx_wlevel_dbg_s cn66xx;
+	struct cvmx_lmcx_wlevel_dbg_s cn68xx;
+	struct cvmx_lmcx_wlevel_dbg_s cn68xxp1;
+	struct cvmx_lmcx_wlevel_dbg_s cnf71xx;
+};
+
+union cvmx_lmcx_wlevel_rankx {
+	uint64_t u64;
+	struct cvmx_lmcx_wlevel_rankx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t status:2;
+		uint64_t byte8:5;
+		uint64_t byte7:5;
+		uint64_t byte6:5;
+		uint64_t byte5:5;
+		uint64_t byte4:5;
+		uint64_t byte3:5;
+		uint64_t byte2:5;
+		uint64_t byte1:5;
+		uint64_t byte0:5;
+#else
+		uint64_t byte0:5;
+		uint64_t byte1:5;
+		uint64_t byte2:5;
+		uint64_t byte3:5;
+		uint64_t byte4:5;
+		uint64_t byte5:5;
+		uint64_t byte6:5;
+		uint64_t byte7:5;
+		uint64_t byte8:5;
+		uint64_t status:2;
+		uint64_t reserved_47_63:17;
+#endif
+	} s;
+	struct cvmx_lmcx_wlevel_rankx_s cn61xx;
+	struct cvmx_lmcx_wlevel_rankx_s cn63xx;
+	struct cvmx_lmcx_wlevel_rankx_s cn63xxp1;
+	struct cvmx_lmcx_wlevel_rankx_s cn66xx;
+	struct cvmx_lmcx_wlevel_rankx_s cn68xx;
+	struct cvmx_lmcx_wlevel_rankx_s cn68xxp1;
+	struct cvmx_lmcx_wlevel_rankx_s cnf71xx;
+};
+
+union cvmx_lmcx_wodt_ctl0 {
+	uint64_t u64;
+	struct cvmx_lmcx_wodt_ctl0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
+	} s;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wodt_d1_r1:8;
+		uint64_t wodt_d1_r0:8;
+		uint64_t wodt_d0_r1:8;
+		uint64_t wodt_d0_r0:8;
+#else
+		uint64_t wodt_d0_r0:8;
+		uint64_t wodt_d0_r1:8;
+		uint64_t wodt_d1_r0:8;
+		uint64_t wodt_d1_r1:8;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn30xx;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx cn31xx;
+	struct cvmx_lmcx_wodt_ctl0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wodt_hi3:4;
+		uint64_t wodt_hi2:4;
+		uint64_t wodt_hi1:4;
+		uint64_t wodt_hi0:4;
+		uint64_t wodt_lo3:4;
+		uint64_t wodt_lo2:4;
+		uint64_t wodt_lo1:4;
+		uint64_t wodt_lo0:4;
+#else
+		uint64_t wodt_lo0:4;
+		uint64_t wodt_lo1:4;
+		uint64_t wodt_lo2:4;
+		uint64_t wodt_lo3:4;
+		uint64_t wodt_hi0:4;
+		uint64_t wodt_hi1:4;
+		uint64_t wodt_hi2:4;
+		uint64_t wodt_hi3:4;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn38xx;
+	struct cvmx_lmcx_wodt_ctl0_cn38xx cn38xxp2;
+	struct cvmx_lmcx_wodt_ctl0_cn38xx cn50xx;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx cn52xx;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx cn52xxp1;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx cn56xx;
+	struct cvmx_lmcx_wodt_ctl0_cn30xx cn56xxp1;
+	struct cvmx_lmcx_wodt_ctl0_cn38xx cn58xx;
+	struct cvmx_lmcx_wodt_ctl0_cn38xx cn58xxp1;
+};
+
+union cvmx_lmcx_wodt_ctl1 {
+	uint64_t u64;
+	struct cvmx_lmcx_wodt_ctl1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wodt_d3_r1:8;
+		uint64_t wodt_d3_r0:8;
+		uint64_t wodt_d2_r1:8;
+		uint64_t wodt_d2_r0:8;
+#else
+		uint64_t wodt_d2_r0:8;
+		uint64_t wodt_d2_r1:8;
+		uint64_t wodt_d3_r0:8;
+		uint64_t wodt_d3_r1:8;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_lmcx_wodt_ctl1_s cn30xx;
+	struct cvmx_lmcx_wodt_ctl1_s cn31xx;
+	struct cvmx_lmcx_wodt_ctl1_s cn52xx;
+	struct cvmx_lmcx_wodt_ctl1_s cn52xxp1;
+	struct cvmx_lmcx_wodt_ctl1_s cn56xx;
+	struct cvmx_lmcx_wodt_ctl1_s cn56xxp1;
+};
+
+union cvmx_lmcx_wodt_mask {
+	uint64_t u64;
+	struct cvmx_lmcx_wodt_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t wodt_d3_r1:8;
+		uint64_t wodt_d3_r0:8;
+		uint64_t wodt_d2_r1:8;
+		uint64_t wodt_d2_r0:8;
+		uint64_t wodt_d1_r1:8;
+		uint64_t wodt_d1_r0:8;
+		uint64_t wodt_d0_r1:8;
+		uint64_t wodt_d0_r0:8;
+#else
+		uint64_t wodt_d0_r0:8;
+		uint64_t wodt_d0_r1:8;
+		uint64_t wodt_d1_r0:8;
+		uint64_t wodt_d1_r1:8;
+		uint64_t wodt_d2_r0:8;
+		uint64_t wodt_d2_r1:8;
+		uint64_t wodt_d3_r0:8;
+		uint64_t wodt_d3_r1:8;
+#endif
+	} s;
+	struct cvmx_lmcx_wodt_mask_s cn61xx;
+	struct cvmx_lmcx_wodt_mask_s cn63xx;
+	struct cvmx_lmcx_wodt_mask_s cn63xxp1;
+	struct cvmx_lmcx_wodt_mask_s cn66xx;
+	struct cvmx_lmcx_wodt_mask_s cn68xx;
+	struct cvmx_lmcx_wodt_mask_s cn68xxp1;
+	struct cvmx_lmcx_wodt_mask_s cnf71xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index 14dd11f..349bb2b 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -218,6 +218,12 @@
 #define OCTEON_CN5XXX           (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
 #define OCTEON_CN6XXX           (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
 
+/* These are used to cover entire families of OCTEON processors */
+#define OCTEON_FAM_1		(OCTEON_CN3XXX)
+#define OCTEON_FAM_PLUS		(OCTEON_CN5XXX)
+#define OCTEON_FAM_1_PLUS	(OCTEON_FAM_PLUS | OM_MATCH_PREVIOUS_MODELS)
+#define OCTEON_FAM_2		(OCTEON_CN6XXX)
+
 /* The revision byte (low byte) has two different encodings.
  * CN3XXX:
  *
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 790939d..254e995 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -209,13 +209,6 @@
 	} s;
 };
 
-struct octeon_cf_data {
-	unsigned long	base_region_bias;
-	unsigned int	base_region;	/* The chip select region used by CF */
-	int		is16bit;	/* 0 - 8bit, !0 - 16bit */
-	int		dma_engine;	/* -1 for no DMA */
-};
-
 extern void octeon_write_lcd(const char *s);
 extern void octeon_check_cpu_bist(void);
 extern int octeon_get_boot_debug_flag(void);
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index da9bd7d..31ab10f 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -31,19 +31,19 @@
 #define PAGE_SHIFT	16
 #endif
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK       (~((1 << PAGE_SHIFT) - 1))
+#define PAGE_MASK       (~(PAGE_SIZE - 1))
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 #define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
 #define HPAGE_SIZE	(_AC(1,UL) << HPAGE_SHIFT)
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
-#else /* !CONFIG_HUGETLB_PAGE */
+#else /* !CONFIG_MIPS_HUGE_TLB_SUPPORT */
 #define HPAGE_SHIFT	({BUILD_BUG(); 0; })
 #define HPAGE_SIZE	({BUILD_BUG(); 0; })
 #define HPAGE_MASK	({BUILD_BUG(); 0; })
 #define HUGETLB_PAGE_ORDER	({BUILD_BUG(); 0; })
-#endif /* CONFIG_HUGETLB_PAGE */
+#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index f5b521d..c631910 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -175,7 +175,7 @@
 
 static inline int pmd_bad(pmd_t pmd)
 {
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/* pmd_huge(pmd) but inline */
 	if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
 		return 0;
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index da4ba49..f6a0439 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -34,38 +34,72 @@
  */
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
 
-#define _PAGE_PRESENT               (1<<6)  /* implemented in software */
-#define _PAGE_READ                  (1<<7)  /* implemented in software */
-#define _PAGE_WRITE                 (1<<8)  /* implemented in software */
-#define _PAGE_ACCESSED              (1<<9)  /* implemented in software */
-#define _PAGE_MODIFIED              (1<<10) /* implemented in software */
-#define _PAGE_FILE                  (1<<10) /* set:pagecache unset:swap */
+/*
+ * The following bits are directly used by the TLB hardware
+ */
+#define _PAGE_R4KBUG		(1 << 0)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL		(1 << 0)
+#define _PAGE_VALID_SHIFT	1
+#define _PAGE_VALID		(1 << _PAGE_VALID_SHIFT)
+#define _PAGE_SILENT_READ	(1 << 1)  /* synonym                 */
+#define _PAGE_DIRTY_SHIFT	2
+#define _PAGE_DIRTY		(1 << _PAGE_DIRTY_SHIFT)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE	(1 << 2)
+#define _CACHE_SHIFT		3
+#define _CACHE_MASK		(7 << 3)
 
-#define _PAGE_R4KBUG                (1<<0)  /* workaround for r4k bug  */
-#define _PAGE_GLOBAL                (1<<0)
-#define _PAGE_VALID                 (1<<1)
-#define _PAGE_SILENT_READ           (1<<1)  /* synonym                 */
-#define _PAGE_DIRTY                 (1<<2)  /* The MIPS dirty bit      */
-#define _PAGE_SILENT_WRITE          (1<<2)
-#define _CACHE_SHIFT                3
-#define _CACHE_MASK                 (7<<3)
+/*
+ * The following bits are implemented in software
+ *
+ * _PAGE_FILE semantics: set:pagecache unset:swap
+ */ 
+#define _PAGE_PRESENT_SHIFT	6
+#define _PAGE_PRESENT		(1 << _PAGE_PRESENT_SHIFT)
+#define _PAGE_READ_SHIFT	7
+#define _PAGE_READ		(1 << _PAGE_READ_SHIFT)
+#define _PAGE_WRITE_SHIFT	8
+#define _PAGE_WRITE		(1 << _PAGE_WRITE_SHIFT)
+#define _PAGE_ACCESSED_SHIFT	9
+#define _PAGE_ACCESSED		(1 << _PAGE_ACCESSED_SHIFT)
+#define _PAGE_MODIFIED_SHIFT	10
+#define _PAGE_MODIFIED		(1 << _PAGE_MODIFIED_SHIFT)
+
+#define _PAGE_FILE		(1 << 10)
 
 #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
-#define _PAGE_PRESENT               (1<<0)  /* implemented in software */
-#define _PAGE_READ                  (1<<1)  /* implemented in software */
-#define _PAGE_WRITE                 (1<<2)  /* implemented in software */
-#define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
-#define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
-#define _PAGE_FILE                  (1<<4)  /* set:pagecache unset:swap */
+/*
+ * The following are implemented by software
+ *
+ * _PAGE_FILE semantics: set:pagecache unset:swap
+ */
+#define _PAGE_PRESENT_SHIFT	0
+#define _PAGE_PRESENT		(1 <<  _PAGE_PRESENT_SHIFT)
+#define _PAGE_READ_SHIFT	1
+#define _PAGE_READ		(1 <<  _PAGE_READ_SHIFT)
+#define _PAGE_WRITE_SHIFT	2
+#define _PAGE_WRITE		(1 <<  _PAGE_WRITE_SHIFT)
+#define _PAGE_ACCESSED_SHIFT	3
+#define _PAGE_ACCESSED		(1 <<  _PAGE_ACCESSED_SHIFT)
+#define _PAGE_MODIFIED_SHIFT	4
+#define _PAGE_MODIFIED		(1 <<  _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE_SHIFT	4
+#define _PAGE_FILE		(1 <<  _PAGE_FILE_SHIFT)
 
-#define _PAGE_GLOBAL                (1<<8)
-#define _PAGE_VALID                 (1<<9)
-#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
-#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
-#define _PAGE_SILENT_WRITE          (1<<10)
-#define _CACHE_UNCACHED             (1<<11)
-#define _CACHE_MASK                 (1<<11)
+/*
+ * And these are the hardware TLB bits
+ */
+#define _PAGE_GLOBAL_SHIFT	8
+#define _PAGE_GLOBAL		(1 <<  _PAGE_GLOBAL_SHIFT)
+#define _PAGE_VALID_SHIFT	9
+#define _PAGE_VALID		(1 <<  _PAGE_VALID_SHIFT)
+#define _PAGE_SILENT_READ	(1 <<  _PAGE_VALID_SHIFT)	/* synonym  */
+#define _PAGE_DIRTY_SHIFT	10
+#define _PAGE_DIRTY		(1 << _PAGE_DIRTY_SHIFT)
+#define _PAGE_SILENT_WRITE	(1 << _PAGE_DIRTY_SHIFT)
+#define _CACHE_UNCACHED_SHIFT	11
+#define _CACHE_UNCACHED		(1 << _CACHE_UNCACHED_SHIFT)
+#define _CACHE_MASK		(1 << _CACHE_UNCACHED_SHIFT)
 
 #else /* 'Normal' r4K case */
 /*
@@ -76,25 +110,25 @@
  * which is more than we need right now.
  */
 
-/* implemented in software */
+/*
+ * The following bits are implemented in software
+ *
+ * _PAGE_READ / _PAGE_READ_SHIFT should be unused if cpu_has_rixi.
+ * _PAGE_FILE semantics: set:pagecache unset:swap
+ */
 #define _PAGE_PRESENT_SHIFT	(0)
 #define _PAGE_PRESENT		(1 << _PAGE_PRESENT_SHIFT)
-/* implemented in software, should be unused if cpu_has_rixi. */
 #define _PAGE_READ_SHIFT	(cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
 #define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
-/* implemented in software */
 #define _PAGE_WRITE_SHIFT	(_PAGE_READ_SHIFT + 1)
 #define _PAGE_WRITE		(1 << _PAGE_WRITE_SHIFT)
-/* implemented in software */
 #define _PAGE_ACCESSED_SHIFT	(_PAGE_WRITE_SHIFT + 1)
 #define _PAGE_ACCESSED		(1 << _PAGE_ACCESSED_SHIFT)
-/* implemented in software */
 #define _PAGE_MODIFIED_SHIFT	(_PAGE_ACCESSED_SHIFT + 1)
 #define _PAGE_MODIFIED		(1 << _PAGE_MODIFIED_SHIFT)
-/* set:pagecache unset:swap */
 #define _PAGE_FILE		(_PAGE_MODIFIED)
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 /* huge tlb page */
 #define _PAGE_HUGE_SHIFT	(_PAGE_MODIFIED_SHIFT + 1)
 #define _PAGE_HUGE		(1 << _PAGE_HUGE_SHIFT)
@@ -103,8 +137,17 @@
 #define _PAGE_HUGE		({BUG(); 1; })  /* Dummy value */
 #endif
 
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+/* huge tlb page */
+#define _PAGE_SPLITTING_SHIFT	(_PAGE_HUGE_SHIFT + 1)
+#define _PAGE_SPLITTING		(1 << _PAGE_SPLITTING_SHIFT)
+#else
+#define _PAGE_SPLITTING_SHIFT	(_PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING		({BUG(); 1; })  /* Dummy value */
+#endif
+
 /* Page cannot be executed */
-#define _PAGE_NO_EXEC_SHIFT	(cpu_has_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
+#define _PAGE_NO_EXEC_SHIFT	(cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT)
 #define _PAGE_NO_EXEC		({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; })
 
 /* Page cannot be read */
@@ -192,20 +235,6 @@
 #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
 #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT)
 
-#elif defined(CONFIG_CPU_RM9000)
-
-#define _CACHE_WT		    (0<<_CACHE_SHIFT)
-#define _CACHE_WTWA		    (1<<_CACHE_SHIFT)
-#define _CACHE_UC_B		    (2<<_CACHE_SHIFT)
-#define _CACHE_WB		    (3<<_CACHE_SHIFT)
-#define _CACHE_CWBEA		    (4<<_CACHE_SHIFT)
-#define _CACHE_CWB		    (5<<_CACHE_SHIFT)
-#define _CACHE_UCNB		    (6<<_CACHE_SHIFT)
-#define _CACHE_FPC		    (7<<_CACHE_SHIFT)
-
-#define _CACHE_UNCACHED		    _CACHE_UC_B
-#define _CACHE_CACHABLE_NONCOHERENT _CACHE_WB
-
 #else
 
 #define _CACHE_CACHABLE_NO_WA	    (0<<_CACHE_SHIFT)  /* R4600 only      */
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 14490e9..ec50d52 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -8,6 +8,7 @@
 #ifndef _ASM_PGTABLE_H
 #define _ASM_PGTABLE_H
 
+#include <linux/mmzone.h>
 #ifdef CONFIG_32BIT
 #include <asm/pgtable-32.h>
 #endif
@@ -85,7 +86,12 @@
  * and a page entry and page directory to the page they refer to.
  */
 #define pmd_phys(pmd)		virt_to_phys((void *)pmd_val(pmd))
-#define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+
+#define __pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+#ifndef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_page(pmd)		__pmd_page(pmd)
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE  */
+
 #define pmd_page_vaddr(pmd)	pmd_val(pmd)
 
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
@@ -98,7 +104,6 @@
 	ptep->pte_high = pte.pte_high;
 	smp_wmb();
 	ptep->pte_low = pte.pte_low;
-	//printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
 
 	if (pte.pte_low & _PAGE_GLOBAL) {
 		pte_t *buddy = ptep_buddy(ptep);
@@ -366,6 +371,14 @@
 	__update_cache(vma, address, pte);
 }
 
+static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+	unsigned long address, pmd_t *pmdp)
+{
+	pte_t pte = *(pte_t *)pmdp;
+
+	__update_tlb(vma, address, pte);
+}
+
 #define kern_addr_valid(addr)	(1)
 
 #ifdef CONFIG_64BIT_PHYS_ADDR
@@ -385,6 +398,157 @@
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 #endif
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+extern int has_transparent_hugepage(void);
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_HUGE);
+}
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_HUGE;
+
+	return pmd;
+}
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_SPLITTING);
+}
+
+static inline pmd_t pmd_mksplitting(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_SPLITTING;
+
+	return pmd;
+}
+
+extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		       pmd_t *pmdp, pmd_t pmd);
+
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+/* Extern to avoid header file madness */
+extern void pmdp_splitting_flush(struct vm_area_struct *vma,
+					unsigned long address,
+					pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMD_WRITE
+static inline int pmd_write(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_WRITE);
+}
+
+static inline pmd_t pmd_wrprotect(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	return pmd;
+}
+
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_WRITE;
+	if (pmd_val(pmd) & _PAGE_MODIFIED)
+		pmd_val(pmd) |= _PAGE_SILENT_WRITE;
+
+	return pmd;
+}
+
+static inline int pmd_dirty(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_MODIFIED);
+}
+
+static inline pmd_t pmd_mkclean(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
+	return pmd;
+}
+
+static inline pmd_t pmd_mkdirty(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_MODIFIED;
+	if (pmd_val(pmd) & _PAGE_WRITE)
+		pmd_val(pmd) |= _PAGE_SILENT_WRITE;
+
+	return pmd;
+}
+
+static inline int pmd_young(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_ACCESSED);
+}
+
+static inline pmd_t pmd_mkold(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+
+	return pmd;
+}
+
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_ACCESSED;
+
+	if (cpu_has_rixi) {
+		if (!(pmd_val(pmd) & _PAGE_NO_READ))
+			pmd_val(pmd) |= _PAGE_SILENT_READ;
+	} else {
+		if (pmd_val(pmd) & _PAGE_READ)
+			pmd_val(pmd) |= _PAGE_SILENT_READ;
+	}
+
+	return pmd;
+}
+
+/* Extern to avoid header file madness */
+extern pmd_t mk_pmd(struct page *page, pgprot_t prot);
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+	return pmd_val(pmd) >> _PFN_SHIFT;
+}
+
+static inline struct page *pmd_page(pmd_t pmd)
+{
+	if (pmd_trans_huge(pmd))
+		return pfn_to_page(pmd_pfn(pmd));
+
+	return pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT);
+}
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+	pmd_val(pmd) = (pmd_val(pmd) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+	return pmd;
+}
+
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY);
+
+	return pmd;
+}
+
+/*
+ * The generic version pmdp_get_and_clear uses a version of pmd_clear() with a
+ * different prototype.
+ */
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+				       unsigned long address, pmd_t *pmdp)
+{
+	pmd_t old = *pmdp;
+
+	pmd_clear(pmdp);
+
+	return old;
+}
+
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
 #include <asm-generic/pgtable.h>
 
 /*
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/war.h b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h
index 9e2ee42..c74eb16 100644
--- a/arch/mips/include/asm/pmc-sierra/msp71xx/war.h
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h
@@ -17,7 +17,6 @@
 #define MIPS4K_ICACHE_REFILL_WAR	0
 #define MIPS_CACHE_SYNC_WAR		0
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
 #define ICACHE_REFILLS_WORKAROUND_WAR	0
 #define R10000_LLSC_WAR			0
 #if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index d28c41e..bd98b50 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -226,8 +226,6 @@
 	unsigned long cp0_badvaddr;	/* Last user fault */
 	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
 	unsigned long error_code;
-	unsigned long irix_trampoline;  /* Wheee... */
-	unsigned long irix_oldctx;
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
     struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
     struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
@@ -297,8 +295,6 @@
 	.cp0_badvaddr		= 0,				\
 	.cp0_baduaddr		= 0,				\
 	.error_code		= 0,				\
-	.irix_trampoline	= 0,				\
-	.irix_oldctx		= 0,				\
 	/*							\
 	 * Cavium Octeon specifics (null if not Octeon)		\
 	 */							\
diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h
index 1493429..3dce7c7 100644
--- a/arch/mips/include/asm/sgiarcs.h
+++ b/arch/mips/include/asm/sgiarcs.h
@@ -366,7 +366,7 @@
  * Macros for calling a 32-bit ARC implementation from 64-bit code
  */
 
-#if defined(CONFIG_64BIT) && defined(CONFIG_ARC32)
+#if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32)
 
 #define __arc_clobbers							\
 	"$2", "$3" /* ... */, "$8", "$9", "$10", "$11", 			\
@@ -475,10 +475,10 @@
 	__res;								\
 })
 
-#endif /* defined(CONFIG_64BIT) && defined(CONFIG_ARC32) */
+#endif /* defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) */
 
-#if (defined(CONFIG_32BIT) && defined(CONFIG_ARC32)) ||		\
-    (defined(CONFIG_64BIT) && defined(CONFIG_ARC64))
+#if (defined(CONFIG_32BIT) && defined(CONFIG_FW_ARC32)) ||		\
+    (defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC64))
 
 #define ARC_CALL0(dest)							\
 ({	long __res;							\
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index d4fb4d8..f33b5fd 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -40,6 +40,8 @@
 #define SMP_CALL_FUNCTION	0x2
 /* Octeon - Tell another core to flush its icache */
 #define SMP_ICACHE_FLUSH	0x4
+/* Used by kexec crashdump to save all cpu's state */
+#define SMP_DUMP		0x8
 
 extern volatile cpumask_t cpu_callin_map;
 
@@ -91,4 +93,8 @@
 	mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
 }
 
+#if defined(CONFIG_KEXEC)
+extern void (*dump_ipi_function_ptr)(void *);
+void dump_send_ipi(void (*dump_ipi_callback)(void *));
+#endif
 #endif /* __ASM_SMP_H */
diff --git a/arch/mips/include/asm/smvp.h b/arch/mips/include/asm/smvp.h
deleted file mode 100644
index 0d0e80a..0000000
--- a/arch/mips/include/asm/smvp.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _ASM_SMVP_H
-#define _ASM_SMVP_H
-
-/*
- * Definitions for SMVP multitasking on MIPS MT cores
- */
-struct task_struct;
-
-extern void smvp_smp_setup(void);
-extern void smvp_smp_finish(void);
-extern void smvp_boot_secondary(int cpu, struct task_struct *t);
-extern void smvp_init_secondary(void);
-extern void smvp_smp_finish(void);
-extern void smvp_cpus_done(void);
-extern void smvp_prepare_cpus(unsigned int max_cpus);
-
-/* This is platform specific */
-extern void smvp_send_ipi(int cpu, unsigned int action);
-#endif /*  _ASM_SMVP_H */
diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h
index 4461198..65900da 100644
--- a/arch/mips/include/asm/sparsemem.h
+++ b/arch/mips/include/asm/sparsemem.h
@@ -6,7 +6,7 @@
  * SECTION_SIZE_BITS		2^N: how big each section will be
  * MAX_PHYSMEM_BITS		2^N: how much memory we can have in that space
  */
-#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PAGE_SIZE_64KB)
+#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && defined(CONFIG_PAGE_SIZE_64KB)
 # define SECTION_SIZE_BITS	29
 #else
 # define SECTION_SIZE_BITS	28
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index bc14447..761f2e9 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -50,10 +50,8 @@
 /*
  * Initialize the calling CPU's compare interrupt as clockevent device
  */
-#ifdef CONFIG_CEVT_R4K_LIB
 extern unsigned int __weak get_c0_compare_int(void);
 extern int r4k_clockevent_init(void);
-#endif
 
 static inline int mips_clockevent_init(void)
 {
@@ -71,7 +69,7 @@
 /*
  * Initialize the count register as a clocksource
  */
-#ifdef CONFIG_CSRC_R4K_LIB
+#ifdef CONFIG_CSRC_R4K
 extern int init_r4k_clocksource(void);
 #endif
 
diff --git a/arch/mips/include/asm/titan_dep.h b/arch/mips/include/asm/titan_dep.h
deleted file mode 100644
index fee1908..0000000
--- a/arch/mips/include/asm/titan_dep.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Board specific definititions for the PMC-Sierra Yosemite
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __TITAN_DEP_H__
-#define __TITAN_DEP_H__
-
-#include <asm/addrspace.h>              /* for KSEG1ADDR() */
-#include <asm/byteorder.h>              /* for cpu_to_le32() */
-
-#define TITAN_READ(ofs)							\
-	(*(volatile u32 *)(ocd_base+(ofs)))
-#define TITAN_READ_16(ofs)						\
-	(*(volatile u16 *)(ocd_base+(ofs)))
-#define TITAN_READ_8(ofs)						\
-	(*(volatile u8 *)(ocd_base+(ofs)))
-
-#define TITAN_WRITE(ofs, data)						\
-	do { *(volatile u32 *)(ocd_base+(ofs)) = (data); } while (0)
-#define TITAN_WRITE_16(ofs, data)					\
-	do { *(volatile u16 *)(ocd_base+(ofs)) = (data); } while (0)
-#define TITAN_WRITE_8(ofs, data)					\
-	do { *(volatile u8 *)(ocd_base+(ofs)) = (data); } while (0)
-
-/*
- * PCI specific defines
- */
-#define	TITAN_PCI_0_CONFIG_ADDRESS	0x780
-#define	TITAN_PCI_0_CONFIG_DATA		0x784
-
-/*
- * HT specific defines
- */
-#define RM9000x2_HTLINK_REG		0xbb000644
-#define RM9000x2_BASE_ADDR		0xbb000000
-
-#define OCD_BASE			0xfb000000UL
-#define OCD_SIZE			0x3000UL
-
-extern unsigned long ocd_base;
-
-/*
- * OCD Registers
- */
-#define RM9000x2_OCD_LKB5		0x0128		/* Ethernet */
-#define RM9000x2_OCD_LKM5		0x012c
-
-#define RM9000x2_OCD_LKB7		0x0138		/* HT Region 0 */
-#define RM9000x2_OCD_LKM7		0x013c
-#define RM9000x2_OCD_LKB8		0x0140		/* HT Region 1 */
-#define RM9000x2_OCD_LKM8		0x0144
-
-#define RM9000x2_OCD_LKB9		0x0148		/* Local Bus */
-#define RM9000x2_OCD_LKM9		0x014c
-#define RM9000x2_OCD_LKB10		0x0150
-#define RM9000x2_OCD_LKM10		0x0154
-#define RM9000x2_OCD_LKB11		0x0158
-#define RM9000x2_OCD_LKM11		0x015c
-#define RM9000x2_OCD_LKB12		0x0160
-#define RM9000x2_OCD_LKM12		0x0164
-
-#define RM9000x2_OCD_LKB13		0x0168		/* Scratch RAM */
-#define RM9000x2_OCD_LKM13		0x016c
-
-#define RM9000x2_OCD_LPD0		0x0200		/* Local Bus */
-#define RM9000x2_OCD_LPD1		0x0210
-#define RM9000x2_OCD_LPD2		0x0220
-#define RM9000x2_OCD_LPD3		0x0230
-
-#define RM9000x2_OCD_HTDVID		0x0600	/* HT Device Header */
-#define RM9000x2_OCD_HTSC		0x0604
-#define RM9000x2_OCD_HTCCR		0x0608
-#define RM9000x2_OCD_HTBHL		0x060c
-#define RM9000x2_OCD_HTBAR0		0x0610
-#define RM9000x2_OCD_HTBAR1		0x0614
-#define RM9000x2_OCD_HTBAR2		0x0618
-#define RM9000x2_OCD_HTBAR3		0x061c
-#define RM9000x2_OCD_HTBAR4		0x0620
-#define RM9000x2_OCD_HTBAR5		0x0624
-#define RM9000x2_OCD_HTCBCPT		0x0628
-#define RM9000x2_OCD_HTSDVID		0x062c
-#define RM9000x2_OCD_HTXRA		0x0630
-#define RM9000x2_OCD_HTCAP1		0x0634
-#define RM9000x2_OCD_HTIL		0x063c
-
-#define RM9000x2_OCD_HTLCC		0x0640	/* HT Capability Block */
-#define RM9000x2_OCD_HTLINK		0x0644
-#define RM9000x2_OCD_HTFQREV		0x0648
-
-#define RM9000x2_OCD_HTERCTL		0x0668	/* HT Controller */
-#define RM9000x2_OCD_HTRXDB		0x066c
-#define RM9000x2_OCD_HTIMPED		0x0670
-#define RM9000x2_OCD_HTSWIMP		0x0674
-#define RM9000x2_OCD_HTCAL		0x0678
-
-#define RM9000x2_OCD_HTBAA30		0x0680
-#define RM9000x2_OCD_HTBAA54		0x0684
-#define RM9000x2_OCD_HTMASK0		0x0688
-#define RM9000x2_OCD_HTMASK1		0x068c
-#define RM9000x2_OCD_HTMASK2		0x0690
-#define RM9000x2_OCD_HTMASK3		0x0694
-#define RM9000x2_OCD_HTMASK4		0x0698
-#define RM9000x2_OCD_HTMASK5		0x069c
-
-#define RM9000x2_OCD_HTIFCTL		0x06a0
-#define RM9000x2_OCD_HTPLL		0x06a4
-
-#define RM9000x2_OCD_HTSRI		0x06b0
-#define RM9000x2_OCD_HTRXNUM		0x06b4
-#define RM9000x2_OCD_HTTXNUM		0x06b8
-
-#define RM9000x2_OCD_HTTXCNT		0x06c8
-
-#define RM9000x2_OCD_HTERROR		0x06d8
-#define RM9000x2_OCD_HTRCRCE		0x06dc
-#define RM9000x2_OCD_HTEOI		0x06e0
-
-#define RM9000x2_OCD_CRCR		0x06f0
-
-#define RM9000x2_OCD_HTCFGA		0x06f8
-#define RM9000x2_OCD_HTCFGD		0x06fc
-
-#define RM9000x2_OCD_INTMSG		0x0a00
-
-#define RM9000x2_OCD_INTPIN0		0x0a40
-#define RM9000x2_OCD_INTPIN1		0x0a44
-#define RM9000x2_OCD_INTPIN2		0x0a48
-#define RM9000x2_OCD_INTPIN3		0x0a4c
-#define RM9000x2_OCD_INTPIN4		0x0a50
-#define RM9000x2_OCD_INTPIN5		0x0a54
-#define RM9000x2_OCD_INTPIN6		0x0a58
-#define RM9000x2_OCD_INTPIN7		0x0a5c
-#define RM9000x2_OCD_SEM		0x0a60
-#define RM9000x2_OCD_SEMSET		0x0a64
-#define RM9000x2_OCD_SEMCLR		0x0a68
-
-#define RM9000x2_OCD_TKT		0x0a70
-#define RM9000x2_OCD_TKTINC		0x0a74
-
-#define RM9000x2_OCD_NMICONFIG		0x0ac0		/* Interrupts */
-#define RM9000x2_OCD_INTP0PRI		0x1a80
-#define RM9000x2_OCD_INTP1PRI		0x1a80
-#define RM9000x2_OCD_INTP0STATUS0	0x1b00
-#define RM9000x2_OCD_INTP0MASK0		0x1b04
-#define RM9000x2_OCD_INTP0SET0		0x1b08
-#define RM9000x2_OCD_INTP0CLEAR0	0x1b0c
-#define RM9000x2_OCD_INTP0STATUS1	0x1b10
-#define RM9000x2_OCD_INTP0MASK1		0x1b14
-#define RM9000x2_OCD_INTP0SET1		0x1b18
-#define RM9000x2_OCD_INTP0CLEAR1	0x1b1c
-#define RM9000x2_OCD_INTP0STATUS2	0x1b20
-#define RM9000x2_OCD_INTP0MASK2		0x1b24
-#define RM9000x2_OCD_INTP0SET2		0x1b28
-#define RM9000x2_OCD_INTP0CLEAR2	0x1b2c
-#define RM9000x2_OCD_INTP0STATUS3	0x1b30
-#define RM9000x2_OCD_INTP0MASK3		0x1b34
-#define RM9000x2_OCD_INTP0SET3		0x1b38
-#define RM9000x2_OCD_INTP0CLEAR3	0x1b3c
-#define RM9000x2_OCD_INTP0STATUS4	0x1b40
-#define RM9000x2_OCD_INTP0MASK4		0x1b44
-#define RM9000x2_OCD_INTP0SET4		0x1b48
-#define RM9000x2_OCD_INTP0CLEAR4	0x1b4c
-#define RM9000x2_OCD_INTP0STATUS5	0x1b50
-#define RM9000x2_OCD_INTP0MASK5		0x1b54
-#define RM9000x2_OCD_INTP0SET5		0x1b58
-#define RM9000x2_OCD_INTP0CLEAR5	0x1b5c
-#define RM9000x2_OCD_INTP0STATUS6	0x1b60
-#define RM9000x2_OCD_INTP0MASK6		0x1b64
-#define RM9000x2_OCD_INTP0SET6		0x1b68
-#define RM9000x2_OCD_INTP0CLEAR6	0x1b6c
-#define RM9000x2_OCD_INTP0STATUS7	0x1b70
-#define RM9000x2_OCD_INTP0MASK7		0x1b74
-#define RM9000x2_OCD_INTP0SET7		0x1b78
-#define RM9000x2_OCD_INTP0CLEAR7	0x1b7c
-#define RM9000x2_OCD_INTP1STATUS0	0x2b00
-#define RM9000x2_OCD_INTP1MASK0		0x2b04
-#define RM9000x2_OCD_INTP1SET0		0x2b08
-#define RM9000x2_OCD_INTP1CLEAR0	0x2b0c
-#define RM9000x2_OCD_INTP1STATUS1	0x2b10
-#define RM9000x2_OCD_INTP1MASK1		0x2b14
-#define RM9000x2_OCD_INTP1SET1		0x2b18
-#define RM9000x2_OCD_INTP1CLEAR1	0x2b1c
-#define RM9000x2_OCD_INTP1STATUS2	0x2b20
-#define RM9000x2_OCD_INTP1MASK2		0x2b24
-#define RM9000x2_OCD_INTP1SET2		0x2b28
-#define RM9000x2_OCD_INTP1CLEAR2	0x2b2c
-#define RM9000x2_OCD_INTP1STATUS3	0x2b30
-#define RM9000x2_OCD_INTP1MASK3		0x2b34
-#define RM9000x2_OCD_INTP1SET3		0x2b38
-#define RM9000x2_OCD_INTP1CLEAR3	0x2b3c
-#define RM9000x2_OCD_INTP1STATUS4	0x2b40
-#define RM9000x2_OCD_INTP1MASK4		0x2b44
-#define RM9000x2_OCD_INTP1SET4		0x2b48
-#define RM9000x2_OCD_INTP1CLEAR4	0x2b4c
-#define RM9000x2_OCD_INTP1STATUS5	0x2b50
-#define RM9000x2_OCD_INTP1MASK5		0x2b54
-#define RM9000x2_OCD_INTP1SET5		0x2b58
-#define RM9000x2_OCD_INTP1CLEAR5	0x2b5c
-#define RM9000x2_OCD_INTP1STATUS6	0x2b60
-#define RM9000x2_OCD_INTP1MASK6		0x2b64
-#define RM9000x2_OCD_INTP1SET6		0x2b68
-#define RM9000x2_OCD_INTP1CLEAR6	0x2b6c
-#define RM9000x2_OCD_INTP1STATUS7	0x2b70
-#define RM9000x2_OCD_INTP1MASK7		0x2b74
-#define RM9000x2_OCD_INTP1SET7		0x2b78
-#define RM9000x2_OCD_INTP1CLEAR7	0x2b7c
-
-#define OCD_READ(reg)		(*(volatile unsigned int *)(ocd_base + (reg)))
-#define OCD_WRITE(reg, val)					\
-	do { *(volatile unsigned int *)(ocd_base + (reg)) = (val); } while (0)
-
-/*
- * Hypertransport specific macros
- */
-#define RM9K_WRITE(ofs, data)   *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) = data
-#define RM9K_WRITE_8(ofs, data) *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) = data
-#define RM9K_WRITE_16(ofs, data) *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) = data
-
-#define RM9K_READ(ofs, val)     *(val) = *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs)
-#define RM9K_READ_8(ofs, val)   *(val) = *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs)
-#define RM9K_READ_16(ofs, val)  *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs)
-
-#endif
diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h
index fa133c1..65e3445 100644
--- a/arch/mips/include/asm/war.h
+++ b/arch/mips/include/asm/war.h
@@ -209,14 +209,6 @@
 #endif
 
 /*
- * On the RM9000 there is a problem which makes the CreateDirtyExclusive
- * eache operation unusable on SMP systems.
- */
-#ifndef RM9000_CDEX_SMP_WAR
-#error Check setting of RM9000_CDEX_SMP_WAR for your platform
-#endif
-
-/*
  * The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra
  * opposes it being called that) where invalid instructions in the same
  * I-cache line worth of instructions being fetched may case spurious
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 8b28bc4..007c33d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -16,7 +16,7 @@
 endif
 
 obj-$(CONFIG_CEVT_BCM1480)	+= cevt-bcm1480.o
-obj-$(CONFIG_CEVT_R4K_LIB)	+= cevt-r4k.o
+obj-$(CONFIG_CEVT_R4K)		+= cevt-r4k.o
 obj-$(CONFIG_MIPS_MT_SMTC)	+= cevt-smtc.o
 obj-$(CONFIG_CEVT_DS1287)	+= cevt-ds1287.o
 obj-$(CONFIG_CEVT_GT641XX)	+= cevt-gt641xx.o
@@ -25,7 +25,7 @@
 obj-$(CONFIG_CSRC_BCM1480)	+= csrc-bcm1480.o
 obj-$(CONFIG_CSRC_IOASIC)	+= csrc-ioasic.o
 obj-$(CONFIG_CSRC_POWERTV)	+= csrc-powertv.o
-obj-$(CONFIG_CSRC_R4K_LIB)	+= csrc-r4k.o
+obj-$(CONFIG_CSRC_R4K)		+= csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)	+= csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)		+= sync-r4k.o
 
@@ -58,7 +58,6 @@
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
 obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
-obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
 obj-$(CONFIG_MIPS_MSC)		+= irq-msc01.o
 obj-$(CONFIG_IRQ_TXX9)		+= irq_txx9.o
 obj-$(CONFIG_IRQ_GT641XX)	+= irq-gt641xx.o
@@ -80,7 +79,8 @@
 
 obj-$(CONFIG_GPIO_TXX9)		+= gpio_txx9.o
 
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 obj-$(CONFIG_SPINLOCK_TEST)	+= spinlock_test.o
 obj-$(CONFIG_MIPS_MACHINE)	+= mips_machine.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 0c4bce4..9690998 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -125,10 +125,6 @@
 	       thread.cp0_baduaddr);
 	OFFSET(THREAD_ECODE, task_struct, \
 	       thread.error_code);
-	OFFSET(THREAD_TRAMP, task_struct, \
-	       thread.irix_trampoline);
-	OFFSET(THREAD_OLDCTX, task_struct, \
-	       thread.irix_oldctx);
 	BLANK();
 }
 
diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c
new file mode 100644
index 0000000..0f53c39
--- /dev/null
+++ b/arch/mips/kernel/crash.c
@@ -0,0 +1,71 @@
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/reboot.h>
+#include <linux/kexec.h>
+#include <linux/bootmem.h>
+#include <linux/crash_dump.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+/* This keeps a track of which one is crashing cpu. */
+static int crashing_cpu = -1;
+static cpumask_t cpus_in_crash = CPU_MASK_NONE;
+
+#ifdef CONFIG_SMP
+static void crash_shutdown_secondary(void *ignore)
+{
+	struct pt_regs *regs;
+	int cpu = smp_processor_id();
+
+	regs = task_pt_regs(current);
+
+	if (!cpu_online(cpu))
+		return;
+
+	local_irq_disable();
+	if (!cpu_isset(cpu, cpus_in_crash))
+		crash_save_cpu(regs, cpu);
+	cpu_set(cpu, cpus_in_crash);
+
+	while (!atomic_read(&kexec_ready_to_reboot))
+		cpu_relax();
+	relocated_kexec_smp_wait(NULL);
+	/* NOTREACHED */
+}
+
+static void crash_kexec_prepare_cpus(void)
+{
+	unsigned int msecs;
+
+	unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
+
+	dump_send_ipi(crash_shutdown_secondary);
+	smp_wmb();
+
+	/*
+	 * The crash CPU sends an IPI and wait for other CPUs to
+	 * respond. Delay of at least 10 seconds.
+	 */
+	pr_emerg("Sending IPI to other cpus...\n");
+	msecs = 10000;
+	while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) {
+		cpu_relax();
+		mdelay(1);
+	}
+}
+
+#else /* !defined(CONFIG_SMP)  */
+static void crash_kexec_prepare_cpus(void) {}
+#endif /* !defined(CONFIG_SMP)  */
+
+void default_machine_crash_shutdown(struct pt_regs *regs)
+{
+	local_irq_disable();
+	crashing_cpu = smp_processor_id();
+	crash_save_cpu(regs, crashing_cpu);
+	crash_kexec_prepare_cpus();
+	cpu_set(crashing_cpu, cpus_in_crash);
+}
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c
new file mode 100644
index 0000000..35bed0d
--- /dev/null
+++ b/arch/mips/kernel/crash_dump.c
@@ -0,0 +1,75 @@
+#include <linux/highmem.h>
+#include <linux/bootmem.h>
+#include <linux/crash_dump.h>
+#include <asm/uaccess.h>
+
+static int __init parse_savemaxmem(char *p)
+{
+	if (p)
+		saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
+
+	return 1;
+}
+__setup("savemaxmem=", parse_savemaxmem);
+
+
+static void *kdump_buf_page;
+
+/**
+ * copy_oldmem_page - copy one page from "oldmem"
+ * @pfn: page frame number to be copied
+ * @buf: target memory address for the copy; this can be in kernel address
+ *	space or user address space (see @userbuf)
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
+ *	otherwise @buf is in kernel address space, use memcpy().
+ *
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel.
+ *
+ * Calling copy_to_user() in atomic context is not desirable. Hence first
+ * copying the data to a pre-allocated kernel page and then copying to user
+ * space in non-atomic context.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+			 size_t csize, unsigned long offset, int userbuf)
+{
+	void  *vaddr;
+
+	if (!csize)
+		return 0;
+
+	vaddr = kmap_atomic_pfn(pfn);
+
+	if (!userbuf) {
+		memcpy(buf, (vaddr + offset), csize);
+		kunmap_atomic(vaddr);
+	} else {
+		if (!kdump_buf_page) {
+			pr_warning("Kdump: Kdump buffer page not allocated\n");
+
+			return -EFAULT;
+		}
+		copy_page(kdump_buf_page, vaddr);
+		kunmap_atomic(vaddr);
+		if (copy_to_user(buf, (kdump_buf_page + offset), csize))
+			return -EFAULT;
+	}
+
+	return csize;
+}
+
+static int __init kdump_buf_page_init(void)
+{
+	int ret = 0;
+
+	kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!kdump_buf_page) {
+		pr_warning("Kdump: Failed to allocate kdump buffer page\n");
+		ret = -ENOMEM;
+	}
+
+	return ret;
+}
+arch_initcall(kdump_buf_page_init);
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
deleted file mode 100644
index 1282b9a..0000000
--- a/arch/mips/kernel/irq-rm9000.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2003 Ralf Baechle
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Handler for RM9000 extended interrupts.  These are a non-standard
- * feature so we handle them separately from standard interrupts.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-
-static inline void unmask_rm9k_irq(struct irq_data *d)
-{
-	set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
-}
-
-static inline void mask_rm9k_irq(struct irq_data *d)
-{
-	clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
-}
-
-static inline void rm9k_cpu_irq_enable(struct irq_data *d)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	unmask_rm9k_irq(d);
-	local_irq_restore(flags);
-}
-
-/*
- * Performance counter interrupts are global on all processors.
- */
-static void local_rm9k_perfcounter_irq_startup(void *args)
-{
-	rm9k_cpu_irq_enable(args);
-}
-
-static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d)
-{
-	on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1);
-
-	return 0;
-}
-
-static void local_rm9k_perfcounter_irq_shutdown(void *args)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	mask_rm9k_irq(args);
-	local_irq_restore(flags);
-}
-
-static void rm9k_perfcounter_irq_shutdown(struct irq_data *d)
-{
-	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1);
-}
-
-static struct irq_chip rm9k_irq_controller = {
-	.name = "RM9000",
-	.irq_ack = mask_rm9k_irq,
-	.irq_mask = mask_rm9k_irq,
-	.irq_mask_ack = mask_rm9k_irq,
-	.irq_unmask = unmask_rm9k_irq,
-	.irq_eoi = unmask_rm9k_irq
-};
-
-static struct irq_chip rm9k_perfcounter_irq = {
-	.name = "RM9000",
-	.irq_startup = rm9k_perfcounter_irq_startup,
-	.irq_shutdown = rm9k_perfcounter_irq_shutdown,
-	.irq_ack = mask_rm9k_irq,
-	.irq_mask = mask_rm9k_irq,
-	.irq_mask_ack = mask_rm9k_irq,
-	.irq_unmask = unmask_rm9k_irq,
-};
-
-unsigned int rm9000_perfcount_irq;
-
-EXPORT_SYMBOL(rm9000_perfcount_irq);
-
-void __init rm9k_cpu_irq_init(void)
-{
-	int base = RM9K_CPU_IRQ_BASE;
-	int i;
-
-	clear_c0_intcontrol(0x0000f000);		/* Mask all */
-
-	for (i = base; i < base + 4; i++)
-		irq_set_chip_and_handler(i, &rm9k_irq_controller,
-					 handle_level_irq);
-
-	rm9000_perfcount_irq = base + 1;
-	irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq,
-				 handle_percpu_irq);
-}
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 85beb9b..992e184 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -5,7 +5,7 @@
  * This source code is licensed under the GNU General Public License,
  * Version 2.  See the file COPYING for more details.
  */
-
+#include <linux/compiler.h>
 #include <linux/kexec.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
@@ -19,9 +19,19 @@
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
 
+int (*_machine_kexec_prepare)(struct kimage *) = NULL;
+void (*_machine_kexec_shutdown)(void) = NULL;
+void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
+#ifdef CONFIG_SMP
+void (*relocated_kexec_smp_wait) (void *);
+atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
+#endif
+
 int
 machine_kexec_prepare(struct kimage *kimage)
 {
+	if (_machine_kexec_prepare)
+		return _machine_kexec_prepare(kimage);
 	return 0;
 }
 
@@ -33,14 +43,20 @@
 void
 machine_shutdown(void)
 {
+	if (_machine_kexec_shutdown)
+		_machine_kexec_shutdown();
 }
 
 void
 machine_crash_shutdown(struct pt_regs *regs)
 {
+	if (_machine_crash_shutdown)
+		_machine_crash_shutdown(regs);
+	else
+		default_machine_crash_shutdown(regs);
 }
 
-typedef void (*noretfun_t)(void) __attribute__((noreturn));
+typedef void (*noretfun_t)(void) __noreturn;
 
 void
 machine_kexec(struct kimage *image)
@@ -52,7 +68,9 @@
 	reboot_code_buffer =
 	  (unsigned long)page_address(image->control_code_page);
 
-	kexec_start_address = image->start;
+	kexec_start_address =
+		(unsigned long) phys_to_virt(image->start);
+
 	kexec_indirection_page =
 		(unsigned long) phys_to_virt(image->head & PAGE_MASK);
 
@@ -63,7 +81,7 @@
 	 * The generic kexec code builds a page list with physical
 	 * addresses. they are directly accessible through KSEG0 (or
 	 * CKSEG0 or XPHYS if on 64bit system), hence the
-	 * pys_to_virt() call.
+	 * phys_to_virt() call.
 	 */
 	for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
 	     ptr = (entry & IND_INDIRECTION) ?
@@ -81,5 +99,12 @@
 	printk("Will call new kernel at %08lx\n", image->start);
 	printk("Bye ...\n");
 	__flush_cache_all();
+#ifdef CONFIG_SMP
+	/* All secondary cpus now may jump to kexec_wait cycle */
+	relocated_kexec_smp_wait = reboot_code_buffer +
+		(void *)(kexec_smp_wait - relocate_new_kernel);
+	smp_wmb();
+	atomic_set(&kexec_ready_to_reboot, 1);
+#endif
 	((noretfun_t) reboot_code_buffer)();
 }
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index 33f63ba..fd814e0 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -50,8 +50,8 @@
 
 	rcu_read_lock();
 	pcred = __task_cred(p);
-	match = (cred->euid == pcred->euid ||
-		 cred->euid == pcred->uid);
+	match = (uid_eq(cred->euid, pcred->euid) ||
+		 uid_eq(cred->euid, pcred->uid));
 	rcu_read_unlock();
 	return match;
 }
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 2d9304c..df1e3e4 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -11,7 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/export.h>
 #include <asm/checksum.h>
-#include <asm/pgtable.h>
+#include <linux/mm.h>
 #include <asm/uaccess.h>
 #include <asm/ftrace.h>
 
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index a9b995d..b14c14d 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -840,6 +840,16 @@
 	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
 };
 
+static const struct mips_perf_event xlp_event_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL },
+	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x18, CNTR_ALL }, /* PAPI_TOT_INS */
+	[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */
+	[PERF_COUNT_HW_CACHE_MISSES] = { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x1b, CNTR_ALL }, /* PAPI_BR_CN */
+	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x1c, CNTR_ALL }, /* PAPI_BR_MSP */
+	[PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
 /* 24K/34K/1004K cores can share the same cache event map. */
 static const struct mips_perf_event mipsxxcore_cache_map
 				[PERF_COUNT_HW_CACHE_MAX]
@@ -1092,6 +1102,100 @@
 },
 };
 
+static const struct mips_perf_event xlp_cache_map
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x31, CNTR_ALL }, /* PAPI_L1_DCR */
+		[C(RESULT_MISS)]	= { 0x30, CNTR_ALL }, /* PAPI_L1_LDM */
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { 0x2f, CNTR_ALL }, /* PAPI_L1_DCW */
+		[C(RESULT_MISS)]	= { 0x2e, CNTR_ALL }, /* PAPI_L1_STM */
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(L1I)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */
+		[C(RESULT_MISS)]	= { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(LL)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x35, CNTR_ALL }, /* PAPI_L2_DCR */
+		[C(RESULT_MISS)]	= { 0x37, CNTR_ALL }, /* PAPI_L2_LDM */
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { 0x34, CNTR_ALL }, /* PAPI_L2_DCA */
+		[C(RESULT_MISS)]	= { 0x36, CNTR_ALL }, /* PAPI_L2_DCM */
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(DTLB)] = {
+	/*
+	 * Only general DTLB misses are counted use the same event for
+	 * read and write.
+	 */
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(ITLB)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+[C(BPU)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { 0x25, CNTR_ALL },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+	[C(OP_PREFETCH)] = {
+		[C(RESULT_ACCESS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+		[C(RESULT_MISS)]	= { UNSUPPORTED_PERF_EVENT_ID },
+	},
+},
+};
+
 #ifdef CONFIG_MIPS_MT_SMP
 static void check_and_calc_range(struct perf_event *event,
 				 const struct mips_perf_event *pev)
@@ -1444,6 +1548,20 @@
 	return &raw_event;
 }
 
+static const struct mips_perf_event *xlp_pmu_map_raw_event(u64 config)
+{
+	unsigned int raw_id = config & 0xff;
+
+	/* Only 1-63 are defined */
+	if ((raw_id < 0x01) || (raw_id > 0x3f))
+		return ERR_PTR(-EOPNOTSUPP);
+
+	raw_event.cntr_mask = CNTR_ALL;
+	raw_event.event_id = raw_id;
+
+	return &raw_event;
+}
+
 static int __init
 init_hw_perf_events(void)
 {
@@ -1522,6 +1640,12 @@
 		mipspmu.general_event_map = &bmips5000_event_map;
 		mipspmu.cache_event_map = &bmips5000_cache_map;
 		break;
+	case CPU_XLP:
+		mipspmu.name = "xlp";
+		mipspmu.general_event_map = &xlp_event_map;
+		mipspmu.cache_event_map = &xlp_cache_map;
+		mipspmu.map_raw_event = xlp_pmu_map_raw_event;
+		break;
 	default:
 		pr_cont("Either hardware does not support performance "
 			"counters, or not yet implemented.\n");
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 38097652..a11c6f9 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -72,9 +72,7 @@
 			}
 		}
 #ifdef CONFIG_HOTPLUG_CPU
-		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
-		    (system_state == SYSTEM_RUNNING ||
-		     system_state == SYSTEM_BOOTING))
+		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map))
 			play_dead();
 #endif
 		rcu_idle_exit();
diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
index 87481f9..e4142c5 100644
--- a/arch/mips/kernel/relocate_kernel.S
+++ b/arch/mips/kernel/relocate_kernel.S
@@ -15,6 +15,11 @@
 #include <asm/addrspace.h>
 
 LEAF(relocate_new_kernel)
+	PTR_L a0,	arg0
+	PTR_L a1,	arg1
+	PTR_L a2,	arg2
+	PTR_L a3,	arg3
+
 	PTR_L		s0, kexec_indirection_page
 	PTR_L		s1, kexec_start_address
 
@@ -26,7 +31,6 @@
 	and		s3, s2, 0x1
 	beq		s3, zero, 1f
 	and		s4, s2, ~0x1	/* store destination addr in s4 */
-	move		a0, s4
 	b		process_entry
 
 1:
@@ -60,10 +64,111 @@
 	b		process_entry
 
 done:
+#ifdef CONFIG_SMP
+	/* kexec_flag reset is signal to other CPUs what kernel
+	   was moved to it's location. Note - we need relocated address
+	   of kexec_flag.  */
+
+	bal		1f
+ 1: 	move		t1,ra;
+	PTR_LA		t2,1b
+	PTR_LA		t0,kexec_flag
+	PTR_SUB		t0,t0,t2;
+	PTR_ADD		t0,t1,t0;
+	LONG_S		zero,(t0)
+#endif
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+	/* We need to flush I-cache before jumping to new kernel.
+	 * Unfortunatelly, this code is cpu-specific.
+	 */
+	.set push
+	.set noreorder
+	syncw
+	syncw
+	synci		0($0)
+	.set pop
+#else
+	sync
+#endif
 	/* jump to kexec_start_address */
 	j		s1
 	END(relocate_new_kernel)
 
+#ifdef CONFIG_SMP
+/*
+ * Other CPUs should wait until code is relocated and
+ * then start at entry (?) point.
+ */
+LEAF(kexec_smp_wait)
+	PTR_L		a0, s_arg0
+	PTR_L		a1, s_arg1
+	PTR_L		a2, s_arg2
+	PTR_L		a3, s_arg3
+	PTR_L		s1, kexec_start_address
+
+	/* Non-relocated address works for args and kexec_start_address ( old
+	 * kernel is not overwritten). But we need relocated address of
+	 * kexec_flag.
+	 */
+
+	bal		1f
+1:	move		t1,ra;
+	PTR_LA		t2,1b
+	PTR_LA		t0,kexec_flag
+	PTR_SUB		t0,t0,t2;
+	PTR_ADD		t0,t1,t0;
+
+1:	LONG_L		s0, (t0)
+	bne		s0, zero,1b
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+	.set push
+	.set noreorder
+	synci		0($0)
+	.set pop
+#else
+	sync
+#endif
+	j		s1
+	END(kexec_smp_wait)
+#endif
+
+#ifdef __mips64
+       /* all PTR's must be aligned to 8 byte in 64-bit mode */
+       .align  3
+#endif
+
+/* All parameters to new kernel are passed in registers a0-a3.
+ * kexec_args[0..3] are uses to prepare register values.
+ */
+
+kexec_args:
+	EXPORT(kexec_args)
+arg0:	PTR		0x0
+arg1:	PTR		0x0
+arg2:	PTR		0x0
+arg3:	PTR		0x0
+	.size	kexec_args,PTRSIZE*4
+
+#ifdef CONFIG_SMP
+/*
+ * Secondary CPUs may have different kernel parameters in
+ * their registers a0-a3. secondary_kexec_args[0..3] are used
+ * to prepare register values.
+ */
+secondary_kexec_args:
+	EXPORT(secondary_kexec_args)
+s_arg0:	PTR		0x0
+s_arg1:	PTR		0x0
+s_arg2:	PTR		0x0
+s_arg3:	PTR		0x0
+	.size	secondary_kexec_args,PTRSIZE*4
+kexec_flag:
+	LONG		0x1
+
+#endif
+
 kexec_start_address:
 	EXPORT(kexec_start_address)
 	PTR		0x0
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 6297191..ad3de96 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -17,12 +17,6 @@
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002	/* tracing system calls */
-
-/* This duplicates the definition from <asm/signal.h> */
-#define SIGILL		4		/* Illegal instruction (ANSI).  */
-
 #ifndef CONFIG_MIPS32_O32
 /* No O32, so define handle_sys here */
 #define handle_sysn32 handle_sys
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 290dc6a..8c41187 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -22,6 +22,7 @@
 #include <linux/console.h>
 #include <linux/pfn.h>
 #include <linux/debugfs.h>
+#include <linux/kexec.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -536,12 +537,64 @@
 	}
 
 	bootmem_init();
+#ifdef CONFIG_KEXEC
+	if (crashk_res.start != crashk_res.end)
+		reserve_bootmem(crashk_res.start,
+				crashk_res.end - crashk_res.start + 1,
+				BOOTMEM_DEFAULT);
+#endif
 	device_tree_init();
 	sparse_init();
 	plat_swiotlb_setup();
 	paging_init();
 }
 
+#ifdef CONFIG_KEXEC
+static inline unsigned long long get_total_mem(void)
+{
+	unsigned long long total;
+
+	total = max_pfn - min_low_pfn;
+	return total << PAGE_SHIFT;
+}
+
+static void __init mips_parse_crashkernel(void)
+{
+	unsigned long long total_mem;
+	unsigned long long crash_size, crash_base;
+	int ret;
+
+	total_mem = get_total_mem();
+	ret = parse_crashkernel(boot_command_line, total_mem,
+				&crash_size, &crash_base);
+	if (ret != 0 || crash_size <= 0)
+		return;
+
+	crashk_res.start = crash_base;
+	crashk_res.end   = crash_base + crash_size - 1;
+}
+
+static void __init request_crashkernel(struct resource *res)
+{
+	int ret;
+
+	ret = request_resource(res, &crashk_res);
+	if (!ret)
+		pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
+			(unsigned long)((crashk_res.end -
+				crashk_res.start + 1) >> 20),
+			(unsigned long)(crashk_res.start  >> 20));
+}
+#else /* !defined(CONFIG_KEXEC)  */
+static void __init mips_parse_crashkernel(void)
+{
+}
+
+static void __init request_crashkernel(struct resource *res)
+{
+}
+#endif /* !defined(CONFIG_KEXEC)  */
+
 static void __init resource_init(void)
 {
 	int i;
@@ -557,6 +610,8 @@
 	/*
 	 * Request address space for all standard RAM.
 	 */
+	mips_parse_crashkernel();
+
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
 		struct resource *res;
 		unsigned long start, end;
@@ -593,6 +648,7 @@
 		 */
 		request_resource(res, &code_resource);
 		request_resource(res, &data_resource);
+		request_crashkernel(res);
 	}
 }
 
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 0e1a5b8..b6aa770 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -568,17 +568,20 @@
 	}
 
 	if (regs->regs[0]) {
-		if (regs->regs[2] == ERESTARTNOHAND ||
-		    regs->regs[2] == ERESTARTSYS ||
-		    regs->regs[2] == ERESTARTNOINTR) {
+		switch (regs->regs[2]) {
+		case ERESTARTNOHAND:
+		case ERESTARTSYS:
+		case ERESTARTNOINTR:
 			regs->regs[2] = regs->regs[0];
 			regs->regs[7] = regs->regs[26];
 			regs->cp0_epc -= 4;
-		}
-		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
+			break;
+
+		case ERESTART_RESTARTBLOCK:
 			regs->regs[2] = current->thread.abi->restart;
 			regs->regs[7] = regs->regs[26];
 			regs->cp0_epc -= 4;
+			break;
 		}
 		regs->regs[0] = 0;	/* Don't deal with this again.  */
 	}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 9005bf9..2e6374a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -386,3 +386,20 @@
 
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(flush_tlb_one);
+
+#if defined(CONFIG_KEXEC)
+void (*dump_ipi_function_ptr)(void *) = NULL;
+void dump_send_ipi(void (*dump_ipi_callback)(void *))
+{
+	int i;
+	int cpu = smp_processor_id();
+
+	dump_ipi_function_ptr = dump_ipi_callback;
+	smp_mb();
+	for_each_online_cpu(i)
+		if (i != cpu)
+			mp_ops->send_ipi_single(i, SMP_DUMP);
+
+}
+EXPORT_SYMBOL(dump_send_ipi);
+#endif
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 9be3df1..cf7ac54 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -13,6 +13,7 @@
  */
 #include <linux/bug.h>
 #include <linux/compiler.h>
+#include <linux/kexec.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -409,6 +410,9 @@
 		panic("Fatal exception");
 	}
 
+	if (regs && kexec_should_crash(current))
+		crash_kexec(regs);
+
 	do_exit(sig);
 }
 
@@ -1021,6 +1025,24 @@
 
 		return;
 
+	case 3:
+		/*
+		 * Old (MIPS I and MIPS II) processors will set this code
+		 * for COP1X opcode instructions that replaced the original
+		 * COP3 space.  We don't limit COP1 space instructions in
+		 * the emulator according to the CPU ISA, so we want to
+		 * treat COP1X instructions consistently regardless of which
+		 * code the CPU chose.  Therefore we redirect this trap to
+		 * the FP emulator too.
+		 *
+		 * Then some newer FPU-less processors use this code
+		 * erroneously too, so they are covered by this choice
+		 * as well.
+		 */
+		if (raw_cpu_has_fpu)
+			break;
+		/* Fall through.  */
+
 	case 1:
 		if (used_math())	/* Using the FPU again.  */
 			own_fpu(1);
@@ -1044,9 +1066,6 @@
 	case 2:
 		raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
 		return;
-
-	case 3:
-		break;
 	}
 
 	force_sig(SIGILL, current);
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index d84f361..c002191 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -36,4 +36,8 @@
 	bool "PCI Support"
 	depends on SOC_XWAY && PCI
 
+config XRX200_PHY_FW
+	bool "XRX200 PHY firmware loader"
+	depends on SOC_XWAY
+
 endif
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 6cfd611..9f9e875 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -87,9 +87,6 @@
 	reserve_bootmem(base, size, BOOTMEM_DEFAULT);
 
 	unflatten_device_tree();
-
-	/* free the space reserved for the dt blob */
-	free_bootmem(base, size);
 }
 
 void __init prom_init(void)
@@ -119,7 +116,7 @@
 		sizeof(of_ids[0].compatible));
 	strncpy(of_ids[1].compatible, "simple-bus",
 		sizeof(of_ids[1].compatible));
-	return of_platform_bus_probe(NULL, of_ids, NULL);
+	return of_platform_populate(NULL, of_ids, NULL, NULL);
 }
 
 arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 70a58c7..7a13660 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1 +1,3 @@
 obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
+
+obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
index 55d2c4f..6453962 100644
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -25,6 +25,7 @@
 #include <lantiq_soc.h>
 #include <xway_dma.h>
 
+#define LTQ_DMA_ID		0x08
 #define LTQ_DMA_CTRL		0x10
 #define LTQ_DMA_CPOLL		0x14
 #define LTQ_DMA_CS		0x18
@@ -48,7 +49,7 @@
 #define DMA_CLK_DIV4		BIT(6)		/* polling clock divider */
 #define DMA_2W_BURST		BIT(1)		/* 2 word burst length */
 #define DMA_MAX_CHANNEL		20		/* the soc has 20 channels */
-#define DMA_ETOP_ENDIANESS	(0xf << 8) /* endianess swap etop channels */
+#define DMA_ETOP_ENDIANNESS	(0xf << 8) /* endianness swap etop channels */
 #define DMA_WEIGHT	(BIT(17) | BIT(16))	/* default channel wheight */
 
 #define ltq_dma_r32(x)			ltq_r32(ltq_dma_membase + (x))
@@ -191,10 +192,10 @@
 	switch (p) {
 	case DMA_PORT_ETOP:
 		/*
-		 * Tell the DMA engine to swap the endianess of data frames and
+		 * Tell the DMA engine to swap the endianness of data frames and
 		 * drop packets if the channel arbitration fails.
 		 */
-		ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN,
+		ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN,
 			LTQ_DMA_PCTRL);
 		break;
 
@@ -214,6 +215,7 @@
 {
 	struct clk *clk;
 	struct resource *res;
+	unsigned id;
 	int i;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -243,7 +245,12 @@
 		ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
 		ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
 	}
-	dev_info(&pdev->dev, "init done\n");
+
+	id = ltq_dma_r32(LTQ_DMA_ID);
+	dev_info(&pdev->dev,
+		"Init done - hw rev: %X, ports: %d, channels: %d\n",
+		id & 0x1f, (id >> 16) & 0xf, id >> 20);
+
 	return 0;
 }
 
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 22c55f7..544dbb7 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -28,17 +28,24 @@
 #define RCU_RST_REQ		0x0010
 /* reset status register */
 #define RCU_RST_STAT		0x0014
+/* vr9 gphy registers */
+#define RCU_GFS_ADD0_XRX200	0x0020
+#define RCU_GFS_ADD1_XRX200	0x0068
 
 /* reboot bit */
+#define RCU_RD_GPHY0_XRX200	BIT(31)
 #define RCU_RD_SRST		BIT(30)
+#define RCU_RD_GPHY1_XRX200	BIT(29)
+
 /* reset cause */
 #define RCU_STAT_SHIFT		26
 /* boot selection */
-#define RCU_BOOT_SEL_SHIFT	26
-#define RCU_BOOT_SEL_MASK	0x7
+#define RCU_BOOT_SEL(x)		((x >> 18) & 0x7)
+#define RCU_BOOT_SEL_XRX200(x)	(((x >> 17) & 0xf) | ((x >> 8) & 0x10))
 
 /* remapped base addr of the reset control unit */
 static void __iomem *ltq_rcu_membase;
+static struct device_node *ltq_rcu_np;
 
 /* This function is used by the watchdog driver */
 int ltq_reset_cause(void)
@@ -52,7 +59,41 @@
 unsigned char ltq_boot_select(void)
 {
 	u32 val = ltq_rcu_r32(RCU_RST_STAT);
-	return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
+
+	if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
+		return RCU_BOOT_SEL_XRX200(val);
+
+	return RCU_BOOT_SEL(val);
+}
+
+/* reset / boot a gphy */
+static struct ltq_xrx200_gphy_reset {
+	u32 rd;
+	u32 addr;
+} xrx200_gphy[] = {
+	{RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
+	{RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
+};
+
+/* reset and boot a gphy. these phys only exist on xrx200 SoC */
+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
+{
+	if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) {
+		dev_err(dev, "this SoC has no GPHY\n");
+		return -EINVAL;
+	}
+	if (id > 1) {
+		dev_err(dev, "%u is an invalid gphy id\n", id);
+		return -EINVAL;
+	}
+	dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
+
+	ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd,
+			RCU_RST_REQ);
+	ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
+	ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd,
+			RCU_RST_REQ);
+	return 0;
 }
 
 /* reset a io domain for u micro seconds */
@@ -85,14 +126,17 @@
 static int __init mips_reboot_setup(void)
 {
 	struct resource res;
-	struct device_node *np =
-		of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
+
+	ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
+	if (!ltq_rcu_np)
+		ltq_rcu_np = of_find_compatible_node(NULL, NULL,
+							"lantiq,rcu-xrx200");
 
 	/* check if all the reset register range is available */
-	if (!np)
+	if (!ltq_rcu_np)
 		panic("Failed to load reset resources from devicetree");
 
-	if (of_address_to_resource(np, 0, &res))
+	if (of_address_to_resource(ltq_rcu_np, 0, &res))
 		panic("Failed to get rcu memory range");
 
 	if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 2917b56..3925e66 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -370,6 +370,10 @@
 		clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
 		clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
 		clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
+		clkdev_add_pmu("1e108000.eth", NULL, 0,
+				PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
+				PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+				PMU_PPE_QSB | PMU_PPE_TOP);
 	} else if (of_machine_is_compatible("lantiq,ar9")) {
 		clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
 				ltq_ar9_fpi_hz());
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c
new file mode 100644
index 0000000..fe808bf5
--- /dev/null
+++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c
@@ -0,0 +1,97 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/of_platform.h>
+
+#include <lantiq_soc.h>
+
+#define XRX200_GPHY_FW_ALIGN	(16 * 1024)
+
+static dma_addr_t xway_gphy_load(struct platform_device *pdev)
+{
+	const struct firmware *fw;
+	dma_addr_t dev_addr = 0;
+	const char *fw_name;
+	void *fw_addr;
+	size_t size;
+
+	if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) {
+		dev_err(&pdev->dev, "failed to load firmware filename\n");
+		return 0;
+	}
+
+	dev_info(&pdev->dev, "requesting %s\n", fw_name);
+	if (request_firmware(&fw, fw_name, &pdev->dev)) {
+		dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name);
+		return 0;
+	}
+
+	/*
+	 * GPHY cores need the firmware code in a persistent and contiguous
+	 * memory area with a 16 kB boundary aligned start address
+	 */
+	size = fw->size + XRX200_GPHY_FW_ALIGN;
+
+	fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL);
+	if (fw_addr) {
+		fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
+		dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN);
+		memcpy(fw_addr, fw->data, fw->size);
+	} else {
+		dev_err(&pdev->dev, "failed to alloc firmware memory\n");
+	}
+
+	release_firmware(fw);
+	return dev_addr;
+}
+
+static int __devinit xway_phy_fw_probe(struct platform_device *pdev)
+{
+	dma_addr_t fw_addr;
+	struct property *pp;
+	unsigned char *phyids;
+	int i, ret = 0;
+
+	fw_addr = xway_gphy_load(pdev);
+	if (!fw_addr)
+		return -EINVAL;
+	pp = of_find_property(pdev->dev.of_node, "phys", NULL);
+	if (!pp)
+		return -ENOENT;
+	phyids = pp->value;
+	for (i = 0; i < pp->length && !ret; i++)
+		ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr);
+	if (!ret)
+		mdelay(100);
+	return ret;
+}
+
+static const struct of_device_id xway_phy_match[] = {
+	{ .compatible = "lantiq,phy-xrx200" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, xway_phy_match);
+
+static struct platform_driver xway_phy_driver = {
+	.probe = xway_phy_fw_probe,
+	.driver = {
+		.name = "phy-xrx200",
+		.owner = THIS_MODULE,
+		.of_match_table = xway_phy_match,
+	},
+};
+
+module_platform_driver(xway_phy_driver);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig
index a9a14d6..fbf75f6 100644
--- a/arch/mips/loongson1/Kconfig
+++ b/arch/mips/loongson1/Kconfig
@@ -15,7 +15,7 @@
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
 	select SYS_HAS_EARLY_PRINTK
-	select HAVE_CLK
+	select COMMON_CLK
 
 endchoice
 
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c
index 1bbbbec..07133de 100644
--- a/arch/mips/loongson1/common/clock.c
+++ b/arch/mips/loongson1/common/clock.c
@@ -7,175 +7,22 @@
  * option) any later version.
  */
 
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <asm/clock.h>
 #include <asm/time.h>
-
-#include <loongson1.h>
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-struct clk *clk_get(struct device *dev, const char *name)
-{
-	struct clk *c;
-	struct clk *ret = NULL;
-
-	mutex_lock(&clocks_mutex);
-	list_for_each_entry(c, &clocks, node) {
-		if (!strcmp(c->name, name)) {
-			ret = c;
-			break;
-		}
-	}
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_get);
-
-int clk_enable(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
-static void pll_clk_init(struct clk *clk)
-{
-	u32 pll;
-
-	pll = __raw_readl(LS1X_CLK_PLL_FREQ);
-	clk->rate = (12 + (pll & 0x3f)) * 33 / 2
-			+ ((pll >> 8) & 0x3ff) * 33 / 1024 / 2;
-	clk->rate *= 1000000;
-}
-
-static void cpu_clk_init(struct clk *clk)
-{
-	u32 pll, ctrl;
-
-	pll = clk_get_rate(clk->parent);
-	ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_CPU;
-	clk->rate = pll / (ctrl >> DIV_CPU_SHIFT);
-}
-
-static void ddr_clk_init(struct clk *clk)
-{
-	u32 pll, ctrl;
-
-	pll = clk_get_rate(clk->parent);
-	ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DDR;
-	clk->rate = pll / (ctrl >> DIV_DDR_SHIFT);
-}
-
-static void dc_clk_init(struct clk *clk)
-{
-	u32 pll, ctrl;
-
-	pll = clk_get_rate(clk->parent);
-	ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DC;
-	clk->rate = pll / (ctrl >> DIV_DC_SHIFT);
-}
-
-static struct clk_ops pll_clk_ops = {
-	.init	= pll_clk_init,
-};
-
-static struct clk_ops cpu_clk_ops = {
-	.init	= cpu_clk_init,
-};
-
-static struct clk_ops ddr_clk_ops = {
-	.init	= ddr_clk_init,
-};
-
-static struct clk_ops dc_clk_ops = {
-	.init	= dc_clk_init,
-};
-
-static struct clk pll_clk = {
-	.name	= "pll",
-	.ops	= &pll_clk_ops,
-};
-
-static struct clk cpu_clk = {
-	.name	= "cpu",
-	.parent = &pll_clk,
-	.ops	= &cpu_clk_ops,
-};
-
-static struct clk ddr_clk = {
-	.name	= "ddr",
-	.parent = &pll_clk,
-	.ops	= &ddr_clk_ops,
-};
-
-static struct clk dc_clk = {
-	.name	= "dc",
-	.parent = &pll_clk,
-	.ops	= &dc_clk_ops,
-};
-
-int clk_register(struct clk *clk)
-{
-	mutex_lock(&clocks_mutex);
-	list_add(&clk->node, &clocks);
-	if (clk->ops->init)
-		clk->ops->init(clk);
-	mutex_unlock(&clocks_mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-static struct clk *ls1x_clks[] = {
-	&pll_clk,
-	&cpu_clk,
-	&ddr_clk,
-	&dc_clk,
-};
-
-int __init ls1x_clock_init(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++)
-		clk_register(ls1x_clks[i]);
-
-	return 0;
-}
+#include <platform.h>
 
 void __init plat_time_init(void)
 {
 	struct clk *clk;
 
 	/* Initialize LS1X clocks */
-	ls1x_clock_init();
+	ls1x_clk_init();
 
 	/* setup mips r4k timer */
 	clk = clk_get(NULL, "cpu");
 	if (IS_ERR(clk))
-		panic("unable to get dc clock, err=%ld", PTR_ERR(clk));
+		panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));
 
 	mips_hpt_frequency = clk_get_rate(clk) / 2;
 }
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c
index 0412ad6..69dad4c 100644
--- a/arch/mips/loongson1/common/platform.c
+++ b/arch/mips/loongson1/common/platform.c
@@ -43,16 +43,17 @@
 	},
 };
 
-void __init ls1x_serial_setup(void)
+void __init ls1x_serial_setup(struct platform_device *pdev)
 {
 	struct clk *clk;
 	struct plat_serial8250_port *p;
 
-	clk = clk_get(NULL, "dc");
+	clk = clk_get(NULL, pdev->name);
 	if (IS_ERR(clk))
-		panic("unable to get dc clock, err=%ld", PTR_ERR(clk));
+		panic("unable to get %s clock, err=%ld",
+			pdev->name, PTR_ERR(clk));
 
-	for (p = ls1x_serial8250_port; p->flags != 0; ++p)
+	for (p = pdev->dev.platform_data; p->flags != 0; ++p)
 		p->uartclk = clk_get_rate(clk);
 }
 
@@ -71,7 +72,6 @@
 };
 
 static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
-	.bus_id		= 0,
 	.phy_mask	= 0,
 };
 
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c
index 295b1be..1fbd526 100644
--- a/arch/mips/loongson1/ls1b/board.c
+++ b/arch/mips/loongson1/ls1b/board.c
@@ -9,9 +9,6 @@
 
 #include <platform.h>
 
-#include <linux/serial_8250.h>
-#include <loongson1.h>
-
 static struct platform_device *ls1b_platform_devices[] __initdata = {
 	&ls1x_uart_device,
 	&ls1x_eth0_device,
@@ -23,7 +20,7 @@
 {
 	int err;
 
-	ls1x_serial_setup();
+	ls1x_serial_setup(&ls1x_uart_device);
 
 	err = platform_add_devices(ls1b_platform_devices,
 				   ARRAY_SIZE(ls1b_platform_devices));
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index a03bf00..47c77e7 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -171,16 +171,17 @@
  * In the Linux kernel, we support selection of FPR format on the
  * basis of the Status.FR bit.  If an FPU is not present, the FR bit
  * is hardwired to zero, which would imply a 32-bit FPU even for
- * 64-bit CPUs.  For 64-bit kernels with no FPU we use TIF_32BIT_REGS
- * as a proxy for the FR bit so that a 64-bit FPU is emulated.  In any
- * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
- * even FPRs are used (Status.FR = 0).
+ * 64-bit CPUs so we rather look at TIF_32BIT_REGS.
+ * FPU emu is slow and bulky and optimizing this function offers fairly
+ * sizeable benefits so we try to be clever and make this function return
+ * a constant whenever possible, that is on 64-bit kernels without O32
+ * compatibility enabled and on 32-bit kernels.
  */
 static inline int cop1_64bit(struct pt_regs *xcp)
 {
-	if (cpu_has_fpu)
-		return xcp->cp0_status & ST0_FR;
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32)
+	return 1;
+#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32)
 	return !test_thread_flag(TIF_32BIT_REGS);
 #else
 	return 0;
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
index 44e69e7..6ec04da 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2005-2007 Cavium Networks
  */
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -28,6 +29,7 @@
 #include <asm/octeon/octeon.h>
 
 unsigned long long cache_err_dcache[NR_CPUS];
+EXPORT_SYMBOL_GPL(cache_err_dcache);
 
 /**
  * Octeon automatically flushes the dcache on tlb changes, so
@@ -284,39 +286,59 @@
 	board_cache_error_setup = octeon_cache_error_setup;
 }
 
-/**
+/*
  * Handle a cache error exception
  */
+static RAW_NOTIFIER_HEAD(co_cache_error_chain);
 
-static void  cache_parity_error_octeon(int non_recoverable)
+int register_co_cache_error_notifier(struct notifier_block *nb)
 {
-	unsigned long coreid = cvmx_get_core_num();
-	uint64_t icache_err = read_octeon_c0_icacheerr();
+	return raw_notifier_chain_register(&co_cache_error_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_co_cache_error_notifier);
 
-	pr_err("Cache error exception:\n");
-	pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
-	if (icache_err & 1) {
-		pr_err("CacheErr (Icache) == %llx\n",
-		       (unsigned long long)icache_err);
-		write_octeon_c0_icacheerr(0);
-	}
-	if (cache_err_dcache[coreid] & 1) {
-		pr_err("CacheErr (Dcache) == %llx\n",
-		       (unsigned long long)cache_err_dcache[coreid]);
-		cache_err_dcache[coreid] = 0;
-	}
+int unregister_co_cache_error_notifier(struct notifier_block *nb)
+{
+	return raw_notifier_chain_unregister(&co_cache_error_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier);
 
-	if (non_recoverable)
-		panic("Can't handle cache error: nested exception");
+static void co_cache_error_call_notifiers(unsigned long val)
+{
+	int rv = raw_notifier_call_chain(&co_cache_error_chain, val, NULL);
+	if ((rv & ~NOTIFY_STOP_MASK) != NOTIFY_OK) {
+		u64 dcache_err;
+		unsigned long coreid = cvmx_get_core_num();
+		u64 icache_err = read_octeon_c0_icacheerr();
+
+		if (val) {
+			dcache_err = cache_err_dcache[coreid];
+			cache_err_dcache[coreid] = 0;
+		} else {
+			dcache_err = read_octeon_c0_dcacheerr();
+		}
+
+		pr_err("Core%lu: Cache error exception:\n", coreid);
+		pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
+		if (icache_err & 1) {
+			pr_err("CacheErr (Icache) == %llx\n",
+			       (unsigned long long)icache_err);
+			write_octeon_c0_icacheerr(0);
+		}
+		if (dcache_err & 1) {
+			pr_err("CacheErr (Dcache) == %llx\n",
+			       (unsigned long long)dcache_err);
+		}
+	}
 }
 
-/**
+/*
  * Called when the the exception is recoverable
  */
 
 asmlinkage void cache_parity_error_octeon_recoverable(void)
 {
-	cache_parity_error_octeon(0);
+	co_cache_error_call_notifiers(0);
 }
 
 /**
@@ -325,5 +347,6 @@
 
 asmlinkage void cache_parity_error_octeon_non_recoverable(void)
 {
-	cache_parity_error_octeon(1);
+	co_cache_error_call_notifiers(1);
+	panic("Can't handle cache error: nested exception");
 }
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 4c32ede..0f7d788 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -632,9 +632,6 @@
 		if (size >= scache_size)
 			r4k_blast_scache();
 		else {
-			unsigned long lsize = cpu_scache_line_size();
-			unsigned long almask = ~(lsize - 1);
-
 			/*
 			 * There is no clearly documented alignment requirement
 			 * for the cache instruction on MIPS processors and
@@ -643,9 +640,6 @@
 			 * hit ops with insufficient alignment.  Solved by
 			 * aligning the address to cache line size.
 			 */
-			cache_op(Hit_Writeback_Inv_SD, addr & almask);
-			cache_op(Hit_Writeback_Inv_SD,
-				 (addr + size - 1) & almask);
 			blast_inv_scache_range(addr, addr + size);
 		}
 		__sync();
@@ -655,12 +649,7 @@
 	if (cpu_has_safe_index_cacheops && size >= dcache_size) {
 		r4k_blast_dcache();
 	} else {
-		unsigned long lsize = cpu_dcache_line_size();
-		unsigned long almask = ~(lsize - 1);
-
 		R4600_HIT_CACHEOP_WAR_IMPL;
-		cache_op(Hit_Writeback_Inv_D, addr & almask);
-		cache_op(Hit_Writeback_Inv_D, (addr + size - 1)  & almask);
 		blast_inv_dcache_range(addr, addr + size);
 	}
 
@@ -947,7 +936,6 @@
 	case CPU_RM7000:
 		rm7k_erratum31();
 
-	case CPU_RM9000:
 		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
 		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
 		c->icache.ways = 4;
@@ -958,9 +946,7 @@
 		c->dcache.ways = 4;
 		c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
 
-#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
 		c->options |= MIPS_CPU_CACHE_CDEX_P;
-#endif
 		c->options |= MIPS_CPU_PREFETCH;
 		break;
 
@@ -1245,7 +1231,6 @@
                 return;
 
 	case CPU_RM7000:
-	case CPU_RM9000:
 #ifdef CONFIG_RM7000_CPU_SCACHE
 		rm7k_sc_init();
 #endif
@@ -1348,10 +1333,10 @@
 {
 	get_option(&str, &cca);
 
-	return 1;
+	return 0;
 }
 
-__setup("cca=", cca_setup);
+early_param("cca", cca_setup);
 
 static void __cpuinit coherency_setup(void)
 {
@@ -1401,10 +1386,10 @@
 {
 	coherentio = 1;
 
-	return 1;
+	return 0;
 }
 
-__setup("coherentio", setcoherentio);
+early_param("coherentio", setcoherentio);
 #endif
 
 static void __cpuinit r4k_cache_error_setup(void)
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index aff5705..da815d2 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -1,3 +1,4 @@
+#include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/highmem.h>
 #include <linux/sched.h>
@@ -67,7 +68,7 @@
 void __kunmap_atomic(void *kvaddr)
 {
 	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
-	int type;
+	int type __maybe_unused;
 
 	if (vaddr < FIXADDR_START) { // FIXME
 		pagefault_enable();
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
index 98f530e..8e666c5 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -140,15 +140,6 @@
 			pref_bias_copy_load = 256;
 			break;
 
-		case CPU_RM9000:
-			/*
-			 * As a workaround for erratum G105 which make the
-			 * PrepareForStore hint unusable we fall back to
-			 * StoreRetained on the RM9000.  Once it is known which
-			 * versions of the RM9000 we'll be able to condition-
-			 * alize this.
-			 */
-
 		case CPU_R10000:
 		case CPU_R12000:
 		case CPU_R14000:
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index 2540779..ee331bb 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -11,6 +11,7 @@
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
 
 void pgd_init(unsigned long page)
 {
@@ -61,6 +62,36 @@
 }
 #endif
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+void pmdp_splitting_flush(struct vm_area_struct *vma,
+			 unsigned long address,
+			 pmd_t *pmdp)
+{
+	if (!pmd_trans_splitting(*pmdp)) {
+		pmd_t pmd = pmd_mksplitting(*pmdp);
+		set_pmd_at(vma->vm_mm, address, pmdp, pmd);
+	}
+}
+
+#endif
+
+pmd_t mk_pmd(struct page *page, pgprot_t prot)
+{
+	pmd_t pmd;
+
+	pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot);
+
+	return pmd;
+}
+
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		pmd_t *pmdp, pmd_t pmd)
+{
+	*pmdp = pmd;
+	flush_tlb_all();
+}
+
 void __init pagetable_init(void)
 {
 	unsigned long vaddr;
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 88e79ad..2a7c972 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -295,7 +295,7 @@
 	pudp = pud_offset(pgdp, address);
 	pmdp = pmd_offset(pudp, address);
 	idx = read_c0_index();
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/* this could be a huge page  */
 	if (pmd_huge(*pmdp)) {
 		unsigned long lo;
@@ -367,6 +367,26 @@
 	EXIT_CRITICAL(flags);
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+int __init has_transparent_hugepage(void)
+{
+	unsigned int mask;
+	unsigned long flags;
+
+	ENTER_CRITICAL(flags);
+	write_c0_pagemask(PM_HUGE_MASK);
+	back_to_back_c0_hazard();
+	mask = read_c0_pagemask();
+	write_c0_pagemask(PM_DEFAULT_MASK);
+
+	EXIT_CRITICAL(flags);
+
+	return mask == PM_HUGE_MASK;
+}
+
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE  */
+
 static int __cpuinitdata ntlb;
 static int __init set_ntlb(char *str)
 {
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 2833dcb..0561335 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -158,7 +158,7 @@
 	label_smp_pgtable_change,
 	label_r3000_write_probe_fail,
 	label_large_segbits_fault,
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	label_tlb_huge_update,
 #endif
 };
@@ -177,13 +177,15 @@
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
 UASM_L_LA(_large_segbits_fault)
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 UASM_L_LA(_tlb_huge_update)
 #endif
 
 static int __cpuinitdata hazard_instance;
 
-static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)
+static void __cpuinit uasm_bgezl_hazard(u32 **p,
+					struct uasm_reloc **r,
+					int instance)
 {
 	switch (instance) {
 	case 0 ... 7:
@@ -194,7 +196,9 @@
 	}
 }
 
-static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)
+static void __cpuinit uasm_bgezl_label(struct uasm_label **l,
+				       u32 **p,
+				       int instance)
 {
 	switch (instance) {
 	case 0 ... 7:
@@ -206,19 +210,59 @@
 }
 
 /*
- * For debug purposes.
+ * pgtable bits are assigned dynamically depending on processor feature
+ * and statically based on kernel configuration.  This spits out the actual
+ * values the kernel is using.  Required to make sense from disassembled
+ * TLB exception handlers.
  */
-static inline void dump_handler(const u32 *handler, int count)
+static void output_pgtable_bits_defines(void)
+{
+#define pr_define(fmt, ...)					\
+	pr_debug("#define " fmt, ##__VA_ARGS__)
+
+	pr_debug("#include <asm/asm.h>\n");
+	pr_debug("#include <asm/regdef.h>\n");
+	pr_debug("\n");
+
+	pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT);
+	pr_define("_PAGE_READ_SHIFT %d\n", _PAGE_READ_SHIFT);
+	pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT);
+	pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT);
+	pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT);
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+	pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
+	pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT);
+#endif
+	if (cpu_has_rixi) {
+#ifdef _PAGE_NO_EXEC_SHIFT
+		pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
+#endif
+#ifdef _PAGE_NO_READ_SHIFT
+		pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT);
+#endif
+	}
+	pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT);
+	pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT);
+	pr_define("_PAGE_DIRTY_SHIFT %d\n", _PAGE_DIRTY_SHIFT);
+	pr_define("_PFN_SHIFT %d\n", _PFN_SHIFT);
+	pr_debug("\n");
+}
+
+static inline void dump_handler(const char *symbol, const u32 *handler, int count)
 {
 	int i;
 
+	pr_debug("LEAF(%s)\n", symbol);
+
 	pr_debug("\t.set push\n");
 	pr_debug("\t.set noreorder\n");
 
 	for (i = 0; i < count; i++)
-		pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]);
+		pr_debug("\t.word\t0x%08x\t\t# %p\n", handler[i], &handler[i]);
 
-	pr_debug("\t.set pop\n");
+	pr_debug("\t.set\tpop\n");
+
+	pr_debug("\tEND(%s)\n", symbol);
 }
 
 /* The only general purpose registers allowed in TLB handlers. */
@@ -401,7 +445,7 @@
 
 	memcpy((void *)ebase, tlb_handler, 0x80);
 
-	dump_handler((u32 *)ebase, 32);
+	dump_handler("r3000_tlb_refill", (u32 *)ebase, 32);
 }
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
@@ -443,7 +487,6 @@
 	case CPU_R4600:
 	case CPU_R4700:
 	case CPU_R5000:
-	case CPU_R5000A:
 	case CPU_NEVADA:
 		uasm_i_nop(p);
 		uasm_i_tlbp(p);
@@ -517,7 +560,6 @@
 		break;
 
 	case CPU_R5000:
-	case CPU_R5000A:
 	case CPU_NEVADA:
 		uasm_i_nop(p); /* QED specifies 2 nops hazard */
 		uasm_i_nop(p); /* QED specifies 2 nops hazard */
@@ -565,24 +607,6 @@
 		tlbw(p);
 		break;
 
-	case CPU_RM9000:
-		/*
-		 * When the JTLB is updated by tlbwi or tlbwr, a subsequent
-		 * use of the JTLB for instructions should not occur for 4
-		 * cpu cycles and use for data translations should not occur
-		 * for 3 cpu cycles.
-		 */
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		tlbw(p);
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		uasm_i_ssnop(p);
-		break;
-
 	case CPU_VR4111:
 	case CPU_VR4121:
 	case CPU_VR4122:
@@ -629,7 +653,7 @@
 	}
 }
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 
 static __cpuinit void build_restore_pagemask(u32 **p,
 					     struct uasm_reloc **r,
@@ -755,7 +779,7 @@
 	build_huge_update_entries(p, pte, ptr);
 	build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0);
 }
-#endif /* CONFIG_HUGETLB_PAGE */
+#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
 
 #ifdef CONFIG_64BIT
 /*
@@ -1200,7 +1224,7 @@
 	/* Adjust the context during the load latency. */
 	build_adjust_context(p, tmp);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	uasm_il_bbit1(p, r, scratch, ilog2(_PAGE_HUGE), label_tlb_huge_update);
 	/*
 	 * The in the LWX case we don't want to do the load in the
@@ -1209,7 +1233,7 @@
 	 */
 	if (use_lwx_insns())
 		uasm_i_nop(p);
-#endif /* CONFIG_HUGETLB_PAGE */
+#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
 
 
 	/* build_update_entries */
@@ -1312,7 +1336,7 @@
 		build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
 #endif
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 		build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
 #endif
 
@@ -1322,7 +1346,7 @@
 		uasm_l_leave(&l, p);
 		uasm_i_eret(&p); /* return from trap */
 	}
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	uasm_l_tlb_huge_update(&l, p);
 	build_huge_update_entries(&p, htlb_info.huge_pte, K1);
 	build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
@@ -1367,7 +1391,7 @@
 		uasm_copy_handler(relocs, labels, tlb_handler, p, f);
 		final_len = p - tlb_handler;
 	} else {
-#if defined(CONFIG_HUGETLB_PAGE)
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 		const enum label_id ls = label_tlb_huge_update;
 #else
 		const enum label_id ls = label_vmalloc;
@@ -1436,7 +1460,7 @@
 
 	memcpy((void *)ebase, final_handler, 0x100);
 
-	dump_handler((u32 *)ebase, 64);
+	dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
 }
 
 /*
@@ -1493,7 +1517,8 @@
 	pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
 		 (unsigned int)(p - tlbmiss_handler_setup_pgd));
 
-	dump_handler(tlbmiss_handler_setup_pgd,
+	dump_handler("tlbmiss_handler",
+		     tlbmiss_handler_setup_pgd,
 		     ARRAY_SIZE(tlbmiss_handler_setup_pgd));
 }
 #endif
@@ -1763,7 +1788,7 @@
 	pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbl));
 
-	dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
+	dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl));
 }
 
 static void __cpuinit build_r3000_tlb_store_handler(void)
@@ -1793,7 +1818,7 @@
 	pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbs));
 
-	dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
+	dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs));
 }
 
 static void __cpuinit build_r3000_tlb_modify_handler(void)
@@ -1823,7 +1848,7 @@
 	pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbm));
 
-	dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
+	dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm));
 }
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
@@ -1842,7 +1867,7 @@
 	build_get_pgde32(p, wr.r1, wr.r2); /* get pgd in ptr */
 #endif
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/*
 	 * For huge tlb entries, pmd doesn't contain an address but
 	 * instead contains the tlb pte. Check the PAGE_HUGE bit and
@@ -1958,7 +1983,7 @@
 	build_make_valid(&p, &r, wr.r1, wr.r2);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/*
 	 * This is the entry point when build_r4000_tlbchange_handler_head
 	 * spots a huge page.
@@ -2030,7 +2055,7 @@
 	pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbl));
 
-	dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
+	dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl));
 }
 
 static void __cpuinit build_r4000_tlb_store_handler(void)
@@ -2051,7 +2076,7 @@
 	build_make_write(&p, &r, wr.r1, wr.r2);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/*
 	 * This is the entry point when
 	 * build_r4000_tlbchange_handler_head spots a huge page.
@@ -2077,7 +2102,7 @@
 	pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbs));
 
-	dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
+	dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs));
 }
 
 static void __cpuinit build_r4000_tlb_modify_handler(void)
@@ -2099,7 +2124,7 @@
 	build_make_write(&p, &r, wr.r1, wr.r2);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	/*
 	 * This is the entry point when
 	 * build_r4000_tlbchange_handler_head spots a huge page.
@@ -2125,7 +2150,7 @@
 	pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbm));
 
-	dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
+	dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm));
 }
 
 void __cpuinit build_tlb_refill_handler(void)
@@ -2137,6 +2162,8 @@
 	 */
 	static int run_once = 0;
 
+	output_pgtable_bits_defines();
+
 #ifdef CONFIG_64BIT
 	check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
 #endif
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index 8059eb7..3c05bf9 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -9,6 +9,34 @@
 	  This DTB will be used if the firmware does not pass in a DTB
           pointer to the kernel.  The corresponding DTS file is at
           arch/mips/netlogic/dts/xlp_evp.dts
+
+config NLM_MULTINODE
+	bool "Support for multi-chip boards"
+	depends on NLM_XLP_BOARD
+	default n
+	help
+	  Add support for boards with 2 or 4 XLPs connected over ICI.
+
+if NLM_MULTINODE
+choice
+	prompt "Number of XLPs on the board"
+	default NLM_MULTINODE_2
+	help
+	  In the multi-node case, specify the number of SoCs on the board.
+
+config NLM_MULTINODE_2
+	bool "Dual-XLP board"
+	help
+	  Support boards with upto two XLPs connected over ICI.
+
+config NLM_MULTINODE_4
+	bool "Quad-XLP board"
+	help
+	  Support boards with upto four XLPs connected over ICI.
+
+endchoice
+
+endif
 endif
 
 config NLM_COMMON
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index e52bfcb..00dcc7a 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -36,7 +36,6 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 #include <linux/interrupt.h>
-#include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
@@ -59,68 +58,70 @@
 #elif defined(CONFIG_CPU_XLR)
 #include <asm/netlogic/xlr/iomap.h>
 #include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/fmn.h>
 #else
 #error "Unknown CPU"
 #endif
-/*
- * These are the routines that handle all the low level interrupt stuff.
- * Actions handled here are: initialization of the interrupt map, requesting of
- * interrupt lines by handlers, dispatching if interrupts to handlers, probing
- * for interrupt lines
- */
 
-/* Globals */
-static uint64_t nlm_irq_mask;
-static DEFINE_SPINLOCK(nlm_pic_lock);
+#ifdef CONFIG_SMP
+#define SMP_IRQ_MASK	((1ULL << IRQ_IPI_SMP_FUNCTION) | \
+				 (1ULL << IRQ_IPI_SMP_RESCHEDULE))
+#else
+#define SMP_IRQ_MASK	0
+#endif
+#define PERCPU_IRQ_MASK	(SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \
+				(1ull << IRQ_FMN))
+
+struct nlm_pic_irq {
+	void	(*extra_ack)(struct irq_data *);
+	struct	nlm_soc_info *node;
+	int	picirq;
+	int	irt;
+	int	flags;
+};
 
 static void xlp_pic_enable(struct irq_data *d)
 {
 	unsigned long flags;
-	int irt;
+	struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
 
-	irt = nlm_irq_to_irt(d->irq);
-	if (irt == -1)
-		return;
-	spin_lock_irqsave(&nlm_pic_lock, flags);
-	nlm_pic_enable_irt(nlm_pic_base, irt);
-	spin_unlock_irqrestore(&nlm_pic_lock, flags);
+	BUG_ON(!pd);
+	spin_lock_irqsave(&pd->node->piclock, flags);
+	nlm_pic_enable_irt(pd->node->picbase, pd->irt);
+	spin_unlock_irqrestore(&pd->node->piclock, flags);
 }
 
 static void xlp_pic_disable(struct irq_data *d)
 {
+	struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
 	unsigned long flags;
-	int irt;
 
-	irt = nlm_irq_to_irt(d->irq);
-	if (irt == -1)
-		return;
-	spin_lock_irqsave(&nlm_pic_lock, flags);
-	nlm_pic_disable_irt(nlm_pic_base, irt);
-	spin_unlock_irqrestore(&nlm_pic_lock, flags);
+	BUG_ON(!pd);
+	spin_lock_irqsave(&pd->node->piclock, flags);
+	nlm_pic_disable_irt(pd->node->picbase, pd->irt);
+	spin_unlock_irqrestore(&pd->node->piclock, flags);
 }
 
 static void xlp_pic_mask_ack(struct irq_data *d)
 {
-	uint64_t mask = 1ull << d->irq;
+	struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
+	uint64_t mask = 1ull << pd->picirq;
 
 	write_c0_eirr(mask);            /* ack by writing EIRR */
 }
 
 static void xlp_pic_unmask(struct irq_data *d)
 {
-	void *hd = irq_data_get_irq_handler_data(d);
-	int irt;
+	struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
 
-	irt = nlm_irq_to_irt(d->irq);
-	if (irt == -1)
+	if (!pd)
 		return;
 
-	if (hd) {
-		void (*extra_ack)(void *) = hd;
-		extra_ack(d);
-	}
+	if (pd->extra_ack)
+		pd->extra_ack(d);
+
 	/* Ack is a single write, no need to lock */
-	nlm_pic_ack(nlm_pic_base, irt);
+	nlm_pic_ack(pd->node->picbase, pd->irt);
 }
 
 static struct irq_chip xlp_pic = {
@@ -174,64 +175,108 @@
 	.irq_eoi	= cpuintr_ack,
 };
 
-void __init init_nlm_common_irqs(void)
+static void __init nlm_init_percpu_irqs(void)
 {
-	int i, irq, irt;
+	int i;
 
 	for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)
 		irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);
-
-	for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++)
-		irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq);
-
 #ifdef CONFIG_SMP
 	irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
 			 nlm_smp_function_ipi_handler);
 	irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
 			 nlm_smp_resched_ipi_handler);
-	nlm_irq_mask |=
-	    ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
 #endif
+}
 
-	for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) {
-		irt = nlm_irq_to_irt(irq);
+void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)
+{
+	struct nlm_pic_irq *pic_data;
+	int xirq;
+
+	xirq = nlm_irq_to_xirq(node, irq);
+	pic_data = kzalloc(sizeof(*pic_data), GFP_KERNEL);
+	BUG_ON(pic_data == NULL);
+	pic_data->irt = irt;
+	pic_data->picirq = picirq;
+	pic_data->node = nlm_get_node(node);
+	irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq);
+	irq_set_handler_data(xirq, pic_data);
+}
+
+void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
+{
+	struct nlm_pic_irq *pic_data;
+	int xirq;
+
+	xirq = nlm_irq_to_xirq(node, irq);
+	pic_data = irq_get_handler_data(xirq);
+	pic_data->extra_ack = xack;
+}
+
+static void nlm_init_node_irqs(int node)
+{
+	int i, irt;
+	uint64_t irqmask;
+	struct nlm_soc_info *nodep;
+
+	pr_info("Init IRQ for node %d\n", node);
+	nodep = nlm_get_node(node);
+	irqmask = PERCPU_IRQ_MASK;
+	for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {
+		irt = nlm_irq_to_irt(i);
 		if (irt == -1)
 			continue;
-		nlm_irq_mask |= (1ULL << irq);
-		nlm_pic_init_irt(nlm_pic_base, irt, irq, 0);
+		nlm_setup_pic_irq(node, i, i, irt);
+		/* set interrupts to first cpu in node */
+		nlm_pic_init_irt(nodep->picbase, irt, i,
+					node * NLM_CPUS_PER_NODE);
+		irqmask |= (1ull << i);
 	}
-
-	nlm_irq_mask |= (1ULL << IRQ_TIMER);
+	nodep->irqmask = irqmask;
 }
 
 void __init arch_init_irq(void)
 {
 	/* Initialize the irq descriptors */
-	init_nlm_common_irqs();
-
-	write_c0_eimr(nlm_irq_mask);
+	nlm_init_percpu_irqs();
+	nlm_init_node_irqs(0);
+	write_c0_eimr(nlm_current_node()->irqmask);
+#if defined(CONFIG_CPU_XLR)
+	nlm_setup_fmn_irq();
+#endif
 }
 
-void __cpuinit nlm_smp_irq_init(void)
+void nlm_smp_irq_init(int hwcpuid)
 {
-	/* set interrupt mask for non-zero cpus */
-	write_c0_eimr(nlm_irq_mask);
+	int node, cpu;
+
+	node = hwcpuid / NLM_CPUS_PER_NODE;
+	cpu  = hwcpuid % NLM_CPUS_PER_NODE;
+
+	if (cpu == 0 && node != 0)
+		nlm_init_node_irqs(node);
+	write_c0_eimr(nlm_current_node()->irqmask);
 }
 
 asmlinkage void plat_irq_dispatch(void)
 {
 	uint64_t eirr;
-	int i;
+	int i, node;
 
+	node = nlm_nodeid();
 	eirr = read_c0_eirr() & read_c0_eimr();
-	if (eirr & (1 << IRQ_TIMER)) {
-		do_IRQ(IRQ_TIMER);
-		return;
-	}
 
 	i = __ilog2_u64(eirr);
 	if (i == -1)
 		return;
 
-	do_IRQ(i);
+	/* per-CPU IRQs don't need translation */
+	if (eirr & PERCPU_IRQ_MASK) {
+		do_IRQ(i);
+		return;
+	}
+
+	/* top level irq handling */
+	do_IRQ(nlm_irq_to_xirq(node, i));
 }
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index fab316d..a080d9e 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -59,12 +59,17 @@
 
 void nlm_send_ipi_single(int logical_cpu, unsigned int action)
 {
-	int cpu = cpu_logical_map(logical_cpu);
+	int cpu, node;
+	uint64_t picbase;
+
+	cpu = cpu_logical_map(logical_cpu);
+	node = cpu / NLM_CPUS_PER_NODE;
+	picbase = nlm_get_node(node)->picbase;
 
 	if (action & SMP_CALL_FUNCTION)
-		nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0);
+		nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0);
 	if (action & SMP_RESCHEDULE_YOURSELF)
-		nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);
+		nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);
 }
 
 void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
@@ -96,11 +101,12 @@
 void nlm_early_init_secondary(int cpu)
 {
 	change_c0_config(CONF_CM_CMASK, 0x3);
-	write_c0_ebase((uint32_t)nlm_common_ebase);
 #ifdef CONFIG_CPU_XLP
-	if (hard_smp_processor_id() % 4 == 0)
+	/* mmu init, once per core */
+	if (cpu % NLM_THREADS_PER_CORE == 0)
 		xlp_mmu_init();
 #endif
+	write_c0_ebase(nlm_current_node()->ebase);
 }
 
 /*
@@ -108,8 +114,12 @@
  */
 static void __cpuinit nlm_init_secondary(void)
 {
-	current_cpu_data.core = hard_smp_processor_id() / 4;
-	nlm_smp_irq_init();
+	int hwtid;
+
+	hwtid = hard_smp_processor_id();
+	current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+	nlm_percpu_init(hwtid);
+	nlm_smp_irq_init(hwtid);
 }
 
 void nlm_prepare_cpus(unsigned int max_cpus)
@@ -120,9 +130,6 @@
 
 void nlm_smp_finish(void)
 {
-#ifdef notyet
-	nlm_common_msgring_cpu_init();
-#endif
 	local_irq_enable();
 }
 
@@ -142,27 +149,27 @@
 
 void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 {
-	unsigned long gp = (unsigned long)task_thread_info(idle);
-	unsigned long sp = (unsigned long)__KSTK_TOS(idle);
-	int cpu = cpu_logical_map(logical_cpu);
+	int cpu, node;
 
-	nlm_next_sp = sp;
-	nlm_next_gp = gp;
+	cpu = cpu_logical_map(logical_cpu);
+	node = cpu / NLM_CPUS_PER_NODE;
+	nlm_next_sp = (unsigned long)__KSTK_TOS(idle);
+	nlm_next_gp = (unsigned long)task_thread_info(idle);
 
-	/* barrier */
+	/* barrier for sp/gp store above */
 	__sync();
-	nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1);
+	nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1);  /* NMI */
 }
 
 void __init nlm_smp_setup(void)
 {
 	unsigned int boot_cpu;
-	int num_cpus, i;
+	int num_cpus, i, ncore;
 
 	boot_cpu = hard_smp_processor_id();
-	cpus_clear(phys_cpu_present_map);
+	cpumask_clear(&phys_cpu_present_map);
 
-	cpu_set(boot_cpu, phys_cpu_present_map);
+	cpumask_set_cpu(boot_cpu, &phys_cpu_present_map);
 	__cpu_number_map[boot_cpu] = 0;
 	__cpu_logical_map[0] = boot_cpu;
 	set_cpu_possible(0, true);
@@ -174,7 +181,7 @@
 		 * it is only set for ASPs (see smpboot.S)
 		 */
 		if (nlm_cpu_ready[i]) {
-			cpu_set(i, phys_cpu_present_map);
+			cpumask_set_cpu(i, &phys_cpu_present_map);
 			__cpu_number_map[i] = num_cpus;
 			__cpu_logical_map[num_cpus] = i;
 			set_cpu_possible(num_cpus, true);
@@ -182,20 +189,28 @@
 		}
 	}
 
+	/* check with the cores we have worken up */
+	for (ncore = 0, i = 0; i < NLM_NR_NODES; i++)
+		ncore += hweight32(nlm_get_node(i)->coremask);
+
 	pr_info("Phys CPU present map: %lx, possible map %lx\n",
-		(unsigned long)phys_cpu_present_map.bits[0],
+		(unsigned long)cpumask_bits(&phys_cpu_present_map)[0],
 		(unsigned long)cpumask_bits(cpu_possible_mask)[0]);
 
-	pr_info("Detected %i Slave CPU(s)\n", num_cpus);
+	pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore,
+		nlm_threads_per_core, num_cpus);
 	nlm_set_nmi_handler(nlm_boot_secondary_cpus);
 }
 
-static int nlm_parse_cpumask(u32 cpu_mask)
+static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
 {
 	uint32_t core0_thr_mask, core_thr_mask;
-	int threadmode, i;
+	int threadmode, i, j;
 
-	core0_thr_mask = cpu_mask & 0xf;
+	core0_thr_mask = 0;
+	for (i = 0; i < NLM_THREADS_PER_CORE; i++)
+		if (cpumask_test_cpu(i, wakeup_mask))
+			core0_thr_mask |= (1 << i);
 	switch (core0_thr_mask) {
 	case 1:
 		nlm_threads_per_core = 1;
@@ -214,25 +229,23 @@
 	}
 
 	/* Verify other cores CPU masks */
-	nlm_coremask = 1;
-	nlm_cpumask = core0_thr_mask;
-	for (i = 1; i < 8; i++) {
-		core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
-		if (core_thr_mask) {
-			if (core_thr_mask != core0_thr_mask)
+	for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) {
+		core_thr_mask = 0;
+		for (j = 0; j < NLM_THREADS_PER_CORE; j++)
+			if (cpumask_test_cpu(i + j, wakeup_mask))
+				core_thr_mask |= (1 << j);
+		if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask)
 				goto unsupp;
-			nlm_coremask |= 1 << i;
-			nlm_cpumask |= core0_thr_mask << (4 * i);
-		}
 	}
 	return threadmode;
 
 unsupp:
-	panic("Unsupported CPU mask %x\n", cpu_mask);
+	panic("Unsupported CPU mask %lx\n",
+		(unsigned long)cpumask_bits(wakeup_mask)[0]);
 	return 0;
 }
 
-int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
+int __cpuinit nlm_wakeup_secondary_cpus(void)
 {
 	unsigned long reset_vec;
 	char *reset_data;
@@ -244,7 +257,7 @@
 			(nlm_reset_entry_end - nlm_reset_entry));
 
 	/* verify the mask and setup core config variables */
-	threadmode = nlm_parse_cpumask(wakeup_mask);
+	threadmode = nlm_parse_cpumask(&nlm_cpumask);
 
 	/* Setup CPU init parameters */
 	reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index a13355c..a0b7487 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -61,7 +61,7 @@
 	li	t0, LSU_DEFEATURE
 	mfcr	t1, t0
 
-	lui	t2, 0x4080	/* Enable Unaligned Access, L2HPE */
+	lui	t2, 0xc080	/* SUE, Enable Unaligned Access, L2HPE */
 	or	t1, t1, t2
 #ifdef XLP_AX_WORKAROUND
 	li	t2, ~0xe	/* S1RCM */
@@ -186,7 +186,7 @@
 	* jump to the secondary wait function.
 	*/
 	mfc0	v0, CP0_EBASE, 1
-	andi	v0, 0x7f		/* v0 <- node/core */
+	andi	v0, 0x3ff		/* v0 <- node/core */
 
 	/* Init MMU in the first thread after changing THREAD_MODE
 	 * register (Ax Errata?)
@@ -263,6 +263,8 @@
 	PTR_L	gp, 0(t1)
 
 	/* a0 has the processor id */
+	mfc0	a0, CP0_EBASE, 1
+	andi	a0, 0x3ff		/* a0 <- node/core */
 	PTR_LA	t0, nlm_early_init_secondary
 	jalr	t0
 	nop
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 6c65ac7..529e747 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -40,23 +40,23 @@
 #include <asm/mipsregs.h>
 #include <asm/time.h>
 
+#include <asm/netlogic/common.h>
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/xlp-hal/iomap.h>
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-/* These addresses are computed by the nlm_hal_init() */
-uint64_t nlm_io_base;
-uint64_t nlm_sys_base;
-uint64_t nlm_pic_base;
-
 /* Main initialization */
-void nlm_hal_init(void)
+void nlm_node_init(int node)
 {
-	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
-	nlm_sys_base = nlm_get_sys_regbase(0);	/* node 0 */
-	nlm_pic_base = nlm_get_pic_regbase(0);	/* node 0 */
+	struct nlm_soc_info *nodep;
+
+	nodep = nlm_get_node(node);
+	nodep->sysbase = nlm_get_sys_regbase(node);
+	nodep->picbase = nlm_get_pic_regbase(node);
+	nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	spin_lock_init(&nodep->piclock);
 }
 
 int nlm_irq_to_irt(int irq)
@@ -100,52 +100,15 @@
 	}
 }
 
-int nlm_irt_to_irq(int irt)
-{
-	switch (irt) {
-	case PIC_IRT_UART_0_INDEX:
-		return PIC_UART_0_IRQ;
-	case PIC_IRT_UART_1_INDEX:
-		return PIC_UART_1_IRQ;
-	case PIC_IRT_PCIE_LINK_0_INDEX:
-	       return PIC_PCIE_LINK_0_IRQ;
-	case PIC_IRT_PCIE_LINK_1_INDEX:
-	       return PIC_PCIE_LINK_1_IRQ;
-	case PIC_IRT_PCIE_LINK_2_INDEX:
-	       return PIC_PCIE_LINK_2_IRQ;
-	case PIC_IRT_PCIE_LINK_3_INDEX:
-	       return PIC_PCIE_LINK_3_IRQ;
-	case PIC_IRT_EHCI_0_INDEX:
-		return PIC_EHCI_0_IRQ;
-	case PIC_IRT_EHCI_1_INDEX:
-		return PIC_EHCI_1_IRQ;
-	case PIC_IRT_OHCI_0_INDEX:
-		return PIC_OHCI_0_IRQ;
-	case PIC_IRT_OHCI_1_INDEX:
-		return PIC_OHCI_1_IRQ;
-	case PIC_IRT_OHCI_2_INDEX:
-		return PIC_OHCI_2_IRQ;
-	case PIC_IRT_OHCI_3_INDEX:
-		return PIC_OHCI_3_IRQ;
-	case PIC_IRT_MMC_INDEX:
-	       return PIC_MMC_IRQ;
-	case PIC_IRT_I2C_0_INDEX:
-		return PIC_I2C_0_IRQ;
-	case PIC_IRT_I2C_1_INDEX:
-		return PIC_I2C_1_IRQ;
-	default:
-		return -1;
-	}
-}
-
-unsigned int nlm_get_core_frequency(int core)
+unsigned int nlm_get_core_frequency(int node, int core)
 {
 	unsigned int pll_divf, pll_divr, dfs_div, ext_div;
 	unsigned int rstval, dfsval, denom;
-	uint64_t num;
+	uint64_t num, sysbase;
 
-	rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG);
-	dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE);
+	sysbase = nlm_get_node(node)->sysbase;
+	rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
+	dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
 	pll_divf = ((rstval >> 10) & 0x7f) + 1;
 	pll_divr = ((rstval >> 8)  & 0x3) + 1;
 	ext_div  = ((rstval >> 30) & 0x3) + 1;
@@ -159,5 +122,5 @@
 
 unsigned int nlm_get_cpu_frequency(void)
 {
-	return nlm_get_core_frequency(0);
+	return nlm_get_core_frequency(0, 0);
 }
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index d899709..4894d62 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -52,26 +52,40 @@
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-unsigned long nlm_common_ebase = 0x0;
-
-/* default to uniprocessor */
-uint32_t nlm_coremask = 1, nlm_cpumask  = 1;
-int  nlm_threads_per_core = 1;
+uint64_t nlm_io_base;
+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
+cpumask_t nlm_cpumask = CPU_MASK_CPU0;
+unsigned int nlm_threads_per_core;
 extern u32 __dtb_start[];
 
 static void nlm_linux_exit(void)
 {
-	nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);
+	uint64_t sysbase = nlm_get_node(0)->sysbase;
+
+	nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
 	for ( ; ; )
 		cpu_wait();
 }
 
 void __init plat_mem_setup(void)
 {
+	void *fdtp;
+
 	panic_timeout	= 5;
 	_machine_restart = (void (*)(char *))nlm_linux_exit;
 	_machine_halt	= nlm_linux_exit;
 	pm_power_off	= nlm_linux_exit;
+
+	/*
+	 * If no FDT pointer is passed in, use the built-in FDT.
+	 * device_tree_init() does not handle CKSEG0 pointers in
+	 * 64-bit, so convert pointer.
+	 */
+	fdtp = (void *)(long)fw_arg0;
+	if (!fdtp)
+		fdtp = __dtb_start;
+	fdtp = phys_to_virt(__pa(fdtp));
+	early_init_devtree(fdtp);
 }
 
 const char *get_system_type(void)
@@ -94,27 +108,19 @@
 		(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
 }
 
+void nlm_percpu_init(int hwcpuid)
+{
+}
+
 void __init prom_init(void)
 {
-	void *fdtp;
-
+	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
 	xlp_mmu_init();
-	nlm_hal_init();
+	nlm_node_init(0);
 
-	/*
-	 * If no FDT pointer is passed in, use the built-in FDT.
-	 * device_tree_init() does not handle CKSEG0 pointers in
-	 * 64-bit, so convert pointer.
-	 */
-	fdtp = (void *)(long)fw_arg0;
-	if (!fdtp)
-		fdtp = __dtb_start;
-	fdtp = phys_to_virt(__pa(fdtp));
-	early_init_devtree(fdtp);
-
-	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
 #ifdef CONFIG_SMP
-	nlm_wakeup_secondary_cpus(0xffffffff);
+	cpumask_setall(&nlm_cpumask);
+	nlm_wakeup_secondary_cpus();
 
 	/* update TLB size after waking up threads */
 	current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index 44d923f..cb90106 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -51,45 +51,72 @@
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-static void xlp_enable_secondary_cores(void)
+static int xlp_wakeup_core(uint64_t sysbase, int core)
 {
-	uint32_t core, value, coremask, syscoremask;
+	uint32_t coremask, value;
 	int count;
 
-	/* read cores in reset from SYS block */
-	syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
+	coremask = (1 << core);
 
-	/* update user specified */
-	nlm_coremask = nlm_coremask & (syscoremask | 1);
+	/* Enable CPU clock */
+	value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);
+	value &= ~coremask;
+	nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
 
-	for (core = 1; core < 8; core++) {
-		coremask = 1 << core;
-		if ((nlm_coremask & coremask) == 0)
-			continue;
+	/* Remove CPU Reset */
+	value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
+	value &= ~coremask;
+	nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);
 
-		/* Enable CPU clock */
-		value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL);
-		value &= ~coremask;
-		nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value);
+	/* Poll for CPU to mark itself coherent */
+	count = 100000;
+	do {
+		value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
+	} while ((value & coremask) != 0 && --count > 0);
 
-		/* Remove CPU Reset */
-		value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
-		value &= ~coremask;
-		nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value);
+	return count != 0;
+}
 
-		/* Poll for CPU to mark itself coherent */
-		count = 100000;
-		do {
-			value = nlm_read_sys_reg(nlm_sys_base,
-			    SYS_CPU_NONCOHERENT_MODE);
-		} while ((value & coremask) != 0 && count-- > 0);
+static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
+{
+	struct nlm_soc_info *nodep;
+	uint64_t syspcibase;
+	uint32_t syscoremask;
+	int core, n, cpu;
 
-		if (count == 0)
-			pr_err("Failed to enable core %d\n", core);
+	for (n = 0; n < NLM_NR_NODES; n++) {
+		syspcibase = nlm_get_sys_pcibase(n);
+		if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
+			break;
+
+		/* read cores in reset from SYS and account for boot cpu */
+		nlm_node_init(n);
+		nodep = nlm_get_node(n);
+		syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
+		if (n == 0)
+			syscoremask |= 1;
+
+		for (core = 0; core < NLM_CORES_PER_NODE; core++) {
+			/* see if the core exists */
+			if ((syscoremask & (1 << core)) == 0)
+				continue;
+
+			/* see if at least the first thread is enabled */
+			cpu = (n * NLM_CORES_PER_NODE + core)
+						* NLM_THREADS_PER_CORE;
+			if (!cpumask_test_cpu(cpu, wakeup_mask))
+				continue;
+
+			/* wake up the core */
+			if (xlp_wakeup_core(nodep->sysbase, core))
+				nodep->coremask |= 1u << core;
+			else
+				pr_err("Failed to enable core %d\n", core);
+		}
 	}
 }
 
-void xlp_wakeup_secondary_cpus(void)
+void xlp_wakeup_secondary_cpus()
 {
 	/*
 	 * In case of u-boot, the secondaries are in reset
@@ -98,5 +125,5 @@
 	xlp_boot_core0_siblings();
 
 	/* now get other cores out of reset */
-	xlp_enable_secondary_cores();
+	xlp_enable_secondary_cores(&nlm_cpumask);
 }
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
index c287dea..05902bc 100644
--- a/arch/mips/netlogic/xlr/Makefile
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -1,2 +1,2 @@
-obj-y				+= setup.o platform.o platform-flash.o
-obj-$(CONFIG_SMP)		+= wakeup.o
+obj-y			+=  fmn.o fmn-config.o setup.o platform.o platform-flash.o
+obj-$(CONFIG_SMP)	+= wakeup.o
diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c
new file mode 100644
index 0000000..bed2cff
--- /dev/null
+++ b/arch/mips/netlogic/xlr/fmn-config.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/cpu-info.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/mipsregs.h>
+#include <asm/netlogic/xlr/fmn.h>
+#include <asm/netlogic/xlr/xlr.h>
+#include <asm/netlogic/common.h>
+#include <asm/netlogic/haldefs.h>
+
+struct xlr_board_fmn_config xlr_board_fmn_config;
+
+static void __maybe_unused print_credit_config(struct xlr_fmn_info *fmn_info)
+{
+	int bkt;
+
+	pr_info("Bucket size :\n");
+	pr_info("Station\t: Size\n");
+	for (bkt = 0; bkt < 16; bkt++)
+		pr_info(" %d  %d  %d  %d  %d  %d  %d %d\n",
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 0],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 1],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 2],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 3],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 4],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 5],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 6],
+			xlr_board_fmn_config.bucket_size[(bkt * 8) + 7]);
+	pr_info("\n");
+
+	pr_info("Credits distribution :\n");
+	pr_info("Station\t: Size\n");
+	for (bkt = 0; bkt < 16; bkt++)
+		pr_info(" %d  %d  %d  %d  %d  %d  %d %d\n",
+			fmn_info->credit_config[(bkt * 8) + 0],
+			fmn_info->credit_config[(bkt * 8) + 1],
+			fmn_info->credit_config[(bkt * 8) + 2],
+			fmn_info->credit_config[(bkt * 8) + 3],
+			fmn_info->credit_config[(bkt * 8) + 4],
+			fmn_info->credit_config[(bkt * 8) + 5],
+			fmn_info->credit_config[(bkt * 8) + 6],
+			fmn_info->credit_config[(bkt * 8) + 7]);
+	pr_info("\n");
+}
+
+static void check_credit_distribution(void)
+{
+	struct xlr_board_fmn_config *cfg = &xlr_board_fmn_config;
+	int bkt, n, total_credits, ncores;
+
+	ncores = hweight32(nlm_current_node()->coremask);
+	for (bkt = 0; bkt < 128; bkt++) {
+		total_credits = 0;
+		for (n = 0; n < ncores; n++)
+			total_credits += cfg->cpu[n].credit_config[bkt];
+		total_credits += cfg->gmac[0].credit_config[bkt];
+		total_credits += cfg->gmac[1].credit_config[bkt];
+		total_credits += cfg->dma.credit_config[bkt];
+		total_credits += cfg->cmp.credit_config[bkt];
+		total_credits += cfg->sae.credit_config[bkt];
+		total_credits += cfg->xgmac[0].credit_config[bkt];
+		total_credits += cfg->xgmac[1].credit_config[bkt];
+		if (total_credits > cfg->bucket_size[bkt])
+			pr_err("ERROR: Bucket %d: credits (%d) > size (%d)\n",
+				bkt, total_credits, cfg->bucket_size[bkt]);
+	}
+	pr_info("Credit distribution complete.\n");
+}
+
+/**
+ * Configure bucket size and credits for a device. 'size' is the size of
+ * the buckets for the device. This size is distributed among all the CPUs
+ * so that all of them can send messages to the device.
+ *
+ * The device is also given 'cpu_credits' to send messages to the CPUs
+ *
+ * @dev_info: FMN information structure for each devices
+ * @start_stn_id: Starting station id of dev_info
+ * @end_stn_id: End station id of dev_info
+ * @num_buckets: Total number of buckets for den_info
+ * @cpu_credits: Allowed credits to cpu for each devices pointing by dev_info
+ * @size: Size of the each buckets in the device station
+ */
+static void setup_fmn_cc(struct xlr_fmn_info *dev_info, int start_stn_id,
+		int end_stn_id, int num_buckets, int cpu_credits, int size)
+{
+	int i, j, num_core, n, credits_per_cpu;
+	struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu;
+
+	num_core = hweight32(nlm_current_node()->coremask);
+	dev_info->num_buckets	= num_buckets;
+	dev_info->start_stn_id	= start_stn_id;
+	dev_info->end_stn_id	= end_stn_id;
+
+	n = num_core;
+	if (num_core == 3)
+		n = 4;
+
+	for (i = start_stn_id; i <= end_stn_id; i++) {
+		xlr_board_fmn_config.bucket_size[i] = size;
+
+		/* Dividing device credits equally to cpus */
+		credits_per_cpu = size / n;
+		for (j = 0; j < num_core; j++)
+			cpu[j].credit_config[i] = credits_per_cpu;
+
+		/* credits left to distribute */
+		credits_per_cpu = size - (credits_per_cpu * num_core);
+
+		/* distribute the remaining credits (if any), among cores */
+		for (j = 0; (j < num_core) && (credits_per_cpu >= 4); j++) {
+			cpu[j].credit_config[i] += 4;
+			credits_per_cpu -= 4;
+		}
+	}
+
+	/* Distributing cpu per bucket credits to devices */
+	for (i = 0; i < num_core; i++) {
+		for (j = 0; j < FMN_CORE_NBUCKETS; j++)
+			dev_info->credit_config[(i * 8) + j] = cpu_credits;
+	}
+}
+
+/*
+ * Each core has 256 slots and 8 buckets,
+ * Configure the 8 buckets each with 32 slots
+ */
+static void setup_cpu_fmninfo(struct xlr_fmn_info *cpu, int num_core)
+{
+	int i, j;
+
+	for (i = 0; i < num_core; i++) {
+		cpu[i].start_stn_id     = (8 * i);
+		cpu[i].end_stn_id       = (8 * i + 8);
+
+		for (j = cpu[i].start_stn_id; j < cpu[i].end_stn_id; j++)
+			xlr_board_fmn_config.bucket_size[j] = 32;
+	}
+}
+
+/**
+ * Setup the FMN details for each devices according to the device available
+ * in each variant of XLR/XLS processor
+ */
+void xlr_board_info_setup(void)
+{
+	struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu;
+	struct xlr_fmn_info *gmac = xlr_board_fmn_config.gmac;
+	struct xlr_fmn_info *xgmac = xlr_board_fmn_config.xgmac;
+	struct xlr_fmn_info *dma = &xlr_board_fmn_config.dma;
+	struct xlr_fmn_info *cmp = &xlr_board_fmn_config.cmp;
+	struct xlr_fmn_info *sae = &xlr_board_fmn_config.sae;
+	int processor_id, num_core;
+
+	num_core = hweight32(nlm_current_node()->coremask);
+	processor_id = read_c0_prid() & 0xff00;
+
+	setup_cpu_fmninfo(cpu, num_core);
+	switch (processor_id) {
+	case PRID_IMP_NETLOGIC_XLS104:
+	case PRID_IMP_NETLOGIC_XLS108:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 16, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 8, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 8, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLS204:
+	case PRID_IMP_NETLOGIC_XLS208:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 16, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 8, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 8, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLS404:
+	case PRID_IMP_NETLOGIC_XLS408:
+	case PRID_IMP_NETLOGIC_XLS404B:
+	case PRID_IMP_NETLOGIC_XLS408B:
+	case PRID_IMP_NETLOGIC_XLS416B:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 8, 32);
+		setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,
+					FMN_STNID_GMAC1_TX3, 8, 8, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 4, 64);
+		setup_fmn_cc(cmp, FMN_STNID_CMP_0,
+					FMN_STNID_CMP_3, 4, 4, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 8, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLS412B:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 8, 32);
+		setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,
+					FMN_STNID_GMAC1_TX3, 8, 8, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 4, 64);
+		setup_fmn_cc(cmp, FMN_STNID_CMP_0,
+					FMN_STNID_CMP_3, 4, 4, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 8, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLR308:
+	case PRID_IMP_NETLOGIC_XLR308C:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 16, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 8, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 4, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLR532:
+	case PRID_IMP_NETLOGIC_XLR532C:
+	case PRID_IMP_NETLOGIC_XLR516C:
+	case PRID_IMP_NETLOGIC_XLR508C:
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 16, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 8, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 4, 128);
+		break;
+
+	case PRID_IMP_NETLOGIC_XLR732:
+	case PRID_IMP_NETLOGIC_XLR716:
+		setup_fmn_cc(&xgmac[0], FMN_STNID_XMAC0_00_TX,
+					FMN_STNID_XMAC0_15_TX, 8, 0, 32);
+		setup_fmn_cc(&xgmac[1], FMN_STNID_XMAC1_00_TX,
+					FMN_STNID_XMAC1_15_TX, 8, 0, 32);
+		setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
+					FMN_STNID_GMAC0_TX3, 8, 24, 32);
+		setup_fmn_cc(dma, FMN_STNID_DMA_0,
+					FMN_STNID_DMA_3, 4, 4, 64);
+		setup_fmn_cc(sae, FMN_STNID_SEC0,
+					FMN_STNID_SEC1, 2, 4, 128);
+		break;
+	default:
+		pr_err("Unknown CPU with processor ID [%d]\n", processor_id);
+		pr_err("Error: Cannot initialize FMN credits.\n");
+	}
+
+	check_credit_distribution();
+
+#if 0 /* debug */
+	print_credit_config(&cpu[0]);
+	print_credit_config(&gmac[0]);
+#endif
+}
diff --git a/arch/mips/netlogic/xlr/fmn.c b/arch/mips/netlogic/xlr/fmn.c
new file mode 100644
index 0000000..4d74f03
--- /dev/null
+++ b/arch/mips/netlogic/xlr/fmn.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irqreturn.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/mipsregs.h>
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/xlr/fmn.h>
+#include <asm/netlogic/common.h>
+
+#define COP2_CC_INIT_CPU_DEST(dest, conf) \
+do { \
+	nlm_write_c2_cc##dest(0, conf[(dest * 8) + 0]); \
+	nlm_write_c2_cc##dest(1, conf[(dest * 8) + 1]); \
+	nlm_write_c2_cc##dest(2, conf[(dest * 8) + 2]); \
+	nlm_write_c2_cc##dest(3, conf[(dest * 8) + 3]); \
+	nlm_write_c2_cc##dest(4, conf[(dest * 8) + 4]); \
+	nlm_write_c2_cc##dest(5, conf[(dest * 8) + 5]); \
+	nlm_write_c2_cc##dest(6, conf[(dest * 8) + 6]); \
+	nlm_write_c2_cc##dest(7, conf[(dest * 8) + 7]); \
+} while (0)
+
+struct fmn_message_handler {
+	void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *);
+	void *arg;
+} msg_handlers[128];
+
+/*
+ * FMN interrupt handler. We configure the FMN so that any messages in
+ * any of the CPU buckets will trigger an interrupt on the CPU.
+ * The message can be from any device on the FMN (like NAE/SAE/DMA).
+ * The source station id is used to figure out which of the registered
+ * handlers have to be called.
+ */
+static irqreturn_t fmn_message_handler(int irq, void *data)
+{
+	struct fmn_message_handler *hndlr;
+	int bucket, rv;
+	int size = 0, code = 0, src_stnid = 0;
+	struct nlm_fmn_msg msg;
+	uint32_t mflags, bkt_status;
+
+	mflags = nlm_cop2_enable();
+	/* Disable message ring interrupt */
+	nlm_fmn_setup_intr(irq, 0);
+	while (1) {
+		/* 8 bkts per core, [24:31] each bit represents one bucket
+		 * Bit is Zero if bucket is not empty */
+		bkt_status = (nlm_read_c2_status() >> 24) & 0xff;
+		if (bkt_status == 0xff)
+			break;
+		for (bucket = 0; bucket < 8; bucket++) {
+			/* Continue on empty bucket */
+			if (bkt_status & (1 << bucket))
+				continue;
+			rv = nlm_fmn_receive(bucket, &size, &code, &src_stnid,
+						&msg);
+			if (rv != 0)
+				continue;
+
+			hndlr = &msg_handlers[src_stnid];
+			if (hndlr->action == NULL)
+				pr_warn("No msgring handler for stnid %d\n",
+						src_stnid);
+			else {
+				nlm_cop2_restore(mflags);
+				hndlr->action(bucket, src_stnid, size, code,
+					&msg, hndlr->arg);
+				mflags = nlm_cop2_enable();
+			}
+		}
+	};
+	/* Enable message ring intr, to any thread in core */
+	nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1);
+	nlm_cop2_restore(mflags);
+	return IRQ_HANDLED;
+}
+
+struct irqaction fmn_irqaction = {
+	.handler = fmn_message_handler,
+	.flags = IRQF_PERCPU,
+	.name = "fmn",
+};
+
+void xlr_percpu_fmn_init(void)
+{
+	struct xlr_fmn_info *cpu_fmn_info;
+	int *bucket_sizes;
+	uint32_t flags;
+	int id;
+
+	BUG_ON(nlm_thread_id() != 0);
+	id = nlm_core_id();
+
+	bucket_sizes = xlr_board_fmn_config.bucket_size;
+	cpu_fmn_info = &xlr_board_fmn_config.cpu[id];
+	flags = nlm_cop2_enable();
+
+	/* Setup bucket sizes for the core. */
+	nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]);
+	nlm_write_c2_bucksize(1, bucket_sizes[id * 8 + 1]);
+	nlm_write_c2_bucksize(2, bucket_sizes[id * 8 + 2]);
+	nlm_write_c2_bucksize(3, bucket_sizes[id * 8 + 3]);
+	nlm_write_c2_bucksize(4, bucket_sizes[id * 8 + 4]);
+	nlm_write_c2_bucksize(5, bucket_sizes[id * 8 + 5]);
+	nlm_write_c2_bucksize(6, bucket_sizes[id * 8 + 6]);
+	nlm_write_c2_bucksize(7, bucket_sizes[id * 8 + 7]);
+
+	/*
+	 * For sending FMN messages, we need credits on the destination
+	 * bucket. Program the credits this core has on the 128 possible
+	 * destination buckets.
+	 * We cannot use a loop here, because the the first argument has
+	 * to be a constant integer value.
+	 */
+	COP2_CC_INIT_CPU_DEST(0, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(1, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(2, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(3, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(4, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(5, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(6, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(7, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(8, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(9, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(10, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(11, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(12, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(13, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(14, cpu_fmn_info->credit_config);
+	COP2_CC_INIT_CPU_DEST(15, cpu_fmn_info->credit_config);
+
+	/* enable FMN interrupts on this CPU */
+	nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
+	nlm_cop2_restore(flags);
+}
+
+
+/*
+ * Register a FMN message handler with respect to the source station id
+ * @stnid: source station id
+ * @action: Handler function pointer
+ */
+int nlm_register_fmn_handler(int start_stnid, int end_stnid,
+	void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *),
+	void *arg)
+{
+	int sstnid;
+
+	for (sstnid = start_stnid; sstnid <= end_stnid; sstnid++) {
+		msg_handlers[sstnid].arg = arg;
+		smp_wmb();
+		msg_handlers[sstnid].action = action;
+	}
+	pr_debug("Registered FMN msg handler for stnid %d-%d\n",
+			start_stnid, end_stnid);
+	return 0;
+}
+
+void nlm_setup_fmn_irq(void)
+{
+	uint32_t flags;
+
+	/* setup irq only once */
+	setup_irq(IRQ_FMN, &fmn_irqaction);
+
+	flags = nlm_cop2_enable();
+	nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
+	nlm_cop2_restore(flags);
+}
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index 81b1d31..4e7f49d 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -49,16 +49,15 @@
 #include <asm/netlogic/xlr/iomap.h>
 #include <asm/netlogic/xlr/pic.h>
 #include <asm/netlogic/xlr/gpio.h>
+#include <asm/netlogic/xlr/fmn.h>
 
 uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;
-uint64_t nlm_pic_base;
 struct psb_info nlm_prom_info;
 
-unsigned long nlm_common_ebase = 0x0;
-
 /* default to uniprocessor */
-uint32_t nlm_coremask = 1, nlm_cpumask  = 1;
-int  nlm_threads_per_core = 1;
+unsigned int  nlm_threads_per_core = 1;
+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
+cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 
 static void __init nlm_early_serial_setup(void)
 {
@@ -113,6 +112,12 @@
 	/* Nothing yet */
 }
 
+void nlm_percpu_init(int hwcpuid)
+{
+	if (hwcpuid % 4 == 0)
+		xlr_percpu_fmn_init();
+}
+
 static void __init build_arcs_cmdline(int *argv)
 {
 	int i, remain, len;
@@ -176,9 +181,19 @@
 	}
 }
 
+static void nlm_init_node(void)
+{
+	struct nlm_soc_info *nodep;
+
+	nodep = nlm_current_node();
+	nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);
+	nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	spin_lock_init(&nodep->piclock);
+}
+
 void __init prom_init(void)
 {
-	int *argv, *envp;		/* passed as 32 bit ptrs */
+	int i, *argv, *envp;		/* passed as 32 bit ptrs */
 	struct psb_info *prom_infop;
 
 	/* truncate to 32 bit and sign extend all args */
@@ -187,15 +202,19 @@
 	prom_infop = (struct psb_info *)(long)(int)fw_arg3;
 
 	nlm_prom_info = *prom_infop;
-	nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);
+	nlm_init_node();
 
 	nlm_early_serial_setup();
 	build_arcs_cmdline(argv);
-	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
 	prom_add_memory();
 
 #ifdef CONFIG_SMP
-	nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map);
+	for (i = 0; i < 32; i++)
+		if (nlm_prom_info.online_cpu_map & (1 << i))
+			cpumask_set_cpu(i, &nlm_cpumask);
+	nlm_wakeup_secondary_cpus();
 	register_smp_ops(&nlm_smp_ops);
 #endif
+	xlr_board_info_setup();
+	xlr_percpu_fmn_init();
 }
diff --git a/arch/mips/netlogic/xlr/wakeup.c b/arch/mips/netlogic/xlr/wakeup.c
index db5d987..3ebf741 100644
--- a/arch/mips/netlogic/xlr/wakeup.c
+++ b/arch/mips/netlogic/xlr/wakeup.c
@@ -33,6 +33,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/threads.h>
 
 #include <asm/asm.h>
@@ -50,18 +51,34 @@
 
 int __cpuinit xlr_wakeup_secondary_cpus(void)
 {
-	unsigned int i, boot_cpu;
+	struct nlm_soc_info *nodep;
+	unsigned int i, j, boot_cpu;
 
 	/*
 	 *  In case of RMI boot, hit with NMI to get the cores
 	 *  from bootloader to linux code.
 	 */
+	nodep = nlm_get_node(0);
 	boot_cpu = hard_smp_processor_id();
 	nlm_set_nmi_handler(nlm_rmiboot_preboot);
 	for (i = 0; i < NR_CPUS; i++) {
-		if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0)
+		if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask))
 			continue;
-		nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */
+		nlm_pic_send_ipi(nodep->picbase, i, 1, 1); /* send NMI */
+	}
+
+	/* Fill up the coremask early */
+	nodep->coremask = 1;
+	for (i = 1; i < NLM_CORES_PER_NODE; i++) {
+		for (j = 1000000; j > 0; j--) {
+			if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE])
+				break;
+			udelay(10);
+		}
+		if (j != 0)
+			nodep->coremask |= (1u << i);
+		else
+			pr_err("Failed to wakeup core %d\n", i);
 	}
 
 	return 0;
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 1208c28..9c0a678 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -12,5 +12,5 @@
 oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_R10000)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_SB1)		+= op_model_mipsxx.o
-oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
+oprofile-$(CONFIG_CPU_XLR)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_LOONGSON2)	+= op_model_loongson2.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index f80480a..e32db1f 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -16,7 +16,6 @@
 #include "op_impl.h"
 
 extern struct op_mips_model op_model_mipsxx_ops __weak;
-extern struct op_mips_model op_model_rm9000_ops __weak;
 extern struct op_mips_model op_model_loongson2_ops __weak;
 
 static struct op_mips_model *model;
@@ -91,12 +90,10 @@
 	case CPU_R10000:
 	case CPU_R12000:
 	case CPU_R14000:
+	case CPU_XLR:
 		lmodel = &op_model_mipsxx_ops;
 		break;
 
-	case CPU_RM9000:
-		lmodel = &op_model_rm9000_ops;
-		break;
 	case CPU_LOONGSON2:
 		lmodel = &op_model_loongson2_ops;
 		break;
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 28ea1a4..7862546 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,8 +31,22 @@
 
 #define M_COUNTER_OVERFLOW		(1UL      << 31)
 
+/* Netlogic XLR specific, count events in all threads in a core */
+#define M_PERFCTL_COUNT_ALL_THREADS	(1UL      << 13)
+
 static int (*save_perf_irq)(void);
 
+/*
+ * XLR has only one set of counters per core. Designate the
+ * first hardware thread in the core for setup and init.
+ * Skip CPUs with non-zero hardware thread id (4 hwt per core)
+ */
+#ifdef CONFIG_CPU_XLR
+#define oprofile_skip_cpu(c)	((cpu_logical_map(c) & 0x3) != 0)
+#else
+#define oprofile_skip_cpu(c)	0
+#endif
+
 #ifdef CONFIG_MIPS_MT_SMP
 static int cpu_has_mipsmt_pertccounters;
 #define WHAT		(M_TC_EN_VPE | \
@@ -152,6 +166,8 @@
 			reg.control[i] |= M_PERFCTL_USER;
 		if (ctr[i].exl)
 			reg.control[i] |= M_PERFCTL_EXL;
+		if (current_cpu_type() == CPU_XLR)
+			reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;
 		reg.counter[i] = 0x80000000 - ctr[i].count;
 	}
 }
@@ -162,6 +178,9 @@
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -183,6 +202,9 @@
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(WHAT | reg.control[3]);
@@ -200,6 +222,9 @@
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -372,6 +397,10 @@
 		op_model_mipsxx_ops.cpu_type = "mips/loongson1";
 		break;
 
+	case CPU_XLR:
+		op_model_mipsxx_ops.cpu_type = "mips/xlr";
+		break;
+
 	default:
 		printk(KERN_ERR "Profiling unsupported for this CPU\n");
 
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
deleted file mode 100644
index 3aa8138..0000000
--- a/arch/mips/oprofile/op_model_rm9000.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 by Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-
-#include "op_impl.h"
-
-#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
-#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
-#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
-#define RM9K_COUNTER1_USER		(1ULL    <<  9)
-#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
-#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
-
-#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
-#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
-#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
-#define RM9K_COUNTER2_USER		(1ULL    << 25)
-#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
-#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
-
-extern unsigned int rm9000_perfcount_irq;
-
-static struct rm9k_register_config {
-	unsigned int control;
-	unsigned int reset_counter1;
-	unsigned int reset_counter2;
-} reg;
-
-/* Compute all of the registers in preparation for enabling profiling.  */
-
-static void rm9000_reg_setup(struct op_counter_config *ctr)
-{
-	unsigned int control = 0;
-
-	/* Compute the performance counter control word.  */
-	/* For now count kernel and user mode */
-	if (ctr[0].enabled)
-		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
-		           RM9K_COUNTER1_KERNEL |
-		           RM9K_COUNTER1_USER |
-		           RM9K_COUNTER1_ENABLE;
-	if (ctr[1].enabled)
-		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
-		           RM9K_COUNTER2_KERNEL |
-		           RM9K_COUNTER2_USER |
-		           RM9K_COUNTER2_ENABLE;
-	reg.control = control;
-
-	reg.reset_counter1 = 0x80000000 - ctr[0].count;
-	reg.reset_counter2 = 0x80000000 - ctr[1].count;
-}
-
-/* Program all of the registers in preparation for enabling profiling.  */
-
-static void rm9000_cpu_setup(void *args)
-{
-	uint64_t perfcount;
-
-	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
-	write_c0_perfcount(perfcount);
-}
-
-static void rm9000_cpu_start(void *args)
-{
-	/* Start all counters on current CPU */
-	write_c0_perfcontrol(reg.control);
-}
-
-static void rm9000_cpu_stop(void *args)
-{
-	/* Stop all counters on current CPU */
-	write_c0_perfcontrol(0);
-}
-
-static irqreturn_t rm9000_perfcount_handler(int irq, void *dev_id)
-{
-	unsigned int control = read_c0_perfcontrol();
-	struct pt_regs *regs = get_irq_regs();
-	uint32_t counter1, counter2;
-	uint64_t counters;
-
-	/*
-	 * RM9000 combines two 32-bit performance counters into a single
-	 * 64-bit coprocessor zero register.  To avoid a race updating the
-	 * registers we need to stop the counters while we're messing with
-	 * them ...
-	 */
-	write_c0_perfcontrol(0);
-
-	counters = read_c0_perfcount();
-	counter1 = counters;
-	counter2 = counters >> 32;
-
-	if (control & RM9K_COUNTER1_OVERFLOW) {
-		oprofile_add_sample(regs, 0);
-		counter1 = reg.reset_counter1;
-	}
-	if (control & RM9K_COUNTER2_OVERFLOW) {
-		oprofile_add_sample(regs, 1);
-		counter2 = reg.reset_counter2;
-	}
-
-	counters = ((uint64_t)counter2 << 32) | counter1;
-	write_c0_perfcount(counters);
-	write_c0_perfcontrol(reg.control);
-
-	return IRQ_HANDLED;
-}
-
-static int __init rm9000_init(void)
-{
-	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
-	                   0, "Perfcounter", NULL);
-}
-
-static void rm9000_exit(void)
-{
-	free_irq(rm9000_perfcount_irq, NULL);
-}
-
-struct op_mips_model op_model_rm9000_ops = {
-	.reg_setup	= rm9000_reg_setup,
-	.cpu_setup	= rm9000_cpu_setup,
-	.init		= rm9000_init,
-	.exit		= rm9000_exit,
-	.cpu_start	= rm9000_cpu_start,
-	.cpu_stop	= rm9000_cpu_stop,
-	.cpu_type	= "mips/rm9000",
-	.num_counters	= 2
-};
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index e13a71c..ce995d3 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -34,8 +34,6 @@
 obj-$(CONFIG_PMC_MSP7120_GW)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_FPGA)	+= fixup-pmcmsp.o ops-pmcmsp.o
-obj-$(CONFIG_PMC_YOSEMITE)	+= fixup-yosemite.o ops-titan.o ops-titan-ht.o \
-				   pci-yosemite.o
 obj-$(CONFIG_SGI_IP27)		+= ops-bridge.o pci-ip27.o
 obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
 obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
deleted file mode 100644
index fdafb13..0000000
--- a/arch/mips/pci/fixup-yosemite.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	if (pin == 0)
-		return -1;
-
-	return 3;			/* Everything goes to one irq bit */
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c
index b46b3e2..4383194 100644
--- a/arch/mips/pci/ops-bridge.c
+++ b/arch/mips/pci/ops-bridge.c
@@ -56,7 +56,7 @@
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at it for real ...
 	 */
 	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
@@ -76,7 +76,7 @@
 oh_my_gawd:
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at the wrong register.
 	 */
 	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
@@ -85,7 +85,7 @@
 	}
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * IOC3 is fucking fucked beyond belief ...  Don't try to access
 	 * anything but 32-bit words ...
 	 */
 	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
@@ -118,7 +118,7 @@
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at it for real ...
 	 */
 	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
@@ -139,7 +139,7 @@
 oh_my_gawd:
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at the wrong register.
 	 */
 	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
@@ -148,7 +148,7 @@
 	}
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * IOC3 is fucking fucked beyond belief ...  Don't try to access
 	 * anything but 32-bit words ...
 	 */
 	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
@@ -189,7 +189,7 @@
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at it for real ...
 	 */
 	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
@@ -213,14 +213,14 @@
 oh_my_gawd:
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to touch the wrong register.
 	 */
 	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
 		return PCIBIOS_SUCCESSFUL;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * IOC3 is fucking fucked beyond belief ...  Don't try to access
 	 * anything but 32-bit words ...
 	 */
 	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
@@ -257,7 +257,7 @@
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to look at it for real ...
 	 */
 	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
@@ -281,14 +281,14 @@
 oh_my_gawd:
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * IOC3 is fucking fucked beyond belief ...  Don't even give the
 	 * generic PCI code a chance to touch the wrong register.
 	 */
 	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
 		return PCIBIOS_SUCCESSFUL;
 
 	/*
-	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * IOC3 is fucking fucked beyond belief ...  Don't try to access
 	 * anything but 32-bit words ...
 	 */
 	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
deleted file mode 100644
index 57d54ad..0000000
--- a/arch/mips/pci/ops-titan-ht.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include <asm/titan_dep.h>
-
-static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
-	int offset, u32 *val)
-{
-	volatile uint32_t address;
-	int busno;
-
-	busno = bus->number;
-
-	address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
-	if (busno != 0)
-		address |= 1;
-
-	/*
-	 * RM9000 HT Errata: Issue back to back HT config
-	 * transcations. Issue a BIU sync before and
-	 * after the HT cycle
-	 */
-
-	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
-
-	udelay(30);
-
-	*(volatile int32_t *) 0xfb0006f8 = address;
-	*(val) = *(volatile int32_t *) 0xfb0006fc;
-
-	udelay(30);
-
-	* (volatile int32_t *) 0xfb0000f0 |= 0x2;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
-	int offset, int size, u32 *val)
-{
-	uint32_t dword;
-
-	titan_ht_config_read_dword(bus, devfn, offset, &dword);
-
-	dword >>= ((offset & 3) << 3);
-	dword &= (0xffffffffU >> ((4 - size) << 8));
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static inline int titan_ht_config_write_dword(struct pci_bus *bus,
-	unsigned int devfn, int offset, u32 val)
-{
-	volatile uint32_t address;
-	int busno;
-
-	busno = bus->number;
-
-	address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
-	if (busno != 0)
-		address |= 1;
-
-	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
-
-	udelay(30);
-
-	*(volatile int32_t *) 0xfb0006f8 = address;
-	*(volatile int32_t *) 0xfb0006fc = val;
-
-	udelay(30);
-
-	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn,
-	int offset, int size, u32 val)
-{
-	uint32_t val1, val2, mask;
-
-	titan_ht_config_read_dword(bus, devfn, offset, &val2);
-
-	val1 = val << ((offset & 3) << 3);
-	mask = ~(0xffffffffU >> ((4 - size) << 8));
-	val2 &= ~(mask << ((offset & 3) << 8));
-
-	titan_ht_config_write_dword(bus, devfn, offset, val1 | val2);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops titan_ht_pci_ops = {
-	.read	= titan_ht_config_read,
-	.write	= titan_ht_config_write,
-};
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
deleted file mode 100644
index ebf8fc4..0000000
--- a/arch/mips/pci/ops-titan.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
- *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
- *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-
-#include <asm/pci.h>
-#include <asm/io.h>
-#include <asm/rm9k-ocd.h>
-
-/*
- * PCI specific defines
- */
-#define	TITAN_PCI_0_CONFIG_ADDRESS	0x780
-#define	TITAN_PCI_0_CONFIG_DATA		0x784
-
-/*
- * Titan PCI Config Read Byte
- */
-static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
-	int size, u32 * val)
-{
-	uint32_t address, tmp;
-	int dev, busno, func;
-
-	busno = bus->number;
-	dev = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	address = (busno << 16) | (dev << 11) | (func << 8) |
-	          (reg & 0xfc) | 0x80000000;
-
-
-	/* start the configuration cycle */
-	ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
-	tmp = ocd_readl(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
-
-	switch (size) {
-	case 1:
-		tmp &= 0xff;
-	case 2:
-		tmp &= 0xffff;
-	}
-	*val = tmp;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
-	int size, u32 val)
-{
-	uint32_t address;
-	int dev, busno, func;
-
-	busno = bus->number;
-	dev = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	address = (busno << 16) | (dev << 11) | (func << 8) |
-		(reg & 0xfc) | 0x80000000;
-
-	/* start the configuration cycle */
-	ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
-
-	/* write the data */
-	switch (size) {
-	case 1:
-		ocd_writeb(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3));
-		break;
-
-	case 2:
-		ocd_writew(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2));
-		break;
-
-	case 4:
-		ocd_writel(val, TITAN_PCI_0_CONFIG_DATA);
-		break;
-	}
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * Titan PCI structure
- */
-struct pci_ops titan_pci_ops = {
-	titan_read_config,
-	titan_write_config,
-};
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
index 8a48139..ca179b6 100644
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -11,8 +11,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 #include <asm/bootinfo.h>
 
+#include <bcm63xx_reset.h>
+
 #include "pci-bcm63xx.h"
 
 /*
@@ -119,41 +122,36 @@
 {
 	u32 val;
 
-	/* enable clock */
-	val = bcm_perf_readl(PERF_CKCTL_REG);
-	val |= CKCTL_6328_PCIE_EN;
-	bcm_perf_writel(val, PERF_CKCTL_REG);
-
 	/* enable SERDES */
 	val = bcm_misc_readl(MISC_SERDES_CTRL_REG);
 	val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN;
 	bcm_misc_writel(val, MISC_SERDES_CTRL_REG);
 
 	/* reset the PCIe core */
-	val = bcm_perf_readl(PERF_SOFTRESET_6328_REG);
-
-	val &= ~SOFTRESET_6328_PCIE_MASK;
-	val &= ~SOFTRESET_6328_PCIE_CORE_MASK;
-	val &= ~SOFTRESET_6328_PCIE_HARD_MASK;
-	val &= ~SOFTRESET_6328_PCIE_EXT_MASK;
-	bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+	bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1);
+	bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1);
 	mdelay(10);
 
-	val |= SOFTRESET_6328_PCIE_MASK;
-	val |= SOFTRESET_6328_PCIE_CORE_MASK;
-	val |= SOFTRESET_6328_PCIE_HARD_MASK;
-	bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+	bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0);
 	mdelay(10);
 
-	val |= SOFTRESET_6328_PCIE_EXT_MASK;
-	bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+	bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0);
 	mdelay(200);
 }
 
+static struct clk *pcie_clk;
+
 static int __init bcm63xx_register_pcie(void)
 {
 	u32 val;
 
+	/* enable clock */
+	pcie_clk = clk_get(NULL, "pcie");
+	if (IS_ERR_OR_NULL(pcie_clk))
+		return -ENODEV;
+
+	clk_prepare_enable(pcie_clk);
+
 	bcm63xx_reset_pcie();
 
 	/* configure the PCIe bridge */
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 4b0c347..5b5ed76 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -11,6 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/delay.h>
+#include <linux/platform_device.h>
 #include <linux/swiotlb.h>
 
 #include <asm/time.h>
@@ -704,6 +705,10 @@
 	 */
 	cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
 
+	if (IS_ERR(platform_device_register_simple("octeon_pci_edac",
+						   -1, NULL, 0)))
+		pr_err("Registation of co_pci_edac failed!\n");
+
 	octeon_pci_dma_init();
 
 	return 0;
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 18af021..0c18ccc 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -47,6 +47,7 @@
 
 #include <asm/netlogic/interrupt.h>
 #include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
 
 #include <asm/netlogic/xlr/msidef.h>
 #include <asm/netlogic/xlr/iomap.h>
@@ -174,22 +175,9 @@
 	return p ? bus->self : NULL;
 }
 
-static int get_irq_vector(const struct pci_dev *dev)
+static int nlm_pci_link_to_irq(int link)
 {
-	struct pci_dev *lnk;
-
-	if (!nlm_chip_is_xls())
-		return	PIC_PCIX_IRQ;	/* for XLR just one IRQ */
-
-	/*
-	 * For XLS PCIe, there is an IRQ per Link, find out which
-	 * link the device is on to assign interrupts
-	 */
-	lnk = xls_get_pcie_link(dev);
-	if (lnk == NULL)
-		return 0;
-
-	switch	(PCI_SLOT(lnk->devfn)) {
+	switch	(link) {
 	case 0:
 		return PIC_PCIE_LINK0_IRQ;
 	case 1:
@@ -205,10 +193,26 @@
 		else
 			return PIC_PCIE_LINK3_IRQ;
 	}
-	WARN(1, "Unexpected devfn %d\n", lnk->devfn);
+	WARN(1, "Unexpected link %d\n", link);
 	return 0;
 }
 
+static int get_irq_vector(const struct pci_dev *dev)
+{
+	struct pci_dev *lnk;
+	int link;
+
+	if (!nlm_chip_is_xls())
+		return	PIC_PCIX_IRQ;	/* for XLR just one IRQ */
+
+	lnk = xls_get_pcie_link(dev);
+	if (lnk == NULL)
+		return 0;
+
+	link = PCI_SLOT(lnk->devfn);
+	return nlm_pci_link_to_irq(link);
+}
+
 #ifdef CONFIG_PCI_MSI
 void destroy_irq(unsigned int irq)
 {
@@ -332,6 +336,9 @@
 
 static int __init pcibios_init(void)
 {
+	void (*extra_ack)(struct irq_data *);
+	int link, irq;
+
 	/* PSB assigns PCI resources */
 	pci_set_flags(PCI_PROBE_ONLY);
 	pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);
@@ -350,27 +357,19 @@
 	 * For PCI interrupts, we need to ack the PCI controller too, overload
 	 * irq handler data to do this
 	 */
-	if (nlm_chip_is_xls()) {
-		if (nlm_chip_is_xls_b()) {
-			irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
-							xls_pcie_ack_b);
-			irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
-							xls_pcie_ack_b);
-			irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
-							xls_pcie_ack_b);
-			irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
-							xls_pcie_ack_b);
-		} else {
-			irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
-			irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
-			irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
-			irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
-		}
-	} else {
+	if (!nlm_chip_is_xls()) {
 		/* XLR PCI controller ACK */
-		irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack);
+		nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack);
+	} else {
+		if  (nlm_chip_is_xls_b())
+			extra_ack = xls_pcie_ack_b;
+		else
+			extra_ack = xls_pcie_ack;
+		for (link = 0; link < 4; link++) {
+			irq = nlm_pci_link_to_irq(link);
+			nlm_set_pic_extra_ack(0, irq, extra_ack);
+		}
 	}
-
 	return 0;
 }
 
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
deleted file mode 100644
index cf5e1a2..0000000
--- a/arch/mips/pci/pci-yosemite.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/titan_dep.h>
-
-extern struct pci_ops titan_pci_ops;
-
-static struct resource py_mem_resource = {
-	.start	= 0xe0000000UL,
-	.end	= 0xe3ffffffUL,
-	.name	= "Titan PCI MEM",
-	.flags	= IORESOURCE_MEM
-};
-
-/*
- * PMON really reserves 16MB of I/O port space but that's stupid, nothing
- * needs that much since allocations are limited to 256 bytes per device
- * anyway.  So we just claim 64kB here.
- */
-#define TITAN_IO_SIZE	0x0000ffffUL
-#define TITAN_IO_BASE	0xe8000000UL
-
-static struct resource py_io_resource = {
-	.start	= 0x00001000UL,
-	.end	= TITAN_IO_SIZE - 1,
-	.name	= "Titan IO MEM",
-	.flags	= IORESOURCE_IO,
-};
-
-static struct pci_controller py_controller = {
-	.pci_ops	= &titan_pci_ops,
-	.mem_resource	= &py_mem_resource,
-	.mem_offset	= 0x00000000UL,
-	.io_resource	= &py_io_resource,
-	.io_offset	= 0x00000000UL
-};
-
-static char ioremap_failed[] __initdata = "Could not ioremap I/O port range";
-
-static int __init pmc_yosemite_setup(void)
-{
-	unsigned long io_v_base;
-
-	io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
-	if (!io_v_base)
-		panic(ioremap_failed);
-
-	set_io_port_base(io_v_base);
-	py_controller.io_map_base = io_v_base;
-	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
-
-	ioport_resource.end = TITAN_IO_SIZE - 1;
-
-	register_pci_controller(&py_controller);
-
-	return 0;
-}
-
-arch_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
index bbd7608..3482b8c 100644
--- a/arch/mips/pmc-sierra/Kconfig
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -34,10 +34,6 @@
 
 endchoice
 
-config HYPERTRANSPORT
-	bool "Hypertransport Support for PMC-Sierra Yosemite"
-	depends on PMC_YOSEMITE
-
 config MSP_HAS_USB
 	boolean
 	depends on PMC_MSP
diff --git a/arch/mips/pmc-sierra/Platform b/arch/mips/pmc-sierra/Platform
index f092f25..387fda6 100644
--- a/arch/mips/pmc-sierra/Platform
+++ b/arch/mips/pmc-sierra/Platform
@@ -5,10 +5,3 @@
 cflags-$(CONFIG_PMC_MSP)	+= -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \
 					-mno-branch-likely
 load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
-
-#
-# PMC-Sierra Yosemite
-#
-platform-$(CONFIG_PMC_YOSEMITE)	+= pmc-sierra/yosemite/
-cflags-$(CONFIG_PMC_YOSEMITE)	+= -I$(srctree)/arch/mips/include/asm/mach-yosemite
-load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
deleted file mode 100644
index 5af95ec..0000000
--- a/arch/mips/pmc-sierra/yosemite/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the PMC-Sierra Titan
-#
-
-obj-y    += irq.o prom.o py-console.o setup.o
-
-obj-$(CONFIG_SMP)		+= smp.o
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
deleted file mode 100644
index d6f8bdf..0000000
--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- *  Copyright (C) 2003 PMC-Sierra Inc.
- *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Description:
- *
- * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
- * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
- * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are
- * expected to have a connectivity from the EEPROM to the serial port. This program does
- * __not__ communicate using the I2C protocol
- */
-
-#include "atmel_read_eeprom.h"
-
-static void delay(int delay)
-{
-	while (delay--);
-}
-
-static void send_bit(unsigned char bit)
-{
-	scl_lo;
-	delay(TXX);
-	if (bit)
-		sda_hi;
-	else
-		sda_lo;
-
-	delay(TXX);
-	scl_hi;
-	delay(TXX);
-}
-
-static void send_ack(void)
-{
-	send_bit(0);
-}
-
-static void send_byte(unsigned char byte)
-{
-	int	i = 0;
-
-	for (i = 7; i >= 0; i--)
-		send_bit((byte >> i) & 0x01);
-}
-
-static void send_start(void)
-{
-	sda_hi;
-	delay(TXX);
-	scl_hi;
-	delay(TXX);
-	sda_lo;
-	delay(TXX);
-}
-
-static void send_stop(void)
-{
-	sda_lo;
-	delay(TXX);
-	scl_hi;
-	delay(TXX);
-	sda_hi;
-	delay(TXX);
-}
-
-static void do_idle(void)
-{
-	sda_hi;
-	scl_hi;
-	vcc_off;
-}
-
-static int recv_bit(void)
-{
-	int	status;
-
-	scl_lo;
-	delay(TXX);
-	sda_hi;
-	delay(TXX);
-	scl_hi;
-	delay(TXX);
-
-	return 1;
-}
-
-static unsigned char recv_byte(void) {
-        int i;
-        unsigned char byte=0;
-
-        for (i=7;i>=0;i--)
-                byte |= (recv_bit() << i);
-
-        return byte;
-}
-
-static int recv_ack(void)
-{
-	unsigned int	ack;
-
-	ack = (unsigned int)recv_bit();
-	scl_lo;
-
-	if (ack) {
-		do_idle();
-		printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM\n");
-		return -1;
-	}
-
-	return ack;
-}
-
-/*
- * This function does the actual read of the EEPROM. It needs the buffer into which the
- * read data is copied, the size of the EEPROM being read and the buffer size
- */
-int read_eeprom(char *buffer, int eeprom_size, int size)
-{
-	int	i = 0, err;
-
-	send_start();
-	send_byte(W_HEADER);
-	recv_ack();
-
-	/* EEPROM with size of more than 2K need two byte addressing */
-	if (eeprom_size > 2048) {
-		send_byte(0x00);
-		recv_ack();
-	}
-
-	send_start();
-	send_byte(R_HEADER);
-	err = recv_ack();
-	if (err == -1)
-		return err;
-
-	for (i = 0; i < size; i++) {
-		*buffer++ = recv_byte();
-		send_ack();
-	}
-
-	/* Note : We should do some check if the buffer contains correct information */
-
-	send_stop();
-}
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
deleted file mode 100644
index d6c7ec4..0000000
--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
- *
- *  Copyright (C) 2003 PMC-Sierra Inc.
- *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Header file for atmel_read_eeprom.c
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <asm/pci.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <asm/termios.h>
-#include <asm/ioctls.h>
-#include <linux/ioctl.h>
-#include <linux/fcntl.h>
-
-#define	DEFAULT_PORT 	"/dev/ttyS0"	/* Port to open */
-#define	TXX		0 		/* Dummy loop for spinning */
-
-#define	BLOCK_SEL	0x00
-#define	SLAVE_ADDR	0xa0
-#define	READ_BIT	0x01
-#define	WRITE_BIT	0x00
-#define	R_HEADER	SLAVE_ADDR + BLOCK_SEL + READ_BIT
-#define	W_HEADER	SLAVE_ADDR + BLOCK_SEL + WRITE_BIT
-
-/*
- * Clock, Voltages and Data
- */
-#define	vcc_off		(ioctl(fd, TIOCSBRK, 0))
-#define	vcc_on		(ioctl(fd, TIOCCBRK, 0))
-#define	sda_hi		(ioctl(fd, TIOCMBIS, &dtr))
-#define	sda_lo		(ioctl(fd, TIOCMBIC, &dtr))
-#define	scl_lo		(ioctl(fd, TIOCMBIC, &rts))
-#define	scl_hi		(ioctl(fd, TIOCMBIS, &rts))
-
-const char rts = TIOCM_RTS;
-const char dtr = TIOCM_DTR;
-int fd;
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
deleted file mode 100644
index 62ead66..0000000
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/pci.h>
-
-/*
- * HT Bus fixup for the Titan
- * XXX IRQ values need to change based on the board layout
- */
-void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
-{
-	/*
-	 * PLX and SPKT related changes go here
-	 */
-}
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
deleted file mode 100644
index 14dc9c8..0000000
--- a/arch/mips/pmc-sierra/yosemite/ht.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <asm/pci.h>
-#include <asm/io.h>
-
-#include <linux/init.h>
-#include <asm/titan_dep.h>
-
-#ifdef CONFIG_HYPERTRANSPORT
-
-
-/*
- * This function check if the Hypertransport Link Initialization completed. If
- * it did, then proceed further with scanning bus #2
- */
-static __inline__ int check_titan_htlink(void)
-{
-        u32 val;
-
-        val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
-        if (val & 0x00000020)
-                /* HT Link Initialization completed */
-                return 1;
-        else
-                return 0;
-}
-
-static int titan_ht_config_read_dword(struct pci_dev *device,
-                                             int offset, u32* val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_READ(data_reg, val);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int titan_ht_config_read_word(struct pci_dev *device,
-                                             int offset, u16* val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        if ((offset & 0x3) == 0)
-                offset = 0x2;
-        else
-                offset = 0x0;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_READ_16(data_reg + offset, val);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-
-u32 longswap(unsigned long l)
-{
-        unsigned char b1, b2, b3, b4;
-
-        b1 = l&255;
-        b2 = (l>>8)&255;
-        b3 = (l>>16)&255;
-        b4 = (l>>24)&255;
-
-        return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
-}
-
-
-static int titan_ht_config_read_byte(struct pci_dev *device,
-                                             int offset, u8* val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-        int offset1;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        RM9K_WRITE(address_reg, address);
-
-        if ((offset & 0x3) == 0) {
-                offset1 = 0x3;
-        }
-        if ((offset & 0x3) == 1) {
-                offset1 = 0x2;
-        }
-        if ((offset & 0x3) == 2) {
-                offset1 = 0x1;
-        }
-        if ((offset & 0x3) == 3) {
-                offset1 = 0x0;
-        }
-        RM9K_READ_8(data_reg + offset1, val);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int titan_ht_config_write_dword(struct pci_dev *device,
-                                             int offset, u8 val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_WRITE(data_reg, val);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static int titan_ht_config_write_word(struct pci_dev *device,
-                                             int offset, u8 val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        if ((offset & 0x3) == 0)
-                offset = 0x2;
-        else
-                offset = 0x0;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_WRITE_16(data_reg + offset, val);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static int titan_ht_config_write_byte(struct pci_dev *device,
-                                             int offset, u8 val)
-{
-        int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-        int offset1;
-
-        bus = device->bus->number;
-        dev = PCI_SLOT(device->devfn);
-        func = PCI_FUNC(device->devfn);
-
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        RM9K_WRITE(address_reg, address);
-
-        if ((offset & 0x3) == 0) {
-             offset1 = 0x3;
-        }
-        if ((offset & 0x3) == 1) {
-             offset1 = 0x2;
-        }
-        if ((offset & 0x3) == 2) {
-             offset1 = 0x1;
-        }
-        if ((offset & 0x3) == 3) {
-            offset1 = 0x0;
-        }
-
-        RM9K_WRITE_8(data_reg + offset1, val);
-        return PCIBIOS_SUCCESSFUL;
-}
-
-
-static void titan_pcibios_set_master(struct pci_dev *dev)
-{
-        u16 cmd;
-        int bus = dev->bus->number;
-
-	if (check_titan_htlink())
-            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
-
-	cmd |= PCI_COMMAND_MASTER;
-
-	if (check_titan_htlink())
-            titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
-}
-
-
-int pcibios_enable_resources(struct pci_dev *dev)
-{
-        u16 cmd, old_cmd;
-        u8 tmp1;
-        int idx;
-        struct resource *r;
-        int bus = dev->bus->number;
-
-	if (check_titan_htlink())
-            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
-
-	old_cmd = cmd;
-        for (idx = 0; idx < 6; idx++) {
-                r = &dev->resource[idx];
-                if (!r->start && r->end) {
-                        printk(KERN_ERR
-                               "PCI: Device %s not available because of "
-                               "resource collisions\n", pci_name(dev));
-                        return -EINVAL;
-                }
-                if (r->flags & IORESOURCE_IO)
-                        cmd |= PCI_COMMAND_IO;
-                if (r->flags & IORESOURCE_MEM)
-                        cmd |= PCI_COMMAND_MEMORY;
-        }
-        if (cmd != old_cmd) {
-		if (check_titan_htlink())
-                   titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
-	}
-
-	if (check_titan_htlink())
-		titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
-
-	if (tmp1 != 8) {
-                printk(KERN_WARNING "PCI setting cache line size to 8 from "
-                       "%d\n", tmp1);
-	}
-
-	if (check_titan_htlink())
-		titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
-
-	if (check_titan_htlink())
-		titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
-
-	if (tmp1 < 32 || tmp1 == 0xff) {
-                printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
-                       tmp1);
-	}
-
-	if (check_titan_htlink())
-		titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
-
-	return 0;
-}
-
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-        return pcibios_enable_resources(dev);
-}
-
-resource_size_t pcibios_align_resource(void *data, const struct resource *res,
-				resource_size_t size, resource_size_t align)
-{
-        struct pci_dev *dev = data;
-	resource_size_t start = res->start;
-
-        if (res->flags & IORESOURCE_IO) {
-                /* We need to avoid collisions with `mirrored' VGA ports
-                   and other strange ISA hardware, so we always want the
-                   addresses kilobyte aligned.  */
-                if (size > 0x100) {
-                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
-                               " (%ld bytes)\n", pci_name(dev),
-                                dev->resource - res, size);
-                }
-
-                start = (start + 1024 - 1) & ~(1024 - 1);
-        }
-
-	return start;
-}
-
-struct pci_ops titan_pci_ops = {
-        titan_ht_config_read_byte,
-        titan_ht_config_read_word,
-        titan_ht_config_read_dword,
-        titan_ht_config_write_byte,
-        titan_ht_config_write_word,
-        titan_ht_config_write_dword
-};
-
-void __init pcibios_fixup_bus(struct pci_bus *c)
-{
-        titan_ht_pcibios_fixup_bus(c);
-}
-
-void __init pcibios_init(void)
-{
-
-        /* Reset PCI I/O and PCI MEM values */
-	/* XXX Need to add the proper values here */
-        ioport_resource.start = 0xe0000000;
-        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
-        iomem_resource.start  = 0xc0000000;
-        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
-
-	/* XXX Need to add bus values */
-        pci_scan_bus(2, &titan_pci_ops, NULL);
-        pci_scan_bus(3, &titan_pci_ops, NULL);
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
-        /* We want to use the PCI bus detection done by PMON */
-        return 0;
-}
-
-#endif /* CONFIG_HYPERTRANSPORT */
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
deleted file mode 100644
index 6590812..0000000
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2003 PMC-Sierra Inc.
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/timex.h>
-#include <linux/random.h>
-#include <linux/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/titan_dep.h>
-
-/* Hypertransport specific */
-#define IRQ_ACK_BITS            0x00000000	/* Ack bits */
-
-#define HYPERTRANSPORT_INTA     0x78		/* INTA# */
-#define HYPERTRANSPORT_INTB     0x79		/* INTB# */
-#define HYPERTRANSPORT_INTC     0x7a		/* INTC# */
-#define HYPERTRANSPORT_INTD     0x7b		/* INTD# */
-
-extern void titan_mailbox_irq(void);
-
-#ifdef CONFIG_HYPERTRANSPORT
-/*
- * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
- * For interprocessor interrupts, the best thing to do is to use the INTMSG
- * register. We use the same external interrupt line, i.e. INTB3 and monitor
- * another status bit
- */
-static void ll_ht_smp_irq_handler(int irq)
-{
-	u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
-
-	/* Ack all the bits that correspond to the interrupt sources */
-	if (status != 0)
-		OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
-
-	status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
-	if (status != 0)
-		OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
-
-#ifdef CONFIG_HT_LEVEL_TRIGGER
-	/*
-	 * Level Trigger Mode only. Send the HT EOI message back to the source.
-	 */
-	switch (status) {
-	case 0x1000000:
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
-		break;
-	case 0x2000000:
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
-		break;
-	case 0x4000000:
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
-		break;
-	case 0x8000000:
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
-		break;
-	case 0x0000001:
-		/* PLX */
-		OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20);
-		OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS);
-		break;
-	case 0xf000000:
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
-		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
-		break;
-	}
-#endif /* CONFIG_HT_LEVEL_TRIGGER */
-
-	do_IRQ(irq);
-}
-#endif
-
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int cause = read_c0_cause();
-	unsigned int status = read_c0_status();
-	unsigned int pending = cause & status;
-
-	if (pending & STATUSF_IP7) {
-		do_IRQ(7);
-	} else if (pending & STATUSF_IP2) {
-#ifdef CONFIG_HYPERTRANSPORT
-		ll_ht_smp_irq_handler(2);
-#else
-		do_IRQ(2);
-#endif
-	} else if (pending & STATUSF_IP3) {
-		do_IRQ(3);
-	} else if (pending & STATUSF_IP4) {
-		do_IRQ(4);
-	} else if (pending & STATUSF_IP5) {
-#ifdef CONFIG_SMP
-		titan_mailbox_irq();
-#else
-		do_IRQ(5);
-#endif
-	} else if (pending & STATUSF_IP6) {
-		do_IRQ(4);
-	}
-}
-
-/*
- * Initialize the next level interrupt handler
- */
-void __init arch_init_irq(void)
-{
-	clear_c0_status(ST0_IM);
-
-	mips_cpu_irq_init();
-	rm7k_cpu_irq_init();
-	rm9k_cpu_irq_init();
-}
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
deleted file mode 100644
index 6a2754c..0000000
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 2003, 2004 PMC-Sierra Inc.
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- * Copyright (C) 2004 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/smp.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/smp-ops.h>
-#include <asm/bootinfo.h>
-#include <asm/pmon.h>
-
-#ifdef CONFIG_SMP
-extern void prom_grab_secondary(void);
-#else
-#define prom_grab_secondary() do { } while (0)
-#endif
-
-#include "setup.h"
-
-struct callvectors *debug_vectors;
-
-extern unsigned long yosemite_base;
-extern unsigned long cpu_clock_freq;
-
-const char *get_system_type(void)
-{
-	return "PMC-Sierra Yosemite";
-}
-
-static void prom_cpu0_exit(void *arg)
-{
-	void *nvram = (void *) YOSEMITE_RTC_BASE;
-
-	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
-	writeb(0x84, nvram + 0xff7);
-
-	/* wait for the watchdog to go off */
-	mdelay(100 + (1000 / 16));
-
-	/* if the watchdog fails for some reason, let people know */
-	printk(KERN_NOTICE "Watchdog reset failed\n");
-}
-
-/*
- * Reset the NVRAM over the local bus
- */
-static void prom_exit(void)
-{
-#ifdef CONFIG_SMP
-	if (smp_processor_id())
-		/* CPU 1 */
-		smp_call_function(prom_cpu0_exit, NULL, 1);
-#endif
-	prom_cpu0_exit(NULL);
-}
-
-/*
- * Halt the system
- */
-static void prom_halt(void)
-{
-	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-	while (1)
-		__asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
-}
-
-extern struct plat_smp_ops yos_smp_ops;
-
-/*
- * Init routine which accepts the variables from PMON
- */
-void __init prom_init(void)
-{
-	int argc = fw_arg0;
-	char **arg = (char **) fw_arg1;
-	char **env = (char **) fw_arg2;
-	struct callvectors *cv = (struct callvectors *) fw_arg3;
-	int i = 0;
-
-	/* Callbacks for halt, restart */
-	_machine_restart = (void (*)(char *)) prom_exit;
-	_machine_halt = prom_halt;
-	pm_power_off = prom_halt;
-
-	debug_vectors = cv;
-	arcs_cmdline[0] = '\0';
-
-	/* Get the boot parameters */
-	for (i = 1; i < argc; i++) {
-		if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >=
-		    sizeof(arcs_cmdline))
-			break;
-
-		strcat(arcs_cmdline, arg[i]);
-		strcat(arcs_cmdline, " ");
-	}
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
-		strcat(arcs_cmdline, "console=ttyS0,115200");
-#endif
-
-	while (*env) {
-		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
-			yosemite_base =
-			    simple_strtol(*env + strlen("ocd_base="), NULL,
-					  16);
-
-		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0)
-			cpu_clock_freq =
-			    simple_strtol(*env + strlen("cpuclock="), NULL,
-					  10);
-
-		env++;
-	}
-
-	prom_grab_secondary();
-
-	register_smp_ops(&yos_smp_ops);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
-{
-}
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
deleted file mode 100644
index b7f1d9c..0000000
--- a/arch/mips/pmc-sierra/yosemite/py-console.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001, 2002, 2004 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <linux/termios.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-
-/* SUPERIO uart register map */
-struct yo_uartregs {
-	union {
-		volatile u8	rbr;	/* read only, DLAB == 0 */
-		volatile u8	thr;	/* write only, DLAB == 0 */
-		volatile u8	dll;	/* DLAB == 1 */
-	} u1;
-	union {
-		volatile u8	ier;	/* DLAB == 0 */
-		volatile u8	dlm;	/* DLAB == 1 */
-	} u2;
-	union {
-		volatile u8	iir;	/* read only */
-		volatile u8	fcr;	/* write only */
-	} u3;
-	volatile u8	iu_lcr;
-	volatile u8	iu_mcr;
-	volatile u8	iu_lsr;
-	volatile u8	iu_msr;
-	volatile u8	iu_scr;
-} yo_uregs_t;
-
-#define iu_rbr u1.rbr
-#define iu_thr u1.thr
-#define iu_dll u1.dll
-#define iu_ier u2.ier
-#define iu_dlm u2.dlm
-#define iu_iir u3.iir
-#define iu_fcr u3.fcr
-
-#define ssnop()		__asm__ __volatile__("sll	$0, $0, 1\n");
-#define ssnop_4()	do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
-
-#define IO_BASE_64	0x9000000000000000ULL
-
-static unsigned char readb_outer_space(unsigned long long phys)
-{
-	unsigned long long vaddr = IO_BASE_64 | phys;
-	unsigned char res;
-	unsigned int sr;
-
-	sr = read_c0_status();
-	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	ssnop_4();
-
-	__asm__ __volatile__ (
-	"	.set	mips3		\n"
-	"	ld	%0, %1		\n"
-	"	lbu	%0, (%0)	\n"
-	"	.set	mips0		\n"
-	: "=r" (res)
-	: "m" (vaddr));
-
-	write_c0_status(sr);
-	ssnop_4();
-
-	return res;
-}
-
-static void writeb_outer_space(unsigned long long phys, unsigned char c)
-{
-	unsigned long long vaddr = IO_BASE_64 | phys;
-	unsigned long tmp;
-	unsigned int sr;
-
-	sr = read_c0_status();
-	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	ssnop_4();
-
-	__asm__ __volatile__ (
-	"	.set	mips3		\n"
-	"	ld	%0, %1		\n"
-	"	sb	%2, (%0)	\n"
-	"	.set	mips0		\n"
-	: "=&r" (tmp)
-	: "m" (vaddr), "r" (c));
-
-	write_c0_status(sr);
-	ssnop_4();
-}
-
-void prom_putchar(char c)
-{
-	unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
-	unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
-
-	while ((readb_outer_space(lsr) & 0x20) == 0);
-	writeb_outer_space(thr, c);
-}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
deleted file mode 100644
index b6472fc..0000000
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- *  Copyright (C) 2003 PMC-Sierra Inc.
- *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/bcd.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/swap.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/termios.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-
-#include <asm/time.h>
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/serial.h>
-#include <asm/titan_dep.h>
-#include <asm/m48t37.h>
-
-#include "setup.h"
-
-unsigned char titan_ge_mac_addr_base[6] = {
-	// 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
-	0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
-};
-
-unsigned long cpu_clock_freq;
-unsigned long yosemite_base;
-
-static struct m48t37_rtc *m48t37_base;
-
-void __init bus_error_init(void)
-{
-	/* Do nothing */
-}
-
-
-void read_persistent_clock(struct timespec *ts)
-{
-	unsigned int year, month, day, hour, min, sec;
-	unsigned long flags;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	/* Stop the update to the time */
-	m48t37_base->control = 0x40;
-
-	year = bcd2bin(m48t37_base->year);
-	year += bcd2bin(m48t37_base->century) * 100;
-
-	month = bcd2bin(m48t37_base->month);
-	day = bcd2bin(m48t37_base->date);
-	hour = bcd2bin(m48t37_base->hour);
-	min = bcd2bin(m48t37_base->min);
-	sec = bcd2bin(m48t37_base->sec);
-
-	/* Start the update to the time again */
-	m48t37_base->control = 0x00;
-	spin_unlock_irqrestore(&rtc_lock, flags);
-
-	ts->tv_sec = mktime(year, month, day, hour, min, sec);
-	ts->tv_nsec = 0;
-}
-
-int rtc_mips_set_time(unsigned long tim)
-{
-	struct rtc_time tm;
-	unsigned long flags;
-
-	/*
-	 * Convert to a more useful format -- note months count from 0
-	 * and years from 1900
-	 */
-	rtc_time_to_tm(tim, &tm);
-	tm.tm_year += 1900;
-	tm.tm_mon += 1;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	/* enable writing */
-	m48t37_base->control = 0x80;
-
-	/* year */
-	m48t37_base->year = bin2bcd(tm.tm_year % 100);
-	m48t37_base->century = bin2bcd(tm.tm_year / 100);
-
-	/* month */
-	m48t37_base->month = bin2bcd(tm.tm_mon);
-
-	/* day */
-	m48t37_base->date = bin2bcd(tm.tm_mday);
-
-	/* hour/min/sec */
-	m48t37_base->hour = bin2bcd(tm.tm_hour);
-	m48t37_base->min = bin2bcd(tm.tm_min);
-	m48t37_base->sec = bin2bcd(tm.tm_sec);
-
-	/* day of week -- not really used, but let's keep it up-to-date */
-	m48t37_base->day = bin2bcd(tm.tm_wday + 1);
-
-	/* disable writing */
-	m48t37_base->control = 0x00;
-	spin_unlock_irqrestore(&rtc_lock, flags);
-
-	return 0;
-}
-
-void __init plat_time_init(void)
-{
-	mips_hpt_frequency = cpu_clock_freq / 2;
-mips_hpt_frequency = 33000000 * 3 * 5;
-}
-
-unsigned long ocd_base;
-
-EXPORT_SYMBOL(ocd_base);
-
-/*
- * Common setup before any secondaries are started
- */
-
-#define TITAN_UART_CLK		3686400
-#define TITAN_SERIAL_BASE_BAUD	(TITAN_UART_CLK / 16)
-#define TITAN_SERIAL_IRQ	4
-#define TITAN_SERIAL_BASE	0xfd000008UL
-
-static void __init py_map_ocd(void)
-{
-	ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
-	if (!ocd_base)
-		panic("Mapping OCD failed - game over.  Your score is 0.");
-
-	/* Kludge for PMON bug ... */
-	OCD_WRITE(0x0710, 0x0ffff029);
-}
-
-static void __init py_uart_setup(void)
-{
-#ifdef CONFIG_SERIAL_8250
-	struct uart_port up;
-
-	/*
-	 * Register to interrupt zero because we share the interrupt with
-	 * the serial driver which we don't properly support yet.
-	 */
-	memset(&up, 0, sizeof(up));
-	up.membase      = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8);
-	up.irq          = TITAN_SERIAL_IRQ;
-	up.uartclk      = TITAN_UART_CLK;
-	up.regshift     = 0;
-	up.iotype       = UPIO_MEM;
-	up.flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
-	up.line         = 0;
-
-	if (early_serial_setup(&up))
-		printk(KERN_ERR "Early serial init of port 0 failed\n");
-#endif /* CONFIG_SERIAL_8250 */
-}
-
-static void __init py_rtc_setup(void)
-{
-	m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
-	if (!m48t37_base)
-		printk(KERN_ERR "Mapping the RTC failed\n");
-}
-
-/* Not only time init but that's what the hook it's called through is named */
-static void __init py_late_time_init(void)
-{
-	py_map_ocd();
-	py_uart_setup();
-	py_rtc_setup();
-}
-
-void __init plat_mem_setup(void)
-{
-	late_time_init = py_late_time_init;
-
-	/* Add memory regions */
-	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
-
-#if 0 /* XXX Crash ...  */
-	OCD_WRITE(RM9000x2_OCD_HTSC,
-	          OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE);
-
-	/* Set the BAR. Shifted mode */
-	OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
-	OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
-#endif
-}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h
deleted file mode 100644
index 1a01abf..0000000
--- a/arch/mips/pmc-sierra/yosemite/setup.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2003, 04 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
- *
- * Board specific definititions for the PMC-Sierra Yosemite
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#ifndef __SETUP_H__
-#define __SETUP_H__
-
-/* M48T37 RTC + NVRAM */
-#define	YOSEMITE_RTC_BASE		0xfc800000
-#define	YOSEMITE_RTC_SIZE		0x00800000
-
-#define HYPERTRANSPORT_BAR0_ADDR        0x00000006
-#define HYPERTRANSPORT_SIZE0            0x0fffffff
-#define HYPERTRANSPORT_BAR0_ATTR        0x00002000
-
-#define HYPERTRANSPORT_ENABLE           0x6
-
-/*
- * EEPROM Size
- */
-#define	TITAN_ATMEL_24C32_SIZE		32768
-#define	TITAN_ATMEL_24C64_SIZE		65536
-
-#endif /* __SETUP_H__ */
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
deleted file mode 100644
index 5edab2b..0000000
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-
-#include <asm/pmon.h>
-#include <asm/titan_dep.h>
-#include <asm/time.h>
-
-#define LAUNCHSTACK_SIZE 256
-
-static __cpuinitdata arch_spinlock_t launch_lock = __ARCH_SPIN_LOCK_UNLOCKED;
-
-static unsigned long secondary_sp __cpuinitdata;
-static unsigned long secondary_gp __cpuinitdata;
-
-static unsigned char launchstack[LAUNCHSTACK_SIZE] __initdata
-	__attribute__((aligned(2 * sizeof(long))));
-
-static void __init prom_smp_bootstrap(void)
-{
-	local_irq_disable();
-
-	while (arch_spin_is_locked(&launch_lock));
-
-	__asm__ __volatile__(
-	"	move	$sp, %0		\n"
-	"	move	$gp, %1		\n"
-	"	j	smp_bootstrap	\n"
-	:
-	: "r" (secondary_sp), "r" (secondary_gp));
-}
-
-/*
- * PMON is a fragile beast.  It'll blow up once the mappings it's littering
- * right into the middle of KSEG3 are blown away so we have to grab the slave
- * core early and keep it in a waiting loop.
- */
-void __init prom_grab_secondary(void)
-{
-	arch_spin_lock(&launch_lock);
-
-	pmon_cpustart(1, &prom_smp_bootstrap,
-	              launchstack + LAUNCHSTACK_SIZE, 0);
-}
-
-void titan_mailbox_irq(void)
-{
-	int cpu = smp_processor_id();
-	unsigned long status;
-
-	switch (cpu) {
-	case 0:
-		status = OCD_READ(RM9000x2_OCD_INTP0STATUS3);
-		OCD_WRITE(RM9000x2_OCD_INTP0CLEAR3, status);
-
-		if (status & 0x2)
-			smp_call_function_interrupt();
-		if (status & 0x4)
-			scheduler_ipi();
-		break;
-
-	case 1:
-		status = OCD_READ(RM9000x2_OCD_INTP1STATUS3);
-		OCD_WRITE(RM9000x2_OCD_INTP1CLEAR3, status);
-
-		if (status & 0x2)
-			smp_call_function_interrupt();
-		if (status & 0x4)
-			scheduler_ipi();
-		break;
-	}
-}
-
-/*
- * Send inter-processor interrupt
- */
-static void yos_send_ipi_single(int cpu, unsigned int action)
-{
-	/*
-	 * Generate an INTMSG so that it can be sent over to the
-	 * destination CPU. The INTMSG will put the STATUS bits
-	 * based on the action desired. An alternative strategy
-	 * is to write to the Interrupt Set register, read the
-	 * Interrupt Status register and clear the Interrupt
-	 * Clear register. The latter is preffered.
-	 */
-	switch (action) {
-	case SMP_RESCHEDULE_YOURSELF:
-		if (cpu == 1)
-			OCD_WRITE(RM9000x2_OCD_INTP1SET3, 4);
-		else
-			OCD_WRITE(RM9000x2_OCD_INTP0SET3, 4);
-		break;
-
-	case SMP_CALL_FUNCTION:
-		if (cpu == 1)
-			OCD_WRITE(RM9000x2_OCD_INTP1SET3, 2);
-		else
-			OCD_WRITE(RM9000x2_OCD_INTP0SET3, 2);
-		break;
-	}
-}
-
-static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action)
-{
-	unsigned int i;
-
-	for_each_cpu(i, mask)
-		yos_send_ipi_single(i, action);
-}
-
-/*
- *  After we've done initial boot, this function is called to allow the
- *  board code to clean up state, if needed
- */
-static void __cpuinit yos_init_secondary(void)
-{
-}
-
-static void __cpuinit yos_smp_finish(void)
-{
-	set_c0_status(ST0_CO | ST0_IM | ST0_IE);
-}
-
-/* Hook for after all CPUs are online */
-static void yos_cpus_done(void)
-{
-}
-
-/*
- * Firmware CPU startup hook
- * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
- * It launches the next * available CPU and copies some information on the
- * stack so the first thing we do is throw away that stuff and load useful
- * values into the registers ...
- */
-static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)
-{
-	unsigned long gp = (unsigned long) task_thread_info(idle);
-	unsigned long sp = __KSTK_TOS(idle);
-
-	secondary_sp = sp;
-	secondary_gp = gp;
-
-	arch_spin_unlock(&launch_lock);
-}
-
-/*
- * Detect available CPUs, populate cpu_possible_mask before smp_init
- *
- * We don't want to start the secondary CPU yet nor do we have a nice probing
- * feature in PMON so we just assume presence of the secondary core.
- */
-static void __init yos_smp_setup(void)
-{
-	int i;
-
-	init_cpu_possible(cpu_none_mask);
-
-	for (i = 0; i < 2; i++) {
-		set_cpu_possible(i, true);
-		__cpu_number_map[i]	= i;
-		__cpu_logical_map[i]	= i;
-	}
-}
-
-static void __init yos_prepare_cpus(unsigned int max_cpus)
-{
-	/*
-	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
-	 */
-	if (num_possible_cpus())
-		set_c0_status(STATUSF_IP5);
-}
-
-struct plat_smp_ops yos_smp_ops = {
-	.send_ipi_single	= yos_send_ipi_single,
-	.send_ipi_mask		= yos_send_ipi_mask,
-	.init_secondary		= yos_init_secondary,
-	.smp_finish		= yos_smp_finish,
-	.cpus_done		= yos_cpus_done,
-	.boot_secondary		= yos_boot_secondary,
-	.smp_setup		= yos_smp_setup,
-	.prepare_cpus		= yos_prepare_cpus,
-};
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
index 1cf5abb..c697935 100644
--- a/arch/mips/powertv/init.c
+++ b/arch/mips/powertv/init.c
@@ -69,40 +69,6 @@
 	return result;
 }
 
-/* TODO: Verify on linux-mips mailing list that the following two  */
-/* functions are correct                                           */
-/* TODO: Copy NMI and EJTAG exception vectors to memory from the   */
-/* BootROM exception vectors. Flush their cache entries. test it.  */
-
-static void __init mips_nmi_setup(void)
-{
-	void *base;
-#if defined(CONFIG_CPU_MIPS32_R1)
-	base = cpu_has_veic ?
-		(void *)(CAC_BASE + 0xa80) :
-		(void *)(CAC_BASE + 0x380);
-#elif defined(CONFIG_CPU_MIPS32_R2)
-	base = (void *)0xbfc00000;
-#else
-#error NMI exception handler address not defined
-#endif
-}
-
-static void __init mips_ejtag_setup(void)
-{
-	void *base;
-
-#if defined(CONFIG_CPU_MIPS32_R1)
-	base = cpu_has_veic ?
-		(void *)(CAC_BASE + 0xa00) :
-		(void *)(CAC_BASE + 0x300);
-#elif defined(CONFIG_CPU_MIPS32_R2)
-	base = (void *)0xbfc00480;
-#else
-#error EJTAG exception handler address not defined
-#endif
-}
-
 void __init prom_init(void)
 {
 	int prom_argc;
@@ -113,9 +79,6 @@
 	_prom_envp = (int *) fw_arg2;
 	_prom_memsize = (unsigned long) fw_arg3;
 
-	board_nmi_handler_setup = mips_nmi_setup;
-	board_ejtag_handler_setup = mips_ejtag_setup;
-
 	if (prom_argc == 1) {
 		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 		strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
index d7c26d0..a757ded 100644
--- a/arch/mips/rb532/prom.c
+++ b/arch/mips/rb532/prom.c
@@ -72,12 +72,11 @@
 	static char cmd_line[COMMAND_LINE_SIZE] __initdata;
 	char *cp, *board;
 	int prom_argc;
-	char **prom_argv, **prom_envp;
+	char **prom_argv;
 	int i;
 
 	prom_argc = fw_arg0;
 	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
 
 	cp = cmd_line;
 		/* Note: it is common that parameters start
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
index da44ccb..4a6057b 100644
--- a/arch/mips/sgi-ip22/ip22-eisa.c
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -73,12 +73,10 @@
 
 static irqreturn_t ip22_eisa_intr(int irq, void *dev_id)
 {
-	u8 eisa_irq;
-	u8 dma1, dma2;
+	u8 eisa_irq = inb(EIU_INTRPT_ACK);
 
-	eisa_irq = inb(EIU_INTRPT_ACK);
-	dma1 = inb(EISA_DMA1_STATUS);
-	dma2 = inb(EISA_DMA2_STATUS);
+	inb(EISA_DMA1_STATUS);
+	inb(EISA_DMA2_STATUS);
 
 	if (eisa_irq < EISA_MAX_IRQ) {
 		do_IRQ(eisa_irq);
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index 3cd937e..01cc1a7 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -74,7 +74,7 @@
 	select SWAP_IO_SPACE
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
-	select CFE
+	select FW_CFE
 	select SYS_HAS_EARLY_PRINTK
 
 choice
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 413f17f..d6c7bd4 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -15,12 +15,12 @@
 #include <linux/fb.h>
 #include <linux/screen_info.h>
 
-#ifdef CONFIG_ARC
+#ifdef CONFIG_FW_ARC
 #include <asm/fw/arc/types.h>
 #include <asm/sgialib.h>
 #endif
 
-#ifdef CONFIG_SNIPROM
+#ifdef CONFIG_FW_SNIPROM
 #include <asm/mipsprom.h>
 #endif
 
@@ -37,7 +37,7 @@
 
 static void __init sni_display_setup(void)
 {
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC)
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC)
 	struct screen_info *si = &screen_info;
 	DISPLAY_STATUS *di;
 
@@ -56,7 +56,7 @@
 
 static void __init sni_console_setup(void)
 {
-#ifndef CONFIG_ARC
+#ifndef CONFIG_FW_ARC
 	char *ctype;
 	char *cdev;
 	char *baud;
diff --git a/arch/mips/wrppmc/pci.c b/arch/mips/wrppmc/pci.c
index d06192f..8b8a0e1 100644
--- a/arch/mips/wrppmc/pci.c
+++ b/arch/mips/wrppmc/pci.c
@@ -38,10 +38,8 @@
 
 static int __init gt64120_pci_init(void)
 {
-	u32 tmp;
-
-	tmp = GT_READ(GT_PCI0_CMD_OFS);		/* Huh??? -- Ralf  */
-	tmp = GT_READ(GT_PCI0_BARE_OFS);
+	(void) GT_READ(GT_PCI0_CMD_OFS);	/* Huh??? -- Ralf  */
+	(void) GT_READ(GT_PCI0_BARE_OFS);
 
 	/* reset the whole PCI I/O space range */
 	ioport_resource.start = GT_PCI_IO_BASE;
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index 1d61d5d..4e1194b 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -5,19 +5,22 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005 - 2009 Cavium Networks
+ * Copyright (C) 2005 - 2012 Cavium Inc.
  * Copyright (C) 2008 Wind River Systems
  */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/libata.h>
-#include <linux/irq.h>
+#include <linux/hrtimer.h>
 #include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
-#include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
 
+#include <asm/byteorder.h>
 #include <asm/octeon/octeon.h>
 
 /*
@@ -34,20 +37,36 @@
  */
 
 #define DRV_NAME	"pata_octeon_cf"
-#define DRV_VERSION	"2.1"
+#define DRV_VERSION	"2.2"
 
+/* Poll interval in nS. */
+#define OCTEON_CF_BUSY_POLL_INTERVAL 500000
+
+#define DMA_CFG 0
+#define DMA_TIM 0x20
+#define DMA_INT 0x38
+#define DMA_INT_EN 0x50
 
 struct octeon_cf_port {
-	struct workqueue_struct *wq;
-	struct delayed_work delayed_finish;
+	struct hrtimer delayed_finish;
 	struct ata_port *ap;
 	int dma_finished;
+	void		*c0;
+	unsigned int cs0;
+	unsigned int cs1;
+	bool is_true_ide;
+	u64 dma_base;
 };
 
 static struct scsi_host_template octeon_cf_sht = {
 	ATA_PIO_SHT(DRV_NAME),
 };
 
+static int enable_dma;
+module_param(enable_dma, int, 0444);
+MODULE_PARM_DESC(enable_dma,
+		 "Enable use of DMA on interfaces that support it (0=no dma [default], 1=use dma)");
+
 /**
  * Convert nanosecond based time to setting used in the
  * boot bus timing register, based on timing multiple
@@ -66,12 +85,29 @@
 	return val;
 }
 
-static void octeon_cf_set_boot_reg_cfg(int cs)
+static void octeon_cf_set_boot_reg_cfg(int cs, unsigned int multiplier)
 {
 	union cvmx_mio_boot_reg_cfgx reg_cfg;
+	unsigned int tim_mult;
+
+	switch (multiplier) {
+	case 8:
+		tim_mult = 3;
+		break;
+	case 4:
+		tim_mult = 0;
+		break;
+	case 2:
+		tim_mult = 2;
+		break;
+	default:
+		tim_mult = 1;
+		break;
+	}
+
 	reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
 	reg_cfg.s.dmack = 0;	/* Don't assert DMACK on access */
-	reg_cfg.s.tim_mult = 2;	/* Timing mutiplier 2x */
+	reg_cfg.s.tim_mult = tim_mult;	/* Timing mutiplier */
 	reg_cfg.s.rd_dly = 0;	/* Sample on falling edge of BOOT_OE */
 	reg_cfg.s.sam = 0;	/* Don't combine write and output enable */
 	reg_cfg.s.we_ext = 0;	/* No write enable extension */
@@ -92,12 +128,12 @@
  */
 static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
 {
-	struct octeon_cf_data *ocd = ap->dev->platform_data;
+	struct octeon_cf_port *cf_port = ap->private_data;
 	union cvmx_mio_boot_reg_timx reg_tim;
-	int cs = ocd->base_region;
 	int T;
 	struct ata_timing timing;
 
+	unsigned int div;
 	int use_iordy;
 	int trh;
 	int pause;
@@ -106,7 +142,15 @@
 	int t2;
 	int t2i;
 
-	T = (int)(2000000000000LL / octeon_get_clock_rate());
+	/*
+	 * A divisor value of four will overflow the timing fields at
+	 * clock rates greater than 800MHz
+	 */
+	if (octeon_get_io_clock_rate() <= 800000000)
+		div = 4;
+	else
+		div = 8;
+	T = (int)((1000000000000LL * div) / octeon_get_io_clock_rate());
 
 	if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T))
 		BUG();
@@ -121,23 +165,26 @@
 	if (t2i)
 		t2i--;
 
-	trh = ns_to_tim_reg(2, 20);
+	trh = ns_to_tim_reg(div, 20);
 	if (trh)
 		trh--;
 
-	pause = timing.cycle - timing.active - timing.setup - trh;
+	pause = (int)timing.cycle - (int)timing.active -
+		(int)timing.setup - trh;
+	if (pause < 0)
+		pause = 0;
 	if (pause)
 		pause--;
 
-	octeon_cf_set_boot_reg_cfg(cs);
-	if (ocd->dma_engine >= 0)
+	octeon_cf_set_boot_reg_cfg(cf_port->cs0, div);
+	if (cf_port->is_true_ide)
 		/* True IDE mode, program both chip selects.  */
-		octeon_cf_set_boot_reg_cfg(cs + 1);
+		octeon_cf_set_boot_reg_cfg(cf_port->cs1, div);
 
 
 	use_iordy = ata_pio_need_iordy(dev);
 
-	reg_tim.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_TIMX(cs));
+	reg_tim.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_TIMX(cf_port->cs0));
 	/* Disable page mode */
 	reg_tim.s.pagem = 0;
 	/* Enable dynamic timing */
@@ -161,20 +208,22 @@
 	/* How long read enable is asserted */
 	reg_tim.s.oe = t2;
 	/* Time after CE that read/write starts */
-	reg_tim.s.ce = ns_to_tim_reg(2, 5);
+	reg_tim.s.ce = ns_to_tim_reg(div, 5);
 	/* Time before CE that address is valid */
 	reg_tim.s.adr = 0;
 
 	/* Program the bootbus region timing for the data port chip select. */
-	cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs), reg_tim.u64);
-	if (ocd->dma_engine >= 0)
+	cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cf_port->cs0), reg_tim.u64);
+	if (cf_port->is_true_ide)
 		/* True IDE mode, program both chip selects.  */
-		cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs + 1), reg_tim.u64);
+		cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cf_port->cs1),
+			       reg_tim.u64);
 }
 
 static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev)
 {
-	struct octeon_cf_data *ocd = dev->link->ap->dev->platform_data;
+	struct octeon_cf_port *cf_port = ap->private_data;
+	union cvmx_mio_boot_pin_defs pin_defs;
 	union cvmx_mio_boot_dma_timx dma_tim;
 	unsigned int oe_a;
 	unsigned int oe_n;
@@ -183,6 +232,7 @@
 	unsigned int pause;
 	unsigned int T0, Tkr, Td;
 	unsigned int tim_mult;
+	int c;
 
 	const struct ata_timing *timing;
 
@@ -199,13 +249,19 @@
 	/* not spec'ed, value in eclocks, not affected by tim_mult */
 	dma_arq = 8;
 	pause = 25 - dma_arq * 1000 /
-		(octeon_get_clock_rate() / 1000000); /* Tz */
+		(octeon_get_io_clock_rate() / 1000000); /* Tz */
 
 	oe_a = Td;
 	/* Tkr from cf spec, lengthened to meet T0 */
 	oe_n = max(T0 - oe_a, Tkr);
 
-	dma_tim.s.dmack_pi = 1;
+	pin_defs.u64 = cvmx_read_csr(CVMX_MIO_BOOT_PIN_DEFS);
+
+	/* DMA channel number. */
+	c = (cf_port->dma_base & 8) >> 3;
+
+	/* Invert the polarity if the default is 0*/
+	dma_tim.s.dmack_pi = (pin_defs.u64 & (1ull << (11 + c))) ? 0 : 1;
 
 	dma_tim.s.oe_n = ns_to_tim_reg(tim_mult, oe_n);
 	dma_tim.s.oe_a = ns_to_tim_reg(tim_mult, oe_a);
@@ -228,14 +284,11 @@
 
 	pr_debug("ns to ticks (mult %d) of %d is: %d\n", tim_mult, 60,
 		 ns_to_tim_reg(tim_mult, 60));
-	pr_debug("oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: "
-		 "%d, dmarq: %d, pause: %d\n",
+	pr_debug("oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: %d, dmarq: %d, pause: %d\n",
 		 dma_tim.s.oe_n, dma_tim.s.oe_a, dma_tim.s.dmack_s,
 		 dma_tim.s.dmack_h, dma_tim.s.dmarq, dma_tim.s.pause);
 
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_TIMX(ocd->dma_engine),
-		       dma_tim.u64);
-
+	cvmx_write_csr(cf_port->dma_base + DMA_TIM, dma_tim.u64);
 }
 
 /**
@@ -489,15 +542,10 @@
 	ata_wait_idle(ap);
 }
 
-static void octeon_cf_irq_on(struct ata_port *ap)
+static void octeon_cf_ata_port_noaction(struct ata_port *ap)
 {
 }
 
-static void octeon_cf_irq_clear(struct ata_port *ap)
-{
-	return;
-}
-
 static void octeon_cf_dma_setup(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
@@ -519,7 +567,7 @@
  */
 static void octeon_cf_dma_start(struct ata_queued_cmd *qc)
 {
-	struct octeon_cf_data *ocd = qc->ap->dev->platform_data;
+	struct octeon_cf_port *cf_port = qc->ap->private_data;
 	union cvmx_mio_boot_dma_cfgx mio_boot_dma_cfg;
 	union cvmx_mio_boot_dma_intx mio_boot_dma_int;
 	struct scatterlist *sg;
@@ -535,15 +583,16 @@
 	 */
 	mio_boot_dma_int.u64 = 0;
 	mio_boot_dma_int.s.done = 1;
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine),
-		       mio_boot_dma_int.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_INT, mio_boot_dma_int.u64);
 
 	/* Enable the interrupt.  */
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine),
-		       mio_boot_dma_int.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_INT_EN, mio_boot_dma_int.u64);
 
 	/* Set the direction of the DMA */
 	mio_boot_dma_cfg.u64 = 0;
+#ifdef __LITTLE_ENDIAN
+	mio_boot_dma_cfg.s.endian = 1;
+#endif
 	mio_boot_dma_cfg.s.en = 1;
 	mio_boot_dma_cfg.s.rw = ((qc->tf.flags & ATA_TFLAG_WRITE) != 0);
 
@@ -569,8 +618,7 @@
 		(mio_boot_dma_cfg.s.rw) ? "write" : "read", sg->length,
 		(void *)(unsigned long)mio_boot_dma_cfg.s.adr);
 
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine),
-		       mio_boot_dma_cfg.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_CFG, mio_boot_dma_cfg.u64);
 }
 
 /**
@@ -583,10 +631,9 @@
 					struct ata_queued_cmd *qc)
 {
 	struct ata_eh_info *ehi = &ap->link.eh_info;
-	struct octeon_cf_data *ocd = ap->dev->platform_data;
+	struct octeon_cf_port *cf_port = ap->private_data;
 	union cvmx_mio_boot_dma_cfgx dma_cfg;
 	union cvmx_mio_boot_dma_intx dma_int;
-	struct octeon_cf_port *cf_port;
 	u8 status;
 
 	VPRINTK("ata%u: protocol %d task_state %d\n",
@@ -596,9 +643,7 @@
 	if (ap->hsm_task_state != HSM_ST_LAST)
 		return 0;
 
-	cf_port = ap->private_data;
-
-	dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
+	dma_cfg.u64 = cvmx_read_csr(cf_port->dma_base + DMA_CFG);
 	if (dma_cfg.s.size != 0xfffff) {
 		/* Error, the transfer was not complete.  */
 		qc->err_mask |= AC_ERR_HOST_BUS;
@@ -608,15 +653,15 @@
 	/* Stop and clear the dma engine.  */
 	dma_cfg.u64 = 0;
 	dma_cfg.s.size = -1;
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine), dma_cfg.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_CFG, dma_cfg.u64);
 
 	/* Disable the interrupt.  */
 	dma_int.u64 = 0;
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine), dma_int.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_INT_EN, dma_int.u64);
 
 	/* Clear the DMA complete status */
 	dma_int.s.done = 1;
-	cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine), dma_int.u64);
+	cvmx_write_csr(cf_port->dma_base + DMA_INT, dma_int.u64);
 
 	status = ap->ops->sff_check_status(ap);
 
@@ -649,69 +694,68 @@
 		struct ata_queued_cmd *qc;
 		union cvmx_mio_boot_dma_intx dma_int;
 		union cvmx_mio_boot_dma_cfgx dma_cfg;
-		struct octeon_cf_data *ocd;
 
 		ap = host->ports[i];
-		ocd = ap->dev->platform_data;
 		cf_port = ap->private_data;
-		dma_int.u64 =
-			cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine));
-		dma_cfg.u64 =
-			cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
+
+		dma_int.u64 = cvmx_read_csr(cf_port->dma_base + DMA_INT);
+		dma_cfg.u64 = cvmx_read_csr(cf_port->dma_base + DMA_CFG);
 
 		qc = ata_qc_from_tag(ap, ap->link.active_tag);
 
-		if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING)) {
-			if (dma_int.s.done && !dma_cfg.s.en) {
-				if (!sg_is_last(qc->cursg)) {
-					qc->cursg = sg_next(qc->cursg);
-					handled = 1;
-					octeon_cf_dma_start(qc);
-					continue;
-				} else {
-					cf_port->dma_finished = 1;
-				}
-			}
-			if (!cf_port->dma_finished)
-				continue;
-			status = ioread8(ap->ioaddr.altstatus_addr);
-			if (status & (ATA_BUSY | ATA_DRQ)) {
-				/*
-				 * We are busy, try to handle it
-				 * later.  This is the DMA finished
-				 * interrupt, and it could take a
-				 * little while for the card to be
-				 * ready for more commands.
-				 */
-				/* Clear DMA irq. */
-				dma_int.u64 = 0;
-				dma_int.s.done = 1;
-				cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine),
-					       dma_int.u64);
+		if (!qc || (qc->tf.flags & ATA_TFLAG_POLLING))
+			continue;
 
-				queue_delayed_work(cf_port->wq,
-						   &cf_port->delayed_finish, 1);
+		if (dma_int.s.done && !dma_cfg.s.en) {
+			if (!sg_is_last(qc->cursg)) {
+				qc->cursg = sg_next(qc->cursg);
 				handled = 1;
+				octeon_cf_dma_start(qc);
+				continue;
 			} else {
-				handled |= octeon_cf_dma_finished(ap, qc);
+				cf_port->dma_finished = 1;
 			}
 		}
+		if (!cf_port->dma_finished)
+			continue;
+		status = ioread8(ap->ioaddr.altstatus_addr);
+		if (status & (ATA_BUSY | ATA_DRQ)) {
+			/*
+			 * We are busy, try to handle it later.  This
+			 * is the DMA finished interrupt, and it could
+			 * take a little while for the card to be
+			 * ready for more commands.
+			 */
+			/* Clear DMA irq. */
+			dma_int.u64 = 0;
+			dma_int.s.done = 1;
+			cvmx_write_csr(cf_port->dma_base + DMA_INT,
+				       dma_int.u64);
+			hrtimer_start_range_ns(&cf_port->delayed_finish,
+					       ns_to_ktime(OCTEON_CF_BUSY_POLL_INTERVAL),
+					       OCTEON_CF_BUSY_POLL_INTERVAL / 5,
+					       HRTIMER_MODE_REL);
+			handled = 1;
+		} else {
+			handled |= octeon_cf_dma_finished(ap, qc);
+		}
 	}
 	spin_unlock_irqrestore(&host->lock, flags);
 	DPRINTK("EXIT\n");
 	return IRQ_RETVAL(handled);
 }
 
-static void octeon_cf_delayed_finish(struct work_struct *work)
+static enum hrtimer_restart octeon_cf_delayed_finish(struct hrtimer *hrt)
 {
-	struct octeon_cf_port *cf_port = container_of(work,
+	struct octeon_cf_port *cf_port = container_of(hrt,
 						      struct octeon_cf_port,
-						      delayed_finish.work);
+						      delayed_finish);
 	struct ata_port *ap = cf_port->ap;
 	struct ata_host *host = ap->host;
 	struct ata_queued_cmd *qc;
 	unsigned long flags;
 	u8 status;
+	enum hrtimer_restart rv = HRTIMER_NORESTART;
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -726,15 +770,17 @@
 	status = ioread8(ap->ioaddr.altstatus_addr);
 	if (status & (ATA_BUSY | ATA_DRQ)) {
 		/* Still busy, try again. */
-		queue_delayed_work(cf_port->wq,
-				   &cf_port->delayed_finish, 1);
+		hrtimer_forward_now(hrt,
+				    ns_to_ktime(OCTEON_CF_BUSY_POLL_INTERVAL));
+		rv = HRTIMER_RESTART;
 		goto out;
 	}
 	qc = ata_qc_from_tag(ap, ap->link.active_tag);
-	if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING))
+	if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
 		octeon_cf_dma_finished(ap, qc);
 out:
 	spin_unlock_irqrestore(&host->lock, flags);
+	return rv;
 }
 
 static void octeon_cf_dev_config(struct ata_device *dev)
@@ -786,8 +832,8 @@
 	.qc_prep		= ata_noop_qc_prep,
 	.qc_issue		= octeon_cf_qc_issue,
 	.sff_dev_select		= octeon_cf_dev_select,
-	.sff_irq_on		= octeon_cf_irq_on,
-	.sff_irq_clear		= octeon_cf_irq_clear,
+	.sff_irq_on		= octeon_cf_ata_port_noaction,
+	.sff_irq_clear		= octeon_cf_ata_port_noaction,
 	.cable_detect		= ata_cable_40wire,
 	.set_piomode		= octeon_cf_set_piomode,
 	.set_dmamode		= octeon_cf_set_dmamode,
@@ -798,46 +844,113 @@
 {
 	struct resource *res_cs0, *res_cs1;
 
+	bool is_16bit;
+	const __be32 *cs_num;
+	struct property *reg_prop;
+	int n_addr, n_size, reg_len;
+	struct device_node *node;
+	const void *prop;
 	void __iomem *cs0;
 	void __iomem *cs1 = NULL;
 	struct ata_host *host;
 	struct ata_port *ap;
-	struct octeon_cf_data *ocd;
 	int irq = 0;
 	irq_handler_t irq_handler = NULL;
 	void __iomem *base;
 	struct octeon_cf_port *cf_port;
-	char version[32];
+	int rv = -ENOMEM;
+
+
+	node = pdev->dev.of_node;
+	if (node == NULL)
+		return -EINVAL;
+
+	cf_port = kzalloc(sizeof(*cf_port), GFP_KERNEL);
+	if (!cf_port)
+		return -ENOMEM;
+
+	cf_port->is_true_ide = (of_find_property(node, "cavium,true-ide", NULL) != NULL);
+
+	prop = of_get_property(node, "cavium,bus-width", NULL);
+	if (prop)
+		is_16bit = (be32_to_cpup(prop) == 16);
+	else
+		is_16bit = false;
+
+	n_addr = of_n_addr_cells(node);
+	n_size = of_n_size_cells(node);
+
+	reg_prop = of_find_property(node, "reg", &reg_len);
+	if (!reg_prop || reg_len < sizeof(__be32)) {
+		rv = -EINVAL;
+		goto free_cf_port;
+	}
+	cs_num = reg_prop->value;
+	cf_port->cs0 = be32_to_cpup(cs_num);
+
+	if (cf_port->is_true_ide) {
+		struct device_node *dma_node;
+		dma_node = of_parse_phandle(node,
+					    "cavium,dma-engine-handle", 0);
+		if (dma_node) {
+			struct platform_device *dma_dev;
+			dma_dev = of_find_device_by_node(dma_node);
+			if (dma_dev) {
+				struct resource *res_dma;
+				int i;
+				res_dma = platform_get_resource(dma_dev, IORESOURCE_MEM, 0);
+				if (!res_dma) {
+					of_node_put(dma_node);
+					rv = -EINVAL;
+					goto free_cf_port;
+				}
+				cf_port->dma_base = (u64)devm_ioremap_nocache(&pdev->dev, res_dma->start,
+									 resource_size(res_dma));
+
+				if (!cf_port->dma_base) {
+					of_node_put(dma_node);
+					rv = -EINVAL;
+					goto free_cf_port;
+				}
+
+				irq_handler = octeon_cf_interrupt;
+				i = platform_get_irq(dma_dev, 0);
+				if (i > 0)
+					irq = i;
+			}
+			of_node_put(dma_node);
+		}
+		res_cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!res_cs1) {
+			rv = -EINVAL;
+			goto free_cf_port;
+		}
+		cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
+					   res_cs1->end - res_cs1->start + 1);
+
+		if (!cs1)
+			goto free_cf_port;
+
+		if (reg_len < (n_addr + n_size + 1) * sizeof(__be32)) {
+			rv = -EINVAL;
+			goto free_cf_port;
+		}
+		cs_num += n_addr + n_size;
+		cf_port->cs1 = be32_to_cpup(cs_num);
+	}
 
 	res_cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	if (!res_cs0)
-		return -EINVAL;
-
-	ocd = pdev->dev.platform_data;
+	if (!res_cs0) {
+		rv = -EINVAL;
+		goto free_cf_port;
+	}
 
 	cs0 = devm_ioremap_nocache(&pdev->dev, res_cs0->start,
 				   resource_size(res_cs0));
 
 	if (!cs0)
-		return -ENOMEM;
-
-	/* Determine from availability of DMA if True IDE mode or not */
-	if (ocd->dma_engine >= 0) {
-		res_cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		if (!res_cs1)
-			return -EINVAL;
-
-		cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
-					   resource_size(res_cs1));
-
-		if (!cs1)
-			return -ENOMEM;
-	}
-
-	cf_port = kzalloc(sizeof(*cf_port), GFP_KERNEL);
-	if (!cf_port)
-		return -ENOMEM;
+		goto free_cf_port;
 
 	/* allocate host */
 	host = ata_host_alloc(&pdev->dev, 1);
@@ -846,21 +959,22 @@
 
 	ap = host->ports[0];
 	ap->private_data = cf_port;
+	pdev->dev.platform_data = cf_port;
 	cf_port->ap = ap;
 	ap->ops = &octeon_cf_ops;
 	ap->pio_mask = ATA_PIO6;
 	ap->flags |= ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING;
 
-	base = cs0 + ocd->base_region_bias;
-	if (!ocd->is16bit) {
+	if (!is_16bit) {
+		base = cs0 + 0x800;
 		ap->ioaddr.cmd_addr	= base;
 		ata_sff_std_ports(&ap->ioaddr);
 
 		ap->ioaddr.altstatus_addr = base + 0xe;
 		ap->ioaddr.ctl_addr	= base + 0xe;
 		octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer8;
-	} else if (cs1) {
-		/* Presence of cs1 indicates True IDE mode.  */
+	} else if (cf_port->is_true_ide) {
+		base = cs0;
 		ap->ioaddr.cmd_addr	= base + (ATA_REG_CMD << 1) + 1;
 		ap->ioaddr.data_addr	= base + (ATA_REG_DATA << 1);
 		ap->ioaddr.error_addr	= base + (ATA_REG_ERR << 1) + 1;
@@ -876,19 +990,15 @@
 		ap->ioaddr.ctl_addr	= cs1 + (6 << 1) + 1;
 		octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16;
 
-		ap->mwdma_mask	= ATA_MWDMA4;
-		irq = platform_get_irq(pdev, 0);
-		irq_handler = octeon_cf_interrupt;
+		ap->mwdma_mask	= enable_dma ? ATA_MWDMA4 : 0;
 
-		/* True IDE mode needs delayed work to poll for not-busy.  */
-		cf_port->wq = create_singlethread_workqueue(DRV_NAME);
-		if (!cf_port->wq)
-			goto free_cf_port;
-		INIT_DELAYED_WORK(&cf_port->delayed_finish,
-				  octeon_cf_delayed_finish);
-
+		/* True IDE mode needs a timer to poll for not-busy.  */
+		hrtimer_init(&cf_port->delayed_finish, CLOCK_MONOTONIC,
+			     HRTIMER_MODE_REL);
+		cf_port->delayed_finish.function = octeon_cf_delayed_finish;
 	} else {
 		/* 16 bit but not True IDE */
+		base = cs0 + 0x800;
 		octeon_cf_ops.sff_data_xfer	= octeon_cf_data_xfer16;
 		octeon_cf_ops.softreset		= octeon_cf_softreset16;
 		octeon_cf_ops.sff_check_status	= octeon_cf_check_status16;
@@ -902,28 +1012,71 @@
 		ap->ioaddr.ctl_addr	= base + 0xe;
 		ap->ioaddr.altstatus_addr = base + 0xe;
 	}
+	cf_port->c0 = ap->ioaddr.ctl_addr;
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
 	ata_port_desc(ap, "cmd %p ctl %p", base, ap->ioaddr.ctl_addr);
 
 
-	snprintf(version, sizeof(version), "%s %d bit%s",
-		 DRV_VERSION,
-		 (ocd->is16bit) ? 16 : 8,
-		 (cs1) ? ", True IDE" : "");
-	ata_print_version_once(&pdev->dev, version);
+	dev_info(&pdev->dev, "version " DRV_VERSION" %d bit%s.\n",
+		 is_16bit ? 16 : 8,
+		 cf_port->is_true_ide ? ", True IDE" : "");
 
-	return ata_host_activate(host, irq, irq_handler, 0, &octeon_cf_sht);
+	return ata_host_activate(host, irq, irq_handler,
+				 IRQF_SHARED, &octeon_cf_sht);
 
 free_cf_port:
 	kfree(cf_port);
-	return -ENOMEM;
+	return rv;
 }
 
+static void octeon_cf_shutdown(struct device *dev)
+{
+	union cvmx_mio_boot_dma_cfgx dma_cfg;
+	union cvmx_mio_boot_dma_intx dma_int;
+
+	struct octeon_cf_port *cf_port = dev->platform_data;
+
+	if (cf_port->dma_base) {
+		/* Stop and clear the dma engine.  */
+		dma_cfg.u64 = 0;
+		dma_cfg.s.size = -1;
+		cvmx_write_csr(cf_port->dma_base + DMA_CFG, dma_cfg.u64);
+
+		/* Disable the interrupt.  */
+		dma_int.u64 = 0;
+		cvmx_write_csr(cf_port->dma_base + DMA_INT_EN, dma_int.u64);
+
+		/* Clear the DMA complete status */
+		dma_int.s.done = 1;
+		cvmx_write_csr(cf_port->dma_base + DMA_INT, dma_int.u64);
+
+		__raw_writeb(0, cf_port->c0);
+		udelay(20);
+		__raw_writeb(ATA_SRST, cf_port->c0);
+		udelay(20);
+		__raw_writeb(0, cf_port->c0);
+		mdelay(100);
+	}
+}
+
+static struct of_device_id octeon_cf_match[] = {
+	{
+		.compatible = "cavium,ebt3000-compact-flash",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, octeon_i2c_match);
+
 static struct platform_driver octeon_cf_driver = {
 	.probe		= octeon_cf_probe,
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = octeon_cf_match,
+		.shutdown = octeon_cf_shutdown
 	},
 };
 
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index a533af2..d7b56a8 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -65,6 +65,15 @@
 
 	  If unsure, say N
 
+config BCMA_DRIVER_GPIO
+	bool "BCMA GPIO driver"
+	depends on BCMA
+	select GPIOLIB
+	help
+	  Driver to provide access to the GPIO pins of the bcma bus.
+
+	  If unsure, say N
+
 config BCMA_DEBUG
 	bool "BCMA debugging"
 	depends on BCMA
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 8ad42d4..734b32f 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -6,6 +6,7 @@
 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)	+= driver_pci_host.o
 bcma-$(CONFIG_BCMA_DRIVER_MIPS)		+= driver_mips.o
 bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN)	+= driver_gmac_cmn.o
+bcma-$(CONFIG_BCMA_DRIVER_GPIO)		+= driver_gpio.o
 bcma-$(CONFIG_BCMA_HOST_PCI)		+= host_pci.o
 bcma-$(CONFIG_BCMA_HOST_SOC)		+= host_soc.o
 obj-$(CONFIG_BCMA)			+= bcma.o
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 537ae53..4a2d72e 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -91,4 +91,14 @@
 void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
 
+#ifdef CONFIG_BCMA_DRIVER_GPIO
+/* driver_gpio.c */
+int bcma_gpio_init(struct bcma_drv_cc *cc);
+#else
+static inline int bcma_gpio_init(struct bcma_drv_cc *cc)
+{
+	return -ENOTSUPP;
+}
+#endif /* CONFIG_BCMA_DRIVER_GPIO */
+
 #endif
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index dc96dd8..e461ad2 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -114,6 +114,8 @@
 	if (cc->early_setup_done)
 		return;
 
+	spin_lock_init(&cc->gpio_lock);
+
 	if (cc->core->id.rev >= 11)
 		cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
 	cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -202,28 +204,97 @@
 
 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
-	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
+	unsigned long flags;
+	u32 res;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
-	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
+	unsigned long flags;
+	u32 res;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
+/*
+ * If the bit is set to 0, chipcommon controlls this GPIO,
+ * if the bit is set to 1, it is used by some part of the chip and not our code.
+ */
 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
-	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
+	unsigned long flags;
+	u32 res;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
 
 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
-	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
+	unsigned long flags;
+	u32 res;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
-	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
+	unsigned long flags;
+	u32 res;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
+}
+
+u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res;
+
+	if (cc->core->id.rev < 20)
+		return 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
+}
+
+u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res;
+
+	if (cc->core->id.rev < 20)
+		return 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 #ifdef CONFIG_BCMA_DRIVER_MIPS
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
new file mode 100644
index 0000000..9a6f585
--- /dev/null
+++ b/drivers/bcma/driver_gpio.c
@@ -0,0 +1,98 @@
+/*
+ * Broadcom specific AMBA
+ * GPIO driver
+ *
+ * Copyright 2011, Broadcom Corporation
+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/gpio.h>
+#include <linux/export.h>
+#include <linux/bcma/bcma.h>
+
+#include "bcma_private.h"
+
+static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip)
+{
+	return container_of(chip, struct bcma_drv_cc, gpio);
+}
+
+static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	return !!bcma_chipco_gpio_in(cc, 1 << gpio);
+}
+
+static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
+				int value)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
+}
+
+static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	bcma_chipco_gpio_outen(cc, 1 << gpio, 0);
+	return 0;
+}
+
+static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+				      int value)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio);
+	bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
+	return 0;
+}
+
+static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	bcma_chipco_gpio_control(cc, 1 << gpio, 0);
+	/* clear pulldown */
+	bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0);
+	/* Set pullup */
+	bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio);
+
+	return 0;
+}
+
+static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
+{
+	struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
+
+	/* clear pullup */
+	bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
+}
+
+int bcma_gpio_init(struct bcma_drv_cc *cc)
+{
+	struct gpio_chip *chip = &cc->gpio;
+
+	chip->label		= "bcma_gpio";
+	chip->owner		= THIS_MODULE;
+	chip->request		= bcma_gpio_request;
+	chip->free		= bcma_gpio_free;
+	chip->get		= bcma_gpio_get_value;
+	chip->set		= bcma_gpio_set_value;
+	chip->direction_input	= bcma_gpio_direction_input;
+	chip->direction_output	= bcma_gpio_direction_output;
+	chip->ngpio		= 16;
+	/* There is just one SoC in one device and its GPIO addresses should be
+	 * deterministic to address them more easily. The other buses could get
+	 * a random base number. */
+	if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
+		chip->base		= 0;
+	else
+		chip->base		= -1;
+
+	return gpiochip_add(chip);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index debd4f1..53ba20c 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -164,6 +164,11 @@
 			bcma_err(bus, "Error registering NAND flash\n");
 	}
 #endif
+	err = bcma_gpio_init(&bus->drv_cc);
+	if (err == -ENOTSUPP)
+		bcma_debug(bus, "GPIO driver not activated\n");
+	else if (err)
+		bcma_err(bus, "Error registering GPIO driver: %i\n", err);
 
 	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
 		err = bcma_chipco_watchdog_register(&bus->drv_cc);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index bb82d6b..4c6c876 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -7,7 +7,7 @@
 menuconfig EDAC
 	bool "EDAC (Error Detection And Correction) reporting"
 	depends on HAS_IOMEM
-	depends on X86 || PPC || TILE || ARM
+	depends on X86 || PPC || TILE || ARM || EDAC_SUPPORT
 	help
 	  EDAC is designed to report errors in the core system.
 	  These are low-level errors that are reported in the CPU or
@@ -27,6 +27,9 @@
 	  There is also a mailing list for the EDAC project, which can
 	  be found via the sourceforge page.
 
+config EDAC_SUPPORT
+	bool
+
 if EDAC
 
 comment "Reporting subsystems"
@@ -316,4 +319,32 @@
 	  Support for error detection and correction on the
 	  Calxeda Highbank memory controller.
 
+config EDAC_OCTEON_PC
+	tristate "Cavium Octeon Primary Caches"
+	depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON
+	help
+	  Support for error detection and correction on the primary caches of
+	  the cnMIPS cores of Cavium Octeon family SOCs.
+
+config EDAC_OCTEON_L2C
+	tristate "Cavium Octeon Secondary Caches (L2C)"
+	depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON
+	help
+	  Support for error detection and correction on the
+	  Cavium Octeon family of SOCs.
+
+config EDAC_OCTEON_LMC
+	tristate "Cavium Octeon DRAM Memory Controller (LMC)"
+	depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON
+	help
+	  Support for error detection and correction on the
+	  Cavium Octeon family of SOCs.
+
+config EDAC_OCTEON_PCI
+	tristate "Cavium Octeon PCI Controller"
+	depends on EDAC_MM_EDAC && PCI && CPU_CAVIUM_OCTEON
+	help
+	  Support for error detection and correction on the
+	  Cavium Octeon family of SOCs.
+
 endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 7e5129a..5608a9b 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -58,3 +58,8 @@
 
 obj-$(CONFIG_EDAC_HIGHBANK_MC)	+= highbank_mc_edac.o
 obj-$(CONFIG_EDAC_HIGHBANK_L2)	+= highbank_l2_edac.o
+
+obj-$(CONFIG_EDAC_OCTEON_PC)		+= octeon_edac-pc.o
+obj-$(CONFIG_EDAC_OCTEON_L2C)		+= octeon_edac-l2c.o
+obj-$(CONFIG_EDAC_OCTEON_LMC)		+= octeon_edac-lmc.o
+obj-$(CONFIG_EDAC_OCTEON_PCI)		+= octeon_edac-pci.o
diff --git a/drivers/edac/octeon_edac-l2c.c b/drivers/edac/octeon_edac-l2c.c
new file mode 100644
index 0000000..40fde6a
--- /dev/null
+++ b/drivers/edac/octeon_edac-l2c.c
@@ -0,0 +1,208 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Cavium, Inc.
+ *
+ * Copyright (C) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/edac.h>
+
+#include <asm/octeon/cvmx.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+
+#define EDAC_MOD_STR "octeon-l2c"
+
+static void octeon_l2c_poll_oct1(struct edac_device_ctl_info *l2c)
+{
+	union cvmx_l2t_err l2t_err, l2t_err_reset;
+	union cvmx_l2d_err l2d_err, l2d_err_reset;
+
+	l2t_err_reset.u64 = 0;
+	l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+	if (l2t_err.s.sec_err) {
+		edac_device_handle_ce(l2c, 0, 0,
+				      "Tag Single bit error (corrected)");
+		l2t_err_reset.s.sec_err = 1;
+	}
+	if (l2t_err.s.ded_err) {
+		edac_device_handle_ue(l2c, 0, 0,
+				      "Tag Double bit error (detected)");
+		l2t_err_reset.s.ded_err = 1;
+	}
+	if (l2t_err_reset.u64)
+		cvmx_write_csr(CVMX_L2T_ERR, l2t_err_reset.u64);
+
+	l2d_err_reset.u64 = 0;
+	l2d_err.u64 = cvmx_read_csr(CVMX_L2D_ERR);
+	if (l2d_err.s.sec_err) {
+		edac_device_handle_ce(l2c, 0, 1,
+				      "Data Single bit error (corrected)");
+		l2d_err_reset.s.sec_err = 1;
+	}
+	if (l2d_err.s.ded_err) {
+		edac_device_handle_ue(l2c, 0, 1,
+				      "Data Double bit error (detected)");
+		l2d_err_reset.s.ded_err = 1;
+	}
+	if (l2d_err_reset.u64)
+		cvmx_write_csr(CVMX_L2D_ERR, l2d_err_reset.u64);
+
+}
+
+static void _octeon_l2c_poll_oct2(struct edac_device_ctl_info *l2c, int tad)
+{
+	union cvmx_l2c_err_tdtx err_tdtx, err_tdtx_reset;
+	union cvmx_l2c_err_ttgx err_ttgx, err_ttgx_reset;
+	char buf1[64];
+	char buf2[80];
+
+	err_tdtx_reset.u64 = 0;
+	err_tdtx.u64 = cvmx_read_csr(CVMX_L2C_ERR_TDTX(tad));
+	if (err_tdtx.s.dbe || err_tdtx.s.sbe ||
+	    err_tdtx.s.vdbe || err_tdtx.s.vsbe)
+		snprintf(buf1, sizeof(buf1),
+			 "type:%d, syn:0x%x, way:%d",
+			 err_tdtx.s.type, err_tdtx.s.syn, err_tdtx.s.wayidx);
+
+	if (err_tdtx.s.dbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "L2D Double bit error (detected):%s", buf1);
+		err_tdtx_reset.s.dbe = 1;
+		edac_device_handle_ue(l2c, tad, 1, buf2);
+	}
+	if (err_tdtx.s.sbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "L2D Single bit error (corrected):%s", buf1);
+		err_tdtx_reset.s.sbe = 1;
+		edac_device_handle_ce(l2c, tad, 1, buf2);
+	}
+	if (err_tdtx.s.vdbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "VBF Double bit error (detected):%s", buf1);
+		err_tdtx_reset.s.vdbe = 1;
+		edac_device_handle_ue(l2c, tad, 1, buf2);
+	}
+	if (err_tdtx.s.vsbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "VBF Single bit error (corrected):%s", buf1);
+		err_tdtx_reset.s.vsbe = 1;
+		edac_device_handle_ce(l2c, tad, 1, buf2);
+	}
+	if (err_tdtx_reset.u64)
+		cvmx_write_csr(CVMX_L2C_ERR_TDTX(tad), err_tdtx_reset.u64);
+
+	err_ttgx_reset.u64 = 0;
+	err_ttgx.u64 = cvmx_read_csr(CVMX_L2C_ERR_TTGX(tad));
+
+	if (err_ttgx.s.dbe || err_ttgx.s.sbe)
+		snprintf(buf1, sizeof(buf1),
+			 "type:%d, syn:0x%x, way:%d",
+			 err_ttgx.s.type, err_ttgx.s.syn, err_ttgx.s.wayidx);
+
+	if (err_ttgx.s.dbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "Tag Double bit error (detected):%s", buf1);
+		err_ttgx_reset.s.dbe = 1;
+		edac_device_handle_ue(l2c, tad, 0, buf2);
+	}
+	if (err_ttgx.s.sbe) {
+		snprintf(buf2, sizeof(buf2),
+			 "Tag Single bit error (corrected):%s", buf1);
+		err_ttgx_reset.s.sbe = 1;
+		edac_device_handle_ce(l2c, tad, 0, buf2);
+	}
+	if (err_ttgx_reset.u64)
+		cvmx_write_csr(CVMX_L2C_ERR_TTGX(tad), err_ttgx_reset.u64);
+}
+
+static void octeon_l2c_poll_oct2(struct edac_device_ctl_info *l2c)
+{
+	int i;
+	for (i = 0; i < l2c->nr_instances; i++)
+		_octeon_l2c_poll_oct2(l2c, i);
+}
+
+static int __devinit octeon_l2c_probe(struct platform_device *pdev)
+{
+	struct edac_device_ctl_info *l2c;
+
+	int num_tads = OCTEON_IS_MODEL(OCTEON_CN68XX) ? 4 : 1;
+
+	/* 'Tags' are block 0, 'Data' is block 1*/
+	l2c = edac_device_alloc_ctl_info(0, "l2c", num_tads, "l2c", 2, 0,
+					 NULL, 0, edac_device_alloc_index());
+	if (!l2c)
+		return -ENOMEM;
+
+	l2c->dev = &pdev->dev;
+	platform_set_drvdata(pdev, l2c);
+	l2c->dev_name = dev_name(&pdev->dev);
+
+	l2c->mod_name = "octeon-l2c";
+	l2c->ctl_name = "octeon_l2c_err";
+
+
+	if (OCTEON_IS_MODEL(OCTEON_FAM_1_PLUS)) {
+		union cvmx_l2t_err l2t_err;
+		union cvmx_l2d_err l2d_err;
+
+		l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+		l2t_err.s.sec_intena = 0;	/* We poll */
+		l2t_err.s.ded_intena = 0;
+		cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+
+		l2d_err.u64 = cvmx_read_csr(CVMX_L2D_ERR);
+		l2d_err.s.sec_intena = 0;	/* We poll */
+		l2d_err.s.ded_intena = 0;
+		cvmx_write_csr(CVMX_L2T_ERR, l2d_err.u64);
+
+		l2c->edac_check = octeon_l2c_poll_oct1;
+	} else {
+		/* OCTEON II */
+		l2c->edac_check = octeon_l2c_poll_oct2;
+	}
+
+	if (edac_device_add_device(l2c) > 0) {
+		pr_err("%s: edac_device_add_device() failed\n", __func__);
+		goto err;
+	}
+
+
+	return 0;
+
+err:
+	edac_device_free_ctl_info(l2c);
+
+	return -ENXIO;
+}
+
+static int octeon_l2c_remove(struct platform_device *pdev)
+{
+	struct edac_device_ctl_info *l2c = platform_get_drvdata(pdev);
+
+	edac_device_del_device(&pdev->dev);
+	edac_device_free_ctl_info(l2c);
+
+	return 0;
+}
+
+static struct platform_driver octeon_l2c_driver = {
+	.probe = octeon_l2c_probe,
+	.remove = octeon_l2c_remove,
+	.driver = {
+		   .name = "octeon_l2c_edac",
+	}
+};
+module_platform_driver(octeon_l2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
diff --git a/drivers/edac/octeon_edac-lmc.c b/drivers/edac/octeon_edac-lmc.c
new file mode 100644
index 0000000..33bca76
--- /dev/null
+++ b/drivers/edac/octeon_edac-lmc.c
@@ -0,0 +1,186 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/edac.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-lmcx-defs.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+
+#define OCTEON_MAX_MC 4
+
+static void octeon_lmc_edac_poll(struct mem_ctl_info *mci)
+{
+	union cvmx_lmcx_mem_cfg0 cfg0;
+	bool do_clear = false;
+	char msg[64];
+
+	cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx));
+	if (cfg0.s.sec_err || cfg0.s.ded_err) {
+		union cvmx_lmcx_fadr fadr;
+		fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));
+		snprintf(msg, sizeof(msg),
+			 "DIMM %d rank %d bank %d row %d col %d",
+			 fadr.cn30xx.fdimm, fadr.cn30xx.fbunk,
+			 fadr.cn30xx.fbank, fadr.cn30xx.frow, fadr.cn30xx.fcol);
+	}
+
+	if (cfg0.s.sec_err) {
+		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0,
+				     -1, -1, -1, msg, "");
+		cfg0.s.sec_err = -1;	/* Done, re-arm */
+		do_clear = true;
+	}
+
+	if (cfg0.s.ded_err) {
+		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
+				     -1, -1, -1, msg, "");
+		cfg0.s.ded_err = -1;	/* Done, re-arm */
+		do_clear = true;
+	}
+	if (do_clear)
+		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx), cfg0.u64);
+}
+
+static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci)
+{
+	union cvmx_lmcx_int int_reg;
+	bool do_clear = false;
+	char msg[64];
+
+	int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx));
+	if (int_reg.s.sec_err || int_reg.s.ded_err) {
+		union cvmx_lmcx_fadr fadr;
+		fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));
+		snprintf(msg, sizeof(msg),
+			 "DIMM %d rank %d bank %d row %d col %d",
+			 fadr.cn61xx.fdimm, fadr.cn61xx.fbunk,
+			 fadr.cn61xx.fbank, fadr.cn61xx.frow, fadr.cn61xx.fcol);
+	}
+
+	if (int_reg.s.sec_err) {
+		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0,
+				     -1, -1, -1, msg, "");
+		int_reg.s.sec_err = -1;	/* Done, re-arm */
+		do_clear = true;
+	}
+
+	if (int_reg.s.ded_err) {
+		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
+				     -1, -1, -1, msg, "");
+		int_reg.s.ded_err = -1;	/* Done, re-arm */
+		do_clear = true;
+	}
+	if (do_clear)
+		cvmx_write_csr(CVMX_LMCX_INT(mci->mc_idx), int_reg.u64);
+}
+
+static int __devinit octeon_lmc_edac_probe(struct platform_device *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct edac_mc_layer layers[1];
+	int mc = pdev->id;
+
+	layers[0].type = EDAC_MC_LAYER_CHANNEL;
+	layers[0].size = 1;
+	layers[0].is_virt_csrow = false;
+
+	if (OCTEON_IS_MODEL(OCTEON_FAM_1_PLUS)) {
+		union cvmx_lmcx_mem_cfg0 cfg0;
+
+		cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(0));
+		if (!cfg0.s.ecc_ena) {
+			dev_info(&pdev->dev, "Disabled (ECC not enabled)\n");
+			return 0;
+		}
+
+		mci = edac_mc_alloc(mc, ARRAY_SIZE(layers), layers, 0);
+		if (!mci)
+			return -ENXIO;
+
+		mci->pdev = &pdev->dev;
+		mci->dev_name = dev_name(&pdev->dev);
+
+		mci->mod_name = "octeon-lmc";
+		mci->ctl_name = "octeon-lmc-err";
+		mci->edac_check = octeon_lmc_edac_poll;
+
+		if (edac_mc_add_mc(mci)) {
+			dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
+			edac_mc_free(mci);
+			return -ENXIO;
+		}
+
+		cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
+		cfg0.s.intr_ded_ena = 0;	/* We poll */
+		cfg0.s.intr_sec_ena = 0;
+		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mc), cfg0.u64);
+	} else {
+		/* OCTEON II */
+		union cvmx_lmcx_int_en en;
+		union cvmx_lmcx_config config;
+
+		config.u64 = cvmx_read_csr(CVMX_LMCX_CONFIG(0));
+		if (!config.s.ecc_ena) {
+			dev_info(&pdev->dev, "Disabled (ECC not enabled)\n");
+			return 0;
+		}
+
+		mci = edac_mc_alloc(mc, ARRAY_SIZE(layers), layers, 0);
+		if (!mci)
+			return -ENXIO;
+
+		mci->pdev = &pdev->dev;
+		mci->dev_name = dev_name(&pdev->dev);
+
+		mci->mod_name = "octeon-lmc";
+		mci->ctl_name = "co_lmc_err";
+		mci->edac_check = octeon_lmc_edac_poll_o2;
+
+		if (edac_mc_add_mc(mci)) {
+			dev_err(&pdev->dev, "edac_mc_add_mc() failed\n");
+			edac_mc_free(mci);
+			return -ENXIO;
+		}
+
+		en.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mc));
+		en.s.intr_ded_ena = 0;	/* We poll */
+		en.s.intr_sec_ena = 0;
+		cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mc), en.u64);
+	}
+	platform_set_drvdata(pdev, mci);
+
+	return 0;
+}
+
+static int octeon_lmc_edac_remove(struct platform_device *pdev)
+{
+	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
+
+	edac_mc_del_mc(&pdev->dev);
+	edac_mc_free(mci);
+	return 0;
+}
+
+static struct platform_driver octeon_lmc_edac_driver = {
+	.probe = octeon_lmc_edac_probe,
+	.remove = octeon_lmc_edac_remove,
+	.driver = {
+		   .name = "octeon_lmc_edac",
+	}
+};
+module_platform_driver(octeon_lmc_edac_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
diff --git a/drivers/edac/octeon_edac-pc.c b/drivers/edac/octeon_edac-pc.c
new file mode 100644
index 0000000..14a5e57
--- /dev/null
+++ b/drivers/edac/octeon_edac-pc.c
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Cavium, Inc.
+ *
+ * Copyright (C) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/edac.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+
+#include <asm/octeon/cvmx.h>
+#include <asm/mipsregs.h>
+
+extern int register_co_cache_error_notifier(struct notifier_block *nb);
+extern int unregister_co_cache_error_notifier(struct notifier_block *nb);
+
+extern unsigned long long cache_err_dcache[NR_CPUS];
+
+struct co_cache_error {
+	struct notifier_block notifier;
+	struct edac_device_ctl_info *ed;
+};
+
+/**
+ * EDAC CPU cache error callback
+ *
+ * @event: non-zero if unrecoverable.
+ */
+static int  co_cache_error_event(struct notifier_block *this,
+	unsigned long event, void *ptr)
+{
+	struct co_cache_error *p = container_of(this, struct co_cache_error,
+						notifier);
+
+	unsigned int core = cvmx_get_core_num();
+	unsigned int cpu = smp_processor_id();
+	u64 icache_err = read_octeon_c0_icacheerr();
+	u64 dcache_err;
+
+	if (event) {
+		dcache_err = cache_err_dcache[core];
+		cache_err_dcache[core] = 0;
+	} else {
+		dcache_err = read_octeon_c0_dcacheerr();
+	}
+
+	if (icache_err & 1) {
+		edac_device_printk(p->ed, KERN_ERR,
+				   "CacheErr (Icache):%llx, core %d/cpu %d, cp0_errorepc == %lx\n",
+				   (unsigned long long)icache_err, core, cpu,
+				   read_c0_errorepc());
+		write_octeon_c0_icacheerr(0);
+		edac_device_handle_ce(p->ed, cpu, 1, "icache");
+	}
+	if (dcache_err & 1) {
+		edac_device_printk(p->ed, KERN_ERR,
+				   "CacheErr (Dcache):%llx, core %d/cpu %d, cp0_errorepc == %lx\n",
+				   (unsigned long long)dcache_err, core, cpu,
+				   read_c0_errorepc());
+		if (event)
+			edac_device_handle_ue(p->ed, cpu, 0, "dcache");
+		else
+			edac_device_handle_ce(p->ed, cpu, 0, "dcache");
+
+		/* Clear the error indication */
+		if (OCTEON_IS_MODEL(OCTEON_FAM_2))
+			write_octeon_c0_dcacheerr(1);
+		else
+			write_octeon_c0_dcacheerr(0);
+	}
+
+	return NOTIFY_STOP;
+}
+
+static int __devinit co_cache_error_probe(struct platform_device *pdev)
+{
+	struct co_cache_error *p = devm_kzalloc(&pdev->dev, sizeof(*p),
+						GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	p->notifier.notifier_call = co_cache_error_event;
+	platform_set_drvdata(pdev, p);
+
+	p->ed = edac_device_alloc_ctl_info(0, "cpu", num_possible_cpus(),
+					   "cache", 2, 0, NULL, 0,
+					   edac_device_alloc_index());
+	if (!p->ed)
+		goto err;
+
+	p->ed->dev = &pdev->dev;
+
+	p->ed->dev_name = dev_name(&pdev->dev);
+
+	p->ed->mod_name = "octeon-cpu";
+	p->ed->ctl_name = "cache";
+
+	if (edac_device_add_device(p->ed)) {
+		pr_err("%s: edac_device_add_device() failed\n", __func__);
+		goto err1;
+	}
+
+	register_co_cache_error_notifier(&p->notifier);
+
+	return 0;
+
+err1:
+	edac_device_free_ctl_info(p->ed);
+err:
+	return -ENXIO;
+}
+
+static int co_cache_error_remove(struct platform_device *pdev)
+{
+	struct co_cache_error *p = platform_get_drvdata(pdev);
+
+	unregister_co_cache_error_notifier(&p->notifier);
+	edac_device_del_device(&pdev->dev);
+	edac_device_free_ctl_info(p->ed);
+	return 0;
+}
+
+static struct platform_driver co_cache_error_driver = {
+	.probe = co_cache_error_probe,
+	.remove = co_cache_error_remove,
+	.driver = {
+		   .name = "octeon_pc_edac",
+	}
+};
+module_platform_driver(co_cache_error_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
diff --git a/drivers/edac/octeon_edac-pci.c b/drivers/edac/octeon_edac-pci.c
new file mode 100644
index 0000000..758c1ef
--- /dev/null
+++ b/drivers/edac/octeon_edac-pci.c
@@ -0,0 +1,111 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Cavium, Inc.
+ * Copyright (C) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/edac.h>
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+#include <asm/octeon/octeon.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+
+static void octeon_pci_poll(struct edac_pci_ctl_info *pci)
+{
+	union cvmx_pci_cfg01 cfg01;
+
+	cfg01.u32 = octeon_npi_read32(CVMX_NPI_PCI_CFG01);
+	if (cfg01.s.dpe) {		/* Detected parity error */
+		edac_pci_handle_pe(pci, pci->ctl_name);
+		cfg01.s.dpe = 1;		/* Reset  */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+	if (cfg01.s.sse) {
+		edac_pci_handle_npe(pci, "Signaled System Error");
+		cfg01.s.sse = 1;		/* Reset */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+	if (cfg01.s.rma) {
+		edac_pci_handle_npe(pci, "Received Master Abort");
+		cfg01.s.rma = 1;		/* Reset */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+	if (cfg01.s.rta) {
+		edac_pci_handle_npe(pci, "Received Target Abort");
+		cfg01.s.rta = 1;		/* Reset */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+	if (cfg01.s.sta) {
+		edac_pci_handle_npe(pci, "Signaled Target Abort");
+		cfg01.s.sta = 1;		/* Reset */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+	if (cfg01.s.mdpe) {
+		edac_pci_handle_npe(pci, "Master Data Parity Error");
+		cfg01.s.mdpe = 1;		/* Reset */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+	}
+}
+
+static int __devinit octeon_pci_probe(struct platform_device *pdev)
+{
+	struct edac_pci_ctl_info *pci;
+	int res = 0;
+
+	pci = edac_pci_alloc_ctl_info(0, "octeon_pci_err");
+	if (!pci)
+		return -ENOMEM;
+
+	pci->dev = &pdev->dev;
+	platform_set_drvdata(pdev, pci);
+	pci->dev_name = dev_name(&pdev->dev);
+
+	pci->mod_name = "octeon-pci";
+	pci->ctl_name = "octeon_pci_err";
+	pci->edac_check = octeon_pci_poll;
+
+	if (edac_pci_add_device(pci, 0) > 0) {
+		pr_err("%s: edac_pci_add_device() failed\n", __func__);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	edac_pci_free_ctl_info(pci);
+
+	return res;
+}
+
+static int octeon_pci_remove(struct platform_device *pdev)
+{
+	struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);
+
+	edac_pci_del_device(&pdev->dev);
+	edac_pci_free_ctl_info(pci);
+
+	return 0;
+}
+
+static struct platform_driver octeon_pci_driver = {
+	.probe = octeon_pci_probe,
+	.remove = octeon_pci_remove,
+	.driver = {
+		   .name = "octeon_pci_edac",
+	}
+};
+module_platform_driver(octeon_pci_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 42cdaa9..ff3c8a2 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -160,4 +160,13 @@
 
 	  If unsure, say N
 
+config SSB_DRIVER_GPIO
+	bool "SSB GPIO driver"
+	depends on SSB
+	select GPIOLIB
+	help
+	  Driver to provide access to the GPIO pins on the bus.
+
+	  If unsure, say N
+
 endmenu
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 656e58b..9159ba7 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -15,6 +15,7 @@
 ssb-$(CONFIG_SSB_DRIVER_EXTIF)		+= driver_extif.o
 ssb-$(CONFIG_SSB_DRIVER_PCICORE)	+= driver_pcicore.o
 ssb-$(CONFIG_SSB_DRIVER_GIGE)		+= driver_gige.o
+ssb-$(CONFIG_SSB_DRIVER_GPIO)		+= driver_gpio.o
 
 # b43 pci-ssb-bridge driver
 # Not strictly a part of SSB, but kept here for convenience
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 95c33a0..71098a7 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -349,6 +349,9 @@
 {
 	if (!cc->dev)
 		return; /* We don't have a ChipCommon */
+
+	spin_lock_init(&cc->gpio_lock);
+
 	if (cc->dev->id.revision >= 11)
 		cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
 	ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
@@ -505,28 +508,93 @@
 
 u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
-	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
-	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
-	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 EXPORT_SYMBOL(ssb_chipco_gpio_control);
 
 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
-	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
-	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
+}
+
+u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	if (cc->dev->id.revision < 20)
+		return 0xffffffff;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
+}
+
+u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	if (cc->dev->id.revision < 20)
+		return 0xffffffff;
+
+	spin_lock_irqsave(&cc->gpio_lock, flags);
+	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);
+	spin_unlock_irqrestore(&cc->gpio_lock, flags);
+
+	return res;
 }
 
 #ifdef CONFIG_SSB_SERIAL
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index 553227a..59385fd 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -138,6 +138,13 @@
 	return ticks;
 }
 
+void ssb_extif_init(struct ssb_extif *extif)
+{
+	if (!extif->dev)
+		return; /* We don't have a Extif core */
+	spin_lock_init(&extif->gpio_lock);
+}
+
 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
 {
 	return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
@@ -145,22 +152,50 @@
 
 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
 {
-	return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&extif->gpio_lock, flags);
+	res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
 				   mask, value);
+	spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
 {
-	return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&extif->gpio_lock, flags);
+	res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
 				   mask, value);
+	spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
 {
-	return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&extif->gpio_lock, flags);
+	res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
+	spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+	return res;
 }
 
 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
 {
-	return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&extif->gpio_lock, flags);
+	res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
+	spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+	return res;
 }
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c
new file mode 100644
index 0000000..97ac0a3
--- /dev/null
+++ b/drivers/ssb/driver_gpio.c
@@ -0,0 +1,176 @@
+/*
+ * Sonics Silicon Backplane
+ * GPIO driver
+ *
+ * Copyright 2011, Broadcom Corporation
+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/gpio.h>
+#include <linux/export.h>
+#include <linux/ssb/ssb.h>
+
+#include "ssb_private.h"
+
+static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
+{
+	return container_of(chip, struct ssb_bus, gpio);
+}
+
+static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);
+}
+
+static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio,
+				      int value)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
+}
+
+static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,
+					   unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);
+	return 0;
+}
+
+static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,
+					    unsigned gpio, int value)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);
+	ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
+	return 0;
+}
+
+static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);
+	/* clear pulldown */
+	ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);
+	/* Set pullup */
+	ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);
+
+	return 0;
+}
+
+static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	/* clear pullup */
+	ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
+}
+
+static int ssb_gpio_chipco_init(struct ssb_bus *bus)
+{
+	struct gpio_chip *chip = &bus->gpio;
+
+	chip->label		= "ssb_chipco_gpio";
+	chip->owner		= THIS_MODULE;
+	chip->request		= ssb_gpio_chipco_request;
+	chip->free		= ssb_gpio_chipco_free;
+	chip->get		= ssb_gpio_chipco_get_value;
+	chip->set		= ssb_gpio_chipco_set_value;
+	chip->direction_input	= ssb_gpio_chipco_direction_input;
+	chip->direction_output	= ssb_gpio_chipco_direction_output;
+	chip->ngpio		= 16;
+	/* There is just one SoC in one device and its GPIO addresses should be
+	 * deterministic to address them more easily. The other buses could get
+	 * a random base number. */
+	if (bus->bustype == SSB_BUSTYPE_SSB)
+		chip->base		= 0;
+	else
+		chip->base		= -1;
+
+	return gpiochip_add(chip);
+}
+
+#ifdef CONFIG_SSB_DRIVER_EXTIF
+
+static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
+}
+
+static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio,
+				     int value)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
+}
+
+static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
+					  unsigned gpio)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
+	return 0;
+}
+
+static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
+					   unsigned gpio, int value)
+{
+	struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+	ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
+	ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
+	return 0;
+}
+
+static int ssb_gpio_extif_init(struct ssb_bus *bus)
+{
+	struct gpio_chip *chip = &bus->gpio;
+
+	chip->label		= "ssb_extif_gpio";
+	chip->owner		= THIS_MODULE;
+	chip->get		= ssb_gpio_extif_get_value;
+	chip->set		= ssb_gpio_extif_set_value;
+	chip->direction_input	= ssb_gpio_extif_direction_input;
+	chip->direction_output	= ssb_gpio_extif_direction_output;
+	chip->ngpio		= 5;
+	/* There is just one SoC in one device and its GPIO addresses should be
+	 * deterministic to address them more easily. The other buses could get
+	 * a random base number. */
+	if (bus->bustype == SSB_BUSTYPE_SSB)
+		chip->base		= 0;
+	else
+		chip->base		= -1;
+
+	return gpiochip_add(chip);
+}
+
+#else
+static int ssb_gpio_extif_init(struct ssb_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+int ssb_gpio_init(struct ssb_bus *bus)
+{
+	if (ssb_chipco_available(&bus->chipco))
+		return ssb_gpio_chipco_init(bus);
+	else if (ssb_extif_available(&bus->extif))
+		return ssb_gpio_extif_init(bus);
+	else
+		SSB_WARN_ON(1);
+
+	return -1;
+}
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 6e0daaa..c82c5c9 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -804,7 +804,14 @@
 	if (err)
 		goto err_pcmcia_exit;
 	ssb_chipcommon_init(&bus->chipco);
+	ssb_extif_init(&bus->extif);
 	ssb_mipscore_init(&bus->mipscore);
+	err = ssb_gpio_init(bus);
+	if (err == -ENOTSUPP)
+		ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n");
+	else if (err)
+		ssb_dprintk(KERN_ERR PFX
+			   "Error registering GPIO driver: %i\n", err);
 	err = ssb_fetch_invariants(bus, get_invariants);
 	if (err) {
 		ssb_bus_may_powerdown(bus);
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 8942db1..6c10b66 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -242,4 +242,21 @@
 }
 #endif /* CONFIG_SSB_EMBEDDED */
 
+#ifdef CONFIG_SSB_DRIVER_EXTIF
+extern void ssb_extif_init(struct ssb_extif *extif);
+#else
+static inline void ssb_extif_init(struct ssb_extif *extif)
+{
+}
+#endif
+
+#ifdef CONFIG_SSB_DRIVER_GPIO
+extern int ssb_gpio_init(struct ssb_bus *bus);
+#else /* CONFIG_SSB_DRIVER_GPIO */
+static inline int ssb_gpio_init(struct ssb_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif /* CONFIG_SSB_DRIVER_GPIO */
+
 #endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 6d15966..b05afd0 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -327,9 +327,16 @@
 
 static void newport_init(struct vc_data *vc, int init)
 {
-	vc->vc_cols = newport_xsize / 8;
-	vc->vc_rows = newport_ysize / 16;
+	int cols, rows;
+
+	cols = newport_xsize / 8;
+	rows = newport_ysize / 16;
 	vc->vc_can_do_color = 1;
+	if (init) {
+		vc->vc_cols = cols;
+		vc->vc_rows = rows;
+	} else
+		vc_resize(vc, cols, rows);
 }
 
 static void newport_deinit(struct vc_data *c)
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index e513591..9a0e3fa 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -2,6 +2,7 @@
 #define LINUX_BCMA_DRIVER_CC_H_
 
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 /** ChipCommon core registers. **/
 #define BCMA_CC_ID			0x0000
@@ -574,6 +575,12 @@
 #endif /* CONFIG_BCMA_DRIVER_MIPS */
 	u32 ticks_per_ms;
 	struct platform_device *watchdog;
+
+	/* Lock for GPIO register access. */
+	spinlock_t gpio_lock;
+#ifdef CONFIG_BCMA_DRIVER_GPIO
+	struct gpio_chip gpio;
+#endif
 };
 
 /* Register access */
@@ -610,6 +617,8 @@
 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value);
+u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value);
 
 /* PMU support */
 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 1f64e3f..22958d6 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
+#include <linux/gpio.h>
 #include <linux/mod_devicetable.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
@@ -435,6 +436,9 @@
 	spinlock_t gpio_lock;
 	struct platform_device *watchdog;
 #endif /* EMBEDDED */
+#ifdef CONFIG_SSB_DRIVER_GPIO
+	struct gpio_chip gpio;
+#endif /* DRIVER_GPIO */
 
 	/* Internal-only stuff follows. Do not touch. */
 	struct list_head list;
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 38339fd..9e492be 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -590,6 +590,7 @@
 	u32 status;
 	/* Fast Powerup Delay constant */
 	u16 fast_pwrup_delay;
+	spinlock_t gpio_lock;
 	struct ssb_chipcommon_pmu pmu;
 	u32 ticks_per_ms;
 	u32 max_timer_ms;
@@ -645,6 +646,8 @@
 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value);
 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value);
 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value);
+u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value);
 
 #ifdef CONFIG_SSB_SERIAL
 extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
index 99511d0..a410e84 100644
--- a/include/linux/ssb/ssb_driver_extif.h
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -161,6 +161,7 @@
 
 struct ssb_extif {
 	struct ssb_device *dev;
+	spinlock_t gpio_lock;
 };
 
 static inline bool ssb_extif_available(struct ssb_extif *extif)