diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 6653017680ddcd0d813b074245de53c3b59310fb..1762b81fcdf2ec4a235423687865453a16196aed 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -285,6 +285,7 @@ architectures:
 - sparc64 (Return probes not yet implemented.)
 - arm
 - ppc
+- mips
 
 3. Configuring Kprobes
 
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..e322d65f33a41e0085e5d352410ca0b5c3f37e26
--- /dev/null
+++ b/arch/mips/Kbuild
@@ -0,0 +1,15 @@
+# Fail on warnings - also for files referenced in subdirs
+# -Werror can be disabled for specific files using:
+# CFLAGS_<file.o> := -Wno-error
+subdir-ccflags-y := -Werror
+
+# platform specific definitions
+include arch/mips/Kbuild.platforms
+obj-y := $(platform-y)
+
+# mips object files
+# The object files are linked as core-y files would be linked
+
+obj-y += kernel/
+obj-y += mm/
+obj-y += math-emu/
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
new file mode 100644
index 0000000000000000000000000000000000000000..78439b8a83c48418ce93e2eb4a0a0e065bca4efe
--- /dev/null
+++ b/arch/mips/Kbuild.platforms
@@ -0,0 +1,32 @@
+# All platforms listed in alphabetic order
+
+platforms += alchemy
+platforms += ar7
+platforms += bcm47xx
+platforms += bcm63xx
+platforms += cavium-octeon
+platforms += cobalt
+platforms += dec
+platforms += emma
+platforms += jazz
+platforms += jz4740
+platforms += lasat
+platforms += loongson
+platforms += mipssim
+platforms += mti-malta
+platforms += pmc-sierra
+platforms += pnx833x
+platforms += pnx8550
+platforms += powertv
+platforms += rb532
+platforms += sgi-ip22
+platforms += sgi-ip27
+platforms += sgi-ip32
+platforms += sibyte
+platforms += sni
+platforms += txx9
+platforms += vr41xx
+platforms += wrppmc
+
+# include the platform specific files
+include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index cdaae942623d0e46e96df91b4dffc21439fdf25f..36642df7d5f6117ed0d8d8fd1c991a3237ddb8b9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -10,6 +10,8 @@ config MIPS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_KPROBES
+	select HAVE_KRETPROBES
 	select RTC_LIB if !MACH_LOONGSON
 
 mainmenu "Linux/MIPS Kernel Configuration"
@@ -23,8 +25,17 @@ choice
 	prompt "System type"
 	default SGI_IP22
 
-config MACH_ALCHEMY
+config MIPS_ALCHEMY
 	bool "Alchemy processor based machines"
+	select 64BIT_PHYS_ADDR
+	select CEVT_R4K_LIB
+	select CSRC_R4K_LIB
+	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_APM_EMULATION
+	select GENERIC_GPIO
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select SYS_SUPPORTS_ZBOOT
 
 config AR7
@@ -62,6 +73,7 @@ config BCM47XX
 	select SSB_DRIVER_MIPS
 	select SSB_DRIVER_EXTIF
 	select SSB_EMBEDDED
+	select SSB_B43_PCI_BRIDGE if PCI
 	select SSB_PCICORE_HOSTMODE if PCI
 	select GENERIC_GPIO
 	select SYS_HAS_EARLY_PRINTK
@@ -162,6 +174,18 @@ config MACH_JAZZ
 	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
 	 Olivetti M700-10 workstations.
 
+config MACH_JZ4740
+	bool "Ingenic JZ4740 based machines"
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	select SYS_HAS_EARLY_PRINTK
+	select HAVE_PWM
+
 config LASAT
 	bool "LASAT Networks platforms"
 	select CEVT_R4K
@@ -686,6 +710,7 @@ endchoice
 source "arch/mips/alchemy/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
+source "arch/mips/jz4740/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
 source "arch/mips/powertv/Kconfig"
@@ -892,6 +917,9 @@ config CPU_LITTLE_ENDIAN
 
 endchoice
 
+config EXPORT_UASM
+	bool
+
 config SYS_SUPPORTS_APM_EMULATION
 	bool
 
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 0b9c01add0a06d91b49ff813f8eb127c70ae112a..f0d196090e944b1c0af943a97322d0b033ba3d57 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -130,26 +130,6 @@ cflags-$(CONFIG_CPU_R4300)	+= -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap
 cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4600 -Wa,--trap
-# only gcc >= 4.4 have the loongson-specific support
-cflags-$(CONFIG_CPU_LOONGSON2)	+= -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2E) += \
-	$(call cc-option,-march=loongson2e,-march=r4600)
-cflags-$(CONFIG_CPU_LOONGSON2F) += \
-	$(call cc-option,-march=loongson2f,-march=r4600)
-# enable the workarounds for loongson2f
-ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
-  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
-    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
-  else
-    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
-  endif
-  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
-    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
-  else
-    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
-  endif
-endif
-
 cflags-$(CONFIG_CPU_MIPS32_R1)	+= $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
 			-Wa,-mips32 -Wa,--trap
 cflags-$(CONFIG_CPU_MIPS32_R2)	+= $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -209,455 +189,7 @@ endif
 #
 # Board-dependent options and extra files
 #
-
-#
-# Texas Instruments AR7
-#
-core-$(CONFIG_AR7)		+= arch/mips/ar7/
-cflags-$(CONFIG_AR7)		+= -I$(srctree)/arch/mips/include/asm/mach-ar7
-load-$(CONFIG_AR7)		+= 0xffffffff94100000
-
-#
-# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
-#
-core-$(CONFIG_MACH_JAZZ)	+= arch/mips/jazz/
-cflags-$(CONFIG_MACH_JAZZ)	+= -I$(srctree)/arch/mips/include/asm/mach-jazz
-load-$(CONFIG_MACH_JAZZ)	+= 0xffffffff80080000
-
-#
-# Common Alchemy Au1x00 stuff
-#
-core-$(CONFIG_SOC_AU1X00)	+= arch/mips/alchemy/common/
-
-#
-# AMD Alchemy Pb1000 eval board
-#
-core-$(CONFIG_MIPS_PB1000)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1000)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1000)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1100 eval board
-#
-core-$(CONFIG_MIPS_PB1100)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1100)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1100)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1500 eval board
-#
-core-$(CONFIG_MIPS_PB1500)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1500)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1500)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1550 eval board
-#
-core-$(CONFIG_MIPS_PB1550)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1550)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1550)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1200 eval board
-#
-core-$(CONFIG_MIPS_PB1200)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1200)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1200)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Db1000 eval board
-#
-core-$(CONFIG_MIPS_DB1000)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1000)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1000)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Db1100 eval board
-#
-core-$(CONFIG_MIPS_DB1100)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1100)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1100)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Db1500 eval board
-#
-core-$(CONFIG_MIPS_DB1500)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1500)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1500)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Db1550 eval board
-#
-core-$(CONFIG_MIPS_DB1550)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1550)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1550)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Db1200 eval board
-#
-core-$(CONFIG_MIPS_DB1200)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1200)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1200)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Bosporus eval board
-#
-core-$(CONFIG_MIPS_BOSPORUS)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_BOSPORUS)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_BOSPORUS)	+= 0xffffffff80100000
-
-#
-# AMD Alchemy Mirage eval board
-#
-core-$(CONFIG_MIPS_MIRAGE)	+= arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_MIRAGE)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_MIRAGE)	+= 0xffffffff80100000
-
-#
-# 4G-Systems eval board
-#
-libs-$(CONFIG_MIPS_MTX1)	+= arch/mips/alchemy/mtx-1/
-load-$(CONFIG_MIPS_MTX1)	+= 0xffffffff80100000
-
-#
-# MyCable eval board
-#
-libs-$(CONFIG_MIPS_XXS1500)	+= arch/mips/alchemy/xxs1500/
-load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000
-
-# must be last for Alchemy systems for GPIO to work properly
-cflags-$(CONFIG_SOC_AU1X00)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00
-
-
-#
-# Cobalt Server
-#
-core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
-cflags-$(CONFIG_MIPS_COBALT)	+= -I$(srctree)/arch/mips/include/asm/mach-cobalt
-load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
-
-#
-# DECstation family
-#
-core-$(CONFIG_MACH_DECSTATION)	+= arch/mips/dec/
-cflags-$(CONFIG_MACH_DECSTATION)+= -I$(srctree)/arch/mips/include/asm/mach-dec
-libs-$(CONFIG_MACH_DECSTATION)	+= arch/mips/dec/prom/
-load-$(CONFIG_MACH_DECSTATION)	+= 0xffffffff80040000
-
-#
-# Wind River PPMC Board (4KC + GT64120)
-#
-core-$(CONFIG_WR_PPMC)		+= arch/mips/gt64120/wrppmc/
-cflags-$(CONFIG_WR_PPMC)		+= -I$(srctree)/arch/mips/include/asm/mach-wrppmc
-load-$(CONFIG_WR_PPMC)		+= 0xffffffff80100000
-
-#
-# Loongson family
-#
-core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
-cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
-                    -mno-branch-likely
-load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
-load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
-
-#
-# MIPS Malta board
-#
-core-$(CONFIG_MIPS_MALTA)	+= arch/mips/mti-malta/
-cflags-$(CONFIG_MIPS_MALTA)	+= -I$(srctree)/arch/mips/include/asm/mach-malta
-load-$(CONFIG_MIPS_MALTA)	+= 0xffffffff80100000
-all-$(CONFIG_MIPS_MALTA)	:= $(COMPRESSION_FNAME).bin
-
-#
-# MIPS SIM
-#
-core-$(CONFIG_MIPS_SIM)		+= arch/mips/mipssim/
-cflags-$(CONFIG_MIPS_SIM)	+= -I$(srctree)/arch/mips/include/asm/mach-mipssim
-load-$(CONFIG_MIPS_SIM)		+= 0x80100000
-
-#
-# PMC-Sierra MSP SOCs
-#
-core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
-cflags-$(CONFIG_PMC_MSP)	+= -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \
-					-mno-branch-likely
-load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
-
-#
-# PMC-Sierra Yosemite
-#
-core-$(CONFIG_PMC_YOSEMITE)	+= arch/mips/pmc-sierra/yosemite/
-cflags-$(CONFIG_PMC_YOSEMITE)	+= -I$(srctree)/arch/mips/include/asm/mach-yosemite
-load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
-
-#
-# LASAT platforms
-#
-core-$(CONFIG_LASAT)		+= arch/mips/lasat/
-cflags-$(CONFIG_LASAT)		+= -I$(srctree)/arch/mips/include/asm/mach-lasat
-load-$(CONFIG_LASAT)		+= 0xffffffff80000000
-
-#
-# Common VR41xx
-#
-core-$(CONFIG_MACH_VR41XX)	+= arch/mips/vr41xx/common/
-cflags-$(CONFIG_MACH_VR41XX)	+= -I$(srctree)/arch/mips/include/asm/mach-vr41xx
-
-#
-# ZAO Networks Capcella (VR4131)
-#
-load-$(CONFIG_ZAO_CAPCELLA)	+= 0xffffffff80000000
-
-#
-# Victor MP-C303/304 (VR4122)
-#
-load-$(CONFIG_VICTOR_MPC30X)	+= 0xffffffff80001000
-
-#
-# IBM WorkPad z50 (VR4121)
-#
-core-$(CONFIG_IBM_WORKPAD)	+= arch/mips/vr41xx/ibm-workpad/
-load-$(CONFIG_IBM_WORKPAD)	+= 0xffffffff80004000
-
-#
-# CASIO CASSIPEIA E-55/65 (VR4111)
-#
-core-$(CONFIG_CASIO_E55)	+= arch/mips/vr41xx/casio-e55/
-load-$(CONFIG_CASIO_E55)	+= 0xffffffff80004000
-
-#
-# TANBAC VR4131 multichip module(TB0225) and TANBAC VR4131DIMM(TB0229) (VR4131)
-#
-load-$(CONFIG_TANBAC_TB022X)	+= 0xffffffff80000000
-
-# NXP STB225
-core-$(CONFIG_SOC_PNX833X)		+= arch/mips/nxp/pnx833x/common/
-cflags-$(CONFIG_SOC_PNX833X)	+= -Iarch/mips/include/asm/mach-pnx833x
-libs-$(CONFIG_NXP_STB220)		+= arch/mips/nxp/pnx833x/stb22x/
-load-$(CONFIG_NXP_STB220)		+= 0xffffffff80001000
-libs-$(CONFIG_NXP_STB225)		+= arch/mips/nxp/pnx833x/stb22x/
-load-$(CONFIG_NXP_STB225)		+= 0xffffffff80001000
-
-#
-# Common NXP PNX8550
-#
-core-$(CONFIG_SOC_PNX8550)	+= arch/mips/nxp/pnx8550/common/
-cflags-$(CONFIG_SOC_PNX8550)	+= -I$(srctree)/arch/mips/include/asm/mach-pnx8550
-
-#
-# NXP PNX8550 JBS board
-#
-libs-$(CONFIG_PNX8550_JBS)	+= arch/mips/nxp/pnx8550/jbs/
-#cflags-$(CONFIG_PNX8550_JBS)	+= -I$(srctree)/arch/mips/include/asm/mach-pnx8550
-load-$(CONFIG_PNX8550_JBS)	+= 0xffffffff80060000
-
-# NXP PNX8550 STB810 board
-#
-libs-$(CONFIG_PNX8550_STB810)	+= arch/mips/nxp/pnx8550/stb810/
-load-$(CONFIG_PNX8550_STB810)	+= 0xffffffff80060000
-
-#
-# Common NEC EMMAXXX
-#
-core-$(CONFIG_SOC_EMMA2RH)	+= arch/mips/emma/common/
-cflags-$(CONFIG_SOC_EMMA2RH)	+= -I$(srctree)/arch/mips/include/asm/mach-emma2rh
-
-#
-# NEC EMMA2RH Mark-eins
-#
-core-$(CONFIG_NEC_MARKEINS)	+= arch/mips/emma/markeins/
-load-$(CONFIG_NEC_MARKEINS)	+= 0xffffffff88100000
-
-#
-# Cisco PowerTV Platform
-#
-core-$(CONFIG_POWERTV)		+= arch/mips/powertv/
-cflags-$(CONFIG_POWERTV)        += -I$(srctree)/arch/mips/include/asm/mach-powertv
-load-$(CONFIG_POWERTV)		+= 0xffffffff90800000
-
-#
-# SGI IP22 (Indy/Indigo2)
-#
-# Set the load address to >= 0xffffffff88069000 if you want to leave space for
-# symmon, 0xffffffff80002000 for production kernels.  Note that the value must
-# be aligned to a multiple of the kernel stack size or the handling of the
-# current variable will break so for 64-bit kernels we have to raise the start
-# address by 8kb.
-#
-core-$(CONFIG_SGI_IP22)		+= arch/mips/sgi-ip22/
-cflags-$(CONFIG_SGI_IP22)	+= -I$(srctree)/arch/mips/include/asm/mach-ip22
-ifdef CONFIG_32BIT
-load-$(CONFIG_SGI_IP22)		+= 0xffffffff88002000
-endif
-ifdef CONFIG_64BIT
-load-$(CONFIG_SGI_IP22)		+= 0xffffffff88004000
-endif
-
-#
-# SGI-IP27 (Origin200/2000)
-#
-# Set the load address to >= 0xc000000000300000 if you want to leave space for
-# symmon, 0xc00000000001c000 for production kernels.  Note that the value must
-# be 16kb aligned or the handling of the current variable will break.
-#
-ifdef CONFIG_SGI_IP27
-core-$(CONFIG_SGI_IP27)		+= arch/mips/sgi-ip27/
-cflags-$(CONFIG_SGI_IP27)	+= -I$(srctree)/arch/mips/include/asm/mach-ip27
-ifdef CONFIG_MAPPED_KERNEL
-load-$(CONFIG_SGI_IP27)		+= 0xc00000004001c000
-OBJCOPYFLAGS			:= --change-addresses=0x3fffffff80000000
-dataoffset-$(CONFIG_SGI_IP27)	+= 0x01000000
-else
-load-$(CONFIG_SGI_IP27)		+= 0xa80000000001c000
-OBJCOPYFLAGS			:= --change-addresses=0x57ffffff80000000
-endif
-endif
-
-#
-# SGI IP28 (Indigo2 R10k)
-#
-# Set the load address to >= 0xa800000020080000 if you want to leave space for
-# symmon, 0xa800000020004000 for production kernels ?  Note that the value must
-# be 16kb aligned or the handling of the current variable will break.
-# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
-#
-ifdef CONFIG_SGI_IP28
-  ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
-      $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
-  endif
-endif
-core-$(CONFIG_SGI_IP28)		+= arch/mips/sgi-ip22/
-cflags-$(CONFIG_SGI_IP28)	+= -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
-load-$(CONFIG_SGI_IP28)		+= 0xa800000020004000
-
-#
-# SGI-IP32 (O2)
-#
-# Set the load address to >= 80069000 if you want to leave space for symmon,
-# 0xffffffff80004000 for production kernels.  Note that the value must be aligned to
-# a multiple of the kernel stack size or the handling of the current variable
-# will break.
-#
-core-$(CONFIG_SGI_IP32)		+= arch/mips/sgi-ip32/
-cflags-$(CONFIG_SGI_IP32)	+= -I$(srctree)/arch/mips/include/asm/mach-ip32
-load-$(CONFIG_SGI_IP32)		+= 0xffffffff80004000
-
-#
-# Sibyte SB1250/BCM1480 SOC
-#
-# This is a LIB so that it links at the end, and initcalls are later
-# the sequence; but it is built as an object so that modules don't get
-# removed (as happens, even if they have __initcall/module_init)
-#
-core-$(CONFIG_SIBYTE_BCM112X)	+= arch/mips/sibyte/sb1250/
-core-$(CONFIG_SIBYTE_BCM112X)	+= arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM112X)	+= -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
-
-core-$(CONFIG_SIBYTE_SB1250)	+= arch/mips/sibyte/sb1250/
-core-$(CONFIG_SIBYTE_SB1250)	+= arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_SB1250)	+= -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
-
-core-$(CONFIG_SIBYTE_BCM1x55)	+= arch/mips/sibyte/bcm1480/
-core-$(CONFIG_SIBYTE_BCM1x55)	+= arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM1x55)	+= -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
-
-core-$(CONFIG_SIBYTE_BCM1x80)	+= arch/mips/sibyte/bcm1480/
-core-$(CONFIG_SIBYTE_BCM1x80)	+= arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM1x80)	+= -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
-
-#
-# Sibyte BCM91120x (Carmel) board
-# Sibyte BCM91120C (CRhine) board
-# Sibyte BCM91125C (CRhone) board
-# Sibyte BCM91125E (Rhone) board
-# Sibyte SWARM board
-# Sibyte BCM91x80 (BigSur) board
-#
-core-$(CONFIG_SIBYTE_CARMEL)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CARMEL)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_CRHINE)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CRHINE)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_CRHONE)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CRHONE)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_RHONE)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_RHONE)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_SENTOSA)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_SENTOSA)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_SWARM)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
-core-$(CONFIG_SIBYTE_BIGSUR)	+= arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_BIGSUR)	:= 0xffffffff80100000
-
-#
-# Broadcom BCM47XX boards
-#
-core-$(CONFIG_BCM47XX)		+= arch/mips/bcm47xx/
-cflags-$(CONFIG_BCM47XX)	+= -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
-load-$(CONFIG_BCM47XX)		:= 0xffffffff80001000
-
-#
-# Broadcom BCM63XX boards
-#
-core-$(CONFIG_BCM63XX)		+= arch/mips/bcm63xx/
-cflags-$(CONFIG_BCM63XX)	+= -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
-load-$(CONFIG_BCM63XX)		:= 0xffffffff80010000
-
-#
-# SNI RM
-#
-core-$(CONFIG_SNI_RM)		+= arch/mips/sni/
-cflags-$(CONFIG_SNI_RM)		+= -I$(srctree)/arch/mips/include/asm/mach-rm
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-load-$(CONFIG_SNI_RM)		+= 0xffffffff80600000
-else
-load-$(CONFIG_SNI_RM)		+= 0xffffffff80030000
-endif
-all-$(CONFIG_SNI_RM)		:= $(COMPRESSION_FNAME).ecoff
-
-#
-# Common TXx9
-#
-core-$(CONFIG_MACH_TX39XX)	+= arch/mips/txx9/generic/
-cflags-$(CONFIG_MACH_TX39XX) += -I$(srctree)/arch/mips/include/asm/mach-tx39xx
-load-$(CONFIG_MACH_TX39XX)	+= 0xffffffff80050000
-core-$(CONFIG_MACH_TX49XX)	+= arch/mips/txx9/generic/
-cflags-$(CONFIG_MACH_TX49XX) += -I$(srctree)/arch/mips/include/asm/mach-tx49xx
-load-$(CONFIG_MACH_TX49XX)	+= 0xffffffff80100000
-
-#
-# Toshiba JMR-TX3927 board
-#
-core-$(CONFIG_TOSHIBA_JMR3927)	+= arch/mips/txx9/jmr3927/
-
-#
-# Routerboard 532 board
-#
-core-$(CONFIG_MIKROTIK_RB532)	+= arch/mips/rb532/
-cflags-$(CONFIG_MIKROTIK_RB532) += -I$(srctree)/arch/mips/include/asm/mach-rc32434
-load-$(CONFIG_MIKROTIK_RB532)	+= 0xffffffff80101000
-
-#
-# Toshiba RBTX49XX boards
-#
-core-$(CONFIG_TOSHIBA_RBTX4927)	+= arch/mips/txx9/rbtx4927/
-core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/
-core-$(CONFIG_TOSHIBA_RBTX4939) += arch/mips/txx9/rbtx4939/
-
-#
-# Cavium Octeon
-#
-core-$(CONFIG_CPU_CAVIUM_OCTEON)	+= arch/mips/cavium-octeon/
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON)	+= -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
-core-$(CONFIG_CPU_CAVIUM_OCTEON)	+= arch/mips/cavium-octeon/executive/
-ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
-load-$(CONFIG_CPU_CAVIUM_OCTEON)	+= 0xffffffff84100000
-else
-load-$(CONFIG_CPU_CAVIUM_OCTEON) 	+= 0xffffffff81100000
-endif
+include $(srctree)/arch/mips/Kbuild.platforms
 
 cflags-y			+= -I$(srctree)/arch/mips/include/asm/mach-generic
 drivers-$(CONFIG_PCI)		+= arch/mips/pci/
@@ -706,7 +238,8 @@ head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
 
 libs-y			+= arch/mips/lib/
 
-core-y			+= arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
+# See arch/mips/Kbuild for content of core part of the kernel
+core-y += arch/mips/
 
 drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
 
@@ -726,6 +259,9 @@ endif
 vmlinux.32: vmlinux
 	$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
 
+
+#obj-$(CONFIG_KPROBES)		+= kprobes.o
+
 #
 # The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
 # ELF files from 32-bit files by conversion.
@@ -733,35 +269,19 @@ vmlinux.32: vmlinux
 vmlinux.64: vmlinux
 	$(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
 
-makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
-makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
-	   VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1)
-
 all:	$(all-y)
 
-vmlinuz: vmlinux FORCE
-	+@$(call makezboot,$@)
+# boot
+vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE
+	$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@
 
-vmlinuz.bin: vmlinux
-	+@$(call makezboot,$@)
+# boot/compressed
+vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE
+	$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
+	   VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@
 
-vmlinuz.ecoff: vmlinux
-	+@$(call makezboot,$@)
 
-vmlinuz.srec: vmlinux
-	+@$(call makezboot,$@)
-
-vmlinux.bin: $(vmlinux-32)
-	+@$(call makeboot,$@)
-
-vmlinux.ecoff: $(vmlinux-32)
-	+@$(call makeboot,$@)
-
-vmlinux.srec: $(vmlinux-32)
-	+@$(call makeboot,$@)
-
-CLEAN_FILES += vmlinux.ecoff \
-	       vmlinux.srec
+CLEAN_FILES += vmlinux.32 vmlinux.64
 
 archprepare:
 ifdef CONFIG_MIPS32_N32
@@ -780,9 +300,9 @@ install:
 	$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
 
 archclean:
-	@$(MAKE) $(clean)=arch/mips/boot
-	@$(MAKE) $(clean)=arch/mips/boot/compressed
-	@$(MAKE) $(clean)=arch/mips/lasat
+	$(Q)$(MAKE) $(clean)=arch/mips/boot
+	$(Q)$(MAKE) $(clean)=arch/mips/boot/compressed
+	$(Q)$(MAKE) $(clean)=arch/mips/lasat
 
 define archhelp
 	echo '  install              - install kernel into $(INSTALL_PATH)'
@@ -796,11 +316,3 @@ define archhelp
 	echo
 	echo '  These will be default as apropriate for a configured platform.'
 endef
-
-CLEAN_FILES += vmlinux.32 \
-	       vmlinux.64 \
-	       vmlinux.ecoff \
-	       vmlinuz \
-	       vmlinuz.ecoff \
-	       vmlinuz.bin \
-	       vmlinuz.srec
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index df3b1a7eb15d98b7d5643ee940aef5a90d04bd9a..2ccfd4a135bce633d3fcefba360faeceeae3724e 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -11,7 +11,7 @@ config ALCHEMY_GPIO_INDIRECT
 
 choice
 	prompt "Machine type"
-	depends on MACH_ALCHEMY
+	depends on MIPS_ALCHEMY
 	default MIPS_DB1000
 
 config MIPS_MTX1
@@ -128,41 +128,33 @@ config MIPS_XXS1500
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_HAS_EARLY_PRINTK
 
+config MIPS_GPR
+	bool "Trapeze ITS GPR board"
+	select SOC_AU1550
+	select HW_HAS_PCI
+	select DMA_NONCOHERENT
+	select MIPS_DISABLE_OBSOLETE_IDE
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
+
 endchoice
 
 config SOC_AU1000
 	bool
-	select SOC_AU1X00
 	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1100
 	bool
-	select SOC_AU1X00
 	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1500
 	bool
-	select SOC_AU1X00
 	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1550
 	bool
-	select SOC_AU1X00
 	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1200
 	bool
-	select SOC_AU1X00
 	select ALCHEMY_GPIOINT_AU1000
-
-config SOC_AU1X00
-	bool
-	select 64BIT_PHYS_ADDR
-	select CEVT_R4K_LIB
-	select CSRC_R4K_LIB
-	select IRQ_CPU
-	select SYS_HAS_CPU_MIPS32_R1
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_APM_EMULATION
-	select GENERIC_GPIO
-	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..96e9e41f1b2afd4354776d7772eae0d9a9580df1
--- /dev/null
+++ b/arch/mips/alchemy/Platform
@@ -0,0 +1,114 @@
+#
+# Core Alchemy code
+#
+platform-$(CONFIG_MIPS_ALCHEMY)	+= alchemy/common/
+
+
+#
+# AMD Alchemy Pb1000 eval board
+#
+platform-$(CONFIG_MIPS_PB1000)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1000)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1000)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1100 eval board
+#
+platform-$(CONFIG_MIPS_PB1100)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1100)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1100)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1500 eval board
+#
+platform-$(CONFIG_MIPS_PB1500)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1500)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1500)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1550 eval board
+#
+platform-$(CONFIG_MIPS_PB1550)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1550)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1550)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1200 eval board
+#
+platform-$(CONFIG_MIPS_PB1200)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1200)	+= -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1200)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1000 eval board
+#
+platform-$(CONFIG_MIPS_DB1000)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1000)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1000)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1100 eval board
+#
+platform-$(CONFIG_MIPS_DB1100)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1100)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1100)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1500 eval board
+#
+platform-$(CONFIG_MIPS_DB1500)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1500)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1500)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1550 eval board
+#
+platform-$(CONFIG_MIPS_DB1550)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1550)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1550)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1200 eval board
+#
+platform-$(CONFIG_MIPS_DB1200)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1200)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1200)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Bosporus eval board
+#
+platform-$(CONFIG_MIPS_BOSPORUS) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_BOSPORUS)	 += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_BOSPORUS)	 += 0xffffffff80100000
+
+#
+# AMD Alchemy Mirage eval board
+#
+platform-$(CONFIG_MIPS_MIRAGE)	+= alchemy/devboards/
+cflags-$(CONFIG_MIPS_MIRAGE)	+= -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_MIRAGE)	+= 0xffffffff80100000
+
+#
+# 4G-Systems eval board
+#
+platform-$(CONFIG_MIPS_MTX1)	+= alchemy/mtx-1/
+load-$(CONFIG_MIPS_MTX1)	+= 0xffffffff80100000
+
+#
+# MyCable eval board
+#
+platform-$(CONFIG_MIPS_XXS1500)	+= alchemy/xxs1500/
+load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000
+
+#
+# Trapeze ITS GRP board
+#
+platform-$(CONFIG_MIPS_GPR)	+= alchemy/gpr/
+load-$(CONFIG_MIPS_GPR)		+= 0xffffffff80100000
+
+# boards can specify their own <gpio.h> in one of their include dirs.
+# If they do, placing this line here at the end will make sure the
+# compiler picks the board one.  If they don't, it will make sure
+# the alchemy generic gpio header is picked up.
+
+cflags-$(CONFIG_MIPS_ALCHEMY)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index 06c0e65a54b5e079c1fd4f52ed71e289e68874c9..27811fe341d6e732353a55243ee7b49d916eb482 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -18,5 +18,3 @@ ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
 endif
 
 obj-$(CONFIG_PCI)		+= pci.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c
index 460c6285c1bbe00cda3f0f89b2da1b5867d6f223..af0fe41055af7eb421bf08fabc2959d282842f53 100644
--- a/arch/mips/alchemy/common/clocks.c
+++ b/arch/mips/alchemy/common/clocks.c
@@ -89,11 +89,7 @@ unsigned long au1xxx_calc_clock(void)
 	 * over backwards trying to determine the frequency.
 	 */
 	if (au1xxx_cpu_has_pll_wo())
-#ifdef CONFIG_SOC_AU1000_FREQUENCY
-		cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
-#else
 		cpu_speed = 396000000;
-#endif
 	else
 		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
 
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index f9e5622ebc95b8e37a42ac96d3556176c44b11c9..1dc55ee2681b01ee5841524083c78b2360245966 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/init.h>
@@ -21,6 +22,8 @@
 #include <asm/mach-au1x00/au1100_mmc.h>
 #include <asm/mach-au1x00/au1xxx_eth.h>
 
+#include <prom.h>
+
 #define PORT(_base, _irq)					\
 	{							\
 		.mapbase	= _base,			\
@@ -33,7 +36,6 @@
 	}
 
 static struct plat_serial8250_port au1x00_uart_data[] = {
-#if defined(CONFIG_SERIAL_8250_AU1X00)
 #if defined(CONFIG_SOC_AU1000)
 	PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
 	PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
@@ -54,7 +56,6 @@ static struct plat_serial8250_port au1x00_uart_data[] = {
 	PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
 	PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
 #endif
-#endif	/* CONFIG_SERIAL_8250_AU1X00 */
 	{ },
 };
 
@@ -436,17 +437,27 @@ static int __init au1xxx_platform_init(void)
 {
 	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
 	int err, i;
+	unsigned char ethaddr[6];
 
 	/* Fill up uartclk. */
 	for (i = 0; au1x00_uart_data[i].flags; i++)
 		au1x00_uart_data[i].uartclk = uartclk;
 
+	/* use firmware-provided mac addr if available and necessary */
+	i = prom_get_ethernet_addr(ethaddr);
+	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
+		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
+
 	err = platform_add_devices(au1xxx_platform_devices,
 				   ARRAY_SIZE(au1xxx_platform_devices));
 #ifndef CONFIG_SOC_AU1100
+	ethaddr[5] += 1;	/* next addr for 2nd MAC */
+	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
+		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
+
 	/* Register second MAC if enabled in pinfunc */
 	if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
-		platform_device_register(&au1xxx_eth1_device);
+		err = platform_device_register(&au1xxx_eth1_device);
 #endif
 
 	return err;
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index ecbd37f9ee873f77b37d52d11d1532c67cb80afa..826449c817c3acef53919a17b4d73b60e449f8d3 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -16,5 +16,3 @@ obj-$(CONFIG_MIPS_DB1500)	+= db1x00/
 obj-$(CONFIG_MIPS_DB1550)	+= db1x00/
 obj-$(CONFIG_MIPS_BOSPORUS)	+= db1x00/
 obj-$(CONFIG_MIPS_MIRAGE)	+= db1x00/
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
index 3cb95a98ab31bc107b3a994401841c9189efa251..3fa34c3abc0408a04d668c262e03360506b4d861 100644
--- a/arch/mips/alchemy/devboards/db1200/platform.c
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -216,14 +216,14 @@ static struct resource db1200_ide_res[] = {
 	}
 };
 
-static u64 ide_dmamask = DMA_32BIT_MASK;
+static u64 ide_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device db1200_ide_dev = {
 	.name		= "au1200-ide",
 	.id		= 0,
 	.dev = {
 		.dma_mask 		= &ide_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(db1200_ide_res),
 	.resource	= db1200_ide_res,
@@ -385,12 +385,12 @@ static struct au1550_spi_info db1200_spi_platdata = {
 	.activate_cs	= db1200_spi_cs_en,
 };
 
-static u64 spi_dmamask = DMA_32BIT_MASK;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device db1200_spi_dev = {
 	.dev	= {
 		.dma_mask		= &spi_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.platform_data		= &db1200_spi_platdata,
 	},
 	.name		= "au1550-spi",
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index 50c9bef99daa58e93842cfd87926e3bcd07dd5be..9e45971343edcd3a751f470bbefdce595e1e0adf 100644
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -79,7 +79,6 @@ static struct au1000_eth_platform_data eth0_pdata = {
 
 static void bosporus_power_off(void)
 {
-	printk(KERN_INFO "It's now safe to turn off power\n");
 	while (1)
 		asm volatile (".set mips3 ; wait ; .set mips0");
 }
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
index 4ef50d86b18127c0dae904127cba9bec5c31520c..f6540ec47a64412d982aee01f9e92acd161d363c 100644
--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -47,9 +47,11 @@ static void board_reset(char *c)
 
 static void board_power_off(void)
 {
-	printk(KERN_ALERT "It's now safe to remove power\n");
 	while (1)
-		asm volatile (".set mips3 ; wait ; .set mips1");
+		asm volatile (
+		"	.set	mips32					\n"
+		"	wait						\n"
+		"	.set	mips0					\n");
 }
 
 void __init board_setup(void)
diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
index 2ea9b02ef09f4c9f0ca25c1ea23fae3af7e63a7c..18c1bd53e4c0e5464b972fc994c0838c5fd75cb0 100644
--- a/arch/mips/alchemy/devboards/pb1200/Makefile
+++ b/arch/mips/alchemy/devboards/pb1200/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y := board_setup.o platform.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/gpr/Makefile b/arch/mips/alchemy/gpr/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..cb73fe256dce2ad0d46606ed0d06cfc4ce3134f3
--- /dev/null
+++ b/arch/mips/alchemy/gpr/Makefile
@@ -0,0 +1,8 @@
+#
+#  Copyright 2003 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for Trapeze ITS GPR board.
+#
+
+obj-y += board_setup.o init.o platform.o
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..ad2e3f1379338e1d209d73d0276825df8cc97d28
--- /dev/null
+++ b/arch/mips/alchemy/gpr/board_setup.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
+ *
+ * Copyright 2000-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+#define UART1_ADDR	KSEG1ADDR(UART1_PHYS_ADDR)
+#define UART3_ADDR	KSEG1ADDR(UART3_PHYS_ADDR)
+
+char irq_tab_alchemy[][5] __initdata = {
+	[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
+};
+
+static void gpr_reset(char *c)
+{
+	/* switch System-LED to orange (red# and green# on) */
+	alchemy_gpio_direction_output(4, 0);
+	alchemy_gpio_direction_output(5, 0);
+
+	/* trigger watchdog to reset board in 200ms */
+	printk(KERN_EMERG "Triggering watchdog soft reset...\n");
+	raw_local_irq_disable();
+	alchemy_gpio_direction_output(1, 0);
+	udelay(1);
+	alchemy_gpio_set_value(1, 1);
+	while (1)
+		cpu_wait();
+}
+
+static void gpr_power_off(void)
+{
+	while (1)
+		cpu_wait();
+}
+
+void __init board_setup(void)
+{
+	printk(KERN_INFO "Tarpeze ITS GPR board\n");
+
+	pm_power_off = gpr_power_off;
+	_machine_halt = gpr_power_off;
+	_machine_restart = gpr_reset;
+
+	/* Enable UART3 */
+	au_writel(0x1, UART3_ADDR + UART_MOD_CNTRL);/* clock enable (CE) */
+	au_writel(0x3, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
+	/* Enable UART1 */
+	au_writel(0x1, UART1_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
+	au_writel(0x3, UART1_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
+
+	/* Take away Reset of UMTS-card */
+	alchemy_gpio_direction_output(215, 1);
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+#endif
+}
diff --git a/arch/mips/alchemy/gpr/init.c b/arch/mips/alchemy/gpr/init.c
new file mode 100644
index 0000000000000000000000000000000000000000..f044f4c541d7a78f06244245c280ced4ba66d16a
--- /dev/null
+++ b/arch/mips/alchemy/gpr/init.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+	return "GPR";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
+
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str)
+		memsize = 0x04000000;
+	else
+		strict_strtoul(memsize_str, 0, &memsize);
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/alchemy/gpr/platform.c b/arch/mips/alchemy/gpr/platform.c
new file mode 100644
index 0000000000000000000000000000000000000000..14b46629cfc81cb1a23c5665f759cb89b76cbfa0
--- /dev/null
+++ b/arch/mips/alchemy/gpr/platform.c
@@ -0,0 +1,183 @@
+/*
+ * GPR board platform device registration
+ *
+ * Copyright (C) 2010 Wolfgang Grandegger <wg@denx.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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+/*
+ * Watchdog
+ */
+static struct resource gpr_wdt_resource[] = {
+	[0] = {
+		.start	= 1,
+		.end	= 1,
+		.name	= "gpr-adm6320-wdt",
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device gpr_wdt_device = {
+	.name = "adm6320-wdt",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(gpr_wdt_resource),
+	.resource = gpr_wdt_resource,
+};
+
+/*
+ * FLASH
+ *
+ * 0x00000000-0x00200000 : "kernel"
+ * 0x00200000-0x00a00000 : "rootfs"
+ * 0x01d00000-0x01f00000 : "config"
+ * 0x01c00000-0x01d00000 : "yamon"
+ * 0x01d00000-0x01d40000 : "yamon env vars"
+ * 0x00000000-0x00a00000 : "kernel+rootfs"
+ */
+static struct mtd_partition gpr_mtd_partitions[] = {
+	{
+		.name	= "kernel",
+		.size	= 0x00200000,
+		.offset	= 0,
+	},
+	{
+		.name	= "rootfs",
+		.size	= 0x00800000,
+		.offset	= MTDPART_OFS_APPEND,
+		.mask_flags = MTD_WRITEABLE,
+	},
+	{
+		.name	= "config",
+		.size	= 0x00200000,
+		.offset	= 0x01d00000,
+	},
+	{
+		.name	= "yamon",
+		.size	= 0x00100000,
+		.offset	= 0x01c00000,
+	},
+	{
+		.name	= "yamon env vars",
+		.size	= 0x00040000,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	{
+		.name	= "kernel+rootfs",
+		.size	= 0x00a00000,
+		.offset	= 0,
+	},
+};
+
+static struct physmap_flash_data gpr_flash_data = {
+	.width		= 4,
+	.nr_parts	= ARRAY_SIZE(gpr_mtd_partitions),
+	.parts		= gpr_mtd_partitions,
+};
+
+static struct resource gpr_mtd_resource = {
+	.start	= 0x1e000000,
+	.end	= 0x1fffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device gpr_mtd_device = {
+	.name		= "physmap-flash",
+	.dev		= {
+		.platform_data	= &gpr_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &gpr_mtd_resource,
+};
+
+/*
+ * LEDs
+ */
+static struct gpio_led gpr_gpio_leds[] = {
+	{	/* green */
+		.name			= "gpr:green",
+		.gpio			= 4,
+		.active_low		= 1,
+	},
+	{	/* red */
+		.name			= "gpr:red",
+		.gpio			= 5,
+		.active_low		= 1,
+	}
+};
+
+static struct gpio_led_platform_data gpr_led_data = {
+	.num_leds = ARRAY_SIZE(gpr_gpio_leds),
+	.leds = gpr_gpio_leds,
+};
+
+static struct platform_device gpr_led_devices = {
+	.name = "leds-gpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &gpr_led_data,
+	}
+};
+
+/*
+ * I2C
+ */
+static struct i2c_gpio_platform_data gpr_i2c_data = {
+	.sda_pin		= 209,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= 210,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+	.timeout		= HZ,
+ };
+
+static struct platform_device gpr_i2c_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &gpr_i2c_data,
+};
+
+static struct i2c_board_info gpr_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("lm83", 0x18),
+		.type = "lm83"
+	}
+};
+
+static struct platform_device *gpr_devices[] __initdata = {
+	&gpr_wdt_device,
+	&gpr_mtd_device,
+	&gpr_i2c_device,
+	&gpr_led_devices,
+};
+
+static int __init gpr_dev_init(void)
+{
+	i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info));
+
+	return platform_add_devices(gpr_devices, ARRAY_SIZE(gpr_devices));
+}
+device_initcall(gpr_dev_init);
diff --git a/arch/mips/alchemy/mtx-1/Makefile b/arch/mips/alchemy/mtx-1/Makefile
index 4a53815b3c6c53558f4abf7f1f8a82819fbddd1c..81b540ceaf888d797042c12f6b8eb7d586594a3d 100644
--- a/arch/mips/alchemy/mtx-1/Makefile
+++ b/arch/mips/alchemy/mtx-1/Makefile
@@ -6,7 +6,4 @@
 # Makefile for 4G Systems MTX-1 board.
 #
 
-lib-y := init.o board_setup.o
-obj-y := platform.o
-
-EXTRA_CFLAGS += -Werror
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
index 52d883d37dd7e4b69a82ab89e724c7b0c2cca7d4..6398fa95905c9036518aa728292b16fe925eee39 100644
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -60,9 +60,11 @@ static void mtx1_reset(char *c)
 
 static void mtx1_power_off(void)
 {
-	printk(KERN_ALERT "It's now safe to remove power\n");
 	while (1)
-		asm volatile (".set mips3 ; wait ; .set mips1");
+		asm volatile (
+		"	.set	mips32					\n"
+		"	wait						\n"
+		"	.set	mips0					\n");
 }
 
 void __init board_setup(void)
@@ -105,14 +107,10 @@ void __init board_setup(void)
 int
 mtx1_pci_idsel(unsigned int devsel, int assert)
 {
-#define MTX_IDSEL_ONLY_0_AND_3 0
-#if MTX_IDSEL_ONLY_0_AND_3
-	if (devsel != 0 && devsel != 3) {
-		printk(KERN_ERR "*** not 0 or 3\n");
-		return 0;
-	}
-#endif
-
+	/* This function is only necessary to support a proprietary Cardbus
+	 * adapter on the mtx-1 "singleboard" variant. It triggers a custom
+	 * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
+	 */
 	if (assert && devsel != 0)
 		/* Suppress signal to Cardbus */
 		alchemy_gpio_set_value(1, 0);	/* set EXT_IO3 OFF */
diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
index 4dc81d794cb8dc65b4af71868e3c5eed267d081f..91defcf4f335e8d51ffc8551264f8ef0a2850d74 100644
--- a/arch/mips/alchemy/xxs1500/Makefile
+++ b/arch/mips/alchemy/xxs1500/Makefile
@@ -5,6 +5,4 @@
 # Makefile for MyCable XXS1500 board.
 #
 
-lib-y := init.o board_setup.o platform.o
-
-EXTRA_CFLAGS += -Werror
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
index 47b42927607b2eb11d98a1cf8345515260538747..b43c918925d36406cd0903afb95f6c2d6abe546f 100644
--- a/arch/mips/alchemy/xxs1500/board_setup.c
+++ b/arch/mips/alchemy/xxs1500/board_setup.c
@@ -42,9 +42,11 @@ static void xxs1500_reset(char *c)
 
 static void xxs1500_power_off(void)
 {
-	printk(KERN_ALERT "It's now safe to remove power\n");
 	while (1)
-		asm volatile (".set mips3 ; wait ; .set mips1");
+		asm volatile (
+		"	.set	mips32					\n"
+		"	wait						\n"
+		"	.set	mips0					\n");
 }
 
 void __init board_setup(void)
diff --git a/arch/mips/ar7/Makefile b/arch/mips/ar7/Makefile
index 26bc5da189971c1714174c82e0c4f8a72f6d4fa6..7435e44b396404b355fe60dc1bf7e9de96e33665 100644
--- a/arch/mips/ar7/Makefile
+++ b/arch/mips/ar7/Makefile
@@ -8,4 +8,3 @@ obj-y := \
 	platform.o \
 	gpio.o \
 	clock.o
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/ar7/Platform b/arch/mips/ar7/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..0bf85c416c6c6f28acea8c848729b1bbe0d57c43
--- /dev/null
+++ b/arch/mips/ar7/Platform
@@ -0,0 +1,6 @@
+#
+# Texas Instruments AR7
+#
+platform-$(CONFIG_AR7)          += ar7/
+cflags-$(CONFIG_AR7)            += -I$(srctree)/arch/mips/include/asm/mach-ar7
+load-$(CONFIG_AR7)              += 0xffffffff94100000
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 8f31d1d59683383124035708659089ced9a804a2..0da5b2b8dd88a4a08d75b4eaf9aa3965b1af655f 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -292,40 +292,28 @@ static struct platform_device cpmac_high = {
 	.num_resources	= ARRAY_SIZE(cpmac_high_res),
 };
 
-static inline unsigned char char2hex(char h)
+static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
 {
-	switch (h) {
-	case '0': case '1': case '2': case '3': case '4':
-	case '5': case '6': case '7': case '8': case '9':
-		return h - '0';
-	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-		return h - 'A' + 10;
-	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-		return h - 'a' + 10;
-	default:
-		return 0;
-	}
-}
-
-static void cpmac_get_mac(int instance, unsigned char *dev_addr)
-{
-	int i;
-	char name[5], default_mac[ETH_ALEN], *mac;
+	char name[5], *mac;
 
-	mac = NULL;
 	sprintf(name, "mac%c", 'a' + instance);
 	mac = prom_getenv(name);
-	if (!mac) {
+	if (!mac && instance) {
 		sprintf(name, "mac%c", 'a');
 		mac = prom_getenv(name);
 	}
-	if (!mac) {
-		random_ether_addr(default_mac);
-		mac = default_mac;
-	}
-	for (i = 0; i < 6; i++)
-		dev_addr[i] = (char2hex(mac[i * 3]) << 4) +
-			char2hex(mac[i * 3 + 1]);
+
+	if (mac) {
+		if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+					&dev_addr[0], &dev_addr[1],
+					&dev_addr[2], &dev_addr[3],
+					&dev_addr[4], &dev_addr[5]) != 6) {
+			pr_warning("cannot parse mac address, "
+					"using random address\n");
+			random_ether_addr(dev_addr);
+		}
+	} else
+		random_ether_addr(dev_addr);
 }
 
 /*****************************************************************************
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..874b7ca4cd11de1d81d3a39d16bf986a7006d0c2
--- /dev/null
+++ b/arch/mips/bcm47xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM47XX boards
+#
+platform-$(CONFIG_BCM47XX)	+= bcm47xx/
+cflags-$(CONFIG_BCM47XX)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-bcm47xx
+load-$(CONFIG_BCM47XX)		:= 0xffffffff80001000
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 06e03b222f6dee5962fbd7fb2be6073e9f903708..e5b6615731e5c24dd963190bc2d244930ba08299 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -69,7 +69,7 @@ int nvram_getenv(char *name, char *val, size_t val_len)
 	char *var, *value, *end, *eq;
 
 	if (!name)
-		return 1;
+		return NVRAM_ERR_INV_PARAM;
 
 	if (!nvram_buf[0])
 		early_nvram_init();
@@ -89,6 +89,6 @@ int nvram_getenv(char *name, char *val, size_t val_len)
 			return 0;
 		}
 	}
-	return 1;
+	return NVRAM_ERR_ENVNOTFOUND;
 }
 EXPORT_SYMBOL(nvram_getenv);
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 0fa646c5a844bfb18186db1625c26e1b6f6e5114..f6e9063cc4c2011f057f468a30a8ab7c4c0e4ecd 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -126,6 +126,7 @@ static __init void prom_init_cmdline(void)
 static __init void prom_init_mem(void)
 {
 	unsigned long mem;
+	unsigned long max;
 
 	/* Figure out memory size by finding aliases.
 	 *
@@ -134,21 +135,26 @@ static __init void prom_init_mem(void)
 	 * want to reuse the memory used by CFE (around 4MB). That means cfe_*
 	 * functions stop to work at some point during the boot, we should only
 	 * call them at the beginning of the boot.
+	 *
+	 * BCM47XX uses 128MB for addressing the ram, if the system contains
+	 * less that that amount of ram it remaps the ram more often into the
+	 * available space.
+	 * Accessing memory after 128MB will cause an exception.
+	 * 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));
 	for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
+		if (((unsigned long)(prom_init) + 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))
 			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 (mem == 0x8000000)
-		mem -= 0x1000;
-
 	add_memory_region(0, mem, BOOT_MEM_RAM);
 }
 
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 00064b6608096f1cd8722cf832cae7b353e39eec..6dfdc69928accdfc1d062cf9315b04f8bc28a9c2 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -3,5 +3,3 @@ obj-y		+= clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-y		+= boards/
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/Platform b/arch/mips/bcm63xx/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..5f86b2fff6def6e046cd20728477d60dced4bc1b
--- /dev/null
+++ b/arch/mips/bcm63xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM63XX boards
+#
+platform-$(CONFIG_BCM63XX)	+= bcm63xx/
+cflags-$(CONFIG_BCM63XX)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
+load-$(CONFIG_BCM63XX)		:= 0xffffffff80010000
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
index 4667a5f9280bece570f5845b8781dd9d8b69084b..f210b09ececcf0fe9ab0ee282da0f9332c050394 100644
--- a/arch/mips/boot/.gitignore
+++ b/arch/mips/boot/.gitignore
@@ -3,3 +3,4 @@ elf2ecoff
 vmlinux.*
 zImage
 zImage.tmp
+calc_vmlinuz_load_addr
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index e39a08edcaaa02b02790944cc5d64cd199e3a23b..85bcb5adc7cb16531a4ea93d41a101a83ee786ba 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -11,35 +11,32 @@
 # Some DECstations need all possible sections of an ECOFF executable
 #
 ifdef CONFIG_MACH_DECSTATION
-  E2EFLAGS = -a
-else
-  E2EFLAGS =
+  e2eflag := -a
 endif
 
 #
 # Drop some uninteresting sections in the kernel.
 # This is only relevant for ELF kernels but doesn't hurt a.out
 #
-drop-sections	= .reginfo .mdebug .comment .note .pdr .options .MIPS.options
-strip-flags	= $(addprefix --remove-section=,$(drop-sections))
-
-VMLINUX = vmlinux
-
-all: vmlinux.ecoff vmlinux.srec
-
-vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
-	$(obj)/elf2ecoff $(VMLINUX) $(obj)/vmlinux.ecoff $(E2EFLAGS)
-
-$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
-	$(HOSTCC) -o $@ $^
-
-vmlinux.bin: $(VMLINUX)
-	$(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
-
-vmlinux.srec: $(VMLINUX)
-	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
-
-clean-files += elf2ecoff \
-	       vmlinux.bin \
-	       vmlinux.ecoff \
-	       vmlinux.srec
+drop-sections := .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags   := $(addprefix --remove-section=,$(drop-sections))
+
+hostprogs-y := elf2ecoff
+
+targets := vmlinux.ecoff
+quiet_cmd_ecoff = ECOFF   $@
+      cmd_ecoff = $(obj)/elf2ecoff $(VMLINUX) $@ $(e2eflag)
+$(obj)/vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) FORCE
+	$(call if_changed,ecoff)
+
+targets += vmlinux.bin
+quiet_cmd_bin = OBJCOPY $@
+      cmd_bin = $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.bin: $(VMLINUX) FORCE
+	$(call if_changed,bin)
+
+targets += vmlinux.srec
+quiet_cmd_srec = OBJCOPY $@
+      cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.srec: $(VMLINUX) FORCE
+	$(call if_changed,srec)
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 790ddd39762080b9e0900f3c3b1e32b51ad7860b..ed9bb709c9a3816a4738d0ceef91db8c8de20cd4 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -12,14 +12,6 @@
 # Author: Wu Zhangjin <wuzhangjin@gmail.com>
 #
 
-# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
-VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1)
-VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
-# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE"
-HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10)))
-LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8)
-VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32))))
-
 # set the default size of the mallocing area for decompressing
 BOOT_HEAP_SIZE := 0x400000
 
@@ -33,49 +25,61 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
 	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
 	-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
 
-obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
+targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o
+
+# decompressor objects (linked with vmlinuz)
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
 
 ifdef CONFIG_DEBUG_ZBOOT
-obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
-obj-$(CONFIG_MACH_ALCHEMY)		   += $(obj)/uart-alchemy.o
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)		   += $(obj)/uart-alchemy.o
 endif
 
+targets += vmlinux.bin
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
-$(obj)/vmlinux.bin: $(KBUILD_IMAGE)
+$(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
 	$(call if_changed,objcopy)
 
-suffix_$(CONFIG_KERNEL_GZIP)  = gz
-suffix_$(CONFIG_KERNEL_BZIP2) = bz2
-suffix_$(CONFIG_KERNEL_LZMA)  = lzma
-suffix_$(CONFIG_KERNEL_LZO)   = lzo
 tool_$(CONFIG_KERNEL_GZIP)    = gzip
 tool_$(CONFIG_KERNEL_BZIP2)   = bzip2
 tool_$(CONFIG_KERNEL_LZMA)    = lzma
 tool_$(CONFIG_KERNEL_LZO)     = lzo
-$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
+
+targets += vmlinux.bin.z
+$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,$(tool_y))
 
-$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o
-	$(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \
-		--add-section=.image=$< \
-		--set-section-flags=.image=contents,alloc,load,readonly,data \
-		$(obj)/dummy.o $@
+targets += piggy.o
+OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
+                        --set-section-flags=.image=contents,alloc,load,readonly,data
+$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
+	$(call if_changed,objcopy)
+
+# Calculate the load address of the compressed kernel image
+hostprogs-y := calc_vmlinuz_load_addr
+
+VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
+		$(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS))
 
-LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T
-vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o
-	$(call if_changed,ld)
-	$(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@
+vmlinuzobjs-y += $(obj)/piggy.o
+
+quiet_cmd_zld = LD      $@
+      cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
+quiet_cmd_strip = STRIP   $@
+      cmd_strip = $(STRIP) -s $@
+vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/calc_vmlinuz_load_addr
+	$(call cmd,zld)
+	$(call cmd,strip)
 
 #
 # Some DECstations need all possible sections of an ECOFF executable
 #
 ifdef CONFIG_MACH_DECSTATION
-  E2EFLAGS = -a
-else
-  E2EFLAGS =
+  e2eflag := -a
 endif
 
 # elf2ecoff can only handle 32bit image
+hostprogs-y += ../elf2ecoff
 
 ifdef CONFIG_32BIT
 	VMLINUZ = vmlinuz
@@ -83,23 +87,22 @@ else
 	VMLINUZ = vmlinuz.32
 endif
 
+quiet_cmd_32 = OBJCOPY $@
+      cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
 vmlinuz.32: vmlinuz
-	$(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+	$(call cmd,32)
 
+quiet_cmd_ecoff = ECOFF   $@
+      cmd_ecoff = $< $(VMLINUZ) $@ $(e2eflag)
 vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
-	$(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS)
-
-$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c
-	$(Q)$(HOSTCC) -o $@ $^
+	$(call cmd,ecoff)
 
 OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
 vmlinuz.bin: vmlinuz
-	$(call if_changed,objcopy)
+	$(call cmd,objcopy)
 
 OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
 vmlinuz.srec: vmlinuz
-	$(call if_changed,objcopy)
+	$(call cmd,objcopy)
 
-clean:
-clean-files += *.o \
-	       vmlinu*
+clean-files := $(objtree)/vmlinuz.*
diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
new file mode 100644
index 0000000000000000000000000000000000000000..88c9d963be88872df85924046a614858c59593af
--- /dev/null
+++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhangjin@gmail.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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+	struct stat sb;
+	uint64_t vmlinux_size, vmlinux_load_addr, vmlinuz_load_addr;
+
+	if (argc != 3) {
+		fprintf(stderr, "Usage: %s <pathname> <vmlinux_load_addr>\n",
+				argv[0]);
+		return EXIT_FAILURE;
+	}
+
+	if (stat(argv[1], &sb) == -1) {
+		perror("stat");
+		return EXIT_FAILURE;
+	}
+
+	/* Convert hex characters to dec number */
+	errno = 0;
+	if (sscanf(argv[2], "%llx", &vmlinux_load_addr) != 1) {
+		if (errno != 0)
+			perror("sscanf");
+		else
+			fprintf(stderr, "No matching characters\n");
+
+		return EXIT_FAILURE;
+	}
+
+	vmlinux_size = (uint64_t)sb.st_size;
+	vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
+
+	/*
+	 * Align with 16 bytes: "greater than that used for any standard data
+	 * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition).
+	 */
+
+	vmlinuz_load_addr += (16 - vmlinux_size % 16);
+
+	printf("0x%llx\n", vmlinuz_load_addr);
+
+	return EXIT_SUCCESS;
+}
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
index 5db43c58b1bf7e844eeaa683d3a61d45c0ea340a..5cad0faefa17cdcd7425eb07e93e48554cc99f2f 100644
--- a/arch/mips/boot/compressed/decompress.c
+++ b/arch/mips/boot/compressed/decompress.c
@@ -1,9 +1,6 @@
 /*
- * Misc. bootloader code for many machines.
- *
  * Copyright 2001 MontaVista Software Inc.
- * Author: Matt Porter <mporter@mvista.com> Derived from
- * arch/ppc/boot/prep/misc.c
+ * Author: Matt Porter <mporter@mvista.com>
  *
  * Copyright (C) 2009 Lemote, Inc.
  * Author: Wu Zhangjin <wuzhangjin@gmail.com>
@@ -19,12 +16,12 @@
 
 #include <asm/addrspace.h>
 
-/* These two variables specify the free mem region
+/*
+ * These two variables specify the free mem region
  * that can be used for temporary malloc area
  */
 unsigned long free_mem_ptr;
 unsigned long free_mem_end_ptr;
-char *zimage_start;
 
 /* The linker tells us where the image is. */
 extern unsigned char __image_begin, __image_end;
@@ -83,38 +80,31 @@ void *memset(void *s, int c, size_t n)
 
 void decompress_kernel(unsigned long boot_heap_start)
 {
-	int zimage_size;
-
-	/*
-	 * We link ourself to an arbitrary low address.  When we run, we
-	 * relocate outself to that address.  __image_beign points to
-	 * the part of the image where the zImage is. -- Tom
-	 */
-	zimage_start = (char *)(unsigned long)(&__image_begin);
+	unsigned long zimage_start, zimage_size;
+
+	zimage_start = (unsigned long)(&__image_begin);
 	zimage_size = (unsigned long)(&__image_end) -
 	    (unsigned long)(&__image_begin);
 
-	/*
-	 * The zImage and initrd will be between start and _end, so they've
-	 * already been moved once.  We're good to go now. -- Tom
-	 */
 	puts("zimage at:     ");
-	puthex((unsigned long)zimage_start);
+	puthex(zimage_start);
 	puts(" ");
-	puthex((unsigned long)(zimage_size + zimage_start));
+	puthex(zimage_size + zimage_start);
 	puts("\n");
 
-	/* this area are prepared for mallocing when decompressing */
+	/* This area are prepared for mallocing when decompressing */
 	free_mem_ptr = boot_heap_start;
 	free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
 
-	/* Display standard Linux/MIPS boot prompt for kernel args */
+	/* Display standard Linux/MIPS boot prompt */
 	puts("Uncompressing Linux at load address ");
 	puthex(VMLINUX_LOAD_ADDRESS_ULL);
 	puts("\n");
+
 	/* Decompress the kernel with according algorithm */
-	decompress(zimage_start, zimage_size, 0, 0,
+	decompress((char *)zimage_start, zimage_size, 0, 0,
 		   (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
-	/* FIXME: is there a need to flush cache here? */
+
+	/* FIXME: should we flush cache here? */
 	puts("Now, booting the kernel...\n");
 }
diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script
index 613a35b02f50b8f372f4a701c2b589c134a0e5ed..8e6b07ca2f5e6924b68b8ce177aa7c9e7119e80e 100644
--- a/arch/mips/boot/compressed/ld.script
+++ b/arch/mips/boot/compressed/ld.script
@@ -2,61 +2,44 @@
  * ld.script for compressed kernel support of MIPS
  *
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhanjing@gmail.com>
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhanjing@gmail.com>
  */
 
 OUTPUT_ARCH(mips)
 ENTRY(start)
 SECTIONS
 {
-	/* . = VMLINUZ_LOAD_ADDRESS */
-	/* read-only */
-	_text = .;	/* Text and read-only data */
-	.text	: {
-		_ftext = . ;
+	/* Text and read-only data */
+	/* . = VMLINUZ_LOAD_ADDRESS; */
+	.text : {
 		*(.text)
 		*(.rodata)
-	} = 0
-	_etext = .;	/* End of text section */
+	}
+	/* End of text section */
 
-	/* writable */
-	.data	: {	/* Data */
-		_fdata = . ;
+	/* Writable data */
+	.data : {
 		*(.data)
-		/* Put the compressed image here, so bss is on the end. */
+		/* Put the compressed image here */
 		__image_begin = .;
 		*(.image)
 		__image_end = .;
 		CONSTRUCTORS
 	}
-	.sdata	: { *(.sdata) }
-	. = ALIGN(4);
-	_edata  =  .;	/* End of data section */
+	. = ALIGN(16);
+	_edata = .;
+	/* End of data section */
 
 	/* BSS */
-	__bss_start = .;
-	_fbss = .;
-	.sbss	: { *(.sbss) *(.scommon) }
-	.bss	: {
-		*(.dynbss)
+	.bss : {
 		*(.bss)
-		*(COMMON)
 	}
-	.  = ALIGN(4);
-	_end = . ;
-
-	/* These are needed for ELF backends which have not yet been converted
-	 * to the new style linker.  */
-
-	.stab 0 : { *(.stab) }
-	.stabstr 0 : { *(.stabstr) }
-
-	/* These must appear regardless of  .  */
-	.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
-	.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+	. = ALIGN(16);
+	_end = .;
 
 	/* Sections to be discarded */
-	/DISCARD/	: {
+	/DISCARD/ : {
 		*(.MIPS.options)
 		*(.options)
 		*(.pdr)
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 3e9876317e61c2c040021a6b3e91a7e7f3b2bb2a..19eb0434269ffc6017bb79da7f00485d2cb13813 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -12,7 +12,6 @@
 obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
 obj-y += dma-octeon.o flash_setup.o
 obj-y += octeon-memcpy.o
+obj-y += executive/
 
 obj-$(CONFIG_SMP)                     += smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cavium-octeon/Platform b/arch/mips/cavium-octeon/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..1e43ccf1a792f84afa76354bf0c6f2c2c893b7b1
--- /dev/null
+++ b/arch/mips/cavium-octeon/Platform
@@ -0,0 +1,11 @@
+#
+# Cavium Octeon
+#
+platform-$(CONFIG_CPU_CAVIUM_OCTEON)	+= cavium-octeon/
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON)	+=				\
+		-I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
+ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+load-$(CONFIG_CPU_CAVIUM_OCTEON)	+= 0xffffffff84100000
+else
+load-$(CONFIG_CPU_CAVIUM_OCTEON)	+= 0xffffffff81100000
+endif
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c
index b6df5387e855d10ad1d483851f3f3d553ef1335c..c664c8cc2b42cb8970b9f57531a03e2998075566 100644
--- a/arch/mips/cavium-octeon/cpu.c
+++ b/arch/mips/cavium-octeon/cpu.c
@@ -41,12 +41,8 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
 	return NOTIFY_OK;		/* Let default notifier send signals */
 }
 
-static struct notifier_block cnmips_cu2_notifier = {
-	.notifier_call = cnmips_cu2_call,
-};
-
 static int cnmips_cu2_setup(void)
 {
-	return register_cu2_notifier(&cnmips_cu2_notifier);
+	return cu2_notifier(cnmips_cu2_call, 0);
 }
 early_initcall(cnmips_cu2_setup);
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index 0bf4bbe04ae2219b66fd032e52c82b8ee1350a97..b6847c8e0ddd3784b4050b7dee6558cfd595e119 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -53,7 +53,6 @@ static struct clocksource clocksource_mips = {
 unsigned long long notrace sched_clock(void)
 {
 	/* 64-bit arithmatic can overflow, so use 128-bit.  */
-#if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 3))
 	u64 t1, t2, t3;
 	unsigned long long rv;
 	u64 mult = clocksource_mips.mult;
@@ -73,13 +72,6 @@ unsigned long long notrace sched_clock(void)
 		: [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift)
 		: "hi", "lo");
 	return rv;
-#else
-	/* GCC > 4.3 do it the easy way.  */
-	unsigned int __attribute__((mode(TI))) t;
-	t = read_c0_cvmcount();
-	t = t * clocksource_mips.mult;
-	return (unsigned long long)(t >> clocksource_mips.shift);
-#endif
 }
 
 void __init plat_time_init(void)
@@ -88,3 +80,58 @@ void __init plat_time_init(void)
 	clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
 	clocksource_register(&clocksource_mips);
 }
+
+static u64 octeon_udelay_factor;
+static u64 octeon_ndelay_factor;
+
+void __init octeon_setup_delays(void)
+{
+	octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
+	/*
+	 * For __ndelay we divide by 2^16, so the factor is multiplied
+	 * by the same amount.
+	 */
+	octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
+
+	preset_lpj = octeon_get_clock_rate() / HZ;
+}
+
+void __udelay(unsigned long us)
+{
+	u64 cur, end, inc;
+
+	cur = read_c0_cvmcount();
+
+	inc = us * octeon_udelay_factor;
+	end = cur + inc;
+
+	while (end > cur)
+		cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long ns)
+{
+	u64 cur, end, inc;
+
+	cur = read_c0_cvmcount();
+
+	inc = ((ns * octeon_ndelay_factor) >> 16);
+	end = cur + inc;
+
+	while (end > cur)
+		cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__ndelay);
+
+void __delay(unsigned long loops)
+{
+	u64 cur, end;
+
+	cur = read_c0_cvmcount();
+	end = cur + loops;
+
+	while (end > cur)
+		cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__delay);
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index be531ec1f2064b590b58dfe8b4db4f5534999bab..d22b5a2d64f47988659f55d2998925ff569b0711 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -99,13 +99,16 @@ dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
 			panic("dma_map_single: "
 			      "Attempt to map illegal memory address 0x%llx\n",
 			      physical);
-		else if ((physical + size >=
-			  (4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20))
-			 && physical < (4ull<<30))
-			pr_warning("dma_map_single: Warning: "
-				   "Mapping memory address that might "
-				   "conflict with devices 0x%llx-0x%llx\n",
-				   physical, physical+size-1);
+		else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE &&
+			 physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) {
+			result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
+
+			if (((result+size-1) & dma_mask) != result+size-1)
+				panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n",
+				      physical, physical+size-1, dma_mask);
+			goto done;
+		}
+
 		/* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
 		if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
 			result = physical - 0x400000000ull;
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index c424cd158dc6c7f195a3c4c3a29f8e4793da8493..ce7500cdf5b709de9755d94f6b07b41eeca17359 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,15 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2008 Cavium Networks
+ * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
  */
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 
 #include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-pexp-defs.h>
-#include <asm/octeon/cvmx-npi-defs.h>
 
 static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
 static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
@@ -41,14 +39,14 @@ static void octeon_irq_core_ack(unsigned int irq)
 
 static void octeon_irq_core_eoi(unsigned int irq)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * If an IRQ is being processed while we are disabling it the
 	 * handler will attempt to unmask the interrupt after it has
 	 * been disabled.
 	 */
-	if (desc->status & IRQ_DISABLED)
+	if ((unlikely(desc->status & IRQ_DISABLED)))
 		return;
 	/*
 	 * We don't need to disable IRQs to make these atomic since
@@ -106,6 +104,29 @@ static struct irq_chip octeon_irq_chip_core = {
 
 static void octeon_irq_ciu0_ack(unsigned int irq)
 {
+	switch (irq) {
+	case OCTEON_IRQ_GMX_DRP0:
+	case OCTEON_IRQ_GMX_DRP1:
+	case OCTEON_IRQ_IPD_DRP:
+	case OCTEON_IRQ_KEY_ZERO:
+	case OCTEON_IRQ_TIMER0:
+	case OCTEON_IRQ_TIMER1:
+	case OCTEON_IRQ_TIMER2:
+	case OCTEON_IRQ_TIMER3:
+	{
+		int index = cvmx_get_core_num() * 2;
+		u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+		/*
+		 * CIU timer type interrupts must be acknoleged by
+		 * writing a '1' bit to their sum0 bit.
+		 */
+		cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
+		break;
+	}
+	default:
+		break;
+	}
+
 	/*
 	 * In order to avoid any locking accessing the CIU, we
 	 * acknowledge CIU interrupts by disabling all of them.  This
@@ -130,7 +151,53 @@ static void octeon_irq_ciu0_eoi(unsigned int irq)
 	set_c0_status(0x100 << 2);
 }
 
+static int next_coreid_for_irq(struct irq_desc *desc)
+{
+
+#ifdef CONFIG_SMP
+	int coreid;
+	int weight = cpumask_weight(desc->affinity);
+
+	if (weight > 1) {
+		int cpu = smp_processor_id();
+		for (;;) {
+			cpu = cpumask_next(cpu, desc->affinity);
+			if (cpu >= nr_cpu_ids) {
+				cpu = -1;
+				continue;
+			} else if (cpumask_test_cpu(cpu, cpu_online_mask)) {
+				break;
+			}
+		}
+		coreid = octeon_coreid_for_cpu(cpu);
+	} else if (weight == 1) {
+		coreid = octeon_coreid_for_cpu(cpumask_first(desc->affinity));
+	} else {
+		coreid = cvmx_get_core_num();
+	}
+	return coreid;
+#else
+	return cvmx_get_core_num();
+#endif
+}
+
 static void octeon_irq_ciu0_enable(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	int coreid = next_coreid_for_irq(desc);
+	unsigned long flags;
+	uint64_t en0;
+	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
+
+	raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+	en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+	en0 |= 1ull << bit;
+	cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+	cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+}
+
+static void octeon_irq_ciu0_enable_mbox(unsigned int irq)
 {
 	int coreid = cvmx_get_core_num();
 	unsigned long flags;
@@ -167,63 +234,76 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
 }
 
 /*
- * Enable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
+ * Enable the irq on the next core in the affinity set for chips that
+ * have the EN*_W1{S,C} registers.
  */
 static void octeon_irq_ciu0_enable_v2(unsigned int irq)
 {
-	int index = cvmx_get_core_num() * 2;
+	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+	if ((desc->status & IRQ_DISABLED) == 0) {
+		index = next_coreid_for_irq(desc) * 2;
+		cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+	}
 }
 
 /*
- * Disable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
+ * Enable the irq on the current CPU for chips that
+ * have the EN*_W1{S,C} registers.
  */
-static void octeon_irq_ciu0_ack_v2(unsigned int irq)
+static void octeon_irq_ciu0_enable_mbox_v2(unsigned int irq)
 {
-	int index = cvmx_get_core_num() * 2;
+	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 
-	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+	index = cvmx_get_core_num() * 2;
+	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
 }
 
 /*
- * CIU timer type interrupts must be acknoleged by writing a '1' bit
- * to their sum0 bit.
+ * Disable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
  */
-static void octeon_irq_ciu0_timer_ack(unsigned int irq)
+static void octeon_irq_ciu0_ack_v2(unsigned int irq)
 {
 	int index = cvmx_get_core_num() * 2;
-	uint64_t mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
-	cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
-}
+	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 
-static void octeon_irq_ciu0_timer_ack_v1(unsigned int irq)
-{
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack(irq);
-}
+	switch (irq) {
+	case OCTEON_IRQ_GMX_DRP0:
+	case OCTEON_IRQ_GMX_DRP1:
+	case OCTEON_IRQ_IPD_DRP:
+	case OCTEON_IRQ_KEY_ZERO:
+	case OCTEON_IRQ_TIMER0:
+	case OCTEON_IRQ_TIMER1:
+	case OCTEON_IRQ_TIMER2:
+	case OCTEON_IRQ_TIMER3:
+		/*
+		 * CIU timer type interrupts must be acknoleged by
+		 * writing a '1' bit to their sum0 bit.
+		 */
+		cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
+		break;
+	default:
+		break;
+	}
 
-static void octeon_irq_ciu0_timer_ack_v2(unsigned int irq)
-{
-	octeon_irq_ciu0_timer_ack(irq);
-	octeon_irq_ciu0_ack_v2(irq);
+	cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
 }
 
 /*
  * Enable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu0_eoi_mbox_v2(unsigned int irq)
 {
-	struct irq_desc *desc = irq_desc + irq;
+	struct irq_desc *desc = irq_to_desc(irq);
 	int index = cvmx_get_core_num() * 2;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
 
-	if ((desc->status & IRQ_DISABLED) == 0)
+	if (likely((desc->status & IRQ_DISABLED) == 0))
 		cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
 }
 
@@ -246,18 +326,30 @@ static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
 static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
 {
 	int cpu;
+	struct irq_desc *desc = irq_to_desc(irq);
+	int enable_one = (desc->status & IRQ_DISABLED) == 0;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
 
+	/*
+	 * For non-v2 CIU, we will allow only single CPU affinity.
+	 * This removes the need to do locking in the .ack/.eoi
+	 * functions.
+	 */
+	if (cpumask_weight(dest) != 1)
+		return -EINVAL;
+
 	raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		uint64_t en0 =
 			cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
-		if (cpumask_test_cpu(cpu, dest))
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = 0;
 			en0 |= 1ull << bit;
-		else
+		} else {
 			en0 &= ~(1ull << bit);
+		}
 		cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
 	}
 	/*
@@ -279,13 +371,18 @@ static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
 {
 	int cpu;
 	int index;
+	struct irq_desc *desc = irq_to_desc(irq);
+	int enable_one = (desc->status & IRQ_DISABLED) == 0;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+
 	for_each_online_cpu(cpu) {
 		index = octeon_coreid_for_cpu(cpu) * 2;
-		if (cpumask_test_cpu(cpu, dest))
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = 0;
 			cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
-		else
+		} else {
 			cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+		}
 	}
 	return 0;
 }
@@ -298,8 +395,7 @@ static struct irq_chip octeon_irq_chip_ciu0_v2 = {
 	.name = "CIU0",
 	.enable = octeon_irq_ciu0_enable_v2,
 	.disable = octeon_irq_ciu0_disable_all_v2,
-	.ack = octeon_irq_ciu0_ack_v2,
-	.eoi = octeon_irq_ciu0_eoi_v2,
+	.eoi = octeon_irq_ciu0_enable_v2,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu0_set_affinity_v2,
 #endif
@@ -309,36 +405,27 @@ static struct irq_chip octeon_irq_chip_ciu0 = {
 	.name = "CIU0",
 	.enable = octeon_irq_ciu0_enable,
 	.disable = octeon_irq_ciu0_disable,
-	.ack = octeon_irq_ciu0_ack,
 	.eoi = octeon_irq_ciu0_eoi,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu0_set_affinity,
 #endif
 };
 
-static struct irq_chip octeon_irq_chip_ciu0_timer_v2 = {
-	.name = "CIU0-T",
-	.enable = octeon_irq_ciu0_enable_v2,
-	.disable = octeon_irq_ciu0_disable_all_v2,
-	.ack = octeon_irq_ciu0_timer_ack_v2,
-	.eoi = octeon_irq_ciu0_eoi_v2,
-#ifdef CONFIG_SMP
-	.set_affinity = octeon_irq_ciu0_set_affinity_v2,
-#endif
+/* The mbox versions don't do any affinity or round-robin. */
+static struct irq_chip octeon_irq_chip_ciu0_mbox_v2 = {
+	.name = "CIU0-M",
+	.enable = octeon_irq_ciu0_enable_mbox_v2,
+	.disable = octeon_irq_ciu0_disable,
+	.eoi = octeon_irq_ciu0_eoi_mbox_v2,
 };
 
-static struct irq_chip octeon_irq_chip_ciu0_timer = {
-	.name = "CIU0-T",
-	.enable = octeon_irq_ciu0_enable,
+static struct irq_chip octeon_irq_chip_ciu0_mbox = {
+	.name = "CIU0-M",
+	.enable = octeon_irq_ciu0_enable_mbox,
 	.disable = octeon_irq_ciu0_disable,
-	.ack = octeon_irq_ciu0_timer_ack_v1,
 	.eoi = octeon_irq_ciu0_eoi,
-#ifdef CONFIG_SMP
-	.set_affinity = octeon_irq_ciu0_set_affinity,
-#endif
 };
 
-
 static void octeon_irq_ciu1_ack(unsigned int irq)
 {
 	/*
@@ -365,10 +452,30 @@ static void octeon_irq_ciu1_eoi(unsigned int irq)
 
 static void octeon_irq_ciu1_enable(unsigned int irq)
 {
-	int coreid = cvmx_get_core_num();
+	struct irq_desc *desc = irq_to_desc(irq);
+	int coreid = next_coreid_for_irq(desc);
+	unsigned long flags;
+	uint64_t en1;
+	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
+
+	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+	en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+	en1 |= 1ull << bit;
+	cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+	cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+}
+
+/*
+ * Watchdog interrupts are special.  They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu1_wd_enable(unsigned int irq)
+{
 	unsigned long flags;
 	uint64_t en1;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
+	int coreid = bit;
 
 	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 	en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
@@ -405,36 +512,43 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
  */
 static void octeon_irq_ciu1_enable_v2(unsigned int irq)
 {
-	int index = cvmx_get_core_num() * 2 + 1;
+	int index;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+	if ((desc->status & IRQ_DISABLED) == 0) {
+		index = next_coreid_for_irq(desc) * 2 + 1;
+		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+	}
 }
 
 /*
- * Disable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
+ * Watchdog interrupts are special.  They are associated with a single
+ * core, so we hardwire the affinity to that core.
  */
-static void octeon_irq_ciu1_ack_v2(unsigned int irq)
+static void octeon_irq_ciu1_wd_enable_v2(unsigned int irq)
 {
-	int index = cvmx_get_core_num() * 2 + 1;
+	int index;
+	int coreid = irq - OCTEON_IRQ_WDOG0;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+	if ((desc->status & IRQ_DISABLED) == 0) {
+		index = coreid * 2 + 1;
+		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+	}
 }
 
 /*
- * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
+static void octeon_irq_ciu1_ack_v2(unsigned int irq)
 {
-	struct irq_desc *desc = irq_desc + irq;
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 
-	if ((desc->status & IRQ_DISABLED) == 0)
-		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+	cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
 }
 
 /*
@@ -457,19 +571,30 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq,
 					const struct cpumask *dest)
 {
 	int cpu;
+	struct irq_desc *desc = irq_to_desc(irq);
+	int enable_one = (desc->status & IRQ_DISABLED) == 0;
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 
+	/*
+	 * For non-v2 CIU, we will allow only single CPU affinity.
+	 * This removes the need to do locking in the .ack/.eoi
+	 * functions.
+	 */
+	if (cpumask_weight(dest) != 1)
+		return -EINVAL;
+
 	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		uint64_t en1 =
-			cvmx_read_csr(CVMX_CIU_INTX_EN1
-				(coreid * 2 + 1));
-		if (cpumask_test_cpu(cpu, dest))
+			cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = 0;
 			en1 |= 1ull << bit;
-		else
+		} else {
 			en1 &= ~(1ull << bit);
+		}
 		cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
 	}
 	/*
@@ -491,13 +616,17 @@ static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
 {
 	int cpu;
 	int index;
+	struct irq_desc *desc = irq_to_desc(irq);
+	int enable_one = (desc->status & IRQ_DISABLED) == 0;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
 	for_each_online_cpu(cpu) {
 		index = octeon_coreid_for_cpu(cpu) * 2 + 1;
-		if (cpumask_test_cpu(cpu, dest))
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = 0;
 			cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
-		else
+		} else {
 			cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+		}
 	}
 	return 0;
 }
@@ -507,11 +636,10 @@ static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
  * Newer octeon chips have support for lockless CIU operation.
  */
 static struct irq_chip octeon_irq_chip_ciu1_v2 = {
-	.name = "CIU0",
+	.name = "CIU1",
 	.enable = octeon_irq_ciu1_enable_v2,
 	.disable = octeon_irq_ciu1_disable_all_v2,
-	.ack = octeon_irq_ciu1_ack_v2,
-	.eoi = octeon_irq_ciu1_eoi_v2,
+	.eoi = octeon_irq_ciu1_enable_v2,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu1_set_affinity_v2,
 #endif
@@ -521,103 +649,36 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
 	.name = "CIU1",
 	.enable = octeon_irq_ciu1_enable,
 	.disable = octeon_irq_ciu1_disable,
-	.ack = octeon_irq_ciu1_ack,
 	.eoi = octeon_irq_ciu1_eoi,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu1_set_affinity,
 #endif
 };
 
-#ifdef CONFIG_PCI_MSI
-
-static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
-
-static void octeon_irq_msi_ack(unsigned int irq)
-{
-	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
-		/* These chips have PCI */
-		cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
-			       1ull << (irq - OCTEON_IRQ_MSI_BIT0));
-	} else {
-		/*
-		 * These chips have PCIe. Thankfully the ACK doesn't
-		 * need any locking.
-		 */
-		cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
-			       1ull << (irq - OCTEON_IRQ_MSI_BIT0));
-	}
-}
-
-static void octeon_irq_msi_eoi(unsigned int irq)
-{
-	/* Nothing needed */
-}
-
-static void octeon_irq_msi_enable(unsigned int irq)
-{
-	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
-		/*
-		 * Octeon PCI doesn't have the ability to mask/unmask
-		 * MSI interrupts individually.  Instead of
-		 * masking/unmasking them in groups of 16, we simple
-		 * assume MSI devices are well behaved.  MSI
-		 * interrupts are always enable and the ACK is assumed
-		 * to be enough.
-		 */
-	} else {
-		/* These chips have PCIe.  Note that we only support
-		 * the first 64 MSI interrupts.  Unfortunately all the
-		 * MSI enables are in the same register.  We use
-		 * MSI0's lock to control access to them all.
-		 */
-		uint64_t en;
-		unsigned long flags;
-		raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
-		en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
-		cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
-		cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
-	}
-}
-
-static void octeon_irq_msi_disable(unsigned int irq)
-{
-	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
-		/* See comment in enable */
-	} else {
-		/*
-		 * These chips have PCIe.  Note that we only support
-		 * the first 64 MSI interrupts.  Unfortunately all the
-		 * MSI enables are in the same register.  We use
-		 * MSI0's lock to control access to them all.
-		 */
-		uint64_t en;
-		unsigned long flags;
-		raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
-		en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
-		cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
-		cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
-	}
-}
+static struct irq_chip octeon_irq_chip_ciu1_wd_v2 = {
+	.name = "CIU1-W",
+	.enable = octeon_irq_ciu1_wd_enable_v2,
+	.disable = octeon_irq_ciu1_disable_all_v2,
+	.eoi = octeon_irq_ciu1_wd_enable_v2,
+};
 
-static struct irq_chip octeon_irq_chip_msi = {
-	.name = "MSI",
-	.enable = octeon_irq_msi_enable,
-	.disable = octeon_irq_msi_disable,
-	.ack = octeon_irq_msi_ack,
-	.eoi = octeon_irq_msi_eoi,
+static struct irq_chip octeon_irq_chip_ciu1_wd = {
+	.name = "CIU1-W",
+	.enable = octeon_irq_ciu1_wd_enable,
+	.disable = octeon_irq_ciu1_disable,
+	.eoi = octeon_irq_ciu1_eoi,
 };
-#endif
+
+static void (*octeon_ciu0_ack)(unsigned int);
+static void (*octeon_ciu1_ack)(unsigned int);
 
 void __init arch_init_irq(void)
 {
-	int irq;
+	unsigned int irq;
 	struct irq_chip *chip0;
-	struct irq_chip *chip0_timer;
+	struct irq_chip *chip0_mbox;
 	struct irq_chip *chip1;
+	struct irq_chip *chip1_wd;
 
 #ifdef CONFIG_SMP
 	/* Set the default affinity to the boot cpu. */
@@ -631,13 +692,19 @@ void __init arch_init_irq(void)
 	if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
+		octeon_ciu0_ack = octeon_irq_ciu0_ack_v2;
+		octeon_ciu1_ack = octeon_irq_ciu1_ack_v2;
 		chip0 = &octeon_irq_chip_ciu0_v2;
-		chip0_timer = &octeon_irq_chip_ciu0_timer_v2;
+		chip0_mbox = &octeon_irq_chip_ciu0_mbox_v2;
 		chip1 = &octeon_irq_chip_ciu1_v2;
+		chip1_wd = &octeon_irq_chip_ciu1_wd_v2;
 	} else {
+		octeon_ciu0_ack = octeon_irq_ciu0_ack;
+		octeon_ciu1_ack = octeon_irq_ciu1_ack;
 		chip0 = &octeon_irq_chip_ciu0;
-		chip0_timer = &octeon_irq_chip_ciu0_timer;
+		chip0_mbox = &octeon_irq_chip_ciu0_mbox;
 		chip1 = &octeon_irq_chip_ciu1;
+		chip1_wd = &octeon_irq_chip_ciu1_wd;
 	}
 
 	/* 0 - 15 reserved for i8259 master and slave controller. */
@@ -651,34 +718,23 @@ void __init arch_init_irq(void)
 	/* 24 - 87 CIU_INT_SUM0 */
 	for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
 		switch (irq) {
-		case OCTEON_IRQ_GMX_DRP0:
-		case OCTEON_IRQ_GMX_DRP1:
-		case OCTEON_IRQ_IPD_DRP:
-		case OCTEON_IRQ_KEY_ZERO:
-		case OCTEON_IRQ_TIMER0:
-		case OCTEON_IRQ_TIMER1:
-		case OCTEON_IRQ_TIMER2:
-		case OCTEON_IRQ_TIMER3:
-			set_irq_chip_and_handler(irq, chip0_timer, handle_percpu_irq);
+		case OCTEON_IRQ_MBOX0:
+		case OCTEON_IRQ_MBOX1:
+			set_irq_chip_and_handler(irq, chip0_mbox, handle_percpu_irq);
 			break;
 		default:
-			set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
+			set_irq_chip_and_handler(irq, chip0, handle_fasteoi_irq);
 			break;
 		}
 	}
 
 	/* 88 - 151 CIU_INT_SUM1 */
-	for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
-		set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
-	}
+	for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_WDOG15; irq++)
+		set_irq_chip_and_handler(irq, chip1_wd, handle_fasteoi_irq);
+
+	for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED151; irq++)
+		set_irq_chip_and_handler(irq, chip1, handle_fasteoi_irq);
 
-#ifdef CONFIG_PCI_MSI
-	/* 152 - 215 PCI/PCIe MSI interrupts */
-	for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
-		set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
-					 handle_percpu_irq);
-	}
-#endif
 	set_c0_status(0x300 << 2);
 }
 
@@ -693,6 +749,7 @@ asmlinkage void plat_irq_dispatch(void)
 	unsigned long cop0_status;
 	uint64_t ciu_en;
 	uint64_t ciu_sum;
+	unsigned int irq;
 
 	while (1) {
 		cop0_cause = read_c0_cause();
@@ -704,18 +761,24 @@ asmlinkage void plat_irq_dispatch(void)
 			ciu_sum = cvmx_read_csr(ciu_sum0_address);
 			ciu_en = cvmx_read_csr(ciu_en0_address);
 			ciu_sum &= ciu_en;
-			if (likely(ciu_sum))
-				do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1);
-			else
+			if (likely(ciu_sum)) {
+				irq = fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1;
+				octeon_ciu0_ack(irq);
+				do_IRQ(irq);
+			} else {
 				spurious_interrupt();
+			}
 		} else if (unlikely(cop0_cause & STATUSF_IP3)) {
 			ciu_sum = cvmx_read_csr(ciu_sum1_address);
 			ciu_en = cvmx_read_csr(ciu_en1_address);
 			ciu_sum &= ciu_en;
-			if (likely(ciu_sum))
-				do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1);
-			else
+			if (likely(ciu_sum)) {
+				irq = fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1;
+				octeon_ciu1_ack(irq);
+				do_IRQ(irq);
+			} else {
 				spurious_interrupt();
+			}
 		} else if (likely(cop0_cause)) {
 			do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
 		} else {
@@ -725,54 +788,84 @@ asmlinkage void plat_irq_dispatch(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu)
-{
-	unsigned int isset;
-	int coreid = octeon_coreid_for_cpu(cpu);
-	int bit = (irq < OCTEON_IRQ_WDOG0) ?
-		   irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0;
-       if (irq < 64) {
-		isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) &
-			(1ull << bit)) >> bit;
-       } else {
-	       isset = (cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)) &
-			(1ull << bit)) >> bit;
-       }
-       return isset;
-}
 
 void fixup_irqs(void)
 {
-       int irq;
+	int irq;
+	struct irq_desc *desc;
+	cpumask_t new_affinity;
+	unsigned long flags;
+	int do_set_affinity;
+	int cpu;
+
+	cpu = smp_processor_id();
 
 	for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++)
 		octeon_irq_core_disable_local(irq);
 
-	for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_GPIO15; irq++) {
-		if (is_irq_enabled_on_cpu(irq, smp_processor_id())) {
-			/* ciu irq migrates to next cpu */
-			octeon_irq_chip_ciu0.disable(irq);
-			octeon_irq_ciu0_set_affinity(irq, &cpu_online_map);
-		}
-	}
-
-#if 0
-	for (irq = OCTEON_IRQ_MBOX0; irq <= OCTEON_IRQ_MBOX1; irq++)
-		octeon_irq_mailbox_mask(irq);
-#endif
-	for (irq = OCTEON_IRQ_UART0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
-		if (is_irq_enabled_on_cpu(irq, smp_processor_id())) {
-			/* ciu irq migrates to next cpu */
-			octeon_irq_chip_ciu0.disable(irq);
-			octeon_irq_ciu0_set_affinity(irq, &cpu_online_map);
-		}
-	}
+	for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) {
+		desc = irq_to_desc(irq);
+		switch (irq) {
+		case OCTEON_IRQ_MBOX0:
+		case OCTEON_IRQ_MBOX1:
+			/* The eoi function will disable them on this CPU. */
+			desc->chip->eoi(irq);
+			break;
+		case OCTEON_IRQ_WDOG0:
+		case OCTEON_IRQ_WDOG1:
+		case OCTEON_IRQ_WDOG2:
+		case OCTEON_IRQ_WDOG3:
+		case OCTEON_IRQ_WDOG4:
+		case OCTEON_IRQ_WDOG5:
+		case OCTEON_IRQ_WDOG6:
+		case OCTEON_IRQ_WDOG7:
+		case OCTEON_IRQ_WDOG8:
+		case OCTEON_IRQ_WDOG9:
+		case OCTEON_IRQ_WDOG10:
+		case OCTEON_IRQ_WDOG11:
+		case OCTEON_IRQ_WDOG12:
+		case OCTEON_IRQ_WDOG13:
+		case OCTEON_IRQ_WDOG14:
+		case OCTEON_IRQ_WDOG15:
+			/*
+			 * These have special per CPU semantics and
+			 * are handled in the watchdog driver.
+			 */
+			break;
+		default:
+			raw_spin_lock_irqsave(&desc->lock, flags);
+			/*
+			 * If this irq has an action, it is in use and
+			 * must be migrated if it has affinity to this
+			 * cpu.
+			 */
+			if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) {
+				if (cpumask_weight(desc->affinity) > 1) {
+					/*
+					 * It has multi CPU affinity,
+					 * just remove this CPU from
+					 * the affinity set.
+					 */
+					cpumask_copy(&new_affinity, desc->affinity);
+					cpumask_clear_cpu(cpu, &new_affinity);
+				} else {
+					/*
+					 * Otherwise, put it on lowest
+					 * numbered online CPU.
+					 */
+					cpumask_clear(&new_affinity);
+					cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
+				}
+				do_set_affinity = 1;
+			} else {
+				do_set_affinity = 0;
+			}
+			raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+			if (do_set_affinity)
+				irq_set_affinity(irq, &new_affinity);
 
-	for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED135; irq++) {
-		if (is_irq_enabled_on_cpu(irq, smp_processor_id())) {
-			/* ciu irq migrates to next cpu */
-			octeon_irq_chip_ciu1.disable(irq);
-			octeon_irq_ciu1_set_affinity(irq, &cpu_online_map);
+			break;
 		}
 	}
 }
diff --git a/arch/mips/cavium-octeon/octeon_boot.h b/arch/mips/cavium-octeon/octeon_boot.h
index 0f7f84accf9a88b9fec5ccd56172ba6f74cc14e9..428864b2ba4133070c563023f9c170346e24c4ca 100644
--- a/arch/mips/cavium-octeon/octeon_boot.h
+++ b/arch/mips/cavium-octeon/octeon_boot.h
@@ -23,14 +23,16 @@
 #include <linux/types.h>
 
 struct boot_init_vector {
-	uint32_t stack_addr;
-	uint32_t code_addr;
+	/* First stage address - in ram instead of flash */
+	uint64_t code_addr;
+	/* Setup code for application, NOT application entry point */
 	uint32_t app_start_func_addr;
+	/* k0 is used for global data - needs to be passed to other cores */
 	uint32_t k0_val;
-	uint32_t flags;
-	uint32_t boot_info_addr;
+	/* Address of boot info block structure */
+	uint64_t boot_info_addr;
+	uint32_t flags;         /* flags */
 	uint32_t pad;
-	uint32_t pad2;
 };
 
 /* similar to bootloader's linux_app_boot_info but without global data */
@@ -40,7 +42,7 @@ struct linux_app_boot_info {
 	uint32_t avail_coremask;
 	uint32_t pci_console_active;
 	uint32_t icache_prefetch_disable;
-	uint32_t InitTLBStart_addr;
+	uint64_t InitTLBStart_addr;
 	uint32_t start_app_addr;
 	uint32_t cur_exception_base;
 	uint32_t no_mark_private_data;
@@ -58,7 +60,7 @@ struct linux_app_boot_info {
 
 #define LINUX_APP_BOOT_BLOCK_NAME "linux-app-boot"
 
-#define LABI_SIGNATURE 0xAABBCCDD
+#define LABI_SIGNATURE 0xAABBCC01
 
 /*  from uboot-headers/octeon_mem_map.h */
 #define EXCEPTION_BASE_INCR     (4 * 1024)
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
index 83eac37a1ff976a92bca4134b21591dfa179997a..638adab028428002186bb83c589b553a0c40545b 100644
--- a/arch/mips/cavium-octeon/serial.c
+++ b/arch/mips/cavium-octeon/serial.c
@@ -18,11 +18,7 @@
 
 #include <asm/octeon/octeon.h>
 
-#ifdef CONFIG_GDB_CONSOLE
-#define DEBUG_UART 0
-#else
 #define DEBUG_UART 1
-#endif
 
 unsigned int octeon_serial_in(struct uart_port *up, int offset)
 {
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index d1b5ffaf02819f75d8a123cdeea74e3430aa2025..69197cb6c7ea106349a23ad5b81f615a8c70c614 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -32,6 +32,7 @@
 #include <asm/time.h>
 
 #include <asm/octeon/octeon.h>
+#include <asm/octeon/pci-octeon.h>
 
 #ifdef CONFIG_CAVIUM_DECODE_RSL
 extern void cvmx_interrupt_rsl_decode(void);
@@ -578,9 +579,6 @@ void __init prom_init(void)
 	}
 
 	if (strstr(arcs_cmdline, "console=") == NULL) {
-#ifdef CONFIG_GDB_CONSOLE
-		strcat(arcs_cmdline, " console=gdb");
-#else
 #ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
 		strcat(arcs_cmdline, " console=ttyS0,115200");
 #else
@@ -588,7 +586,6 @@ void __init prom_init(void)
 			strcat(arcs_cmdline, " console=ttyS1,115200");
 		else
 			strcat(arcs_cmdline, " console=ttyS0,115200");
-#endif
 #endif
 	}
 
@@ -598,13 +595,13 @@ void __init prom_init(void)
 		 * the filesystem. Also specify the calibration delay
 		 * to avoid calculating it every time.
 		 */
-		strcat(arcs_cmdline, " rw root=1f00"
-		       " lpj=60176 slram=root,0x40000000,+1073741824");
+		strcat(arcs_cmdline, " rw root=1f00 slram=root,0x40000000,+1073741824");
 	}
 
 	mips_hpt_frequency = octeon_get_clock_rate();
 
 	octeon_init_cvmcount();
+	octeon_setup_delays();
 
 	_machine_restart = octeon_restart;
 	_machine_halt = octeon_halt;
@@ -613,6 +610,22 @@ void __init prom_init(void)
 	register_smp_ops(&octeon_smp_ops);
 }
 
+/* Exclude a single page from the regions obtained in plat_mem_setup. */
+static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size)
+{
+	if (addr > *mem && addr < *mem + *size) {
+		u64 inc = addr - *mem;
+		add_memory_region(*mem, inc, BOOT_MEM_RAM);
+		*mem += inc;
+		*size -= inc;
+	}
+
+	if (addr == *mem && *size > PAGE_SIZE) {
+		*mem += PAGE_SIZE;
+		*size -= PAGE_SIZE;
+	}
+}
+
 void __init plat_mem_setup(void)
 {
 	uint64_t mem_alloc_size;
@@ -663,12 +676,27 @@ void __init plat_mem_setup(void)
 						CVMX_BOOTMEM_FLAG_NO_LOCKING);
 #endif
 		if (memory >= 0) {
+			u64 size = mem_alloc_size;
+
+			/*
+			 * exclude a page at the beginning and end of
+			 * the 256MB PCIe 'hole' so the kernel will not
+			 * try to allocate multi-page buffers that
+			 * span the discontinuity.
+			 */
+			memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE,
+					    &memory, &size);
+			memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE +
+					    CVMX_PCIE_BAR1_PHYS_SIZE,
+					    &memory, &size);
+
 			/*
 			 * This function automatically merges address
 			 * regions next to each other if they are
 			 * received in incrementing order.
 			 */
-			add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
+			if (size)
+				add_memory_region(memory, size, BOOT_MEM_RAM);
 			total += mem_alloc_size;
 		} else {
 			break;
@@ -691,7 +719,10 @@ void __init plat_mem_setup(void)
 		      "cvmx_bootmem_phy_alloc\n");
 }
 
-
+/*
+ * Emit one character to the boot UART.  Exported for use by the
+ * watchdog timer.
+ */
 int prom_putchar(char c)
 {
 	uint64_t lsrval;
@@ -705,6 +736,7 @@ int prom_putchar(char c)
 	cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c & 0xffull);
 	return 1;
 }
+EXPORT_SYMBOL(prom_putchar);
 
 void prom_free_prom_memory(void)
 {
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 6d99b9d8887dd3d77ab4f94d79170fc0eacfbc25..391cefe556b3d025872b36b1ad38eb1ae850234c 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2008 Cavium Networks
+ * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
  */
 #include <linux/cpu.h>
 #include <linux/init.h>
@@ -27,7 +27,8 @@ volatile unsigned long octeon_processor_sp;
 volatile unsigned long octeon_processor_gp;
 
 #ifdef CONFIG_HOTPLUG_CPU
-static unsigned int InitTLBStart_addr;
+uint64_t octeon_bootloader_entry_addr;
+EXPORT_SYMBOL(octeon_bootloader_entry_addr);
 #endif
 
 static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
@@ -80,20 +81,13 @@ static inline void octeon_send_ipi_mask(const struct cpumask *mask,
 static void octeon_smp_hotplug_setup(void)
 {
 #ifdef CONFIG_HOTPLUG_CPU
-	uint32_t labi_signature;
-
-	labi_signature =
-		cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-					LABI_ADDR_IN_BOOTLOADER +
-					offsetof(struct linux_app_boot_info,
-						    labi_signature)));
-	if (labi_signature != LABI_SIGNATURE)
-		pr_err("The bootloader version on this board is incorrect\n");
-	InitTLBStart_addr =
-		cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-				   LABI_ADDR_IN_BOOTLOADER +
-					   offsetof(struct linux_app_boot_info,
-						    InitTLBStart_addr)));
+	struct linux_app_boot_info *labi;
+
+	labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+	if (labi->labi_signature != LABI_SIGNATURE)
+		panic("The bootloader version on this board is incorrect.");
+
+	octeon_bootloader_entry_addr = labi->InitTLBStart_addr;
 #endif
 }
 
@@ -102,24 +96,47 @@ static void octeon_smp_setup(void)
 	const int coreid = cvmx_get_core_num();
 	int cpus;
 	int id;
-
 	int core_mask = octeon_get_boot_coremask();
+#ifdef CONFIG_HOTPLUG_CPU
+	unsigned int num_cores = cvmx_octeon_num_cores();
+#endif
+
+	/* The present CPUs are initially just the boot cpu (CPU 0). */
+	for (id = 0; id < NR_CPUS; id++) {
+		set_cpu_possible(id, id == 0);
+		set_cpu_present(id, id == 0);
+	}
 
-	cpus_clear(cpu_possible_map);
 	__cpu_number_map[coreid] = 0;
 	__cpu_logical_map[0] = coreid;
-	cpu_set(0, cpu_possible_map);
 
+	/* The present CPUs get the lowest CPU numbers. */
 	cpus = 1;
-	for (id = 0; id < 16; id++) {
+	for (id = 0; id < NR_CPUS; id++) {
 		if ((id != coreid) && (core_mask & (1 << id))) {
-			cpu_set(cpus, cpu_possible_map);
+			set_cpu_possible(cpus, true);
+			set_cpu_present(cpus, true);
 			__cpu_number_map[id] = cpus;
 			__cpu_logical_map[cpus] = id;
 			cpus++;
 		}
 	}
-	cpu_present_map = cpu_possible_map;
+
+#ifdef CONFIG_HOTPLUG_CPU
+	/*
+	 * The possible CPUs are all those present on the chip.  We
+	 * will assign CPU numbers for possible cores as well.  Cores
+	 * are always consecutively numberd from 0.
+	 */
+	for (id = 0; id < num_cores && id < NR_CPUS; id++) {
+		if (!(core_mask & (1 << id))) {
+			set_cpu_possible(cpus, true);
+			__cpu_number_map[id] = cpus;
+			__cpu_logical_map[cpus] = id;
+			cpus++;
+		}
+	}
+#endif
 
 	octeon_smp_hotplug_setup();
 }
@@ -158,18 +175,21 @@ static void octeon_init_secondary(void)
 {
 	const int coreid = cvmx_get_core_num();
 	union cvmx_ciu_intx_sum0 interrupt_enable;
+	unsigned int sr;
 
 #ifdef CONFIG_HOTPLUG_CPU
-	unsigned int cur_exception_base;
-
-	cur_exception_base = cvmx_read64_uint32(
-		CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-			     LABI_ADDR_IN_BOOTLOADER +
-			     offsetof(struct linux_app_boot_info,
-				      cur_exception_base)));
-	/* cur_exception_base is incremented in bootloader after setting */
-	write_c0_ebase((unsigned int)(cur_exception_base - EXCEPTION_BASE_INCR));
+	struct linux_app_boot_info *labi;
+
+	labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+	if (labi->labi_signature != LABI_SIGNATURE)
+		panic("The bootloader version on this board is incorrect.");
 #endif
+
+	sr = set_c0_status(ST0_BEV);
+	write_c0_ebase((u32)ebase);
+	write_c0_status(sr);
+
 	octeon_check_cpu_bist();
 	octeon_init_cvmcount();
 	/*
@@ -276,8 +296,8 @@ static int octeon_cpu_disable(void)
 static void octeon_cpu_die(unsigned int cpu)
 {
 	int coreid = cpu_logical_map(cpu);
-	uint32_t avail_coremask;
-	struct cvmx_bootmem_named_block_desc *block_desc;
+	uint32_t mask, new_mask;
+	const struct cvmx_bootmem_named_block_desc *block_desc;
 
 	while (per_cpu(cpu_state, cpu) != CPU_DEAD)
 		cpu_relax();
@@ -286,52 +306,40 @@ static void octeon_cpu_die(unsigned int cpu)
 	 * This is a bit complicated strategics of getting/settig available
 	 * cores mask, copied from bootloader
 	 */
+
+	mask = 1 << coreid;
 	/* LINUX_APP_BOOT_BLOCK is initialized in bootoct binary */
 	block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME);
 
 	if (!block_desc) {
-		avail_coremask =
-			cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-						   LABI_ADDR_IN_BOOTLOADER +
-						   offsetof
-						   (struct linux_app_boot_info,
-						    avail_coremask)));
-	} else {		       /* alternative, already initialized */
-	       avail_coremask =
-		   cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-						   block_desc->base_addr +
-						  AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK));
-	}
+		struct linux_app_boot_info *labi;
 
-	avail_coremask |= 1 << coreid;
+		labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
 
-	/* Setting avail_coremask for bootoct binary */
-	if (!block_desc) {
-		cvmx_write64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-						LABI_ADDR_IN_BOOTLOADER +
-						offsetof(struct linux_app_boot_info,
-							 avail_coremask)),
-				   avail_coremask);
-	} else {
-		cvmx_write64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-						block_desc->base_addr +
-						AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK),
-				   avail_coremask);
+		labi->avail_coremask |= mask;
+		new_mask = labi->avail_coremask;
+	} else {		       /* alternative, already initialized */
+		uint32_t *p = (uint32_t *)PHYS_TO_XKSEG_CACHED(block_desc->base_addr +
+							       AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK);
+		*p |= mask;
+		new_mask = *p;
 	}
 
-	pr_info("Reset core %d. Available Coremask = %x\n", coreid,
-		avail_coremask);
+	pr_info("Reset core %d. Available Coremask = 0x%x \n", coreid, new_mask);
+	mb();
 	cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid);
 	cvmx_write_csr(CVMX_CIU_PP_RST, 0);
 }
 
 void play_dead(void)
 {
-	int coreid = cvmx_get_core_num();
+	int cpu = cpu_number_map(cvmx_get_core_num());
 
 	idle_task_exit();
 	octeon_processor_boot = 0xff;
-	per_cpu(cpu_state, coreid) = CPU_DEAD;
+	per_cpu(cpu_state, cpu) = CPU_DEAD;
+
+	mb();
 
 	while (1)	/* core will be reset here */
 		;
@@ -344,29 +352,27 @@ static void start_after_reset(void)
 	kernel_entry(0, 0, 0);  /* set a2 = 0 for secondary core */
 }
 
-int octeon_update_boot_vector(unsigned int cpu)
+static int octeon_update_boot_vector(unsigned int cpu)
 {
 
 	int coreid = cpu_logical_map(cpu);
-	unsigned int avail_coremask;
-	struct cvmx_bootmem_named_block_desc *block_desc;
+	uint32_t avail_coremask;
+	const struct cvmx_bootmem_named_block_desc *block_desc;
 	struct boot_init_vector *boot_vect =
-		(struct boot_init_vector *) cvmx_phys_to_ptr(0x0 +
-						  BOOTLOADER_BOOT_VECTOR);
+		(struct boot_init_vector *)PHYS_TO_XKSEG_CACHED(BOOTLOADER_BOOT_VECTOR);
 
 	block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME);
 
 	if (!block_desc) {
-		avail_coremask =
-			cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-					   LABI_ADDR_IN_BOOTLOADER +
-						offsetof(struct linux_app_boot_info,
-						avail_coremask)));
+		struct linux_app_boot_info *labi;
+
+		labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+		avail_coremask = labi->avail_coremask;
+		labi->avail_coremask &= ~(1 << coreid);
 	} else {		       /* alternative, already initialized */
-	       avail_coremask =
-		   cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
-						   block_desc->base_addr +
-						   AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK));
+		avail_coremask = *(uint32_t *)PHYS_TO_XKSEG_CACHED(
+			block_desc->base_addr + AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK);
 	}
 
 	if (!(avail_coremask & (1 << coreid))) {
@@ -377,9 +383,9 @@ int octeon_update_boot_vector(unsigned int cpu)
 
 	boot_vect[coreid].app_start_func_addr =
 		(uint32_t) (unsigned long) start_after_reset;
-	boot_vect[coreid].code_addr = InitTLBStart_addr;
+	boot_vect[coreid].code_addr = octeon_bootloader_entry_addr;
 
-	CVMX_SYNC;
+	mb();
 
 	cvmx_write_csr(CVMX_CIU_NMI, (1 << coreid) & avail_coremask);
 
@@ -405,17 +411,11 @@ static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb,
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata octeon_cpu_notifier = {
-	.notifier_call = octeon_cpu_callback,
-};
-
 static int __cpuinit register_cavium_notifier(void)
 {
-	register_hotcpu_notifier(&octeon_cpu_notifier);
-
+	hotcpu_notifier(octeon_cpu_callback, 0);
 	return 0;
 }
-
 late_initcall(register_cavium_notifier);
 
 #endif  /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 237926288d6d57ff5fb15feebeadda3a0cedf505..61a334ac43ac7c52565713e4a45ed882da57132d 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -7,5 +7,3 @@ obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_EARLY_PRINTK)	+= console.o
 obj-$(CONFIG_MTD_PHYSMAP)	+= mtd.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cobalt/Platform b/arch/mips/cobalt/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..34123efd6dfeb6bd6af588632228d0fbb88b3840
--- /dev/null
+++ b/arch/mips/cobalt/Platform
@@ -0,0 +1,6 @@
+#
+# Cobalt Server
+#
+platform-$(CONFIG_MIPS_COBALT)	+= cobalt/
+cflags-$(CONFIG_MIPS_COBALT)	+= -I$(srctree)/arch/mips/include/asm/mach-cobalt
+load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index f66d406aadceac31d47599bd88e480adf120eb3e..3a9ec6ccd40df637f1d8676eb83aa45fa0f2c572 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_DB1000=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1000=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index abb9a5805adcca5ef362eb620bcd24d0aa0f4dac..4589b84301f3f59545920374f81f7ee9ac6a09c6 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_DB1100=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1100=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 991c20adf471cbf25035d5065d550c7774e534b1..9950f2aabd318d8b166ca32c015f48699ed5fb5a 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_DB1200=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1200=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 5424c9167bf2b891e2e711d81c85c863aeb95679..346ae631d1ef9c7451a53191beb2bae1ec782ffb 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_DB1500=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1500=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 949b6dcf634b873e75cc9e2a49fe322dfc368641..10eafb942af3306d361c44e5a5d37a75b62fdda4 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_DB1550=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1550=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..17e2e624d03fc1bf6a9296d2b67845fbd14178ae
--- /dev/null
+++ b/arch/mips/configs/gpr_defconfig
@@ -0,0 +1,2060 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35-rc6
+# Fri Jul 23 19:28:52 2010
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+CONFIG_MIPS_ALCHEMY=y
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_MIPS_GPR=y
+CONFIG_SOC_AU1550=y
+CONFIG_LOONGSON_UART_BASE=y
+# CONFIG_LOONGSON_MC146818 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=m
+
+#
+# Xtables targets
+#
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HL=m
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+# CONFIG_IP_VS_PROTO_SCTP is not set
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+# CONFIG_BRIDGE_EBT_NFLOG is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+# CONFIG_NET_SCH_MULTIQ is not set
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+# CONFIG_NET_SCH_DRR is not set
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+# CONFIG_NET_ACT_GACT is not set
+# CONFIG_NET_ACT_MIRRED is not set
+# CONFIG_NET_ACT_IPT is not set
+# CONFIG_NET_ACT_NAT is not set
+# CONFIG_NET_ACT_PEDIT is not set
+# CONFIG_NET_ACT_SIMP is not set
+# CONFIG_NET_ACT_SKBEDIT is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=m
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_HOST_SMP=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+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_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
+CONFIG_ATH_COMMON=y
+CONFIG_ATH_DEBUG=y
+CONFIG_ATH5K=y
+CONFIG_ATH5K_DEBUG=y
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_AR9170_USB is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WAN=y
+CONFIG_LANMEDIA=m
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_RAW_ETH=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+CONFIG_HDLC_X25=m
+CONFIG_PCI200SYN=m
+CONFIG_WANXL=m
+# CONFIG_PC300TOO is not set
+CONFIG_FARSYNC=m
+CONFIG_DSCC4=m
+CONFIG_DSCC4_PCISYNC=y
+CONFIG_DSCC4_PCI_RST=y
+CONFIG_DLCI=m
+CONFIG_DLCI_MAX=8
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_CYCLADES_SYNC=m
+CONFIG_CYCLOMX_X25=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+CONFIG_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+CONFIG_ATM_ZATM=m
+# CONFIG_ATM_ZATM_DEBUG is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_IA=m
+# CONFIG_ATM_IA_DEBUG is not set
+CONFIG_ATM_FORE200E=m
+# CONFIG_ATM_FORE200E_USE_TASKLET is not set
+CONFIG_ATM_FORE200E_TX_RETRY=16
+CONFIG_ATM_FORE200E_DEBUG=0
+CONFIG_ATM_HE=m
+CONFIG_ATM_HE_USE_SUNI=y
+# CONFIG_ATM_SOLOS is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+CONFIG_NETCONSOLE=m
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_AU1550 is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_CS5535 is not set
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+CONFIG_SENSORS_LM83=y
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_DRIVER_MIPS is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TC35892 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_3M_PCT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EGALAX is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+CONFIG_USB_SERIAL_SIERRAWIRELESS=y
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_ATM is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_LKDTM is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw ip=auto"
+# CONFIG_CMDLINE_OVERRIDE is not set
+# CONFIG_SPINLOCK_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index cff8f4c0e57c4a5a8c666333b32e6a85676e94a9..10d20aa731d3a1493117e13c47a373209dcc65d1 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_MTX1=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1500=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 97382b698b9be94c1c68961f912eea7341db9b77..778f726af8e079320b2ac91cd0c231279673e73f 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_PB1100=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1100=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/pb1200_defconfig b/arch/mips/configs/pb1200_defconfig
index e9ad77320f168f5a7d4d11e246cda843a082ab99..0f908c6921114630aa9269d8e673bf1a61bfa76e 100644
--- a/arch/mips/configs/pb1200_defconfig
+++ b/arch/mips/configs/pb1200_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_PB1200=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1200=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 7497d3306b91f4a1c52862579432c6c9ccb84fc5..1c5fe6f06c0e9573af846934fbf91948b4e5455e 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_MIPS_PB1500=y
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1500=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index aa526f53cb1b1db8c179fdc350a731eba84c655a..49494b01138b6a8824394870923ca263bf749858 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS=y
 #
 # Machine selection
 #
-CONFIG_MACH_ALCHEMY=y
+CONFIG_MIPS_ALCHEMY=y
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
@@ -64,7 +64,6 @@ CONFIG_ALCHEMY_GPIOINT_AU1000=y
 CONFIG_MIPS_PB1550=y
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_SOC_AU1550=y
-CONFIG_SOC_AU1X00=y
 CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
index 7291633d81ccf9f80962fa95ba569293bff24fd5..af0ab73bfce8feeeda03b192b9ef5f9a1c7e09c9 100644
--- a/arch/mips/configs/powertv_defconfig
+++ b/arch/mips/configs/powertv_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc5
-# Fri Aug 28 14:49:33 2009
+# Linux kernel version: 2.6.35-rc3
+# Thu Jul  1 11:03:28 2010
 #
 CONFIG_MIPS=y
 
@@ -11,11 +11,12 @@ CONFIG_MIPS=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
 # CONFIG_NEC_MARKEINS is not set
@@ -50,7 +51,6 @@ CONFIG_POWERTV=y
 # CONFIG_MIN_RUNTIME_RESOURCES is not set
 # CONFIG_BOOTLOADER_DRIVER is not set
 CONFIG_BOOTLOADER_FAMILY="R2"
-CONFIG_CSRC_POWERTV=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -65,9 +65,9 @@ CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_CEVT_R4K_LIB=y
 CONFIG_CEVT_R4K=y
+CONFIG_CSRC_POWERTV=y
 CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
@@ -79,7 +79,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 CONFIG_CPU_MIPS32_R2=y
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -122,7 +123,7 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_IRQ_EI=y
 CONFIG_CPU_HAS_SYNC=y
@@ -144,8 +145,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -177,6 +177,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="mips-linux-"
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
@@ -190,19 +191,15 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=16
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
 # CONFIG_NAMESPACES is not set
@@ -211,6 +208,7 @@ CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_RD_GZIP is not set
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -234,18 +232,16 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 
 #
@@ -253,7 +249,7 @@ CONFIG_HAVE_OPROFILE=y
 #
 # CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
@@ -271,15 +267,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_PROBE_INITRD_HEADER is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -289,7 +311,6 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -318,7 +339,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -390,12 +410,26 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+
+#
+# Xtables targets
+#
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_MARK is not set
 # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 # CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
 # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
 # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+
+#
+# Xtables matches
+#
 # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
 # CONFIG_NETFILTER_XT_MATCH_DCCP is not set
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
@@ -465,10 +499,13 @@ CONFIG_IP6_NF_FILTER=y
 # CONFIG_IP6_NF_RAW is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+# CONFIG_L2TP is not set
 CONFIG_STP=y
 CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
@@ -526,10 +563,21 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
 
 #
 # Device Drivers
@@ -539,6 +587,7 @@ CONFIG_NET_SCH_FIFO=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -550,9 +599,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
@@ -568,6 +617,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
 # CONFIG_MTD_OOPS is not set
 
 #
@@ -611,11 +661,16 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
 CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_SM_COMMON is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_DENALI is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
 CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
@@ -641,6 +696,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -658,6 +717,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -693,64 +753,95 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
 # CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_AHCI_PLATFORM is not set
+# CONFIG_SATA_INIC162X is not set
 # CONFIG_SATA_SIL24 is not set
 CONFIG_ATA_SFF=y
-# CONFIG_SATA_SVW is not set
+
+#
+# SFF controllers with custom DMA interface
+#
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
 # CONFIG_ATA_PIIX is not set
 # CONFIG_SATA_MV is not set
 # CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
 # CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
 # CONFIG_SATA_SIL is not set
 # CONFIG_SATA_SIS is not set
+# CONFIG_SATA_SVW is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
 # CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
 # CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_CMD64X is not set
 # CONFIG_PATA_CS5520 is not set
 # CONFIG_PATA_CS5530 is not set
 # CONFIG_PATA_CYPRESS is not set
 # CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
 # CONFIG_PATA_HPT366 is not set
 # CONFIG_PATA_HPT37X is not set
 # CONFIG_PATA_HPT3X2N is not set
 # CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
 # CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
 # CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_SCH is not set
+# CONFIG_PATA_RZ1000 is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
@@ -763,7 +854,7 @@ CONFIG_ATA_SFF=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -787,6 +878,7 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -800,6 +892,7 @@ CONFIG_MII=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
@@ -829,6 +922,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -841,16 +936,12 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -864,6 +955,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_USB_PEGASUS is not set
 CONFIG_USB_RTL8150=y
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -873,6 +965,7 @@ CONFIG_USB_RTL8150=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -882,6 +975,7 @@ CONFIG_USB_RTL8150=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -913,6 +1007,7 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
 # CONFIG_NOZOMI is not set
 
 #
@@ -924,6 +1019,9 @@ CONFIG_INPUT_EVDEV=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -934,6 +1032,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
 
@@ -945,7 +1044,6 @@ CONFIG_DEVPORT=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -953,20 +1051,14 @@ CONFIG_SSB_POSSIBLE=y
 # Sonics Silicon Backplane
 #
 # CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_SUPPORT is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGA_ARB is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -980,7 +1072,6 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -993,31 +1084,43 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO is not set
 # CONFIG_HID_CHERRY is not set
 # CONFIG_HID_CHICONY is not set
 # CONFIG_HID_CYPRESS is not set
 # CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EGALAX is not set
 # CONFIG_HID_EZKEY is not set
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
 # CONFIG_HID_TOPSEED is not set
 # CONFIG_HID_THRUSTMASTER is not set
 # CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1032,7 +1135,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 # CONFIG_USB_MON is not set
@@ -1050,6 +1152,7 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1133,6 +1236,7 @@ CONFIG_USB_SERIAL_CP210X=y
 # CONFIG_USB_SERIAL_NAVMAN is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1146,6 +1250,8 @@ CONFIG_USB_SERIAL_CP210X=y
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1158,7 +1264,6 @@ CONFIG_USB_SERIAL_CP210X=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1171,7 +1276,6 @@ CONFIG_USB_SERIAL_CP210X=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1189,10 +1293,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
-
-#
-# TI VLYNQ
-#
 # CONFIG_STAGING is not set
 
 #
@@ -1214,6 +1314,7 @@ CONFIG_JBD=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -1274,6 +1375,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1284,7 +1386,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1299,6 +1400,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1360,6 +1462,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1393,15 +1496,25 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
@@ -1410,19 +1523,22 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
+# CONFIG_EARLY_PRINTK is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M"
+CONFIG_CMDLINE=""
 # CONFIG_CMDLINE_OVERRIDE is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_SPINLOCK_TEST is not set
 
 #
 # Security options
@@ -1430,13 +1546,16 @@ CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
@@ -1479,11 +1598,13 @@ CONFIG_CRYPTO_CBC=y
 #
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
index c530208ee15494ce22c09ca247ed1ba32b70ce1d..9eb2f9c036aad596584427a5512255aab1769f8b 100644
--- a/arch/mips/dec/Makefile
+++ b/arch/mips/dec/Makefile
@@ -8,5 +8,3 @@ obj-y		:= ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
 obj-$(CONFIG_TC)		+= tc.o
 obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/dec/Platform b/arch/mips/dec/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..3adbcbd95db1efd4dbb18fba91bc978153079d7f
--- /dev/null
+++ b/arch/mips/dec/Platform
@@ -0,0 +1,8 @@
+#
+# DECstation family
+#
+platform-$(CONFIG_MACH_DECSTATION)	= dec/
+cflags-$(CONFIG_MACH_DECSTATION)	+= \
+			-I$(srctree)/arch/mips/include/asm/mach-dec
+libs-$(CONFIG_MACH_DECSTATION)		+= arch/mips/dec/prom/
+load-$(CONFIG_MACH_DECSTATION)		+= 0xffffffff80040000
diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c
index 9f0972f5a7023f8ff416cb44700d1c5872026650..c239c25b79ff90bcfb1bb3f43648570d81d10138 100644
--- a/arch/mips/dec/promcon.c
+++ b/arch/mips/dec/promcon.c
@@ -33,8 +33,7 @@ static int __init prom_console_setup(struct console *co, char *options)
 	return 0;
 }
 
-static struct console sercons =
-{
+static struct console sercons = {
 	.name	= "ttyS",
 	.write	= prom_console_write,
 	.setup	= prom_console_setup,
diff --git a/arch/mips/emma/Makefile b/arch/mips/emma/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4254a31edb099894a9fed0aa9a3dac5bf2f67bbc
--- /dev/null
+++ b/arch/mips/emma/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SOC_EMMA2RH)	+= common/
+
+#
+# NEC EMMA2RH Mark-eins
+#
+obj-$(CONFIG_NEC_MARKEINS)	+= markeins/
diff --git a/arch/mips/emma/Platform b/arch/mips/emma/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..0282f7f99b8870d83e8e482cb6135afcaa008b94
--- /dev/null
+++ b/arch/mips/emma/Platform
@@ -0,0 +1,4 @@
+platform-$(CONFIG_SOC_EMMA2RH)	+= emma/
+cflags-$(CONFIG_SOC_EMMA2RH)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-emma2rh
+load-$(CONFIG_NEC_MARKEINS)	+= 0xffffffff88100000
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 9504b7ee0b7c0d51a5adf1c3fd4fa702d414b660..3a96799eb65fec6b25b87e53fbf13b74c12464de 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -301,7 +301,7 @@ void __init arch_init_irq(void)
 	/* setup cascade interrupts */
 	setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade);
 	setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade);
-	setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade);
+	setup_irq(MIPS_CPU_IRQ_BASE + 2, &irq_cascade);
 }
 
 asmlinkage void plat_irq_dispatch(void)
@@ -309,13 +309,13 @@ asmlinkage void plat_irq_dispatch(void)
         unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP7)
-		do_IRQ(CPU_IRQ_BASE + 7);
+		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
 	else if (pending & STATUSF_IP2)
 		emma2rh_irq_dispatch();
 	else if (pending & STATUSF_IP1)
-		do_IRQ(CPU_IRQ_BASE + 1);
+		do_IRQ(MIPS_CPU_IRQ_BASE + 1);
 	else if (pending & STATUSF_IP0)
-		do_IRQ(CPU_IRQ_BASE + 0);
+		do_IRQ(MIPS_CPU_IRQ_BASE + 0);
 	else
 		spurious_interrupt();
 }
diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c
index 9b3f51e5f140219120c8cdfe2df85487d5bf7ab4..feceebcfff4269bd9d740749d080aae7831673ba 100644
--- a/arch/mips/emma/markeins/setup.c
+++ b/arch/mips/emma/markeins/setup.c
@@ -52,7 +52,6 @@ static void markeins_machine_halt(void)
 
 static void markeins_machine_power_off(void)
 {
-	printk("EMMA2RH Mark-eins halted. Please turn off the power.\n");
 	markeins_led("poweroff.");
 	while (1) ;
 }
diff --git a/arch/mips/include/asm/arch_hweight.h b/arch/mips/include/asm/arch_hweight.h
new file mode 100644
index 0000000000000000000000000000000000000000..712a7445ee93a11082afb9e781e4393296b1ec3b
--- /dev/null
+++ b/arch/mips/include/asm/arch_hweight.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ */
+#ifndef _ASM_ARCH_HWEIGHT_H
+#define _ASM_ARCH_HWEIGHT_H
+
+#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+	return __builtin_popcount(w);
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+	return __builtin_popcount(w & 0xffff);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+	return __builtin_popcount(w & 0xff);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+	return __builtin_popcountll(w);
+}
+
+#else
+#include <asm-generic/bitops/arch_hweight.h>
+#endif
+
+#endif /* _ASM_ARCH_HWEIGHT_H */
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 9255cfbee4596b2281a470a740d8bb0d493d5700..b0ce7ca2851f8fc32413e407942cc7367d6643d9 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -700,7 +700,10 @@ static inline int ffs(int word)
 #ifdef __KERNEL__
 
 #include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/hweight.h>
+
+#include <asm/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
+
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/minix.h>
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 09eee09780f2335b0153fe656b4aafcac8d217ec..15a8ef0707c695538fa5463d1ac05893e91f55b4 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -71,6 +71,12 @@
 #define MACH_LEMOTE_LL2F       7
 #define MACH_LOONGSON_END      8
 
+/*
+ * Valid machtype for group INGENIC
+ */
+#define  MACH_INGENIC_JZ4730	0	/* JZ4730 SOC		*/
+#define  MACH_INGENIC_JZ4740	1	/* JZ4740 SOC		*/
+
 extern char *system_type;
 const char *get_system_type(void);
 
diff --git a/arch/mips/include/asm/break.h b/arch/mips/include/asm/break.h
index 44437ed765e899a52caa04bd81f0c8036a9c2f64..9161e684cb4c6ce81cf9875024e0301893c8063d 100644
--- a/arch/mips/include/asm/break.h
+++ b/arch/mips/include/asm/break.h
@@ -30,6 +30,8 @@
 #define BRK_BUG		512	/* Used by BUG() */
 #define BRK_KDB		513	/* Used in KDB_ENTER() */
 #define BRK_MEMU	514	/* Used by FPU emulator */
+#define BRK_KPROBE_BP	515	/* Kprobe break */
+#define BRK_KPROBE_SSTEPBP 516	/* Kprobe single step software implementation */
 #define BRK_MULOVF	1023	/* Multiply overflow */
 
 #endif /* __ASM_BREAK_H */
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
index 256ad2cc6eb8f8a4bb242ae383f50266eea47270..8f99c11ab6657d8f8ab68a61155f01b1ff20bfdb 100644
--- a/arch/mips/include/asm/cacheops.h
+++ b/arch/mips/include/asm/cacheops.h
@@ -62,6 +62,8 @@
  * RM7000-specific cacheops
  */
 #define Page_Invalidate_T	0x16
+#define Index_Store_Tag_T	0x0a
+#define Index_Load_Tag_T	0x06
 
 /*
  * R10000-specific cacheops
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
index 6b04c98b7fad1dd5be1ff7a64e9cda1b88537835..2cb2f0c2c4f89342ae5256a79d8082f01af4d319 100644
--- a/arch/mips/include/asm/cop2.h
+++ b/arch/mips/include/asm/cop2.h
@@ -9,6 +9,8 @@
 #ifndef __ASM_COP2_H
 #define __ASM_COP2_H
 
+#include <linux/notifier.h>
+
 enum cu2_ops {
 	CU2_EXCEPTION,
 	CU2_LWC2_OP,
@@ -20,4 +22,14 @@ enum cu2_ops {
 extern int register_cu2_notifier(struct notifier_block *nb);
 extern int cu2_notifier_call_chain(unsigned long val, void *v);
 
+#define cu2_notifier(fn, pri)						\
+({									\
+	static struct notifier_block fn##_nb __cpuinitdata = {		\
+		.notifier_call = fn,					\
+		.priority = pri						\
+	};								\
+									\
+	register_cu2_notifier(&fn##_nb);				\
+})
+
 #endif /* __ASM_COP2_H */
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index ac73cede3a0a5eec6487b97433e618daa5efea39..ca400f7c3f594944d31a7b1341b6aa04d7e4c757 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -159,7 +159,8 @@
 
 /*
  * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
- * pre-MIPS32/MIPS53 processors have CLO, CLZ.  For 64-bit kernels
+ * pre-MIPS32/MIPS53 processors have CLO, CLZ.  The IDT RC64574 is 64-bit and
+ * has CLO and CLZ but not DCLO nor DCLZ.  For 64-bit kernels
  * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
  */
 # ifndef cpu_has_clo_clz
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index a5acda41694696f598c957e0a1d8124dfb7d40cf..b201a8f5b127898ff645cfe0da800158a3b6595d 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -34,7 +34,7 @@
 #define PRID_COMP_LSI		0x080000
 #define PRID_COMP_LEXRA		0x0b0000
 #define PRID_COMP_CAVIUM	0x0d0000
-
+#define PRID_COMP_INGENIC	0xd00000
 
 /*
  * Assigned values for the product ID register.  In order to detect a
@@ -132,6 +132,12 @@
 #define PRID_IMP_CAVIUM_CN50XX 0x0600
 #define PRID_IMP_CAVIUM_CN52XX 0x0700
 
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
+ */
+
+#define PRID_IMP_JZRISC        0x0200
+
 /*
  * Definitions for 7:0 on legacy processors
  */
@@ -219,6 +225,7 @@ enum cpu_type_enum {
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
 	CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
 	CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
+	CPU_JZRISC,
 
 	/*
 	 * MIPS64 class processors
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index ea77a42c5f8cb1bfc6ae03e131b60dde810f87bf..fd1d39eb74319b60473daf46cb5e4ecf1bcacb2e 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -372,4 +372,9 @@ extern const char *__elf_platform;
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int uses_interp);
+
+struct mm_struct;
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
 #endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/emma/emma2rh.h b/arch/mips/include/asm/emma/emma2rh.h
index 2afb2fe11b300a84d4332970788058b78c35eeb2..c1449d20ef0e3022e5e3ee9c229b800f4c017bbc 100644
--- a/arch/mips/include/asm/emma/emma2rh.h
+++ b/arch/mips/include/asm/emma/emma2rh.h
@@ -99,88 +99,22 @@
 #define EMMA2RH_PCI_CONFIG_BASE	EMMA2RH_PCI_IO_BASE
 #define EMMA2RH_PCI_CONFIG_SIZE	EMMA2RH_PCI_IO_SIZE
 
-#define NUM_CPU_IRQ		8
 #define NUM_EMMA2RH_IRQ		96
 
-#define CPU_EMMA2RH_CASCADE	2
-#define CPU_IRQ_BASE		MIPS_CPU_IRQ_BASE
-#define EMMA2RH_IRQ_BASE	(CPU_IRQ_BASE + NUM_CPU_IRQ)
+#define EMMA2RH_IRQ_BASE	(MIPS_CPU_IRQ_BASE + 8)
 
 /*
  * emma2rh irq defs
  */
 
-#define EMMA2RH_IRQ_INT0	(0 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT1	(1 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT2	(2 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT3	(3 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT4	(4 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT5	(5 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT6	(6 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT7	(7 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT8	(8 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT9	(9 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT10	(10 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT11	(11 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT12	(12 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT13	(13 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT14	(14 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT15	(15 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT16	(16 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT17	(17 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT18	(18 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT19	(19 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT20	(20 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT21	(21 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT22	(22 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT23	(23 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT24	(24 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT25	(25 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT26	(26 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT27	(27 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT28	(28 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT29	(29 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT30	(30 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT31	(31 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT32	(32 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT33	(33 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT34	(34 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT35	(35 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT36	(36 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT37	(37 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT38	(38 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT39	(39 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT40	(40 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT41	(41 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT42	(42 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT43	(43 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT44	(44 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT45	(45 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT46	(46 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT47	(47 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT48	(48 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT49	(49 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT50	(50 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT51	(51 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT52	(52 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT53	(53 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT54	(54 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT55	(55 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT56	(56 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT57	(57 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT58	(58 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT59	(59 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT60	(60 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT61	(61 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT62	(62 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT63	(63 + EMMA2RH_IRQ_BASE)
-
-#define EMMA2RH_IRQ_PFUR0	EMMA2RH_IRQ_INT49
-#define EMMA2RH_IRQ_PFUR1	EMMA2RH_IRQ_INT50
-#define EMMA2RH_IRQ_PFUR2	EMMA2RH_IRQ_INT51
-#define EMMA2RH_IRQ_PIIC0	EMMA2RH_IRQ_INT56
-#define EMMA2RH_IRQ_PIIC1	EMMA2RH_IRQ_INT57
-#define EMMA2RH_IRQ_PIIC2	EMMA2RH_IRQ_INT58
+#define EMMA2RH_IRQ_INT(n)	(EMMA2RH_IRQ_BASE + (n))
+
+#define EMMA2RH_IRQ_PFUR0	EMMA2RH_IRQ_INT(49)
+#define EMMA2RH_IRQ_PFUR1	EMMA2RH_IRQ_INT(50)
+#define EMMA2RH_IRQ_PFUR2	EMMA2RH_IRQ_INT(51)
+#define EMMA2RH_IRQ_PIIC0	EMMA2RH_IRQ_INT(56)
+#define EMMA2RH_IRQ_PIIC1	EMMA2RH_IRQ_INT(57)
+#define EMMA2RH_IRQ_PIIC2	EMMA2RH_IRQ_INT(58)
 
 /*
  *  EMMA2RH Register Access
diff --git a/arch/mips/include/asm/emma/markeins.h b/arch/mips/include/asm/emma/markeins.h
index 2618bf230248b5e1711e7a2a83bae5f7eae9f9d1..bf2d229c2dae602738fc3ff3c14274d065881fbd 100644
--- a/arch/mips/include/asm/emma/markeins.h
+++ b/arch/mips/include/asm/emma/markeins.h
@@ -25,44 +25,13 @@
 #define NUM_EMMA2RH_IRQ_SW	32
 #define NUM_EMMA2RH_IRQ_GPIO	32
 
-#define EMMA2RH_SW_CASCADE	(EMMA2RH_IRQ_INT7 - EMMA2RH_IRQ_INT0)
-#define EMMA2RH_GPIO_CASCADE	(EMMA2RH_IRQ_INT46 - EMMA2RH_IRQ_INT0)
+#define EMMA2RH_SW_CASCADE	(EMMA2RH_IRQ_INT(7) - EMMA2RH_IRQ_INT(0))
+#define EMMA2RH_GPIO_CASCADE	(EMMA2RH_IRQ_INT(46) - EMMA2RH_IRQ_INT(0))
 
 #define EMMA2RH_SW_IRQ_BASE	(EMMA2RH_IRQ_BASE + NUM_EMMA2RH_IRQ)
 #define EMMA2RH_GPIO_IRQ_BASE	(EMMA2RH_SW_IRQ_BASE + NUM_EMMA2RH_IRQ_SW)
 
-#define EMMA2RH_SW_IRQ_INT0	(0+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT1	(1+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT2	(2+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT3	(3+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT4	(4+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT5	(5+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT6	(6+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT7	(7+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT8	(8+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT9	(9+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT10	(10+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT11	(11+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT12	(12+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT13	(13+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT14	(14+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT15	(15+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT16	(16+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT17	(17+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT18	(18+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT19	(19+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT20	(20+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT21	(21+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT22	(22+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT23	(23+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT24	(24+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT25	(25+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT26	(26+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT27	(27+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT28	(28+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT29	(29+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT30	(30+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT31	(31+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT(n)	(EMMA2RH_SW_IRQ_BASE + (n))
 
 #define MARKEINS_PCI_IRQ_INTA	EMMA2RH_GPIO_IRQ_BASE+15
 #define MARKEINS_PCI_IRQ_INTB	EMMA2RH_GPIO_IRQ_BASE+16
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 0eaf77ffbc4f1df94606f27dccd0c1a6f9a3a882..4e332165d7b710a8e4327c7d820c66883d12b89c 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -87,7 +87,7 @@ do {									\
 	: "=r" (tmp));							\
 } while (0)
 
-#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MACH_ALCHEMY)
+#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)
 
 /*
  * These are slightly complicated by the fact that we guarantee R1 kernels to
@@ -138,7 +138,7 @@ do {									\
 		__instruction_hazard();					\
 } while (0)
 
-#elif defined(CONFIG_MACH_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
+#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
       defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
       defined(CONFIG_CPU_R5500)
 
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h
index 6489f00731caad3e904850dbbcf8d97f30afcd10..444ff71aa0e8d2759b85fb56c6955806234ef4e0 100644
--- a/arch/mips/include/asm/inst.h
+++ b/arch/mips/include/asm/inst.h
@@ -247,6 +247,12 @@ struct ma_format {	/* FPU multipy and add format (MIPS IV) */
 	unsigned int fmt : 2;
 };
 
+struct b_format { /* BREAK and SYSCALL */
+	unsigned int opcode:6;
+	unsigned int code:20;
+	unsigned int func:6;
+};
+
 #elif defined(__MIPSEL__)
 
 struct j_format {	/* Jump format */
@@ -314,6 +320,12 @@ struct ma_format {	/* FPU multipy and add format (MIPS IV) */
 	unsigned int opcode : 6;
 };
 
+struct b_format { /* BREAK and SYSCALL */
+	unsigned int func:6;
+	unsigned int code:20;
+	unsigned int opcode:6;
+};
+
 #else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
 #error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
 #endif
@@ -328,7 +340,8 @@ union mips_instruction {
 	struct c_format c_format;
 	struct r_format r_format;
 	struct f_format f_format;
-        struct ma_format ma_format;
+	struct ma_format ma_format;
+	struct b_format b_format;
 };
 
 /* HACHACHAHCAHC ...  */
diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h
index 5bf62aafc8909308c40d3de0452f764eab88a55c..6a9af5fcb5d72ef7878dc9581f366b07568a1c0f 100644
--- a/arch/mips/include/asm/kdebug.h
+++ b/arch/mips/include/asm/kdebug.h
@@ -8,6 +8,9 @@ enum die_val {
 	DIE_FP,
 	DIE_TRAP,
 	DIE_RI,
+	DIE_PAGE_FAULT,
+	DIE_BREAK,
+	DIE_SSTEPBP
 };
 
 #endif /* _ASM_MIPS_KDEBUG_H */
diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6ea4d4d720545c1746a575436aef03308d28b30
--- /dev/null
+++ b/arch/mips/include/asm/kprobes.h
@@ -0,0 +1,92 @@
+/*
+ *  Kernel Probes (KProbes)
+ *  include/asm-mips/kprobes.h
+ *
+ *  Copyright 2006 Sony Corp.
+ *  Copyright 2010 Cavium Networks
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ASM_KPROBES_H
+#define _ASM_KPROBES_H
+
+#include <linux/ptrace.h>
+#include <linux/types.h>
+
+#include <asm/cacheflush.h>
+#include <asm/kdebug.h>
+#include <asm/inst.h>
+
+#define  __ARCH_WANT_KPROBES_INSN_SLOT
+
+struct kprobe;
+struct pt_regs;
+
+typedef union mips_instruction kprobe_opcode_t;
+
+#define MAX_INSN_SIZE 2
+
+#define flush_insn_slot(p)						\
+do {									\
+	flush_icache_range((unsigned long)p->addr,			\
+			   (unsigned long)p->addr +			\
+			   (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));	\
+} while (0)
+
+
+#define kretprobe_blacklist_size 0
+
+void arch_remove_kprobe(struct kprobe *p);
+
+/* Architecture specific copy of original instruction*/
+struct arch_specific_insn {
+	/* copy of the original instruction */
+	kprobe_opcode_t *insn;
+};
+
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned long status;
+	unsigned long old_SR;
+	unsigned long saved_SR;
+	unsigned long saved_epc;
+};
+
+#define MAX_JPROBES_STACK_SIZE 128
+#define MAX_JPROBES_STACK_ADDR \
+	(((unsigned long)current_thread_info()) + THREAD_SIZE - 32 - sizeof(struct pt_regs))
+
+#define MIN_JPROBES_STACK_SIZE(ADDR)					\
+	((((ADDR) + MAX_JPROBES_STACK_SIZE) > MAX_JPROBES_STACK_ADDR)	\
+		? MAX_JPROBES_STACK_ADDR - (ADDR)			\
+		: MAX_JPROBES_STACK_SIZE)
+
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	unsigned long kprobe_old_SR;
+	unsigned long kprobe_saved_SR;
+	unsigned long kprobe_saved_epc;
+	unsigned long jprobe_saved_sp;
+	struct pt_regs jprobe_saved_regs;
+	u8 jprobes_stack[MAX_JPROBES_STACK_SIZE];
+	struct prev_kprobe prev_kprobe;
+};
+
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+				    unsigned long val, void *data);
+
+#endif				/* _ASM_KPROBES_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
index bae9b758fcde85bb3b8ebd1298480cc642b38af6..49dc8d9db186fec5b1ab279243785391839428fa 100644
--- a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
@@ -9,6 +9,7 @@ struct au1000_eth_platform_data {
 	int phy_addr;
 	int phy_busid;
 	int phy_irq;
+	char mac[6];
 };
 
 void __init au1xxx_override_eth_cfg(unsigned port,
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
index 0d8cc146f7a4dbb315f57a9353502e28bc556a1f..c58ebd8bc1551dd92e14111acc1ac92c4b17d1b7 100644
--- a/arch/mips/include/asm/mach-bcm47xx/nvram.h
+++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
@@ -31,6 +31,9 @@ struct nvram_header {
 #define NVRAM_MAX_VALUE_LEN 255
 #define NVRAM_MAX_PARAM_LEN 64
 
+#define NVRAM_ERR_INV_PARAM	-8
+#define NVRAM_ERR_ENVNOTFOUND	-9
+
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
 #endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index bbf05404239565927c2f4bea282863cf4766b132..b952fc7215e204463174d30608eff1e9a5bcba00 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -61,21 +61,18 @@
 
 #define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
 
-#define ARCH_HAS_READ_CURRENT_TIMER 1
 #define ARCH_HAS_IRQ_PER_CPU	1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
 #define spin_lock_prefetch(x) prefetch(x)
 #define PREFETCH_STRIDE 128
 
-static inline int read_current_timer(unsigned long *result)
-{
-	asm volatile ("rdhwr %0,$31\n"
-#ifndef CONFIG_64BIT
-		      "\tsll %0, 0"
+#ifdef __OCTEON__
+/*
+ * All gcc versions that have OCTEON support define __OCTEON__ and have the
+ *  __builtin_popcount support.
+ */
+#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
 #endif
-		      : "=r" (*result));
-	return 0;
-}
 
 static inline int octeon_has_saa(void)
 {
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index d32220fbf4f1315c0fd91e182b4ce0245b1eaa48..6ddab8aef64478984164e372d5463bd18b5116c6 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -172,71 +172,9 @@
 #ifdef CONFIG_PCI_MSI
 /* 152 - 215 represent the MSI interrupts 0-63 */
 #define OCTEON_IRQ_MSI_BIT0	152
-#define OCTEON_IRQ_MSI_BIT1	153
-#define OCTEON_IRQ_MSI_BIT2	154
-#define OCTEON_IRQ_MSI_BIT3	155
-#define OCTEON_IRQ_MSI_BIT4	156
-#define OCTEON_IRQ_MSI_BIT5	157
-#define OCTEON_IRQ_MSI_BIT6	158
-#define OCTEON_IRQ_MSI_BIT7	159
-#define OCTEON_IRQ_MSI_BIT8	160
-#define OCTEON_IRQ_MSI_BIT9	161
-#define OCTEON_IRQ_MSI_BIT10	162
-#define OCTEON_IRQ_MSI_BIT11	163
-#define OCTEON_IRQ_MSI_BIT12	164
-#define OCTEON_IRQ_MSI_BIT13	165
-#define OCTEON_IRQ_MSI_BIT14	166
-#define OCTEON_IRQ_MSI_BIT15	167
-#define OCTEON_IRQ_MSI_BIT16	168
-#define OCTEON_IRQ_MSI_BIT17	169
-#define OCTEON_IRQ_MSI_BIT18	170
-#define OCTEON_IRQ_MSI_BIT19	171
-#define OCTEON_IRQ_MSI_BIT20	172
-#define OCTEON_IRQ_MSI_BIT21	173
-#define OCTEON_IRQ_MSI_BIT22	174
-#define OCTEON_IRQ_MSI_BIT23	175
-#define OCTEON_IRQ_MSI_BIT24	176
-#define OCTEON_IRQ_MSI_BIT25	177
-#define OCTEON_IRQ_MSI_BIT26	178
-#define OCTEON_IRQ_MSI_BIT27	179
-#define OCTEON_IRQ_MSI_BIT28	180
-#define OCTEON_IRQ_MSI_BIT29	181
-#define OCTEON_IRQ_MSI_BIT30	182
-#define OCTEON_IRQ_MSI_BIT31	183
-#define OCTEON_IRQ_MSI_BIT32	184
-#define OCTEON_IRQ_MSI_BIT33	185
-#define OCTEON_IRQ_MSI_BIT34	186
-#define OCTEON_IRQ_MSI_BIT35	187
-#define OCTEON_IRQ_MSI_BIT36	188
-#define OCTEON_IRQ_MSI_BIT37	189
-#define OCTEON_IRQ_MSI_BIT38	190
-#define OCTEON_IRQ_MSI_BIT39	191
-#define OCTEON_IRQ_MSI_BIT40	192
-#define OCTEON_IRQ_MSI_BIT41	193
-#define OCTEON_IRQ_MSI_BIT42	194
-#define OCTEON_IRQ_MSI_BIT43	195
-#define OCTEON_IRQ_MSI_BIT44	196
-#define OCTEON_IRQ_MSI_BIT45	197
-#define OCTEON_IRQ_MSI_BIT46	198
-#define OCTEON_IRQ_MSI_BIT47	199
-#define OCTEON_IRQ_MSI_BIT48	200
-#define OCTEON_IRQ_MSI_BIT49	201
-#define OCTEON_IRQ_MSI_BIT50	202
-#define OCTEON_IRQ_MSI_BIT51	203
-#define OCTEON_IRQ_MSI_BIT52	204
-#define OCTEON_IRQ_MSI_BIT53	205
-#define OCTEON_IRQ_MSI_BIT54	206
-#define OCTEON_IRQ_MSI_BIT55	207
-#define OCTEON_IRQ_MSI_BIT56	208
-#define OCTEON_IRQ_MSI_BIT57	209
-#define OCTEON_IRQ_MSI_BIT58	210
-#define OCTEON_IRQ_MSI_BIT59	211
-#define OCTEON_IRQ_MSI_BIT60	212
-#define OCTEON_IRQ_MSI_BIT61	213
-#define OCTEON_IRQ_MSI_BIT62	214
-#define OCTEON_IRQ_MSI_BIT63	215
+#define OCTEON_IRQ_MSI_LAST	(OCTEON_IRQ_MSI_BIT0 + 255)
 
-#define OCTEON_IRQ_LAST         216
+#define OCTEON_IRQ_LAST		(OCTEON_IRQ_MSI_LAST + 1)
 #else
 #define OCTEON_IRQ_LAST         152
 #endif
diff --git a/arch/mips/include/asm/mach-jz4740/base.h b/arch/mips/include/asm/mach-jz4740/base.h
new file mode 100644
index 0000000000000000000000000000000000000000..f373186054527ae3f81b90fadf136a609ad6fe31
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/base.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_MACH_JZ4740_BASE_H__
+#define __ASM_MACH_JZ4740_BASE_H__
+
+#define JZ4740_CPM_BASE_ADDR	0x10000000
+#define JZ4740_INTC_BASE_ADDR	0x10001000
+#define JZ4740_WDT_BASE_ADDR	0x10002000
+#define JZ4740_TCU_BASE_ADDR	0x10002010
+#define JZ4740_RTC_BASE_ADDR	0x10003000
+#define JZ4740_GPIO_BASE_ADDR	0x10010000
+#define JZ4740_AIC_BASE_ADDR	0x10020000
+#define JZ4740_MSC_BASE_ADDR	0x10021000
+#define JZ4740_UART0_BASE_ADDR	0x10030000
+#define JZ4740_UART1_BASE_ADDR	0x10031000
+#define JZ4740_I2C_BASE_ADDR	0x10042000
+#define JZ4740_SSI_BASE_ADDR	0x10043000
+#define JZ4740_SADC_BASE_ADDR	0x10070000
+#define JZ4740_EMC_BASE_ADDR	0x13010000
+#define JZ4740_DMAC_BASE_ADDR	0x13020000
+#define JZ4740_UHC_BASE_ADDR	0x13030000
+#define JZ4740_UDC_BASE_ADDR	0x13040000
+#define JZ4740_LCD_BASE_ADDR	0x13050000
+#define JZ4740_SLCD_BASE_ADDR	0x13050000
+#define JZ4740_CIM_BASE_ADDR	0x13060000
+#define JZ4740_IPU_BASE_ADDR	0x13080000
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b7408dd0e23b89113d96635b133d29d539e0816
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.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
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_JZ4740_CLOCK_H__
+#define __ASM_JZ4740_CLOCK_H__
+
+enum jz4740_wait_mode {
+	JZ4740_WAIT_MODE_IDLE,
+	JZ4740_WAIT_MODE_SLEEP,
+};
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
+
+void jz4740_clock_udc_enable_auto_suspend(void);
+void jz4740_clock_udc_disable_auto_suspend(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
new file mode 100644
index 0000000000000000000000000000000000000000..d12e5c6477b943fe46cd564539375094836079f1
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ */
+#ifndef __ASM_MACH_JZ4740_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_JZ4740_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_tx39_cache	0
+#define cpu_has_fpu		0
+#define cpu_has_32fpr	0
+#define cpu_has_counter		0
+#define cpu_has_watch		1
+#define cpu_has_divec		1
+#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 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc		1
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define kernel_uses_llsc	1
+#define cpu_has_vtag_icache	1
+#define cpu_has_dc_aliases	0
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_pindexed_dcache 0
+#define cpu_has_mips32r1	1
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+#define cpu_has_dsp		0
+#define cpu_has_mipsmt		0
+#define cpu_has_userlocal	0
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits		0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3be12183599c0253614d12b9ccd1565d5781f63
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/dma.h
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ7420/JZ4740 DMA definitions
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_DMA_H__
+#define __ASM_MACH_JZ4740_DMA_H__
+
+struct jz4740_dma_chan;
+
+enum jz4740_dma_request_type {
+	JZ4740_DMA_TYPE_AUTO_REQUEST	= 8,
+	JZ4740_DMA_TYPE_UART_TRANSMIT	= 20,
+	JZ4740_DMA_TYPE_UART_RECEIVE	= 21,
+	JZ4740_DMA_TYPE_SPI_TRANSMIT	= 22,
+	JZ4740_DMA_TYPE_SPI_RECEIVE	= 23,
+	JZ4740_DMA_TYPE_AIC_TRANSMIT	= 24,
+	JZ4740_DMA_TYPE_AIC_RECEIVE	= 25,
+	JZ4740_DMA_TYPE_MMC_TRANSMIT	= 26,
+	JZ4740_DMA_TYPE_MMC_RECEIVE	= 27,
+	JZ4740_DMA_TYPE_TCU		= 28,
+	JZ4740_DMA_TYPE_SADC		= 29,
+	JZ4740_DMA_TYPE_SLCD		= 30,
+};
+
+enum jz4740_dma_width {
+	JZ4740_DMA_WIDTH_32BIT	= 0,
+	JZ4740_DMA_WIDTH_8BIT	= 1,
+	JZ4740_DMA_WIDTH_16BIT	= 2,
+};
+
+enum jz4740_dma_transfer_size {
+	JZ4740_DMA_TRANSFER_SIZE_4BYTE  = 0,
+	JZ4740_DMA_TRANSFER_SIZE_1BYTE  = 1,
+	JZ4740_DMA_TRANSFER_SIZE_2BYTE  = 2,
+	JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
+	JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
+};
+
+enum jz4740_dma_flags {
+	JZ4740_DMA_SRC_AUTOINC = 0x2,
+	JZ4740_DMA_DST_AUTOINC = 0x1,
+};
+
+enum jz4740_dma_mode {
+	JZ4740_DMA_MODE_SINGLE	= 0,
+	JZ4740_DMA_MODE_BLOCK	= 1,
+};
+
+struct jz4740_dma_config {
+	enum jz4740_dma_width src_width;
+	enum jz4740_dma_width dst_width;
+	enum jz4740_dma_transfer_size transfer_size;
+	enum jz4740_dma_request_type request_type;
+	enum jz4740_dma_flags flags;
+	enum jz4740_dma_mode mode;
+};
+
+typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
+
+struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
+void jz4740_dma_free(struct jz4740_dma_chan *dma);
+
+void jz4740_dma_configure(struct jz4740_dma_chan *dma,
+	const struct jz4740_dma_config *config);
+
+
+void jz4740_dma_enable(struct jz4740_dma_chan *dma);
+void jz4740_dma_disable(struct jz4740_dma_chan *dma);
+
+void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
+void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
+void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
+
+uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
+
+void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
+	jz4740_dma_complete_callback_t cb);
+
+#endif  /* __ASM_JZ4740_DMA_H__ */
diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b74703745bb16b6e69c23a0658d589e934e1ade
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/gpio.h
@@ -0,0 +1,398 @@
+/*
+ *  Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 GPIO pin definitions
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef _JZ_GPIO_H
+#define _JZ_GPIO_H
+
+#include <linux/types.h>
+
+enum jz_gpio_function {
+    JZ_GPIO_FUNC_NONE,
+    JZ_GPIO_FUNC1,
+    JZ_GPIO_FUNC2,
+    JZ_GPIO_FUNC3,
+};
+
+
+/*
+ Usually a driver for a SoC component has to request several gpio pins and
+ configure them as funcion pins.
+ jz_gpio_bulk_request can be used to ease this process.
+ Usually one would do something like:
+
+ const static struct jz_gpio_bulk_request i2c_pins[] = {
+	JZ_GPIO_BULK_PIN(I2C_SDA),
+	JZ_GPIO_BULK_PIN(I2C_SCK),
+ };
+
+ inside the probe function:
+
+    ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
+    if (ret) {
+	...
+
+ inside the remove function:
+
+    jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
+
+
+*/
+struct jz_gpio_bulk_request {
+	int gpio;
+	const char *name;
+	enum jz_gpio_function function;
+};
+
+#define JZ_GPIO_BULK_PIN(pin) { \
+    .gpio = JZ_GPIO_ ## pin, \
+    .name = #pin, \
+    .function = JZ_GPIO_FUNC_ ## pin \
+}
+
+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_enable_pullup(unsigned gpio);
+void jz_gpio_disable_pullup(unsigned gpio);
+int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
+
+int jz_gpio_port_direction_input(int port, uint32_t mask);
+int jz_gpio_port_direction_output(int port, uint32_t mask);
+void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
+uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
+
+#include <asm/mach-generic/gpio.h>
+
+#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
+#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
+#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
+#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
+
+/* Port A function pins */
+#define JZ_GPIO_MEM_DATA0		JZ_GPIO_PORTA(0)
+#define JZ_GPIO_MEM_DATA1		JZ_GPIO_PORTA(1)
+#define JZ_GPIO_MEM_DATA2		JZ_GPIO_PORTA(2)
+#define JZ_GPIO_MEM_DATA3		JZ_GPIO_PORTA(3)
+#define JZ_GPIO_MEM_DATA4		JZ_GPIO_PORTA(4)
+#define JZ_GPIO_MEM_DATA5		JZ_GPIO_PORTA(5)
+#define JZ_GPIO_MEM_DATA6		JZ_GPIO_PORTA(6)
+#define JZ_GPIO_MEM_DATA7		JZ_GPIO_PORTA(7)
+#define JZ_GPIO_MEM_DATA8		JZ_GPIO_PORTA(8)
+#define JZ_GPIO_MEM_DATA9		JZ_GPIO_PORTA(9)
+#define JZ_GPIO_MEM_DATA10		JZ_GPIO_PORTA(10)
+#define JZ_GPIO_MEM_DATA11		JZ_GPIO_PORTA(11)
+#define JZ_GPIO_MEM_DATA12		JZ_GPIO_PORTA(12)
+#define JZ_GPIO_MEM_DATA13		JZ_GPIO_PORTA(13)
+#define JZ_GPIO_MEM_DATA14		JZ_GPIO_PORTA(14)
+#define JZ_GPIO_MEM_DATA15		JZ_GPIO_PORTA(15)
+#define JZ_GPIO_MEM_DATA16		JZ_GPIO_PORTA(16)
+#define JZ_GPIO_MEM_DATA17		JZ_GPIO_PORTA(17)
+#define JZ_GPIO_MEM_DATA18		JZ_GPIO_PORTA(18)
+#define JZ_GPIO_MEM_DATA19		JZ_GPIO_PORTA(19)
+#define JZ_GPIO_MEM_DATA20		JZ_GPIO_PORTA(20)
+#define JZ_GPIO_MEM_DATA21		JZ_GPIO_PORTA(21)
+#define JZ_GPIO_MEM_DATA22		JZ_GPIO_PORTA(22)
+#define JZ_GPIO_MEM_DATA23		JZ_GPIO_PORTA(23)
+#define JZ_GPIO_MEM_DATA24		JZ_GPIO_PORTA(24)
+#define JZ_GPIO_MEM_DATA25		JZ_GPIO_PORTA(25)
+#define JZ_GPIO_MEM_DATA26		JZ_GPIO_PORTA(26)
+#define JZ_GPIO_MEM_DATA27		JZ_GPIO_PORTA(27)
+#define JZ_GPIO_MEM_DATA28		JZ_GPIO_PORTA(28)
+#define JZ_GPIO_MEM_DATA29		JZ_GPIO_PORTA(29)
+#define JZ_GPIO_MEM_DATA30		JZ_GPIO_PORTA(30)
+#define JZ_GPIO_MEM_DATA31		JZ_GPIO_PORTA(31)
+
+#define JZ_GPIO_FUNC_MEM_DATA0		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA1		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA2		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA3		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA4		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA5		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA6		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA7		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA8		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA9		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA10		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA11		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA12		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA13		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA14		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA15		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA16		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA17		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA18		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA19		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA20		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA21		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA22		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA23		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA24		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA25		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA26		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA27		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA28		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA29		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA30		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA31		JZ_GPIO_FUNC1
+
+/* Port B function pins */
+#define JZ_GPIO_MEM_ADDR0		JZ_GPIO_PORTB(0)
+#define JZ_GPIO_MEM_ADDR1		JZ_GPIO_PORTB(1)
+#define JZ_GPIO_MEM_ADDR2		JZ_GPIO_PORTB(2)
+#define JZ_GPIO_MEM_ADDR3		JZ_GPIO_PORTB(3)
+#define JZ_GPIO_MEM_ADDR4		JZ_GPIO_PORTB(4)
+#define JZ_GPIO_MEM_ADDR5		JZ_GPIO_PORTB(5)
+#define JZ_GPIO_MEM_ADDR6		JZ_GPIO_PORTB(6)
+#define JZ_GPIO_MEM_ADDR7		JZ_GPIO_PORTB(7)
+#define JZ_GPIO_MEM_ADDR8		JZ_GPIO_PORTB(8)
+#define JZ_GPIO_MEM_ADDR9		JZ_GPIO_PORTB(9)
+#define JZ_GPIO_MEM_ADDR10		JZ_GPIO_PORTB(10)
+#define JZ_GPIO_MEM_ADDR11		JZ_GPIO_PORTB(11)
+#define JZ_GPIO_MEM_ADDR12		JZ_GPIO_PORTB(12)
+#define JZ_GPIO_MEM_ADDR13		JZ_GPIO_PORTB(13)
+#define JZ_GPIO_MEM_ADDR14		JZ_GPIO_PORTB(14)
+#define JZ_GPIO_MEM_ADDR15		JZ_GPIO_PORTB(15)
+#define JZ_GPIO_MEM_ADDR16		JZ_GPIO_PORTB(16)
+#define JZ_GPIO_LCD_CLS			JZ_GPIO_PORTB(17)
+#define JZ_GPIO_LCD_SPL			JZ_GPIO_PORTB(18)
+#define JZ_GPIO_MEM_DCS			JZ_GPIO_PORTB(19)
+#define JZ_GPIO_MEM_RAS			JZ_GPIO_PORTB(20)
+#define JZ_GPIO_MEM_CAS			JZ_GPIO_PORTB(21)
+#define JZ_GPIO_MEM_SDWE		JZ_GPIO_PORTB(22)
+#define JZ_GPIO_MEM_CKE			JZ_GPIO_PORTB(23)
+#define JZ_GPIO_MEM_CKO			JZ_GPIO_PORTB(24)
+#define JZ_GPIO_MEM_CS0			JZ_GPIO_PORTB(25)
+#define JZ_GPIO_MEM_CS1			JZ_GPIO_PORTB(26)
+#define JZ_GPIO_MEM_CS2			JZ_GPIO_PORTB(27)
+#define JZ_GPIO_MEM_CS3			JZ_GPIO_PORTB(28)
+#define JZ_GPIO_MEM_RD			JZ_GPIO_PORTB(29)
+#define JZ_GPIO_MEM_WR			JZ_GPIO_PORTB(30)
+#define JZ_GPIO_MEM_WE0			JZ_GPIO_PORTB(31)
+
+#define JZ_GPIO_FUNC_MEM_ADDR0		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR1		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR2		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR3		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR4		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR5		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR6		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR7		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR8		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR9		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR10		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR11		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR12		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR13		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR14		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR15		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR16		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_CLS	        JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_SPL		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DCS		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_RAS		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CAS		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_SDWE		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CKE		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CKO		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS0		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS1		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS2		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS3		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_RD		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WR		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE0		JZ_GPIO_FUNC1
+
+
+#define JZ_GPIO_MEM_ADDR21		JZ_GPIO_PORTB(17)
+#define JZ_GPIO_MEM_ADDR22		JZ_GPIO_PORTB(18)
+
+#define JZ_GPIO_FUNC_MEM_ADDR21		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR22		JZ_GPIO_FUNC2
+
+/* Port C function pins */
+#define JZ_GPIO_LCD_DATA0		JZ_GPIO_PORTC(0)
+#define JZ_GPIO_LCD_DATA1		JZ_GPIO_PORTC(1)
+#define JZ_GPIO_LCD_DATA2		JZ_GPIO_PORTC(2)
+#define JZ_GPIO_LCD_DATA3		JZ_GPIO_PORTC(3)
+#define JZ_GPIO_LCD_DATA4		JZ_GPIO_PORTC(4)
+#define JZ_GPIO_LCD_DATA5		JZ_GPIO_PORTC(5)
+#define JZ_GPIO_LCD_DATA6		JZ_GPIO_PORTC(6)
+#define JZ_GPIO_LCD_DATA7		JZ_GPIO_PORTC(7)
+#define JZ_GPIO_LCD_DATA8		JZ_GPIO_PORTC(8)
+#define JZ_GPIO_LCD_DATA9		JZ_GPIO_PORTC(9)
+#define JZ_GPIO_LCD_DATA10		JZ_GPIO_PORTC(10)
+#define JZ_GPIO_LCD_DATA11		JZ_GPIO_PORTC(11)
+#define JZ_GPIO_LCD_DATA12		JZ_GPIO_PORTC(12)
+#define JZ_GPIO_LCD_DATA13		JZ_GPIO_PORTC(13)
+#define JZ_GPIO_LCD_DATA14		JZ_GPIO_PORTC(14)
+#define JZ_GPIO_LCD_DATA15		JZ_GPIO_PORTC(15)
+#define JZ_GPIO_LCD_DATA16		JZ_GPIO_PORTC(16)
+#define JZ_GPIO_LCD_DATA17		JZ_GPIO_PORTC(17)
+#define JZ_GPIO_LCD_PCLK		JZ_GPIO_PORTC(18)
+#define JZ_GPIO_LCD_HSYNC		JZ_GPIO_PORTC(19)
+#define JZ_GPIO_LCD_VSYNC		JZ_GPIO_PORTC(20)
+#define JZ_GPIO_LCD_DE			JZ_GPIO_PORTC(21)
+#define JZ_GPIO_LCD_PS			JZ_GPIO_PORTC(22)
+#define JZ_GPIO_LCD_REV			JZ_GPIO_PORTC(23)
+#define JZ_GPIO_MEM_WE1			JZ_GPIO_PORTC(24)
+#define JZ_GPIO_MEM_WE2			JZ_GPIO_PORTC(25)
+#define JZ_GPIO_MEM_WE3			JZ_GPIO_PORTC(26)
+#define JZ_GPIO_MEM_WAIT		JZ_GPIO_PORTC(27)
+#define JZ_GPIO_MEM_FRE			JZ_GPIO_PORTC(28)
+#define JZ_GPIO_MEM_FWE			JZ_GPIO_PORTC(29)
+
+#define JZ_GPIO_FUNC_LCD_DATA0		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA1		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA2		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA3		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA4		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA5		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA6		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA7		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA8		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA9		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA10		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA11		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA12		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA13		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA14		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA15		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA16		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA17		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_PCLK		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_VSYNC		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_HSYNC		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DE		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_PS		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_REV		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE1		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE2		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE3		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WAIT		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_FRE		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_FWE		JZ_GPIO_FUNC1
+
+
+#define JZ_GPIO_MEM_ADDR19		JZ_GPIO_PORTB(22)
+#define JZ_GPIO_MEM_ADDR20		JZ_GPIO_PORTB(23)
+
+#define JZ_GPIO_FUNC_MEM_ADDR19		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR20		JZ_GPIO_FUNC2
+
+/* Port D function pins */
+#define JZ_GPIO_CIM_DATA0		JZ_GPIO_PORTD(0)
+#define JZ_GPIO_CIM_DATA1		JZ_GPIO_PORTD(1)
+#define JZ_GPIO_CIM_DATA2		JZ_GPIO_PORTD(2)
+#define JZ_GPIO_CIM_DATA3		JZ_GPIO_PORTD(3)
+#define JZ_GPIO_CIM_DATA4		JZ_GPIO_PORTD(4)
+#define JZ_GPIO_CIM_DATA5		JZ_GPIO_PORTD(5)
+#define JZ_GPIO_CIM_DATA6		JZ_GPIO_PORTD(6)
+#define JZ_GPIO_CIM_DATA7		JZ_GPIO_PORTD(7)
+#define JZ_GPIO_MSC_CMD			JZ_GPIO_PORTD(8)
+#define JZ_GPIO_MSC_CLK			JZ_GPIO_PORTD(9)
+#define JZ_GPIO_MSC_DATA0		JZ_GPIO_PORTD(10)
+#define JZ_GPIO_MSC_DATA1		JZ_GPIO_PORTD(11)
+#define JZ_GPIO_MSC_DATA2		JZ_GPIO_PORTD(12)
+#define JZ_GPIO_MSC_DATA3		JZ_GPIO_PORTD(13)
+#define JZ_GPIO_CIM_MCLK		JZ_GPIO_PORTD(14)
+#define JZ_GPIO_CIM_PCLK		JZ_GPIO_PORTD(15)
+#define JZ_GPIO_CIM_VSYNC		JZ_GPIO_PORTD(16)
+#define JZ_GPIO_CIM_HSYNC		JZ_GPIO_PORTD(17)
+#define JZ_GPIO_SPI_CLK			JZ_GPIO_PORTD(18)
+#define JZ_GPIO_SPI_CE0			JZ_GPIO_PORTD(19)
+#define JZ_GPIO_SPI_DT			JZ_GPIO_PORTD(20)
+#define JZ_GPIO_SPI_DR			JZ_GPIO_PORTD(21)
+#define JZ_GPIO_SPI_CE1			JZ_GPIO_PORTD(22)
+#define JZ_GPIO_PWM0			JZ_GPIO_PORTD(23)
+#define JZ_GPIO_PWM1			JZ_GPIO_PORTD(24)
+#define JZ_GPIO_PWM2			JZ_GPIO_PORTD(25)
+#define JZ_GPIO_PWM3			JZ_GPIO_PORTD(26)
+#define JZ_GPIO_PWM4			JZ_GPIO_PORTD(27)
+#define JZ_GPIO_PWM5			JZ_GPIO_PORTD(28)
+#define JZ_GPIO_PWM6			JZ_GPIO_PORTD(30)
+#define JZ_GPIO_PWM7			JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_CIM_DATA		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_DATA0		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA1		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA2		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA3		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA4		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA5		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA6		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA7		JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_MSC_CMD		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_CLK		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_DATA		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_DATA0		JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA1		JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA2		JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA3		JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_CIM_MCLK		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_PCLK		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_VSYNC		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_HSYNC		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CLK		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CE0		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_DT		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_DR		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CE1		JZ_GPIO_FUNC1
+
+#define JZ_GPIO_FUNC_PWM		JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_PWM0		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM1		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM2		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM3		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM4		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM5		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM6		JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM7		JZ_GPIO_FUNC_PWM
+
+#define JZ_GPIO_MEM_SCLK_RSTN		JZ_GPIO_PORTD(18)
+#define JZ_GPIO_MEM_BCLK		JZ_GPIO_PORTD(19)
+#define JZ_GPIO_MEM_SDATO		JZ_GPIO_PORTD(20)
+#define JZ_GPIO_MEM_SDATI		JZ_GPIO_PORTD(21)
+#define JZ_GPIO_MEM_SYNC		JZ_GPIO_PORTD(22)
+#define JZ_GPIO_I2C_SDA			JZ_GPIO_PORTD(23)
+#define JZ_GPIO_I2C_SCK			JZ_GPIO_PORTD(24)
+#define JZ_GPIO_UART0_TXD		JZ_GPIO_PORTD(25)
+#define JZ_GPIO_UART0_RXD		JZ_GPIO_PORTD(26)
+#define JZ_GPIO_MEM_ADDR17		JZ_GPIO_PORTD(27)
+#define JZ_GPIO_MEM_ADDR18		JZ_GPIO_PORTD(28)
+#define JZ_GPIO_UART0_CTS		JZ_GPIO_PORTD(30)
+#define JZ_GPIO_UART0_RTS		JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_MEM_SCLK_RSTN	JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_BCLK		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SDATO		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SDATI		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SYNC		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_I2C_SDA		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_I2C_SCK		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_TXD		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_RXD		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR17		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR18		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_CTS		JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_RTS		JZ_GPIO_FUNC2
+
+#define JZ_GPIO_UART1_RXD		JZ_GPIO_PORTD(30)
+#define JZ_GPIO_UART1_TXD		JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_UART1_RXD		JZ_GPIO_FUNC3
+#define JZ_GPIO_FUNC_UART1_TXD		JZ_GPIO_FUNC3
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
new file mode 100644
index 0000000000000000000000000000000000000000..a865c983c70affffc26ce5c00ab8742df7a442e8
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 IRQ definitions
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_IRQ_H__
+#define __ASM_MACH_JZ4740_IRQ_H__
+
+#define MIPS_CPU_IRQ_BASE 0
+#define JZ4740_IRQ_BASE 8
+
+/* 1st-level interrupts */
+#define JZ4740_IRQ(x)		(JZ4740_IRQ_BASE + (x))
+#define JZ4740_IRQ_I2C		JZ4740_IRQ(1)
+#define JZ4740_IRQ_UHC		JZ4740_IRQ(3)
+#define JZ4740_IRQ_UART1	JZ4740_IRQ(8)
+#define JZ4740_IRQ_UART0	JZ4740_IRQ(9)
+#define JZ4740_IRQ_SADC		JZ4740_IRQ(12)
+#define JZ4740_IRQ_MSC		JZ4740_IRQ(14)
+#define JZ4740_IRQ_RTC		JZ4740_IRQ(15)
+#define JZ4740_IRQ_SSI		JZ4740_IRQ(16)
+#define JZ4740_IRQ_CIM		JZ4740_IRQ(17)
+#define JZ4740_IRQ_AIC		JZ4740_IRQ(18)
+#define JZ4740_IRQ_ETH		JZ4740_IRQ(19)
+#define JZ4740_IRQ_DMAC		JZ4740_IRQ(20)
+#define JZ4740_IRQ_TCU2		JZ4740_IRQ(21)
+#define JZ4740_IRQ_TCU1		JZ4740_IRQ(22)
+#define JZ4740_IRQ_TCU0		JZ4740_IRQ(23)
+#define JZ4740_IRQ_UDC		JZ4740_IRQ(24)
+#define JZ4740_IRQ_GPIO3	JZ4740_IRQ(25)
+#define JZ4740_IRQ_GPIO2	JZ4740_IRQ(26)
+#define JZ4740_IRQ_GPIO1	JZ4740_IRQ(27)
+#define JZ4740_IRQ_GPIO0	JZ4740_IRQ(28)
+#define JZ4740_IRQ_IPU		JZ4740_IRQ(29)
+#define JZ4740_IRQ_LCD		JZ4740_IRQ(30)
+
+/* 2nd-level interrupts */
+#define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(32) + (X))
+
+#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
+#define JZ4740_IRQ_GPIO(x)	(JZ4740_IRQ(48) + (x))
+
+#define JZ4740_IRQ_ADC_BASE	JZ4740_IRQ(176)
+
+#define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_fb.h b/arch/mips/include/asm/mach-jz4740/jz4740_fb.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a50e6f7a21a5f90b85fcc684b63521466deafa7
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_fb.h
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.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
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__
+#define __ASM_MACH_JZ4740_JZ4740_FB_H__
+
+#include <linux/fb.h>
+
+enum jz4740_fb_lcd_type {
+	JZ_LCD_TYPE_GENERIC_16_BIT = 0,
+	JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4),
+	JZ_LCD_TYPE_SPECIAL_TFT_1 = 1,
+	JZ_LCD_TYPE_SPECIAL_TFT_2 = 2,
+	JZ_LCD_TYPE_SPECIAL_TFT_3 = 3,
+	JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5,
+	JZ_LCD_TYPE_INTERLACED_CCIR656 = 7,
+	JZ_LCD_TYPE_SINGLE_COLOR_STN = 8,
+	JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9,
+	JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
+	JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11,
+	JZ_LCD_TYPE_8BIT_SERIAL = 12,
+};
+
+#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop))
+
+/*
+* width: width of the lcd display in mm
+* height: height of the lcd display in mm
+* num_modes: size of modes
+* modes: list of valid video modes
+* bpp: bits per pixel for the lcd
+* lcd_type: lcd type
+*/
+
+struct jz4740_fb_platform_data {
+	unsigned int width;
+	unsigned int height;
+
+	size_t num_modes;
+	struct fb_videomode *modes;
+
+	unsigned int bpp;
+	enum jz4740_fb_lcd_type lcd_type;
+
+	struct {
+		uint32_t spl;
+		uint32_t cls;
+		uint32_t ps;
+		uint32_t rev;
+	} special_tft_config;
+
+	unsigned pixclk_falling_edge:1;
+	unsigned date_enable_active_low:1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..8543f432b4b369f2ae4b9d2898ae539d3a196fc7
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h
@@ -0,0 +1,15 @@
+#ifndef __LINUX_MMC_JZ4740_MMC
+#define __LINUX_MMC_JZ4740_MMC
+
+struct jz4740_mmc_platform_data {
+	int gpio_power;
+	int gpio_card_detect;
+	int gpio_read_only;
+	unsigned card_detect_active_low:1;
+	unsigned read_only_active_low:1;
+	unsigned power_active_low:1;
+
+	unsigned data_1bit:1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
new file mode 100644
index 0000000000000000000000000000000000000000..bb5b9a4e29c8226846796a162e1b447f4a0e4ab8
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC NAND controller driver
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_JZ4740_NAND_H__
+#define __ASM_MACH_JZ4740_JZ4740_NAND_H__
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+struct jz_nand_platform_data {
+	int			num_partitions;
+	struct mtd_partition	*partitions;
+
+	struct nand_ecclayout	*ecc_layout;
+
+	unsigned int busy_gpio;
+
+	void (*ident_callback)(struct platform_device *, struct nand_chip *,
+				struct mtd_partition **, int *num_partitions);
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
new file mode 100644
index 0000000000000000000000000000000000000000..8987a76e9676a310492e9b67783c0ad47eb7f78b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform device definitions
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+
+#ifndef __JZ4740_PLATFORM_H
+#define __JZ4740_PLATFORM_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device jz4740_usb_ohci_device;
+extern struct platform_device jz4740_udc_device;
+extern struct platform_device jz4740_mmc_device;
+extern struct platform_device jz4740_rtc_device;
+extern struct platform_device jz4740_i2c_device;
+extern struct platform_device jz4740_nand_device;
+extern struct platform_device jz4740_framebuffer_device;
+extern struct platform_device jz4740_i2s_device;
+extern struct platform_device jz4740_pcm_device;
+extern struct platform_device jz4740_codec_device;
+extern struct platform_device jz4740_adc_device;
+
+void jz4740_serial_device_register(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..9baa03ce748ca173ad4c1c61a77817231c1a15c0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/timer.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform timer support
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_TIMER
+#define __ASM_MACH_JZ4740_TIMER
+
+void jz4740_timer_enable_watchdog(void);
+void jz4740_timer_disable_watchdog(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a5bc17e28fe3b7f834ca45f0dfb66613d12f9c3
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/war.h
@@ -0,0 +1,25 @@
+/*
+ * 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_JZ4740_WAR_H
+#define __ASM_MIPS_MACH_JZ4740_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		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index fcdbe3a4ce1f4f42de0887506cf1c3cba584e04d..cb6985f24303668e661c0373b39e0f08a5d898f5 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -45,7 +45,6 @@ static inline void prom_init_uart_base(void)
 /* irq operation functions */
 extern void bonito_irqdispatch(void);
 extern void __init bonito_irq_init(void);
-extern void __init set_irq_trigger_mode(void);
 extern void __init mach_init_irq(void);
 extern void mach_irq_dispatch(unsigned int pending);
 extern int mach_i8259_irq(void);
@@ -63,6 +62,14 @@ extern int mach_i8259_irq(void);
 #define LOONGSON_IRQ_BASE	32
 #define LOONGSON2_PERFCNT_IRQ	(MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
 
+#include <linux/interrupt.h>
+static inline void do_perfcnt_IRQ(void)
+{
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+	do_IRQ(LOONGSON2_PERFCNT_IRQ);
+#endif
+}
+
 #define LOONGSON_FLASH_BASE	0x1c000000
 #define LOONGSON_FLASH_SIZE	0x02000000	/* 32M */
 #define LOONGSON_FLASH_TOP	(LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h
index 58796410bd6ed375f7fa6b2d28a54d5a1faf7774..fc4d766641ce180b6b9a8422ef8e05d96a367f6a 100644
--- a/arch/mips/include/asm/mach-pb1x00/pb1550.h
+++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h
@@ -40,14 +40,6 @@
 #define SMBUS_PSC_BASE		PSC2_BASE_ADDR
 #define I2S_PSC_BASE		PSC3_BASE_ADDR
 
-#if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_BOTH_BANKS
-#elif defined(CONFIG_MTD_PB1550_BOOT) && !defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_BOOT_ONLY
-#elif !defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_USER_ONLY
-#endif
-
 /*
  * Timing values as described in databook, * ns value stripped of
  * lower 2 bits.
diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h
index bcad43a93ebf40b6acb6ec3f9d564f7ba3c8ab0b..c7077a64b9a727acb042b7ea57e7f81a1a03a223 100644
--- a/arch/mips/include/asm/mach-powertv/asic.h
+++ b/arch/mips/include/asm/mach-powertv/asic.h
@@ -20,6 +20,7 @@
 #define _ASM_MACH_POWERTV_ASIC_H
 
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
 #include <asm/mach-powertv/asic_regs.h>
 
 #define DVR_CAPABLE     (1<<0)
@@ -40,19 +41,23 @@ enum family_type {
 	FAMILY_8600VZB,
 	FAMILY_1500VZE,
 	FAMILY_1500VZF,
+	FAMILY_8700,
 	FAMILIES
 };
 
 /* Register maps for each ASIC */
 extern const struct register_map calliope_register_map;
 extern const struct register_map cronus_register_map;
+extern const struct register_map gaia_register_map;
 extern const struct register_map zeus_register_map;
 
 extern struct resource dvr_cronus_resources[];
+extern struct resource dvr_gaia_resources[];
 extern struct resource dvr_zeus_resources[];
 extern struct resource non_dvr_calliope_resources[];
 extern struct resource non_dvr_cronus_resources[];
 extern struct resource non_dvr_cronuslite_resources[];
+extern struct resource non_dvr_gaia_resources[];
 extern struct resource non_dvr_vz_calliope_resources[];
 extern struct resource non_dvr_vze_calliope_resources[];
 extern struct resource non_dvr_vzf_calliope_resources[];
@@ -67,16 +72,24 @@ extern int platform_supports_ffs(void);
 extern int platform_supports_pcie(void);
 extern int platform_supports_display(void);
 extern void configure_platform(void);
-extern void platform_configure_usb_ehci(void);
-extern void platform_unconfigure_usb_ehci(void);
-extern void platform_configure_usb_ohci(void);
-extern void platform_unconfigure_usb_ohci(void);
 
 /* Platform Resources */
 #define ASIC_RESOURCE_GET_EXISTS 1
 extern struct resource *asic_resource_get(const char *name);
 extern void platform_release_memory(void *baddr, int size);
 
+/* USB configuration */
+struct usb_hcd;			/* Forward reference */
+extern void platform_configure_usb_ehci(void);
+extern void platform_unconfigure_usb_ehci(void);
+extern void platform_configure_usb_ohci(void);
+extern void platform_unconfigure_usb_ohci(void);
+
+/* Resource for ASIC registers */
+extern struct resource asic_resource;
+extern int platform_usb_devices_init(struct platform_device **echi_dev,
+	struct platform_device **ohci_dev);
+
 /* Reboot Cause */
 extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
 extern void set_locked_reboot_cause(char code, unsigned int data,
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
index 6f26cb09828ed4aecf4574e5451ecbc331ad8e05..20348e817b0930cab7b3243b28d63449ab4c8e00 100644
--- a/arch/mips/include/asm/mach-powertv/asic_reg_map.h
+++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
@@ -64,7 +64,7 @@ REGISTER_MAP_ELEMENT(int_level_0_1)
 REGISTER_MAP_ELEMENT(int_level_0_0)
 REGISTER_MAP_ELEMENT(int_docsis_en)
 REGISTER_MAP_ELEMENT(mips_pll_setup)
-REGISTER_MAP_ELEMENT(usb_fs)
+REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl)
 REGISTER_MAP_ELEMENT(test_bus)
 REGISTER_MAP_ELEMENT(crt_spare)
 REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h
index 1e11236c6dbcaf4b4968f64abb6bdd2c801c5aac..deecb26a077ef82c60a7ea03afcca89454b74341 100644
--- a/arch/mips/include/asm/mach-powertv/asic_regs.h
+++ b/arch/mips/include/asm/mach-powertv/asic_regs.h
@@ -27,7 +27,8 @@ enum asic_type {
 	ASIC_CALLIOPE,
 	ASIC_CRONUS,
 	ASIC_CRONUSLITE,
-	ASICS
+	ASIC_GAIA,
+	ASICS			/* Number of supported ASICs */
 };
 
 /* hardcoded values read from Chip Version registers */
@@ -37,6 +38,7 @@ enum asic_type {
 
 #define NAND_FLASH_BASE		0x03000000
 #define CALLIOPE_IO_BASE	0x08000000
+#define GAIA_IO_BASE		0x09000000
 #define CRONUS_IO_BASE		0x09000000
 #define ZEUS_IO_BASE		0x09000000
 
@@ -99,6 +101,7 @@ static inline void register_map_virtualize(struct register_map *map)
 }
 
 extern struct register_map _asic_register_map;
+extern unsigned long asic_phy_base;
 
 /*
  * Macros to interface to registers through their ioremapped address
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
index 5b8d5ebeb838add15df89cc5d87e4de6295e26bd..f76029c2406e6e33acae1edb2db73a3d0efb0344 100644
--- a/arch/mips/include/asm/mach-powertv/dma-coherence.h
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -65,21 +65,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
 	size_t size)
 {
 	if (is_kseg2(addr))
-		return phys_to_bus(virt_to_phys_from_pte(addr));
+		return phys_to_dma(virt_to_phys_from_pte(addr));
 	else
-		return phys_to_bus(virt_to_phys(addr));
+		return phys_to_dma(virt_to_phys(addr));
 }
 
 static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
 	struct page *page)
 {
-	return phys_to_bus(page_to_phys(page));
+	return phys_to_dma(page_to_phys(page));
 }
 
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
 	dma_addr_t dma_addr)
 {
-	return bus_to_phys(dma_addr);
+	return dma_to_phys(dma_addr);
 }
 
 static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h
index e6276d5146e80365a88f861997c21b0d2a1c1dec..076f2eeaa5759571835a51dadafb96dce41c3d26 100644
--- a/arch/mips/include/asm/mach-powertv/ioremap.h
+++ b/arch/mips/include/asm/mach-powertv/ioremap.h
@@ -10,64 +10,101 @@
 #define __ASM_MACH_POWERTV_IOREMAP_H
 
 #include <linux/types.h>
+#include <linux/log2.h>
+#include <linux/compiler.h>
 
-#define LOW_MEM_BOUNDARY_PHYS	0x20000000
-#define LOW_MEM_BOUNDARY_MASK	(~(LOW_MEM_BOUNDARY_PHYS - 1))
+#include <asm/pgtable-bits.h>
+#include <asm/addrspace.h>
+
+/* We're going to mess with bits, so get sizes */
+#define IOR_BPC			8			/* Bits per char */
+#define IOR_PHYS_BITS		(IOR_BPC * sizeof(phys_addr_t))
+#define IOR_DMA_BITS		(IOR_BPC * sizeof(dma_addr_t))
 
 /*
- * The bus addresses are different than the physical addresses that
- * the processor sees by an offset. This offset varies by ASIC
- * version. Define a variable to hold the offset and some macros to
- * make the conversion simpler. */
-extern unsigned long phys_to_bus_offset;
-
-#ifdef CONFIG_HIGHMEM
-#define MEM_GAP_PHYS		0x60000000
+ * Define the granularity of physical/DMA mapping in terms of the number
+ * of bits that defines the offset within a grain. These will be the
+ * least significant bits of the address. The rest of a physical or DMA
+ * address will be used to index into an appropriate table to find the
+ * offset to add to the address to yield the corresponding DMA or physical
+ * address, respectively.
+ */
+#define IOR_LSBITS		22			/* Bits in a grain */
+
 /*
- * TODO: We will use the hard code for conversion between physical and
- * bus until the bootloader releases their device tree to us.
+ * Compute the number of most significant address bits after removing those
+ * used for the offset within a grain and then compute the number of table
+ * entries for the conversion.
  */
-#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \
-	((x) + phys_to_bus_offset) : (x))
-#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \
-	((x) - phys_to_bus_offset) : (x))
-#else
-#define phys_to_bus(x) ((x) + phys_to_bus_offset)
-#define bus_to_phys(x) ((x) - phys_to_bus_offset)
-#endif
+#define IOR_PHYS_MSBITS		(IOR_PHYS_BITS - IOR_LSBITS)
+#define IOR_NUM_PHYS_TO_DMA	((phys_addr_t) 1 << IOR_PHYS_MSBITS)
+
+#define IOR_DMA_MSBITS		(IOR_DMA_BITS - IOR_LSBITS)
+#define IOR_NUM_DMA_TO_PHYS	((dma_addr_t) 1 << IOR_DMA_MSBITS)
 
 /*
- * Determine whether the address we are given is for an ASIC device
- * Params:  addr    Address to check
- * Returns: Zero if the address is not for ASIC devices, non-zero
- *      if it is.
+ * Define data structures used as elements in the arrays for the conversion
+ * between physical and DMA addresses. We do some slightly fancy math to
+ * compute the width of the offset element of the conversion tables so
+ * that we can have the smallest conversion tables. Next, round up the
+ * sizes to the next higher power of two, i.e. the offset element will have
+ * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any
+ * bits.  Finally, we compute a shift value that puts the most significant
+ * bits of the offset into the most significant bits of the offset element.
+ * This makes it more efficient on processors without barrel shifters and
+ * easier to see the values if the conversion table is dumped in binary.
  */
-static inline int asic_is_device_addr(phys_t addr)
+#define _IOR_OFFSET_WIDTH(n)	(1 << order_base_2(n))
+#define IOR_OFFSET_WIDTH(n) \
+	(_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n))
+
+#define IOR_PHYS_OFFSET_BITS	IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS)
+#define IOR_PHYS_SHIFT		(IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS)
+
+#define IOR_DMA_OFFSET_BITS	IOR_OFFSET_WIDTH(IOR_DMA_MSBITS)
+#define IOR_DMA_SHIFT		(IOR_DMA_BITS - IOR_DMA_OFFSET_BITS)
+
+struct ior_phys_to_dma {
+	dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed
+		__aligned((IOR_DMA_OFFSET_BITS / IOR_BPC));
+};
+
+struct ior_dma_to_phys {
+	dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed
+		__aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC));
+};
+
+extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+
+static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys)
 {
-	return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK);
+	return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset;
 }
 
-/*
- * Determine whether the address we are given is external RAM mappable
- * into KSEG1.
- * Params:  addr    Address to check
- * Returns: Zero if the address is not for external RAM and
- */
-static inline int asic_is_lowmem_ram_addr(phys_t addr)
+static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma)
 {
-	/*
-	 * The RAM always starts at the following address in the processor's
-	 * physical address space
-	 */
-	static const phys_t phys_ram_base = 0x10000000;
-	phys_t bus_ram_base;
+	return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset;
+}
 
-	bus_ram_base = phys_to_bus_offset + phys_ram_base;
+/* These are not portable and should not be used in drivers. Drivers should
+ * be using ioremap() and friends to map physical addreses to virtual
+ * addresses and dma_map*() and friends to map virtual addresses into DMA
+ * addresses and back.
+ */
+static inline dma_addr_t phys_to_dma(phys_addr_t phys)
+{
+	return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT);
+}
 
-	return addr >= bus_ram_base &&
-		addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base));
+static inline phys_addr_t dma_to_phys(dma_addr_t dma)
+{
+	return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT);
 }
 
+extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias,
+	dma_addr_t size);
+
 /*
  * Allow physical addresses to be fixed up to help peripherals located
  * outside the low 32-bit range -- generic pass-through version.
@@ -77,10 +114,50 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 	return phys_addr;
 }
 
-static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+/*
+ * Handle the special case of addresses the area aliased into the first
+ * 512 MiB of the processor's physical address space. These turn into either
+ * kseg0 or kseg1 addresses, depending on flags.
+ */
+static inline void __iomem *plat_ioremap(phys_t start, unsigned long size,
 	unsigned long flags)
 {
-	return NULL;
+	phys_addr_t start_offset;
+	void __iomem *result = NULL;
+
+	/* Start by checking to see whether this is an aliased address */
+	start_offset = _dma_to_phys_offset_raw(start);
+
+	/*
+	 * If:
+	 * o	the memory is aliased into the first 512 MiB, and
+	 * o	the start and end are in the same RAM bank, and
+	 * o	we don't have a zero size or wrap around, and
+	 * o	we are supposed to create an uncached mapping,
+	 *	handle this is a kseg0 or kseg1 address
+	 */
+	if (start_offset != 0) {
+		phys_addr_t last;
+		dma_addr_t dma_to_phys_offset;
+
+		last = start + size - 1;
+		dma_to_phys_offset =
+			_dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT;
+
+		if (dma_to_phys_offset == start_offset &&
+			size != 0 && start <= last) {
+			phys_t adjusted_start;
+			adjusted_start = start + start_offset;
+			if (flags == _CACHE_UNCACHED)
+				result = (void __iomem *) (unsigned long)
+					CKSEG1ADDR(adjusted_start);
+			else
+				result = (void __iomem *) (unsigned long)
+					CKSEG0ADDR(adjusted_start);
+		}
+	}
+
+	return result;
 }
 
 static inline int plat_iounmap(const volatile void __iomem *addr)
diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
index 913ff196259d418c3ac746ee1a420774cde63677..b74caf65482b2e068b86d2763daa81733bc45503 100644
--- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h
+++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_MACH_TX49XX_KMALLOC_H
 #define __ASM_MACH_TX49XX_KMALLOC_H
 
-/*
- * All happy, no need to define ARCH_KMALLOC_MINALIGN
- */
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
 
 #endif /* __ASM_MACH_TX49XX_KMALLOC_H */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index c6e3c93ce7c7a5aad8267d88f8c0089301d1e239..335474c155f6e6187aa19ce49527712ca954c8fb 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -408,6 +408,7 @@
 #define  STATUSB_IP15		7
 #define  STATUSF_IP15		(_ULCAST_(1) <<  7)
 #define ST0_CH			0x00040000
+#define ST0_NMI			0x00080000
 #define ST0_SR			0x00100000
 #define ST0_TS			0x00200000
 #define ST0_BEV			0x00400000
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index ca6214b5ccb96c3baa86bbd5cc5380179249c6e3..917a6c413b1abfd511b1333e4b903be04c0809cf 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -50,6 +50,7 @@ extern void octeon_crypto_disable(struct octeon_cop2_state *state,
 extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
 
 extern void octeon_init_cvmcount(void);
+extern void octeon_setup_delays(void);
 
 #define OCTEON_ARGV_MAX_ARGS	64
 #define OCTOEN_SERIAL_LEN	20
@@ -253,4 +254,6 @@ static inline uint32_t octeon_npi_read32(uint64_t address)
 
 extern struct cvmx_bootinfo *octeon_bootinfo;
 
+extern uint64_t octeon_bootloader_entry_addr;
+
 #endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h
index 6ac5d3e3398eaff20144dafc5190910eb8f4ef13..ece78043acf6e0572e501f26a51cc16243da3c43 100644
--- a/arch/mips/include/asm/octeon/pci-octeon.h
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -14,6 +14,19 @@
 /* Some PCI cards require delays when accessing config space. */
 #define PCI_CONFIG_SPACE_DELAY 10000
 
+/*
+ * The physical memory base mapped by BAR1.  256MB at the end of the
+ * first 4GB.
+ */
+#define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28))
+#define CVMX_PCIE_BAR1_PHYS_SIZE (1ull << 28)
+
+/*
+ * The RC base of BAR1.  gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2,
+ * place BAR1 so it is the same for both.
+ */
+#define CVMX_PCIE_BAR1_RC_BASE (1ull << 41)
+
 /*
  * pcibios_map_irq() is defined inside pci-octeon.c. All it does is
  * call the Octeon specific version pointed to by this variable. This
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 3beea1479b4385a19af34efbf4a3b720daeff76d..576397c699208160f60e13f5aa5f95c7bd1b4bb5 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -140,6 +140,11 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 	return channel ? 15 : 14;
 }
 
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+/* MSI arch hook for OCTEON */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+#endif
+
 extern int pci_probe_only;
 
 extern char * (*pcibios_plat_setup)(char *str);
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
index 54ef1a96d7ceb9fe37299e789101cd7b794a6485..786d82daf8d60c25eaa154e2070a32340ce44a23 100644
--- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
@@ -124,10 +124,6 @@ extern void prom_meminit(void);
 extern void prom_fixup_mem_map(unsigned long start_mem,
 			       unsigned long end_mem);
 
-#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
-extern bool get_ramroot(void **start, unsigned long *size);
-#endif
-
 extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr);
 extern unsigned long get_deviceid(void);
 extern char identify_enet(unsigned long interface_num);
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 5d33b727acf51eeedec4b43525f2452351f66465..0d629bb93cbe1abc175ef5adcd7976e5d424d52e 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -33,6 +33,11 @@ extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
+/*
+ * MIPS does have an arch_pick_mmap_layout()
+ */
+#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+
 /*
  * A special page (the vdso) is mapped into all processes at the very
  * top of the virtual memory space.
@@ -52,6 +57,9 @@ extern unsigned int vced_count, vcei_count;
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE	((TASK_SIZE / 3) & ~(PAGE_SIZE))
+
+#define TASK_IS_32BIT_ADDR 1
+
 #endif
 
 #ifdef CONFIG_64BIT
@@ -77,6 +85,9 @@ extern unsigned int vced_count, vcei_count;
 		PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
 #define TASK_SIZE_OF(tsk)						\
 	(test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+
+#define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
+
 #endif
 
 #ifdef __KERNEL__
@@ -218,7 +229,6 @@ struct thread_struct {
 	unsigned long cp0_badvaddr;	/* Last user fault */
 	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
 	unsigned long error_code;
-	unsigned long trap_no;
 	unsigned long irix_trampoline;  /* Wheee... */
 	unsigned long irix_oldctx;
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
@@ -290,7 +300,6 @@ struct thread_struct {
 	.cp0_badvaddr		= 0,				\
 	.cp0_baduaddr		= 0,				\
 	.error_code		= 0,				\
-	.trap_no		= 0,				\
 	.irix_trampoline	= 0,				\
 	.irix_oldctx		= 0,				\
 	/*							\
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index cdc6a46efd988a0b5d09bf134232ac2bf8007764..9f1b8dba2c81aa1b7dea3d5269ddcea4bb33692b 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -137,6 +137,7 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
  */
 #define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
 
+#define regs_return_value(_regs) ((_regs)->regs[2])
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 #define profile_pc(regs) instruction_pointer(regs)
 
diff --git a/arch/mips/include/asm/sn/agent.h b/arch/mips/include/asm/sn/agent.h
index ac4ea85c3a5c7da6338859581135486b8c65607a..dc81114d4742494d366e5f566dbd6a3a61286f10 100644
--- a/arch/mips/include/asm/sn/agent.h
+++ b/arch/mips/include/asm/sn/agent.h
@@ -11,7 +11,6 @@
 #ifndef _ASM_SGI_SN_AGENT_H
 #define _ASM_SGI_SN_AGENT_H
 
-#include <linux/topology.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 697e40c06497bd62d8627b6171f43faf22ccfac8..892062d6d748f5a234a3da2d1ee98211f11c2d4d 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -10,44 +10,55 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_EXPORT_UASM
+#include <linux/module.h>
+#define __uasminit
+#define __uasminitdata
+#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
+#else
+#define __uasminit __cpuinit
+#define __uasminitdata __cpuinitdata
+#define UASM_EXPORT_SYMBOL(sym)
+#endif
+
 #define Ip_u1u2u3(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u2u1u3(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u3u1u2(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u1u2s3(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
 #define Ip_u2s3u1(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
 
 #define Ip_u2u1s3(op)							\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
 #define Ip_u2u1msbu3(op)						\
-void __cpuinit								\
+void __uasminit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c,	\
 	   unsigned int d)
 
 #define Ip_u1u2(op)							\
-void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+void __uasminit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
 
 #define Ip_u1s2(op)							\
-void __cpuinit uasm_i##op(u32 **buf, unsigned int a, signed int b)
+void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b)
 
-#define Ip_u1(op) void __cpuinit uasm_i##op(u32 **buf, unsigned int a)
+#define Ip_u1(op) void __uasminit uasm_i##op(u32 **buf, unsigned int a)
 
-#define Ip_0(op) void __cpuinit uasm_i##op(u32 **buf)
+#define Ip_0(op) void __uasminit uasm_i##op(u32 **buf)
 
 Ip_u2u1s3(_addiu);
 Ip_u3u1u2(_addu);
@@ -71,6 +82,7 @@ Ip_u2u1u3(_dsra);
 Ip_u2u1u3(_dsrl);
 Ip_u2u1u3(_dsrl32);
 Ip_u2u1u3(_drotr);
+Ip_u2u1u3(_drotr32);
 Ip_u3u1u2(_dsubu);
 Ip_0(_eret);
 Ip_u1(_j);
@@ -111,7 +123,7 @@ struct uasm_label {
 	int lab;
 };
 
-void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
+void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
 #ifdef CONFIG_64BIT
 int uasm_in_compat_space_p(long addr);
 #endif
@@ -121,7 +133,7 @@ void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
 void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
 
 #define UASM_L_LA(lb)							\
-static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
+static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
 {									\
 	uasm_build_label(lab, addr, label##lb);				\
 }
@@ -176,6 +188,15 @@ static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
 		uasm_i_dsrl32(p, a1, a2, a3 - 32);
 }
 
+static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1,
+				     unsigned int a2, unsigned int a3)
+{
+	if (a3 < 32)
+		uasm_i_drotr(p, a1, a2, a3);
+	else
+		uasm_i_drotr32(p, a1, a2, a3 - 32);
+}
+
 static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
 				    unsigned int a2, unsigned int a3)
 {
@@ -213,3 +234,7 @@ void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
 void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
 void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
 void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
+		   unsigned int bit, int lid);
+void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
+		   unsigned int bit, int lid);
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
index 5aee0c266d188654f12bffab7c5c9e0977c6829a..dd9d99bfcf7a2d5cf6535740f2a7cb1594aa2e58 100644
--- a/arch/mips/jazz/Makefile
+++ b/arch/mips/jazz/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 	:= irq.o jazzdma.o reset.o setup.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/jazz/Platform b/arch/mips/jazz/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..3373788acca12e0b7af34a5f04ce5ed7024a3f94
--- /dev/null
+++ b/arch/mips/jazz/Platform
@@ -0,0 +1,6 @@
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+platform-$(CONFIG_MACH_JAZZ)	+= jazz/
+cflags-$(CONFIG_MACH_JAZZ)	+= -I$(srctree)/arch/mips/include/asm/mach-jazz
+load-$(CONFIG_MACH_JAZZ)	+= 0xffffffff80080000
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..3e7141f0746c4617bbea24459ef5b13ec41afa87
--- /dev/null
+++ b/arch/mips/jz4740/Kconfig
@@ -0,0 +1,12 @@
+choice
+	prompt "Machine type"
+	depends on MACH_JZ4740
+	default JZ4740_QI_LB60
+
+config JZ4740_QI_LB60
+	bool "Qi Hardware Ben NanoNote"
+
+endchoice
+
+config HAVE_PWM
+	bool
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a604eaeb6c08533616839485b6f8fc89a032ed2b
--- /dev/null
+++ b/arch/mips/jz4740/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the Ingenic JZ4740.
+#
+
+# Object file lists.
+
+obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
+	gpio.o clock.o platform.o timer.o pwm.o serial.o
+
+obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
+
+# board specific support
+
+obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+
+EXTRA_CFLAGS += -Werror -Wall
diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..6a97230e3d05ee4a53478c2a4625c51d92b26bd2
--- /dev/null
+++ b/arch/mips/jz4740/Platform
@@ -0,0 +1,3 @@
+core-$(CONFIG_MACH_JZ4740)	+= arch/mips/jz4740/
+cflags-$(CONFIG_MACH_JZ4740)	+= -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_MACH_JZ4740)	+= 0xffffffff80010000
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
new file mode 100644
index 0000000000000000000000000000000000000000..5742bb4d78f4db6aefa966b443dee7e095a2cfc5
--- /dev/null
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -0,0 +1,471 @@
+/*
+ * linux/arch/mips/jz4740/board-qi_lb60.c
+ *
+ * QI_LB60 board support
+ *
+ * Copyright (c) 2009 Qi Hardware inc.,
+ * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
+ * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or later
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/power_supply.h>
+#include <linux/power/jz4740-battery.h>
+
+#include <asm/mach-jz4740/jz4740_fb.h>
+#include <asm/mach-jz4740/jz4740_mmc.h>
+#include <asm/mach-jz4740/jz4740_nand.h>
+
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/leds_pwm.h>
+
+#include <asm/mach-jz4740/platform.h>
+
+#include "clock.h"
+
+static bool is_avt2;
+
+/* GPIOs */
+#define QI_LB60_GPIO_SD_CD		JZ_GPIO_PORTD(0)
+#define QI_LB60_GPIO_SD_VCC_EN_N	JZ_GPIO_PORTD(2)
+
+#define QI_LB60_GPIO_KEYOUT(x)		(JZ_GPIO_PORTC(10) + (x))
+#define QI_LB60_GPIO_KEYIN(x)		(JZ_GPIO_PORTD(18) + (x))
+#define QI_LB60_GPIO_KEYIN8		JZ_GPIO_PORTD(26)
+
+/* NAND */
+static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
+/*	.eccbytes = 36,
+	.eccpos = {
+		6,  7,  8,  9,  10, 11, 12, 13,
+		14, 15, 16, 17, 18, 19, 20, 21,
+		22, 23, 24, 25, 26, 27, 28, 29,
+		30, 31, 32, 33, 34, 35, 36, 37,
+		38, 39, 40, 41
+	},*/
+	.oobfree = {
+		{ .offset = 2, .length = 4 },
+		{ .offset = 42, .length = 22 }
+	},
+};
+
+/* Early prototypes of the QI LB60 had only 1GB of NAND.
+ * In order to support these devices aswell the partition and ecc layout is
+ * initalized depending on the NAND size */
+static struct mtd_partition qi_lb60_partitions_1gb[] = {
+	{
+		.name = "NAND BOOT partition",
+		.offset = 0 * 0x100000,
+		.size = 4 * 0x100000,
+	},
+	{
+		.name = "NAND KERNEL partition",
+		.offset = 4 * 0x100000,
+		.size = 4 * 0x100000,
+	},
+	{
+		.name = "NAND ROOTFS partition",
+		.offset = 8 * 0x100000,
+		.size = (504 + 512) * 0x100000,
+	},
+};
+
+static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
+/*	.eccbytes = 72,
+	.eccpos = {
+		12, 13, 14, 15, 16, 17, 18, 19,
+		20, 21, 22, 23, 24, 25, 26, 27,
+		28, 29, 30, 31, 32, 33, 34, 35,
+		36, 37, 38, 39, 40, 41, 42, 43,
+		44, 45, 46, 47, 48, 49, 50, 51,
+		52, 53, 54, 55, 56, 57, 58, 59,
+		60, 61, 62, 63, 64, 65, 66, 67,
+		68, 69, 70, 71, 72, 73, 74, 75,
+		76, 77, 78, 79, 80, 81, 82, 83
+	},*/
+	.oobfree = {
+		{ .offset = 2, .length = 10 },
+		{ .offset = 84, .length = 44 },
+	},
+};
+
+static struct mtd_partition qi_lb60_partitions_2gb[] = {
+	{
+		.name = "NAND BOOT partition",
+		.offset = 0 * 0x100000,
+		.size = 4 * 0x100000,
+	},
+	{
+		.name = "NAND KERNEL partition",
+		.offset = 4 * 0x100000,
+		.size = 4 * 0x100000,
+	},
+	{
+		.name = "NAND ROOTFS partition",
+		.offset = 8 * 0x100000,
+		.size = (504 + 512 + 1024) * 0x100000,
+	},
+};
+
+static void qi_lb60_nand_ident(struct platform_device *pdev,
+		struct nand_chip *chip, struct mtd_partition **partitions,
+		int *num_partitions)
+{
+	if (chip->page_shift == 12) {
+		chip->ecc.layout = &qi_lb60_ecclayout_2gb;
+		*partitions = qi_lb60_partitions_2gb;
+		*num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
+	} else {
+		chip->ecc.layout = &qi_lb60_ecclayout_1gb;
+		*partitions = qi_lb60_partitions_1gb;
+		*num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
+	}
+}
+
+static struct jz_nand_platform_data qi_lb60_nand_pdata = {
+	.ident_callback = qi_lb60_nand_ident,
+	.busy_gpio = 94,
+};
+
+/* Keyboard*/
+
+#define KEY_QI_QI	KEY_F13
+#define KEY_QI_UPRED	KEY_RIGHTALT
+#define KEY_QI_VOLUP	KEY_VOLUMEUP
+#define KEY_QI_VOLDOWN	KEY_VOLUMEDOWN
+#define KEY_QI_FN	KEY_LEFTCTRL
+
+static const uint32_t qi_lb60_keymap[] = {
+	KEY(0, 0, KEY_F1),	/* S2 */
+	KEY(0, 1, KEY_F2),	/* S3 */
+	KEY(0, 2, KEY_F3),	/* S4 */
+	KEY(0, 3, KEY_F4),	/* S5 */
+	KEY(0, 4, KEY_F5),	/* S6 */
+	KEY(0, 5, KEY_F6),	/* S7 */
+	KEY(0, 6, KEY_F7),	/* S8 */
+
+	KEY(1, 0, KEY_Q),	/* S10 */
+	KEY(1, 1, KEY_W),	/* S11 */
+	KEY(1, 2, KEY_E),	/* S12 */
+	KEY(1, 3, KEY_R),	/* S13 */
+	KEY(1, 4, KEY_T),	/* S14 */
+	KEY(1, 5, KEY_Y),	/* S15 */
+	KEY(1, 6, KEY_U),	/* S16 */
+	KEY(1, 7, KEY_I),	/* S17 */
+	KEY(2, 0, KEY_A),	/* S18 */
+	KEY(2, 1, KEY_S),	/* S19 */
+	KEY(2, 2, KEY_D),	/* S20 */
+	KEY(2, 3, KEY_F),	/* S21 */
+	KEY(2, 4, KEY_G),	/* S22 */
+	KEY(2, 5, KEY_H),	/* S23 */
+	KEY(2, 6, KEY_J),	/* S24 */
+	KEY(2, 7, KEY_K),	/* S25 */
+	KEY(3, 0, KEY_ESC),	/* S26 */
+	KEY(3, 1, KEY_Z),	/* S27 */
+	KEY(3, 2, KEY_X),	/* S28 */
+	KEY(3, 3, KEY_C),	/* S29 */
+	KEY(3, 4, KEY_V),	/* S30 */
+	KEY(3, 5, KEY_B),	/* S31 */
+	KEY(3, 6, KEY_N),	/* S32 */
+	KEY(3, 7, KEY_M),	/* S33 */
+	KEY(4, 0, KEY_TAB),	/* S34 */
+	KEY(4, 1, KEY_CAPSLOCK),	/* S35 */
+	KEY(4, 2, KEY_BACKSLASH),	/* S36 */
+	KEY(4, 3, KEY_APOSTROPHE),	/* S37 */
+	KEY(4, 4, KEY_COMMA),	/* S38 */
+	KEY(4, 5, KEY_DOT),	/* S39 */
+	KEY(4, 6, KEY_SLASH),	/* S40 */
+	KEY(4, 7, KEY_UP),	/* S41 */
+	KEY(5, 0, KEY_O),	/* S42 */
+	KEY(5, 1, KEY_L),	/* S43 */
+	KEY(5, 2, KEY_EQUAL),	/* S44 */
+	KEY(5, 3, KEY_QI_UPRED),	/* S45 */
+	KEY(5, 4, KEY_SPACE),	/* S46 */
+	KEY(5, 5, KEY_QI_QI),	/* S47 */
+	KEY(5, 6, KEY_RIGHTCTRL),	/* S48 */
+	KEY(5, 7, KEY_LEFT),	/* S49 */
+	KEY(6, 0, KEY_F8),	/* S50 */
+	KEY(6, 1, KEY_P),	/* S51 */
+	KEY(6, 2, KEY_BACKSPACE),/* S52 */
+	KEY(6, 3, KEY_ENTER),	/* S53 */
+	KEY(6, 4, KEY_QI_VOLUP),	/* S54 */
+	KEY(6, 5, KEY_QI_VOLDOWN),	/* S55 */
+	KEY(6, 6, KEY_DOWN),	/* S56 */
+	KEY(6, 7, KEY_RIGHT),	/* S57 */
+
+	KEY(7, 0, KEY_LEFTSHIFT),	/* S58 */
+	KEY(7, 1, KEY_LEFTALT),	/* S59 */
+	KEY(7, 2, KEY_QI_FN),	/* S60 */
+};
+
+static const struct matrix_keymap_data qi_lb60_keymap_data = {
+	.keymap		= qi_lb60_keymap,
+	.keymap_size	= ARRAY_SIZE(qi_lb60_keymap),
+};
+
+static const unsigned int qi_lb60_keypad_cols[] = {
+	QI_LB60_GPIO_KEYOUT(0),
+	QI_LB60_GPIO_KEYOUT(1),
+	QI_LB60_GPIO_KEYOUT(2),
+	QI_LB60_GPIO_KEYOUT(3),
+	QI_LB60_GPIO_KEYOUT(4),
+	QI_LB60_GPIO_KEYOUT(5),
+	QI_LB60_GPIO_KEYOUT(6),
+	QI_LB60_GPIO_KEYOUT(7),
+};
+
+static const unsigned int qi_lb60_keypad_rows[] = {
+	QI_LB60_GPIO_KEYIN(0),
+	QI_LB60_GPIO_KEYIN(1),
+	QI_LB60_GPIO_KEYIN(2),
+	QI_LB60_GPIO_KEYIN(3),
+	QI_LB60_GPIO_KEYIN(4),
+	QI_LB60_GPIO_KEYIN(5),
+	QI_LB60_GPIO_KEYIN(7),
+	QI_LB60_GPIO_KEYIN8,
+};
+
+static struct matrix_keypad_platform_data qi_lb60_pdata = {
+	.keymap_data = &qi_lb60_keymap_data,
+	.col_gpios	= qi_lb60_keypad_cols,
+	.row_gpios	= qi_lb60_keypad_rows,
+	.num_col_gpios	= ARRAY_SIZE(qi_lb60_keypad_cols),
+	.num_row_gpios	= ARRAY_SIZE(qi_lb60_keypad_rows),
+	.col_scan_delay_us	= 10,
+	.debounce_ms		= 10,
+	.wakeup			= 1,
+	.active_low		= 1,
+};
+
+static struct platform_device qi_lb60_keypad = {
+	.name		= "matrix-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &qi_lb60_pdata,
+	},
+};
+
+/* Display */
+static struct fb_videomode qi_lb60_video_modes[] = {
+	{
+		.name = "320x240",
+		.xres = 320,
+		.yres = 240,
+		.refresh = 30,
+		.left_margin = 140,
+		.right_margin = 273,
+		.upper_margin = 20,
+		.lower_margin = 2,
+		.hsync_len = 1,
+		.vsync_len = 1,
+		.sync = 0,
+		.vmode = FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
+	.width		= 60,
+	.height		= 45,
+	.num_modes	= ARRAY_SIZE(qi_lb60_video_modes),
+	.modes		= qi_lb60_video_modes,
+	.bpp		= 24,
+	.lcd_type	= JZ_LCD_TYPE_8BIT_SERIAL,
+	.pixclk_falling_edge = 1,
+};
+
+struct spi_gpio_platform_data spigpio_platform_data = {
+	.sck = JZ_GPIO_PORTC(23),
+	.mosi = JZ_GPIO_PORTC(22),
+	.miso = -1,
+	.num_chipselect = 1,
+};
+
+static struct platform_device spigpio_device = {
+	.name = "spi_gpio",
+	.id   = 1,
+	.dev = {
+		.platform_data = &spigpio_platform_data,
+	},
+};
+
+static struct spi_board_info qi_lb60_spi_board_info[] = {
+	{
+		.modalias = "ili8960",
+		.controller_data = (void *)JZ_GPIO_PORTC(21),
+		.chip_select = 0,
+		.bus_num = 1,
+		.max_speed_hz = 30 * 1000,
+		.mode = SPI_3WIRE,
+	},
+};
+
+/* Battery */
+static struct jz_battery_platform_data qi_lb60_battery_pdata = {
+	.gpio_charge =  JZ_GPIO_PORTC(27),
+	.gpio_charge_active_low = 1,
+	.info = {
+		.name = "battery",
+		.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+		.voltage_max_design = 4200000,
+		.voltage_min_design = 3600000,
+	},
+};
+
+/* GPIO Key: power */
+static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
+	[0] = {
+		.code		= KEY_POWER,
+		.gpio		= JZ_GPIO_PORTD(29),
+		.active_low	= 1,
+		.desc		= "Power",
+		.wakeup		= 1,
+	},
+};
+
+static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = {
+	.nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons),
+	.buttons = qi_lb60_gpio_keys_buttons,
+};
+
+static struct platform_device qi_lb60_gpio_keys = {
+	.name =	"gpio-keys",
+	.id =	-1,
+	.dev = {
+		.platform_data = &qi_lb60_gpio_keys_data,
+	}
+};
+
+static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = {
+	.gpio_card_detect	= QI_LB60_GPIO_SD_CD,
+	.gpio_read_only		= -1,
+	.gpio_power		= QI_LB60_GPIO_SD_VCC_EN_N,
+	.power_active_low	= 1,
+};
+
+/* OHCI */
+static struct regulator_consumer_supply avt2_usb_regulator_consumer =
+	REGULATOR_SUPPLY("vbus", "jz4740-ohci");
+
+static struct regulator_init_data avt2_usb_regulator_init_data = {
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &avt2_usb_regulator_consumer,
+	.constraints = {
+		.name = "USB power",
+		.min_uV = 5000000,
+		.max_uV = 5000000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static struct fixed_voltage_config avt2_usb_regulator_data = {
+	.supply_name = "USB power",
+	.microvolts = 5000000,
+	.gpio = JZ_GPIO_PORTB(17),
+	.init_data = &avt2_usb_regulator_init_data,
+};
+
+static struct platform_device avt2_usb_regulator_device = {
+	.name = "reg-fixed-voltage",
+	.id = -1,
+	.dev = {
+		.platform_data = &avt2_usb_regulator_data,
+	}
+};
+
+/* beeper */
+static struct platform_device qi_lb60_pwm_beeper = {
+	.name = "pwm-beeper",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)4,
+	},
+};
+
+static struct platform_device *jz_platform_devices[] __initdata = {
+	&jz4740_udc_device,
+	&jz4740_mmc_device,
+	&jz4740_nand_device,
+	&qi_lb60_keypad,
+	&spigpio_device,
+	&jz4740_framebuffer_device,
+	&jz4740_pcm_device,
+	&jz4740_i2s_device,
+	&jz4740_codec_device,
+	&jz4740_rtc_device,
+	&jz4740_adc_device,
+	&qi_lb60_gpio_keys,
+	&qi_lb60_pwm_beeper,
+};
+
+static void __init board_gpio_setup(void)
+{
+	/* We only need to enable/disable pullup here for pins used in generic
+	 * drivers. Everything else is done by the drivers themselfs. */
+	jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N);
+	jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD);
+}
+
+static int __init qi_lb60_init_platform_devices(void)
+{
+	jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata;
+	jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata;
+	jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata;
+	jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata;
+
+	jz4740_serial_device_register();
+
+	spi_register_board_info(qi_lb60_spi_board_info,
+				ARRAY_SIZE(qi_lb60_spi_board_info));
+
+	if (is_avt2) {
+		platform_device_register(&avt2_usb_regulator_device);
+		platform_device_register(&jz4740_usb_ohci_device);
+	}
+
+	return platform_add_devices(jz_platform_devices,
+					ARRAY_SIZE(jz_platform_devices));
+
+}
+
+struct jz4740_clock_board_data jz4740_clock_bdata = {
+	.ext_rate = 12000000,
+	.rtc_rate = 32768,
+};
+
+static __init int board_avt2(char *str)
+{
+	qi_lb60_mmc_pdata.card_detect_active_low = 1;
+	is_avt2 = true;
+
+	return 1;
+}
+__setup("avt2", board_avt2);
+
+static int __init qi_lb60_board_setup(void)
+{
+	printk(KERN_INFO "Qi Hardware JZ4740 QI %s setup\n",
+		is_avt2 ? "AVT2" : "LB60");
+
+	board_gpio_setup();
+
+	if (qi_lb60_init_platform_devices())
+		panic("Failed to initalize platform devices\n");
+
+	return 0;
+}
+arch_initcall(qi_lb60_board_setup);
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..330a0f2bf17bb5a062ebd1e32a573cbbb15c25f5
--- /dev/null
+++ b/arch/mips/jz4740/clock-debugfs.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support debugfs entries
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include "clock.h"
+
+static struct dentry *jz4740_clock_debugfs;
+
+static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
+{
+	struct clk *clk = data;
+	*value = clk_is_enabled(clk);
+
+	return 0;
+}
+
+static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
+{
+	struct clk *clk = data;
+
+	if (value)
+		return clk_enable(clk);
+	else
+		clk_disable(clk);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
+	jz4740_clock_debugfs_show_enabled,
+	jz4740_clock_debugfs_set_enabled,
+	"%llu\n");
+
+static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
+{
+	struct clk *clk = data;
+	*value = clk_get_rate(clk);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
+	jz4740_clock_debugfs_show_rate,
+	NULL,
+	"%llu\n");
+
+void jz4740_clock_debugfs_add_clk(struct clk *clk)
+{
+	if (!jz4740_clock_debugfs)
+		return;
+
+	clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
+	debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
+				&jz4740_clock_debugfs_ops_rate);
+	debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
+				&jz4740_clock_debugfs_ops_enabled);
+
+	if (clk->parent) {
+		char parent_path[100];
+		snprintf(parent_path, 100, "../%s", clk->parent->name);
+		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+						clk->debugfs_entry,
+						parent_path);
+	}
+}
+
+/* TODO: Locking */
+void jz4740_clock_debugfs_update_parent(struct clk *clk)
+{
+	if (clk->debugfs_parent_entry)
+		debugfs_remove(clk->debugfs_parent_entry);
+
+	if (clk->parent) {
+		char parent_path[100];
+		snprintf(parent_path, 100, "../%s", clk->parent->name);
+		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+						clk->debugfs_entry,
+						parent_path);
+	} else {
+		clk->debugfs_parent_entry = NULL;
+	}
+}
+
+void jz4740_clock_debugfs_init(void)
+{
+	jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
+	if (IS_ERR(jz4740_clock_debugfs))
+		jz4740_clock_debugfs = NULL;
+}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
new file mode 100644
index 0000000000000000000000000000000000000000..118a8a5562ddce782a3ac35e44740a63862f6e0a
--- /dev/null
+++ b/arch/mips/jz4740/clock.c
@@ -0,0 +1,924 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support
+ *
+ *  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.
+ *
+ *  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/errno.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include <asm/mach-jz4740/base.h>
+
+#include "clock.h"
+
+#define JZ_REG_CLOCK_CTRL	0x00
+#define JZ_REG_CLOCK_LOW_POWER	0x04
+#define JZ_REG_CLOCK_PLL	0x10
+#define JZ_REG_CLOCK_GATE	0x20
+#define JZ_REG_CLOCK_SLEEP_CTRL	0x24
+#define JZ_REG_CLOCK_I2S	0x60
+#define JZ_REG_CLOCK_LCD	0x64
+#define JZ_REG_CLOCK_MMC	0x68
+#define JZ_REG_CLOCK_UHC	0x6C
+#define JZ_REG_CLOCK_SPI	0x74
+
+#define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
+#define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
+#define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
+#define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
+#define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
+#define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
+#define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
+#define JZ_CLOCK_CTRL_UDIV_OFFSET	23
+#define JZ_CLOCK_CTRL_LDIV_OFFSET	16
+#define JZ_CLOCK_CTRL_MDIV_OFFSET	12
+#define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
+#define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
+#define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
+
+#define JZ_CLOCK_GATE_UART0	BIT(0)
+#define JZ_CLOCK_GATE_TCU	BIT(1)
+#define JZ_CLOCK_GATE_RTC	BIT(2)
+#define JZ_CLOCK_GATE_I2C	BIT(3)
+#define JZ_CLOCK_GATE_SPI	BIT(4)
+#define JZ_CLOCK_GATE_AIC	BIT(5)
+#define JZ_CLOCK_GATE_I2S	BIT(6)
+#define JZ_CLOCK_GATE_MMC	BIT(7)
+#define JZ_CLOCK_GATE_ADC	BIT(8)
+#define JZ_CLOCK_GATE_CIM	BIT(9)
+#define JZ_CLOCK_GATE_LCD	BIT(10)
+#define JZ_CLOCK_GATE_UDC	BIT(11)
+#define JZ_CLOCK_GATE_DMAC	BIT(12)
+#define JZ_CLOCK_GATE_IPU	BIT(13)
+#define JZ_CLOCK_GATE_UHC	BIT(14)
+#define JZ_CLOCK_GATE_UART1	BIT(15)
+
+#define JZ_CLOCK_I2S_DIV_MASK		0x01ff
+
+#define JZ_CLOCK_LCD_DIV_MASK		0x01ff
+
+#define JZ_CLOCK_MMC_DIV_MASK		0x001f
+
+#define JZ_CLOCK_UHC_DIV_MASK		0x000f
+
+#define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
+#define JZ_CLOCK_SPI_DIV_MASK		0x000f
+
+#define JZ_CLOCK_PLL_M_MASK		0x01ff
+#define JZ_CLOCK_PLL_N_MASK		0x001f
+#define JZ_CLOCK_PLL_OD_MASK		0x0003
+#define JZ_CLOCK_PLL_STABLE		BIT(10)
+#define JZ_CLOCK_PLL_BYPASS		BIT(9)
+#define JZ_CLOCK_PLL_ENABLED		BIT(8)
+#define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
+#define JZ_CLOCK_PLL_M_OFFSET		23
+#define JZ_CLOCK_PLL_N_OFFSET		18
+#define JZ_CLOCK_PLL_OD_OFFSET		16
+
+#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
+#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
+
+#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
+#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
+
+static void __iomem *jz_clock_base;
+static spinlock_t jz_clock_lock;
+static LIST_HEAD(jz_clocks);
+
+struct main_clk {
+	struct clk clk;
+	uint32_t div_offset;
+};
+
+struct divided_clk {
+	struct clk clk;
+	uint32_t reg;
+	uint32_t mask;
+};
+
+struct static_clk {
+	struct clk clk;
+	unsigned long rate;
+};
+
+static uint32_t jz_clk_reg_read(int reg)
+{
+	return readl(jz_clock_base + reg);
+}
+
+static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
+{
+	uint32_t val2;
+
+	spin_lock(&jz_clock_lock);
+	val2 = readl(jz_clock_base + reg);
+	val2 &= ~mask;
+	val2 |= val;
+	writel(val2, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_set_bits(int reg, uint32_t mask)
+{
+	uint32_t val;
+
+	spin_lock(&jz_clock_lock);
+	val = readl(jz_clock_base + reg);
+	val |= mask;
+	writel(val, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
+{
+	uint32_t val;
+
+	spin_lock(&jz_clock_lock);
+	val = readl(jz_clock_base + reg);
+	val &= ~mask;
+	writel(val, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static int jz_clk_enable_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return -EINVAL;
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+	return 0;
+}
+
+static int jz_clk_disable_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return -EINVAL;
+
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+	return 0;
+}
+
+static int jz_clk_is_enabled_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return 1;
+
+	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
+}
+
+static unsigned long jz_clk_static_get_rate(struct clk *clk)
+{
+	return ((struct static_clk *)clk)->rate;
+}
+
+static int jz_clk_ko_enable(struct clk *clk)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+	return 0;
+}
+
+static int jz_clk_ko_disable(struct clk *clk)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+	return 0;
+}
+
+static int jz_clk_ko_is_enabled(struct clk *clk)
+{
+	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
+}
+
+static const int pllno[] = {1, 2, 2, 4};
+
+static unsigned long jz_clk_pll_get_rate(struct clk *clk)
+{
+	uint32_t val;
+	int m;
+	int n;
+	int od;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+
+	if (val & JZ_CLOCK_PLL_BYPASS)
+		return clk_get_rate(clk->parent);
+
+	m = ((val >> 23) & 0x1ff) + 2;
+	n = ((val >> 18) & 0x1f) + 2;
+	od = (val >> 16) & 0x3;
+
+	return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
+}
+
+static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
+{
+	uint32_t reg;
+
+	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
+		return jz_clk_pll_get_rate(clk->parent);
+	return jz_clk_pll_get_rate(clk->parent) >> 1;
+}
+
+static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+
+static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+	int div;
+
+	div = parent_rate / rate;
+	if (div > 32)
+		return parent_rate / 32;
+	else if (div < 1)
+		return parent_rate;
+
+	div &= (0x3 << (ffs(div) - 1));
+
+	return parent_rate / div;
+}
+
+static unsigned long jz_clk_main_get_rate(struct clk *clk)
+{
+	struct main_clk *mclk = (struct main_clk *)clk;
+	uint32_t div;
+
+	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+	div >>= mclk->div_offset;
+	div &= 0xf;
+
+	if (div >= ARRAY_SIZE(jz_clk_main_divs))
+		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
+
+	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
+}
+
+static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct main_clk *mclk = (struct main_clk *)clk;
+	int i;
+	int div;
+	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+
+	rate = jz_clk_main_round_rate(clk, rate);
+
+	div = parent_rate / rate;
+
+	i = (ffs(div) - 1) << 1;
+	if (i > 0 && !(div & BIT(i-1)))
+		i -= 1;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
+				0xf << mclk->div_offset);
+
+	return 0;
+}
+
+static struct clk_ops jz_clk_static_ops = {
+	.get_rate = jz_clk_static_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct static_clk jz_clk_ext = {
+	.clk = {
+		.name = "ext",
+		.gate_bit = JZ4740_CLK_NOT_GATED,
+		.ops = &jz_clk_static_ops,
+	},
+};
+
+static struct clk_ops jz_clk_pll_ops = {
+	.get_rate = jz_clk_pll_get_rate,
+};
+
+static struct clk jz_clk_pll = {
+	.name = "pll",
+	.parent = &jz_clk_ext.clk,
+	.ops = &jz_clk_pll_ops,
+};
+
+static struct clk_ops jz_clk_pll_half_ops = {
+	.get_rate = jz_clk_pll_half_get_rate,
+};
+
+static struct clk jz_clk_pll_half = {
+	.name = "pll half",
+	.parent = &jz_clk_pll,
+	.ops = &jz_clk_pll_half_ops,
+};
+
+static const struct clk_ops jz_clk_main_ops = {
+	.get_rate = jz_clk_main_get_rate,
+	.set_rate = jz_clk_main_set_rate,
+	.round_rate = jz_clk_main_round_rate,
+};
+
+static struct main_clk jz_clk_cpu = {
+	.clk = {
+		.name = "cclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_memory = {
+	.clk = {
+		.name = "mclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_high_speed_peripheral = {
+	.clk = {
+		.name = "hclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
+};
+
+
+static struct main_clk jz_clk_low_speed_peripheral = {
+	.clk = {
+		.name = "pclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
+};
+
+static const struct clk_ops jz_clk_ko_ops = {
+	.enable = jz_clk_ko_enable,
+	.disable = jz_clk_ko_disable,
+	.is_enabled = jz_clk_ko_is_enabled,
+};
+
+static struct clk jz_clk_ko = {
+	.name = "cko",
+	.parent = &jz_clk_memory.clk,
+	.ops = &jz_clk_ko_ops,
+};
+
+static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll)
+		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll_half)
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_udc_enable(struct clk *clk)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+	return 0;
+}
+
+static int jz_clk_udc_disable(struct clk *clk)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+	return 0;
+}
+
+static int jz_clk_udc_is_enabled(struct clk *clk)
+{
+	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+}
+
+static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll_half)
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return -EINVAL;
+
+	div = clk_get_rate(clk->parent) / rate - 1;
+
+	if (div < 0)
+		div = 0;
+	else if (div > 63)
+		div = 63;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
+				JZ_CLOCK_CTRL_UDIV_MASK);
+	return 0;
+}
+
+static unsigned long jz_clk_udc_get_rate(struct clk *clk)
+{
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return clk_get_rate(clk->parent);
+
+	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
+	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
+	div += 1;
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long jz_clk_divided_get_rate(struct clk *clk)
+{
+	struct divided_clk *dclk = (struct divided_clk *)clk;
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return clk_get_rate(clk->parent);
+
+	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct divided_clk *dclk = (struct divided_clk *)clk;
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return -EINVAL;
+
+	div = clk_get_rate(clk->parent) / rate - 1;
+
+	if (div < 0)
+		div = 0;
+	else if (div > dclk->mask)
+		div = dclk->mask;
+
+	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
+
+	return 0;
+}
+
+static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
+
+	if (rate > 150000000)
+		return 150000000;
+
+	div = parent_rate / rate;
+	if (div < 1)
+		div = 1;
+	else if (div > 32)
+		div = 32;
+
+	return parent_rate / div;
+}
+
+static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+
+	if (rate > 150000000)
+		return -EINVAL;
+
+	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
+	if (div < 0)
+		div = 0;
+	else if (div > 31)
+		div = 31;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
+				JZ_CLOCK_CTRL_LDIV_MASK);
+
+	return 0;
+}
+
+static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
+{
+	int div;
+
+	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
+	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
+
+	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
+}
+
+static const struct clk_ops jz_clk_ops_ld = {
+	.set_rate = jz_clk_ldclk_set_rate,
+	.get_rate = jz_clk_ldclk_get_rate,
+	.round_rate = jz_clk_ldclk_round_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz_clk_ld = {
+	.name = "lcd",
+	.gate_bit = JZ_CLOCK_GATE_LCD,
+	.parent = &jz_clk_pll_half,
+	.ops = &jz_clk_ops_ld,
+};
+
+static const struct clk_ops jz_clk_i2s_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+	.set_parent = jz_clk_i2s_set_parent,
+};
+
+static const struct clk_ops jz_clk_spi_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+	.set_parent = jz_clk_spi_set_parent,
+};
+
+static const struct clk_ops jz_clk_divided_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct divided_clk jz4740_clock_divided_clks[] = {
+	[0] = {
+		.clk = {
+			.name = "i2s",
+			.parent = &jz_clk_ext.clk,
+			.gate_bit = JZ_CLOCK_GATE_I2S,
+			.ops = &jz_clk_i2s_ops,
+		},
+		.reg = JZ_REG_CLOCK_I2S,
+		.mask = JZ_CLOCK_I2S_DIV_MASK,
+	},
+	[1] = {
+		.clk = {
+			.name = "spi",
+			.parent = &jz_clk_ext.clk,
+			.gate_bit = JZ_CLOCK_GATE_SPI,
+			.ops = &jz_clk_spi_ops,
+		},
+		.reg = JZ_REG_CLOCK_SPI,
+		.mask = JZ_CLOCK_SPI_DIV_MASK,
+	},
+	[2] = {
+		.clk = {
+			.name = "lcd_pclk",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ4740_CLK_NOT_GATED,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_LCD,
+		.mask = JZ_CLOCK_LCD_DIV_MASK,
+	},
+	[3] = {
+		.clk = {
+			.name = "mmc",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ_CLOCK_GATE_MMC,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_MMC,
+		.mask = JZ_CLOCK_MMC_DIV_MASK,
+	},
+	[4] = {
+		.clk = {
+			.name = "uhc",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ_CLOCK_GATE_UHC,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_UHC,
+		.mask = JZ_CLOCK_UHC_DIV_MASK,
+	},
+};
+
+static const struct clk_ops jz_clk_udc_ops = {
+	.set_parent = jz_clk_udc_set_parent,
+	.set_rate = jz_clk_udc_set_rate,
+	.get_rate = jz_clk_udc_get_rate,
+	.enable = jz_clk_udc_enable,
+	.disable = jz_clk_udc_disable,
+	.is_enabled = jz_clk_udc_is_enabled,
+};
+
+static const struct clk_ops jz_clk_simple_ops = {
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz4740_clock_simple_clks[] = {
+	[0] = {
+		.name = "udc",
+		.parent = &jz_clk_ext.clk,
+		.ops = &jz_clk_udc_ops,
+	},
+	[1] = {
+		.name = "uart0",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART0,
+		.ops = &jz_clk_simple_ops,
+	},
+	[2] = {
+		.name = "uart1",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART1,
+		.ops = &jz_clk_simple_ops,
+	},
+	[3] = {
+		.name = "dma",
+		.parent = &jz_clk_high_speed_peripheral.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART0,
+		.ops = &jz_clk_simple_ops,
+	},
+	[4] = {
+		.name = "ipu",
+		.parent = &jz_clk_high_speed_peripheral.clk,
+		.gate_bit = JZ_CLOCK_GATE_IPU,
+		.ops = &jz_clk_simple_ops,
+	},
+	[5] = {
+		.name = "adc",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_ADC,
+		.ops = &jz_clk_simple_ops,
+	},
+	[6] = {
+		.name = "i2c",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_I2C,
+		.ops = &jz_clk_simple_ops,
+	},
+	[7] = {
+		.name = "aic",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_AIC,
+		.ops = &jz_clk_simple_ops,
+	},
+};
+
+static struct static_clk jz_clk_rtc = {
+	.clk = {
+		.name = "rtc",
+		.gate_bit = JZ_CLOCK_GATE_RTC,
+		.ops = &jz_clk_static_ops,
+	},
+	.rate = 32768,
+};
+
+int clk_enable(struct clk *clk)
+{
+	if (!clk->ops->enable)
+		return -EINVAL;
+
+	return clk->ops->enable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	if (clk->ops->disable)
+		clk->ops->disable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+int clk_is_enabled(struct clk *clk)
+{
+	if (clk->ops->is_enabled)
+		return clk->ops->is_enabled(clk);
+
+	return 1;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+	if (clk->parent)
+		return clk_get_rate(clk->parent);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (!clk->ops->set_rate)
+		return -EINVAL;
+	return clk->ops->set_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->round_rate)
+		return clk->ops->round_rate(clk, rate);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret;
+	int enabled;
+
+	if (!clk->ops->set_parent)
+		return -EINVAL;
+
+	enabled = clk_is_enabled(clk);
+	if (enabled)
+		clk_disable(clk);
+	ret = clk->ops->set_parent(clk, parent);
+	if (enabled)
+		clk_enable(clk);
+
+	jz4740_clock_debugfs_update_parent(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get(struct device *dev, const char *name)
+{
+	struct clk *clk;
+
+	list_for_each_entry(clk, &jz_clocks, list) {
+		if (strcmp(clk->name, name) == 0)
+			return clk;
+	}
+	return ERR_PTR(-ENXIO);
+}
+EXPORT_SYMBOL_GPL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+static inline void clk_add(struct clk *clk)
+{
+	list_add_tail(&clk->list, &jz_clocks);
+
+	jz4740_clock_debugfs_add_clk(clk);
+}
+
+static void clk_register_clks(void)
+{
+	size_t i;
+
+	clk_add(&jz_clk_ext.clk);
+	clk_add(&jz_clk_pll);
+	clk_add(&jz_clk_pll_half);
+	clk_add(&jz_clk_cpu.clk);
+	clk_add(&jz_clk_high_speed_peripheral.clk);
+	clk_add(&jz_clk_low_speed_peripheral.clk);
+	clk_add(&jz_clk_ko);
+	clk_add(&jz_clk_ld);
+	clk_add(&jz_clk_rtc.clk);
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
+		clk_add(&jz4740_clock_divided_clks[i].clk);
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
+		clk_add(&jz4740_clock_simple_clks[i]);
+}
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+	switch (mode) {
+	case JZ4740_WAIT_MODE_IDLE:
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+		break;
+	case JZ4740_WAIT_MODE_SLEEP:
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+		break;
+	}
+}
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+void jz4740_clock_suspend(void)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
+		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+}
+
+void jz4740_clock_resume(void)
+{
+	uint32_t pll;
+
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+
+	do {
+		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+	} while (!(pll & JZ_CLOCK_PLL_STABLE));
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
+		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+}
+
+static int jz4740_clock_init(void)
+{
+	uint32_t val;
+
+	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
+	if (!jz_clock_base)
+		return -EBUSY;
+
+	spin_lock_init(&jz_clock_lock);
+
+	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
+	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
+
+	if (val & JZ_CLOCK_SPI_SRC_PLL)
+		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
+		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
+
+	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
+		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
+
+	jz4740_clock_debugfs_init();
+
+	clk_register_clks();
+
+	return 0;
+}
+arch_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d07499d74619f517d149e9563ff1ecb302a9597
--- /dev/null
+++ b/arch/mips/jz4740/clock.h
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_CLOCK_H__
+#define __MIPS_JZ4740_CLOCK_H__
+
+#include <linux/list.h>
+
+struct jz4740_clock_board_data {
+	unsigned long ext_rate;
+	unsigned long rtc_rate;
+};
+
+extern struct jz4740_clock_board_data jz4740_clock_bdata;
+
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
+struct clk;
+
+struct clk_ops {
+	unsigned long (*get_rate)(struct clk *clk);
+	unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	int (*enable)(struct clk *clk);
+	int (*disable)(struct clk *clk);
+	int (*is_enabled)(struct clk *clk);
+
+	int (*set_parent)(struct clk *clk, struct clk *parent);
+
+};
+
+struct clk {
+	const char *name;
+	struct clk *parent;
+
+	uint32_t gate_bit;
+
+	const struct clk_ops *ops;
+
+	struct list_head list;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_entry;
+	struct dentry *debugfs_parent_entry;
+#endif
+
+};
+
+#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
+
+int clk_is_enabled(struct clk *clk);
+
+#ifdef CONFIG_DEBUG_FS
+void jz4740_clock_debugfs_init(void);
+void jz4740_clock_debugfs_add_clk(struct clk *clk);
+void jz4740_clock_debugfs_update_parent(struct clk *clk);
+#else
+static inline void jz4740_clock_debugfs_init(void) {};
+static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
+static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
+#endif
+
+#endif
diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ebe75a68350a186e5d5b1a9965ac5a757092b3d
--- /dev/null
+++ b/arch/mips/jz4740/dma.c
@@ -0,0 +1,289 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC DMA support
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <linux/dma-mapping.h>
+#include <asm/mach-jz4740/dma.h>
+#include <asm/mach-jz4740/base.h>
+
+#define JZ_REG_DMA_SRC_ADDR(x)		(0x00 + (x) * 0x20)
+#define JZ_REG_DMA_DST_ADDR(x)		(0x04 + (x) * 0x20)
+#define JZ_REG_DMA_TRANSFER_COUNT(x)	(0x08 + (x) * 0x20)
+#define JZ_REG_DMA_REQ_TYPE(x)		(0x0C + (x) * 0x20)
+#define JZ_REG_DMA_STATUS_CTRL(x)	(0x10 + (x) * 0x20)
+#define JZ_REG_DMA_CMD(x)		(0x14 + (x) * 0x20)
+#define JZ_REG_DMA_DESC_ADDR(x)		(0x18 + (x) * 0x20)
+
+#define JZ_REG_DMA_CTRL			0x300
+#define JZ_REG_DMA_IRQ			0x304
+#define JZ_REG_DMA_DOORBELL		0x308
+#define JZ_REG_DMA_DOORBELL_SET		0x30C
+
+#define JZ_DMA_STATUS_CTRL_NO_DESC		BIT(31)
+#define JZ_DMA_STATUS_CTRL_DESC_INV		BIT(6)
+#define JZ_DMA_STATUS_CTRL_ADDR_ERR		BIT(4)
+#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE	BIT(3)
+#define JZ_DMA_STATUS_CTRL_HALT			BIT(2)
+#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE	BIT(1)
+#define JZ_DMA_STATUS_CTRL_ENABLE		BIT(0)
+
+#define JZ_DMA_CMD_SRC_INC			BIT(23)
+#define JZ_DMA_CMD_DST_INC			BIT(22)
+#define JZ_DMA_CMD_RDIL_MASK			(0xf << 16)
+#define JZ_DMA_CMD_SRC_WIDTH_MASK		(0x3 << 14)
+#define JZ_DMA_CMD_DST_WIDTH_MASK		(0x3 << 12)
+#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK		(0x7 << 8)
+#define JZ_DMA_CMD_BLOCK_MODE			BIT(7)
+#define JZ_DMA_CMD_DESC_VALID			BIT(4)
+#define JZ_DMA_CMD_DESC_VALID_MODE		BIT(3)
+#define JZ_DMA_CMD_VALID_IRQ_ENABLE		BIT(2)
+#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE		BIT(1)
+#define JZ_DMA_CMD_LINK_ENABLE			BIT(0)
+
+#define JZ_DMA_CMD_FLAGS_OFFSET 22
+#define JZ_DMA_CMD_RDIL_OFFSET 16
+#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
+#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
+#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
+#define JZ_DMA_CMD_MODE_OFFSET 7
+
+#define JZ_DMA_CTRL_PRIORITY_MASK	(0x3 << 8)
+#define JZ_DMA_CTRL_HALT		BIT(3)
+#define JZ_DMA_CTRL_ADDRESS_ERROR	BIT(2)
+#define JZ_DMA_CTRL_ENABLE		BIT(0)
+
+
+static void __iomem *jz4740_dma_base;
+static spinlock_t jz4740_dma_lock;
+
+static inline uint32_t jz4740_dma_read(size_t reg)
+{
+	return readl(jz4740_dma_base + reg);
+}
+
+static inline void jz4740_dma_write(size_t reg, uint32_t val)
+{
+	writel(val, jz4740_dma_base + reg);
+}
+
+static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
+{
+	uint32_t val2;
+	val2 = jz4740_dma_read(reg);
+	val2 &= ~mask;
+	val2 |= val;
+	jz4740_dma_write(reg, val2);
+}
+
+struct jz4740_dma_chan {
+	unsigned int id;
+	void *dev;
+	const char *name;
+
+	enum jz4740_dma_flags flags;
+	uint32_t transfer_shift;
+
+	jz4740_dma_complete_callback_t complete_cb;
+
+	unsigned used:1;
+};
+
+#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
+
+struct jz4740_dma_chan jz4740_dma_channels[] = {
+	JZ4740_DMA_CHANNEL(0),
+	JZ4740_DMA_CHANNEL(1),
+	JZ4740_DMA_CHANNEL(2),
+	JZ4740_DMA_CHANNEL(3),
+	JZ4740_DMA_CHANNEL(4),
+	JZ4740_DMA_CHANNEL(5),
+};
+
+struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
+{
+	unsigned int i;
+	struct jz4740_dma_chan *dma = NULL;
+
+	spin_lock(&jz4740_dma_lock);
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
+		if (!jz4740_dma_channels[i].used) {
+			dma = &jz4740_dma_channels[i];
+			dma->used = 1;
+			break;
+		}
+	}
+
+	spin_unlock(&jz4740_dma_lock);
+
+	if (!dma)
+		return NULL;
+
+	dma->dev = dev;
+	dma->name = name;
+
+	return dma;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_request);
+
+void jz4740_dma_configure(struct jz4740_dma_chan *dma,
+	const struct jz4740_dma_config *config)
+{
+	uint32_t cmd;
+
+	switch (config->transfer_size) {
+	case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
+		dma->transfer_shift = 1;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
+		dma->transfer_shift = 2;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
+		dma->transfer_shift = 4;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
+		dma->transfer_shift = 5;
+		break;
+	default:
+		dma->transfer_shift = 0;
+		break;
+	}
+
+	cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
+	cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
+	cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
+	cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
+	cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
+	cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
+
+	jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
+	jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), 0);
+	jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_configure);
+
+void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
+{
+	jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
+
+void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
+{
+	jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
+
+void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
+{
+	count >>= dma->transfer_shift;
+	jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
+
+void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
+	jz4740_dma_complete_callback_t cb)
+{
+	dma->complete_cb = cb;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
+
+void jz4740_dma_free(struct jz4740_dma_chan *dma)
+{
+	dma->dev = NULL;
+	dma->complete_cb = NULL;
+	dma->used = 0;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_free);
+
+void jz4740_dma_enable(struct jz4740_dma_chan *dma)
+{
+	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
+			JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
+			JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
+			JZ_DMA_STATUS_CTRL_ENABLE);
+
+	jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
+			JZ_DMA_CTRL_ENABLE,
+			JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_enable);
+
+void jz4740_dma_disable(struct jz4740_dma_chan *dma)
+{
+	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
+			JZ_DMA_STATUS_CTRL_ENABLE);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_disable);
+
+uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
+{
+	uint32_t residue;
+	residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
+	return residue << dma->transfer_shift;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
+
+static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
+{
+	uint32_t status;
+
+	status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
+
+	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
+		JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
+
+	if (dma->complete_cb)
+		dma->complete_cb(dma, 0, dma->dev);
+}
+
+static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
+{
+	uint32_t irq_status;
+	unsigned int i;
+
+	irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
+
+	for (i = 0; i < 6; ++i) {
+		if (irq_status & (1 << i))
+			jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int jz4740_dma_init(void)
+{
+	unsigned int ret;
+
+	jz4740_dma_base = ioremap(JZ4740_DMAC_BASE_ADDR, 0x400);
+
+	if (!jz4740_dma_base)
+		return -EBUSY;
+
+	spin_lock_init(&jz4740_dma_lock);
+
+	ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
+
+	if (ret)
+		printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
+
+	return ret;
+}
+arch_initcall(jz4740_dma_init);
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..38f60f35156c5da6146811deaab69748d2d009a0
--- /dev/null
+++ b/arch/mips/jz4740/gpio.c
@@ -0,0 +1,604 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform GPIO support
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/init.h>
+
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <asm/mach-jz4740/base.h>
+
+#define JZ4740_GPIO_BASE_A (32*0)
+#define JZ4740_GPIO_BASE_B (32*1)
+#define JZ4740_GPIO_BASE_C (32*2)
+#define JZ4740_GPIO_BASE_D (32*3)
+
+#define JZ4740_GPIO_NUM_A 32
+#define JZ4740_GPIO_NUM_B 32
+#define JZ4740_GPIO_NUM_C 31
+#define JZ4740_GPIO_NUM_D 32
+
+#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
+#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
+#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
+#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
+
+#define JZ_REG_GPIO_PIN			0x00
+#define JZ_REG_GPIO_DATA		0x10
+#define JZ_REG_GPIO_DATA_SET		0x14
+#define JZ_REG_GPIO_DATA_CLEAR		0x18
+#define JZ_REG_GPIO_MASK		0x20
+#define JZ_REG_GPIO_MASK_SET		0x24
+#define JZ_REG_GPIO_MASK_CLEAR		0x28
+#define JZ_REG_GPIO_PULL		0x30
+#define JZ_REG_GPIO_PULL_SET		0x34
+#define JZ_REG_GPIO_PULL_CLEAR		0x38
+#define JZ_REG_GPIO_FUNC		0x40
+#define JZ_REG_GPIO_FUNC_SET		0x44
+#define JZ_REG_GPIO_FUNC_CLEAR		0x48
+#define JZ_REG_GPIO_SELECT		0x50
+#define JZ_REG_GPIO_SELECT_SET		0x54
+#define JZ_REG_GPIO_SELECT_CLEAR	0x58
+#define JZ_REG_GPIO_DIRECTION		0x60
+#define JZ_REG_GPIO_DIRECTION_SET	0x64
+#define JZ_REG_GPIO_DIRECTION_CLEAR	0x68
+#define JZ_REG_GPIO_TRIGGER		0x70
+#define JZ_REG_GPIO_TRIGGER_SET		0x74
+#define JZ_REG_GPIO_TRIGGER_CLEAR	0x78
+#define JZ_REG_GPIO_FLAG		0x80
+#define JZ_REG_GPIO_FLAG_CLEAR		0x14
+
+#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
+#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
+#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
+
+struct jz_gpio_chip {
+	unsigned int irq;
+	unsigned int irq_base;
+	uint32_t wakeup;
+	uint32_t suspend_mask;
+	uint32_t edge_trigger_both;
+
+	void __iomem *base;
+
+	spinlock_t lock;
+
+	struct gpio_chip gpio_chip;
+	struct irq_chip irq_chip;
+	struct sys_device sysdev;
+};
+
+static struct jz_gpio_chip jz4740_gpio_chips[];
+
+static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
+{
+	return &jz4740_gpio_chips[gpio >> 5];
+}
+
+static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
+{
+	return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
+}
+
+static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
+{
+	return get_irq_chip_data(irq);
+}
+
+static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
+{
+	writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
+}
+
+int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
+{
+	if (function == JZ_GPIO_FUNC_NONE) {
+		jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
+		jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
+		jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
+	} else {
+		jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
+		jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
+		switch (function) {
+		case JZ_GPIO_FUNC1:
+			jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
+			break;
+		case JZ_GPIO_FUNC3:
+			jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
+		case JZ_GPIO_FUNC2: /* Falltrough */
+			jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
+			break;
+		default:
+			BUG();
+			break;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(jz_gpio_set_function);
+
+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
+{
+	size_t i;
+	int ret;
+
+	for (i = 0; i < num; ++i, ++request) {
+		ret = gpio_request(request->gpio, request->name);
+		if (ret)
+			goto err;
+		jz_gpio_set_function(request->gpio, request->function);
+	}
+
+	return 0;
+
+err:
+	for (--request; i > 0; --i, --request) {
+		gpio_free(request->gpio);
+		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
+
+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
+{
+	size_t i;
+
+	for (i = 0; i < num; ++i, ++request) {
+		gpio_free(request->gpio);
+		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+	}
+
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
+
+void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
+{
+	size_t i;
+
+	for (i = 0; i < num; ++i, ++request) {
+		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+		jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
+		jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
+	}
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
+
+void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
+{
+	size_t i;
+
+	for (i = 0; i < num; ++i, ++request)
+		jz_gpio_set_function(request->gpio, request->function);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
+
+void jz_gpio_enable_pullup(unsigned gpio)
+{
+	jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
+
+void jz_gpio_disable_pullup(unsigned gpio)
+{
+	jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
+
+static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
+}
+
+static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
+	reg += !value;
+	writel(BIT(gpio), reg);
+}
+
+static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+	int value)
+{
+	writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
+	jz_gpio_set_value(chip, gpio, value);
+
+	return 0;
+}
+
+static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
+
+	return 0;
+}
+
+int jz_gpio_port_direction_input(int port, uint32_t mask)
+{
+	writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
+
+	return 0;
+}
+EXPORT_SYMBOL(jz_gpio_port_direction_input);
+
+int jz_gpio_port_direction_output(int port, uint32_t mask)
+{
+	writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
+
+	return 0;
+}
+EXPORT_SYMBOL(jz_gpio_port_direction_output);
+
+void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
+{
+	writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
+	writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
+}
+EXPORT_SYMBOL(jz_gpio_port_set_value);
+
+uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
+{
+	uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
+
+	return value & mask;
+}
+EXPORT_SYMBOL(jz_gpio_port_get_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+	return JZ4740_IRQ_GPIO(0) + gpio;
+}
+EXPORT_SYMBOL_GPL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+	return irq - JZ4740_IRQ_GPIO(0);
+}
+EXPORT_SYMBOL_GPL(irq_to_gpio);
+
+#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
+
+static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
+{
+	uint32_t value;
+	void __iomem *reg;
+	uint32_t mask = IRQ_TO_BIT(irq);
+
+	if (!(chip->edge_trigger_both & mask))
+		return;
+
+	reg = chip->base;
+
+	value = readl(chip->base + JZ_REG_GPIO_PIN);
+	if (value & mask)
+		reg += JZ_REG_GPIO_DIRECTION_CLEAR;
+	else
+		reg += JZ_REG_GPIO_DIRECTION_SET;
+
+	writel(mask, reg);
+}
+
+static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+	uint32_t flag;
+	unsigned int gpio_irq;
+	unsigned int gpio_bank;
+	struct jz_gpio_chip *chip = get_irq_desc_data(desc);
+
+	gpio_bank = JZ4740_IRQ_GPIO0 - irq;
+
+	flag = readl(chip->base + JZ_REG_GPIO_FLAG);
+
+	if (!flag)
+		return;
+
+	gpio_irq = __fls(flag);
+
+	jz_gpio_check_trigger_both(chip, irq);
+
+	gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
+
+	generic_handle_irq(gpio_irq);
+};
+
+static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
+{
+	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
+	writel(IRQ_TO_BIT(irq), chip->base + reg);
+}
+
+static void jz_gpio_irq_mask(unsigned int irq)
+{
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
+};
+
+static void jz_gpio_irq_unmask(unsigned int irq)
+{
+	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
+
+	jz_gpio_check_trigger_both(chip, irq);
+
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
+};
+
+/* TODO: Check if function is gpio */
+static unsigned int jz_gpio_irq_startup(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
+
+	desc->status &= ~IRQ_MASKED;
+	jz_gpio_irq_unmask(irq);
+
+	return 0;
+}
+
+static void jz_gpio_irq_shutdown(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	jz_gpio_irq_mask(irq);
+	desc->status |= IRQ_MASKED;
+
+	/* Set direction to input */
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
+}
+
+static void jz_gpio_irq_ack(unsigned int irq)
+{
+	jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
+};
+
+static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	jz_gpio_irq_mask(irq);
+
+	if (flow_type == IRQ_TYPE_EDGE_BOTH) {
+		uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
+		if (value & IRQ_TO_BIT(irq))
+			flow_type = IRQ_TYPE_EDGE_FALLING;
+		else
+			flow_type = IRQ_TYPE_EDGE_RISING;
+		chip->edge_trigger_both |= IRQ_TO_BIT(irq);
+	} else {
+		chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
+	}
+
+	switch (flow_type) {
+	case IRQ_TYPE_EDGE_RISING:
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
+		jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (!(desc->status & IRQ_MASKED))
+		jz_gpio_irq_unmask(irq);
+
+	return 0;
+}
+
+static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
+	spin_lock(&chip->lock);
+	if (on)
+		chip->wakeup |= IRQ_TO_BIT(irq);
+	else
+		chip->wakeup &= ~IRQ_TO_BIT(irq);
+	spin_unlock(&chip->lock);
+
+	set_irq_wake(chip->irq, on);
+	return 0;
+}
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+#define JZ4740_GPIO_CHIP(_bank) { \
+	.irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
+	.gpio_chip = { \
+		.label = "Bank " # _bank, \
+		.owner = THIS_MODULE, \
+		.set = jz_gpio_set_value, \
+		.get = jz_gpio_get_value, \
+		.direction_output = jz_gpio_direction_output, \
+		.direction_input = jz_gpio_direction_input, \
+		.base = JZ4740_GPIO_BASE_ ## _bank, \
+		.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
+	}, \
+	.irq_chip =  { \
+		.name = "GPIO Bank " # _bank, \
+		.mask = jz_gpio_irq_mask, \
+		.unmask = jz_gpio_irq_unmask, \
+		.ack = jz_gpio_irq_ack, \
+		.startup = jz_gpio_irq_startup, \
+		.shutdown = jz_gpio_irq_shutdown, \
+		.set_type = jz_gpio_irq_set_type, \
+		.set_wake = jz_gpio_irq_set_wake, \
+	}, \
+}
+
+static struct jz_gpio_chip jz4740_gpio_chips[] = {
+	JZ4740_GPIO_CHIP(A),
+	JZ4740_GPIO_CHIP(B),
+	JZ4740_GPIO_CHIP(C),
+	JZ4740_GPIO_CHIP(D),
+};
+
+static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
+{
+	return container_of(dev, struct jz_gpio_chip, sysdev);
+}
+
+static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct jz_gpio_chip *chip = sysdev_to_chip(dev);
+
+	chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
+	writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
+	writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
+
+	return 0;
+}
+
+static int jz4740_gpio_resume(struct sys_device *dev)
+{
+	struct jz_gpio_chip *chip = sysdev_to_chip(dev);
+	uint32_t mask = chip->suspend_mask;
+
+	writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
+	writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
+
+	return 0;
+}
+
+static struct sysdev_class jz4740_gpio_sysdev_class = {
+	.name = "gpio",
+	.suspend = jz4740_gpio_suspend,
+	.resume = jz4740_gpio_resume,
+};
+
+static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
+{
+	int ret, irq;
+
+	chip->sysdev.id = id;
+	chip->sysdev.cls = &jz4740_gpio_sysdev_class;
+	ret = sysdev_register(&chip->sysdev);
+
+	if (ret)
+		return ret;
+
+	spin_lock_init(&chip->lock);
+
+	chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
+
+	gpiochip_add(&chip->gpio_chip);
+
+	chip->irq = JZ4740_IRQ_INTC_GPIO(id);
+	set_irq_data(chip->irq, chip);
+	set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
+
+	for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
+		lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
+		set_irq_chip_data(irq, chip);
+		set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
+	}
+
+	return 0;
+}
+
+static int __init jz4740_gpio_init(void)
+{
+	unsigned int i;
+	int ret;
+
+	ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
+		jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
+
+	printk(KERN_INFO "JZ4740 GPIO initalized\n");
+
+	return 0;
+}
+arch_initcall(jz4740_gpio_init);
+
+#ifdef CONFIG_DEBUG_FS
+
+static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
+	const char *name, unsigned int reg)
+{
+	seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
+}
+
+static int gpio_regs_show(struct seq_file *s, void *unused)
+{
+	struct jz_gpio_chip *chip = jz4740_gpio_chips;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
+		seq_printf(s, "==GPIO %d==\n", i);
+		gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
+		gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
+		gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
+		gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
+		gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
+		gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
+		gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
+		gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
+		gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
+	}
+
+	return 0;
+}
+
+static int gpio_regs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, gpio_regs_show, NULL);
+}
+
+static const struct file_operations gpio_regs_operations = {
+	.open		= gpio_regs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init gpio_debugfs_init(void)
+{
+	(void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
+				NULL, NULL, &gpio_regs_operations);
+	return 0;
+}
+subsys_initcall(gpio_debugfs_init);
+
+#endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d33ff83580f17efb307a46b4169b4ab663e2c32
--- /dev/null
+++ b/arch/mips/jz4740/irq.c
@@ -0,0 +1,167 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform IRQ support
+ *
+ *  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.
+ *
+ *  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/errno.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/irq_cpu.h>
+
+#include <asm/mach-jz4740/base.h>
+
+static void __iomem *jz_intc_base;
+static uint32_t jz_intc_wakeup;
+static uint32_t jz_intc_saved;
+
+#define JZ_REG_INTC_STATUS	0x00
+#define JZ_REG_INTC_MASK	0x04
+#define JZ_REG_INTC_SET_MASK	0x08
+#define JZ_REG_INTC_CLEAR_MASK	0x0c
+#define JZ_REG_INTC_PENDING	0x10
+
+#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
+
+static void intc_irq_unmask(unsigned int irq)
+{
+	writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+	writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
+}
+
+static int intc_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	if (on)
+		jz_intc_wakeup |= IRQ_BIT(irq);
+	else
+		jz_intc_wakeup &= ~IRQ_BIT(irq);
+
+	return 0;
+}
+
+static struct irq_chip intc_irq_type = {
+	.name =		"INTC",
+	.mask =		intc_irq_mask,
+	.mask_ack =	intc_irq_mask,
+	.unmask =	intc_irq_unmask,
+	.set_wake =	intc_irq_set_wake,
+};
+
+static irqreturn_t jz4740_cascade(int irq, void *data)
+{
+	uint32_t irq_reg;
+
+	irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
+
+	if (irq_reg)
+		generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction jz4740_cascade_action = {
+	.handler = jz4740_cascade,
+	.name = "JZ4740 cascade interrupt",
+};
+
+void __init arch_init_irq(void)
+{
+	int i;
+	mips_cpu_irq_init();
+
+	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
+
+	for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
+		intc_irq_mask(i);
+		set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+	}
+
+	setup_irq(2, &jz4740_cascade_action);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+	if (pending & STATUSF_IP2)
+		do_IRQ(2);
+	else if (pending & STATUSF_IP3)
+		do_IRQ(3);
+	else
+		spurious_interrupt();
+}
+
+void jz4740_intc_suspend(void)
+{
+	jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
+	writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
+	writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+}
+
+void jz4740_intc_resume(void)
+{
+	writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+	writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static inline void intc_seq_reg(struct seq_file *s, const char *name,
+	unsigned int reg)
+{
+	seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
+}
+
+static int intc_regs_show(struct seq_file *s, void *unused)
+{
+	intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
+	intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
+	intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
+
+	return 0;
+}
+
+static int intc_regs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, intc_regs_show, NULL);
+}
+
+static const struct file_operations intc_regs_operations = {
+	.open		= intc_regs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init intc_debugfs_init(void)
+{
+	(void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
+				NULL, NULL, &intc_regs_operations);
+	return 0;
+}
+subsys_initcall(intc_debugfs_init);
+
+#endif
diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h
new file mode 100644
index 0000000000000000000000000000000000000000..56b5eadd1fa27d3e00e76370c34324d152dc26b4
--- /dev/null
+++ b/arch/mips/jz4740/irq.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.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
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_IRQ_H__
+#define __MIPS_JZ4740_IRQ_H__
+
+extern void jz4740_intc_suspend(void);
+extern void jz4740_intc_resume(void);
+
+#endif
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
new file mode 100644
index 0000000000000000000000000000000000000000..95bc2b5b14f1b2c56cd141f2c8a2b8ea6370dcde
--- /dev/null
+++ b/arch/mips/jz4740/platform.c
@@ -0,0 +1,291 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform devices
+ *
+ *  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.
+ *
+ *  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/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-jz4740/platform.h>
+#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/irq.h>
+
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include "serial.h"
+#include "clock.h"
+
+/* OHCI controller */
+static struct resource jz4740_usb_ohci_resources[] = {
+	{
+		.start	= JZ4740_UHC_BASE_ADDR,
+		.end	= JZ4740_UHC_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_UHC,
+		.end	= JZ4740_IRQ_UHC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device jz4740_usb_ohci_device = {
+	.name		= "jz4740-ohci",
+	.id		= -1,
+	.dev = {
+		.dma_mask = &jz4740_usb_ohci_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(jz4740_usb_ohci_resources),
+	.resource	= jz4740_usb_ohci_resources,
+};
+
+/* UDC (USB gadget controller) */
+static struct resource jz4740_usb_gdt_resources[] = {
+	{
+		.start	= JZ4740_UDC_BASE_ADDR,
+		.end	= JZ4740_UDC_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_UDC,
+		.end	= JZ4740_IRQ_UDC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device jz4740_udc_device = {
+	.name		= "jz-udc",
+	.id		= -1,
+	.dev = {
+		.dma_mask = &jz4740_udc_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(jz4740_usb_gdt_resources),
+	.resource	= jz4740_usb_gdt_resources,
+};
+
+/* MMC/SD controller */
+static struct resource jz4740_mmc_resources[] = {
+	{
+		.start	= JZ4740_MSC_BASE_ADDR,
+		.end	= JZ4740_MSC_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_MSC,
+		.end	= JZ4740_IRQ_MSC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device jz4740_mmc_device = {
+	.name		= "jz4740-mmc",
+	.id		= 0,
+	.dev = {
+		.dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources  = ARRAY_SIZE(jz4740_mmc_resources),
+	.resource	= jz4740_mmc_resources,
+};
+
+/* RTC controller */
+static struct resource jz4740_rtc_resources[] = {
+	{
+		.start	= JZ4740_RTC_BASE_ADDR,
+		.end	= JZ4740_RTC_BASE_ADDR + 0x38 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start  = JZ4740_IRQ_RTC,
+		.end	= JZ4740_IRQ_RTC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device jz4740_rtc_device = {
+	.name		= "jz4740-rtc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_rtc_resources),
+	.resource	= jz4740_rtc_resources,
+};
+
+/* I2C controller */
+static struct resource jz4740_i2c_resources[] = {
+	{
+		.start	= JZ4740_I2C_BASE_ADDR,
+		.end	= JZ4740_I2C_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_I2C,
+		.end	= JZ4740_IRQ_I2C,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device jz4740_i2c_device = {
+	.name		= "jz4740-i2c",
+	.id		= 0,
+	.num_resources  = ARRAY_SIZE(jz4740_i2c_resources),
+	.resource	= jz4740_i2c_resources,
+};
+
+/* NAND controller */
+static struct resource jz4740_nand_resources[] = {
+	{
+		.name	= "mmio",
+		.start	= JZ4740_EMC_BASE_ADDR,
+		.end	= JZ4740_EMC_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "bank",
+		.start	= 0x18000000,
+		.end	= 0x180C0000 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device jz4740_nand_device = {
+	.name = "jz4740-nand",
+	.num_resources = ARRAY_SIZE(jz4740_nand_resources),
+	.resource = jz4740_nand_resources,
+};
+
+/* LCD controller */
+static struct resource jz4740_framebuffer_resources[] = {
+	{
+		.start	= JZ4740_LCD_BASE_ADDR,
+		.end	= JZ4740_LCD_BASE_ADDR + 0x1000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device jz4740_framebuffer_device = {
+	.name		= "jz4740-fb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_framebuffer_resources),
+	.resource	= jz4740_framebuffer_resources,
+	.dev = {
+		.dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+};
+
+/* I2S controller */
+static struct resource jz4740_i2s_resources[] = {
+	{
+		.start	= JZ4740_AIC_BASE_ADDR,
+		.end	= JZ4740_AIC_BASE_ADDR + 0x38 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device jz4740_i2s_device = {
+	.name		= "jz4740-i2s",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_i2s_resources),
+	.resource	= jz4740_i2s_resources,
+};
+
+/* PCM */
+struct platform_device jz4740_pcm_device = {
+	.name		= "jz4740-pcm",
+	.id		= -1,
+};
+
+/* Codec */
+static struct resource jz4740_codec_resources[] = {
+	{
+		.start	= JZ4740_AIC_BASE_ADDR + 0x80,
+		.end	= JZ4740_AIC_BASE_ADDR + 0x88 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device jz4740_codec_device = {
+	.name		= "jz4740-codec",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_codec_resources),
+	.resource	= jz4740_codec_resources,
+};
+
+/* ADC controller */
+static struct resource jz4740_adc_resources[] = {
+	{
+		.start	= JZ4740_SADC_BASE_ADDR,
+		.end	= JZ4740_SADC_BASE_ADDR + 0x30,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_SADC,
+		.end	= JZ4740_IRQ_SADC,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= JZ4740_IRQ_ADC_BASE,
+		.end	= JZ4740_IRQ_ADC_BASE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device jz4740_adc_device = {
+	.name		= "jz4740-adc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_adc_resources),
+	.resource	= jz4740_adc_resources,
+};
+
+/* Serial */
+#define JZ4740_UART_DATA(_id) \
+	{ \
+		.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
+		.iotype = UPIO_MEM, \
+		.regshift = 2, \
+		.serial_out = jz4740_serial_out, \
+		.type = PORT_16550, \
+		.mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
+		.irq = JZ4740_IRQ_UART ## _id, \
+	}
+
+static struct plat_serial8250_port jz4740_uart_data[] = {
+	JZ4740_UART_DATA(0),
+	JZ4740_UART_DATA(1),
+	{},
+};
+
+static struct platform_device jz4740_uart_device = {
+	.name = "serial8250",
+	.id = 0,
+	.dev = {
+		.platform_data = jz4740_uart_data,
+	},
+};
+
+void jz4740_serial_device_register(void)
+{
+	struct plat_serial8250_port *p;
+
+	for (p = jz4740_uart_data; p->flags != 0; ++p)
+		p->uartclk = jz4740_clock_bdata.ext_rate;
+
+	platform_device_register(&jz4740_uart_device);
+}
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9994585424d531afffd1ab9c0ee5c45c201d975
--- /dev/null
+++ b/arch/mips/jz4740/pm.c
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *	JZ4740 SoC power management support
+ *
+ *  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.
+ *
+ *  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/init.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+
+#include <asm/mach-jz4740/clock.h>
+
+#include "clock.h"
+#include "irq.h"
+
+static int jz4740_pm_enter(suspend_state_t state)
+{
+	jz4740_intc_suspend();
+	jz4740_clock_suspend();
+
+	jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
+
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+
+	jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
+
+	jz4740_clock_resume();
+	jz4740_intc_resume();
+
+	return 0;
+}
+
+static struct platform_suspend_ops jz4740_pm_ops = {
+	.valid		= suspend_valid_only_mem,
+	.enter		= jz4740_pm_enter,
+};
+
+static int __init jz4740_pm_init(void)
+{
+	suspend_set_ops(&jz4740_pm_ops);
+	return 0;
+
+}
+late_initcall(jz4740_pm_init);
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
new file mode 100644
index 0000000000000000000000000000000000000000..cfeac15eb2e4d5716530fd07c5b6db3a8d77cadb
--- /dev/null
+++ b/arch/mips/jz4740/prom.c
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC prom code
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-jz4740/base.h>
+
+void jz4740_init_cmdline(int argc, char *argv[])
+{
+	unsigned int count = COMMAND_LINE_SIZE - 1;
+	int i;
+	char *dst = &(arcs_cmdline[0]);
+	char *src;
+
+	for (i = 1; i < argc && count; ++i) {
+		src = argv[i];
+		while (*src && count) {
+			*dst++ = *src++;
+			--count;
+		}
+		*dst++ = ' ';
+	}
+	if (i > 1)
+		--dst;
+
+	*dst = 0;
+}
+
+void __init prom_init(void)
+{
+	jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
+	mips_machtype = MACH_INGENIC_JZ4740;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2)))
+
+void prom_putchar(char c)
+{
+	uint8_t lsr;
+
+	do {
+		lsr = readb(UART_REG(UART_LSR));
+	} while ((lsr & UART_LSR_TEMT) == 0);
+
+	writeb(c, UART_REG(UART_TX));
+}
diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
new file mode 100644
index 0000000000000000000000000000000000000000..a26a6faec9a6229f9d02b8c97a0ee825b31bb6bf
--- /dev/null
+++ b/arch/mips/jz4740/pwm.c
@@ -0,0 +1,177 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform PWM support
+ *
+ *  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.
+ *
+ *  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/clk.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-jz4740/gpio.h>
+#include "timer.h"
+
+static struct clk *jz4740_pwm_clk;
+
+DEFINE_MUTEX(jz4740_pwm_mutex);
+
+struct pwm_device {
+	unsigned int id;
+	unsigned int gpio;
+	bool used;
+};
+
+static struct pwm_device jz4740_pwm_list[] = {
+	{ 2, JZ_GPIO_PWM2, false },
+	{ 3, JZ_GPIO_PWM3, false },
+	{ 4, JZ_GPIO_PWM4, false },
+	{ 5, JZ_GPIO_PWM5, false },
+	{ 6, JZ_GPIO_PWM6, false },
+	{ 7, JZ_GPIO_PWM7, false },
+};
+
+struct pwm_device *pwm_request(int id, const char *label)
+{
+	int ret = 0;
+	struct pwm_device *pwm;
+
+	if (id < 2 || id > 7 || !jz4740_pwm_clk)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&jz4740_pwm_mutex);
+
+	pwm = &jz4740_pwm_list[id - 2];
+	if (pwm->used)
+		ret = -EBUSY;
+	else
+		pwm->used = true;
+
+	mutex_unlock(&jz4740_pwm_mutex);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = gpio_request(pwm->gpio, label);
+
+	if (ret) {
+		printk(KERN_ERR "Failed to request pwm gpio: %d\n", ret);
+		pwm->used = false;
+		return ERR_PTR(ret);
+	}
+
+	jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
+
+	jz4740_timer_start(id);
+
+	return pwm;
+}
+
+void pwm_free(struct pwm_device *pwm)
+{
+	pwm_disable(pwm);
+	jz4740_timer_set_ctrl(pwm->id, 0);
+
+	jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
+	gpio_free(pwm->gpio);
+
+	jz4740_timer_stop(pwm->id);
+
+	pwm->used = false;
+}
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	unsigned long long tmp;
+	unsigned long period, duty;
+	unsigned int prescaler = 0;
+	unsigned int id = pwm->id;
+	uint16_t ctrl;
+	bool is_enabled;
+
+	if (duty_ns < 0 || duty_ns > period_ns)
+		return -EINVAL;
+
+	tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
+	do_div(tmp, 1000000000);
+	period = tmp;
+
+	while (period > 0xffff && prescaler < 6) {
+		period >>= 2;
+		++prescaler;
+	}
+
+	if (prescaler == 6)
+		return -EINVAL;
+
+	tmp = (unsigned long long)period * duty_ns;
+	do_div(tmp, period_ns);
+	duty = period - tmp;
+
+	if (duty >= period)
+		duty = period - 1;
+
+	is_enabled = jz4740_timer_is_enabled(id);
+	if (is_enabled)
+		pwm_disable(pwm);
+
+	jz4740_timer_set_count(id, 0);
+	jz4740_timer_set_duty(id, duty);
+	jz4740_timer_set_period(id, period);
+
+	ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
+		JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
+
+	jz4740_timer_set_ctrl(id, ctrl);
+
+	if (is_enabled)
+		pwm_enable(pwm);
+
+	return 0;
+}
+
+int pwm_enable(struct pwm_device *pwm)
+{
+	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
+
+	ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
+	jz4740_timer_set_ctrl(pwm->id, ctrl);
+	jz4740_timer_enable(pwm->id);
+
+	return 0;
+}
+
+void pwm_disable(struct pwm_device *pwm)
+{
+	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
+
+	ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
+	jz4740_timer_disable(pwm->id);
+	jz4740_timer_set_ctrl(pwm->id, ctrl);
+}
+
+static int __init jz4740_pwm_init(void)
+{
+	int ret = 0;
+
+	jz4740_pwm_clk = clk_get(NULL, "ext");
+
+	if (IS_ERR(jz4740_pwm_clk)) {
+		ret = PTR_ERR(jz4740_pwm_clk);
+		jz4740_pwm_clk = NULL;
+	}
+
+	return ret;
+}
+subsys_initcall(jz4740_pwm_init);
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f1fb95c0d0daf980bc20194be8bb4c6f35f002d
--- /dev/null
+++ b/arch/mips/jz4740/reset.c
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.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
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  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/io.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/timer.h>
+
+static void jz4740_halt(void)
+{
+	while (1) {
+		__asm__(".set push;\n"
+			".set mips3;\n"
+			"wait;\n"
+			".set pop;\n"
+		);
+	}
+}
+
+#define JZ_REG_WDT_DATA 0x00
+#define JZ_REG_WDT_COUNTER_ENABLE 0x04
+#define JZ_REG_WDT_COUNTER 0x08
+#define JZ_REG_WDT_CTRL 0x0c
+
+static void jz4740_restart(char *command)
+{
+	void __iomem *wdt_base = ioremap(JZ4740_WDT_BASE_ADDR, 0x0f);
+
+	jz4740_timer_enable_watchdog();
+
+	writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
+
+	writew(0, wdt_base + JZ_REG_WDT_COUNTER);
+	writew(0, wdt_base + JZ_REG_WDT_DATA);
+	writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL);
+
+	writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
+	jz4740_halt();
+}
+
+#define JZ_REG_RTC_CTRL		0x00
+#define JZ_REG_RTC_HIBERNATE	0x20
+
+#define JZ_RTC_CTRL_WRDY	BIT(7)
+
+static void jz4740_power_off(void)
+{
+	void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24);
+	uint32_t ctrl;
+
+	do {
+		ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
+	} while (!(ctrl & JZ_RTC_CTRL_WRDY));
+
+	writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
+	jz4740_halt();
+}
+
+void jz4740_reset_init(void)
+{
+	_machine_restart = jz4740_restart;
+	_machine_halt = jz4740_halt;
+	pm_power_off = jz4740_power_off;
+}
diff --git a/arch/mips/jz4740/reset.h b/arch/mips/jz4740/reset.h
new file mode 100644
index 0000000000000000000000000000000000000000..5202ab4ad9db8c2b8d29bc301a370b2ce97de7cb
--- /dev/null
+++ b/arch/mips/jz4740/reset.h
@@ -0,0 +1,6 @@
+#ifndef __MIPS_JZ4740_RESET_H__
+#define __MIPS_JZ4740_RESET_H__
+
+extern void jz4740_reset_init(void);
+
+#endif
diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..d23de45826d1c80b7eb3999a4774dba30c7ad69c
--- /dev/null
+++ b/arch/mips/jz4740/serial.c
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 serial support
+ *
+ *  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.
+ *
+ *  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/io.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+void jz4740_serial_out(struct uart_port *p, int offset, int value)
+{
+	switch (offset) {
+	case UART_FCR:
+		value |= 0x10; /* Enable uart module */
+		break;
+	case UART_IER:
+		value |= (value & 0x4) << 2;
+		break;
+	default:
+		break;
+	}
+	writeb(value, p->membase + (offset << p->regshift));
+}
diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9fe3ade028987f67a97b29e1192ef8768d72c17
--- /dev/null
+++ b/arch/mips/jz4740/serial.h
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 serial support
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_SERIAL_H__
+
+void jz4740_serial_out(struct uart_port *p, int offset, int value);
+
+#endif
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a9e14dab91eb88d68f7b25dc6565af47449e40e
--- /dev/null
+++ b/arch/mips/jz4740/setup.c
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 setup code
+ *
+ *  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.
+ *
+ *  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/init.h>
+#include <linux/kernel.h>
+
+#include "reset.h"
+
+void __init plat_mem_setup(void)
+{
+	jz4740_reset_init();
+}
+
+const char *get_system_type(void)
+{
+	return "JZ4740";
+}
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe01678d94fd4c439cd2353e3b74f57da6efebaf
--- /dev/null
+++ b/arch/mips/jz4740/time.c
@@ -0,0 +1,144 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform time support
+ *
+ *  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.
+ *
+ *  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/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+
+#include <linux/clockchips.h>
+
+#include <asm/mach-jz4740/irq.h>
+#include <asm/time.h>
+
+#include "clock.h"
+#include "timer.h"
+
+#define TIMER_CLOCKEVENT 0
+#define TIMER_CLOCKSOURCE 1
+
+static uint16_t jz4740_jiffies_per_tick;
+
+static cycle_t jz4740_clocksource_read(struct clocksource *cs)
+{
+	return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
+}
+
+static struct clocksource jz4740_clocksource = {
+	.name = "jz4740-timer",
+	.rating = 200,
+	.read = jz4740_clocksource_read,
+	.mask = CLOCKSOURCE_MASK(16),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
+{
+	struct clock_event_device *cd = devid;
+
+	jz4740_timer_ack_full(TIMER_CLOCKEVENT);
+
+	if (cd->mode != CLOCK_EVT_MODE_PERIODIC)
+		jz4740_timer_disable(TIMER_CLOCKEVENT);
+
+	cd->event_handler(cd);
+
+	return IRQ_HANDLED;
+}
+
+static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *cd)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
+		jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
+	case CLOCK_EVT_MODE_RESUME:
+		jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
+		jz4740_timer_enable(TIMER_CLOCKEVENT);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		jz4740_timer_disable(TIMER_CLOCKEVENT);
+		break;
+	default:
+		break;
+	}
+}
+
+static int jz4740_clockevent_set_next(unsigned long evt,
+	struct clock_event_device *cd)
+{
+	jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
+	jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
+	jz4740_timer_enable(TIMER_CLOCKEVENT);
+
+	return 0;
+}
+
+static struct clock_event_device jz4740_clockevent = {
+	.name = "jz4740-timer",
+	.features = CLOCK_EVT_FEAT_PERIODIC,
+	.set_next_event = jz4740_clockevent_set_next,
+	.set_mode = jz4740_clockevent_set_mode,
+	.rating = 200,
+	.irq = JZ4740_IRQ_TCU0,
+};
+
+static struct irqaction timer_irqaction = {
+	.handler	= jz4740_clockevent_irq,
+	.flags		= IRQF_PERCPU | IRQF_TIMER,
+	.name		= "jz4740-timerirq",
+	.dev_id		= &jz4740_clockevent,
+};
+
+void __init plat_time_init(void)
+{
+	int ret;
+	uint32_t clk_rate;
+	uint16_t ctrl;
+
+	jz4740_timer_init();
+
+	clk_rate = jz4740_clock_bdata.ext_rate >> 4;
+	jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
+
+	clockevent_set_clock(&jz4740_clockevent, clk_rate);
+	jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
+	jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
+	jz4740_clockevent.cpumask = cpumask_of(0);
+
+	clockevents_register_device(&jz4740_clockevent);
+
+	clocksource_set_clock(&jz4740_clocksource, clk_rate);
+	ret = clocksource_register(&jz4740_clocksource);
+
+	if (ret)
+		printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
+
+	setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
+
+	ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
+
+	jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
+	jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
+
+	jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
+	jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
+
+	jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
+
+	jz4740_timer_enable(TIMER_CLOCKEVENT);
+	jz4740_timer_enable(TIMER_CLOCKSOURCE);
+}
diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
new file mode 100644
index 0000000000000000000000000000000000000000..b2c01512905587fb775869396aeb5719b14a94a9
--- /dev/null
+++ b/arch/mips/jz4740/timer.c
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform timer support
+ *
+ *  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.
+ *
+ *  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/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "timer.h"
+
+#include <asm/mach-jz4740/base.h>
+
+void __iomem *jz4740_timer_base;
+
+void jz4740_timer_enable_watchdog(void)
+{
+	writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+
+void jz4740_timer_disable_watchdog(void)
+{
+	writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+
+void __init jz4740_timer_init(void)
+{
+	jz4740_timer_base = ioremap(JZ4740_TCU_BASE_ADDR, 0x100);
+
+	if (!jz4740_timer_base)
+		panic("Failed to ioremap timer registers");
+
+	/* Disable all timer clocks except for those used as system timers */
+	writel(0x000100fc, jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+
+	/* Timer irqs are unmasked by default, mask them */
+	writel(0x00ff00ff, jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..fca3994f2e6d3d3fca6342bd3801ba862da0470c
--- /dev/null
+++ b/arch/mips/jz4740/timer.h
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform timer support
+ *
+ *  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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_TIMER_H__
+#define __MIPS_JZ4740_TIMER_H__
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#define JZ_REG_TIMER_STOP		0x0C
+#define JZ_REG_TIMER_STOP_SET		0x1C
+#define JZ_REG_TIMER_STOP_CLEAR		0x2C
+#define JZ_REG_TIMER_ENABLE		0x00
+#define JZ_REG_TIMER_ENABLE_SET		0x04
+#define JZ_REG_TIMER_ENABLE_CLEAR	0x08
+#define JZ_REG_TIMER_FLAG		0x10
+#define JZ_REG_TIMER_FLAG_SET		0x14
+#define JZ_REG_TIMER_FLAG_CLEAR		0x18
+#define JZ_REG_TIMER_MASK		0x20
+#define JZ_REG_TIMER_MASK_SET		0x24
+#define JZ_REG_TIMER_MASK_CLEAR		0x28
+
+#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
+#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
+#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
+#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
+
+#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
+#define JZ_TIMER_IRQ_FULL(x) BIT(x)
+
+#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN	BIT(9)
+#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW		BIT(8)
+#define JZ_TIMER_CTRL_PWM_ENABLE		BIT(7)
+#define JZ_TIMER_CTRL_PRESCALE_MASK		0x1c
+#define JZ_TIMER_CTRL_PRESCALE_OFFSET		0x3
+#define JZ_TIMER_CTRL_PRESCALE_1		(0 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_4		(1 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_16		(2 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_64		(3 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_256		(4 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_1024		(5 << 3)
+
+#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
+
+#define JZ_TIMER_CTRL_SRC_EXT		BIT(2)
+#define JZ_TIMER_CTRL_SRC_RTC		BIT(1)
+#define JZ_TIMER_CTRL_SRC_PCLK		BIT(0)
+
+extern void __iomem *jz4740_timer_base;
+void __init jz4740_timer_init(void);
+
+static inline void jz4740_timer_stop(unsigned int timer)
+{
+	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+
+static inline void jz4740_timer_start(unsigned int timer)
+{
+	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+
+static inline bool jz4740_timer_is_enabled(unsigned int timer)
+{
+	return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
+}
+
+static inline void jz4740_timer_enable(unsigned int timer)
+{
+	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
+}
+
+static inline void jz4740_timer_disable(unsigned int timer)
+{
+	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
+}
+
+
+static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
+{
+	writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
+}
+
+static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
+{
+	writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
+}
+
+static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
+{
+	writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline uint16_t jz4740_timer_get_count(unsigned int timer)
+{
+	return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline void jz4740_timer_ack_full(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_enable(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_disable(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
+
+static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
+{
+	writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
+{
+	return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+#endif
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 7a6ac501cbb5abc07cb4f78f43c2e806200ce023..06f848299785c1785fc914da5b57a189c517b103 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_IRQ_TXX9)		+= irq_txx9.o
 obj-$(CONFIG_IRQ_GT641XX)	+= irq-gt641xx.o
 obj-$(CONFIG_IRQ_GIC)		+= irq-gic.o
 
+obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_32BIT)		+= scall32-o32.o
 obj-$(CONFIG_64BIT)		+= scall64-64.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o ptrace32.o signal32.o
@@ -101,6 +102,4 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
 
 obj-$(CONFIG_MIPS_CPUFREQ)	+= cpufreq/
 
-EXTRA_CFLAGS += -Werror
-
 CPPFLAGS_vmlinux.lds		:= $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ca6c83218caa8df0c49f283593a2c2974315af2e..6b30fb2caa67170b01f3d12d1fa67e7dd0696d6c 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -126,7 +126,6 @@ void output_thread_defines(void)
 	       thread.cp0_baduaddr);
 	OFFSET(THREAD_ECODE, task_struct, \
 	       thread.error_code);
-	OFFSET(THREAD_TRAPNO, task_struct, thread.trap_no);
 	OFFSET(THREAD_TRAMP, task_struct, \
 	       thread.irix_trampoline);
 	OFFSET(THREAD_OLDCTX, task_struct, \
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 0b2450ceb13f1c6aaf0cef071216158b06c3de62..2a4d50ff5e2c17e8ad56e86593e48b70f29ee4df 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -163,7 +163,6 @@ int c0_compare_int_usable(void)
 
 int __cpuinit r4k_clockevent_init(void)
 {
-	uint64_t mips_freq = mips_hpt_frequency;
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd;
 	unsigned int irq;
@@ -188,9 +187,9 @@ int __cpuinit r4k_clockevent_init(void)
 	cd->name		= "MIPS";
 	cd->features		= CLOCK_EVT_FEAT_ONESHOT;
 
+	clockevent_set_clock(cd, mips_hpt_frequency);
+
 	/* Calculate the min / max delta */
-	cd->mult	= div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-	cd->shift		= 32;
 	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd);
 	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd);
 
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index 408d0a07b3a37d2bac6eef16cb669d738da3ff65..b8bb8ba608696a0483a64e5b4fb14a7d82f27261 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -239,7 +239,7 @@ static inline void check_daddi(void)
 	panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
 }
 
-int daddiu_bug __cpuinitdata = -1;
+int daddiu_bug  = -1;
 
 static inline void check_daddiu(void)
 {
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 3562b854f2cd4e0e61086073e11534d39479484f..b1b304ea21288414415ec02f9005ee6e5eec9b2e 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -187,6 +187,7 @@ void __init check_wait(void)
 	case CPU_BCM6358:
 	case CPU_CAVIUM_OCTEON:
 	case CPU_CAVIUM_OCTEON_PLUS:
+	case CPU_JZRISC:
 		cpu_wait = r4k_wait;
 		break;
 
@@ -760,6 +761,9 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
 		ok = decode_config4(c);
 
 	mips_probe_watch_registers(c);
+
+	if (cpu_has_mips_r2)
+		c->core = read_c0_ebase() & 0x3ff;
 }
 
 static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
@@ -956,6 +960,22 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
 	}
 }
 
+static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
+{
+	decode_configs(c);
+	/* JZRISC does not implement the CP0 counter. */
+	c->options &= ~MIPS_CPU_COUNTER;
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_JZRISC:
+		c->cputype = CPU_JZRISC;
+		__cpu_name[cpu] = "Ingenic JZRISC";
+		break;
+	default:
+		panic("Unknown Ingenic Processor ID!");
+		break;
+	}
+}
+
 const char *__cpu_name[NR_CPUS];
 const char *__elf_platform;
 
@@ -994,6 +1014,9 @@ __cpuinit void cpu_probe(void)
 	case PRID_COMP_CAVIUM:
 		cpu_probe_cavium(c, cpu);
 		break;
+	case PRID_COMP_INGENIC:
+		cpu_probe_ingenic(c, cpu);
+		break;
 	}
 
 	BUG_ON(!__cpu_name[cpu]);
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee28683fc2acbb7168d437702f2f0fdf453a4a3d
--- /dev/null
+++ b/arch/mips/kernel/kprobes.c
@@ -0,0 +1,557 @@
+/*
+ *  Kernel Probes (KProbes)
+ *  arch/mips/kernel/kprobes.c
+ *
+ *  Copyright 2006 Sony Corp.
+ *  Copyright 2010 Cavium Networks
+ *
+ *  Some portions copied from the powerpc version.
+ *
+ *   Copyright (C) IBM Corporation, 2002, 2004
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kprobes.h>
+#include <linux/preempt.h>
+#include <linux/kdebug.h>
+#include <linux/slab.h>
+
+#include <asm/ptrace.h>
+#include <asm/break.h>
+#include <asm/inst.h>
+
+static const union mips_instruction breakpoint_insn = {
+	.b_format = {
+		.opcode = spec_op,
+		.code = BRK_KPROBE_BP,
+		.func = break_op
+	}
+};
+
+static const union mips_instruction breakpoint2_insn = {
+	.b_format = {
+		.opcode = spec_op,
+		.code = BRK_KPROBE_SSTEPBP,
+		.func = break_op
+	}
+};
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe);
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+static int __kprobes insn_has_delayslot(union mips_instruction insn)
+{
+	switch (insn.i_format.opcode) {
+
+		/*
+		 * This group contains:
+		 * jr and jalr are in r_format format.
+		 */
+	case spec_op:
+		switch (insn.r_format.func) {
+		case jr_op:
+		case jalr_op:
+			break;
+		default:
+			goto insn_ok;
+		}
+
+		/*
+		 * This group contains:
+		 * bltz_op, bgez_op, bltzl_op, bgezl_op,
+		 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+		 */
+	case bcond_op:
+
+		/*
+		 * These are unconditional and in j_format.
+		 */
+	case jal_op:
+	case j_op:
+
+		/*
+		 * These are conditional and in i_format.
+		 */
+	case beq_op:
+	case beql_op:
+	case bne_op:
+	case bnel_op:
+	case blez_op:
+	case blezl_op:
+	case bgtz_op:
+	case bgtzl_op:
+
+		/*
+		 * These are the FPA/cp1 branch instructions.
+		 */
+	case cop1_op:
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+	case lwc2_op: /* This is bbit0 on Octeon */
+	case ldc2_op: /* This is bbit032 on Octeon */
+	case swc2_op: /* This is bbit1 on Octeon */
+	case sdc2_op: /* This is bbit132 on Octeon */
+#endif
+		return 1;
+	default:
+		break;
+	}
+insn_ok:
+	return 0;
+}
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+	union mips_instruction insn;
+	union mips_instruction prev_insn;
+	int ret = 0;
+
+	prev_insn = p->addr[-1];
+	insn = p->addr[0];
+
+	if (insn_has_delayslot(insn) || insn_has_delayslot(prev_insn)) {
+		pr_notice("Kprobes for branch and jump instructions are not supported\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* insn: must be on special executable page on mips. */
+	p->ainsn.insn = get_insn_slot();
+	if (!p->ainsn.insn) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * In the kprobe->ainsn.insn[] array we store the original
+	 * instruction at index zero and a break trap instruction at
+	 * index one.
+	 */
+
+	memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
+	p->ainsn.insn[1] = breakpoint2_insn;
+	p->opcode = *p->addr;
+
+out:
+	return ret;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+	*p->addr = breakpoint_insn;
+	flush_insn_slot(p);
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+	*p->addr = p->opcode;
+	flush_insn_slot(p);
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+	free_insn_slot(p->ainsn.insn, 0);
+}
+
+static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.old_SR = kcb->kprobe_old_SR;
+	kcb->prev_kprobe.saved_SR = kcb->kprobe_saved_SR;
+	kcb->prev_kprobe.saved_epc = kcb->kprobe_saved_epc;
+}
+
+static void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_old_SR = kcb->prev_kprobe.old_SR;
+	kcb->kprobe_saved_SR = kcb->prev_kprobe.saved_SR;
+	kcb->kprobe_saved_epc = kcb->prev_kprobe.saved_epc;
+}
+
+static void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+			       struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_saved_SR = kcb->kprobe_old_SR = (regs->cp0_status & ST0_IE);
+	kcb->kprobe_saved_epc = regs->cp0_epc;
+}
+
+static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+	regs->cp0_status &= ~ST0_IE;
+
+	/* single step inline if the instruction is a break */
+	if (p->opcode.word == breakpoint_insn.word ||
+	    p->opcode.word == breakpoint2_insn.word)
+		regs->cp0_epc = (unsigned long)p->addr;
+	else
+		regs->cp0_epc = (unsigned long)&p->ainsn.insn[0];
+}
+
+static int __kprobes kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *p;
+	int ret = 0;
+	kprobe_opcode_t *addr;
+	struct kprobe_ctlblk *kcb;
+
+	addr = (kprobe_opcode_t *) regs->cp0_epc;
+
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
+	preempt_disable();
+	kcb = get_kprobe_ctlblk();
+
+	/* Check we're not actually recursing */
+	if (kprobe_running()) {
+		p = get_kprobe(addr);
+		if (p) {
+			if (kcb->kprobe_status == KPROBE_HIT_SS &&
+			    p->ainsn.insn->word == breakpoint_insn.word) {
+				regs->cp0_status &= ~ST0_IE;
+				regs->cp0_status |= kcb->kprobe_saved_SR;
+				goto no_kprobe;
+			}
+			/*
+			 * We have reentered the kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, regs, kcb);
+			kprobes_inc_nmissed_count(p);
+			prepare_singlestep(p, regs);
+			kcb->kprobe_status = KPROBE_REENTER;
+			return 1;
+		} else {
+			if (addr->word != breakpoint_insn.word) {
+				/*
+				 * The breakpoint instruction was removed by
+				 * another cpu right after we hit, no further
+				 * handling of this interrupt is appropriate
+				 */
+				ret = 1;
+				goto no_kprobe;
+			}
+			p = __get_cpu_var(current_kprobe);
+			if (p->break_handler && p->break_handler(p, regs))
+				goto ss_probe;
+		}
+		goto no_kprobe;
+	}
+
+	p = get_kprobe(addr);
+	if (!p) {
+		if (addr->word != breakpoint_insn.word) {
+			/*
+			 * The breakpoint instruction was removed right
+			 * after we hit it.  Another cpu has removed
+			 * either a probepoint or a debugger breakpoint
+			 * at this address.  In either case, no further
+			 * handling of this interrupt is appropriate.
+			 */
+			ret = 1;
+		}
+		/* Not one of ours: let kernel handle it */
+		goto no_kprobe;
+	}
+
+	set_current_kprobe(p, regs, kcb);
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+	if (p->pre_handler && p->pre_handler(p, regs)) {
+		/* handler has already set things up, so skip ss setup */
+		return 1;
+	}
+
+ss_probe:
+	prepare_singlestep(p, regs);
+	kcb->kprobe_status = KPROBE_HIT_SS;
+	return 1;
+
+no_kprobe:
+	preempt_enable_no_resched();
+	return ret;
+
+}
+
+/*
+ * Called after single-stepping.  p->addr is the address of the
+ * instruction whose first byte has been replaced by the "break 0"
+ * instruction.  To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction.  The address of this
+ * copy is p->ainsn.insn.
+ *
+ * This function prepares to return from the post-single-step
+ * breakpoint trap.
+ */
+static void __kprobes resume_execution(struct kprobe *p,
+				       struct pt_regs *regs,
+				       struct kprobe_ctlblk *kcb)
+{
+	unsigned long orig_epc = kcb->kprobe_saved_epc;
+	regs->cp0_epc = orig_epc + 4;
+}
+
+static inline int post_kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
+		return 0;
+
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
+	}
+
+	resume_execution(cur, regs, kcb);
+
+	regs->cp0_status |= kcb->kprobe_saved_SR;
+
+	/* Restore back the original saved kprobes variables and continue. */
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
+		goto out;
+	}
+	reset_current_kprobe();
+out:
+	preempt_enable_no_resched();
+
+	return 1;
+}
+
+static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+		return 1;
+
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs, kcb);
+		regs->cp0_status |= kcb->kprobe_old_SR;
+
+		reset_current_kprobe();
+		preempt_enable_no_resched();
+	}
+	return 0;
+}
+
+/*
+ * Wrapper routine for handling exceptions.
+ */
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
+{
+
+	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
+	switch (val) {
+	case DIE_BREAK:
+		if (kprobe_handler(args->regs))
+			ret = NOTIFY_STOP;
+		break;
+	case DIE_SSTEPBP:
+		if (post_kprobe_handler(args->regs))
+			ret = NOTIFY_STOP;
+		break;
+
+	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
+
+		if (kprobe_running()
+		    && kprobe_fault_handler(args->regs, args->trapnr))
+			ret = NOTIFY_STOP;
+		preempt_enable();
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	kcb->jprobe_saved_regs = *regs;
+	kcb->jprobe_saved_sp = regs->regs[29];
+
+	memcpy(kcb->jprobes_stack, (void *)kcb->jprobe_saved_sp,
+	       MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
+
+	regs->cp0_epc = (unsigned long)(jp->entry);
+
+	return 1;
+}
+
+/* Defined in the inline asm below. */
+void jprobe_return_end(void);
+
+void __kprobes jprobe_return(void)
+{
+	/* Assembler quirk necessitates this '0,code' business.  */
+	asm volatile(
+		"break 0,%0\n\t"
+		".globl jprobe_return_end\n"
+		"jprobe_return_end:\n"
+		: : "n" (BRK_KPROBE_BP) : "memory");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (regs->cp0_epc >= (unsigned long)jprobe_return &&
+	    regs->cp0_epc <= (unsigned long)jprobe_return_end) {
+		*regs = kcb->jprobe_saved_regs;
+		memcpy((void *)kcb->jprobe_saved_sp, kcb->jprobes_stack,
+		       MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
+		preempt_enable_no_resched();
+
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Function return probe trampoline:
+ *	- init_kprobes() establishes a probepoint here
+ *	- When the probed function returns, this probe causes the
+ *	  handlers to fire
+ */
+static void __used kretprobe_trampoline_holder(void)
+{
+	asm volatile(
+		".set push\n\t"
+		/* Keep the assembler from reordering and placing JR here. */
+		".set noreorder\n\t"
+		"nop\n\t"
+		".global kretprobe_trampoline\n"
+		"kretprobe_trampoline:\n\t"
+		"nop\n\t"
+		".set pop"
+		: : : "memory");
+}
+
+void kretprobe_trampoline(void);
+
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+				      struct pt_regs *regs)
+{
+	ri->ret_addr = (kprobe_opcode_t *) regs->regs[31];
+
+	/* Replace the return addr with trampoline addr */
+	regs->regs[31] = (unsigned long)kretprobe_trampoline;
+}
+
+/*
+ * Called when the probe at kretprobe trampoline is hit
+ */
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+						struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *node, *tmp;
+	unsigned long flags, orig_ret_address = 0;
+	unsigned long trampoline_address = (unsigned long)kretprobe_trampoline;
+
+	INIT_HLIST_HEAD(&empty_rp);
+	kretprobe_hash_lock(current, &head, &flags);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more than one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+	 *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+		if (ri->task != current)
+			/* another task is sharing our hash bucket */
+			continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri, &empty_rp);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	kretprobe_assert(ri, orig_ret_address, trampoline_address);
+	instruction_pointer(regs) = orig_ret_address;
+
+	reset_current_kprobe();
+	kretprobe_hash_unlock(current, &flags);
+	preempt_enable_no_resched();
+
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+	/*
+	 * By returning a non-zero value, we are telling
+	 * kprobe_handler() that we don't want the post_handler
+	 * to run (and have re-enabled preemption)
+	 */
+	return 1;
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+	if (p->addr == (kprobe_opcode_t *)kretprobe_trampoline)
+		return 1;
+
+	return 0;
+}
+
+static struct kprobe trampoline_p = {
+	.addr = (kprobe_opcode_t *)kretprobe_trampoline,
+	.pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+	return register_kprobe(&trampoline_p);
+}
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
index 6bfcb7a00ec68bb0cc53d1250aed40451787522c..4c968e7efb747d997ec20ba8ceeb500f4c12807d 100644
--- a/arch/mips/kernel/mcount.S
+++ b/arch/mips/kernel/mcount.S
@@ -165,12 +165,12 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra)
 
 	/* arg3: Get frame pointer of current stack */
 #ifdef CONFIG_FRAME_POINTER
-	 move	a2, fp
+	move	a2, fp
 #else /* ! CONFIG_FRAME_POINTER */
 #ifdef CONFIG_64BIT
-	 PTR_LA	a2, PT_SIZE(sp)
+	PTR_LA	a2, PT_SIZE(sp)
 #else
-	 PTR_LA	a2, (PT_SIZE+8)(sp)
+	PTR_LA	a2, (PT_SIZE+8)(sp)
 #endif
 #endif
 
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index a4faceea9d885043a0628afcf649d6b957c9b7a3..a3d66137731ac24386972c82426a4679d9ff9be3 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -400,22 +400,22 @@ EXPORT(sysn32_call_table)
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_get
 	PTR	compat_sys_utimensat
-	PTR	compat_sys_signalfd		/* 5280 */
+	PTR	compat_sys_signalfd		/* 6280 */
 	PTR	sys_ni_syscall
 	PTR	sys_eventfd
 	PTR	sys_fallocate
 	PTR	sys_timerfd_create
-	PTR	compat_sys_timerfd_gettime	/* 5285 */
+	PTR	compat_sys_timerfd_gettime	/* 6285 */
 	PTR	compat_sys_timerfd_settime
 	PTR	sys_signalfd4
 	PTR	sys_eventfd2
 	PTR	sys_epoll_create1
-	PTR	sys_dup3			/* 5290 */
+	PTR	sys_dup3			/* 6290 */
 	PTR	sys_pipe2
 	PTR	sys_inotify_init1
 	PTR	sys_preadv
 	PTR	sys_pwritev
-	PTR	compat_sys_rt_tgsigqueueinfo	/* 5295 */
+	PTR	compat_sys_rt_tgsigqueueinfo	/* 6295 */
 	PTR	sys_perf_event_open
 	PTR	sys_accept4
 	PTR     compat_sys_recvmmsg
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 6cdca1956b77c0f829cf507b57d19916b74cfad9..383aeb95cb49ee2a8e27f489826c66b6d0f6663f 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -47,8 +47,12 @@
 #endif /* CONFIG_MIPS_MT_SMTC */
 
 volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
+
 int __cpu_number_map[NR_CPUS];		/* Map physical to logical */
+EXPORT_SYMBOL(__cpu_number_map);
+
 int __cpu_logical_map[NR_CPUS];		/* Map logical to physical */
+EXPORT_SYMBOL(__cpu_logical_map);
 
 /* Number of TCs (or siblings in Intel speak) per CPU core */
 int smp_num_siblings = 1;
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index a95dea5459c4d5034514ae68a8134d3bb2eb578d..cfeb2c1558967a540df6be261478df57c73a440f 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -975,8 +975,7 @@ void ipi_decode(struct smtc_ipi *pipi)
 			ipi_call_interrupt();
 			break;
 		default:
-			printk("Impossible SMTC IPI Argument 0x%x\n",
-				(int)arg_copy);
+			printk("Impossible SMTC IPI Argument %p\n", arg_copy);
 			break;
 		}
 		break;
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index dd81b0f875183d887e97996ee14f961f79055118..58bab2ef257fae911623b6296879db2d9d427578 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -29,6 +29,8 @@
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/elf.h>
 
 #include <asm/asm.h>
 #include <asm/branch.h>
@@ -116,7 +118,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		    (!vmm || addr + len <= vmm->vm_start))
 			return addr;
 	}
-	addr = TASK_UNMAPPED_BASE;
+	addr = current->mm->mmap_base;
 	if (do_color_align)
 		addr = COLOUR_ALIGN(addr, pgoff);
 	else
@@ -134,6 +136,51 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	}
 }
 
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	unsigned long random_factor = 0UL;
+
+	if (current->flags & PF_RANDOMIZE) {
+		random_factor = get_random_int();
+		random_factor = random_factor << PAGE_SHIFT;
+		if (TASK_IS_32BIT_ADDR)
+			random_factor &= 0xfffffful;
+		else
+			random_factor &= 0xffffffful;
+	}
+
+	mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+	mm->get_unmapped_area = arch_get_unmapped_area;
+	mm->unmap_area = arch_unmap_area;
+}
+
+static inline unsigned long brk_rnd(void)
+{
+	unsigned long rnd = get_random_int();
+
+	rnd = rnd << PAGE_SHIFT;
+	/* 8MB for 32bit, 256MB for 64bit */
+	if (TASK_IS_32BIT_ADDR)
+		rnd = rnd & 0x7ffffful;
+	else
+		rnd = rnd & 0xffffffful;
+
+	return rnd;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long base = mm->brk;
+	unsigned long ret;
+
+	ret = PAGE_ALIGN(base + brk_rnd());
+
+	if (ret < mm->brk)
+		return mm->brk;
+
+	return ret;
+}
+
 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags, unsigned long,
 	fd, off_t, offset)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 852780868fb4914e4711107e96c388e1ad8ab38d..03ec0019032bc50ebbc9435cdec3c71eeaa9ac70 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -25,6 +25,7 @@
 #include <linux/ptrace.h>
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/kprobes.h>
 #include <linux/notifier.h>
 #include <linux/kdb.h>
 
@@ -334,7 +335,7 @@ void show_regs(struct pt_regs *regs)
 	__show_regs((struct pt_regs *)regs);
 }
 
-void show_registers(const struct pt_regs *regs)
+void show_registers(struct pt_regs *regs)
 {
 	const int field = 2 * sizeof(unsigned long);
 
@@ -356,9 +357,14 @@ void show_registers(const struct pt_regs *regs)
 	printk("\n");
 }
 
+static int regs_to_trapnr(struct pt_regs *regs)
+{
+	return (regs->cp0_cause >> 2) & 0x1f;
+}
+
 static DEFINE_SPINLOCK(die_lock);
 
-void __noreturn die(const char * str, struct pt_regs * regs)
+void __noreturn die(const char *str, struct pt_regs *regs)
 {
 	static int die_counter;
 	int sig = SIGSEGV;
@@ -366,7 +372,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
 	unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-	notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0);
+	notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV);
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
@@ -375,7 +381,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
 	mips_mt_regdump(dvpret);
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-	if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
+	if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
 		sig = 0;
 
 	printk("%s[#%d]:\n", str, ++die_counter);
@@ -449,7 +455,7 @@ asmlinkage void do_be(struct pt_regs *regs)
 	printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
 	       data ? "Data" : "Instruction",
 	       field, regs->cp0_epc, field, regs->regs[31]);
-	if (notify_die(DIE_OOPS, "bus error", regs, SIGBUS, 0, 0)
+	if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
 	    == NOTIFY_STOP)
 		return;
 
@@ -650,7 +656,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
 	siginfo_t info;
 
-	if (notify_die(DIE_FP, "FP exception", regs, SIGFPE, 0, 0)
+	if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
 	    == NOTIFY_STOP)
 		return;
 	die_if_kernel("FP exception in kernel code", regs);
@@ -713,11 +719,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
 	char b[40];
 
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
-	if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP)
+	if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
 		return;
 #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
 
-	if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP)
+	if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
 		return;
 
 	/*
@@ -783,6 +789,25 @@ asmlinkage void do_bp(struct pt_regs *regs)
 	if (bcode >= (1 << 10))
 		bcode >>= 10;
 
+	/*
+	 * notify the kprobe handlers, if instruction is likely to
+	 * pertain to them.
+	 */
+	switch (bcode) {
+	case BRK_KPROBE_BP:
+		if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+			return;
+		else
+			break;
+	case BRK_KPROBE_SSTEPBP:
+		if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+			return;
+		else
+			break;
+	default:
+		break;
+	}
+
 	do_trap_or_bp(regs, bcode, "Break");
 	return;
 
@@ -815,7 +840,7 @@ asmlinkage void do_ri(struct pt_regs *regs)
 	unsigned int opcode = 0;
 	int status = -1;
 
-	if (notify_die(DIE_RI, "RI Fault", regs, SIGSEGV, 0, 0)
+	if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
 	    == NOTIFY_STOP)
 		return;
 
@@ -907,11 +932,6 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
 	return NOTIFY_OK;
 }
 
-static struct notifier_block default_cu2_notifier = {
-	.notifier_call	= default_cu2_call,
-	.priority	= 0x80000000,		/* Run last  */
-};
-
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
 	unsigned int __user *epc;
@@ -1734,5 +1754,5 @@ void __init trap_init(void)
 
 	sort_extable(__start___dbe_table, __stop___dbe_table);
 
-	register_cu2_notifier(&default_cu2_notifier);
+	cu2_notifier(default_cu2_call, 0x80000000);	/* Run last  */
 }
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
index 33791609fe99928aad677d0c5a312b1111e3d161..9cc4e4db8b9932e14325803a793576dd90b50400 100644
--- a/arch/mips/lasat/Makefile
+++ b/arch/mips/lasat/Makefile
@@ -12,5 +12,3 @@ obj-$(CONFIG_PICVUE_PROC)	+= picvue_proc.o
 
 clean:
 	make -C image clean
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/lasat/Platform b/arch/mips/lasat/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..760252828bf1fab1f299a289c4a9626746245333
--- /dev/null
+++ b/arch/mips/lasat/Platform
@@ -0,0 +1,7 @@
+#
+# LASAT platforms
+#
+platform-$(CONFIG_LASAT)	+= lasat/
+cflags-$(CONFIG_LASAT)		+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-lasat
+load-$(CONFIG_LASAT)		+= 0xffffffff80000000
diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..29692e5433b19d0d5f00d41bd61f0008242d46eb
--- /dev/null
+++ b/arch/mips/loongson/Platform
@@ -0,0 +1,32 @@
+#
+# Loongson Processors' Support
+#
+
+# Only gcc >= 4.4 have Loongson specific support
+cflags-$(CONFIG_CPU_LOONGSON2)	+= -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+	$(call cc-option,-march=loongson2e,-march=r4600)
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+	$(call cc-option,-march=loongson2f,-march=r4600)
+# Enable the workarounds for Loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+  else
+    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+  endif
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+  else
+    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+  endif
+endif
+
+#
+# Loongson Machines' Support
+#
+
+platform-$(CONFIG_MACH_LOONGSON) += loongson/
+cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile
index 510d4cdc23784def1bb243a794fb1064b8d9145d..f12e64007347087dfd5771cb16441fb81f1350e8 100644
--- a/arch/mips/loongson/common/cs5536/Makefile
+++ b/arch/mips/loongson/common/cs5536/Makefile
@@ -9,5 +9,3 @@ obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \
 # Enable cs5536 mfgpt Timer
 #
 obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
index 20e7328319787e3554f479890ea75736575e1117..5897471dedcada602d7e3ea720d1bf909e63d354 100644
--- a/arch/mips/loongson/common/irq.c
+++ b/arch/mips/loongson/common/irq.c
@@ -21,19 +21,16 @@ void bonito_irqdispatch(void)
 
 	/* workaround the IO dma problem: let cpu looping to allow DMA finish */
 	int_status = LOONGSON_INTISR;
-	if (int_status & (1 << 10)) {
-		while (int_status & (1 << 10)) {
-			udelay(1);
-			int_status = LOONGSON_INTISR;
-		}
+	while (int_status & (1 << 10)) {
+		udelay(1);
+		int_status = LOONGSON_INTISR;
 	}
 
 	/* Get pending sources, masked by current enables */
 	int_status = LOONGSON_INTISR & LOONGSON_INTEN;
 
-	if (int_status != 0) {
+	if (int_status) {
 		i = __ffs(int_status);
-		int_status &= ~(1 << i);
 		do_IRQ(LOONGSON_IRQ_BASE + i);
 	}
 }
@@ -56,9 +53,6 @@ void __init arch_init_irq(void)
 	 */
 	clear_c0_status(ST0_IM | ST0_BEV);
 
-	/* setting irq trigger mode */
-	set_irq_trigger_mode();
-
 	/* no steer */
 	LOONGSON_INTSTEER = 0;
 
diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile
index 3aba5fcc09dc8185470f91f7842441c4b6c04df9..b7622720c1ad55b0f07adb00b4130a9f77766b07 100644
--- a/arch/mips/loongson/fuloong-2e/Makefile
+++ b/arch/mips/loongson/fuloong-2e/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y += irq.o reset.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
index 320e9379bdd769e9171b5287218619ccf13de7c3..d61a04222b87217563543b8fb1ead4241c3ff859 100644
--- a/arch/mips/loongson/fuloong-2e/irq.c
+++ b/arch/mips/loongson/fuloong-2e/irq.c
@@ -30,7 +30,7 @@ asmlinkage void mach_irq_dispatch(unsigned int pending)
 	if (pending & CAUSEF_IP7)
 		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
 	else if (pending & CAUSEF_IP6) /* perf counter loverflow */
-		do_IRQ(LOONGSON2_PERFCNT_IRQ);
+		do_perfcnt_IRQ();
 	else if (pending & CAUSEF_IP5)
 		i8259_irqdispatch();
 	else if (pending & CAUSEF_IP2)
@@ -44,13 +44,6 @@ static struct irqaction cascade_irqaction = {
 	.name = "cascade",
 };
 
-void __init set_irq_trigger_mode(void)
-{
-	/* most bonito irq should be level triggered */
-	LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
-	    LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
-}
-
 void __init mach_init_irq(void)
 {
 	/* init all controller
@@ -59,6 +52,10 @@ void __init mach_init_irq(void)
 	 *   32-63        ------> bonito irq
 	 */
 
+	/* most bonito irq should be level triggered */
+	LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
+	    LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
+
 	/* Sets the first-level interrupt dispatcher. */
 	mips_cpu_irq_init();
 	init_i8259_irqs();
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
index 1d8b4d28a0580c3ada3b4eb1834ad64db50c3b59..081db102bb9835d7c15dd4f71db536e5783c40b8 100644
--- a/arch/mips/loongson/lemote-2f/irq.c
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -19,7 +19,6 @@
 #include <machine.h>
 
 #define LOONGSON_TIMER_IRQ	(MIPS_CPU_IRQ_BASE + 7)	/* cpu timer */
-#define LOONGSON_PERFCNT_IRQ	(MIPS_CPU_IRQ_BASE + 6)	/* cpu perf counter */
 #define LOONGSON_NORTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 6)	/* bonito */
 #define LOONGSON_UART_IRQ	(MIPS_CPU_IRQ_BASE + 3)	/* cpu serial port */
 #define LOONGSON_SOUTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 2)	/* i8259 */
@@ -79,9 +78,7 @@ void mach_irq_dispatch(unsigned int pending)
 	if (pending & CAUSEF_IP7)
 		do_IRQ(LOONGSON_TIMER_IRQ);
 	else if (pending & CAUSEF_IP6) {	/* North Bridge, Perf counter */
-#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
-		do_IRQ(LOONGSON2_PERFCNT_IRQ);
-#endif
+		do_perfcnt_IRQ();
 		bonito_irqdispatch();
 	} else if (pending & CAUSEF_IP3)	/* CPU UART */
 		do_IRQ(LOONGSON_UART_IRQ);
@@ -91,13 +88,6 @@ void mach_irq_dispatch(unsigned int pending)
 		spurious_interrupt();
 }
 
-void __init set_irq_trigger_mode(void)
-{
-	/* setup cs5536 as high level trigger */
-	LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
-	LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
-}
-
 static irqreturn_t ip6_action(int cpl, void *dev_id)
 {
 	return IRQ_HANDLED;
@@ -122,6 +112,10 @@ void __init mach_init_irq(void)
 	 *   32-63        ------> bonito irq
 	 */
 
+	/* setup cs5536 as high level trigger */
+	LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
+	LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
+
 	/* Sets the first-level interrupt dispatcher. */
 	mips_cpu_irq_init();
 	init_i8259_irqs();
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
index d547efdeedc2b105fda8bf34a6aa023898d371d2..96607230d9eab7751935ba0699e976ec8399ae19 100644
--- a/arch/mips/math-emu/Makefile
+++ b/arch/mips/math-emu/Makefile
@@ -10,4 +10,3 @@ obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
 	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
 	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
 
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
index 25861a42c36f80b01e036e70b8d4dfd5f3c70694..a8570e5c3efc13f2e516be0ac9903de2a348d71e 100644
--- a/arch/mips/math-emu/dp_modf.c
+++ b/arch/mips/math-emu/dp_modf.c
@@ -29,7 +29,7 @@
 
 /* modf function is always exact for a finite number
 */
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp *ip)
 {
 	COMPXDP;
 
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
index 77b2b7ccf28a997aabd54de8eb71bba179f04feb..24478623c117446d9c394204dbd5a18e811b6206 100644
--- a/arch/mips/math-emu/dp_tint.c
+++ b/arch/mips/math-emu/dp_tint.c
@@ -69,8 +69,7 @@ int ieee754dp_tint(ieee754dp x)
 			round = 0;
 			sticky = residue != 0;
 			xm = 0;
-		}
-		else {
+		} else {
 			residue = xm << (64 - DP_MBITS + xe);
 			round = (residue >> 63) != 0;
 			sticky = (residue << 1) != 0;
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
index d71113e071641939adf3802b08c5dd4f8a9bc7a3..0f07ec2be3f93198198f29940345dc613484a107 100644
--- a/arch/mips/math-emu/dp_tlong.c
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -71,8 +71,7 @@ s64 ieee754dp_tlong(ieee754dp x)
 			round = 0;
 			sticky = residue != 0;
 			xm = 0;
-		}
-		else {
+		} else {
 			/* Shifting a u64 64 times does not work,
 			* so we do it in two steps. Be aware that xe
 			* may be -1 */
diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
index 4b1dbac796f87116fcb050494978e5cdd0532f18..76568946b4c025f0176d62a0ec17970dd2ce8c9b 100644
--- a/arch/mips/math-emu/sp_modf.c
+++ b/arch/mips/math-emu/sp_modf.c
@@ -29,7 +29,7 @@
 
 /* modf function is always exact for a finite number
 */
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp *ip)
 {
 	COMPXSP;
 
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
index 1d73d2abe0b5a516198c2c0bc622c7a9b29e6414..352dc3a5f1afc597978c00a7f7467d15be35c0bf 100644
--- a/arch/mips/math-emu/sp_tint.c
+++ b/arch/mips/math-emu/sp_tint.c
@@ -72,8 +72,7 @@ int ieee754sp_tint(ieee754sp x)
 			round = 0;
 			sticky = residue != 0;
 			xm = 0;
-		}
-		else {
+		} else {
 			/* Shifting a u32 32 times does not work,
 			* so we do it in two steps. Be aware that xe
 			* may be -1 */
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index 4be21aa81fbf99443a77ba5e6e10bd63cff08a4a..92cd9c511a107c5227ea65d479c020bb2a07e317 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -71,8 +71,7 @@ s64 ieee754sp_tlong(ieee754sp x)
 			round = 0;
 			sticky = residue != 0;
 			xm = 0;
-		}
-		else {
+		} else {
 			residue = xm << (32 - SP_MBITS + xe);
 			round = (residue >> 31) != 0;
 			sticky = (residue << 1) != 0;
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
index 41b96571315e76009322209e8bf28bdb9eac3a67..01410a3f1729c47ad43b9f653701e77e8ff25006 100644
--- a/arch/mips/mipssim/Makefile
+++ b/arch/mips/mipssim/Makefile
@@ -21,5 +21,3 @@ obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
 
 obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
 obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..3df60b8a12ef15859b99fbe5918fc4cf0c23f6b7
--- /dev/null
+++ b/arch/mips/mipssim/Platform
@@ -0,0 +1,6 @@
+#
+# MIPS SIM
+#
+platform-$(CONFIG_MIPS_SIM)	+= mipssim/
+cflags-$(CONFIG_MIPS_SIM)	+= -I$(srctree)/arch/mips/include/asm/mach-mipssim
+load-$(CONFIG_MIPS_SIM)		+= 0x80100000
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index f0e4355997076864bc1d13d0b6b1d1915fcb2693..d679c772d082a2bf8b09612f7837b89576e051e7 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -34,5 +34,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm7k.o
 obj-$(CONFIG_MIPS_CPU_SCACHE)	+= sc-mips.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index b78f7d913ca4f468a56a9771c4b0619440efa9fc..783ad0065fdf49e8c35df2499e8fc7eca9b59ef4 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -16,8 +16,8 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/module.h>
+#include <linux/kprobes.h>
 
 #include <asm/branch.h>
 #include <asm/mmu_context.h>
@@ -25,13 +25,14 @@
 #include <asm/uaccess.h>
 #include <asm/ptrace.h>
 #include <asm/highmem.h>		/* For VMALLOC_END */
+#include <linux/kdebug.h>
 
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long write,
 			      unsigned long address)
 {
 	struct vm_area_struct * vma = NULL;
@@ -47,6 +48,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
 	       field, regs->cp0_epc);
 #endif
 
+#ifdef CONFIG_KPROBES
+	/*
+	 * This is to notify the fault handler of the kprobes.  The
+	 * exception code is redundant as it is also carried in REGS,
+	 * but we pass it anyhow.
+	 */
+	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
+		       (regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP)
+		return;
+#endif
+
 	info.si_code = SEGV_MAPERR;
 
 	/*
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
index de69bfbf506e251b078527096fba6b9efc6ddbbe..1ef75cd80a0d819827f5057549fdd2622442a752 100644
--- a/arch/mips/mm/sc-rm7k.c
+++ b/arch/mips/mm/sc-rm7k.c
@@ -16,6 +16,7 @@
 #include <asm/cacheops.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
+#include <asm/sections.h>
 #include <asm/cacheflush.h> /* for run_uncached() */
 
 /* Primary cache parameters. */
@@ -25,11 +26,15 @@
 /* Secondary cache parameters. */
 #define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
 
+/* Tertiary cache parameters */
+#define tc_lsize	32
+
 extern unsigned long icache_way_size, dcache_way_size;
+unsigned long tcache_size;
 
 #include <asm/r4kcache.h>
 
-static int rm7k_tcache_enabled;
+static int rm7k_tcache_init;
 
 /*
  * Writeback and invalidate the primary cache dcache before DMA.
@@ -46,7 +51,7 @@ static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size)
 
 	blast_scache_range(addr, addr + size);
 
-	if (!rm7k_tcache_enabled)
+	if (!rm7k_tcache_init)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -70,7 +75,7 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size)
 
 	blast_inv_scache_range(addr, addr + size);
 
-	if (!rm7k_tcache_enabled)
+	if (!rm7k_tcache_init)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -83,6 +88,45 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size)
 	}
 }
 
+static void blast_rm7k_tcache(void)
+{
+	unsigned long start = CKSEG0ADDR(0);
+	unsigned long end = start + tcache_size;
+
+	write_c0_taglo(0);
+
+	while (start < end) {
+		cache_op(Page_Invalidate_T, start);
+		start += tc_pagesize;
+	}
+}
+
+/*
+ * This function is executed in uncached address space.
+ */
+static __cpuinit void __rm7k_tc_enable(void)
+{
+	int i;
+
+	set_c0_config(RM7K_CONF_TE);
+
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+
+	for (i = 0; i < tcache_size; i += tc_lsize)
+		cache_op(Index_Store_Tag_T, CKSEG0ADDR(i));
+}
+
+static __cpuinit void rm7k_tc_enable(void)
+{
+	if (read_c0_config() & RM7K_CONF_TE)
+		return;
+
+	BUG_ON(tcache_size == 0);
+
+	run_uncached(__rm7k_tc_enable);
+}
+
 /*
  * This function is executed in uncached address space.
  */
@@ -95,16 +139,8 @@ static __cpuinit void __rm7k_sc_enable(void)
 	write_c0_taglo(0);
 	write_c0_taghi(0);
 
-	for (i = 0; i < scache_size; i += sc_lsize) {
-		__asm__ __volatile__ (
-		      ".set noreorder\n\t"
-		      ".set mips3\n\t"
-		      "cache %1, (%0)\n\t"
-		      ".set mips0\n\t"
-		      ".set reorder"
-		      :
-		      : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
-	}
+	for (i = 0; i < scache_size; i += sc_lsize)
+		cache_op(Index_Store_Tag_SD, CKSEG0ADDR(i));
 }
 
 static __cpuinit void rm7k_sc_enable(void)
@@ -112,13 +148,29 @@ static __cpuinit void rm7k_sc_enable(void)
 	if (read_c0_config() & RM7K_CONF_SE)
 		return;
 
-	printk(KERN_INFO "Enabling secondary cache...\n");
+	pr_info("Enabling secondary cache...\n");
 	run_uncached(__rm7k_sc_enable);
+
+	if (rm7k_tcache_init)
+		rm7k_tc_enable();
+}
+
+static void rm7k_tc_disable(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_rm7k_tcache();
+	clear_c0_config(RM7K_CONF_TE);
+	local_irq_save(flags);
 }
 
 static void rm7k_sc_disable(void)
 {
 	clear_c0_config(RM7K_CONF_SE);
+
+	if (rm7k_tcache_init)
+		rm7k_tc_disable();
 }
 
 static struct bcache_ops rm7k_sc_ops = {
@@ -128,6 +180,52 @@ static struct bcache_ops rm7k_sc_ops = {
 	.bc_inv = rm7k_sc_inv
 };
 
+/*
+ * This is a probing function like the one found in c-r4k.c, we look for the
+ * wrap around point with different addresses.
+ */
+static __cpuinit void __probe_tcache(void)
+{
+	unsigned long flags, addr, begin, end, pow2;
+
+	begin = (unsigned long) &_stext;
+	begin  &= ~((8 * 1024 * 1024) - 1);
+	end = begin + (8 * 1024 * 1024);
+
+	local_irq_save(flags);
+
+	set_c0_config(RM7K_CONF_TE);
+
+	/* Fill size-multiple lines with a valid tag */
+	pow2 = (256 * 1024);
+	for (addr = begin; addr <= end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p));
+		pow2 <<= 1;
+	}
+
+	/* Load first line with a 0 tag, to check after */
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+	cache_op(Index_Store_Tag_T, begin);
+
+	/* Look for the wrap-around */
+	pow2 = (512 * 1024);
+	for (addr = begin + (512 * 1024); addr <= end; addr = begin + pow2) {
+		cache_op(Index_Load_Tag_T, addr);
+		if (!read_c0_taglo())
+			break;
+		pow2 <<= 1;
+	}
+
+	addr -= begin;
+	tcache_size = addr;
+
+	clear_c0_config(RM7K_CONF_TE);
+
+	local_irq_restore(flags);
+}
+
 void __cpuinit rm7k_sc_init(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
@@ -147,27 +245,26 @@ void __cpuinit rm7k_sc_init(void)
 	if (!(config & RM7K_CONF_SE))
 		rm7k_sc_enable();
 
+	bcops = &rm7k_sc_ops;
+
 	/*
 	 * While we're at it let's deal with the tertiary cache.
 	 */
-	if (!(config & RM7K_CONF_TC)) {
-
-		/*
-		 * We can't enable the L3 cache yet. There may be board-specific
-		 * magic necessary to turn it on, and blindly asking the CPU to
-		 * start using it would may give cache errors.
-		 *
-		 * Also, board-specific knowledge may allow us to use the
-		 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
-		 * it, and may specify the size of the L3 cache so we don't have
-		 * to probe it.
-		 */
-		printk(KERN_INFO "Tertiary cache present, %s enabled\n",
-		       (config & RM7K_CONF_TE) ? "already" : "not (yet)");
-
-		if ((config & RM7K_CONF_TE))
-			rm7k_tcache_enabled = 1;
-	}
 
-	bcops = &rm7k_sc_ops;
+	rm7k_tcache_init = 0;
+	tcache_size = 0;
+
+	if (config & RM7K_CONF_TC)
+		return;
+
+	/*
+	 * No efficient way to ask the hardware for the size of the tcache,
+	 * so must probe for it.
+	 */
+	run_uncached(__probe_tcache);
+	rm7k_tc_enable();
+	rm7k_tcache_init = 1;
+	c->tcache.linesz = tc_lsize;
+	c->tcache.ways = 1;
+	pr_info("Tertiary cache size %ldK.\n", (tcache_size >> 10));
 }
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 86f004dc83557240a18e02ca15bf2f17fe96005d..4510e61883eb2b8df22ea6e62f1bf13f4de1cc0d 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -409,6 +409,11 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
 		tlbw(p);
 		break;
 
+	case CPU_JZRISC:
+		tlbw(p);
+		uasm_i_nop(p);
+		break;
+
 	default:
 		panic("No TLB refill handler yet (CPU type: %d)",
 		      current_cpu_data.cputype);
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 611d564fdcf1e1bb4cbad07244ee2ca34192582c..d2647a4e012bbaf2b7bdbeae1e581ea5f1d02e37 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -62,12 +62,13 @@ enum opcode {
 	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
 	insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
 	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
-	insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
-	insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-	insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
-	insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
-	insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
-	insn_dins, insn_syscall
+	insn_dsrl32, insn_drotr, insn_drotr32, insn_dsubu, insn_eret,
+	insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld,
+	insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_or, insn_ori,
+	insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+	insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp,
+	insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
+	insn_dins, insn_syscall, insn_bbit0, insn_bbit1
 };
 
 struct insn {
@@ -85,7 +86,7 @@ struct insn {
 	 | (e) << RE_SH						\
 	 | (f) << FUNC_SH)
 
-static struct insn insn_table[] __cpuinitdata = {
+static struct insn insn_table[] __uasminitdata = {
 	{ insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
 	{ insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
 	{ insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
@@ -108,6 +109,7 @@ static struct insn insn_table[] __cpuinitdata = {
 	{ insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
 	{ insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
 	{ insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
+	{ insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE },
 	{ insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
 	{ insn_eret,  M(cop0_op, cop_op, 0, 0, 0, eret_op),  0 },
 	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
@@ -141,12 +143,14 @@ static struct insn insn_table[] __cpuinitdata = {
 	{ insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
 	{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
+	{ insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+	{ insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
 	{ insn_invalid, 0, 0 }
 };
 
 #undef M
 
-static inline __cpuinit u32 build_rs(u32 arg)
+static inline __uasminit u32 build_rs(u32 arg)
 {
 	if (arg & ~RS_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -154,7 +158,7 @@ static inline __cpuinit u32 build_rs(u32 arg)
 	return (arg & RS_MASK) << RS_SH;
 }
 
-static inline __cpuinit u32 build_rt(u32 arg)
+static inline __uasminit u32 build_rt(u32 arg)
 {
 	if (arg & ~RT_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -162,7 +166,7 @@ static inline __cpuinit u32 build_rt(u32 arg)
 	return (arg & RT_MASK) << RT_SH;
 }
 
-static inline __cpuinit u32 build_rd(u32 arg)
+static inline __uasminit u32 build_rd(u32 arg)
 {
 	if (arg & ~RD_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -170,7 +174,7 @@ static inline __cpuinit u32 build_rd(u32 arg)
 	return (arg & RD_MASK) << RD_SH;
 }
 
-static inline __cpuinit u32 build_re(u32 arg)
+static inline __uasminit u32 build_re(u32 arg)
 {
 	if (arg & ~RE_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -178,7 +182,7 @@ static inline __cpuinit u32 build_re(u32 arg)
 	return (arg & RE_MASK) << RE_SH;
 }
 
-static inline __cpuinit u32 build_simm(s32 arg)
+static inline __uasminit u32 build_simm(s32 arg)
 {
 	if (arg > 0x7fff || arg < -0x8000)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -186,7 +190,7 @@ static inline __cpuinit u32 build_simm(s32 arg)
 	return arg & 0xffff;
 }
 
-static inline __cpuinit u32 build_uimm(u32 arg)
+static inline __uasminit u32 build_uimm(u32 arg)
 {
 	if (arg & ~IMM_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -194,7 +198,7 @@ static inline __cpuinit u32 build_uimm(u32 arg)
 	return arg & IMM_MASK;
 }
 
-static inline __cpuinit u32 build_bimm(s32 arg)
+static inline __uasminit u32 build_bimm(s32 arg)
 {
 	if (arg > 0x1ffff || arg < -0x20000)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -205,7 +209,7 @@ static inline __cpuinit u32 build_bimm(s32 arg)
 	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
 }
 
-static inline __cpuinit u32 build_jimm(u32 arg)
+static inline __uasminit u32 build_jimm(u32 arg)
 {
 	if (arg & ~((JIMM_MASK) << 2))
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -213,7 +217,7 @@ static inline __cpuinit u32 build_jimm(u32 arg)
 	return (arg >> 2) & JIMM_MASK;
 }
 
-static inline __cpuinit u32 build_scimm(u32 arg)
+static inline __uasminit u32 build_scimm(u32 arg)
 {
 	if (arg & ~SCIMM_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -221,7 +225,7 @@ static inline __cpuinit u32 build_scimm(u32 arg)
 	return (arg & SCIMM_MASK) << SCIMM_SH;
 }
 
-static inline __cpuinit u32 build_func(u32 arg)
+static inline __uasminit u32 build_func(u32 arg)
 {
 	if (arg & ~FUNC_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -229,7 +233,7 @@ static inline __cpuinit u32 build_func(u32 arg)
 	return arg & FUNC_MASK;
 }
 
-static inline __cpuinit u32 build_set(u32 arg)
+static inline __uasminit u32 build_set(u32 arg)
 {
 	if (arg & ~SET_MASK)
 		printk(KERN_WARNING "Micro-assembler field overflow\n");
@@ -241,7 +245,7 @@ static inline __cpuinit u32 build_set(u32 arg)
  * The order of opcode arguments is implicitly left to right,
  * starting with RS and ending with FUNC or IMM.
  */
-static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
+static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
 {
 	struct insn *ip = NULL;
 	unsigned int i;
@@ -291,67 +295,78 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
 Ip_u1u2u3(op)						\
 {							\
 	build_insn(buf, insn##op, a, b, c);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u2u1u3(op)					\
 Ip_u2u1u3(op)						\
 {							\
 	build_insn(buf, insn##op, b, a, c);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u3u1u2(op)					\
 Ip_u3u1u2(op)						\
 {							\
 	build_insn(buf, insn##op, b, c, a);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u1u2s3(op)					\
 Ip_u1u2s3(op)						\
 {							\
 	build_insn(buf, insn##op, a, b, c);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u2s3u1(op)					\
 Ip_u2s3u1(op)						\
 {							\
 	build_insn(buf, insn##op, c, a, b);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u2u1s3(op)					\
 Ip_u2u1s3(op)						\
 {							\
 	build_insn(buf, insn##op, b, a, c);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u2u1msbu3(op)					\
 Ip_u2u1msbu3(op)					\
 {							\
 	build_insn(buf, insn##op, b, a, c+d-1, c);	\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u1u2(op)					\
 Ip_u1u2(op)						\
 {							\
 	build_insn(buf, insn##op, a, b);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u1s2(op)					\
 Ip_u1s2(op)						\
 {							\
 	build_insn(buf, insn##op, a, b);		\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_u1(op)					\
 Ip_u1(op)						\
 {							\
 	build_insn(buf, insn##op, a);			\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 #define I_0(op)						\
 Ip_0(op)						\
 {							\
 	build_insn(buf, insn##op);			\
-}
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
 
 I_u2u1s3(_addiu)
 I_u3u1u2(_addu)
@@ -375,6 +390,7 @@ I_u2u1u3(_dsra)
 I_u2u1u3(_dsrl)
 I_u2u1u3(_dsrl32)
 I_u2u1u3(_drotr)
+I_u2u1u3(_drotr32)
 I_u3u1u2(_dsubu)
 I_0(_eret)
 I_u1(_j)
@@ -408,16 +424,19 @@ I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
 I_u1(_syscall);
+I_u1u2s3(_bbit0);
+I_u1u2s3(_bbit1);
 
 /* Handle labels. */
-void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
+void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
 {
 	(*lab)->addr = addr;
 	(*lab)->lab = lid;
 	(*lab)++;
 }
+UASM_EXPORT_SYMBOL(uasm_build_label);
 
-int __cpuinit uasm_in_compat_space_p(long addr)
+int __uasminit uasm_in_compat_space_p(long addr)
 {
 	/* Is this address in 32bit compat space? */
 #ifdef CONFIG_64BIT
@@ -426,8 +445,9 @@ int __cpuinit uasm_in_compat_space_p(long addr)
 	return 1;
 #endif
 }
+UASM_EXPORT_SYMBOL(uasm_in_compat_space_p);
 
-static int __cpuinit uasm_rel_highest(long val)
+static int __uasminit uasm_rel_highest(long val)
 {
 #ifdef CONFIG_64BIT
 	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
@@ -436,7 +456,7 @@ static int __cpuinit uasm_rel_highest(long val)
 #endif
 }
 
-static int __cpuinit uasm_rel_higher(long val)
+static int __uasminit uasm_rel_higher(long val)
 {
 #ifdef CONFIG_64BIT
 	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
@@ -445,17 +465,19 @@ static int __cpuinit uasm_rel_higher(long val)
 #endif
 }
 
-int __cpuinit uasm_rel_hi(long val)
+int __uasminit uasm_rel_hi(long val)
 {
 	return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
 }
+UASM_EXPORT_SYMBOL(uasm_rel_hi);
 
-int __cpuinit uasm_rel_lo(long val)
+int __uasminit uasm_rel_lo(long val)
 {
 	return ((val & 0xffff) ^ 0x8000) - 0x8000;
 }
+UASM_EXPORT_SYMBOL(uasm_rel_lo);
 
-void __cpuinit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
+void __uasminit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
 {
 	if (!uasm_in_compat_space_p(addr)) {
 		uasm_i_lui(buf, rs, uasm_rel_highest(addr));
@@ -470,8 +492,9 @@ void __cpuinit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
 	} else
 		uasm_i_lui(buf, rs, uasm_rel_hi(addr));
 }
+UASM_EXPORT_SYMBOL(UASM_i_LA_mostly);
 
-void __cpuinit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
+void __uasminit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
 {
 	UASM_i_LA_mostly(buf, rs, addr);
 	if (uasm_rel_lo(addr)) {
@@ -481,9 +504,10 @@ void __cpuinit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
 			uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr));
 	}
 }
+UASM_EXPORT_SYMBOL(UASM_i_LA);
 
 /* Handle relocations. */
-void __cpuinit
+void __uasminit
 uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
 {
 	(*rel)->addr = addr;
@@ -491,8 +515,9 @@ uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
 	(*rel)->lab = lid;
 	(*rel)++;
 }
+UASM_EXPORT_SYMBOL(uasm_r_mips_pc16);
 
-static inline void __cpuinit
+static inline void __uasminit
 __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 {
 	long laddr = (long)lab->addr;
@@ -509,7 +534,7 @@ __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 	}
 }
 
-void __cpuinit
+void __uasminit
 uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 {
 	struct uasm_label *l;
@@ -519,24 +544,27 @@ uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 			if (rel->lab == l->lab)
 				__resolve_relocs(rel, l);
 }
+UASM_EXPORT_SYMBOL(uasm_resolve_relocs);
 
-void __cpuinit
+void __uasminit
 uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off)
 {
 	for (; rel->lab != UASM_LABEL_INVALID; rel++)
 		if (rel->addr >= first && rel->addr < end)
 			rel->addr += off;
 }
+UASM_EXPORT_SYMBOL(uasm_move_relocs);
 
-void __cpuinit
+void __uasminit
 uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off)
 {
 	for (; lab->lab != UASM_LABEL_INVALID; lab++)
 		if (lab->addr >= first && lab->addr < end)
 			lab->addr += off;
 }
+UASM_EXPORT_SYMBOL(uasm_move_labels);
 
-void __cpuinit
+void __uasminit
 uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
 		  u32 *end, u32 *target)
 {
@@ -547,8 +575,9 @@ uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
 	uasm_move_relocs(rel, first, end, off);
 	uasm_move_labels(lab, first, end, off);
 }
+UASM_EXPORT_SYMBOL(uasm_copy_handler);
 
-int __cpuinit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
+int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
 {
 	for (; rel->lab != UASM_LABEL_INVALID; rel++) {
 		if (rel->addr == addr
@@ -559,61 +588,88 @@ int __cpuinit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
 
 	return 0;
 }
+UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay);
 
 /* Convenience functions for labeled branches. */
-void __cpuinit
+void __uasminit
 uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_bltz(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_bltz);
 
-void __cpuinit
+void __uasminit
 uasm_il_b(u32 **p, struct uasm_reloc **r, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_b(p, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_b);
 
-void __cpuinit
+void __uasminit
 uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_beqz(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_beqz);
 
-void __cpuinit
+void __uasminit
 uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_beqzl(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_beqzl);
 
-void __cpuinit
+void __uasminit
 uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
 	unsigned int reg2, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_bne(p, reg1, reg2, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_bne);
 
-void __cpuinit
+void __uasminit
 uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_bnez(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_bnez);
 
-void __cpuinit
+void __uasminit
 uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_bgezl(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_bgezl);
 
-void __cpuinit
+void __uasminit
 uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	uasm_i_bgez(p, reg, 0);
 }
+UASM_EXPORT_SYMBOL(uasm_il_bgez);
+
+void __uasminit
+uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
+	      unsigned int bit, int lid)
+{
+	uasm_r_mips_pc16(r, *p, lid);
+	uasm_i_bbit0(p, reg, bit, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bbit0);
+
+void __uasminit
+uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
+	      unsigned int bit, int lid)
+{
+	uasm_r_mips_pc16(r, *p, lid);
+	uasm_i_bbit1(p, reg, bit, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bbit1);
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile
index 32e847808df166cf6469a4d919b2763dd7bde8da..6079ef33b5f0670e0e3f4de945bd287a821a7381 100644
--- a/arch/mips/mti-malta/Makefile
+++ b/arch/mips/mti-malta/Makefile
@@ -15,5 +15,3 @@ obj-$(CONFIG_PCI)		+= malta-pci.o
 
 # FIXME FIXME FIXME
 obj-$(CONFIG_MIPS_MT_SMTC)	+= malta-smtc.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mti-malta/Platform b/arch/mips/mti-malta/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..5b548b5a4fcf1f5bf116d6dd59e4c42755193c4c
--- /dev/null
+++ b/arch/mips/mti-malta/Platform
@@ -0,0 +1,7 @@
+#
+# MIPS Malta board
+#
+platform-$(CONFIG_MIPS_MALTA)	+= mti-malta/
+cflags-$(CONFIG_MIPS_MALTA)	+= -I$(srctree)/arch/mips/include/asm/mach-malta
+load-$(CONFIG_MIPS_MALTA)	+= 0xffffffff80100000
+all-$(CONFIG_MIPS_MALTA)	:= $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/nxp/pnx833x/stb22x/Makefile b/arch/mips/nxp/pnx833x/stb22x/Makefile
deleted file mode 100644
index f81c5801f455e9b8f12e1bd3d12f0227508751a4..0000000000000000000000000000000000000000
--- a/arch/mips/nxp/pnx833x/stb22x/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-lib-y := board.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx8550/jbs/Makefile b/arch/mips/nxp/pnx8550/jbs/Makefile
deleted file mode 100644
index ad6a8ca7d8ce1420bd23ff538f1314cadf9aaad7..0000000000000000000000000000000000000000
--- a/arch/mips/nxp/pnx8550/jbs/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Makefile for the NXP JBS Board.
-
-lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/stb810/Makefile b/arch/mips/nxp/pnx8550/stb810/Makefile
deleted file mode 100644
index ab91d72c5664556515b13f3e2cd0f5ecbc901e0d..0000000000000000000000000000000000000000
--- a/arch/mips/nxp/pnx8550/stb810/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Makefile for the NXP STB810 Board.
-
-lib-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 03742e64765717ec3976c0eb7d7e77c8d8a283e0..d8080499872a5af2bbf47c1f2431744b94d4ef1b 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005-2009 Cavium Networks
+ * Copyright (C) 2005-2009, 2010 Cavium Networks
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -22,7 +22,7 @@
  * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
  * in use.
  */
-static uint64_t msi_free_irq_bitmask;
+static u64 msi_free_irq_bitmask[4];
 
 /*
  * Each bit in msi_multiple_irq_bitmask tells that the device using
@@ -30,7 +30,7 @@ static uint64_t msi_free_irq_bitmask;
  * is used so we can disable all of the MSI interrupts when a device
  * uses multiple.
  */
-static uint64_t msi_multiple_irq_bitmask;
+static u64 msi_multiple_irq_bitmask[4];
 
 /*
  * This lock controls updates to msi_free_irq_bitmask and
@@ -38,6 +38,11 @@ static uint64_t msi_multiple_irq_bitmask;
  */
 static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
 
+/*
+ * Number of MSI IRQs used. This variable is set up in
+ * the module init time.
+ */
+static int msi_irq_size;
 
 /**
  * Called when a driver request MSI interrupts instead of the
@@ -54,12 +59,13 @@ static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
 int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
 	struct msi_msg msg;
-	uint16_t control;
+	u16 control;
 	int configured_private_bits;
 	int request_private_bits;
-	int irq;
+	int irq = 0;
 	int irq_step;
-	uint64_t search_mask;
+	u64 search_mask;
+	int index;
 
 	/*
 	 * Read the MSI config to figure out how many IRQs this device
@@ -111,29 +117,31 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 	 * use.
 	 */
 	spin_lock(&msi_free_irq_bitmask_lock);
-	for (irq = 0; irq < 64; irq += irq_step) {
-		if ((msi_free_irq_bitmask & (search_mask << irq)) == 0) {
-			msi_free_irq_bitmask |= search_mask << irq;
-			msi_multiple_irq_bitmask |= (search_mask >> 1) << irq;
-			break;
+	for (index = 0; index < msi_irq_size/64; index++) {
+		for (irq = 0; irq < 64; irq += irq_step) {
+			if ((msi_free_irq_bitmask[index] & (search_mask << irq)) == 0) {
+				msi_free_irq_bitmask[index] |= search_mask << irq;
+				msi_multiple_irq_bitmask[index] |= (search_mask >> 1) << irq;
+				goto msi_irq_allocated;
+			}
 		}
 	}
+msi_irq_allocated:
 	spin_unlock(&msi_free_irq_bitmask_lock);
 
 	/* Make sure the search for available interrupts didn't fail */
 	if (irq >= 64) {
 		if (request_private_bits) {
-			pr_err("arch_setup_msi_irq: Unable to find %d free "
-			       "interrupts, trying just one",
+			pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
 			       1 << request_private_bits);
 			request_private_bits = 0;
 			goto try_only_one;
 		} else
-			panic("arch_setup_msi_irq: Unable to find a free MSI "
-			      "interrupt");
+			panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
 	}
 
 	/* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
+	irq += index*64;
 	irq += OCTEON_IRQ_MSI_BIT0;
 
 	switch (octeon_dma_bar_type) {
@@ -169,6 +177,34 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 	return 0;
 }
 
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+	struct msi_desc *entry;
+	int ret;
+
+	/*
+	 * MSI-X is not supported.
+	 */
+	if (type == PCI_CAP_ID_MSIX)
+		return -EINVAL;
+
+	/*
+	 * If an architecture wants to support multiple MSI, it needs to
+	 * override arch_setup_msi_irqs()
+	 */
+	if (type == PCI_CAP_ID_MSI && nvec > 1)
+		return 1;
+
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		ret = arch_setup_msi_irq(dev, entry);
+		if (ret < 0)
+			return ret;
+		if (ret > 0)
+			return -ENOSPC;
+	}
+
+	return 0;
+}
 
 /**
  * Called when a device no longer needs its MSI interrupts. All
@@ -179,12 +215,18 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 void arch_teardown_msi_irq(unsigned int irq)
 {
 	int number_irqs;
-	uint64_t bitmask;
+	u64 bitmask;
+	int index = 0;
+	int irq0;
 
-	if ((irq < OCTEON_IRQ_MSI_BIT0) || (irq > OCTEON_IRQ_MSI_BIT63))
+	if ((irq < OCTEON_IRQ_MSI_BIT0)
+		|| (irq > msi_irq_size + OCTEON_IRQ_MSI_BIT0))
 		panic("arch_teardown_msi_irq: Attempted to teardown illegal "
 		      "MSI interrupt (%d)", irq);
+
 	irq -= OCTEON_IRQ_MSI_BIT0;
+	index = irq / 64;
+	irq0 = irq % 64;
 
 	/*
 	 * Count the number of IRQs we need to free by looking at the
@@ -192,97 +234,198 @@ void arch_teardown_msi_irq(unsigned int irq)
 	 * IRQ is also owned by this device.
 	 */
 	number_irqs = 0;
-	while ((irq+number_irqs < 64) &&
-	       (msi_multiple_irq_bitmask & (1ull << (irq + number_irqs))))
+	while ((irq0 + number_irqs < 64) &&
+	       (msi_multiple_irq_bitmask[index]
+		& (1ull << (irq0 + number_irqs))))
 		number_irqs++;
 	number_irqs++;
 	/* Mask with one bit for each IRQ */
 	bitmask = (1 << number_irqs) - 1;
 	/* Shift the mask to the correct bit location */
-	bitmask <<= irq;
-	if ((msi_free_irq_bitmask & bitmask) != bitmask)
+	bitmask <<= irq0;
+	if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
 		panic("arch_teardown_msi_irq: Attempted to teardown MSI "
 		      "interrupt (%d) not in use", irq);
 
 	/* Checks are done, update the in use bitmask */
 	spin_lock(&msi_free_irq_bitmask_lock);
-	msi_free_irq_bitmask &= ~bitmask;
-	msi_multiple_irq_bitmask &= ~bitmask;
+	msi_free_irq_bitmask[index] &= ~bitmask;
+	msi_multiple_irq_bitmask[index] &= ~bitmask;
 	spin_unlock(&msi_free_irq_bitmask_lock);
 }
 
+static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
+
+static u64 msi_rcv_reg[4];
+static u64 mis_ena_reg[4];
+
+static void octeon_irq_msi_enable_pcie(unsigned int irq)
+{
+	u64 en;
+	unsigned long flags;
+	int msi_number = irq - OCTEON_IRQ_MSI_BIT0;
+	int irq_index = msi_number >> 6;
+	int irq_bit = msi_number & 0x3f;
+
+	raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+	en = cvmx_read_csr(mis_ena_reg[irq_index]);
+	en |= 1ull << irq_bit;
+	cvmx_write_csr(mis_ena_reg[irq_index], en);
+	cvmx_read_csr(mis_ena_reg[irq_index]);
+	raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+}
+
+static void octeon_irq_msi_disable_pcie(unsigned int irq)
+{
+	u64 en;
+	unsigned long flags;
+	int msi_number = irq - OCTEON_IRQ_MSI_BIT0;
+	int irq_index = msi_number >> 6;
+	int irq_bit = msi_number & 0x3f;
+
+	raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+	en = cvmx_read_csr(mis_ena_reg[irq_index]);
+	en &= ~(1ull << irq_bit);
+	cvmx_write_csr(mis_ena_reg[irq_index], en);
+	cvmx_read_csr(mis_ena_reg[irq_index]);
+	raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+}
+
+static struct irq_chip octeon_irq_chip_msi_pcie = {
+	.name = "MSI",
+	.enable = octeon_irq_msi_enable_pcie,
+	.disable = octeon_irq_msi_disable_pcie,
+};
+
+static void octeon_irq_msi_enable_pci(unsigned int irq)
+{
+	/*
+	 * Octeon PCI doesn't have the ability to mask/unmask MSI
+	 * interrupts individually. Instead of masking/unmasking them
+	 * in groups of 16, we simple assume MSI devices are well
+	 * behaved. MSI interrupts are always enable and the ACK is
+	 * assumed to be enough
+	 */
+}
+
+static void octeon_irq_msi_disable_pci(unsigned int irq)
+{
+	/* See comment in enable */
+}
+
+static struct irq_chip octeon_irq_chip_msi_pci = {
+	.name = "MSI",
+	.enable = octeon_irq_msi_enable_pci,
+	.disable = octeon_irq_msi_disable_pci,
+};
 
 /*
  * Called by the interrupt handling code when an MSI interrupt
  * occurs.
  */
-static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
+static irqreturn_t __octeon_msi_do_interrupt(int index, u64 msi_bits)
 {
-	uint64_t msi_bits;
 	int irq;
+	int bit;
 
-	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE)
-		msi_bits = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_RCV0);
-	else
-		msi_bits = cvmx_read_csr(CVMX_NPI_NPI_MSI_RCV);
-	irq = fls64(msi_bits);
-	if (irq) {
-		irq += OCTEON_IRQ_MSI_BIT0 - 1;
-		if (irq_desc[irq].action) {
-			do_IRQ(irq);
-			return IRQ_HANDLED;
-		} else {
-			pr_err("Spurious MSI interrupt %d\n", irq);
-			if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
-				/* These chips have PCIe */
-				cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
-					       1ull << (irq -
-							OCTEON_IRQ_MSI_BIT0));
-			} else {
-				/* These chips have PCI */
-				cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
-					       1ull << (irq -
-							OCTEON_IRQ_MSI_BIT0));
-			}
-		}
+	bit = fls64(msi_bits);
+	if (bit) {
+		bit--;
+		/* Acknowledge it first. */
+		cvmx_write_csr(msi_rcv_reg[index], 1ull << bit);
+
+		irq = bit + OCTEON_IRQ_MSI_BIT0 + 64 * index;
+		do_IRQ(irq);
+		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
 }
 
+#define OCTEON_MSI_INT_HANDLER_X(x)					\
+static irqreturn_t octeon_msi_interrupt##x(int cpl, void *dev_id)	\
+{									\
+	u64 msi_bits = cvmx_read_csr(msi_rcv_reg[(x)]);			\
+	return __octeon_msi_do_interrupt((x), msi_bits);		\
+}
+
+/*
+ * Create octeon_msi_interrupt{0-3} function body
+ */
+OCTEON_MSI_INT_HANDLER_X(0);
+OCTEON_MSI_INT_HANDLER_X(1);
+OCTEON_MSI_INT_HANDLER_X(2);
+OCTEON_MSI_INT_HANDLER_X(3);
 
 /*
  * Initializes the MSI interrupt handling code
  */
-int octeon_msi_initialize(void)
+int __init octeon_msi_initialize(void)
 {
+	int irq;
+	struct irq_chip *msi;
+
+	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) {
+		msi_rcv_reg[0] = CVMX_PEXP_NPEI_MSI_RCV0;
+		msi_rcv_reg[1] = CVMX_PEXP_NPEI_MSI_RCV1;
+		msi_rcv_reg[2] = CVMX_PEXP_NPEI_MSI_RCV2;
+		msi_rcv_reg[3] = CVMX_PEXP_NPEI_MSI_RCV3;
+		mis_ena_reg[0] = CVMX_PEXP_NPEI_MSI_ENB0;
+		mis_ena_reg[1] = CVMX_PEXP_NPEI_MSI_ENB1;
+		mis_ena_reg[2] = CVMX_PEXP_NPEI_MSI_ENB2;
+		mis_ena_reg[3] = CVMX_PEXP_NPEI_MSI_ENB3;
+		msi = &octeon_irq_chip_msi_pcie;
+	} else {
+		msi_rcv_reg[0] = CVMX_NPI_NPI_MSI_RCV;
+#define INVALID_GENERATE_ADE 0x8700000000000000ULL;
+		msi_rcv_reg[1] = INVALID_GENERATE_ADE;
+		msi_rcv_reg[2] = INVALID_GENERATE_ADE;
+		msi_rcv_reg[3] = INVALID_GENERATE_ADE;
+		mis_ena_reg[0] = INVALID_GENERATE_ADE;
+		mis_ena_reg[1] = INVALID_GENERATE_ADE;
+		mis_ena_reg[2] = INVALID_GENERATE_ADE;
+		mis_ena_reg[3] = INVALID_GENERATE_ADE;
+		msi = &octeon_irq_chip_msi_pci;
+	}
+
+	for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++)
+		set_irq_chip_and_handler(irq, msi, handle_simple_irq);
+
 	if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
-		if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
-				IRQF_SHARED,
-				"MSI[0:63]", octeon_msi_interrupt))
+		if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
+				0, "MSI[0:63]", octeon_msi_interrupt0))
 			panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
+
+		if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt1,
+				0, "MSI[64:127]", octeon_msi_interrupt1))
+			panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
+
+		if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt2,
+				0, "MSI[127:191]", octeon_msi_interrupt2))
+			panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
+
+		if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt3,
+				0, "MSI[192:255]", octeon_msi_interrupt3))
+			panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
+
+		msi_irq_size = 256;
 	} else if (octeon_is_pci_host()) {
-		if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
-				IRQF_SHARED,
-				"MSI[0:15]", octeon_msi_interrupt))
+		if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
+				0, "MSI[0:15]", octeon_msi_interrupt0))
 			panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
 
-		if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt,
-				IRQF_SHARED,
-				"MSI[16:31]", octeon_msi_interrupt))
+		if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt0,
+				0, "MSI[16:31]", octeon_msi_interrupt0))
 			panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
 
-		if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt,
-				IRQF_SHARED,
-				"MSI[32:47]", octeon_msi_interrupt))
+		if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt0,
+				0, "MSI[32:47]", octeon_msi_interrupt0))
 			panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
 
-		if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt,
-				IRQF_SHARED,
-				"MSI[48:63]", octeon_msi_interrupt))
+		if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt0,
+				0, "MSI[48:63]", octeon_msi_interrupt0))
 			panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
-
+		msi_irq_size = 64;
 	}
 	return 0;
 }
-
 subsys_initcall(octeon_msi_initialize);
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
index 749c1922d4205f0da1ea468fc89edef76c49e462..57d54adc9e20784fa3f7d1695caba3f5e8dabbb6 100644
--- a/arch/mips/pci/ops-titan-ht.c
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -32,7 +32,7 @@
 #include <asm/titan_dep.h>
 
 static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
-	int offset, u32 * val)
+	int offset, u32 *val)
 {
 	volatile uint32_t address;
 	int busno;
@@ -64,7 +64,7 @@ static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
 }
 
 static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
-	int offset, int size, u32 * val)
+	int offset, int size, u32 *val)
 {
 	uint32_t dword;
 
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
index 6aa5c542d52dff2a72670722ad882ef79418594e..861361e0c9afc668f5914f67ea8351134ab56ecc 100644
--- a/arch/mips/pci/pcie-octeon.c
+++ b/arch/mips/pci/pcie-octeon.c
@@ -402,6 +402,10 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
 	npei_ctl_status2.s.mps = 0;
 	/* Max read request size = 128 bytes for best Octeon DMA performance */
 	npei_ctl_status2.s.mrrs = 0;
+	if (pcie_port)
+		npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
+	else
+		npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
 	cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
 
 	/* ECRC Generation (PCIE*_CFG070[GE,CE]) */
@@ -666,6 +670,8 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
 static int cvmx_pcie_rc_initialize(int pcie_port)
 {
 	int i;
+	int base;
+	u64 addr_swizzle;
 	union cvmx_ciu_soft_prst ciu_soft_prst;
 	union cvmx_pescx_bist_status pescx_bist_status;
 	union cvmx_pescx_bist_status2 pescx_bist_status2;
@@ -674,6 +680,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
 	union cvmx_npei_mem_access_subidx mem_access_subid;
 	union cvmx_npei_dbg_data npei_dbg_data;
 	union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+	union cvmx_npei_bar1_indexx bar1_index;
 
 	/*
 	 * Make sure we aren't trying to setup a target mode interface
@@ -918,12 +925,30 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
 	/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
 	cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
 
-	/*
-	 * Disable Octeon's BAR1. It isn't needed in RC mode since
-	 * BAR2 maps all of memory. BAR2 also maps 256MB-512MB into
-	 * the 2nd 256MB of memory.
-	 */
-	cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1);
+	/* BAR1 follows BAR2 with a gap. */
+	cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
+
+	bar1_index.u32 = 0;
+	bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
+	bar1_index.s.ca = 1;       /* Not Cached */
+	bar1_index.s.end_swp = 1;  /* Endian Swap mode */
+	bar1_index.s.addr_v = 1;   /* Valid entry */
+
+	base = pcie_port ? 16 : 0;
+
+	/* Big endian swizzle for 32-bit PEXP_NCB register. */
+#ifdef __MIPSEB__
+	addr_swizzle = 4;
+#else
+	addr_swizzle = 0;
+#endif
+	for (i = 0; i < 16; i++) {
+		cvmx_write64_uint32((CVMX_PEXP_NPEI_BAR1_INDEXX(base) ^ addr_swizzle),
+				    bar1_index.u32);
+		base++;
+		/* 256MB / 16 >> 22 == 4 */
+		bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
+	}
 
 	/*
 	 * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
diff --git a/arch/mips/pmc-sierra/Platform b/arch/mips/pmc-sierra/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..f092f2524c5f2b8605d653f854b339adc4b417ad
--- /dev/null
+++ b/arch/mips/pmc-sierra/Platform
@@ -0,0 +1,14 @@
+#
+# PMC-Sierra MSP SOCs
+#
+platform-$(CONFIG_PMC_MSP)	+= pmc-sierra/msp71xx/
+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/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
index 11769b55438c27da2c113da9d21c39e21affa31e..c841f083a7f55644d1d62829591ef26cdf954c15 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -32,9 +32,6 @@
 #include <msp_int.h>
 #include <msp_regs.h>
 #include <msp_regops.h>
-#ifdef CONFIG_PMCTWILED
-#include <msp_led_macros.h>
-#endif
 
 /* For hwbutton_interrupt->initial_state */
 #define HWBUTTON_HI	0x1
@@ -82,10 +79,6 @@ static void standby_on(void *data)
 	printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
 
 	/* TODO: Put board in standby mode */
-#ifdef CONFIG_PMCTWILED
-	msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN);
-	msp_led_turn_on(MSP_LED_PWRSTANDBY_RED);
-#endif
 }
 
 static void standby_off(void *data)
@@ -94,10 +87,6 @@ static void standby_off(void *data)
 		"STANDBY switch was set to OFF (not implemented)\n");
 
 	/* TODO: Take out of standby mode */
-#ifdef CONFIG_PMCTWILED
-	msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN);
-	msp_led_turn_off(MSP_LED_PWRSTANDBY_RED);
-#endif
 }
 
 static struct hwbutton_interrupt softreset_sw = {
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
index 5aec4057314e40e34eab6713b5b37fde5547faa8..86b98e98fb4f2f09906a8ee271550e1ab9b961c9 100644
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -35,18 +35,17 @@
  */
 void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
 {
-        struct pci_bus *current_bus = bus;
-        struct pci_dev *devices;
-        struct list_head *devices_link;
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
 
 	list_for_each(devices_link, &(current_bus->devices)) {
-                devices = pci_dev_b(devices_link);
-                if (devices == NULL)
-                        continue;
+		devices = pci_dev_b(devices_link);
+		if (devices == NULL)
+			continue;
 	}
 
 	/*
 	 * PLX and SPKT related changes go here
 	 */
-
 }
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
index 51021cfd04bc1de986912be4346da35cba7df1dd..25bbbf428be940917b35cd518139c072918264f0 100644
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -150,8 +150,4 @@ void __init arch_init_irq(void)
 	mips_cpu_irq_init();
 	rm7k_cpu_irq_init();
 	rm9k_cpu_irq_init();
-
-#ifdef CONFIG_GDB_CONSOLE
-	register_gdb_console();
-#endif
 }
diff --git a/arch/mips/pnx833x/Makefile b/arch/mips/pnx833x/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..02c4698cab05332b211fff3f06777aad473345e4
--- /dev/null
+++ b/arch/mips/pnx833x/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX833X)	+= common/
+obj-$(CONFIG_NXP_STB220)	+= stb22x/
+obj-$(CONFIG_NXP_STB225)	+= stb22x/
diff --git a/arch/mips/pnx833x/Platform b/arch/mips/pnx833x/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..7e6ec4dbc8ddb16b769f90b02601e4625a1ad162
--- /dev/null
+++ b/arch/mips/pnx833x/Platform
@@ -0,0 +1,5 @@
+# NXP STB225
+platform-$(CONFIG_SOC_PNX833X)	+= pnx833x/
+cflags-$(CONFIG_SOC_PNX833X)    += -Iarch/mips/include/asm/mach-pnx833x
+load-$(CONFIG_NXP_STB220)	+= 0xffffffff80001000
+load-$(CONFIG_NXP_STB225)	+= 0xffffffff80001000
diff --git a/arch/mips/nxp/pnx833x/common/Makefile b/arch/mips/pnx833x/common/Makefile
similarity index 69%
rename from arch/mips/nxp/pnx833x/common/Makefile
rename to arch/mips/pnx833x/common/Makefile
index 4a16f3b503b55b0919b7fe12422396c5d0f5560f..1a46dd291b16d3cfc193ae0df59d18de1ac67c80 100644
--- a/arch/mips/nxp/pnx833x/common/Makefile
+++ b/arch/mips/pnx833x/common/Makefile
@@ -1,3 +1 @@
 obj-y := interrupts.o platform.o prom.o setup.o reset.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/common/interrupts.c
rename to arch/mips/pnx833x/common/interrupts.c
diff --git a/arch/mips/nxp/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/common/platform.c
rename to arch/mips/pnx833x/common/platform.c
diff --git a/arch/mips/nxp/pnx833x/common/prom.c b/arch/mips/pnx833x/common/prom.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/common/prom.c
rename to arch/mips/pnx833x/common/prom.c
diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/common/reset.c
rename to arch/mips/pnx833x/common/reset.c
diff --git a/arch/mips/nxp/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/common/setup.c
rename to arch/mips/pnx833x/common/setup.c
diff --git a/arch/mips/pnx833x/stb22x/Makefile b/arch/mips/pnx833x/stb22x/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7b580060de50f02ec34cb0881433bddd2e5390aa
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/Makefile
@@ -0,0 +1 @@
+obj-y := board.o
diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c
similarity index 100%
rename from arch/mips/nxp/pnx833x/stb22x/board.c
rename to arch/mips/pnx833x/stb22x/board.c
diff --git a/arch/mips/pnx8550/Makefile b/arch/mips/pnx8550/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3f7e8561437bce14d8e2dc4cb0ee5cc9bdd3f66c
--- /dev/null
+++ b/arch/mips/pnx8550/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX8550)	+= common/
+obj-$(CONFIG_PNX8550_JBS)	+= jbs/
+obj-$(CONFIG_PNX8550_STB810)	+= stb810/
diff --git a/arch/mips/pnx8550/Platform b/arch/mips/pnx8550/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..0e7fbde768d505a8002ff7528483cb798f640697
--- /dev/null
+++ b/arch/mips/pnx8550/Platform
@@ -0,0 +1,7 @@
+platform-$(CONFIG_SOC_PNX8550)	+= pnx8550/
+
+cflags-$(CONFIG_SOC_PNX8550)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-pnx8550
+
+load-$(CONFIG_PNX8550_JBS)	+= 0xffffffff80060000
+load-$(CONFIG_PNX8550_STB810)	+= 0xffffffff80060000
diff --git a/arch/mips/nxp/pnx8550/common/Makefile b/arch/mips/pnx8550/common/Makefile
similarity index 97%
rename from arch/mips/nxp/pnx8550/common/Makefile
rename to arch/mips/pnx8550/common/Makefile
index dd9e7b1f7fd34f7e9d3bfb0d16bd91b0e8e02f8a..f8ce695dc54ff98cf679cabfd13e51b53323e0ab 100644
--- a/arch/mips/nxp/pnx8550/common/Makefile
+++ b/arch/mips/pnx8550/common/Makefile
@@ -24,5 +24,3 @@
 
 obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
 obj-$(CONFIG_PCI) += pci.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/int.c
rename to arch/mips/pnx8550/common/int.c
diff --git a/arch/mips/pnx8550/common/pci.c b/arch/mips/pnx8550/common/pci.c
new file mode 100644
index 0000000000000000000000000000000000000000..98e86ddb86ccd6e07766d53a04998d7f3a413cc4
--- /dev/null
+++ b/arch/mips/pnx8550/common/pci.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * Author: source@mvista.com
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  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.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <pci.h>
+#include <glb.h>
+#include <nand.h>
+
+static struct resource pci_io_resource = {
+	.start	= PNX8550_PCIIO + 0x1000,	/* reserve regacy I/O space */
+	.end	= PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
+	.name	= "pci IO space",
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	.start	= PNX8550_PCIMEM,
+	.end	= PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
+	.name	= "pci memory space",
+	.flags	= IORESOURCE_MEM
+};
+
+extern struct pci_ops pnx8550_pci_ops;
+
+static struct pci_controller pnx8550_controller = {
+	.pci_ops	= &pnx8550_pci_ops,
+	.io_map_base	= PNX8550_PORT_BASE,
+	.io_resource	= &pci_io_resource,
+	.mem_resource	= &pci_mem_resource,
+};
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+static inline unsigned long get_system_mem_size(void)
+{
+	/* Read IP2031_RANK0_ADDR_LO */
+	unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+	/* Read IP2031_RANK1_ADDR_HI */
+	unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+	return dram_r1_hi - dram_r0_lo + 1;
+}
+
+static int __init pnx8550_pci_setup(void)
+{
+	int pci_mem_code;
+	int mem_size = get_system_mem_size() >> 20;
+
+	/* Clear the Global 2 Register, PCI Inta Output Enable Registers
+	   Bit 1:Enable DAC Powerdown
+	  -> 0:DACs are enabled and are working normally
+	     1:DACs are powerdown
+	   Bit 0:Enable of PCI inta output
+	  -> 0 = Disable PCI inta output
+	     1 = Enable PCI inta output
+	*/
+	PNX8550_GLB2_ENAB_INTA_O = 0;
+
+	/* Calc the PCI mem size code */
+	if (mem_size >= 128)
+		pci_mem_code = SIZE_128M;
+	else if (mem_size >= 64)
+		pci_mem_code = SIZE_64M;
+	else if (mem_size >= 32)
+		pci_mem_code = SIZE_32M;
+	else
+		pci_mem_code = SIZE_16M;
+
+	/* Set PCI_XIO registers */
+	outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
+	outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
+	outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
+	outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
+
+	/* Send memory transaction via PCI_BASE2 */
+	outl(0x00000001, PCI_BASE | PCI_IO);
+
+	/* Unlock the setup register */
+	outl(0xca, PCI_BASE | PCI_UNLOCKREG);
+
+	/*
+	 * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
+	 * to work, and in order for bus_to_baddr to work without any
+	 * hacks.
+	 */
+	outl(0x00000000, PCI_BASE | PCI_BASE10);
+
+	/*
+	 *These two bars are set by default or the boot code.
+	 * However, it's safer to set them here so we're not boot
+	 * code dependent.
+	 */
+	outl(0x1be00000, PCI_BASE | PCI_BASE14);  /* PNX MMIO */
+	outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18);  /* XIO      */
+
+	outl(PCI_EN_TA |
+	     PCI_EN_PCI2MMI |
+	     PCI_EN_XIO |
+	     PCI_SETUP_BASE18_SIZE(SIZE_32M) |
+	     PCI_SETUP_BASE18_EN |
+	     PCI_SETUP_BASE14_EN |
+	     PCI_SETUP_BASE10_PREF |
+	     PCI_SETUP_BASE10_SIZE(pci_mem_code) |
+	     PCI_SETUP_CFGMANAGE_EN |
+	     PCI_SETUP_PCIARB_EN,
+	     PCI_BASE |
+	     PCI_SETUP);	/* PCI_SETUP */
+	outl(0x00000000, PCI_BASE | PCI_CTRL);	/* PCI_CONTROL */
+
+	register_pci_controller(&pnx8550_controller);
+
+	return 0;
+}
+
+arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/nxp/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/platform.c
rename to arch/mips/pnx8550/common/platform.c
diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/pnx8550/common/proc.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/proc.c
rename to arch/mips/pnx8550/common/proc.c
diff --git a/arch/mips/nxp/pnx8550/common/prom.c b/arch/mips/pnx8550/common/prom.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/prom.c
rename to arch/mips/pnx8550/common/prom.c
diff --git a/arch/mips/nxp/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/reset.c
rename to arch/mips/pnx8550/common/reset.c
diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..64246c9c875c51d09e5c3861ca0e6f1096d50ac5
--- /dev/null
+++ b/arch/mips/pnx8550/common/setup.c
@@ -0,0 +1,145 @@
+/*
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ *  Based on Per Hallsmark, per.hallsmark@mvista.com
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  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.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/pm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+
+#include <glb.h>
+#include <int.h>
+#include <pci.h>
+#include <uart.h>
+#include <nand.h>
+
+extern void __init board_setup(void);
+extern void pnx8550_machine_restart(char *);
+extern void pnx8550_machine_halt(void);
+extern void pnx8550_machine_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern char *prom_getcmdline(void);
+
+struct resource standard_io_resources[] = {
+	{
+		.start	= 0x00,
+		.end	= 0x1f,
+		.name	= "dma1",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x40,
+		.end	= 0x5f,
+		.name	= "timer",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x80,
+		.end	= 0x8f,
+		.name	= "dma page reg",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0xc0,
+		.end	= 0xdf,
+		.name	= "dma2",
+		.flags	= IORESOURCE_BUSY
+	},
+};
+
+#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+unsigned long get_system_mem_size(void)
+{
+	/* Read IP2031_RANK0_ADDR_LO */
+	unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+	/* Read IP2031_RANK1_ADDR_HI */
+	unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+	return dram_r1_hi - dram_r0_lo + 1;
+}
+
+int pnx8550_console_port = -1;
+
+void __init plat_mem_setup(void)
+{
+	int i;
+	char* argptr;
+
+	board_setup();  /* board specific setup */
+
+        _machine_restart = pnx8550_machine_restart;
+        _machine_halt = pnx8550_machine_halt;
+        pm_power_off = pnx8550_machine_power_off;
+
+	/* Clear the Global 2 Register, PCI Inta Output Enable Registers
+	   Bit 1:Enable DAC Powerdown
+	  -> 0:DACs are enabled and are working normally
+	     1:DACs are powerdown
+	   Bit 0:Enable of PCI inta output
+	  -> 0 = Disable PCI inta output
+	     1 = Enable PCI inta output
+	*/
+	PNX8550_GLB2_ENAB_INTA_O = 0;
+
+	/* IO/MEM resources. */
+	set_io_port_base(PNX8550_PORT_BASE);
+	ioport_resource.start = 0;
+	ioport_resource.end = ~0;
+	iomem_resource.start = 0;
+	iomem_resource.end = ~0;
+
+	/* Request I/O space for devices on this board */
+	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+		request_resource(&ioport_resource, standard_io_resources + i);
+
+	/* Place the Mode Control bit for GPIO pin 16 in primary function */
+	/* Pin 16 is used by UART1, UA1_TX                                */
+	outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
+			(PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
+			PNX8550_GPIO_MC1);
+
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
+		argptr += strlen("console=ttyS");
+		pnx8550_console_port = *argptr == '0' ? 0 : 1;
+
+		/* We must initialize the UART (console) before early printk */
+		/* Set LCR to 8-bit and BAUD to 38400 (no 5)                */
+		ip3106_lcr(UART_BASE, pnx8550_console_port) =
+			PNX8XXX_UART_LCR_8BIT;
+		ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
+	}
+
+	return;
+}
diff --git a/arch/mips/nxp/pnx8550/common/time.c b/arch/mips/pnx8550/common/time.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/common/time.c
rename to arch/mips/pnx8550/common/time.c
diff --git a/arch/mips/pnx8550/jbs/Makefile b/arch/mips/pnx8550/jbs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c4dc3d53eb5c712503c70edf908a27514cc519ab
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP JBS Board.
+
+obj-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/jbs/board_setup.c b/arch/mips/pnx8550/jbs/board_setup.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/jbs/board_setup.c
rename to arch/mips/pnx8550/jbs/board_setup.c
diff --git a/arch/mips/nxp/pnx8550/jbs/init.c b/arch/mips/pnx8550/jbs/init.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/jbs/init.c
rename to arch/mips/pnx8550/jbs/init.c
diff --git a/arch/mips/nxp/pnx8550/jbs/irqmap.c b/arch/mips/pnx8550/jbs/irqmap.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/jbs/irqmap.c
rename to arch/mips/pnx8550/jbs/irqmap.c
diff --git a/arch/mips/pnx8550/stb810/Makefile b/arch/mips/pnx8550/stb810/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..cb4ff022f1fbc96890ed0631736a05f242ae293c
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP STB810 Board.
+
+obj-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/stb810/board_setup.c b/arch/mips/pnx8550/stb810/board_setup.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/stb810/board_setup.c
rename to arch/mips/pnx8550/stb810/board_setup.c
diff --git a/arch/mips/nxp/pnx8550/stb810/irqmap.c b/arch/mips/pnx8550/stb810/irqmap.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/stb810/irqmap.c
rename to arch/mips/pnx8550/stb810/irqmap.c
diff --git a/arch/mips/nxp/pnx8550/stb810/prom_init.c b/arch/mips/pnx8550/stb810/prom_init.c
similarity index 100%
rename from arch/mips/nxp/pnx8550/stb810/prom_init.c
rename to arch/mips/pnx8550/stb810/prom_init.c
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
index 0a0d73c0564fa9d4743d6417f73c653ae38b754d..baf6e9092a9f84b941b37986dac89a289b5225a8 100644
--- a/arch/mips/powertv/Makefile
+++ b/arch/mips/powertv/Makefile
@@ -23,6 +23,9 @@
 # under Linux.
 #
 
-obj-y += init.o memory.o reset.o time.o powertv_setup.o asic/ pci/
+obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \
+	asic/ pci/
 
-EXTRA_CFLAGS += -Wall -Werror
+obj-$(CONFIG_USB) += powertv-usb.o
+
+EXTRA_CFLAGS += -Wall
diff --git a/arch/mips/powertv/Platform b/arch/mips/powertv/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..4eb5af1d8eea8bb21333659a46b2141a74c29843
--- /dev/null
+++ b/arch/mips/powertv/Platform
@@ -0,0 +1,7 @@
+#
+# Cisco PowerTV Platform
+#
+platform-$(CONFIG_POWERTV)	+= powertv/
+cflags-$(CONFIG_POWERTV)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-powertv
+load-$(CONFIG_POWERTV)		+= 0xffffffff90800000
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
index bebfdcff0443ef5f3b3dfd8a0c9dffabdb8707cc..f0e95dc0ac97b4f63e924f3ae4387eb49e73199b 100644
--- a/arch/mips/powertv/asic/Makefile
+++ b/arch/mips/powertv/asic/Makefile
@@ -16,8 +16,8 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-obj-y += asic-calliope.o asic-cronus.o asic-zeus.o asic_devices.o asic_int.o \
-	 irq_asic.o prealloc-calliope.o prealloc-cronus.o \
-	 prealloc-cronuslite.o prealloc-zeus.o
+obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \
+	asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \
+	prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o
 
 EXTRA_CFLAGS += -Wall -Werror
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
index 1ae6623444b2d5c6d3cf21f51c47b58f17f83224..0a170e0ffeaae4ea84e0d5bfe1480203e69524be 100644
--- a/arch/mips/powertv/asic/asic-calliope.c
+++ b/arch/mips/powertv/asic/asic-calliope.c
@@ -77,7 +77,7 @@ const struct register_map calliope_register_map __initdata = {
 	.int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
 
 	.mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
-	.usb_fs = {.phys = CALLIOPE_ADDR(0x980030)},
+	.fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)},
 	.test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
 	.crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
 	.usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
index 5bb64bfb508b1e83e5f81dab74351d76d9413639..bbc0c122be5ee34c3ece4cb2fdee9ddf8efef384 100644
--- a/arch/mips/powertv/asic/asic-cronus.c
+++ b/arch/mips/powertv/asic/asic-cronus.c
@@ -77,13 +77,13 @@ const struct register_map cronus_register_map __initdata = {
 	.int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
 
 	.mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
-	.usb_fs = {.phys = CRONUS_ADDR(0x1C0018)},
+	.fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)},
 	.test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
 	.crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
 	.usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
 	.usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
 	.ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
-	.ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)},
+	.ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)},
 	.bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
 	.usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
 	.usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c
new file mode 100644
index 0000000000000000000000000000000000000000..91dda682752ce25ece90b800a9103bb33cd80c86
--- /dev/null
+++ b/arch/mips/powertv/asic/asic-gaia.c
@@ -0,0 +1,96 @@
+/*
+ * Locations of devices in the Gaia ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       David VomLehn
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+const struct register_map gaia_register_map __initdata = {
+	.eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000},
+	.eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038},
+	.eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C},
+
+	.chipver3 = {.phys = GAIA_IO_BASE + 0x2A0800},
+	.chipver2 = {.phys = GAIA_IO_BASE + 0x2A0804},
+	.chipver1 = {.phys = GAIA_IO_BASE + 0x2A0808},
+	.chipver0 = {.phys = GAIA_IO_BASE + 0x2A080C},
+
+	/* The registers of IRBlaster */
+	.uart1_intstat = {.phys = GAIA_IO_BASE + 0x2A1800},
+	.uart1_inten = {.phys = GAIA_IO_BASE + 0x2A1804},
+	.uart1_config1 = {.phys = GAIA_IO_BASE + 0x2A1808},
+	.uart1_config2 = {.phys = GAIA_IO_BASE + 0x2A180C},
+	.uart1_divisorhi = {.phys = GAIA_IO_BASE + 0x2A1810},
+	.uart1_divisorlo = {.phys = GAIA_IO_BASE + 0x2A1814},
+	.uart1_data = {.phys = GAIA_IO_BASE + 0x2A1818},
+	.uart1_status = {.phys = GAIA_IO_BASE + 0x2A181C},
+
+	.int_stat_3 = {.phys = GAIA_IO_BASE + 0x2A2800},
+	.int_stat_2 = {.phys = GAIA_IO_BASE + 0x2A2804},
+	.int_stat_1 = {.phys = GAIA_IO_BASE + 0x2A2808},
+	.int_stat_0 = {.phys = GAIA_IO_BASE + 0x2A280C},
+	.int_config = {.phys = GAIA_IO_BASE + 0x2A2810},
+	.int_int_scan = {.phys = GAIA_IO_BASE + 0x2A2818},
+	.ien_int_3 = {.phys = GAIA_IO_BASE + 0x2A2830},
+	.ien_int_2 = {.phys = GAIA_IO_BASE + 0x2A2834},
+	.ien_int_1 = {.phys = GAIA_IO_BASE + 0x2A2838},
+	.ien_int_0 = {.phys = GAIA_IO_BASE + 0x2A283C},
+	.int_level_3_3 = {.phys = GAIA_IO_BASE + 0x2A2880},
+	.int_level_3_2 = {.phys = GAIA_IO_BASE + 0x2A2884},
+	.int_level_3_1 = {.phys = GAIA_IO_BASE + 0x2A2888},
+	.int_level_3_0 = {.phys = GAIA_IO_BASE + 0x2A288C},
+	.int_level_2_3 = {.phys = GAIA_IO_BASE + 0x2A2890},
+	.int_level_2_2 = {.phys = GAIA_IO_BASE + 0x2A2894},
+	.int_level_2_1 = {.phys = GAIA_IO_BASE + 0x2A2898},
+	.int_level_2_0 = {.phys = GAIA_IO_BASE + 0x2A289C},
+	.int_level_1_3 = {.phys = GAIA_IO_BASE + 0x2A28A0},
+	.int_level_1_2 = {.phys = GAIA_IO_BASE + 0x2A28A4},
+	.int_level_1_1 = {.phys = GAIA_IO_BASE + 0x2A28A8},
+	.int_level_1_0 = {.phys = GAIA_IO_BASE + 0x2A28AC},
+	.int_level_0_3 = {.phys = GAIA_IO_BASE + 0x2A28B0},
+	.int_level_0_2 = {.phys = GAIA_IO_BASE + 0x2A28B4},
+	.int_level_0_1 = {.phys = GAIA_IO_BASE + 0x2A28B8},
+	.int_level_0_0 = {.phys = GAIA_IO_BASE + 0x2A28BC},
+	.int_docsis_en = {.phys = GAIA_IO_BASE + 0x2A28F4},
+
+	.mips_pll_setup = {.phys = GAIA_IO_BASE + 0x1C0000},
+	.fs432x4b4_usb_ctl = {.phys = GAIA_IO_BASE + 0x1C0024},
+	.test_bus = {.phys = GAIA_IO_BASE + 0x1C00CC},
+	.crt_spare = {.phys = GAIA_IO_BASE + 0x1c0108},
+	.usb2_ohci_int_mask = {.phys = GAIA_IO_BASE + 0x20000C},
+	.usb2_strap = {.phys = GAIA_IO_BASE + 0x200014},
+	.ehci_hcapbase = {.phys = GAIA_IO_BASE + 0x21FE00},
+	.ohci_hc_revision = {.phys = GAIA_IO_BASE + 0x21fc00},
+	.bcm1_bs_lmi_steer = {.phys = GAIA_IO_BASE + 0x2E0004},
+	.usb2_control = {.phys = GAIA_IO_BASE + 0x2E004C},
+	.usb2_stbus_obc = {.phys = GAIA_IO_BASE + 0x21FF00},
+	.usb2_stbus_mess_size = {.phys = GAIA_IO_BASE + 0x21FF04},
+	.usb2_stbus_chunk_size = {.phys = GAIA_IO_BASE + 0x21FF08},
+
+	.pcie_regs = {.phys = GAIA_IO_BASE + 0x220000},
+	.tim_ch = {.phys = GAIA_IO_BASE + 0x2A2C10},
+	.tim_cl = {.phys = GAIA_IO_BASE + 0x2A2C14},
+	.gpio_dout = {.phys = GAIA_IO_BASE + 0x2A2C20},
+	.gpio_din = {.phys = GAIA_IO_BASE + 0x2A2C24},
+	.gpio_dir = {.phys = GAIA_IO_BASE + 0x2A2C2C},
+	.watchdog = {.phys = GAIA_IO_BASE + 0x2A2C30},
+	.front_panel = {.phys = GAIA_IO_BASE + 0x2A3800},
+};
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
index 095cbe10ebb90e92833ea4517df7bec9c81f3f21..4a05bb096476a1ef7751f528c16d9ea9015827a9 100644
--- a/arch/mips/powertv/asic/asic-zeus.c
+++ b/arch/mips/powertv/asic/asic-zeus.c
@@ -77,7 +77,7 @@ const struct register_map zeus_register_map __initdata = {
 	.int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
 
 	.mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
-	.usb_fs = {.phys = ZEUS_ADDR(0x1a0018)},
+	.fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)},
 	.test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
 	.crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
 	.usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
index 9ec523e4dd060afb93ebd5fea93c07450daf933f..e56fa61b39916a8e869350f715ee4d169c37f122 100644
--- a/arch/mips/powertv/asic/asic_devices.c
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -1,7 +1,6 @@
 /*
- *                   ASIC Device List Intialization
  *
- * Description:  Defines the platform resources for the SA settop.
+ * Description:  Defines the platform resources for Gaia-based settops.
  *
  * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
  *
@@ -19,11 +18,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  *
- * Author:       Ken Eppinett
- *               David Schleef <ds@schleef.org>
- *
- * Description:  Defines the platform resources for the SA settop.
- *
  * NOTE: The bootloader allocates persistent memory at an address which is
  * 16 MiB below the end of the highest address in KSEG0. All fixed
  * address memory reservations must avoid this region.
@@ -39,7 +33,6 @@
 #include <linux/mm.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
-#include <linux/gfp.h>
 #include <asm/page.h>
 #include <linux/swap.h>
 #include <linux/highmem.h>
@@ -74,14 +67,13 @@ unsigned long asic_phy_base;
 unsigned long asic_base;
 EXPORT_SYMBOL(asic_base);			/* Exported for testing */
 struct resource *gp_resources;
-static bool usb_configured;
 
 /*
  * Don't recommend to use it directly, it is usually used by kernel internally.
  * Portable code should be using interfaces such as ioremp, dma_map_single, etc.
  */
-unsigned long phys_to_bus_offset;
-EXPORT_SYMBOL(phys_to_bus_offset);
+unsigned long phys_to_dma_offset;
+EXPORT_SYMBOL(phys_to_dma_offset);
 
 /*
  *
@@ -96,102 +88,20 @@ struct resource asic_resource = {
 	.flags = IORESOURCE_MEM,
 };
 
-/*
- *
- * USB Host Resource Definition
- *
- */
-
-static struct resource ehci_resources[] = {
-	{
-		.parent = &asic_resource,
-		.start  = 0,
-		.end    = 0xff,
-		.flags  = IORESOURCE_MEM,
-	},
-	{
-		.start  = irq_usbehci,
-		.end    = irq_usbehci,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static u64 ehci_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device ehci_device = {
-	.name = "powertv-ehci",
-	.id = 0,
-	.num_resources = 2,
-	.resource = ehci_resources,
-	.dev = {
-		.dma_mask = &ehci_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-static struct resource ohci_resources[] = {
-	{
-		.parent = &asic_resource,
-		.start  = 0,
-		.end    = 0xff,
-		.flags  = IORESOURCE_MEM,
-	},
-	{
-		.start  = irq_usbohci,
-		.end    = irq_usbohci,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static u64 ohci_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device ohci_device = {
-	.name = "powertv-ohci",
-	.id = 0,
-	.num_resources = 2,
-	.resource = ohci_resources,
-	.dev = {
-		.dma_mask = &ohci_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-static struct platform_device *platform_devices[] = {
-	&ehci_device,
-	&ohci_device,
-};
-
-/*
- *
- * Platform Configuration and Device Initialization
- *
- */
-static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3)
-{
-	int en_prg, byp, pwr, nsb, val;
-	int sout;
-
-	sout = 1;
-	en_prg = 1;
-	byp = 0;
-	nsb = 1;
-	pwr = 1;
-
-	val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) |
-		(nsb<<1) | (disable_div_by_3<<5));
-
-	asic_write(val, usb_fs);
-	asic_write(val | (en_prg<<4), usb_fs);
-	asic_write(val | (en_prg<<4) | pwr, usb_fs);
-}
-
 /*
  * Allow override of bootloader-specified model
+ * Returns zero on success, a negative errno value on failure.  This parameter
+ * allows overriding of the bootloader-specified model.
  */
 static char __initdata cmdline[COMMAND_LINE_SIZE];
 
 #define	FORCEFAMILY_PARAM	"forcefamily"
 
+/*
+ * check_forcefamily - check for, and parse, forcefamily command line parameter
+ * @forced_family:	Pointer to two-character array in which to store the
+ *			value of the forcedfamily parameter, if any.
+ */
 static __init int check_forcefamily(unsigned char forced_family[2])
 {
 	const char *p;
@@ -231,14 +141,10 @@ static __init int check_forcefamily(unsigned char forced_family[2])
  */
 static __init noinline void platform_set_family(void)
 {
-#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
-
 	unsigned char forced_family[2];
 	unsigned short bootldr_family;
 
-	check_forcefamily(forced_family);
-
-	if (forced_family[0] != '\0' && forced_family[1] != '\0')
+	if (check_forcefamily(forced_family) == 0)
 		bootldr_family = BOOTLDRFAMILY(forced_family[0],
 			forced_family[1]);
 	else {
@@ -289,6 +195,9 @@ static __init noinline void platform_set_family(void)
 	case BOOTLDRFAMILY('F', '1'):
 		platform_family = FAMILY_1500VZF;
 		break;
+	case BOOTLDRFAMILY('8', '7'):
+		platform_family = FAMILY_8700;
+		break;
 	default:
 		platform_family = -1;
 	}
@@ -300,25 +209,10 @@ unsigned int platform_get_family(void)
 }
 EXPORT_SYMBOL(platform_get_family);
 
-/*
- * \brief usb_eye_configure() for optimizing the USB eye on Calliope.
- *
- * \param     unsigned int value saved to the register.
- *
- * \return    none
- *
- */
-static void __init usb_eye_configure(unsigned int value)
-{
-	asic_write(asic_read(crt_spare) | value, crt_spare);
-}
-
 /*
  * platform_get_asic - determine the ASIC type.
  *
- * \param     none
- *
- * \return    ASIC type; ASIC_UNKNOWN if none
+ * Returns the ASIC type, or ASIC_UNKNOWN if unknown
  *
  */
 enum asic_type platform_get_asic(void)
@@ -328,93 +222,10 @@ enum asic_type platform_get_asic(void)
 EXPORT_SYMBOL(platform_get_asic);
 
 /*
- * platform_configure_usb - usb configuration based on platform type.
- * @bcm1_usb2_ctl:	value for the BCM1_USB2_CTL register, which is
- *			quirky
- */
-static void __init platform_configure_usb(void)
-{
-	u32 bcm1_usb2_ctl;
-
-	if (usb_configured)
-		return;
-
-	switch (asic) {
-	case ASIC_ZEUS:
-	case ASIC_CRONUS:
-	case ASIC_CRONUSLITE:
-		fs_update(0x0000, 0x11, 0x02, 0);
-		bcm1_usb2_ctl = 0x803;
-		break;
-
-	case ASIC_CALLIOPE:
-		fs_update(0x0000, 0x11, 0x02, 1);
-
-		switch (platform_family) {
-		case FAMILY_1500VZE:
-			break;
-
-		case FAMILY_1500VZF:
-			usb_eye_configure(0x003c0000);
-			break;
-
-		default:
-			usb_eye_configure(0x00300000);
-			break;
-		}
-
-		bcm1_usb2_ctl = 0x803;
-		break;
-
-	default:
-		pr_err("Unknown ASIC type: %d\n", asic);
-		break;
-	}
-
-	/* turn on USB power */
-	asic_write(0, usb2_strap);
-	/* Enable all OHCI interrupts */
-	asic_write(bcm1_usb2_ctl, usb2_control);
-	/* USB2_STBUS_OBC store32/load32 */
-	asic_write(3, usb2_stbus_obc);
-	/* USB2_STBUS_MESS_SIZE 2 packets */
-	asic_write(1, usb2_stbus_mess_size);
-	/* USB2_STBUS_CHUNK_SIZE 2 packets */
-	asic_write(1, usb2_stbus_chunk_size);
-
-	usb_configured = true;
-}
-
-/*
- * Set up the USB EHCI interface
+ * set_register_map - set ASIC register configuration
+ * @phys_base:	Physical address of the base of the ASIC registers
+ * @map:	Description of key ASIC registers
  */
-void platform_configure_usb_ehci()
-{
-	platform_configure_usb();
-}
-
-/*
- * Set up the USB OHCI interface
- */
-void platform_configure_usb_ohci()
-{
-	platform_configure_usb();
-}
-
-/*
- * Shut the USB EHCI interface down--currently a NOP
- */
-void platform_unconfigure_usb_ehci()
-{
-}
-
-/*
- * Shut the USB OHCI interface down--currently a NOP
- */
-void platform_unconfigure_usb_ohci()
-{
-}
-
 static void __init set_register_map(unsigned long phys_base,
 	const struct register_map *map)
 {
@@ -526,6 +337,15 @@ void __init configure_platform(void)
 			"DVR_CAPABLE\n");
 		break;
 
+	case FAMILY_8700:
+		platform_features = FFS_CAPABLE | PCIE_CAPABLE;
+		asic = ASIC_GAIA;
+		set_register_map(GAIA_IO_BASE, &gaia_register_map);
+		gp_resources = dvr_gaia_resources;
+
+		pr_info("Platform: 8700 - GAIA, DVR_CAPABLE\n");
+		break;
+
 	default:
 		pr_crit("Platform:  UNKNOWN PLATFORM\n");
 		break;
@@ -533,10 +353,10 @@ void __init configure_platform(void)
 
 	switch (asic) {
 	case ASIC_ZEUS:
-		phys_to_bus_offset = 0x30000000;
+		phys_to_dma_offset = 0x30000000;
 		break;
 	case ASIC_CALLIOPE:
-		phys_to_bus_offset = 0x10000000;
+		phys_to_dma_offset = 0x10000000;
 		break;
 	case ASIC_CRONUSLITE:
 		/* Fall through */
@@ -546,42 +366,16 @@ void __init configure_platform(void)
 		 * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
 		 * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
 		 */
-		phys_to_bus_offset = 0x10000000;
+		phys_to_dma_offset = 0x10000000;
 		break;
 	default:
-		phys_to_bus_offset = 0x00000000;
+		phys_to_dma_offset = 0x00000000;
 		break;
 	}
 }
 
-/**
- * platform_devices_init - sets up USB device resourse.
- */
-static int __init platform_devices_init(void)
-{
-	pr_notice("%s: ----- Initializing USB resources -----\n", __func__);
-
-	asic_resource.start = asic_phy_base;
-	asic_resource.end += asic_resource.start;
-
-	ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
-	ehci_resources[0].end += ehci_resources[0].start;
-
-	ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
-	ohci_resources[0].end += ohci_resources[0].start;
-
-	set_io_port_base(0);
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-
-	return 0;
-}
-
-arch_initcall(platform_devices_init);
-
 /*
- *
- * BOOTMEM ALLOCATION
+ * RESOURCE ALLOCATION
  *
  */
 /*
@@ -603,7 +397,7 @@ void __init platform_alloc_bootmem(void)
 		int size = gp_resources[i].end - gp_resources[i].start + 1;
 		if ((gp_resources[i].start != 0) &&
 			((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
-			reserve_bootmem(bus_to_phys(gp_resources[i].start),
+			reserve_bootmem(dma_to_phys(gp_resources[i].start),
 				size, 0);
 			total += gp_resources[i].end -
 				gp_resources[i].start + 1;
@@ -627,7 +421,7 @@ void __init platform_alloc_bootmem(void)
 
 			else {
 				gp_resources[i].start =
-					phys_to_bus(virt_to_phys(mem));
+					phys_to_dma(virt_to_phys(mem));
 				gp_resources[i].end =
 					gp_resources[i].start + size - 1;
 				total += size;
@@ -691,7 +485,7 @@ static void __init pmem_setup_resource(void)
 	if (resource && pmemaddr && pmemlen) {
 		/* The address provided by bootloader is in kseg0. Convert to
 		 * a bus address. */
-		resource->start = phys_to_bus(pmemaddr - 0x80000000);
+		resource->start = phys_to_dma(pmemaddr - 0x80000000);
 		resource->end = resource->start + pmemlen - 1;
 
 		pr_info("persistent memory: start=0x%x  end=0x%x\n",
diff --git a/arch/mips/powertv/asic/prealloc-gaia.c b/arch/mips/powertv/asic/prealloc-gaia.c
new file mode 100644
index 0000000000000000000000000000000000000000..8ac8c7aeb98646df7972791e799b786da8169db6
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-gaia.c
@@ -0,0 +1,589 @@
+/*
+ * Memory pre-allocations for Gaia boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       David VomLehn
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * DVR_CAPABLE GAIA RESOURCES
+ */
+struct resource dvr_gaia_resources[] __initdata = {
+	/*
+	 *
+	 * VIDEO1 / LX1
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x241FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24201FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		.end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231bImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x60000000,
+		.end    = 0x601FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231bMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x60200000,
+		.end    = 0x60201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory2",
+		.start  = 0x60202000,
+		.end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x63580000,
+		.end    = 0x64180000 - 1,  /* 12 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x62000000,
+		.end    = 0x62700000 - 1,	/* 7 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x62700000,
+		.end    = 0x63500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x26000000,
+		.end    = 0x26020000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x00280000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x64AD4000,
+		.end    = 0x64AD5000 - 1,  /* 4 KB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * ITFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "ITFS",
+		.start  = 0x64180000,
+		/* 815,104 bytes each for 2 ITFS partitions. */
+		.end    = 0x6430DFFF,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * AVFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x6430E000,
+		/* (945K * 8) = (128K *3) 5 playbacks / 3 server */
+		.end    = 0x64AD0000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "AvfsFileSys",
+		.start  = 0x64AD0000,
+		.end    = 0x64AD1000 - 1,  /* 4K */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x64AD1000,
+		.end    = 0x64AD3800 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * KAVNET
+	 *    NP Reset Vector - must be of the form xxCxxxxx
+	 *	   NP Image - must be video bank 1
+	 *	   NP IPC - must be video bank 2
+	 */
+	{
+		.name   = "NP_Reset_Vector",
+		.start  = 0x27c00000,
+		.end    = 0x27c01000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_Image",
+		.start  = 0x27020000,
+		.end    = 0x27060000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_IPC",
+		.start  = 0x63500000,
+		.end    = 0x63580000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
+
+/*
+ * NON_DVR_CAPABLE GAIA RESOURCES
+ */
+struct resource non_dvr_gaia_resources[] __initdata = {
+	/*
+	 *
+	 * VIDEO1 / LX1
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x241FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24201FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		.end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231bImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x60000000,
+		.end    = 0x601FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231bMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x60200000,
+		.end    = 0x60201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory2",
+		.start  = 0x60202000,
+		.end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x63580000,
+		.end    = 0x64180000 - 1,  /* 12 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x62000000,
+		.end    = 0x62700000 - 1,	/* 7 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x62700000,
+		.end    = 0x63500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x26000000,
+		.end    = 0x26020000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x64AD4000,
+		.end    = 0x64AD5000 - 1,  /* 4 KB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x6430E000,
+		.end    = 0x645D2C00 - 1,  /* 945K * 3 for playback */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * PMEM
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Persistent memory for diagnostics.
+	 *
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x64AD1000,
+		.end    = 0x64AD3800 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * KAVNET
+	 *    NP Reset Vector - must be of the form xxCxxxxx
+	 *	   NP Image - must be video bank 1
+	 *	   NP IPC - must be video bank 2
+	 */
+	{
+		.name   = "NP_Reset_Vector",
+		.start  = 0x27c00000,
+		.end    = 0x27c01000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_Image",
+		.start  = 0x27020000,
+		.end    = 0x27060000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_IPC",
+		.start  = 0x63500000,
+		.end    = 0x63580000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	{ },
+};
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
index 0afe227f1d0ac46636d60e2c76fb74a2c24495ca..83552288e8024fa697d11e958272fe01399666e6 100644
--- a/arch/mips/powertv/init.c
+++ b/arch/mips/powertv/init.c
@@ -117,8 +117,10 @@ void __init prom_init(void)
 	board_nmi_handler_setup = mips_nmi_setup;
 	board_ejtag_handler_setup = mips_ejtag_setup;
 
-	if (prom_argc == 1)
+	if (prom_argc == 1) {
+		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 		strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
+	}
 
 	configure_platform();
 	prom_meminit();
diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c
new file mode 100644
index 0000000000000000000000000000000000000000..a77c6f62fe238ccf4e33c6b6784865c2d3a7d2a6
--- /dev/null
+++ b/arch/mips/powertv/ioremap.c
@@ -0,0 +1,136 @@
+/*
+ *			ioremap.c
+ *
+ * Support for mapping between dma_addr_t values a phys_addr_t values.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       David VomLehn <dvomlehn@cisco.com>
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach-powertv/ioremap.h>
+
+/*
+ * Define the sizes of and masks for grains in physical and DMA space. The
+ * values are the same but the types are not.
+ */
+#define IOR_PHYS_GRAIN		((phys_addr_t) 1 << IOR_LSBITS)
+#define IOR_PHYS_GRAIN_MASK	(IOR_PHYS_GRAIN - 1)
+
+#define IOR_DMA_GRAIN		((dma_addr_t) 1 << IOR_LSBITS)
+#define IOR_DMA_GRAIN_MASK	(IOR_DMA_GRAIN - 1)
+
+/*
+ * Values that, when accessed by an index derived from a phys_addr_t and
+ * added to phys_addr_t value, yield a DMA address
+ */
+struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+EXPORT_SYMBOL(_ior_phys_to_dma);
+
+/*
+ * Values that, when accessed by an index derived from a dma_addr_t and
+ * added to that dma_addr_t value, yield a physical address
+ */
+struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+EXPORT_SYMBOL(_ior_dma_to_phys);
+
+/**
+ * setup_dma_to_phys - set up conversion from DMA to physical addresses
+ * @dma_idx:	Top IOR_LSBITS bits of the DMA address, i.e. an index
+ *		into the array _dma_to_phys.
+ * @delta:	Value that, when added to the DMA address, will yield the
+ *		physical address
+ * @s:		Number of bytes in the section of memory with the given delta
+ *		between DMA and physical addresses.
+ */
+static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s)
+{
+	int dma_idx, first_idx, last_idx;
+	phys_addr_t first, last;
+
+	/*
+	 * Calculate the first and last indices, rounding the first up and
+	 * the second down.
+	 */
+	first = dma & ~IOR_DMA_GRAIN_MASK;
+	last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK;
+	first_idx = first >> IOR_LSBITS;		/* Convert to indices */
+	last_idx = last >> IOR_LSBITS;
+
+	for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++)
+		_ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT;
+}
+
+/**
+ * setup_phys_to_dma - set up conversion from DMA to physical addresses
+ * @phys_idx:	Top IOR_LSBITS bits of the DMA address, i.e. an index
+ *		into the array _phys_to_dma.
+ * @delta:	Value that, when added to the DMA address, will yield the
+ *		physical address
+ * @s:		Number of bytes in the section of memory with the given delta
+ *		between DMA and physical addresses.
+ */
+static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s)
+{
+	int phys_idx, first_idx, last_idx;
+	phys_addr_t first, last;
+
+	/*
+	 * Calculate the first and last indices, rounding the first up and
+	 * the second down.
+	 */
+	first = phys & ~IOR_PHYS_GRAIN_MASK;
+	last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK;
+	first_idx = first >> IOR_LSBITS;		/* Convert to indices */
+	last_idx = last >> IOR_LSBITS;
+
+	for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++)
+		_ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT;
+}
+
+/**
+ * ioremap_add_map - add to the physical and DMA address conversion arrays
+ * @phys:	Process's view of the address of the start of the memory chunk
+ * @dma:	DMA address of the start of the memory chunk
+ * @size:	Size, in bytes, of the chunk of memory
+ *
+ * NOTE: It might be obvious, but the assumption is that all @size bytes have
+ * the same offset between the physical address and the DMA address.
+ */
+void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size)
+{
+	if (size == 0)
+		return;
+
+	if ((dma & IOR_DMA_GRAIN_MASK) != 0 ||
+		(phys & IOR_PHYS_GRAIN_MASK) != 0 ||
+		(size & IOR_PHYS_GRAIN_MASK) != 0)
+		pr_crit("Memory allocation must be in chunks of 0x%x bytes\n",
+			IOR_PHYS_GRAIN);
+
+	setup_dma_to_phys(dma, phys - dma, size);
+	setup_phys_to_dma(phys, dma - phys, size);
+}
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
index f49eb3d0358b87e7c1fb102a5600acd746ce9af0..73880ad29bc201ddc9870ab5b968f5341583e6c6 100644
--- a/arch/mips/powertv/memory.c
+++ b/arch/mips/powertv/memory.c
@@ -30,28 +30,141 @@
 #include <asm/sections.h>
 
 #include <asm/mips-boards/prom.h>
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/ioremap.h>
 
 #include "init.h"
 
 /* Memory constants */
 #define KIBIBYTE(n)		((n) * 1024)	/* Number of kibibytes */
 #define MEBIBYTE(n)		((n) * KIBIBYTE(1024)) /* Number of mebibytes */
-#define DEFAULT_MEMSIZE		MEBIBYTE(256)	/* If no memsize provided */
-#define LOW_MEM_MAX		MEBIBYTE(252)	/* Max usable low mem */
-#define RES_BOOTLDR_MEMSIZE	MEBIBYTE(1)	/* Memory reserved for bldr */
-#define BOOT_MEM_SIZE		KIBIBYTE(256)	/* Memory reserved for bldr */
-#define PHYS_MEM_START		0x10000000	/* Start of physical memory */
+#define DEFAULT_MEMSIZE		MEBIBYTE(128)	/* If no memsize provided */
 
-char __initdata cmdline[COMMAND_LINE_SIZE];
+#define BLDR_SIZE	KIBIBYTE(256)		/* Memory reserved for bldr */
+#define RV_SIZE		MEBIBYTE(4)		/* Size of reset vector */
 
-void __init prom_meminit(void)
+#define LOW_MEM_END	0x20000000		/* Highest low memory address */
+#define BLDR_ALIAS	0x10000000		/* Bootloader address */
+#define RV_PHYS		0x1fc00000		/* Reset vector address */
+#define LOW_RAM_END	RV_PHYS			/* End of real RAM in low mem */
+
+/*
+ * Very low-level conversion from processor physical address to device
+ * DMA address for the first bank of memory.
+ */
+#define PHYS_TO_DMA(paddr)	((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS))
+
+unsigned long ptv_memsize;
+
+/*
+ * struct low_mem_reserved - Items in low memmory that are reserved
+ * @start:	Physical address of item
+ * @size:	Size, in bytes, of this item
+ * @is_aliased:	True if this is RAM aliased from another location. If false,
+ *		it is something other than aliased RAM and the RAM in the
+ *		unaliased address is still visible outside of low memory.
+ */
+struct low_mem_reserved {
+	phys_addr_t	start;
+	phys_addr_t	size;
+	bool		is_aliased;
+};
+
+/*
+ * Must be in ascending address order
+ */
+struct low_mem_reserved low_mem_reserved[] = {
+	{BLDR_ALIAS, BLDR_SIZE, true},	/* Bootloader RAM */
+	{RV_PHYS, RV_SIZE, false},	/* Reset vector */
+};
+
+/*
+ * struct mem_layout - layout of a piece of the system RAM
+ * @phys:	Physical address of the start of this piece of RAM. This is the
+ *		address at which both the processor and I/O devices see the
+ *		RAM.
+ * @alias:	Alias of this piece of memory in order to make it appear in
+ *		the low memory part of the processor's address space. I/O
+ *		devices don't see anything here.
+ * @size:	Size, in bytes, of this piece of RAM
+ */
+struct mem_layout {
+	phys_addr_t	phys;
+	phys_addr_t	alias;
+	phys_addr_t	size;
+};
+
+/*
+ * struct mem_layout_list - list descriptor for layouts of system RAM pieces
+ * @family:	Specifies the family being described
+ * @n:		Number of &struct mem_layout elements
+ * @layout:	Pointer to the list of &mem_layout structures
+ */
+struct mem_layout_list {
+	enum family_type	family;
+	size_t			n;
+	struct mem_layout	*layout;
+};
+
+static struct mem_layout f1500_layout[] = {
+	{0x20000000, 0x10000000, MEBIBYTE(256)},
+};
+
+static struct mem_layout f4500_layout[] = {
+	{0x40000000, 0x10000000, MEBIBYTE(256)},
+	{0x20000000, 0x20000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout f8500_layout[] = {
+	{0x40000000, 0x10000000, MEBIBYTE(256)},
+	{0x20000000, 0x20000000, MEBIBYTE(32)},
+	{0x30000000, 0x30000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout fx600_layout[] = {
+	{0x20000000, 0x10000000, MEBIBYTE(256)},
+	{0x60000000, 0x60000000, MEBIBYTE(128)},
+};
+
+static struct mem_layout_list layout_list[] = {
+	{FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout},
+	{FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout},
+	{FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout},
+	{FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout},
+	{FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout},
+	{FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout},
+	{FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout},
+	{FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout},
+	{FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout},
+	{FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout},
+};
+
+/* If we can't determine the layout, use this */
+static struct mem_layout default_layout[] = {
+	{0x20000000, 0x10000000, MEBIBYTE(128)},
+};
+
+/**
+ * register_non_ram - register low memory not available for RAM usage
+ */
+static __init void register_non_ram(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++)
+		add_memory_region(low_mem_reserved[i].start,
+			low_mem_reserved[i].size, BOOT_MEM_RESERVED);
+}
+
+/**
+ * get_memsize - get the size of memory as a single bank
+ */
+static phys_addr_t get_memsize(void)
 {
+	static char cmdline[COMMAND_LINE_SIZE] __initdata;
+	phys_addr_t memsize = 0;
 	char *memsize_str;
-	unsigned long memsize = 0;
-	unsigned int physend;
 	char *ptr;
-	int low_mem;
-	int high_mem;
 
 	/* Check the command line first for a memsize directive */
 	strcpy(cmdline, arcs_cmdline);
@@ -73,96 +186,156 @@ void __init prom_meminit(void)
 		if (memsize == 0) {
 			if (_prom_memsize != 0) {
 				memsize = _prom_memsize;
-				pr_info("_prom_memsize = 0x%lx\n", memsize);
+				pr_info("_prom_memsize = 0x%x\n", memsize);
 				/* add in memory that the bootloader doesn't
 				 * report */
-				memsize += BOOT_MEM_SIZE;
+				memsize += BLDR_SIZE;
 			} else {
 				memsize = DEFAULT_MEMSIZE;
 				pr_info("Memsize not passed by bootloader, "
-					"defaulting to 0x%lx\n", memsize);
+					"defaulting to 0x%x\n", memsize);
 			}
 		}
 	}
 
-	physend = PFN_ALIGN(&_end) - 0x80000000;
-	if (memsize > LOW_MEM_MAX) {
-		low_mem = LOW_MEM_MAX;
-		high_mem = memsize - low_mem;
-	} else {
-		low_mem = memsize;
-		high_mem = 0;
+	return memsize;
+}
+
+/**
+ * register_low_ram - register an aliased section of RAM
+ * @p:		Alias address of memory
+ * @n:		Number of bytes in this section of memory
+ *
+ * Returns the number of bytes registered
+ *
+ */
+static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n)
+{
+	phys_addr_t s;
+	int i;
+	phys_addr_t orig_n;
+
+	orig_n = n;
+
+	BUG_ON(p + n > RV_PHYS);
+
+	for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) {
+		phys_addr_t start;
+		phys_addr_t size;
+
+		start = low_mem_reserved[i].start;
+		size = low_mem_reserved[i].size;
+
+		/* Handle memory before this low memory section */
+		if (p < start) {
+			phys_addr_t s;
+			s = min(n, start - p);
+			add_memory_region(p, s, BOOT_MEM_RAM);
+			p += s;
+			n -= s;
+		}
+
+		/* Handle the low memory section itself. If it's aliased,
+		 * we reduce the number of byes left, but if not, the RAM
+		 * is available elsewhere and we don't reduce the number of
+		 * bytes remaining. */
+		if (p == start) {
+			if (low_mem_reserved[i].is_aliased) {
+				s = min(n, size);
+				n -= s;
+				p += s;
+			} else
+				p += n;
+		}
 	}
 
+	return orig_n - n;
+}
+
 /*
- * TODO: We will use the hard code for memory configuration until
- * the bootloader releases their device tree to us.
+ * register_ram - register real RAM
+ * @p:	Address of memory as seen by devices
+ * @alias:	If the memory is seen at an additional address by the processor,
+ *		this will be the address, otherwise it is the same as @p.
+ * @n:		Number of bytes in this section of memory
  */
+static __init void register_ram(phys_addr_t p, phys_addr_t alias,
+	phys_addr_t n)
+{
 	/*
-	 * Add the memory reserved for use by the bootloader to the
-	 * memory map.
-	 */
-	add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
-		BOOT_MEM_RESERVED);
-#ifdef CONFIG_HIGHMEM_256_128
-	/*
-	 * Add memory in low for general use by the kernel and its friends
-	 * (like drivers, applications, etc).
-	 */
-	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
-		LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
-	/*
-	 * Add the memory reserved for reset vector.
-	 */
-	add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
-	/*
-	 * Add the memory reserved.
-	 */
-	add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
-	/*
-	 * Add memory in high for general use by the kernel and its friends
-	 * (like drivers, applications, etc).
-	 *
-	 * 75MB is reserved for devices which are using the memory in high.
-	 */
-	add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
-		BOOT_MEM_RAM);
-#elif defined CONFIG_HIGHMEM_128_128
-	/*
-	 * Add memory in low for general use by the kernel and its friends
-	 * (like drivers, applications, etc).
-	 */
-	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
-		MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
-	/*
-	 * Add the memory reserved.
-	 */
-	add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
-		MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
-	/*
-	 * Add memory in high for general use by the kernel and its friends
-	 * (like drivers, applications, etc).
-	 *
-	 * 75MB is reserved for devices which are using the memory in high.
-	 */
-	add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
-		BOOT_MEM_RAM);
-#else
-	/* Add low memory regions for either:
-	 *   - no-highmemory configuration case -OR-
-	 *   - highmemory "HIGHMEM_LOWBANK_ONLY" case
-	 */
-	/*
-	 * Add memory for general use by the kernel and its friends
-	 * (like drivers, applications, etc).
+	 * If some or all of this memory has an alias, break it into the
+	 * aliased and non-aliased portion.
 	 */
-	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
-		low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+	if (p != alias) {
+		phys_addr_t alias_size;
+		phys_addr_t registered;
+
+		alias_size = min(n, LOW_RAM_END - alias);
+		registered = register_low_ram(alias, alias_size);
+		ioremap_add_map(alias, p, n);
+		n -= registered;
+		p += registered;
+	}
+
+#ifdef CONFIG_HIGHMEM
+	if (n != 0) {
+		add_memory_region(p, n, BOOT_MEM_RAM);
+		ioremap_add_map(p, p, n);
+	}
+#endif
+}
+
+/**
+ * register_address_space - register things in the address space
+ * @memsize:	Number of bytes of RAM installed
+ *
+ * Takes the given number of bytes of RAM and registers as many of the regions,
+ * or partial regions, as it can. So, the default configuration might have
+ * two regions with 256 MiB each. If the memsize passed in on the command line
+ * is 384 MiB, it will register the first region with 256 MiB and the second
+ * with 128 MiB.
+ */
+static __init void register_address_space(phys_addr_t memsize)
+{
+	int i;
+	phys_addr_t size;
+	size_t n;
+	struct mem_layout *layout;
+	enum family_type family;
+
 	/*
-	 * Add the memory reserved for reset vector.
+	 * Register all of the things that aren't available to the kernel as
+	 * memory.
 	 */
-	add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
-#endif
+	register_non_ram();
+
+	/* Find the appropriate memory description */
+	family = platform_get_family();
+
+	for (i = 0; i < ARRAY_SIZE(layout_list); i++) {
+		if (layout_list[i].family == family)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(layout_list)) {
+		n = ARRAY_SIZE(default_layout);
+		layout = default_layout;
+	} else {
+		n = layout_list[i].n;
+		layout = layout_list[i].layout;
+	}
+
+	for (i = 0; memsize != 0 && i < n; i++) {
+		size = min(memsize, layout[i].size);
+		register_ram(layout[i].phys, layout[i].alias, size);
+		memsize -= size;
+	}
+}
+
+void __init prom_meminit(void)
+{
+	ptv_memsize = get_memsize();
+	register_address_space(ptv_memsize);
 }
 
 void __init prom_free_prom_memory(void)
diff --git a/arch/mips/powertv/powertv-usb.c b/arch/mips/powertv/powertv-usb.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ac85cf7aa2069ab640dd172685d8749570db048
--- /dev/null
+++ b/arch/mips/powertv/powertv-usb.c
@@ -0,0 +1,403 @@
+/*
+ *				powertv-usb.c
+ *
+ * Description:  ASIC-specific USB device setup and shutdown
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/interrupts.h>
+
+/* misc_clk_ctl1 values */
+#define MCC1_30MHZ_POWERUP_SELECT	(1 << 14)
+#define MCC1_DIV9			(1 << 13)
+#define MCC1_ETHMIPS_POWERUP_SELECT	(1 << 11)
+#define MCC1_USB_POWERUP_SELECT		(1 << 1)
+#define MCC1_CLOCK108_POWERUP_SELECT	(1 << 0)
+
+/* Possible values for clock select */
+#define MCC1_USB_CLOCK_HIGH_Z		(0 << 4)
+#define MCC1_USB_CLOCK_48MHZ		(1 << 4)
+#define MCC1_USB_CLOCK_24MHZ		(2 << 4)
+#define MCC1_USB_CLOCK_6MHZ		(3 << 4)
+
+#define MCC1_CONFIG	(MCC1_30MHZ_POWERUP_SELECT |		\
+			 MCC1_DIV9 |				\
+			 MCC1_ETHMIPS_POWERUP_SELECT |		\
+			 MCC1_USB_POWERUP_SELECT |		\
+			 MCC1_CLOCK108_POWERUP_SELECT)
+
+/* misc_clk_ctl2 values */
+#define MCC2_GMII_GCLK_TO_PAD		(1 << 31)
+#define MCC2_ETHER125_0_CLOCK_SELECT	(1 << 29)
+#define MCC2_RMII_0_CLOCK_SELECT	(1 << 28)
+#define MCC2_GMII_TX0_CLOCK_SELECT	(1 << 27)
+#define MCC2_GMII_RX0_CLOCK_SELECT	(1 << 26)
+#define MCC2_ETHER125_1_CLOCK_SELECT	(1 << 24)
+#define MCC2_RMII_1_CLOCK_SELECT	(1 << 23)
+#define MCC2_GMII_TX1_CLOCK_SELECT	(1 << 22)
+#define MCC2_GMII_RX1_CLOCK_SELECT	(1 << 21)
+#define MCC2_ETHER125_2_CLOCK_SELECT	(1 << 19)
+#define MCC2_RMII_2_CLOCK_SELECT	(1 << 18)
+#define MCC2_GMII_TX2_CLOCK_SELECT	(1 << 17)
+#define MCC2_GMII_RX2_CLOCK_SELECT	(1 << 16)
+
+#define ETHER_CLK_CONFIG	(MCC2_GMII_GCLK_TO_PAD |	\
+				 MCC2_ETHER125_0_CLOCK_SELECT |	\
+				 MCC2_RMII_0_CLOCK_SELECT |	\
+				 MCC2_GMII_TX0_CLOCK_SELECT |	\
+				 MCC2_GMII_RX0_CLOCK_SELECT |	\
+				 MCC2_ETHER125_1_CLOCK_SELECT |	\
+				 MCC2_RMII_1_CLOCK_SELECT |	\
+				 MCC2_GMII_TX1_CLOCK_SELECT |	\
+				 MCC2_GMII_RX1_CLOCK_SELECT |	\
+				 MCC2_ETHER125_2_CLOCK_SELECT |	\
+				 MCC2_RMII_2_CLOCK_SELECT |	\
+				 MCC2_GMII_TX2_CLOCK_SELECT |	\
+				 MCC2_GMII_RX2_CLOCK_SELECT)
+
+/* misc_clk_ctl2 definitions for Gaia */
+#define FSX4A_REF_SELECT		(1 << 16)
+#define FSX4B_REF_SELECT		(1 << 17)
+#define FSX4C_REF_SELECT		(1 << 18)
+#define DDR_PLL_REF_SELECT		(1 << 19)
+#define MIPS_PLL_REF_SELECT		(1 << 20)
+
+/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */
+#define QAM_FS_SDIV_SHIFT		29
+#define QAM_FS_MD_SHIFT			24
+#define QAM_FS_MD_MASK			0x1f	/* Cut down to 5 bits */
+#define QAM_FS_PE_SHIFT			8
+
+#define QAM_FS_DISABLE_DIVIDE_BY_3		(1 << 5)
+#define QAM_FS_ENABLE_PROGRAM			(1 << 4)
+#define	QAM_FS_ENABLE_OUTPUT			(1 << 3)
+#define	QAM_FS_SELECT_TEST_BYPASS		(1 << 2)
+#define	QAM_FS_DISABLE_DIGITAL_STANDBY		(1 << 1)
+#define QAM_FS_CHOOSE_FS			(1 << 0)
+
+/* Definitions for fs432x4a_ctl register */
+#define QAM_FS_NSDIV_54MHZ			(1 << 2)
+
+/* Definitions for bcm1_usb2_ctl register */
+#define BCM1_USB2_CTL_BISTOK				(1 << 11)
+#define BCM1_USB2_CTL_PORT2_SHIFT_JK			(1 << 7)
+#define BCM1_USB2_CTL_PORT1_SHIFT_JK			(1 << 6)
+#define BCM1_USB2_CTL_PORT2_FAST_EDGE			(1 << 5)
+#define BCM1_USB2_CTL_PORT1_FAST_EDGE			(1 << 4)
+#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH		(1 << 1)
+#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH	(1 << 0)
+
+/* Definitions for crt_spare register */
+#define CRT_SPARE_PORT2_SHIFT_JK			(1 << 21)
+#define CRT_SPARE_PORT1_SHIFT_JK			(1 << 20)
+#define CRT_SPARE_PORT2_FAST_EDGE			(1 << 19)
+#define CRT_SPARE_PORT1_FAST_EDGE			(1 << 18)
+#define CRT_SPARE_DIVIDE_BY_9_FROM_432			(1 << 17)
+#define CRT_SPARE_USB_DIVIDE_BY_9			(1 << 16)
+
+/* Definitions for usb2_stbus_obc register */
+#define USB_STBUS_OBC_STORE32_LOAD32			0x3
+
+/* Definitions for usb2_stbus_mess_size register */
+#define USB2_STBUS_MESS_SIZE_2				0x1	/* 2 packets */
+
+/* Definitions for usb2_stbus_chunk_size register */
+#define USB2_STBUS_CHUNK_SIZE_2				0x1	/* 2 packets */
+
+/* Definitions for usb2_strap register */
+#define USB2_STRAP_HFREQ_SELECT				0x1
+
+/*
+ * USB Host Resource Definition
+ */
+
+static struct resource ehci_resources[] = {
+	{
+		.parent = &asic_resource,
+		.start  = 0,
+		.end    = 0xff,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = irq_usbehci,
+		.end    = irq_usbehci,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = 0xffffffffULL;
+
+static struct platform_device ehci_device = {
+	.name = "powertv-ehci",
+	.id = 0,
+	.num_resources = 2,
+	.resource = ehci_resources,
+	.dev = {
+		.dma_mask = &ehci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+};
+
+static struct resource ohci_resources[] = {
+	{
+		.parent = &asic_resource,
+		.start  = 0,
+		.end    = 0xff,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = irq_usbohci,
+		.end    = irq_usbohci,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ohci_dmamask = 0xffffffffULL;
+
+static struct platform_device ohci_device = {
+	.name = "powertv-ohci",
+	.id = 0,
+	.num_resources = 2,
+	.resource = ohci_resources,
+	.dev = {
+		.dma_mask = &ohci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+};
+
+static unsigned usb_users;
+static DEFINE_SPINLOCK(usb_regs_lock);
+
+/*
+ *
+ * fs_update - set frequency synthesizer for USB
+ * @pe_bits		Phase tap setting
+ * @md_bits		Coarse selector bus for algorithm of phase tap
+ * @sdiv_bits		Output divider setting
+ * @disable_div_by_3	Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero
+ * @standby		Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero
+ *
+ * QAM frequency selection code, which affects the frequency at which USB
+ * runs. The frequency is calculated as:
+ *                             2^15 * ndiv * Fin
+ * Fout = ------------------------------------------------------------
+ *        (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32)))
+ * where:
+ * Fin		54 MHz
+ * ndiv		QAM_FS_NSDIV_54MHZ ? 8 : 16
+ * sdiv		1 << (sdiv_bits + 1)
+ * ipe		Same as pe_bits
+ * md		A five-bit, two's-complement integer (range [-16, 15]), which
+ *		is the lower 5 bits of md_bits.
+ */
+static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits,
+	u32 disable_div_by_3, u32 standby)
+{
+	u32 val;
+
+	val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) |
+		((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) |
+		(pe_bits << QAM_FS_PE_SHIFT) |
+		QAM_FS_ENABLE_OUTPUT |
+		standby |
+		disable_div_by_3);
+	asic_write(val, fs432x4b4_usb_ctl);
+	asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl);
+	asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS,
+		fs432x4b4_usb_ctl);
+}
+
+/*
+ * usb_eye_configure - for optimizing the shape USB eye waveform
+ * @set:	Bits to set in the register
+ * @clear:	Bits to clear in the register; each bit with a one will
+ *		be set in the register, zero bits will not be modified
+ */
+static void usb_eye_configure(u32 set, u32 clear)
+{
+	u32 old;
+
+	old = asic_read(crt_spare);
+	old |= set;
+	old &= ~clear;
+	asic_write(old, crt_spare);
+}
+
+/*
+ * platform_configure_usb - usb configuration based on platform type.
+ */
+static void platform_configure_usb(void)
+{
+	u32 bcm1_usb2_ctl_value;
+	enum asic_type asic_type;
+	unsigned long flags;
+
+	spin_lock_irqsave(&usb_regs_lock, flags);
+	usb_users++;
+
+	if (usb_users != 1) {
+		spin_unlock_irqrestore(&usb_regs_lock, flags);
+		return;
+	}
+
+	asic_type = platform_get_asic();
+
+	switch (asic_type) {
+	case ASIC_ZEUS:
+		fs_update(0x0000, -15, 0x02, 0, 0);
+		bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+		break;
+
+	case ASIC_CRONUS:
+	case ASIC_CRONUSLITE:
+		usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9);
+		fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
+			QAM_FS_DISABLE_DIGITAL_STANDBY);
+		bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+		break;
+
+	case ASIC_CALLIOPE:
+		fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3,
+			QAM_FS_DISABLE_DIGITAL_STANDBY);
+
+		switch (platform_get_family()) {
+		case FAMILY_1500VZE:
+			break;
+
+		case FAMILY_1500VZF:
+			usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
+				CRT_SPARE_PORT1_SHIFT_JK |
+				CRT_SPARE_PORT2_FAST_EDGE |
+				CRT_SPARE_PORT1_FAST_EDGE, 0);
+			break;
+
+		default:
+			usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
+				CRT_SPARE_PORT1_SHIFT_JK, 0);
+			break;
+		}
+
+		bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
+			BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+		break;
+
+	case ASIC_GAIA:
+		fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
+			QAM_FS_DISABLE_DIGITAL_STANDBY);
+		bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
+			BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+		break;
+
+	default:
+		pr_err("Unknown ASIC type: %d\n", asic_type);
+		bcm1_usb2_ctl_value = 0;
+		break;
+	}
+
+	/* turn on USB power */
+	asic_write(0, usb2_strap);
+	/* Enable all OHCI interrupts */
+	asic_write(bcm1_usb2_ctl_value, usb2_control);
+	/* usb2_stbus_obc store32/load32 */
+	asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc);
+	/* usb2_stbus_mess_size 2 packets */
+	asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size);
+	/* usb2_stbus_chunk_size 2 packets */
+	asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size);
+	spin_unlock_irqrestore(&usb_regs_lock, flags);
+}
+
+static void platform_unconfigure_usb(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&usb_regs_lock, flags);
+	usb_users--;
+	if (usb_users == 0)
+		asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap);
+	spin_unlock_irqrestore(&usb_regs_lock, flags);
+}
+
+/*
+ * Set up the USB EHCI interface
+ */
+void platform_configure_usb_ehci()
+{
+	platform_configure_usb();
+}
+EXPORT_SYMBOL(platform_configure_usb_ehci);
+
+/*
+ * Set up the USB OHCI interface
+ */
+void platform_configure_usb_ohci()
+{
+	platform_configure_usb();
+}
+EXPORT_SYMBOL(platform_configure_usb_ohci);
+
+/*
+ * Shut the USB EHCI interface down
+ */
+void platform_unconfigure_usb_ehci()
+{
+	platform_unconfigure_usb();
+}
+EXPORT_SYMBOL(platform_unconfigure_usb_ehci);
+
+/*
+ * Shut the USB OHCI interface down
+ */
+void platform_unconfigure_usb_ohci()
+{
+	platform_unconfigure_usb();
+}
+EXPORT_SYMBOL(platform_unconfigure_usb_ohci);
+
+/**
+ * platform_devices_init - sets up USB device resourse.
+ */
+int __init platform_usb_devices_init(struct platform_device **ehci_dev,
+	struct platform_device **ohci_dev)
+{
+	*ehci_dev = &ehci_device;
+	ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
+	ehci_resources[0].end += ehci_resources[0].start;
+
+	*ohci_dev = &ohci_device;
+	ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
+	ohci_resources[0].end += ohci_resources[0].start;
+
+	return 0;
+}
diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c
index af2cae0a5ab3ee44aa9810d31236be9462aadb90..3933c373a438c5e07fce901eb276c8f46c659194 100644
--- a/arch/mips/powertv/powertv_setup.c
+++ b/arch/mips/powertv/powertv_setup.c
@@ -199,14 +199,8 @@ static int panic_handler(struct notifier_block *notifier_block,
 		my_regs.cp0_status = read_c0_status();
 	}
 
-#ifdef CONFIG_DIAGNOSTICS
-	failure_report((char *) cause_string,
-		have_die_regs ? &die_regs : &my_regs);
-	have_die_regs = false;
-#else
 	pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
 		"zzzz... \n");
-#endif
 
 	return NOTIFY_DONE;
 }
diff --git a/arch/mips/rb532/Makefile b/arch/mips/rb532/Makefile
index 8f0b6b6a162558c605e5c5e2343bc2be3682f96c..efdecdb6e3eaefd85a0865c1341b429494df676e 100644
--- a/arch/mips/rb532/Makefile
+++ b/arch/mips/rb532/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	 += irq.o time.o setup.o serial.o prom.o gpio.o devices.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/rb532/Platform b/arch/mips/rb532/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..aeec45a7cbb3546a55d8f93fa2d36e0bb8dc4032
--- /dev/null
+++ b/arch/mips/rb532/Platform
@@ -0,0 +1,7 @@
+#
+# Routerboard 532
+#
+platform-$(CONFIG_MIKROTIK_RB532)	+= rb532/
+cflags-$(CONFIG_MIKROTIK_RB532)		+=				\
+		-I$(srctree)/arch/mips/include/asm/mach-rc32434
+load-$(CONFIG_MIKROTIK_RB532)		+= 0xffffffff80101000
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index 416b18f9fa722152466c1bc1018cf73c1be42f39..cc538493cae16b54b144b5e87565fec8b21c9be7 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -9,5 +9,3 @@ obj-y	+= ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
 obj-$(CONFIG_SGI_IP22) += ip22-berr.o
 obj-$(CONFIG_SGI_IP28) += ip28-berr.o
 obj-$(CONFIG_EISA)	+= ip22-eisa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/Platform b/arch/mips/sgi-ip22/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..b7a4b7e04c387a155242e786e5978382aab9afaa
--- /dev/null
+++ b/arch/mips/sgi-ip22/Platform
@@ -0,0 +1,34 @@
+#
+# SGI IP22 (Indy/Indigo2)
+#
+# Set the load address to >= 0xffffffff88069000 if you want to leave space for
+# symmon, 0xffffffff80002000 for production kernels.  Note that the value must
+# be aligned to a multiple of the kernel stack size or the handling of the
+# current variable will break so for 64-bit kernels we have to raise the start
+# address by 8kb.
+#
+platform-$(CONFIG_SGI_IP22)		+= sgi-ip22/
+cflags-$(CONFIG_SGI_IP22)	+= -I$(srctree)/arch/mips/include/asm/mach-ip22
+ifdef CONFIG_32BIT
+load-$(CONFIG_SGI_IP22)		+= 0xffffffff88002000
+endif
+ifdef CONFIG_64BIT
+load-$(CONFIG_SGI_IP22)		+= 0xffffffff88004000
+endif
+
+#
+# SGI IP28 (Indigo2 R10k)
+#
+# Set the load address to >= 0xa800000020080000 if you want to leave space for
+# symmon, 0xa800000020004000 for production kernels ?  Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
+#
+ifdef CONFIG_SGI_IP28
+  ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
+      $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
+  endif
+endif
+platform-$(CONFIG_SGI_IP28)		+= sgi-ip22/
+cflags-$(CONFIG_SGI_IP28)	+= -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
+load-$(CONFIG_SGI_IP28)		+= 0xa800000020004000
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
index 31f4931b8484334d60cdd0ea6ccc0b3ea214b2de..1f29e761d691e5f732f58e76708cd05c75ef0e85 100644
--- a/arch/mips/sgi-ip27/Makefile
+++ b/arch/mips/sgi-ip27/Makefile
@@ -8,5 +8,3 @@ obj-y	:= ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \
 
 obj-$(CONFIG_EARLY_PRINTK)	+= ip27-console.o
 obj-$(CONFIG_SMP)		+= ip27-smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip27/Platform b/arch/mips/sgi-ip27/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..1fb9c2ea7c8fe6c805ca7b0a2d582834fb5d6f14
--- /dev/null
+++ b/arch/mips/sgi-ip27/Platform
@@ -0,0 +1,19 @@
+#
+# SGI-IP27 (Origin200/2000)
+#
+# Set the load address to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels.  Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+#
+ifdef CONFIG_SGI_IP27
+platform-$(CONFIG_SGI_IP27)	+= sgi-ip27/
+cflags-$(CONFIG_SGI_IP27)	+= -I$(srctree)/arch/mips/include/asm/mach-ip27
+ifdef CONFIG_MAPPED_KERNEL
+load-$(CONFIG_SGI_IP27)		+= 0xc00000004001c000
+OBJCOPYFLAGS			:= --change-addresses=0x3fffffff80000000
+dataoffset-$(CONFIG_SGI_IP27)	+= 0x01000000
+else
+load-$(CONFIG_SGI_IP27)		+= 0xa80000000001c000
+OBJCOPYFLAGS			:= --change-addresses=0x57ffffff80000000
+endif
+endif
diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c
index dd830b3670d15f37a73349d0cb1e2d28a98bcc1d..7afe14688003a237372bd005f1b9353e688c6a92 100644
--- a/arch/mips/sgi-ip27/ip27-klconfig.c
+++ b/arch/mips/sgi-ip27/ip27-klconfig.c
@@ -48,7 +48,7 @@ klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
 	return find_component(brd, (klinfo_t *)NULL, struct_type);
 }
 
-lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
+lboard_t *find_lboard(lboard_t *start, unsigned char brd_type)
 {
 	/* Search all boards stored on this node. */
 	while (start) {
@@ -60,7 +60,7 @@ lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
 	return (lboard_t *)NULL;
 }
 
-lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type)
 {
 	/* Search all boards stored on this node. */
 	while (start) {
@@ -78,7 +78,7 @@ cnodeid_t get_cpu_cnode(cpuid_t cpu)
 	return CPUID_TO_COMPACT_NODEID(cpu);
 }
 
-klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
 {
 	lboard_t *brd;
 	klcpu_t *acpu;
@@ -97,7 +97,7 @@ klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
 	return (klcpu_t *)NULL;
 }
 
-klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
+klcpu_t *sn_get_cpuinfo(cpuid_t cpu)
 {
 	nasid_t nasid;
 	int slice;
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 31c9aa1bcb40b4fe389c9b7a72badc156a848092..60f0227425e709ba82a9a882158a1b2e5ecb4e49 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -5,5 +5,3 @@
 
 obj-y	+= ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
 	   crime.o ip32-memory.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip32/Platform b/arch/mips/sgi-ip32/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..0fea556f3641c64fb7e6b5b6f0bfdce25e87725c
--- /dev/null
+++ b/arch/mips/sgi-ip32/Platform
@@ -0,0 +1,11 @@
+#
+# SGI-IP32 (O2)
+#
+# Set the load address to >= 80069000 if you want to leave space for symmon,
+# 0xffffffff80004000 for production kernels.  Note that the value must be aligned to
+# a multiple of the kernel stack size or the handling of the current variable
+# will break.
+#
+platform-$(CONFIG_SGI_IP32)	+= sgi-ip32/
+cflags-$(CONFIG_SGI_IP32)	+= -I$(srctree)/arch/mips/include/asm/mach-ip32
+load-$(CONFIG_SGI_IP32)		+= 0xffffffff80004000
diff --git a/arch/mips/sibyte/Makefile b/arch/mips/sibyte/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c8ed2c807e69cee3fa89f2a0e1a15d3edec70155
--- /dev/null
+++ b/arch/mips/sibyte/Makefile
@@ -0,0 +1,27 @@
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+obj-$(CONFIG_SIBYTE_BCM112X)	+= sb1250/
+obj-$(CONFIG_SIBYTE_BCM112X)	+= common/
+obj-$(CONFIG_SIBYTE_SB1250)	+= sb1250/
+obj-$(CONFIG_SIBYTE_SB1250)	+= common/
+obj-$(CONFIG_SIBYTE_BCM1x55)	+= bcm1480/
+obj-$(CONFIG_SIBYTE_BCM1x55)	+= common/
+obj-$(CONFIG_SIBYTE_BCM1x80)	+= bcm1480/
+obj-$(CONFIG_SIBYTE_BCM1x80)	+= common/
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+obj-$(CONFIG_SIBYTE_CARMEL)	+= swarm/
+obj-$(CONFIG_SIBYTE_CRHINE)	+= swarm/
+obj-$(CONFIG_SIBYTE_CRHONE)	+= swarm/
+obj-$(CONFIG_SIBYTE_RHONE)	+= swarm/
+obj-$(CONFIG_SIBYTE_SENTOSA)	+= swarm/
+obj-$(CONFIG_SIBYTE_SWARM)	+= swarm/
+obj-$(CONFIG_SIBYTE_BIGSUR)	+= swarm/
diff --git a/arch/mips/sibyte/Platform b/arch/mips/sibyte/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..911dfe39c631b3fe4f22ff5f1fb220c5ad27f27d
--- /dev/null
+++ b/arch/mips/sibyte/Platform
@@ -0,0 +1,43 @@
+#
+# These are all rather similar so we consider them a single platform
+#
+platform-$(CONFIG_SIBYTE_BCM112X)	+= sibyte/
+platform-$(CONFIG_SIBYTE_SB1250)	+= sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x55)	+= sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x80)	+= sibyte/
+
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+cflags-$(CONFIG_SIBYTE_BCM112X)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
+		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+platform-$(CONFIG_SIBYTE_SB1250)	+= sibyte/
+cflags-$(CONFIG_SIBYTE_SB1250)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
+		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x55)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
+		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x80)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
+		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+load-$(CONFIG_SIBYTE_CARMEL)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHINE)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHONE)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_RHONE)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SENTOSA)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_BIGSUR)	:= 0xffffffff80100000
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
index f292f7df0cfb115043c9e250a8be5b493c1aa5b7..cdc4c56c3e29238158cafa0e09422780e46af1ac 100644
--- a/arch/mips/sibyte/bcm1480/Makefile
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -1,5 +1,3 @@
 obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)			+= smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile
index 4f659837c7c6c441cd8f0a894d5201bded85fc37..36aa700cc40c6773954306ac6ba49e8f77f0019d 100644
--- a/arch/mips/sibyte/common/Makefile
+++ b/arch/mips/sibyte/common/Makefile
@@ -1,5 +1,3 @@
 obj-y := cfe.o
 obj-$(CONFIG_SIBYTE_CFE_CONSOLE)	+= cfe_console.o
 obj-$(CONFIG_SIBYTE_TBPROF)		+= sb_tbprof.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
index 1896f4e77a300e0c2ce3f092605310c9a8e9202c..d3d969de407ba6be81175085a1577f566c94b088 100644
--- a/arch/mips/sibyte/sb1250/Makefile
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -2,5 +2,3 @@ obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)			+= smp.o
 obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index a7dbeebe7fe69a61d6466387117c40c719cdb5c6..9d3bad3200ce3563402b2d4944579481f4fad451 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -4,5 +4,3 @@
 
 obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
 obj-$(CONFIG_EISA) += eisa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/Platform b/arch/mips/sni/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..2644a9d63c0f4a4027d4b71abaad5ee63c1a0f27
--- /dev/null
+++ b/arch/mips/sni/Platform
@@ -0,0 +1,11 @@
+#
+# SNI RM
+#
+platform-$(CONFIG_SNI_RM)		+= sni/
+cflags-$(CONFIG_SNI_RM)		+= -I$(srctree)/arch/mips/include/asm/mach-rm
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+load-$(CONFIG_SNI_RM)		+= 0xffffffff80600000
+else
+load-$(CONFIG_SNI_RM)		+= 0xffffffff80030000
+endif
+all-$(CONFIG_SNI_RM)		:= $(COMPRESSION_FNAME).ecoff
diff --git a/arch/mips/txx9/Makefile b/arch/mips/txx9/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34787dabff06d2a4d3560e9bd54e1e4c9f243400
--- /dev/null
+++ b/arch/mips/txx9/Makefile
@@ -0,0 +1,17 @@
+#
+# Common TXx9
+#
+obj-$(CONFIG_MACH_TX39XX)      += generic/
+obj-$(CONFIG_MACH_TX49XX)      += generic/
+
+#
+# Toshiba JMR-TX3927 board
+#
+obj-$(CONFIG_TOSHIBA_JMR3927)  += jmr3927/
+
+#
+# Toshiba RBTX49XX boards
+#
+obj-$(CONFIG_TOSHIBA_RBTX4927) += rbtx4927/
+obj-$(CONFIG_TOSHIBA_RBTX4938) += rbtx4938/
+obj-$(CONFIG_TOSHIBA_RBTX4939) += rbtx4939/
diff --git a/arch/mips/txx9/Platform b/arch/mips/txx9/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..a801abbe138b129bc3b2ea63e15215ec5589b7d3
--- /dev/null
+++ b/arch/mips/txx9/Platform
@@ -0,0 +1,10 @@
+platform-$(CONFIG_MACH_TX39XX)	+= txx9/
+platform-$(CONFIG_MACH_TX49XX)	+= txx9/
+
+cflags-$(CONFIG_MACH_TX39XX)	+=					\
+		-I$(srctree)/arch/mips/include/asm/mach-tx39xx
+cflags-$(CONFIG_MACH_TX49XX)	+=					\
+		 -I$(srctree)/arch/mips/include/asm/mach-tx49xx
+
+load-$(CONFIG_MACH_TX39XX)      += 0xffffffff80050000
+load-$(CONFIG_MACH_TX49XX)      += 0xffffffff80100000
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
index f2579ce054a1b5bc2fa2452db5e4be2203b0894d..1863c167e66e465489b945758f8466c75cce49ed 100644
--- a/arch/mips/txx9/generic/Makefile
+++ b/arch/mips/txx9/generic/Makefile
@@ -11,5 +11,3 @@ obj-$(CONFIG_SOC_TX4939)	+= setup_tx4939.o irq_tx4939.o
 obj-$(CONFIG_TOSHIBA_FPCIB0)	+= smsc_fdc37m81x.o
 obj-$(CONFIG_SPI)		+= spi_eeprom.o
 obj-$(CONFIG_TXX9_7SEGLED)	+= 7segled.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile
index 20d61ac543e59b102591e86bae9432cfdb252498..9f5d5b623839fd66e474469bddb5168435f05697 100644
--- a/arch/mips/txx9/jmr3927/Makefile
+++ b/arch/mips/txx9/jmr3927/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	+= prom.o irq.o setup.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile
index f3e1f597b4f15c99f1fc0edd5a4e810756bea162..60b24c8f7e63fe68ed7716516f344fafdb7fca4b 100644
--- a/arch/mips/txx9/rbtx4927/Makefile
+++ b/arch/mips/txx9/rbtx4927/Makefile
@@ -1,3 +1 @@
 obj-y	+= prom.o setup.o irq.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
index f3e1f597b4f15c99f1fc0edd5a4e810756bea162..60b24c8f7e63fe68ed7716516f344fafdb7fca4b 100644
--- a/arch/mips/txx9/rbtx4938/Makefile
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -1,3 +1 @@
 obj-y	+= prom.o setup.o irq.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile
index 3232cd03a7d6ba7d9ea99cda6bcf897cb002aab6..5c84625a3f1ccfb3cc5793c506439d6622274383 100644
--- a/arch/mips/txx9/rbtx4939/Makefile
+++ b/arch/mips/txx9/rbtx4939/Makefile
@@ -1,3 +1 @@
 obj-y	 += irq.o setup.o prom.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/vr41xx/Platform b/arch/mips/vr41xx/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..b6c8d5c08ddb7d749cd6d423881c811f8fda87ba
--- /dev/null
+++ b/arch/mips/vr41xx/Platform
@@ -0,0 +1,32 @@
+#
+# NEC VR4100 series based machines
+#
+platform-$(CONFIG_MACH_VR41XX)	+= vr41xx/common/
+cflags-$(CONFIG_MACH_VR41XX)	+= -I$(srctree)/arch/mips/include/asm/mach-vr41xx
+
+#
+# CASIO CASSIPEIA E-55/65 (VR4111)
+#
+platform-$(CONFIG_CASIO_E55)	+= vr41xx/casio-e55/
+load-$(CONFIG_CASIO_E55)	+= 0xffffffff80004000
+
+#
+# IBM WorkPad z50 (VR4121)
+#
+platform-$(CONFIG_IBM_WORKPAD)	+= vr41xx/ibm-workpad/
+load-$(CONFIG_IBM_WORKPAD)	+= 0xffffffff80004000
+
+#
+# TANBAC VR4131 multichip module(TB0225) and TANBAC VR4131DIMM(TB0229) (VR4131)
+#
+load-$(CONFIG_TANBAC_TB022X)	+= 0xffffffff80000000
+
+#
+# Victor MP-C303/304 (VR4122)
+#
+load-$(CONFIG_VICTOR_MPC30X)	+= 0xffffffff80001000
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+load-$(CONFIG_ZAO_CAPCELLA)	+= 0xffffffff80000000
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
index 7d5d83b8c582b81c5428a7a0728facf5ca6bed4a..d0d84ec8d63de98428e612484b651a3c2211e554 100644
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -3,5 +3,3 @@
 #
 
 obj-y	+= bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/gt64120/wrppmc/Makefile b/arch/mips/wrppmc/Makefile
similarity index 80%
rename from arch/mips/gt64120/wrppmc/Makefile
rename to arch/mips/wrppmc/Makefile
index b49d282bee8a1bbb4b31bc3719437fa2637987ec..307cc6920ce6d637515fee55125b70c03bd7795f 100644
--- a/arch/mips/gt64120/wrppmc/Makefile
+++ b/arch/mips/wrppmc/Makefile
@@ -6,9 +6,7 @@
 # Copyright 2006 Wind River System, Inc.
 # Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
 #
-# Makefile for the Wind River MIPS 4KC PPMC Eval Board
+# Makefile for the Wind River MIPS 4Kc PPMC Eval Board
 #
 
 obj-y += irq.o pci.o reset.o serial.o setup.o time.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/wrppmc/Platform b/arch/mips/wrppmc/Platform
new file mode 100644
index 0000000000000000000000000000000000000000..e758645e9681939626d9241c10aba3646802fe6f
--- /dev/null
+++ b/arch/mips/wrppmc/Platform
@@ -0,0 +1,7 @@
+#
+# Wind River PPMC Board (4KC + GT64120)
+#
+platform-$(CONFIG_WR_PPMC)	+= wrppmc/
+cflags-$(CONFIG_WR_PPMC)	+= 					\
+		-I$(srctree)/arch/mips/include/asm/mach-wrppmc
+load-$(CONFIG_WR_PPMC)		+= 0xffffffff80100000
diff --git a/arch/mips/gt64120/wrppmc/irq.c b/arch/mips/wrppmc/irq.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/irq.c
rename to arch/mips/wrppmc/irq.c
diff --git a/arch/mips/gt64120/wrppmc/pci.c b/arch/mips/wrppmc/pci.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/pci.c
rename to arch/mips/wrppmc/pci.c
diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/wrppmc/reset.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/reset.c
rename to arch/mips/wrppmc/reset.c
diff --git a/arch/mips/gt64120/wrppmc/serial.c b/arch/mips/wrppmc/serial.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/serial.c
rename to arch/mips/wrppmc/serial.c
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/wrppmc/setup.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/setup.c
rename to arch/mips/wrppmc/setup.c
diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/wrppmc/time.c
similarity index 100%
rename from arch/mips/gt64120/wrppmc/time.c
rename to arch/mips/wrppmc/time.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e19cf8eb6ccfa10f2ed1414387922d16eebb24ac..c57e530d07c75d1bd8472f22370274e86d3022ff 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -446,6 +446,16 @@ config SENSORS_IT87
 	  This driver can also be built as a module.  If so, the module
 	  will be called it87.
 
+config SENSORS_JZ4740
+	tristate "Ingenic JZ4740 SoC ADC driver"
+	depends on MACH_JZ4740 && MFD_JZ4740_ADC
+	help
+	  If you say yes here you get support for reading adc values from the ADCIN
+	  pin on Ingenic JZ4740 SoC based boards.
+
+	  This driver can also be build as a module. If so, the module will be
+	  called jz4740-hwmon.
+
 config SENSORS_LM63
 	tristate "National Semiconductor LM63 and LM64"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2138ceb1a71346f46bf9cb811affb5c598bdd518..c5057745b068351932ba4fe01a462041c92cfee1 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
 obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
 obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
+obj-$(CONFIG_SENSORS_JZ4740)	+= jz4740-hwmon.o
 obj-$(CONFIG_SENSORS_K8TEMP)	+= k8temp.o
 obj-$(CONFIG_SENSORS_K10TEMP)	+= k10temp.o
 obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c8b3d9e205186c4018fc040eeffd305513f725f
--- /dev/null
+++ b/drivers/hwmon/jz4740-hwmon.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC HWMON driver
+ *
+ * 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.
+ *
+ * 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/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/completion.h>
+#include <linux/mfd/core.h>
+
+#include <linux/hwmon.h>
+
+struct jz4740_hwmon {
+	struct resource *mem;
+	void __iomem *base;
+
+	int irq;
+
+	struct mfd_cell *cell;
+	struct device *hwmon;
+
+	struct completion read_completion;
+
+	struct mutex lock;
+};
+
+static ssize_t jz4740_hwmon_show_name(struct device *dev,
+	struct device_attribute *dev_attr, char *buf)
+{
+	return sprintf(buf, "jz4740\n");
+}
+
+static irqreturn_t jz4740_hwmon_irq(int irq, void *data)
+{
+	struct jz4740_hwmon *hwmon = data;
+
+	complete(&hwmon->read_completion);
+	return IRQ_HANDLED;
+}
+
+static ssize_t jz4740_hwmon_read_adcin(struct device *dev,
+	struct device_attribute *dev_attr, char *buf)
+{
+	struct jz4740_hwmon *hwmon = dev_get_drvdata(dev);
+	struct completion *completion = &hwmon->read_completion;
+	unsigned long t;
+	unsigned long val;
+	int ret;
+
+	mutex_lock(&hwmon->lock);
+
+	INIT_COMPLETION(*completion);
+
+	enable_irq(hwmon->irq);
+	hwmon->cell->enable(to_platform_device(dev));
+
+	t = wait_for_completion_interruptible_timeout(completion, HZ);
+
+	if (t > 0) {
+		val = readw(hwmon->base) & 0xfff;
+		val = (val * 3300) >> 12;
+		ret = sprintf(buf, "%lu\n", val);
+	} else {
+		ret = t ? t : -ETIMEDOUT;
+	}
+
+	hwmon->cell->disable(to_platform_device(dev));
+	disable_irq(hwmon->irq);
+
+	mutex_unlock(&hwmon->lock);
+
+	return ret;
+}
+
+static DEVICE_ATTR(name, S_IRUGO, jz4740_hwmon_show_name, NULL);
+static DEVICE_ATTR(in0_input, S_IRUGO, jz4740_hwmon_read_adcin, NULL);
+
+static struct attribute *jz4740_hwmon_attributes[] = {
+	&dev_attr_name.attr,
+	&dev_attr_in0_input.attr,
+	NULL
+};
+
+static const struct attribute_group jz4740_hwmon_attr_group = {
+	.attrs = jz4740_hwmon_attributes,
+};
+
+static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct jz4740_hwmon *hwmon;
+
+	hwmon = kmalloc(sizeof(*hwmon), GFP_KERNEL);
+	if (!hwmon) {
+		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+		return -ENOMEM;
+	}
+
+	hwmon->cell = pdev->dev.platform_data;
+
+	hwmon->irq = platform_get_irq(pdev, 0);
+	if (hwmon->irq < 0) {
+		ret = hwmon->irq;
+		dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
+		goto err_free;
+	}
+
+	hwmon->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!hwmon->mem) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
+		goto err_free;
+	}
+
+	hwmon->mem = request_mem_region(hwmon->mem->start,
+			resource_size(hwmon->mem), pdev->name);
+	if (!hwmon->mem) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
+		goto err_free;
+	}
+
+	hwmon->base = ioremap_nocache(hwmon->mem->start,
+			resource_size(hwmon->mem));
+	if (!hwmon->base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
+		goto err_release_mem_region;
+	}
+
+	init_completion(&hwmon->read_completion);
+	mutex_init(&hwmon->lock);
+
+	platform_set_drvdata(pdev, hwmon);
+
+	ret = request_irq(hwmon->irq, jz4740_hwmon_irq, 0, pdev->name, hwmon);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
+		goto err_iounmap;
+	}
+	disable_irq(hwmon->irq);
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to create sysfs group: %d\n", ret);
+		goto err_free_irq;
+	}
+
+	hwmon->hwmon = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(hwmon->hwmon)) {
+		ret = PTR_ERR(hwmon->hwmon);
+		goto err_remove_file;
+	}
+
+	return 0;
+
+err_remove_file:
+	sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
+err_free_irq:
+	free_irq(hwmon->irq, hwmon);
+err_iounmap:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(hwmon->base);
+err_release_mem_region:
+	release_mem_region(hwmon->mem->start, resource_size(hwmon->mem));
+err_free:
+	kfree(hwmon);
+
+	return ret;
+}
+
+static int __devexit jz4740_hwmon_remove(struct platform_device *pdev)
+{
+	struct jz4740_hwmon *hwmon = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(hwmon->hwmon);
+	sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
+
+	free_irq(hwmon->irq, hwmon);
+
+	iounmap(hwmon->base);
+	release_mem_region(hwmon->mem->start, resource_size(hwmon->mem));
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(hwmon);
+
+	return 0;
+}
+
+struct platform_driver jz4740_hwmon_driver = {
+	.probe	= jz4740_hwmon_probe,
+	.remove = __devexit_p(jz4740_hwmon_remove),
+	.driver = {
+		.name = "jz4740-hwmon",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init jz4740_hwmon_init(void)
+{
+	return platform_driver_register(&jz4740_hwmon_driver);
+}
+module_init(jz4740_hwmon_init);
+
+static void __exit jz4740_hwmon_exit(void)
+{
+	platform_driver_unregister(&jz4740_hwmon_driver);
+}
+module_exit(jz4740_hwmon_exit);
+
+MODULE_DESCRIPTION("JZ4740 SoC HWMON driver");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:jz4740-hwmon");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index f06d06e7fdfa06683d883f26397ace3d9f63970e..d25e22cee4c41c921a00bbbef584083d1862a2a4 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -432,3 +432,12 @@ config MMC_SH_MMCIF
 	  This selects the MMC Host Interface controler (MMCIF).
 
 	  This driver supports MMCIF in sh7724/sh7757/sh7372.
+
+config MMC_JZ4740
+	tristate "JZ4740 SD/Multimedia Card Interface support"
+	depends on MACH_JZ4740
+	help
+	  This selects support for the SD/MMC controller on Ingenic JZ4740
+	  SoCs.
+	  If you have a board based on such a SoC and with a SD/MMC slot,
+	  say Y or M here.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e30c2ee488942c711713647e731d888af5619d64..f4e53c98d9447796aebabdca24e914ba1afb1d6b 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MMC_CB710)	+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
+obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 
 obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
 sdhci-of-y				:= sdhci-of-core.o
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..ad4f9870e3caffefd8c8b2922296cd7fc4b97a03
--- /dev/null
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -0,0 +1,1029 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SD/MMC controller driver
+ *
+ *  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.
+ *
+ *  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/mmc/host.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/scatterlist.h>
+#include <linux/clk.h>
+
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <asm/mach-jz4740/gpio.h>
+#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-jz4740/jz4740_mmc.h>
+
+#define JZ_REG_MMC_STRPCL	0x00
+#define JZ_REG_MMC_STATUS	0x04
+#define JZ_REG_MMC_CLKRT	0x08
+#define JZ_REG_MMC_CMDAT	0x0C
+#define JZ_REG_MMC_RESTO	0x10
+#define JZ_REG_MMC_RDTO		0x14
+#define JZ_REG_MMC_BLKLEN	0x18
+#define JZ_REG_MMC_NOB		0x1C
+#define JZ_REG_MMC_SNOB		0x20
+#define JZ_REG_MMC_IMASK	0x24
+#define JZ_REG_MMC_IREG		0x28
+#define JZ_REG_MMC_CMD		0x2C
+#define JZ_REG_MMC_ARG		0x30
+#define JZ_REG_MMC_RESP_FIFO	0x34
+#define JZ_REG_MMC_RXFIFO	0x38
+#define JZ_REG_MMC_TXFIFO	0x3C
+
+#define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7)
+#define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6)
+#define JZ_MMC_STRPCL_START_READWAIT BIT(5)
+#define JZ_MMC_STRPCL_STOP_READWAIT BIT(4)
+#define JZ_MMC_STRPCL_RESET BIT(3)
+#define JZ_MMC_STRPCL_START_OP BIT(2)
+#define JZ_MMC_STRPCL_CLOCK_CONTROL (BIT(1) | BIT(0))
+#define JZ_MMC_STRPCL_CLOCK_STOP BIT(0)
+#define JZ_MMC_STRPCL_CLOCK_START BIT(1)
+
+
+#define JZ_MMC_STATUS_IS_RESETTING BIT(15)
+#define JZ_MMC_STATUS_SDIO_INT_ACTIVE BIT(14)
+#define JZ_MMC_STATUS_PRG_DONE BIT(13)
+#define JZ_MMC_STATUS_DATA_TRAN_DONE BIT(12)
+#define JZ_MMC_STATUS_END_CMD_RES BIT(11)
+#define JZ_MMC_STATUS_DATA_FIFO_AFULL BIT(10)
+#define JZ_MMC_STATUS_IS_READWAIT BIT(9)
+#define JZ_MMC_STATUS_CLK_EN BIT(8)
+#define JZ_MMC_STATUS_DATA_FIFO_FULL BIT(7)
+#define JZ_MMC_STATUS_DATA_FIFO_EMPTY BIT(6)
+#define JZ_MMC_STATUS_CRC_RES_ERR BIT(5)
+#define JZ_MMC_STATUS_CRC_READ_ERROR BIT(4)
+#define JZ_MMC_STATUS_TIMEOUT_WRITE BIT(3)
+#define JZ_MMC_STATUS_CRC_WRITE_ERROR BIT(2)
+#define JZ_MMC_STATUS_TIMEOUT_RES BIT(1)
+#define JZ_MMC_STATUS_TIMEOUT_READ BIT(0)
+
+#define JZ_MMC_STATUS_READ_ERROR_MASK (BIT(4) | BIT(0))
+#define JZ_MMC_STATUS_WRITE_ERROR_MASK (BIT(3) | BIT(2))
+
+
+#define JZ_MMC_CMDAT_IO_ABORT BIT(11)
+#define JZ_MMC_CMDAT_BUS_WIDTH_4BIT BIT(10)
+#define JZ_MMC_CMDAT_DMA_EN BIT(8)
+#define JZ_MMC_CMDAT_INIT BIT(7)
+#define JZ_MMC_CMDAT_BUSY BIT(6)
+#define JZ_MMC_CMDAT_STREAM BIT(5)
+#define JZ_MMC_CMDAT_WRITE BIT(4)
+#define JZ_MMC_CMDAT_DATA_EN BIT(3)
+#define JZ_MMC_CMDAT_RESPONSE_FORMAT (BIT(2) | BIT(1) | BIT(0))
+#define JZ_MMC_CMDAT_RSP_R1 1
+#define JZ_MMC_CMDAT_RSP_R2 2
+#define JZ_MMC_CMDAT_RSP_R3 3
+
+#define JZ_MMC_IRQ_SDIO BIT(7)
+#define JZ_MMC_IRQ_TXFIFO_WR_REQ BIT(6)
+#define JZ_MMC_IRQ_RXFIFO_RD_REQ BIT(5)
+#define JZ_MMC_IRQ_END_CMD_RES BIT(2)
+#define JZ_MMC_IRQ_PRG_DONE BIT(1)
+#define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0)
+
+
+#define JZ_MMC_CLK_RATE 24000000
+
+enum jz4740_mmc_state {
+	JZ4740_MMC_STATE_READ_RESPONSE,
+	JZ4740_MMC_STATE_TRANSFER_DATA,
+	JZ4740_MMC_STATE_SEND_STOP,
+	JZ4740_MMC_STATE_DONE,
+};
+
+struct jz4740_mmc_host {
+	struct mmc_host *mmc;
+	struct platform_device *pdev;
+	struct jz4740_mmc_platform_data *pdata;
+	struct clk *clk;
+
+	int irq;
+	int card_detect_irq;
+
+	struct resource *mem;
+	void __iomem *base;
+	struct mmc_request *req;
+	struct mmc_command *cmd;
+
+	unsigned long waiting;
+
+	uint32_t cmdat;
+
+	uint16_t irq_mask;
+
+	spinlock_t lock;
+
+	struct timer_list timeout_timer;
+	struct sg_mapping_iter miter;
+	enum jz4740_mmc_state state;
+};
+
+static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host,
+	unsigned int irq, bool enabled)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (enabled)
+		host->irq_mask &= ~irq;
+	else
+		host->irq_mask |= irq;
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
+}
+
+static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
+	bool start_transfer)
+{
+	uint16_t val = JZ_MMC_STRPCL_CLOCK_START;
+
+	if (start_transfer)
+		val |= JZ_MMC_STRPCL_START_OP;
+
+	writew(val, host->base + JZ_REG_MMC_STRPCL);
+}
+
+static void jz4740_mmc_clock_disable(struct jz4740_mmc_host *host)
+{
+	uint32_t status;
+	unsigned int timeout = 1000;
+
+	writew(JZ_MMC_STRPCL_CLOCK_STOP, host->base + JZ_REG_MMC_STRPCL);
+	do {
+		status = readl(host->base + JZ_REG_MMC_STATUS);
+	} while (status & JZ_MMC_STATUS_CLK_EN && --timeout);
+}
+
+static void jz4740_mmc_reset(struct jz4740_mmc_host *host)
+{
+	uint32_t status;
+	unsigned int timeout = 1000;
+
+	writew(JZ_MMC_STRPCL_RESET, host->base + JZ_REG_MMC_STRPCL);
+	udelay(10);
+	do {
+		status = readl(host->base + JZ_REG_MMC_STATUS);
+	} while (status & JZ_MMC_STATUS_IS_RESETTING && --timeout);
+}
+
+static void jz4740_mmc_request_done(struct jz4740_mmc_host *host)
+{
+	struct mmc_request *req;
+
+	req = host->req;
+	host->req = NULL;
+
+	mmc_request_done(host->mmc, req);
+}
+
+static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host,
+	unsigned int irq)
+{
+	unsigned int timeout = 0x800;
+	uint16_t status;
+
+	do {
+		status = readw(host->base + JZ_REG_MMC_IREG);
+	} while (!(status & irq) && --timeout);
+
+	if (timeout == 0) {
+		set_bit(0, &host->waiting);
+		mod_timer(&host->timeout_timer, jiffies + 5*HZ);
+		jz4740_mmc_set_irq_enabled(host, irq, true);
+		return true;
+	}
+
+	return false;
+}
+
+static void jz4740_mmc_transfer_check_state(struct jz4740_mmc_host *host,
+	struct mmc_data *data)
+{
+	int status;
+
+	status = readl(host->base + JZ_REG_MMC_STATUS);
+	if (status & JZ_MMC_STATUS_WRITE_ERROR_MASK) {
+		if (status & (JZ_MMC_STATUS_TIMEOUT_WRITE)) {
+			host->req->cmd->error = -ETIMEDOUT;
+			data->error = -ETIMEDOUT;
+		} else {
+			host->req->cmd->error = -EIO;
+			data->error = -EIO;
+		}
+	}
+}
+
+static bool jz4740_mmc_write_data(struct jz4740_mmc_host *host,
+	struct mmc_data *data)
+{
+	struct sg_mapping_iter *miter = &host->miter;
+	void __iomem *fifo_addr = host->base + JZ_REG_MMC_TXFIFO;
+	uint32_t *buf;
+	bool timeout;
+	size_t i, j;
+
+	while (sg_miter_next(miter)) {
+		buf = miter->addr;
+		i = miter->length / 4;
+		j = i / 8;
+		i = i & 0x7;
+		while (j) {
+			timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ);
+			if (unlikely(timeout))
+				goto poll_timeout;
+
+			writel(buf[0], fifo_addr);
+			writel(buf[1], fifo_addr);
+			writel(buf[2], fifo_addr);
+			writel(buf[3], fifo_addr);
+			writel(buf[4], fifo_addr);
+			writel(buf[5], fifo_addr);
+			writel(buf[6], fifo_addr);
+			writel(buf[7], fifo_addr);
+			buf += 8;
+			--j;
+		}
+		if (unlikely(i)) {
+			timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ);
+			if (unlikely(timeout))
+				goto poll_timeout;
+
+			while (i) {
+				writel(*buf, fifo_addr);
+				++buf;
+				--i;
+			}
+		}
+		data->bytes_xfered += miter->length;
+	}
+	sg_miter_stop(miter);
+
+	return false;
+
+poll_timeout:
+	miter->consumed = (void *)buf - miter->addr;
+	data->bytes_xfered += miter->consumed;
+	sg_miter_stop(miter);
+
+	return true;
+}
+
+static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host,
+				struct mmc_data *data)
+{
+	struct sg_mapping_iter *miter = &host->miter;
+	void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO;
+	uint32_t *buf;
+	uint32_t d;
+	uint16_t status;
+	size_t i, j;
+	unsigned int timeout;
+
+	while (sg_miter_next(miter)) {
+		buf = miter->addr;
+		i = miter->length;
+		j = i / 32;
+		i = i & 0x1f;
+		while (j) {
+			timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ);
+			if (unlikely(timeout))
+				goto poll_timeout;
+
+			buf[0] = readl(fifo_addr);
+			buf[1] = readl(fifo_addr);
+			buf[2] = readl(fifo_addr);
+			buf[3] = readl(fifo_addr);
+			buf[4] = readl(fifo_addr);
+			buf[5] = readl(fifo_addr);
+			buf[6] = readl(fifo_addr);
+			buf[7] = readl(fifo_addr);
+
+			buf += 8;
+			--j;
+		}
+
+		if (unlikely(i)) {
+			timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ);
+			if (unlikely(timeout))
+				goto poll_timeout;
+
+			while (i >= 4) {
+				*buf++ = readl(fifo_addr);
+				i -= 4;
+			}
+			if (unlikely(i > 0)) {
+				d = readl(fifo_addr);
+				memcpy(buf, &d, i);
+			}
+		}
+		data->bytes_xfered += miter->length;
+
+		/* This can go away once MIPS implements
+		 * flush_kernel_dcache_page */
+		flush_dcache_page(miter->page);
+	}
+	sg_miter_stop(miter);
+
+	/* For whatever reason there is sometime one word more in the fifo then
+	 * requested */
+	timeout = 1000;
+	status = readl(host->base + JZ_REG_MMC_STATUS);
+	while (!(status & JZ_MMC_STATUS_DATA_FIFO_EMPTY) && --timeout) {
+		d = readl(fifo_addr);
+		status = readl(host->base + JZ_REG_MMC_STATUS);
+	}
+
+	return false;
+
+poll_timeout:
+	miter->consumed = (void *)buf - miter->addr;
+	data->bytes_xfered += miter->consumed;
+	sg_miter_stop(miter);
+
+	return true;
+}
+
+static void jz4740_mmc_timeout(unsigned long data)
+{
+	struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)data;
+
+	if (!test_and_clear_bit(0, &host->waiting))
+		return;
+
+	jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, false);
+
+	host->req->cmd->error = -ETIMEDOUT;
+	jz4740_mmc_request_done(host);
+}
+
+static void jz4740_mmc_read_response(struct jz4740_mmc_host *host,
+	struct mmc_command *cmd)
+{
+	int i;
+	uint16_t tmp;
+	void __iomem *fifo_addr = host->base + JZ_REG_MMC_RESP_FIFO;
+
+	if (cmd->flags & MMC_RSP_136) {
+		tmp = readw(fifo_addr);
+		for (i = 0; i < 4; ++i) {
+			cmd->resp[i] = tmp << 24;
+			tmp = readw(fifo_addr);
+			cmd->resp[i] |= tmp << 8;
+			tmp = readw(fifo_addr);
+			cmd->resp[i] |= tmp >> 8;
+		}
+	} else {
+		cmd->resp[0] = readw(fifo_addr) << 24;
+		cmd->resp[0] |= readw(fifo_addr) << 8;
+		cmd->resp[0] |= readw(fifo_addr) & 0xff;
+	}
+}
+
+static void jz4740_mmc_send_command(struct jz4740_mmc_host *host,
+	struct mmc_command *cmd)
+{
+	uint32_t cmdat = host->cmdat;
+
+	host->cmdat &= ~JZ_MMC_CMDAT_INIT;
+	jz4740_mmc_clock_disable(host);
+
+	host->cmd = cmd;
+
+	if (cmd->flags & MMC_RSP_BUSY)
+		cmdat |= JZ_MMC_CMDAT_BUSY;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_R1B:
+	case MMC_RSP_R1:
+		cmdat |= JZ_MMC_CMDAT_RSP_R1;
+		break;
+	case MMC_RSP_R2:
+		cmdat |= JZ_MMC_CMDAT_RSP_R2;
+		break;
+	case MMC_RSP_R3:
+		cmdat |= JZ_MMC_CMDAT_RSP_R3;
+		break;
+	default:
+		break;
+	}
+
+	if (cmd->data) {
+		cmdat |= JZ_MMC_CMDAT_DATA_EN;
+		if (cmd->data->flags & MMC_DATA_WRITE)
+			cmdat |= JZ_MMC_CMDAT_WRITE;
+		if (cmd->data->flags & MMC_DATA_STREAM)
+			cmdat |= JZ_MMC_CMDAT_STREAM;
+
+		writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN);
+		writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB);
+	}
+
+	writeb(cmd->opcode, host->base + JZ_REG_MMC_CMD);
+	writel(cmd->arg, host->base + JZ_REG_MMC_ARG);
+	writel(cmdat, host->base + JZ_REG_MMC_CMDAT);
+
+	jz4740_mmc_clock_enable(host, 1);
+}
+
+static void jz_mmc_prepare_data_transfer(struct jz4740_mmc_host *host)
+{
+	struct mmc_command *cmd = host->req->cmd;
+	struct mmc_data *data = cmd->data;
+	int direction;
+
+	if (data->flags & MMC_DATA_READ)
+		direction = SG_MITER_TO_SG;
+	else
+		direction = SG_MITER_FROM_SG;
+
+	sg_miter_start(&host->miter, data->sg, data->sg_len, direction);
+}
+
+
+static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
+{
+	struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid;
+	struct mmc_command *cmd = host->req->cmd;
+	struct mmc_request *req = host->req;
+	bool timeout = false;
+
+	if (cmd->error)
+		host->state = JZ4740_MMC_STATE_DONE;
+
+	switch (host->state) {
+	case JZ4740_MMC_STATE_READ_RESPONSE:
+		if (cmd->flags & MMC_RSP_PRESENT)
+			jz4740_mmc_read_response(host, cmd);
+
+		if (!cmd->data)
+			break;
+
+		jz_mmc_prepare_data_transfer(host);
+
+	case JZ4740_MMC_STATE_TRANSFER_DATA:
+		if (cmd->data->flags & MMC_DATA_READ)
+			timeout = jz4740_mmc_read_data(host, cmd->data);
+		else
+			timeout = jz4740_mmc_write_data(host, cmd->data);
+
+		if (unlikely(timeout)) {
+			host->state = JZ4740_MMC_STATE_TRANSFER_DATA;
+			break;
+		}
+
+		jz4740_mmc_transfer_check_state(host, cmd->data);
+
+		timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_DATA_TRAN_DONE);
+		if (unlikely(timeout)) {
+			host->state = JZ4740_MMC_STATE_SEND_STOP;
+			break;
+		}
+		writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG);
+
+	case JZ4740_MMC_STATE_SEND_STOP:
+		if (!req->stop)
+			break;
+
+		jz4740_mmc_send_command(host, req->stop);
+
+		timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_PRG_DONE);
+		if (timeout) {
+			host->state = JZ4740_MMC_STATE_DONE;
+			break;
+		}
+	case JZ4740_MMC_STATE_DONE:
+		break;
+	}
+
+	if (!timeout)
+		jz4740_mmc_request_done(host);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t jz_mmc_irq(int irq, void *devid)
+{
+	struct jz4740_mmc_host *host = devid;
+	struct mmc_command *cmd = host->cmd;
+	uint16_t irq_reg, status, tmp;
+
+	irq_reg = readw(host->base + JZ_REG_MMC_IREG);
+
+	tmp = irq_reg;
+	irq_reg &= ~host->irq_mask;
+
+	tmp &= ~(JZ_MMC_IRQ_TXFIFO_WR_REQ | JZ_MMC_IRQ_RXFIFO_RD_REQ |
+		JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE);
+
+	if (tmp != irq_reg)
+		writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG);
+
+	if (irq_reg & JZ_MMC_IRQ_SDIO) {
+		writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
+		mmc_signal_sdio_irq(host->mmc);
+		irq_reg &= ~JZ_MMC_IRQ_SDIO;
+	}
+
+	if (host->req && cmd && irq_reg) {
+		if (test_and_clear_bit(0, &host->waiting)) {
+			del_timer(&host->timeout_timer);
+
+			status = readl(host->base + JZ_REG_MMC_STATUS);
+
+			if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
+					cmd->error = -ETIMEDOUT;
+			} else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
+					cmd->error = -EIO;
+			} else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
+				    JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
+					if (cmd->data)
+							cmd->data->error = -EIO;
+					cmd->error = -EIO;
+			} else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
+					JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
+					if (cmd->data)
+							cmd->data->error = -EIO;
+					cmd->error = -EIO;
+			}
+
+			jz4740_mmc_set_irq_enabled(host, irq_reg, false);
+			writew(irq_reg, host->base + JZ_REG_MMC_IREG);
+
+			return IRQ_WAKE_THREAD;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate)
+{
+	int div = 0;
+	int real_rate;
+
+	jz4740_mmc_clock_disable(host);
+	clk_set_rate(host->clk, JZ_MMC_CLK_RATE);
+
+	real_rate = clk_get_rate(host->clk);
+
+	while (real_rate > rate && div < 7) {
+		++div;
+		real_rate >>= 1;
+	}
+
+	writew(div, host->base + JZ_REG_MMC_CLKRT);
+	return real_rate;
+}
+
+static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+	struct jz4740_mmc_host *host = mmc_priv(mmc);
+
+	host->req = req;
+
+	writew(0xffff, host->base + JZ_REG_MMC_IREG);
+
+	writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
+	jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true);
+
+	host->state = JZ4740_MMC_STATE_READ_RESPONSE;
+	set_bit(0, &host->waiting);
+	mod_timer(&host->timeout_timer, jiffies + 5*HZ);
+	jz4740_mmc_send_command(host, req->cmd);
+}
+
+static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct jz4740_mmc_host *host = mmc_priv(mmc);
+	if (ios->clock)
+		jz4740_mmc_set_clock_rate(host, ios->clock);
+
+	switch (ios->power_mode) {
+	case MMC_POWER_UP:
+		jz4740_mmc_reset(host);
+		if (gpio_is_valid(host->pdata->gpio_power))
+			gpio_set_value(host->pdata->gpio_power,
+					!host->pdata->power_active_low);
+		host->cmdat |= JZ_MMC_CMDAT_INIT;
+		clk_enable(host->clk);
+		break;
+	case MMC_POWER_ON:
+		break;
+	default:
+		if (gpio_is_valid(host->pdata->gpio_power))
+			gpio_set_value(host->pdata->gpio_power,
+					host->pdata->power_active_low);
+		clk_disable(host->clk);
+		break;
+	}
+
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_1:
+		host->cmdat &= ~JZ_MMC_CMDAT_BUS_WIDTH_4BIT;
+		break;
+	case MMC_BUS_WIDTH_4:
+		host->cmdat |= JZ_MMC_CMDAT_BUS_WIDTH_4BIT;
+		break;
+	default:
+		break;
+	}
+}
+
+static int jz4740_mmc_get_ro(struct mmc_host *mmc)
+{
+	struct jz4740_mmc_host *host = mmc_priv(mmc);
+	if (!gpio_is_valid(host->pdata->gpio_read_only))
+		return -ENOSYS;
+
+	return gpio_get_value(host->pdata->gpio_read_only) ^
+		host->pdata->read_only_active_low;
+}
+
+static int jz4740_mmc_get_cd(struct mmc_host *mmc)
+{
+	struct jz4740_mmc_host *host = mmc_priv(mmc);
+	if (!gpio_is_valid(host->pdata->gpio_card_detect))
+		return -ENOSYS;
+
+	return gpio_get_value(host->pdata->gpio_card_detect) ^
+			host->pdata->card_detect_active_low;
+}
+
+static irqreturn_t jz4740_mmc_card_detect_irq(int irq, void *devid)
+{
+	struct jz4740_mmc_host *host = devid;
+
+	mmc_detect_change(host->mmc, HZ / 2);
+
+	return IRQ_HANDLED;
+}
+
+static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct jz4740_mmc_host *host = mmc_priv(mmc);
+	jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable);
+}
+
+static const struct mmc_host_ops jz4740_mmc_ops = {
+	.request	= jz4740_mmc_request,
+	.set_ios	= jz4740_mmc_set_ios,
+	.get_ro		= jz4740_mmc_get_ro,
+	.get_cd		= jz4740_mmc_get_cd,
+	.enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
+};
+
+static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = {
+	JZ_GPIO_BULK_PIN(MSC_CMD),
+	JZ_GPIO_BULK_PIN(MSC_CLK),
+	JZ_GPIO_BULK_PIN(MSC_DATA0),
+	JZ_GPIO_BULK_PIN(MSC_DATA1),
+	JZ_GPIO_BULK_PIN(MSC_DATA2),
+	JZ_GPIO_BULK_PIN(MSC_DATA3),
+};
+
+static int __devinit jz4740_mmc_request_gpio(struct device *dev, int gpio,
+	const char *name, bool output, int value)
+{
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return 0;
+
+	ret = gpio_request(gpio, name);
+	if (ret) {
+		dev_err(dev, "Failed to request %s gpio: %d\n", name, ret);
+		return ret;
+	}
+
+	if (output)
+		gpio_direction_output(gpio, value);
+	else
+		gpio_direction_input(gpio);
+
+	return 0;
+}
+
+static int __devinit jz4740_mmc_request_gpios(struct platform_device *pdev)
+{
+	int ret;
+	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return 0;
+
+	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_card_detect,
+			"MMC detect change", false, 0);
+	if (ret)
+		goto err;
+
+	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_read_only,
+			"MMC read only", false, 0);
+	if (ret)
+		goto err_free_gpio_card_detect;
+
+	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_power,
+			"MMC read only", true, pdata->power_active_low);
+	if (ret)
+		goto err_free_gpio_read_only;
+
+	return 0;
+
+err_free_gpio_read_only:
+	if (gpio_is_valid(pdata->gpio_read_only))
+		gpio_free(pdata->gpio_read_only);
+err_free_gpio_card_detect:
+	if (gpio_is_valid(pdata->gpio_card_detect))
+		gpio_free(pdata->gpio_card_detect);
+err:
+	return ret;
+}
+
+static int __devinit jz4740_mmc_request_cd_irq(struct platform_device *pdev,
+	struct jz4740_mmc_host *host)
+{
+	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
+
+	if (!gpio_is_valid(pdata->gpio_card_detect))
+		return 0;
+
+	host->card_detect_irq = gpio_to_irq(pdata->gpio_card_detect);
+	if (host->card_detect_irq < 0) {
+		dev_warn(&pdev->dev, "Failed to get card detect irq\n");
+		return 0;
+	}
+
+	return request_irq(host->card_detect_irq, jz4740_mmc_card_detect_irq,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			"MMC card detect", host);
+}
+
+static void jz4740_mmc_free_gpios(struct platform_device *pdev)
+{
+	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return;
+
+	if (gpio_is_valid(pdata->gpio_power))
+		gpio_free(pdata->gpio_power);
+	if (gpio_is_valid(pdata->gpio_read_only))
+		gpio_free(pdata->gpio_read_only);
+	if (gpio_is_valid(pdata->gpio_card_detect))
+		gpio_free(pdata->gpio_card_detect);
+}
+
+static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host)
+{
+	size_t num_pins = ARRAY_SIZE(jz4740_mmc_pins);
+	if (host->pdata && host->pdata->data_1bit)
+		num_pins -= 3;
+
+	return num_pins;
+}
+
+static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
+{
+	int ret;
+	struct mmc_host *mmc;
+	struct jz4740_mmc_host *host;
+	struct jz4740_mmc_platform_data *pdata;
+
+	pdata = pdev->dev.platform_data;
+
+	mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev);
+	if (!mmc) {
+		dev_err(&pdev->dev, "Failed to alloc mmc host structure\n");
+		return -ENOMEM;
+	}
+
+	host = mmc_priv(mmc);
+	host->pdata = pdata;
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq < 0) {
+		ret = host->irq;
+		dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
+		goto err_free_host;
+	}
+
+	host->clk = clk_get(&pdev->dev, "mmc");
+	if (!host->clk) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get mmc clock\n");
+		goto err_free_host;
+	}
+
+	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!host->mem) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get base platform memory\n");
+		goto err_clk_put;
+	}
+
+	host->mem = request_mem_region(host->mem->start,
+					resource_size(host->mem), pdev->name);
+	if (!host->mem) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to request base memory region\n");
+		goto err_clk_put;
+	}
+
+	host->base = ioremap_nocache(host->mem->start, resource_size(host->mem));
+	if (!host->base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to ioremap base memory\n");
+		goto err_release_mem_region;
+	}
+
+	ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request mmc pins: %d\n", ret);
+		goto err_iounmap;
+	}
+
+	ret = jz4740_mmc_request_gpios(pdev);
+	if (ret)
+		goto err_gpio_bulk_free;
+
+	mmc->ops = &jz4740_mmc_ops;
+	mmc->f_min = JZ_MMC_CLK_RATE / 128;
+	mmc->f_max = JZ_MMC_CLK_RATE;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->caps = (pdata && pdata->data_1bit) ? 0 : MMC_CAP_4_BIT_DATA;
+	mmc->caps |= MMC_CAP_SDIO_IRQ;
+
+	mmc->max_blk_size = (1 << 10) - 1;
+	mmc->max_blk_count = (1 << 15) - 1;
+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+	mmc->max_phys_segs = 128;
+	mmc->max_hw_segs = 128;
+	mmc->max_seg_size = mmc->max_req_size;
+
+	host->mmc = mmc;
+	host->pdev = pdev;
+	spin_lock_init(&host->lock);
+	host->irq_mask = 0xffff;
+
+	ret = jz4740_mmc_request_cd_irq(pdev, host);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request card detect irq\n");
+		goto err_free_gpios;
+	}
+
+	ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0,
+			dev_name(&pdev->dev), host);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
+		goto err_free_card_detect_irq;
+	}
+
+	jz4740_mmc_reset(host);
+	jz4740_mmc_clock_disable(host);
+	setup_timer(&host->timeout_timer, jz4740_mmc_timeout,
+			(unsigned long)host);
+	/* It is not important when it times out, it just needs to timeout. */
+	set_timer_slack(&host->timeout_timer, HZ);
+
+	platform_set_drvdata(pdev, host);
+	ret = mmc_add_host(mmc);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret);
+		goto err_free_irq;
+	}
+	dev_info(&pdev->dev, "JZ SD/MMC card driver registered\n");
+
+	return 0;
+
+err_free_irq:
+	free_irq(host->irq, host);
+err_free_card_detect_irq:
+	if (host->card_detect_irq >= 0)
+		free_irq(host->card_detect_irq, host);
+err_free_gpios:
+	jz4740_mmc_free_gpios(pdev);
+err_gpio_bulk_free:
+	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
+err_iounmap:
+	iounmap(host->base);
+err_release_mem_region:
+	release_mem_region(host->mem->start, resource_size(host->mem));
+err_clk_put:
+	clk_put(host->clk);
+err_free_host:
+	platform_set_drvdata(pdev, NULL);
+	mmc_free_host(mmc);
+
+	return ret;
+}
+
+static int __devexit jz4740_mmc_remove(struct platform_device *pdev)
+{
+	struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
+
+	del_timer_sync(&host->timeout_timer);
+	jz4740_mmc_set_irq_enabled(host, 0xff, false);
+	jz4740_mmc_reset(host);
+
+	mmc_remove_host(host->mmc);
+
+	free_irq(host->irq, host);
+	if (host->card_detect_irq >= 0)
+		free_irq(host->card_detect_irq, host);
+
+	jz4740_mmc_free_gpios(pdev);
+	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
+
+	iounmap(host->base);
+	release_mem_region(host->mem->start, resource_size(host->mem));
+
+	clk_put(host->clk);
+
+	platform_set_drvdata(pdev, NULL);
+	mmc_free_host(host->mmc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int jz4740_mmc_suspend(struct device *dev)
+{
+	struct jz4740_mmc_host *host = dev_get_drvdata(dev);
+
+	mmc_suspend_host(host->mmc);
+
+	jz_gpio_bulk_suspend(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
+
+	return 0;
+}
+
+static int jz4740_mmc_resume(struct device *dev)
+{
+	struct jz4740_mmc_host *host = dev_get_drvdata(dev);
+
+	jz_gpio_bulk_resume(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
+
+	mmc_resume_host(host->mmc);
+
+	return 0;
+}
+
+const struct dev_pm_ops jz4740_mmc_pm_ops = {
+	.suspend	= jz4740_mmc_suspend,
+	.resume		= jz4740_mmc_resume,
+	.poweroff	= jz4740_mmc_suspend,
+	.restore	= jz4740_mmc_resume,
+};
+
+#define JZ4740_MMC_PM_OPS (&jz4740_mmc_pm_ops)
+#else
+#define JZ4740_MMC_PM_OPS NULL
+#endif
+
+static struct platform_driver jz4740_mmc_driver = {
+	.probe = jz4740_mmc_probe,
+	.remove = __devexit_p(jz4740_mmc_remove),
+	.driver = {
+		.name = "jz4740-mmc",
+		.owner = THIS_MODULE,
+		.pm = JZ4740_MMC_PM_OPS,
+	},
+};
+
+static int __init jz4740_mmc_init(void)
+{
+	return platform_driver_register(&jz4740_mmc_driver);
+}
+module_init(jz4740_mmc_init);
+
+static void __exit jz4740_mmc_exit(void)
+{
+	platform_driver_unregister(&jz4740_mmc_driver);
+}
+module_exit(jz4740_mmc_exit);
+
+MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index ffc3720929f10efaca858758902e891220423ee3..362d177efe1b4cb567be70bd980dad4db3bec980 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -526,4 +526,10 @@ config MTD_NAND_NUC900
 	  This enables the driver for the NAND Flash on evaluation board based
 	  on w90p910 / NUC9xx.
 
+config MTD_NAND_JZ4740
+	tristate "Support for JZ4740 SoC NAND controller"
+	depends on MACH_JZ4740
+	help
+		Enables support for NAND Flash on JZ4740 SoC based boards.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index e8ab884ba47bdc562b0d180986cf34d9f2ef19fd..ac83dcdac5d6182048e2279d24659126cd903a72 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -46,5 +46,6 @@ obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
 obj-$(CONFIG_MTD_NAND_BCM_UMI)		+= bcm_umi_nand.o nand_bcm_umi.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
+obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
new file mode 100644
index 0000000000000000000000000000000000000000..67343fc31bd5fc38e61531cf242f790369820d3e
--- /dev/null
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -0,0 +1,516 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC NAND controller driver
+ *
+ *  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.
+ *
+ *  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/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/gpio.h>
+
+#include <asm/mach-jz4740/jz4740_nand.h>
+
+#define JZ_REG_NAND_CTRL	0x50
+#define JZ_REG_NAND_ECC_CTRL	0x100
+#define JZ_REG_NAND_DATA	0x104
+#define JZ_REG_NAND_PAR0	0x108
+#define JZ_REG_NAND_PAR1	0x10C
+#define JZ_REG_NAND_PAR2	0x110
+#define JZ_REG_NAND_IRQ_STAT	0x114
+#define JZ_REG_NAND_IRQ_CTRL	0x118
+#define JZ_REG_NAND_ERR(x)	(0x11C + ((x) << 2))
+
+#define JZ_NAND_ECC_CTRL_PAR_READY	BIT(4)
+#define JZ_NAND_ECC_CTRL_ENCODING	BIT(3)
+#define JZ_NAND_ECC_CTRL_RS		BIT(2)
+#define JZ_NAND_ECC_CTRL_RESET		BIT(1)
+#define JZ_NAND_ECC_CTRL_ENABLE		BIT(0)
+
+#define JZ_NAND_STATUS_ERR_COUNT	(BIT(31) | BIT(30) | BIT(29))
+#define JZ_NAND_STATUS_PAD_FINISH	BIT(4)
+#define JZ_NAND_STATUS_DEC_FINISH	BIT(3)
+#define JZ_NAND_STATUS_ENC_FINISH	BIT(2)
+#define JZ_NAND_STATUS_UNCOR_ERROR	BIT(1)
+#define JZ_NAND_STATUS_ERROR		BIT(0)
+
+#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1)
+#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1)
+
+#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
+#define JZ_NAND_MEM_CMD_OFFSET 0x08000
+
+struct jz_nand {
+	struct mtd_info mtd;
+	struct nand_chip chip;
+	void __iomem *base;
+	struct resource *mem;
+
+	void __iomem *bank_base;
+	struct resource *bank_mem;
+
+	struct jz_nand_platform_data *pdata;
+	bool is_reading;
+};
+
+static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct jz_nand, mtd);
+}
+
+static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+{
+	struct jz_nand *nand = mtd_to_jz_nand(mtd);
+	struct nand_chip *chip = mtd->priv;
+	uint32_t reg;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
+		if (ctrl & NAND_ALE)
+			chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_ADDR_OFFSET;
+		else if (ctrl & NAND_CLE)
+			chip->IO_ADDR_W = nand->bank_base + JZ_NAND_MEM_CMD_OFFSET;
+		else
+			chip->IO_ADDR_W = nand->bank_base;
+
+		reg = readl(nand->base + JZ_REG_NAND_CTRL);
+		if (ctrl & NAND_NCE)
+			reg |= JZ_NAND_CTRL_ASSERT_CHIP(0);
+		else
+			reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0);
+		writel(reg, nand->base + JZ_REG_NAND_CTRL);
+	}
+	if (dat != NAND_CMD_NONE)
+		writeb(dat, chip->IO_ADDR_W);
+}
+
+static int jz_nand_dev_ready(struct mtd_info *mtd)
+{
+	struct jz_nand *nand = mtd_to_jz_nand(mtd);
+	return gpio_get_value_cansleep(nand->pdata->busy_gpio);
+}
+
+static void jz_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+	struct jz_nand *nand = mtd_to_jz_nand(mtd);
+	uint32_t reg;
+
+	writel(0, nand->base + JZ_REG_NAND_IRQ_STAT);
+	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
+
+	reg |= JZ_NAND_ECC_CTRL_RESET;
+	reg |= JZ_NAND_ECC_CTRL_ENABLE;
+	reg |= JZ_NAND_ECC_CTRL_RS;
+
+	switch (mode) {
+	case NAND_ECC_READ:
+		reg &= ~JZ_NAND_ECC_CTRL_ENCODING;
+		nand->is_reading = true;
+		break;
+	case NAND_ECC_WRITE:
+		reg |= JZ_NAND_ECC_CTRL_ENCODING;
+		nand->is_reading = false;
+		break;
+	default:
+		break;
+	}
+
+	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
+}
+
+static int jz_nand_calculate_ecc_rs(struct mtd_info *mtd, const uint8_t *dat,
+	uint8_t *ecc_code)
+{
+	struct jz_nand *nand = mtd_to_jz_nand(mtd);
+	uint32_t reg, status;
+	int i;
+	unsigned int timeout = 1000;
+	static uint8_t empty_block_ecc[] = {0xcd, 0x9d, 0x90, 0x58, 0xf4,
+						0x8b, 0xff, 0xb7, 0x6f};
+
+	if (nand->is_reading)
+		return 0;
+
+	do {
+		status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
+	} while (!(status & JZ_NAND_STATUS_ENC_FINISH) && --timeout);
+
+	if (timeout == 0)
+	    return -1;
+
+	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
+	reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
+	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
+
+	for (i = 0; i < 9; ++i)
+		ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i);
+
+	/* If the written data is completly 0xff, we also want to write 0xff as
+	 * ecc, otherwise we will get in trouble when doing subpage writes. */
+	if (memcmp(ecc_code, empty_block_ecc, 9) == 0)
+		memset(ecc_code, 0xff, 9);
+
+	return 0;
+}
+
+static void jz_nand_correct_data(uint8_t *dat, int index, int mask)
+{
+	int offset = index & 0x7;
+	uint16_t data;
+
+	index += (index >> 3);
+
+	data = dat[index];
+	data |= dat[index+1] << 8;
+
+	mask ^= (data >> offset) & 0x1ff;
+	data &= ~(0x1ff << offset);
+	data |= (mask << offset);
+
+	dat[index] = data & 0xff;
+	dat[index+1] = (data >> 8) & 0xff;
+}
+
+static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
+	uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+	struct jz_nand *nand = mtd_to_jz_nand(mtd);
+	int i, error_count, index;
+	uint32_t reg, status, error;
+	uint32_t t;
+	unsigned int timeout = 1000;
+
+	t = read_ecc[0];
+
+	if (t == 0xff) {
+		for (i = 1; i < 9; ++i)
+			t &= read_ecc[i];
+
+		t &= dat[0];
+		t &= dat[nand->chip.ecc.size / 2];
+		t &= dat[nand->chip.ecc.size - 1];
+
+		if (t == 0xff) {
+			for (i = 1; i < nand->chip.ecc.size - 1; ++i)
+				t &= dat[i];
+			if (t == 0xff)
+				return 0;
+		}
+	}
+
+	for (i = 0; i < 9; ++i)
+		writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i);
+
+	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
+	reg |= JZ_NAND_ECC_CTRL_PAR_READY;
+	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
+
+	do {
+		status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
+	} while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout);
+
+	if (timeout == 0)
+	    return -1;
+
+	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
+	reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
+	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
+
+	if (status & JZ_NAND_STATUS_ERROR) {
+		if (status & JZ_NAND_STATUS_UNCOR_ERROR)
+			return -1;
+
+		error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29;
+
+		for (i = 0; i < error_count; ++i) {
+			error = readl(nand->base + JZ_REG_NAND_ERR(i));
+			index = ((error >> 16) & 0x1ff) - 1;
+			if (index >= 0 && index < 512)
+				jz_nand_correct_data(dat, index, error & 0x1ff);
+		}
+
+		return error_count;
+	}
+
+	return 0;
+}
+
+
+/* Copy paste of nand_read_page_hwecc_oob_first except for different eccpos
+ * handling. The ecc area is for 4k chips 72 bytes long and thus does not fit
+ * into the eccpos array. */
+static int jz_nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
+	struct nand_chip *chip, uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	unsigned int ecc_offset = chip->page_shift;
+
+	/* Read the OOB area first */
+	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		chip->read_buf(mtd, p, eccsize);
+
+		stat = chip->ecc.correct(mtd, p, &chip->oob_poi[i], NULL);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+
+/* Copy-and-paste of nand_write_page_hwecc with different eccpos handling. */
+static void jz_nand_write_page_hwecc(struct mtd_info *mtd,
+	struct nand_chip *chip, const uint8_t *buf)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	const uint8_t *p = buf;
+	unsigned int ecc_offset = chip->page_shift;
+
+	for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+		chip->write_buf(mtd, p, eccsize);
+		chip->ecc.calculate(mtd, p, &chip->oob_poi[i]);
+	}
+
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+}
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+static const char *part_probes[] = {"cmdline", NULL};
+#endif
+
+static int jz_nand_ioremap_resource(struct platform_device *pdev,
+	const char *name, struct resource **res, void __iomem **base)
+{
+	int ret;
+
+	*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	if (!*res) {
+		dev_err(&pdev->dev, "Failed to get platform %s memory\n", name);
+		ret = -ENXIO;
+		goto err;
+	}
+
+	*res = request_mem_region((*res)->start, resource_size(*res),
+				pdev->name);
+	if (!*res) {
+		dev_err(&pdev->dev, "Failed to request %s memory region\n", name);
+		ret = -EBUSY;
+		goto err;
+	}
+
+	*base = ioremap((*res)->start, resource_size(*res));
+	if (!*base) {
+		dev_err(&pdev->dev, "Failed to ioremap %s memory region\n", name);
+		ret = -EBUSY;
+		goto err_release_mem;
+	}
+
+	return 0;
+
+err_release_mem:
+	release_mem_region((*res)->start, resource_size(*res));
+err:
+	*res = NULL;
+	*base = NULL;
+	return ret;
+}
+
+static int __devinit jz_nand_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct jz_nand *nand;
+	struct nand_chip *chip;
+	struct mtd_info *mtd;
+	struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
+#ifdef CONFIG_MTD_PARTITIONS
+	struct mtd_partition *partition_info;
+	int num_partitions = 0;
+#endif
+
+	nand = kzalloc(sizeof(*nand), GFP_KERNEL);
+	if (!nand) {
+		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
+		return -ENOMEM;
+	}
+
+	ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
+	if (ret)
+		goto err_free;
+	ret = jz_nand_ioremap_resource(pdev, "bank", &nand->bank_mem,
+			&nand->bank_base);
+	if (ret)
+		goto err_iounmap_mmio;
+
+	if (pdata && gpio_is_valid(pdata->busy_gpio)) {
+		ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to request busy gpio %d: %d\n",
+				pdata->busy_gpio, ret);
+			goto err_iounmap_mem;
+		}
+	}
+
+	mtd		= &nand->mtd;
+	chip		= &nand->chip;
+	mtd->priv	= chip;
+	mtd->owner	= THIS_MODULE;
+	mtd->name	= "jz4740-nand";
+
+	chip->ecc.hwctl		= jz_nand_hwctl;
+	chip->ecc.calculate	= jz_nand_calculate_ecc_rs;
+	chip->ecc.correct	= jz_nand_correct_ecc_rs;
+	chip->ecc.mode		= NAND_ECC_HW_OOB_FIRST;
+	chip->ecc.size		= 512;
+	chip->ecc.bytes		= 9;
+
+	chip->ecc.read_page	= jz_nand_read_page_hwecc_oob_first;
+	chip->ecc.write_page	= jz_nand_write_page_hwecc;
+
+	if (pdata)
+		chip->ecc.layout = pdata->ecc_layout;
+
+	chip->chip_delay = 50;
+	chip->cmd_ctrl = jz_nand_cmd_ctrl;
+
+	if (pdata && gpio_is_valid(pdata->busy_gpio))
+		chip->dev_ready = jz_nand_dev_ready;
+
+	chip->IO_ADDR_R = nand->bank_base;
+	chip->IO_ADDR_W = nand->bank_base;
+
+	nand->pdata = pdata;
+	platform_set_drvdata(pdev, nand);
+
+	writel(JZ_NAND_CTRL_ENABLE_CHIP(0), nand->base + JZ_REG_NAND_CTRL);
+
+	ret = nand_scan_ident(mtd, 1, NULL);
+	if (ret) {
+		dev_err(&pdev->dev,  "Failed to scan nand\n");
+		goto err_gpio_free;
+	}
+
+	if (pdata && pdata->ident_callback) {
+		pdata->ident_callback(pdev, chip, &pdata->partitions,
+					&pdata->num_partitions);
+	}
+
+	ret = nand_scan_tail(mtd);
+	if (ret) {
+		dev_err(&pdev->dev,  "Failed to scan nand\n");
+		goto err_gpio_free;
+	}
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	num_partitions = parse_mtd_partitions(mtd, part_probes,
+						&partition_info, 0);
+#endif
+	if (num_partitions <= 0 && pdata) {
+		num_partitions = pdata->num_partitions;
+		partition_info = pdata->partitions;
+	}
+
+	if (num_partitions > 0)
+		ret = add_mtd_partitions(mtd, partition_info, num_partitions);
+	else
+#endif
+	ret = add_mtd_device(mtd);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add mtd device\n");
+		goto err_nand_release;
+	}
+
+	dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n");
+
+	return 0;
+
+err_nand_release:
+	nand_release(&nand->mtd);
+err_gpio_free:
+	platform_set_drvdata(pdev, NULL);
+	gpio_free(pdata->busy_gpio);
+err_iounmap_mem:
+	iounmap(nand->bank_base);
+err_iounmap_mmio:
+	iounmap(nand->base);
+err_free:
+	kfree(nand);
+	return ret;
+}
+
+static int __devexit jz_nand_remove(struct platform_device *pdev)
+{
+	struct jz_nand *nand = platform_get_drvdata(pdev);
+
+	nand_release(&nand->mtd);
+
+	/* Deassert and disable all chips */
+	writel(0, nand->base + JZ_REG_NAND_CTRL);
+
+	iounmap(nand->bank_base);
+	release_mem_region(nand->bank_mem->start, resource_size(nand->bank_mem));
+	iounmap(nand->base);
+	release_mem_region(nand->mem->start, resource_size(nand->mem));
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(nand);
+
+	return 0;
+}
+
+struct platform_driver jz_nand_driver = {
+	.probe = jz_nand_probe,
+	.remove = __devexit_p(jz_nand_remove),
+	.driver = {
+		.name = "jz4740-nand",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init jz_nand_init(void)
+{
+	return platform_driver_register(&jz_nand_driver);
+}
+module_init(jz_nand_init);
+
+static void __exit jz_nand_exit(void)
+{
+	platform_driver_unregister(&jz_nand_driver);
+}
+module_exit(jz_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("NAND controller driver for JZ4740 SoC");
+MODULE_ALIAS("platform:jz4740-nand");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ebe68395ecf8c98cd292052d6e78cf5ad9f4ff31..23c13180ff14811dd5925e231db7ac795c99c05c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -484,7 +484,7 @@ config XTENSA_XT2000_SONIC
 
 config MIPS_AU1X00_ENET
 	tristate "MIPS AU1000 Ethernet support"
-	depends on SOC_AU1X00
+	depends on MIPS_ALCHEMY
 	select PHYLIB
 	select CRC32
 	help
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 386d4feec652b4d33ec0b5648c176b3b2048d0bf..15ae6df2ff00b89885e778f8b1a8241a1959ddc3 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -104,14 +104,6 @@ MODULE_VERSION(DRV_VERSION);
  * complete immediately.
  */
 
-/* These addresses are only used if yamon doesn't tell us what
- * the mac address is, and the mac address is not passed on the
- * command line.
- */
-static unsigned char au1000_mac_addr[6] __devinitdata = {
-	0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
-};
-
 struct au1000_private *au_macs[NUM_ETH_INTERFACES];
 
 /*
@@ -1002,7 +994,6 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	db_dest_t *pDB, *pDBfree;
 	int irq, i, err = 0;
 	struct resource *base, *macen;
-	char ethaddr[6];
 
 	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!base) {
@@ -1079,24 +1070,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 	aup->mac_id = pdev->id;
 
-	if (pdev->id == 0) {
-		if (prom_get_ethernet_addr(ethaddr) == 0)
-			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
-		else {
-			netdev_info(dev, "No MAC address found\n");
-				/* Use the hard coded MAC addresses */
-		}
-
+	if (pdev->id == 0)
 		au1000_setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-	} else if (pdev->id == 1)
+	else if (pdev->id == 1)
 		au1000_setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 
-	/*
-	 * Assign to the Ethernet ports two consecutive MAC addresses
-	 * to match those that are printed on their stickers
-	 */
-	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
-	dev->dev_addr[5] += pdev->id;
+	/* set a random MAC now in case platform_data doesn't provide one */
+	random_ether_addr(dev->dev_addr);
 
 	*aup->enable = 0;
 	aup->mac_enabled = 0;
@@ -1106,6 +1086,9 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
 		aup->phy1_search_mac0 = 1;
 	} else {
+		if (is_valid_ether_addr(pd->mac))
+			memcpy(dev->dev_addr, pd->mac, 6);
+
 		aup->phy_static_config = pd->phy_static_config;
 		aup->phy_search_highest_addr = pd->phy_search_highest_addr;
 		aup->phy1_search_mac0 = pd->phy1_search_mac0;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d0f5ad306078f8714c2cd6739717b2f380d42ce1..c988514eb5512fa047b6b2431f0a2b6280149510 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -157,11 +157,11 @@ config PCMCIA_M8XX
 
 config PCMCIA_AU1X00
 	tristate "Au1x00 pcmcia support"
-	depends on SOC_AU1X00 && PCMCIA
+	depends on MIPS_ALCHEMY && PCMCIA
 
 config PCMCIA_ALCHEMY_DEVBOARD
 	tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
-	depends on SOC_AU1X00 && PCMCIA
+	depends on MIPS_ALCHEMY && PCMCIA
 	select 64BIT_PHYS_ADDR
 	help
 	  Enable this driver of you want PCMCIA support on your Alchemy
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 8e9ba177d8173b7df7794c19f0a691c9fca8c60a..1e5506be39b4b1a4c58d1e818761bbfb3dd9a3c9 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -142,4 +142,15 @@ config CHARGER_PCF50633
 	help
 	 Say Y to include support for NXP PCF50633 Main Battery Charger.
 
+config BATTERY_JZ4740
+	tristate "Ingenic JZ4740 battery"
+	depends on MACH_JZ4740
+	depends on MFD_JZ4740_ADC
+	help
+	  Say Y to enable support for the battery on Ingenic JZ4740 based
+	  boards.
+
+	  This driver can be build as a module. If so, the module will be
+	  called jz4740-battery.
+
 endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 00050809a6c7498e5a8eaa7dbe6bbc5defeec17b..cf95009d9bcda05795984877805b56d5f1275566 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_BATTERY_DA9030)	+= da9030_battery.o
 obj-$(CONFIG_BATTERY_MAX17040)	+= max17040_battery.o
 obj-$(CONFIG_BATTERY_Z2)	+= z2_battery.o
 obj-$(CONFIG_CHARGER_PCF50633)	+= pcf50633-charger.o
+obj-$(CONFIG_BATTERY_JZ4740)	+= jz4740-battery.o
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
new file mode 100644
index 0000000000000000000000000000000000000000..20c4b952e9bd1f6cbd75887b79f81b226a36a436
--- /dev/null
+++ b/drivers/power/jz4740-battery.c
@@ -0,0 +1,445 @@
+/*
+ * Battery measurement code for Ingenic JZ SOC.
+ *
+ * Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com>
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * based on tosa_battery.c
+ *
+ * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
+*
+ * 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.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/power_supply.h>
+
+#include <linux/power/jz4740-battery.h>
+#include <linux/jz4740-adc.h>
+
+struct jz_battery {
+	struct jz_battery_platform_data *pdata;
+	struct platform_device *pdev;
+
+	struct resource *mem;
+	void __iomem *base;
+
+	int irq;
+	int charge_irq;
+
+	struct mfd_cell *cell;
+
+	int status;
+	long voltage;
+
+	struct completion read_completion;
+
+	struct power_supply battery;
+	struct delayed_work work;
+};
+
+static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy)
+{
+	return container_of(psy, struct jz_battery, battery);
+}
+
+static irqreturn_t jz_battery_irq_handler(int irq, void *devid)
+{
+	struct jz_battery *battery = devid;
+
+	complete(&battery->read_completion);
+	return IRQ_HANDLED;
+}
+
+static long jz_battery_read_voltage(struct jz_battery *battery)
+{
+	unsigned long t;
+	unsigned long val;
+	long voltage;
+
+	INIT_COMPLETION(battery->read_completion);
+
+	enable_irq(battery->irq);
+	battery->cell->enable(battery->pdev);
+
+	t = wait_for_completion_interruptible_timeout(&battery->read_completion,
+		HZ);
+
+	if (t > 0) {
+		val = readw(battery->base) & 0xfff;
+
+		if (battery->pdata->info.voltage_max_design <= 2500000)
+			val = (val * 78125UL) >> 7UL;
+		else
+			val = ((val * 924375UL) >> 9UL) + 33000;
+		voltage = (long)val;
+	} else {
+		voltage = t ? t : -ETIMEDOUT;
+	}
+
+	battery->cell->disable(battery->pdev);
+	disable_irq(battery->irq);
+
+	return voltage;
+}
+
+static int jz_battery_get_capacity(struct power_supply *psy)
+{
+	struct jz_battery *jz_battery = psy_to_jz_battery(psy);
+	struct power_supply_info *info = &jz_battery->pdata->info;
+	long voltage;
+	int ret;
+	int voltage_span;
+
+	voltage = jz_battery_read_voltage(jz_battery);
+
+	if (voltage < 0)
+		return voltage;
+
+	voltage_span = info->voltage_max_design - info->voltage_min_design;
+	ret = ((voltage - info->voltage_min_design) * 100) / voltage_span;
+
+	if (ret > 100)
+		ret = 100;
+	else if (ret < 0)
+		ret = 0;
+
+	return ret;
+}
+
+static int jz_battery_get_property(struct power_supply *psy,
+	enum power_supply_property psp, union power_supply_propval *val)
+{
+	struct jz_battery *jz_battery = psy_to_jz_battery(psy);
+	struct power_supply_info *info = &jz_battery->pdata->info;
+	long voltage;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = jz_battery->status;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = jz_battery->pdata->info.technology;
+		break;
+	case POWER_SUPPLY_PROP_HEALTH:
+		voltage = jz_battery_read_voltage(jz_battery);
+		if (voltage < info->voltage_min_design)
+			val->intval = POWER_SUPPLY_HEALTH_DEAD;
+		else
+			val->intval = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = jz_battery_get_capacity(psy);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = jz_battery_read_voltage(jz_battery);
+		if (val->intval < 0)
+			return val->intval;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		val->intval = info->voltage_max_design;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = info->voltage_min_design;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void jz_battery_external_power_changed(struct power_supply *psy)
+{
+	struct jz_battery *jz_battery = psy_to_jz_battery(psy);
+
+	cancel_delayed_work(&jz_battery->work);
+	schedule_delayed_work(&jz_battery->work, 0);
+}
+
+static irqreturn_t jz_battery_charge_irq(int irq, void *data)
+{
+	struct jz_battery *jz_battery = data;
+
+	cancel_delayed_work(&jz_battery->work);
+	schedule_delayed_work(&jz_battery->work, 0);
+
+	return IRQ_HANDLED;
+}
+
+static void jz_battery_update(struct jz_battery *jz_battery)
+{
+	int status;
+	long voltage;
+	bool has_changed = false;
+	int is_charging;
+
+	if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
+		is_charging = gpio_get_value(jz_battery->pdata->gpio_charge);
+		is_charging ^= jz_battery->pdata->gpio_charge_active_low;
+		if (is_charging)
+			status = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+
+		if (status != jz_battery->status) {
+			jz_battery->status = status;
+			has_changed = true;
+		}
+	}
+
+	voltage = jz_battery_read_voltage(jz_battery);
+	if (abs(voltage - jz_battery->voltage) < 50000) {
+		jz_battery->voltage = voltage;
+		has_changed = true;
+	}
+
+	if (has_changed)
+		power_supply_changed(&jz_battery->battery);
+}
+
+static enum power_supply_property jz_battery_properties[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_PRESENT,
+};
+
+static void jz_battery_work(struct work_struct *work)
+{
+	/* Too small interval will increase system workload */
+	const int interval = HZ * 30;
+	struct jz_battery *jz_battery = container_of(work, struct jz_battery,
+					    work.work);
+
+	jz_battery_update(jz_battery);
+	schedule_delayed_work(&jz_battery->work, interval);
+}
+
+static int __devinit jz_battery_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data;
+	struct jz_battery *jz_battery;
+	struct power_supply *battery;
+
+	jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL);
+	if (!jz_battery) {
+		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+		return -ENOMEM;
+	}
+
+	jz_battery->cell = pdev->dev.platform_data;
+
+	jz_battery->irq = platform_get_irq(pdev, 0);
+	if (jz_battery->irq < 0) {
+		ret = jz_battery->irq;
+		dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
+		goto err_free;
+	}
+
+	jz_battery->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!jz_battery->mem) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
+		goto err_free;
+	}
+
+	jz_battery->mem = request_mem_region(jz_battery->mem->start,
+				resource_size(jz_battery->mem),	pdev->name);
+	if (!jz_battery->mem) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
+		goto err_free;
+	}
+
+	jz_battery->base = ioremap_nocache(jz_battery->mem->start,
+				resource_size(jz_battery->mem));
+	if (!jz_battery->base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
+		goto err_release_mem_region;
+	}
+
+	battery = &jz_battery->battery;
+	battery->name = pdata->info.name;
+	battery->type = POWER_SUPPLY_TYPE_BATTERY;
+	battery->properties	= jz_battery_properties;
+	battery->num_properties	= ARRAY_SIZE(jz_battery_properties);
+	battery->get_property = jz_battery_get_property;
+	battery->external_power_changed = jz_battery_external_power_changed;
+	battery->use_for_apm = 1;
+
+	jz_battery->pdata = pdata;
+	jz_battery->pdev = pdev;
+
+	init_completion(&jz_battery->read_completion);
+
+	INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work);
+
+	ret = request_irq(jz_battery->irq, jz_battery_irq_handler, 0, pdev->name,
+			jz_battery);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
+		goto err_iounmap;
+	}
+	disable_irq(jz_battery->irq);
+
+	if (gpio_is_valid(pdata->gpio_charge)) {
+		ret = gpio_request(pdata->gpio_charge, dev_name(&pdev->dev));
+		if (ret) {
+			dev_err(&pdev->dev, "charger state gpio request failed.\n");
+			goto err_free_irq;
+		}
+		ret = gpio_direction_input(pdata->gpio_charge);
+		if (ret) {
+			dev_err(&pdev->dev, "charger state gpio set direction failed.\n");
+			goto err_free_gpio;
+		}
+
+		jz_battery->charge_irq = gpio_to_irq(pdata->gpio_charge);
+
+		if (jz_battery->charge_irq >= 0) {
+			ret = request_irq(jz_battery->charge_irq,
+				    jz_battery_charge_irq,
+				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				    dev_name(&pdev->dev), jz_battery);
+			if (ret) {
+				dev_err(&pdev->dev, "Failed to request charge irq: %d\n", ret);
+				goto err_free_gpio;
+			}
+		}
+	} else {
+		jz_battery->charge_irq = -1;
+	}
+
+	if (jz_battery->pdata->info.voltage_max_design <= 2500000)
+		jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB,
+			JZ_ADC_CONFIG_BAT_MB);
+	else
+		jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 0);
+
+	ret = power_supply_register(&pdev->dev, &jz_battery->battery);
+	if (ret) {
+		dev_err(&pdev->dev, "power supply battery register failed.\n");
+		goto err_free_charge_irq;
+	}
+
+	platform_set_drvdata(pdev, jz_battery);
+	schedule_delayed_work(&jz_battery->work, 0);
+
+	return 0;
+
+err_free_charge_irq:
+	if (jz_battery->charge_irq >= 0)
+		free_irq(jz_battery->charge_irq, jz_battery);
+err_free_gpio:
+	if (gpio_is_valid(pdata->gpio_charge))
+		gpio_free(jz_battery->pdata->gpio_charge);
+err_free_irq:
+	free_irq(jz_battery->irq, jz_battery);
+err_iounmap:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(jz_battery->base);
+err_release_mem_region:
+	release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem));
+err_free:
+	kfree(jz_battery);
+	return ret;
+}
+
+static int __devexit jz_battery_remove(struct platform_device *pdev)
+{
+	struct jz_battery *jz_battery = platform_get_drvdata(pdev);
+
+	cancel_delayed_work_sync(&jz_battery->work);
+
+	if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
+		if (jz_battery->charge_irq >= 0)
+			free_irq(jz_battery->charge_irq, jz_battery);
+		gpio_free(jz_battery->pdata->gpio_charge);
+	}
+
+	power_supply_unregister(&jz_battery->battery);
+
+	free_irq(jz_battery->irq, jz_battery);
+
+	iounmap(jz_battery->base);
+	release_mem_region(jz_battery->mem->start, resource_size(jz_battery->mem));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int jz_battery_suspend(struct device *dev)
+{
+	struct jz_battery *jz_battery = dev_get_drvdata(dev);
+
+	cancel_delayed_work_sync(&jz_battery->work);
+	jz_battery->status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+	return 0;
+}
+
+static int jz_battery_resume(struct device *dev)
+{
+	struct jz_battery *jz_battery = dev_get_drvdata(dev);
+
+	schedule_delayed_work(&jz_battery->work, 0);
+
+	return 0;
+}
+
+static const struct dev_pm_ops jz_battery_pm_ops = {
+	.suspend	= jz_battery_suspend,
+	.resume		= jz_battery_resume,
+};
+
+#define JZ_BATTERY_PM_OPS (&jz_battery_pm_ops)
+#else
+#define JZ_BATTERY_PM_OPS NULL
+#endif
+
+static struct platform_driver jz_battery_driver = {
+	.probe		= jz_battery_probe,
+	.remove		= __devexit_p(jz_battery_remove),
+	.driver = {
+		.name = "jz4740-battery",
+		.owner = THIS_MODULE,
+		.pm = JZ_BATTERY_PM_OPS,
+	},
+};
+
+static int __init jz_battery_init(void)
+{
+	return platform_driver_register(&jz_battery_driver);
+}
+module_init(jz_battery_init);
+
+static void __exit jz_battery_exit(void)
+{
+	platform_driver_unregister(&jz_battery_driver);
+}
+module_exit(jz_battery_exit);
+
+MODULE_ALIAS("platform:jz4740-battery");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("JZ4740 SoC battery driver");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 10ba12c8c5e004a044c59ec7a77a91f58cf8f61e..4301a6c7ed3b5c65fecb5a16136591076b8ed4ee 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -774,7 +774,7 @@ config RTC_DRV_AT91SAM9_GPBR
 
 config RTC_DRV_AU1XXX
 	tristate "Au1xxx Counter0 RTC support"
-	depends on SOC_AU1X00
+	depends on MIPS_ALCHEMY
 	help
 	  This is a driver for the Au1xxx on-chip Counter0 (Time-Of-Year
 	  counter) to be used as a RTC.
@@ -905,4 +905,15 @@ config RTC_DRV_MPC5121
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-mpc5121.
 
+config RTC_DRV_JZ4740
+	tristate "Ingenic JZ4740 SoC"
+	depends on RTC_CLASS
+	depends on MACH_JZ4740
+	help
+	  If you say yes here you get support for the Ingenic JZ4740 SoC RTC
+	  controller.
+
+	  This driver can also be buillt as a module. If so, the module
+	  will be called rtc-jz4740.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 5adbba7cf89cfdde453caf77e4571ab1786b9b16..fedf9bb3659305137bfc7e3b04d26230cd66085a 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX)	+= rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)	+= rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
 obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
+obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o
 obj-$(CONFIG_RTC_DRV_M41T80)	+= rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T94)	+= rtc-m41t94.o
 obj-$(CONFIG_RTC_DRV_M48T35)	+= rtc-m48t35.o
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
new file mode 100644
index 0000000000000000000000000000000000000000..2619d57b91d76ee83236bd47a967d093984712a1
--- /dev/null
+++ b/drivers/rtc/rtc-jz4740.c
@@ -0,0 +1,345 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *	 JZ4740 SoC RTC driver
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define JZ_REG_RTC_CTRL		0x00
+#define JZ_REG_RTC_SEC		0x04
+#define JZ_REG_RTC_SEC_ALARM	0x08
+#define JZ_REG_RTC_REGULATOR	0x0C
+#define JZ_REG_RTC_HIBERNATE	0x20
+#define JZ_REG_RTC_SCRATCHPAD	0x34
+
+#define JZ_RTC_CTRL_WRDY	BIT(7)
+#define JZ_RTC_CTRL_1HZ		BIT(6)
+#define JZ_RTC_CTRL_1HZ_IRQ	BIT(5)
+#define JZ_RTC_CTRL_AF		BIT(4)
+#define JZ_RTC_CTRL_AF_IRQ	BIT(3)
+#define JZ_RTC_CTRL_AE		BIT(2)
+#define JZ_RTC_CTRL_ENABLE	BIT(0)
+
+struct jz4740_rtc {
+	struct resource *mem;
+	void __iomem *base;
+
+	struct rtc_device *rtc;
+
+	unsigned int irq;
+
+	spinlock_t lock;
+};
+
+static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
+{
+	return readl(rtc->base + reg);
+}
+
+static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
+{
+	uint32_t ctrl;
+	int timeout = 1000;
+
+	do {
+		ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
+	} while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout);
+
+	return timeout ? 0 : -EIO;
+}
+
+static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
+	uint32_t val)
+{
+	int ret;
+	ret = jz4740_rtc_wait_write_ready(rtc);
+	if (ret == 0)
+		writel(val, rtc->base + reg);
+
+	return ret;
+}
+
+static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
+	bool set)
+{
+	int ret;
+	unsigned long flags;
+	uint32_t ctrl;
+
+	spin_lock_irqsave(&rtc->lock, flags);
+
+	ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
+
+	/* Don't clear interrupt flags by accident */
+	ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;
+
+	if (set)
+		ctrl |= mask;
+	else
+		ctrl &= ~mask;
+
+	ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
+
+	spin_unlock_irqrestore(&rtc->lock, flags);
+
+	return ret;
+}
+
+static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	uint32_t secs, secs2;
+	int timeout = 5;
+
+	/* If the seconds register is read while it is updated, it can contain a
+	 * bogus value. This can be avoided by making sure that two consecutive
+	 * reads have the same value.
+	 */
+	secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
+	secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
+
+	while (secs != secs2 && --timeout) {
+		secs = secs2;
+		secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
+	}
+
+	if (timeout == 0)
+		return -EIO;
+
+	rtc_time_to_tm(secs, time);
+
+	return rtc_valid_tm(time);
+}
+
+static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+
+	return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
+}
+
+static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	uint32_t secs;
+	uint32_t ctrl;
+
+	secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
+
+	ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
+
+	alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE);
+	alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF);
+
+	rtc_time_to_tm(secs, &alrm->time);
+
+	return rtc_valid_tm(&alrm->time);
+}
+
+static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	int ret;
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	unsigned long secs;
+
+	rtc_tm_to_time(&alrm->time, &secs);
+
+	ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs);
+	if (!ret)
+		ret = jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, alrm->enabled);
+
+	return ret;
+}
+
+static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable);
+}
+
+static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable);
+}
+
+static struct rtc_class_ops jz4740_rtc_ops = {
+	.read_time	= jz4740_rtc_read_time,
+	.set_mmss	= jz4740_rtc_set_mmss,
+	.read_alarm	= jz4740_rtc_read_alarm,
+	.set_alarm	= jz4740_rtc_set_alarm,
+	.update_irq_enable = jz4740_rtc_update_irq_enable,
+	.alarm_irq_enable = jz4740_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t jz4740_rtc_irq(int irq, void *data)
+{
+	struct jz4740_rtc *rtc = data;
+	uint32_t ctrl;
+	unsigned long events = 0;
+
+	ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
+
+	if (ctrl & JZ_RTC_CTRL_1HZ)
+		events |= (RTC_UF | RTC_IRQF);
+
+	if (ctrl & JZ_RTC_CTRL_AF)
+		events |= (RTC_AF | RTC_IRQF);
+
+	rtc_update_irq(rtc->rtc, 1, events);
+
+	jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false);
+
+	return IRQ_HANDLED;
+}
+
+void jz4740_rtc_poweroff(struct device *dev)
+{
+	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+	jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1);
+}
+EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff);
+
+static int __devinit jz4740_rtc_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct jz4740_rtc *rtc;
+	uint32_t scratchpad;
+
+	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+	if (!rtc)
+		return -ENOMEM;
+
+	rtc->irq = platform_get_irq(pdev, 0);
+	if (rtc->irq < 0) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get platform irq\n");
+		goto err_free;
+	}
+
+	rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!rtc->mem) {
+		ret = -ENOENT;
+		dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
+		goto err_free;
+	}
+
+	rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
+					pdev->name);
+	if (!rtc->mem) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
+		goto err_free;
+	}
+
+	rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
+	if (!rtc->base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
+		goto err_release_mem_region;
+	}
+
+	spin_lock_init(&rtc->lock);
+
+	platform_set_drvdata(pdev, rtc);
+
+	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
+					THIS_MODULE);
+	if (IS_ERR(rtc->rtc)) {
+		ret = PTR_ERR(rtc->rtc);
+		dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
+		goto err_iounmap;
+	}
+
+	ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
+				pdev->name, rtc);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
+		goto err_unregister_rtc;
+	}
+
+	scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
+	if (scratchpad != 0x12345678) {
+		ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
+		ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
+		if (ret) {
+			dev_err(&pdev->dev, "Could not write write to RTC registers\n");
+			goto err_free_irq;
+		}
+	}
+
+	return 0;
+
+err_free_irq:
+	free_irq(rtc->irq, rtc);
+err_unregister_rtc:
+	rtc_device_unregister(rtc->rtc);
+err_iounmap:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(rtc->base);
+err_release_mem_region:
+	release_mem_region(rtc->mem->start, resource_size(rtc->mem));
+err_free:
+	kfree(rtc);
+
+	return ret;
+}
+
+static int __devexit jz4740_rtc_remove(struct platform_device *pdev)
+{
+	struct jz4740_rtc *rtc = platform_get_drvdata(pdev);
+
+	free_irq(rtc->irq, rtc);
+
+	rtc_device_unregister(rtc->rtc);
+
+	iounmap(rtc->base);
+	release_mem_region(rtc->mem->start, resource_size(rtc->mem));
+
+	kfree(rtc);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+struct platform_driver jz4740_rtc_driver = {
+	.probe = jz4740_rtc_probe,
+	.remove = __devexit_p(jz4740_rtc_remove),
+	.driver = {
+		.name = "jz4740-rtc",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init jz4740_rtc_init(void)
+{
+	return platform_driver_register(&jz4740_rtc_driver);
+}
+module_init(jz4740_rtc_init);
+
+static void __exit jz4740_rtc_exit(void)
+{
+	platform_driver_unregister(&jz4740_rtc_driver);
+}
+module_exit(jz4740_rtc_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
+MODULE_ALIAS("platform:jz4740-rtc");
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 891e1dd65f244ef20b2cc4f75ba980c939d3078f..09ef57034c9c75b217ac8a9c395512ddb5b72e1a 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -302,7 +302,7 @@ static const struct serial8250_config uart_config[] = {
 	},
 };
 
-#if defined (CONFIG_SERIAL_8250_AU1X00)
+#if defined(CONFIG_MIPS_ALCHEMY)
 
 /* Au1x00 UART hardware has a weird register layout */
 static const u8 au_io_in_map[] = {
@@ -422,7 +422,6 @@ static unsigned int mem32_serial_in(struct uart_port *p, int offset)
 	return readl(p->membase + offset);
 }
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
 static unsigned int au_serial_in(struct uart_port *p, int offset)
 {
 	offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -434,7 +433,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value)
 	offset = map_8250_out_reg(p, offset) << p->regshift;
 	__raw_writel(value, p->membase + offset);
 }
-#endif
 
 static unsigned int tsi_serial_in(struct uart_port *p, int offset)
 {
@@ -503,12 +501,11 @@ static void set_io_from_upio(struct uart_port *p)
 		p->serial_out = mem32_serial_out;
 		break;
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
 	case UPIO_AU:
 		p->serial_in = au_serial_in;
 		p->serial_out = au_serial_out;
 		break;
-#endif
+
 	case UPIO_TSI:
 		p->serial_in = tsi_serial_in;
 		p->serial_out = tsi_serial_out;
@@ -535,9 +532,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
 	switch (p->iotype) {
 	case UPIO_MEM:
 	case UPIO_MEM32:
-#ifdef CONFIG_SERIAL_8250_AU1X00
 	case UPIO_AU:
-#endif
 	case UPIO_DWAPB:
 		p->serial_out(p, offset, value);
 		p->serial_in(p, UART_LCR);	/* safe, no side-effects */
@@ -573,7 +568,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value)
 	serial_outp(up, UART_DLM, value >> 8 & 0xff);
 }
 
-#if defined(CONFIG_SERIAL_8250_AU1X00)
+#if defined(CONFIG_MIPS_ALCHEMY)
 /* Au1x00 haven't got a standard divisor latch */
 static int serial_dl_read(struct uart_8250_port *up)
 {
@@ -2596,11 +2591,9 @@ static void serial8250_config_port(struct uart_port *port, int flags)
 	if (flags & UART_CONFIG_TYPE)
 		autoconfig(up, probeflags);
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
 	/* if access method is AU, it is a 16550 with a quirk */
 	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
 		up->bugs |= UART_BUG_NOMSR;
-#endif
 
 	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
 		autoconfig_irq(up);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8b23165bc5dc63dc4ff35728cf93d104f513326f..e437ce8c1748b29b0c6ab8f5de633d7c43106ee9 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -258,14 +258,6 @@ config SERIAL_8250_ACORN
 	  system, say Y to this option.  The driver can handle 1, 2, or 3 port
 	  cards.  If unsure, say N.
 
-config SERIAL_8250_AU1X00
-	bool "Au1x00 serial port support"
-	depends on SERIAL_8250 != n && SOC_AU1X00
-	help
-	  If you have an Au1x00 SOC based board and want to use the serial port,
-	  say Y to this option. The driver can handle up to 4 serial ports,
-	  depending on the SOC. If unsure, say N.
-
 config SERIAL_8250_RM9K
 	bool "Support for MIPS RM9xxx integrated serial port"
 	depends on SERIAL_8250 != n && SERIAL_RM9000
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 6a58cb1330c1dc016eeebd89f3ce74cc656d5c76..4aa00e6e57adea87bf52cb2eca4e37b71ba9828e 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -45,7 +45,8 @@ config USB_ARCH_HAS_OHCI
 	default y if STB03xxx
 	default y if PPC_MPC52xx
 	# MIPS:
-	default y if SOC_AU1X00
+	default y if MIPS_ALCHEMY
+	default y if MACH_JZ4740
 	# SH:
 	default y if CPU_SUBTYPE_SH7720
 	default y if CPU_SUBTYPE_SH7721
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fc576557d8a5d2520aee7e6edcbafb17e4701de8..02864a237a2c1b54e91aeb097ab4a4a6212c409e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1031,7 +1031,7 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_SOC_AU1X00
+#ifdef CONFIG_MIPS_ALCHEMY
 #include "ohci-au1xxx.c"
 #define PLATFORM_DRIVER		ohci_hcd_au1xxx_driver
 #endif
@@ -1095,6 +1095,11 @@ MODULE_LICENSE ("GPL");
 #define TMIO_OHCI_DRIVER	ohci_hcd_tmio_driver
 #endif
 
+#ifdef CONFIG_MACH_JZ4740
+#include "ohci-jz4740.c"
+#define PLATFORM_DRIVER	ohci_hcd_jz4740_driver
+#endif
+
 #if	!defined(PCI_DRIVER) &&		\
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OMAP1_PLATFORM_DRIVER) &&	\
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c
new file mode 100644
index 0000000000000000000000000000000000000000..10e1872f3ab9deb2eb06a150f884a19919d26365
--- /dev/null
+++ b/drivers/usb/host/ohci-jz4740.c
@@ -0,0 +1,276 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.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
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+struct jz4740_ohci_hcd {
+	struct ohci_hcd ohci_hcd;
+
+	struct regulator *vbus;
+	bool vbus_enabled;
+	struct clk *clk;
+};
+
+static inline struct jz4740_ohci_hcd *hcd_to_jz4740_hcd(struct usb_hcd *hcd)
+{
+	return (struct jz4740_ohci_hcd *)(hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *jz4740_hcd_to_hcd(struct jz4740_ohci_hcd *jz4740_ohci)
+{
+	return container_of((void *)jz4740_ohci, struct usb_hcd, hcd_priv);
+}
+
+static int ohci_jz4740_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int	ret;
+
+	ret = ohci_init(ohci);
+	if (ret < 0)
+		return ret;
+
+	ohci->num_ports = 1;
+
+	ret = ohci_run(ohci);
+	if (ret < 0) {
+		dev_err(hcd->self.controller, "Can not start %s",
+			hcd->self.bus_name);
+		ohci_stop(hcd);
+		return ret;
+	}
+	return 0;
+}
+
+static int ohci_jz4740_set_vbus_power(struct jz4740_ohci_hcd *jz4740_ohci,
+	bool enabled)
+{
+	int ret = 0;
+
+	if (!jz4740_ohci->vbus)
+		return 0;
+
+	if (enabled && !jz4740_ohci->vbus_enabled) {
+		ret = regulator_enable(jz4740_ohci->vbus);
+		if (ret)
+			dev_err(jz4740_hcd_to_hcd(jz4740_ohci)->self.controller,
+				"Could not power vbus\n");
+	} else if (!enabled && jz4740_ohci->vbus_enabled) {
+		ret = regulator_disable(jz4740_ohci->vbus);
+	}
+
+	if (ret == 0)
+		jz4740_ohci->vbus_enabled = enabled;
+
+	return ret;
+}
+
+static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+	u16 wIndex, char *buf, u16 wLength)
+{
+	struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
+	int ret;
+
+	switch (typeReq) {
+	case SetHubFeature:
+		if (wValue == USB_PORT_FEAT_POWER)
+			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true);
+		break;
+	case ClearHubFeature:
+		if (wValue == USB_PORT_FEAT_POWER)
+			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false);
+		break;
+	}
+
+	if (ret)
+		return ret;
+
+	return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+}
+
+
+static const struct hc_driver ohci_jz4740_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"JZ4740 OHCI",
+	.hcd_priv_size =	sizeof(struct jz4740_ohci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.start =		ohci_jz4740_start,
+	.stop =			ohci_stop,
+	.shutdown =		ohci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue =		ohci_urb_enqueue,
+	.urb_dequeue =		ohci_urb_dequeue,
+	.endpoint_disable =	ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number =	ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data =	ohci_hub_status_data,
+	.hub_control =		ohci_jz4740_hub_control,
+#ifdef	CONFIG_PM
+	.bus_suspend =		ohci_bus_suspend,
+	.bus_resume =		ohci_bus_resume,
+#endif
+	.start_port_reset =	ohci_start_port_reset,
+};
+
+
+static __devinit int jz4740_ohci_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct usb_hcd *hcd;
+	struct jz4740_ohci_hcd *jz4740_ohci;
+	struct resource *res;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get platform resource\n");
+		return -ENOENT;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "Failed to get platform irq\n");
+		return irq;
+	}
+
+	hcd = usb_create_hcd(&ohci_jz4740_hc_driver, &pdev->dev, "jz4740");
+	if (!hcd) {
+		dev_err(&pdev->dev, "Failed to create hcd.\n");
+		return -ENOMEM;
+	}
+
+	jz4740_ohci = hcd_to_jz4740_hcd(hcd);
+
+	res = request_mem_region(res->start, resource_size(res), hcd_name);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to request mem region.\n");
+		ret = -EBUSY;
+		goto err_free;
+	}
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+	hcd->regs = ioremap(res->start, resource_size(res));
+
+	if (!hcd->regs) {
+		dev_err(&pdev->dev, "Failed to ioremap registers.\n");
+		ret = -EBUSY;
+		goto err_release_mem;
+	}
+
+	jz4740_ohci->clk = clk_get(&pdev->dev, "uhc");
+	if (IS_ERR(jz4740_ohci->clk)) {
+		ret = PTR_ERR(jz4740_ohci->clk);
+		dev_err(&pdev->dev, "Failed to get clock: %d\n", ret);
+		goto err_iounmap;
+	}
+
+	jz4740_ohci->vbus = regulator_get(&pdev->dev, "vbus");
+	if (IS_ERR(jz4740_ohci->vbus))
+		jz4740_ohci->vbus = NULL;
+
+
+	clk_set_rate(jz4740_ohci->clk, 48000000);
+	clk_enable(jz4740_ohci->clk);
+	if (jz4740_ohci->vbus)
+		ohci_jz4740_set_vbus_power(jz4740_ohci, true);
+
+	platform_set_drvdata(pdev, hcd);
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	ret = usb_add_hcd(hcd, irq, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add hcd: %d\n", ret);
+		goto err_disable;
+	}
+
+	return 0;
+
+err_disable:
+	platform_set_drvdata(pdev, NULL);
+	if (jz4740_ohci->vbus) {
+		regulator_disable(jz4740_ohci->vbus);
+		regulator_put(jz4740_ohci->vbus);
+	}
+	clk_disable(jz4740_ohci->clk);
+
+	clk_put(jz4740_ohci->clk);
+err_iounmap:
+	iounmap(hcd->regs);
+err_release_mem:
+	release_mem_region(res->start, resource_size(res));
+err_free:
+	usb_put_hcd(hcd);
+
+	return ret;
+}
+
+static __devexit int jz4740_ohci_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
+
+	usb_remove_hcd(hcd);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (jz4740_ohci->vbus) {
+		regulator_disable(jz4740_ohci->vbus);
+		regulator_put(jz4740_ohci->vbus);
+	}
+
+	clk_disable(jz4740_ohci->clk);
+	clk_put(jz4740_ohci->clk);
+
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static struct platform_driver ohci_hcd_jz4740_driver = {
+	.probe = jz4740_ohci_probe,
+	.remove = __devexit_p(jz4740_ohci_remove),
+	.driver = {
+		.name = "jz4740-ohci",
+		.owner = THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS("platfrom:jz4740-ohci");
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3d94a1471724ff620ba580808be1ceec0d868b15..9e711a1d0d97131bfc557229885e6458a9af4188 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2229,6 +2229,15 @@ config FB_BROADSHEET
 	  and could also have been called by other names when coupled with
 	  a bridge adapter.
 
+config FB_JZ4740
+	tristate "JZ4740 LCD framebuffer support"
+	depends on FB && MACH_JZ4740
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	help
+	  Framebuffer support for the JZ4740 SoC.
+
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
 
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ddc2af2ba45bc68c6404ff96d973098f3a298e43..f56a9cae2157407562bb04189332b9ce50b9b654 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -131,6 +131,7 @@ obj-$(CONFIG_FB_CARMINE)          += carminefb.o
 obj-$(CONFIG_FB_MB862XX)	  += mb862xx/
 obj-$(CONFIG_FB_MSM)              += msm/
 obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
+obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
new file mode 100644
index 0000000000000000000000000000000000000000..670ecaa0385a94f396acb74eadeb6e29d71edb1f
--- /dev/null
+++ b/drivers/video/jz4740_fb.c
@@ -0,0 +1,847 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *	JZ4740 SoC LCD framebuffer driver
+ *
+ *  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.
+ *
+ *  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/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <linux/console.h>
+#include <linux/fb.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-jz4740/jz4740_fb.h>
+#include <asm/mach-jz4740/gpio.h>
+
+#define JZ_REG_LCD_CFG		0x00
+#define JZ_REG_LCD_VSYNC	0x04
+#define JZ_REG_LCD_HSYNC	0x08
+#define JZ_REG_LCD_VAT		0x0C
+#define JZ_REG_LCD_DAH		0x10
+#define JZ_REG_LCD_DAV		0x14
+#define JZ_REG_LCD_PS		0x18
+#define JZ_REG_LCD_CLS		0x1C
+#define JZ_REG_LCD_SPL		0x20
+#define JZ_REG_LCD_REV		0x24
+#define JZ_REG_LCD_CTRL		0x30
+#define JZ_REG_LCD_STATE	0x34
+#define JZ_REG_LCD_IID		0x38
+#define JZ_REG_LCD_DA0		0x40
+#define JZ_REG_LCD_SA0		0x44
+#define JZ_REG_LCD_FID0		0x48
+#define JZ_REG_LCD_CMD0		0x4C
+#define JZ_REG_LCD_DA1		0x50
+#define JZ_REG_LCD_SA1		0x54
+#define JZ_REG_LCD_FID1		0x58
+#define JZ_REG_LCD_CMD1		0x5C
+
+#define JZ_LCD_CFG_SLCD			BIT(31)
+#define JZ_LCD_CFG_PS_DISABLE		BIT(23)
+#define JZ_LCD_CFG_CLS_DISABLE		BIT(22)
+#define JZ_LCD_CFG_SPL_DISABLE		BIT(21)
+#define JZ_LCD_CFG_REV_DISABLE		BIT(20)
+#define JZ_LCD_CFG_HSYNCM		BIT(19)
+#define JZ_LCD_CFG_PCLKM		BIT(18)
+#define JZ_LCD_CFG_INV			BIT(17)
+#define JZ_LCD_CFG_SYNC_DIR		BIT(16)
+#define JZ_LCD_CFG_PS_POLARITY		BIT(15)
+#define JZ_LCD_CFG_CLS_POLARITY		BIT(14)
+#define JZ_LCD_CFG_SPL_POLARITY		BIT(13)
+#define JZ_LCD_CFG_REV_POLARITY		BIT(12)
+#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW	BIT(11)
+#define JZ_LCD_CFG_PCLK_FALLING_EDGE	BIT(10)
+#define JZ_LCD_CFG_DE_ACTIVE_LOW	BIT(9)
+#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW	BIT(8)
+#define JZ_LCD_CFG_18_BIT		BIT(7)
+#define JZ_LCD_CFG_PDW			(BIT(5) | BIT(4))
+#define JZ_LCD_CFG_MODE_MASK 0xf
+
+#define JZ_LCD_CTRL_BURST_4		(0x0 << 28)
+#define JZ_LCD_CTRL_BURST_8		(0x1 << 28)
+#define JZ_LCD_CTRL_BURST_16		(0x2 << 28)
+#define JZ_LCD_CTRL_RGB555		BIT(27)
+#define JZ_LCD_CTRL_OFUP		BIT(26)
+#define JZ_LCD_CTRL_FRC_GRAYSCALE_16	(0x0 << 24)
+#define JZ_LCD_CTRL_FRC_GRAYSCALE_4	(0x1 << 24)
+#define JZ_LCD_CTRL_FRC_GRAYSCALE_2	(0x2 << 24)
+#define JZ_LCD_CTRL_PDD_MASK		(0xff << 16)
+#define JZ_LCD_CTRL_EOF_IRQ		BIT(13)
+#define JZ_LCD_CTRL_SOF_IRQ		BIT(12)
+#define JZ_LCD_CTRL_OFU_IRQ		BIT(11)
+#define JZ_LCD_CTRL_IFU0_IRQ		BIT(10)
+#define JZ_LCD_CTRL_IFU1_IRQ		BIT(9)
+#define JZ_LCD_CTRL_DD_IRQ		BIT(8)
+#define JZ_LCD_CTRL_QDD_IRQ		BIT(7)
+#define JZ_LCD_CTRL_REVERSE_ENDIAN	BIT(6)
+#define JZ_LCD_CTRL_LSB_FISRT		BIT(5)
+#define JZ_LCD_CTRL_DISABLE		BIT(4)
+#define JZ_LCD_CTRL_ENABLE		BIT(3)
+#define JZ_LCD_CTRL_BPP_1		0x0
+#define JZ_LCD_CTRL_BPP_2		0x1
+#define JZ_LCD_CTRL_BPP_4		0x2
+#define JZ_LCD_CTRL_BPP_8		0x3
+#define JZ_LCD_CTRL_BPP_15_16		0x4
+#define JZ_LCD_CTRL_BPP_18_24		0x5
+
+#define JZ_LCD_CMD_SOF_IRQ BIT(15)
+#define JZ_LCD_CMD_EOF_IRQ BIT(16)
+#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
+
+#define JZ_LCD_SYNC_MASK 0x3ff
+
+#define JZ_LCD_STATE_DISABLED BIT(0)
+
+struct jzfb_framedesc {
+	uint32_t next;
+	uint32_t addr;
+	uint32_t id;
+	uint32_t cmd;
+} __packed;
+
+struct jzfb {
+	struct fb_info *fb;
+	struct platform_device *pdev;
+	void __iomem *base;
+	struct resource *mem;
+	struct jz4740_fb_platform_data *pdata;
+
+	size_t vidmem_size;
+	void *vidmem;
+	dma_addr_t vidmem_phys;
+	struct jzfb_framedesc *framedesc;
+	dma_addr_t framedesc_phys;
+
+	struct clk *ldclk;
+	struct clk *lpclk;
+
+	unsigned is_enabled:1;
+	struct mutex lock;
+
+	uint32_t pseudo_palette[16];
+};
+
+static const struct fb_fix_screeninfo jzfb_fix __devinitdata = {
+	.id		= "JZ4740 FB",
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_TRUECOLOR,
+	.xpanstep	= 0,
+	.ypanstep	= 0,
+	.ywrapstep	= 0,
+	.accel		= FB_ACCEL_NONE,
+};
+
+static const struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = {
+	JZ_GPIO_BULK_PIN(LCD_PCLK),
+	JZ_GPIO_BULK_PIN(LCD_HSYNC),
+	JZ_GPIO_BULK_PIN(LCD_VSYNC),
+	JZ_GPIO_BULK_PIN(LCD_DE),
+	JZ_GPIO_BULK_PIN(LCD_PS),
+	JZ_GPIO_BULK_PIN(LCD_REV),
+	JZ_GPIO_BULK_PIN(LCD_CLS),
+	JZ_GPIO_BULK_PIN(LCD_SPL),
+};
+
+static const struct jz_gpio_bulk_request jz_lcd_data_pins[] = {
+	JZ_GPIO_BULK_PIN(LCD_DATA0),
+	JZ_GPIO_BULK_PIN(LCD_DATA1),
+	JZ_GPIO_BULK_PIN(LCD_DATA2),
+	JZ_GPIO_BULK_PIN(LCD_DATA3),
+	JZ_GPIO_BULK_PIN(LCD_DATA4),
+	JZ_GPIO_BULK_PIN(LCD_DATA5),
+	JZ_GPIO_BULK_PIN(LCD_DATA6),
+	JZ_GPIO_BULK_PIN(LCD_DATA7),
+	JZ_GPIO_BULK_PIN(LCD_DATA8),
+	JZ_GPIO_BULK_PIN(LCD_DATA9),
+	JZ_GPIO_BULK_PIN(LCD_DATA10),
+	JZ_GPIO_BULK_PIN(LCD_DATA11),
+	JZ_GPIO_BULK_PIN(LCD_DATA12),
+	JZ_GPIO_BULK_PIN(LCD_DATA13),
+	JZ_GPIO_BULK_PIN(LCD_DATA14),
+	JZ_GPIO_BULK_PIN(LCD_DATA15),
+	JZ_GPIO_BULK_PIN(LCD_DATA16),
+	JZ_GPIO_BULK_PIN(LCD_DATA17),
+};
+
+static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
+{
+	unsigned int num;
+
+	switch (jzfb->pdata->lcd_type) {
+	case JZ_LCD_TYPE_GENERIC_16_BIT:
+		num = 4;
+		break;
+	case JZ_LCD_TYPE_GENERIC_18_BIT:
+		num = 4;
+		break;
+	case JZ_LCD_TYPE_8BIT_SERIAL:
+		num = 3;
+		break;
+	case JZ_LCD_TYPE_SPECIAL_TFT_1:
+	case JZ_LCD_TYPE_SPECIAL_TFT_2:
+	case JZ_LCD_TYPE_SPECIAL_TFT_3:
+		num = 8;
+		break;
+	default:
+		num = 0;
+		break;
+	}
+	return num;
+}
+
+static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
+{
+	unsigned int num;
+
+	switch (jzfb->pdata->lcd_type) {
+	case JZ_LCD_TYPE_GENERIC_16_BIT:
+		num = 16;
+		break;
+	case JZ_LCD_TYPE_GENERIC_18_BIT:
+		num = 18;
+		break;
+	case JZ_LCD_TYPE_8BIT_SERIAL:
+		num = 8;
+		break;
+	case JZ_LCD_TYPE_SPECIAL_TFT_1:
+	case JZ_LCD_TYPE_SPECIAL_TFT_2:
+	case JZ_LCD_TYPE_SPECIAL_TFT_3:
+		if (jzfb->pdata->bpp == 18)
+			num = 18;
+		else
+			num = 16;
+		break;
+	default:
+		num = 0;
+		break;
+	}
+	return num;
+}
+
+/* Based on CNVT_TOHW macro from skeletonfb.c */
+static inline uint32_t jzfb_convert_color_to_hw(unsigned val,
+	struct fb_bitfield *bf)
+{
+	return (((val << bf->length) + 0x7FFF - val) >> 16) << bf->offset;
+}
+
+static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			unsigned blue, unsigned transp, struct fb_info *fb)
+{
+	uint32_t color;
+
+	if (regno >= 16)
+		return -EINVAL;
+
+	color = jzfb_convert_color_to_hw(red, &fb->var.red);
+	color |= jzfb_convert_color_to_hw(green, &fb->var.green);
+	color |= jzfb_convert_color_to_hw(blue, &fb->var.blue);
+	color |= jzfb_convert_color_to_hw(transp, &fb->var.transp);
+
+	((uint32_t *)(fb->pseudo_palette))[regno] = color;
+
+	return 0;
+}
+
+static int jzfb_get_controller_bpp(struct jzfb *jzfb)
+{
+	switch (jzfb->pdata->bpp) {
+	case 18:
+	case 24:
+		return 32;
+	case 15:
+		return 16;
+	default:
+		return jzfb->pdata->bpp;
+	}
+}
+
+static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb,
+	struct fb_var_screeninfo *var)
+{
+	size_t i;
+	struct fb_videomode *mode = jzfb->pdata->modes;
+
+	for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
+		if (mode->xres == var->xres && mode->yres == var->yres)
+			return mode;
+	}
+
+	return NULL;
+}
+
+static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
+{
+	struct jzfb *jzfb = fb->par;
+	struct fb_videomode *mode;
+
+	if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
+		var->bits_per_pixel != jzfb->pdata->bpp)
+		return -EINVAL;
+
+	mode = jzfb_get_mode(jzfb, var);
+	if (mode == NULL)
+		return -EINVAL;
+
+	fb_videomode_to_var(var, mode);
+
+	switch (jzfb->pdata->bpp) {
+	case 8:
+		break;
+	case 15:
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 6;
+		var->green.length = 5;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		break;
+	case 16:
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		break;
+	case 18:
+		var->red.offset = 16;
+		var->red.length = 6;
+		var->green.offset = 8;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 6;
+		var->bits_per_pixel = 32;
+		break;
+	case 32:
+	case 24:
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->bits_per_pixel = 32;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int jzfb_set_par(struct fb_info *info)
+{
+	struct jzfb *jzfb = info->par;
+	struct jz4740_fb_platform_data *pdata = jzfb->pdata;
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_videomode *mode;
+	uint16_t hds, vds;
+	uint16_t hde, vde;
+	uint16_t ht, vt;
+	uint32_t ctrl;
+	uint32_t cfg;
+	unsigned long rate;
+
+	mode = jzfb_get_mode(jzfb, var);
+	if (mode == NULL)
+		return -EINVAL;
+
+	if (mode == info->mode)
+		return 0;
+
+	info->mode = mode;
+
+	hds = mode->hsync_len + mode->left_margin;
+	hde = hds + mode->xres;
+	ht = hde + mode->right_margin;
+
+	vds = mode->vsync_len + mode->upper_margin;
+	vde = vds + mode->yres;
+	vt = vde + mode->lower_margin;
+
+	ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
+
+	switch (pdata->bpp) {
+	case 1:
+		ctrl |= JZ_LCD_CTRL_BPP_1;
+		break;
+	case 2:
+		ctrl |= JZ_LCD_CTRL_BPP_2;
+		break;
+	case 4:
+		ctrl |= JZ_LCD_CTRL_BPP_4;
+		break;
+	case 8:
+		ctrl |= JZ_LCD_CTRL_BPP_8;
+	break;
+	case 15:
+		ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */
+	case 16:
+		ctrl |= JZ_LCD_CTRL_BPP_15_16;
+		break;
+	case 18:
+	case 24:
+	case 32:
+		ctrl |= JZ_LCD_CTRL_BPP_18_24;
+		break;
+	default:
+		break;
+	}
+
+	cfg = pdata->lcd_type & 0xf;
+
+	if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+		cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
+
+	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+		cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
+
+	if (pdata->pixclk_falling_edge)
+		cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
+
+	if (pdata->date_enable_active_low)
+		cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
+
+	if (pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT)
+		cfg |= JZ_LCD_CFG_18_BIT;
+
+	if (mode->pixclock) {
+		rate = PICOS2KHZ(mode->pixclock) * 1000;
+		mode->refresh = rate / vt / ht;
+	} else {
+		if (pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
+			rate = mode->refresh * (vt + 2 * mode->xres) * ht;
+		else
+			rate = mode->refresh * vt * ht;
+
+		mode->pixclock = KHZ2PICOS(rate / 1000);
+	}
+
+	mutex_lock(&jzfb->lock);
+	if (!jzfb->is_enabled)
+		clk_enable(jzfb->ldclk);
+	else
+		ctrl |= JZ_LCD_CTRL_ENABLE;
+
+	switch (pdata->lcd_type) {
+	case JZ_LCD_TYPE_SPECIAL_TFT_1:
+	case JZ_LCD_TYPE_SPECIAL_TFT_2:
+	case JZ_LCD_TYPE_SPECIAL_TFT_3:
+		writel(pdata->special_tft_config.spl, jzfb->base + JZ_REG_LCD_SPL);
+		writel(pdata->special_tft_config.cls, jzfb->base + JZ_REG_LCD_CLS);
+		writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_PS);
+		writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_REV);
+		break;
+	default:
+		cfg |= JZ_LCD_CFG_PS_DISABLE;
+		cfg |= JZ_LCD_CFG_CLS_DISABLE;
+		cfg |= JZ_LCD_CFG_SPL_DISABLE;
+		cfg |= JZ_LCD_CFG_REV_DISABLE;
+		break;
+	}
+
+	writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC);
+	writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC);
+
+	writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT);
+
+	writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH);
+	writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV);
+
+	writel(cfg, jzfb->base + JZ_REG_LCD_CFG);
+
+	writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
+
+	if (!jzfb->is_enabled)
+		clk_disable(jzfb->ldclk);
+
+	mutex_unlock(&jzfb->lock);
+
+	clk_set_rate(jzfb->lpclk, rate);
+	clk_set_rate(jzfb->ldclk, rate * 3);
+
+	return 0;
+}
+
+static void jzfb_enable(struct jzfb *jzfb)
+{
+	uint32_t ctrl;
+
+	clk_enable(jzfb->ldclk);
+
+	jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
+	jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+
+	writel(0, jzfb->base + JZ_REG_LCD_STATE);
+
+	writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
+
+	ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
+	ctrl |= JZ_LCD_CTRL_ENABLE;
+	ctrl &= ~JZ_LCD_CTRL_DISABLE;
+	writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
+}
+
+static void jzfb_disable(struct jzfb *jzfb)
+{
+	uint32_t ctrl;
+
+	ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
+	ctrl |= JZ_LCD_CTRL_DISABLE;
+	writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
+	do {
+		ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
+	} while (!(ctrl & JZ_LCD_STATE_DISABLED));
+
+	jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
+	jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+
+	clk_disable(jzfb->ldclk);
+}
+
+static int jzfb_blank(int blank_mode, struct fb_info *info)
+{
+	struct jzfb *jzfb = info->par;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		mutex_lock(&jzfb->lock);
+		if (jzfb->is_enabled) {
+			mutex_unlock(&jzfb->lock);
+			return 0;
+		}
+
+		jzfb_enable(jzfb);
+		jzfb->is_enabled = 1;
+
+		mutex_unlock(&jzfb->lock);
+		break;
+	default:
+		mutex_lock(&jzfb->lock);
+		if (!jzfb->is_enabled) {
+			mutex_unlock(&jzfb->lock);
+			return 0;
+		}
+
+		jzfb_disable(jzfb);
+		jzfb->is_enabled = 0;
+
+		mutex_unlock(&jzfb->lock);
+		break;
+	}
+
+	return 0;
+}
+
+static int jzfb_alloc_devmem(struct jzfb *jzfb)
+{
+	int max_videosize = 0;
+	struct fb_videomode *mode = jzfb->pdata->modes;
+	void *page;
+	int i;
+
+	for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
+		if (max_videosize < mode->xres * mode->yres)
+			max_videosize = mode->xres * mode->yres;
+	}
+
+	max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3;
+
+	jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
+					sizeof(*jzfb->framedesc),
+					&jzfb->framedesc_phys, GFP_KERNEL);
+
+	if (!jzfb->framedesc)
+		return -ENOMEM;
+
+	jzfb->vidmem_size = PAGE_ALIGN(max_videosize);
+	jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
+					jzfb->vidmem_size,
+					&jzfb->vidmem_phys, GFP_KERNEL);
+
+	if (!jzfb->vidmem)
+		goto err_free_framedesc;
+
+	for (page = jzfb->vidmem;
+		 page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
+		 page += PAGE_SIZE) {
+		SetPageReserved(virt_to_page(page));
+	}
+
+	jzfb->framedesc->next = jzfb->framedesc_phys;
+	jzfb->framedesc->addr = jzfb->vidmem_phys;
+	jzfb->framedesc->id = 0xdeafbead;
+	jzfb->framedesc->cmd = 0;
+	jzfb->framedesc->cmd |= max_videosize / 4;
+
+	return 0;
+
+err_free_framedesc:
+	dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
+				jzfb->framedesc, jzfb->framedesc_phys);
+	return -ENOMEM;
+}
+
+static void jzfb_free_devmem(struct jzfb *jzfb)
+{
+	dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
+				jzfb->vidmem, jzfb->vidmem_phys);
+	dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
+				jzfb->framedesc, jzfb->framedesc_phys);
+}
+
+static struct  fb_ops jzfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = jzfb_check_var,
+	.fb_set_par = jzfb_set_par,
+	.fb_blank = jzfb_blank,
+	.fb_fillrect	= sys_fillrect,
+	.fb_copyarea	= sys_copyarea,
+	.fb_imageblit	= sys_imageblit,
+	.fb_setcolreg = jzfb_setcolreg,
+};
+
+static int __devinit jzfb_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct jzfb *jzfb;
+	struct fb_info *fb;
+	struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *mem;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Missing platform data\n");
+		return -ENXIO;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&pdev->dev, "Failed to get register memory resource\n");
+		return -ENXIO;
+	}
+
+	mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
+	if (!mem) {
+		dev_err(&pdev->dev, "Failed to request register memory region\n");
+		return -EBUSY;
+	}
+
+	fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
+	if (!fb) {
+		dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
+		ret = -ENOMEM;
+		goto err_release_mem_region;
+	}
+
+	fb->fbops = &jzfb_ops;
+	fb->flags = FBINFO_DEFAULT;
+
+	jzfb = fb->par;
+	jzfb->pdev = pdev;
+	jzfb->pdata = pdata;
+	jzfb->mem = mem;
+
+	jzfb->ldclk = clk_get(&pdev->dev, "lcd");
+	if (IS_ERR(jzfb->ldclk)) {
+		ret = PTR_ERR(jzfb->ldclk);
+		dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
+		goto err_framebuffer_release;
+	}
+
+	jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
+	if (IS_ERR(jzfb->lpclk)) {
+		ret = PTR_ERR(jzfb->lpclk);
+		dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
+		goto err_put_ldclk;
+	}
+
+	jzfb->base = ioremap(mem->start, resource_size(mem));
+	if (!jzfb->base) {
+		dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
+		ret = -EBUSY;
+		goto err_put_lpclk;
+	}
+
+	platform_set_drvdata(pdev, jzfb);
+
+	mutex_init(&jzfb->lock);
+
+	fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
+				 &fb->modelist);
+	fb_videomode_to_var(&fb->var, pdata->modes);
+	fb->var.bits_per_pixel = pdata->bpp;
+	jzfb_check_var(&fb->var, fb);
+
+	ret = jzfb_alloc_devmem(jzfb);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to allocate video memory\n");
+		goto err_iounmap;
+	}
+
+	fb->fix = jzfb_fix;
+	fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
+	fb->fix.mmio_start = mem->start;
+	fb->fix.mmio_len = resource_size(mem);
+	fb->fix.smem_start = jzfb->vidmem_phys;
+	fb->fix.smem_len =  fb->fix.line_length * fb->var.yres;
+	fb->screen_base = jzfb->vidmem;
+	fb->pseudo_palette = jzfb->pseudo_palette;
+
+	fb_alloc_cmap(&fb->cmap, 256, 0);
+
+	clk_enable(jzfb->ldclk);
+	jzfb->is_enabled = 1;
+
+	writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
+
+	fb->mode = NULL;
+	jzfb_set_par(fb);
+
+	jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
+	jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+
+	ret = register_framebuffer(fb);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
+		goto err_free_devmem;
+	}
+
+	jzfb->fb = fb;
+
+	return 0;
+
+err_free_devmem:
+	jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
+	jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+
+	fb_dealloc_cmap(&fb->cmap);
+	jzfb_free_devmem(jzfb);
+err_iounmap:
+	iounmap(jzfb->base);
+err_put_lpclk:
+	clk_put(jzfb->lpclk);
+err_put_ldclk:
+	clk_put(jzfb->ldclk);
+err_framebuffer_release:
+	framebuffer_release(fb);
+err_release_mem_region:
+	release_mem_region(mem->start, resource_size(mem));
+	return ret;
+}
+
+static int __devexit jzfb_remove(struct platform_device *pdev)
+{
+	struct jzfb *jzfb = platform_get_drvdata(pdev);
+
+	jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
+
+	jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
+	jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+
+	iounmap(jzfb->base);
+	release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
+
+	fb_dealloc_cmap(&jzfb->fb->cmap);
+	jzfb_free_devmem(jzfb);
+
+	platform_set_drvdata(pdev, NULL);
+
+	clk_put(jzfb->lpclk);
+	clk_put(jzfb->ldclk);
+
+	framebuffer_release(jzfb->fb);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int jzfb_suspend(struct device *dev)
+{
+	struct jzfb *jzfb = dev_get_drvdata(dev);
+
+	acquire_console_sem();
+	fb_set_suspend(jzfb->fb, 1);
+	release_console_sem();
+
+	mutex_lock(&jzfb->lock);
+	if (jzfb->is_enabled)
+		jzfb_disable(jzfb);
+	mutex_unlock(&jzfb->lock);
+
+	return 0;
+}
+
+static int jzfb_resume(struct device *dev)
+{
+	struct jzfb *jzfb = dev_get_drvdata(dev);
+	clk_enable(jzfb->ldclk);
+
+	mutex_lock(&jzfb->lock);
+	if (jzfb->is_enabled)
+		jzfb_enable(jzfb);
+	mutex_unlock(&jzfb->lock);
+
+	acquire_console_sem();
+	fb_set_suspend(jzfb->fb, 0);
+	release_console_sem();
+
+	return 0;
+}
+
+static const struct dev_pm_ops jzfb_pm_ops = {
+	.suspend	= jzfb_suspend,
+	.resume		= jzfb_resume,
+	.poweroff	= jzfb_suspend,
+	.restore	= jzfb_resume,
+};
+
+#define JZFB_PM_OPS (&jzfb_pm_ops)
+
+#else
+#define JZFB_PM_OPS NULL
+#endif
+
+static struct platform_driver jzfb_driver = {
+	.probe = jzfb_probe,
+	.remove = __devexit_p(jzfb_remove),
+	.driver = {
+		.name = "jz4740-fb",
+		.pm = JZFB_PM_OPS,
+	},
+};
+
+static int __init jzfb_init(void)
+{
+	return platform_driver_register(&jzfb_driver);
+}
+module_init(jzfb_init);
+
+static void __exit jzfb_exit(void)
+{
+	platform_driver_unregister(&jzfb_driver);
+}
+module_exit(jzfb_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver");
+MODULE_ALIAS("platform:jz4740-fb");
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 980548390048526c9e5bf5311e4cf8722a886c3b..3ee5e63cfa4fd5ba919f49c70289b92db23b31d9 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1571,8 +1571,8 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
 	if (default_par->mtrr_handle >= 0)
 		mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
 			 info->fix.smem_len);
-	release_mem_region(pci_resource_start(pdev, 2),
-			   pci_resource_len(pdev, 2));
+	release_region(pci_resource_start(pdev, 2),
+		       pci_resource_len(pdev, 2));
 out_err_screenbase:
 	if (info->screen_base)
 		iounmap(info->screen_base);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index afcfacc9bbe2f0b8718c4ef3a5b8cc6a7c7e62b3..b04b1846893265563aaa9abee1a589c35d8ddc42 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -875,6 +875,24 @@ config TXX9_WDT
 	help
 	  Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
 
+config OCTEON_WDT
+	tristate "Cavium OCTEON SOC family Watchdog Timer"
+	depends on CPU_CAVIUM_OCTEON
+	default y
+	select EXPORT_UASM if OCTEON_WDT = m
+	help
+	  Hardware driver for OCTEON's on chip watchdog timer.
+	  Enables the watchdog for all cores running Linux. It
+	  installs a NMI handler and pokes the watchdog based on an
+	  interrupt.  On first expiration of the watchdog, the
+	  interrupt handler pokes it.  The second expiration causes an
+	  NMI that prints a message. The third expiration causes a
+	  global soft reset.
+
+	  When userspace has /dev/watchdog open, no poking is done
+	  from the first interrupt, it is then only poked when the
+	  device is written.
+
 # PARISC Architecture
 
 # POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 72f3e2073f8e4e468f9bb720a313cbf3509bb9ce..e30289a5e36776413e0211dea6bd24745a59b32c 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -114,6 +114,8 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
 obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
 obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
 obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
+octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
 
 # PARISC Architecture
 
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
new file mode 100644
index 0000000000000000000000000000000000000000..2a410170eca67c93b5472fdfa4c419c3bba2f58e
--- /dev/null
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -0,0 +1,745 @@
+/*
+ * Octeon Watchdog driver
+ *
+ * Copyright (C) 2007, 2008, 2009, 2010 Cavium Networks
+ *
+ * Some parts derived from wdt.c
+ *
+ *	(c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
+ *						All Rights Reserved.
+ *
+ *	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.
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ *
+ *	(c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * 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.
+ *
+ *
+ * The OCTEON watchdog has a maximum timeout of 2^32 * io_clock.
+ * For most systems this is less than 10 seconds, so to allow for
+ * software to request longer watchdog heartbeats, we maintain software
+ * counters to count multiples of the base rate.  If the system locks
+ * up in such a manner that we can not run the software counters, the
+ * only result is a watchdog reset sooner than was requested.  But
+ * that is OK, because in this case userspace would likely not be able
+ * to do anything anyhow.
+ *
+ * The hardware watchdog interval we call the period.  The OCTEON
+ * watchdog goes through several stages, after the first period an
+ * irq is asserted, then if it is not reset, after the next period NMI
+ * is asserted, then after an additional period a chip wide soft reset.
+ * So for the software counters, we reset watchdog after each period
+ * and decrement the counter.  But for the last two periods we need to
+ * let the watchdog progress to the NMI stage so we disable the irq
+ * and let it proceed.  Once in the NMI, we print the register state
+ * to the serial port and then wait for the reset.
+ *
+ * A watchdog is maintained for each CPU in the system, that way if
+ * one CPU suffers a lockup, we also get a register dump and reset.
+ * The userspace ping resets the watchdog on all CPUs.
+ *
+ * Before userspace opens the watchdog device, we still run the
+ * watchdogs to catch any lockups that may be kernel related.
+ *
+ */
+
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/watchdog.h>
+#include <linux/cpumask.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
+
+#include <asm/mipsregs.h>
+#include <asm/uasm.h>
+
+#include <asm/octeon/octeon.h>
+
+/* The count needed to achieve timeout_sec. */
+static unsigned int timeout_cnt;
+
+/* The maximum period supported. */
+static unsigned int max_timeout_sec;
+
+/* The current period.  */
+static unsigned int timeout_sec;
+
+/* Set to non-zero when userspace countdown mode active */
+static int do_coundown;
+static unsigned int countdown_reset;
+static unsigned int per_cpu_countdown[NR_CPUS];
+
+static cpumask_t irq_enabled_cpus;
+
+#define WD_TIMO 60			/* Default heartbeat = 60 seconds */
+
+static int heartbeat = WD_TIMO;
+module_param(heartbeat, int, S_IRUGO);
+MODULE_PARM_DESC(heartbeat,
+	"Watchdog heartbeat in seconds. (0 < heartbeat, default="
+				__MODULE_STRING(WD_TIMO) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, S_IRUGO);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static unsigned long octeon_wdt_is_open;
+static char expect_close;
+
+static u32 __initdata nmi_stage1_insns[64];
+/* We need one branch and therefore one relocation per target label. */
+static struct uasm_label __initdata labels[5];
+static struct uasm_reloc __initdata relocs[5];
+
+enum lable_id {
+	label_enter_bootloader = 1
+};
+
+/* Some CP0 registers */
+#define K0		26
+#define C0_CVMMEMCTL 11, 7
+#define C0_STATUS 12, 0
+#define C0_EBASE 15, 1
+#define C0_DESAVE 31, 0
+
+void octeon_wdt_nmi_stage2(void);
+
+static void __init octeon_wdt_build_stage1(void)
+{
+	int i;
+	int len;
+	u32 *p = nmi_stage1_insns;
+#ifdef CONFIG_HOTPLUG_CPU
+	struct uasm_label *l = labels;
+	struct uasm_reloc *r = relocs;
+#endif
+
+	/*
+	 * For the next few instructions running the debugger may
+	 * cause corruption of k0 in the saved registers. Since we're
+	 * about to crash, nobody probably cares.
+	 *
+	 * Save K0 into the debug scratch register
+	 */
+	uasm_i_dmtc0(&p, K0, C0_DESAVE);
+
+	uasm_i_mfc0(&p, K0, C0_STATUS);
+#ifdef CONFIG_HOTPLUG_CPU
+	uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader);
+#endif
+	/* Force 64-bit addressing enabled */
+	uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX);
+	uasm_i_mtc0(&p, K0, C0_STATUS);
+
+#ifdef CONFIG_HOTPLUG_CPU
+	uasm_i_mfc0(&p, K0, C0_EBASE);
+	/* Coreid number in K0 */
+	uasm_i_andi(&p, K0, K0, 0xf);
+	/* 8 * coreid in bits 16-31 */
+	uasm_i_dsll_safe(&p, K0, K0, 3 + 16);
+	uasm_i_ori(&p, K0, K0, 0x8001);
+	uasm_i_dsll_safe(&p, K0, K0, 16);
+	uasm_i_ori(&p, K0, K0, 0x0700);
+	uasm_i_drotr_safe(&p, K0, K0, 32);
+	/*
+	 * Should result in: 0x8001,0700,0000,8*coreid which is
+	 * CVMX_CIU_WDOGX(coreid) - 0x0500
+	 *
+	 * Now ld K0, CVMX_CIU_WDOGX(coreid)
+	 */
+	uasm_i_ld(&p, K0, 0x500, K0);
+	/*
+	 * If bit one set handle the NMI as a watchdog event.
+	 * otherwise transfer control to bootloader.
+	 */
+	uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader);
+	uasm_i_nop(&p);
+#endif
+
+	/* Clear Dcache so cvmseg works right. */
+	uasm_i_cache(&p, 1, 0, 0);
+
+	/* Use K0 to do a read/modify/write of CVMMEMCTL */
+	uasm_i_dmfc0(&p, K0, C0_CVMMEMCTL);
+	/* Clear out the size of CVMSEG	*/
+	uasm_i_dins(&p, K0, 0, 0, 6);
+	/* Set CVMSEG to its largest value */
+	uasm_i_ori(&p, K0, K0, 0x1c0 | 54);
+	/* Store the CVMMEMCTL value */
+	uasm_i_dmtc0(&p, K0, C0_CVMMEMCTL);
+
+	/* Load the address of the second stage handler */
+	UASM_i_LA(&p, K0, (long)octeon_wdt_nmi_stage2);
+	uasm_i_jr(&p, K0);
+	uasm_i_dmfc0(&p, K0, C0_DESAVE);
+
+#ifdef CONFIG_HOTPLUG_CPU
+	uasm_build_label(&l, p, label_enter_bootloader);
+	/* Jump to the bootloader and restore K0 */
+	UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr);
+	uasm_i_jr(&p, K0);
+	uasm_i_dmfc0(&p, K0, C0_DESAVE);
+#endif
+	uasm_resolve_relocs(relocs, labels);
+
+	len = (int)(p - nmi_stage1_insns);
+	pr_debug("Synthesized NMI stage 1 handler (%d instructions).\n", len);
+
+	pr_debug("\t.set push\n");
+	pr_debug("\t.set noreorder\n");
+	for (i = 0; i < len; i++)
+		pr_debug("\t.word 0x%08x\n", nmi_stage1_insns[i]);
+	pr_debug("\t.set pop\n");
+
+	if (len > 32)
+		panic("NMI stage 1 handler exceeds 32 instructions, was %d\n", len);
+}
+
+static int cpu2core(int cpu)
+{
+#ifdef CONFIG_SMP
+	return cpu_logical_map(cpu);
+#else
+	return cvmx_get_core_num();
+#endif
+}
+
+static int core2cpu(int coreid)
+{
+#ifdef CONFIG_SMP
+	return cpu_number_map(coreid);
+#else
+	return 0;
+#endif
+}
+
+/**
+ * Poke the watchdog when an interrupt is received
+ *
+ * @cpl:
+ * @dev_id:
+ *
+ * Returns
+ */
+static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id)
+{
+	unsigned int core = cvmx_get_core_num();
+	int cpu = core2cpu(core);
+
+	if (do_coundown) {
+		if (per_cpu_countdown[cpu] > 0) {
+			/* We're alive, poke the watchdog */
+			cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
+			per_cpu_countdown[cpu]--;
+		} else {
+			/* Bad news, you are about to reboot. */
+			disable_irq_nosync(cpl);
+			cpumask_clear_cpu(cpu, &irq_enabled_cpus);
+		}
+	} else {
+		/* Not open, just ping away... */
+		cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
+	}
+	return IRQ_HANDLED;
+}
+
+/* From setup.c */
+extern int prom_putchar(char c);
+
+/**
+ * Write a string to the uart
+ *
+ * @str:        String to write
+ */
+static void octeon_wdt_write_string(const char *str)
+{
+	/* Just loop writing one byte at a time */
+	while (*str)
+		prom_putchar(*str++);
+}
+
+/**
+ * Write a hex number out of the uart
+ *
+ * @value:      Number to display
+ * @digits:     Number of digits to print (1 to 16)
+ */
+static void octeon_wdt_write_hex(u64 value, int digits)
+{
+	int d;
+	int v;
+	for (d = 0; d < digits; d++) {
+		v = (value >> ((digits - d - 1) * 4)) & 0xf;
+		if (v >= 10)
+			prom_putchar('a' + v - 10);
+		else
+			prom_putchar('0' + v);
+	}
+}
+
+const char *reg_name[] = {
+	"$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+	"a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
+	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+	"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+};
+
+/**
+ * NMI stage 3 handler. NMIs are handled in the following manner:
+ * 1) The first NMI handler enables CVMSEG and transfers from
+ * the bootbus region into normal memory. It is careful to not
+ * destroy any registers.
+ * 2) The second stage handler uses CVMSEG to save the registers
+ * and create a stack for C code. It then calls the third level
+ * handler with one argument, a pointer to the register values.
+ * 3) The third, and final, level handler is the following C
+ * function that prints out some useful infomration.
+ *
+ * @reg:    Pointer to register state before the NMI
+ */
+void octeon_wdt_nmi_stage3(u64 reg[32])
+{
+	u64 i;
+
+	unsigned int coreid = cvmx_get_core_num();
+	/*
+	 * Save status and cause early to get them before any changes
+	 * might happen.
+	 */
+	u64 cp0_cause = read_c0_cause();
+	u64 cp0_status = read_c0_status();
+	u64 cp0_error_epc = read_c0_errorepc();
+	u64 cp0_epc = read_c0_epc();
+
+	/* Delay so output from all cores output is not jumbled together. */
+	__delay(100000000ull * coreid);
+
+	octeon_wdt_write_string("\r\n*** NMI Watchdog interrupt on Core 0x");
+	octeon_wdt_write_hex(coreid, 1);
+	octeon_wdt_write_string(" ***\r\n");
+	for (i = 0; i < 32; i++) {
+		octeon_wdt_write_string("\t");
+		octeon_wdt_write_string(reg_name[i]);
+		octeon_wdt_write_string("\t0x");
+		octeon_wdt_write_hex(reg[i], 16);
+		if (i & 1)
+			octeon_wdt_write_string("\r\n");
+	}
+	octeon_wdt_write_string("\terr_epc\t0x");
+	octeon_wdt_write_hex(cp0_error_epc, 16);
+
+	octeon_wdt_write_string("\tepc\t0x");
+	octeon_wdt_write_hex(cp0_epc, 16);
+	octeon_wdt_write_string("\r\n");
+
+	octeon_wdt_write_string("\tstatus\t0x");
+	octeon_wdt_write_hex(cp0_status, 16);
+	octeon_wdt_write_string("\tcause\t0x");
+	octeon_wdt_write_hex(cp0_cause, 16);
+	octeon_wdt_write_string("\r\n");
+
+	octeon_wdt_write_string("\tsum0\t0x");
+	octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16);
+	octeon_wdt_write_string("\ten0\t0x");
+	octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16);
+	octeon_wdt_write_string("\r\n");
+
+	octeon_wdt_write_string("*** Chip soft reset soon ***\r\n");
+}
+
+static void octeon_wdt_disable_interrupt(int cpu)
+{
+	unsigned int core;
+	unsigned int irq;
+	union cvmx_ciu_wdogx ciu_wdog;
+
+	core = cpu2core(cpu);
+
+	irq = OCTEON_IRQ_WDOG0 + core;
+
+	/* Poke the watchdog to clear out its state */
+	cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
+
+	/* Disable the hardware. */
+	ciu_wdog.u64 = 0;
+	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);
+
+	free_irq(irq, octeon_wdt_poke_irq);
+}
+
+static void octeon_wdt_setup_interrupt(int cpu)
+{
+	unsigned int core;
+	unsigned int irq;
+	union cvmx_ciu_wdogx ciu_wdog;
+
+	core = cpu2core(cpu);
+
+	/* Disable it before doing anything with the interrupts. */
+	ciu_wdog.u64 = 0;
+	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);
+
+	per_cpu_countdown[cpu] = countdown_reset;
+
+	irq = OCTEON_IRQ_WDOG0 + core;
+
+	if (request_irq(irq, octeon_wdt_poke_irq,
+			IRQF_DISABLED, "octeon_wdt", octeon_wdt_poke_irq))
+		panic("octeon_wdt: Couldn't obtain irq %d", irq);
+
+	cpumask_set_cpu(cpu, &irq_enabled_cpus);
+
+	/* Poke the watchdog to clear out its state */
+	cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
+
+	/* Finally enable the watchdog now that all handlers are installed */
+	ciu_wdog.u64 = 0;
+	ciu_wdog.s.len = timeout_cnt;
+	ciu_wdog.s.mode = 3;	/* 3 = Interrupt + NMI + Soft-Reset */
+	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);
+}
+
+static int octeon_wdt_cpu_callback(struct notifier_block *nfb,
+					   unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+
+	switch (action) {
+	case CPU_DOWN_PREPARE:
+		octeon_wdt_disable_interrupt(cpu);
+		break;
+	case CPU_ONLINE:
+	case CPU_DOWN_FAILED:
+		octeon_wdt_setup_interrupt(cpu);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static void octeon_wdt_ping(void)
+{
+	int cpu;
+	int coreid;
+
+	for_each_online_cpu(cpu) {
+		coreid = cpu2core(cpu);
+		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
+		per_cpu_countdown[cpu] = countdown_reset;
+		if ((countdown_reset || !do_coundown) &&
+		    !cpumask_test_cpu(cpu, &irq_enabled_cpus)) {
+			/* We have to enable the irq */
+			int irq = OCTEON_IRQ_WDOG0 + coreid;
+			enable_irq(irq);
+			cpumask_set_cpu(cpu, &irq_enabled_cpus);
+		}
+	}
+}
+
+static void octeon_wdt_calc_parameters(int t)
+{
+	unsigned int periods;
+
+	timeout_sec = max_timeout_sec;
+
+
+	/*
+	 * Find the largest interrupt period, that can evenly divide
+	 * the requested heartbeat time.
+	 */
+	while ((t % timeout_sec) != 0)
+		timeout_sec--;
+
+	periods = t / timeout_sec;
+
+	/*
+	 * The last two periods are after the irq is disabled, and
+	 * then to the nmi, so we subtract them off.
+	 */
+
+	countdown_reset = periods > 2 ? periods - 2 : 0;
+	heartbeat = t;
+	timeout_cnt = ((octeon_get_clock_rate() >> 8) * timeout_sec) >> 8;
+}
+
+static int octeon_wdt_set_heartbeat(int t)
+{
+	int cpu;
+	int coreid;
+	union cvmx_ciu_wdogx ciu_wdog;
+
+	if (t <= 0)
+		return -1;
+
+	octeon_wdt_calc_parameters(t);
+
+	for_each_online_cpu(cpu) {
+		coreid = cpu2core(cpu);
+		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
+		ciu_wdog.u64 = 0;
+		ciu_wdog.s.len = timeout_cnt;
+		ciu_wdog.s.mode = 3;	/* 3 = Interrupt + NMI + Soft-Reset */
+		cvmx_write_csr(CVMX_CIU_WDOGX(coreid), ciu_wdog.u64);
+		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
+	}
+	octeon_wdt_ping(); /* Get the irqs back on. */
+	return 0;
+}
+
+/**
+ *	octeon_wdt_write:
+ *	@file: file handle to the watchdog
+ *	@buf: buffer to write (unused as data does not matter here
+ *	@count: count of bytes
+ *	@ppos: pointer to the position to write. No seeks allowed
+ *
+ *	A write to a watchdog device is defined as a keepalive signal. Any
+ *	write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t octeon_wdt_write(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_close = 1;
+			}
+		}
+		octeon_wdt_ping();
+	}
+	return count;
+}
+
+/**
+ *	octeon_wdt_ioctl:
+ *	@file: file handle to the device
+ *	@cmd: watchdog command
+ *	@arg: argument pointer
+ *
+ *	The watchdog API defines a common set of functions for all
+ *	watchdogs according to their available features. We only
+ *	actually usefully support querying capabilities and setting
+ *	the timeout.
+ */
+
+static long octeon_wdt_ioctl(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int new_heartbeat;
+
+	static struct watchdog_info ident = {
+		.options =		WDIOF_SETTIMEOUT|
+					WDIOF_MAGICCLOSE|
+					WDIOF_KEEPALIVEPING,
+		.firmware_version =	1,
+		.identity =		"OCTEON",
+	};
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, p);
+	case WDIOC_KEEPALIVE:
+		octeon_wdt_ping();
+		return 0;
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_heartbeat, p))
+			return -EFAULT;
+		if (octeon_wdt_set_heartbeat(new_heartbeat))
+			return -EINVAL;
+		/* Fall through. */
+	case WDIOC_GETTIMEOUT:
+		return put_user(heartbeat, p);
+	default:
+		return -ENOTTY;
+	}
+}
+
+/**
+ *	octeon_wdt_open:
+ *	@inode: inode of device
+ *	@file: file handle to device
+ *
+ *	The watchdog device has been opened. The watchdog device is single
+ *	open and on opening we do a ping to reset the counters.
+ */
+
+static int octeon_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &octeon_wdt_is_open))
+		return -EBUSY;
+	/*
+	 *	Activate
+	 */
+	octeon_wdt_ping();
+	do_coundown = 1;
+	return nonseekable_open(inode, file);
+}
+
+/**
+ *	octeon_wdt_release:
+ *	@inode: inode to board
+ *	@file: file handle to board
+ *
+ *	The watchdog has a configurable API. There is a religious dispute
+ *	between people who want their watchdog to be able to shut down and
+ *	those who want to be sure if the watchdog manager dies the machine
+ *	reboots. In the former case we disable the counters, in the latter
+ *	case you have to open it again very soon.
+ */
+
+static int octeon_wdt_release(struct inode *inode, struct file *file)
+{
+	if (expect_close) {
+		do_coundown = 0;
+		octeon_wdt_ping();
+	} else {
+		pr_crit("octeon_wdt: WDT device closed unexpectedly.  WDT will not stop!\n");
+	}
+	clear_bit(0, &octeon_wdt_is_open);
+	expect_close = 0;
+	return 0;
+}
+
+static const struct file_operations octeon_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= octeon_wdt_write,
+	.unlocked_ioctl	= octeon_wdt_ioctl,
+	.open		= octeon_wdt_open,
+	.release	= octeon_wdt_release,
+};
+
+static struct miscdevice octeon_wdt_miscdev = {
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &octeon_wdt_fops,
+};
+
+static struct notifier_block octeon_wdt_cpu_notifier = {
+	.notifier_call = octeon_wdt_cpu_callback,
+};
+
+
+/**
+ * Module/ driver initialization.
+ *
+ * Returns Zero on success
+ */
+static int __init octeon_wdt_init(void)
+{
+	int i;
+	int ret;
+	int cpu;
+	u64 *ptr;
+
+	/*
+	 * Watchdog time expiration length = The 16 bits of LEN
+	 * represent the most significant bits of a 24 bit decrementer
+	 * that decrements every 256 cycles.
+	 *
+	 * Try for a timeout of 5 sec, if that fails a smaller number
+	 * of even seconds,
+	 */
+	max_timeout_sec = 6;
+	do {
+		max_timeout_sec--;
+		timeout_cnt = ((octeon_get_clock_rate() >> 8) * max_timeout_sec) >> 8;
+	} while (timeout_cnt > 65535);
+
+	BUG_ON(timeout_cnt == 0);
+
+	octeon_wdt_calc_parameters(heartbeat);
+
+	pr_info("octeon_wdt: Initial granularity %d Sec.\n", timeout_sec);
+
+	ret = misc_register(&octeon_wdt_miscdev);
+	if (ret) {
+		pr_err("octeon_wdt: cannot register miscdev on minor=%d (err=%d)\n",
+			WATCHDOG_MINOR, ret);
+		goto out;
+	}
+
+	/* Build the NMI handler ... */
+	octeon_wdt_build_stage1();
+
+	/* ... and install it. */
+	ptr = (u64 *) nmi_stage1_insns;
+	for (i = 0; i < 16; i++) {
+		cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
+		cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, ptr[i]);
+	}
+	cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);
+
+	cpumask_clear(&irq_enabled_cpus);
+
+	for_each_online_cpu(cpu)
+		octeon_wdt_setup_interrupt(cpu);
+
+	register_hotcpu_notifier(&octeon_wdt_cpu_notifier);
+out:
+	return ret;
+}
+
+/**
+ * Module / driver shutdown
+ */
+static void __exit octeon_wdt_cleanup(void)
+{
+	int cpu;
+
+	misc_deregister(&octeon_wdt_miscdev);
+
+	unregister_hotcpu_notifier(&octeon_wdt_cpu_notifier);
+
+	for_each_online_cpu(cpu) {
+		int core = cpu2core(cpu);
+		/* Disable the watchdog */
+		cvmx_write_csr(CVMX_CIU_WDOGX(core), 0);
+		/* Free the interrupt handler */
+		free_irq(OCTEON_IRQ_WDOG0 + core, octeon_wdt_poke_irq);
+	}
+	/*
+	 * Disable the boot-bus memory, the code it points to is soon
+	 * to go missing.
+	 */
+	cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
+MODULE_DESCRIPTION("Cavium Networks Octeon Watchdog driver.");
+module_init(octeon_wdt_init);
+module_exit(octeon_wdt_cleanup);
diff --git a/drivers/watchdog/octeon-wdt-nmi.S b/drivers/watchdog/octeon-wdt-nmi.S
new file mode 100644
index 0000000000000000000000000000000000000000..8a900a5e3233eefdae4fd994102a0dd179ddb512
--- /dev/null
+++ b/drivers/watchdog/octeon-wdt-nmi.S
@@ -0,0 +1,64 @@
+/*
+ * 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 Cavium Networks
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define SAVE_REG(r)	sd $r, -32768+6912-(32-r)*8($0)
+
+        NESTED(octeon_wdt_nmi_stage2, 0, sp)
+	.set 	push
+	.set 	noreorder
+	.set 	noat
+	/* Save all registers to the top CVMSEG. This shouldn't
+	 * corrupt any state used by the kernel. Also all registers
+	 * should have the value right before the NMI. */
+	SAVE_REG(0)
+	SAVE_REG(1)
+	SAVE_REG(2)
+	SAVE_REG(3)
+	SAVE_REG(4)
+	SAVE_REG(5)
+	SAVE_REG(6)
+	SAVE_REG(7)
+	SAVE_REG(8)
+	SAVE_REG(9)
+	SAVE_REG(10)
+	SAVE_REG(11)
+	SAVE_REG(12)
+	SAVE_REG(13)
+	SAVE_REG(14)
+	SAVE_REG(15)
+	SAVE_REG(16)
+	SAVE_REG(17)
+	SAVE_REG(18)
+	SAVE_REG(19)
+	SAVE_REG(20)
+	SAVE_REG(21)
+	SAVE_REG(22)
+	SAVE_REG(23)
+	SAVE_REG(24)
+	SAVE_REG(25)
+	SAVE_REG(26)
+	SAVE_REG(27)
+	SAVE_REG(28)
+	SAVE_REG(29)
+	SAVE_REG(30)
+	SAVE_REG(31)
+	/* Set the stack to begin right below the registers */
+	li	sp, -32768+6912-32*8
+	/* Load the address of the third stage handler */
+	dla	a0, octeon_wdt_nmi_stage3
+	/* Call the third stage handler */
+	jal	a0
+	/* a0 is the address of the saved registers */
+	 move	a0, sp
+	/* Loop forvever if we get here. */
+1:	b	1b
+	nop
+	.set pop
+	END(octeon_wdt_nmi_stage2)
diff --git a/include/linux/power/jz4740-battery.h b/include/linux/power/jz4740-battery.h
new file mode 100644
index 0000000000000000000000000000000000000000..19c9610c720adcb48de575a0f7f4cef9ea8129e6
--- /dev/null
+++ b/include/linux/power/jz4740-battery.h
@@ -0,0 +1,24 @@
+/*
+ *  Copyright (C) 2009, Jiejing Zhang <kzjeef@gmail.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.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __JZ4740_BATTERY_H
+#define __JZ4740_BATTERY_H
+
+struct jz_battery_platform_data {
+	struct power_supply_info info;
+	int gpio_charge;	/* GPIO port of Charger state */
+	int gpio_charge_active_low;
+};
+
+#endif
diff --git a/kernel/printk.c b/kernel/printk.c
index 444b770c95959261a491b8a673ff42e29a181592..4ab0164bcf84bc9660a5802c6355817b5d015c2e 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -37,6 +37,8 @@
 #include <linux/ratelimit.h>
 #include <linux/kmsg_dump.h>
 #include <linux/syslog.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
 
 #include <asm/uaccess.h>
 
@@ -984,6 +986,32 @@ void resume_console(void)
 	release_console_sem();
 }
 
+/**
+ * console_cpu_notify - print deferred console messages after CPU hotplug
+ * @self: notifier struct
+ * @action: CPU hotplug event
+ * @hcpu: unused
+ *
+ * If printk() is called from a CPU that is not online yet, the messages
+ * will be spooled but will not show up on the console.  This function is
+ * called when a new CPU comes online (or fails to come up), and ensures
+ * that any such output gets printed.
+ */
+static int __cpuinit console_cpu_notify(struct notifier_block *self,
+	unsigned long action, void *hcpu)
+{
+	switch (action) {
+	case CPU_ONLINE:
+	case CPU_DEAD:
+	case CPU_DYING:
+	case CPU_DOWN_FAILED:
+	case CPU_UP_CANCELED:
+		acquire_console_sem();
+		release_console_sem();
+	}
+	return NOTIFY_OK;
+}
+
 /**
  * acquire_console_sem - lock the console system for exclusive use.
  *
@@ -1371,7 +1399,7 @@ int unregister_console(struct console *console)
 }
 EXPORT_SYMBOL(unregister_console);
 
-static int __init disable_boot_consoles(void)
+static int __init printk_late_init(void)
 {
 	struct console *con;
 
@@ -1382,9 +1410,10 @@ static int __init disable_boot_consoles(void)
 			unregister_console(con);
 		}
 	}
+	hotcpu_notifier(console_cpu_notify, 0);
 	return 0;
 }
-late_initcall(disable_boot_consoles);
+late_initcall(printk_late_init);
 
 #if defined CONFIG_PRINTK
 
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index a681998a871cae548eb05f741ed6533daa17d238..ebf5e0c368ea0eb4bf48fbda2f76b5b347c3e247 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -32,6 +32,11 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
 			" msr = 0x%lx\n",
 		p->addr, regs->nip, regs->msr);
 #endif
+#ifdef CONFIG_MIPS
+	printk(KERN_INFO "pre_handler: p->addr = 0x%p, epc = 0x%lx,"
+			" status = 0x%lx\n",
+		p->addr, regs->cp0_epc, regs->cp0_status);
+#endif
 
 	/* A dump_stack() here will give a stack backtrace */
 	return 0;
@@ -49,6 +54,10 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
 	printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\n",
 		p->addr, regs->msr);
 #endif
+#ifdef CONFIG_MIPS
+	printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\n",
+		p->addr, regs->cp0_status);
+#endif
 }
 
 /*