Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

Conflicts:
	arch/sh/kernel/vmlinux.lds.S
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4c12a29..574ee67 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1561,7 +1561,7 @@
 			of returning the full 64-bit number.
 			The default is to return 64-bit inode numbers.
 
-	nmi_debug=	[KNL,AVR32] Specify one or more actions to take
+	nmi_debug=	[KNL,AVR32,SH] Specify one or more actions to take
 			when a NMI is triggered.
 			Format: [state][,regs][,debounce][,die]
 
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index e2bdd7b..2f5352c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -10,12 +10,16 @@
 	select EMBEDDED
 	select HAVE_CLK
 	select HAVE_IDE
+	select HAVE_LMB
 	select HAVE_OPROFILE
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_PERF_COUNTERS
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZMA
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	help
@@ -31,6 +35,9 @@
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FTRACE_SYSCALLS
+	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_ARCH_KGDB
 	select ARCH_HIBERNATION_POSSIBLE if MMU
 
@@ -212,6 +219,8 @@
 config ARCH_SHMOBILE
 	bool
 	select ARCH_SUSPEND_POSSIBLE
+	select PM
+	select PM_RUNTIME
 
 if SUPERH32
 
@@ -389,6 +398,13 @@
 	help
 	  Select SH7724 if you have an SH-MobileR2R CPU.
 
+config CPU_SUBTYPE_SH7757
+	bool "Support SH7757 processor"
+	select CPU_SH4A
+	select CPU_SHX2
+	help
+	  Select SH7757 if you have a SH4A SH7757 CPU.
+
 config CPU_SUBTYPE_SH7763
 	bool "Support SH7763 processor"
 	select CPU_SH4A
@@ -751,12 +767,31 @@
 
 	  If unsure, say N.
 
-config CMDLINE_BOOL
-	bool "Default bootloader kernel arguments"
+choice
+	prompt "Kernel command line"
+	optional
+	default CMDLINE_OVERWRITE
+	help
+	  Setting this option allows the kernel command line arguments
+	  to be set.
+
+config CMDLINE_OVERWRITE
+	bool "Overwrite bootloader kernel arguments"
+	help
+	  Given string will overwrite any arguments passed in by
+	  a bootloader.
+
+config CMDLINE_EXTEND
+	bool "Extend bootloader kernel arguments"
+	help
+	  Given string will be concatenated with arguments passed in
+	  by a bootloader.
+
+endchoice
 
 config CMDLINE
-	string "Initial kernel command string"
-	depends on CMDLINE_BOOL
+	string "Kernel command line arguments string"
+	depends on CMDLINE_OVERWRITE || CMDLINE_EXTEND
 	default "console=ttySC1,115200"
 
 endmenu
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 39224b5..55907af 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -38,11 +38,13 @@
 	default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
 				CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
 				CPU_SUBTYPE_SH7343
-	default "0xffea0000" if CPU_SUBTYPE_SH7785
+	default "0xfe4c0000" if CPU_SUBTYPE_SH7757
+	default "0xffeb0000" if CPU_SUBTYPE_SH7785
 	default "0xffeb0000" if CPU_SUBTYPE_SH7786
 	default "0xfffe8000" if CPU_SUBTYPE_SH7203
 	default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
 	default "0xffe80000" if CPU_SH4
+	default "0xa4000150" if CPU_SH3
 	default "0x00000000"
 
 config EARLY_PRINTK
@@ -61,12 +63,14 @@
 	  select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
 	  the kernel command line option to toggle back and forth.
 
-config DEBUG_STACKOVERFLOW
+config STACK_DEBUG
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL && SUPERH32
 	help
 	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
+	  drops below a certain limit. Saying Y here will add overhead to
+	  every function call and will therefore incur a major
+	  performance hit. Most users should say N.
 
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
@@ -107,6 +111,14 @@
 
 	  Those looking for more verbose debugging output should say Y.
 
+config DWARF_UNWINDER
+	bool "Enable the DWARF unwinder for stacktraces"
+	select FRAME_POINTER
+	default n
+	help
+	  Enabling this option will make stacktraces more accurate, at
+	  the cost of an increase in overall kernel size.
+
 config SH_NO_BSS_INIT
 	bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
 	depends on DEBUG_KERNEL
@@ -123,4 +135,9 @@
 	bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
 	depends on SUPERH64
 
+config MCOUNT
+	def_bool y
+	depends on SUPERH32
+	depends on STACK_DEBUG || FUNCTION_TRACER
+
 endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 75d049b0..fc51a91 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -136,6 +136,8 @@
 machdir-$(CONFIG_SH_EDOSK7705)			+= mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)			+= mach-highlander
 machdir-$(CONFIG_SH_MIGOR)			+= mach-migor
+machdir-$(CONFIG_SH_KFR2R09)			+= mach-kfr2r09
+machdir-$(CONFIG_SH_ECOVEC)			+= mach-ecovec24
 machdir-$(CONFIG_SH_SDK7780)			+= mach-sdk7780
 machdir-$(CONFIG_SH_X3PROTO)			+= mach-x3proto
 machdir-$(CONFIG_SH_SH7763RDP)			+= mach-sh7763rdp
@@ -186,17 +188,27 @@
 KBUILD_CPPFLAGS		+= $(cflags-y)
 KBUILD_AFLAGS		+= $(cflags-y)
 
+ifeq ($(CONFIG_MCOUNT),y)
+  KBUILD_CFLAGS += -pg
+endif
+
+ifeq ($(CONFIG_DWARF_UNWINDER),y)
+  KBUILD_CFLAGS += -fasynchronous-unwind-tables
+endif
+
 libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
 libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)
 
-PHONY += maketools FORCE
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
+	       zImage vmlinux.srec romImage
+PHONY += maketools $(BOOT_TARGETS) FORCE
 
 maketools:  include/linux/version.h FORCE
 	$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
 
 all: $(KBUILD_IMAGE)
 
-zImage uImage uImage.srec vmlinux.srec: vmlinux
+$(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 compressed: zImage
@@ -208,10 +220,14 @@
 	$(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall
 
 define archhelp
-	@echo '* zImage 	           - Compressed kernel image'
+	@echo '  zImage 	           - Compressed kernel image'
+	@echo '  romImage	           - Compressed ROM image, if supported'
 	@echo '  vmlinux.srec	           - Create an ELF S-record'
-	@echo '  uImage  	           - Create a bootable image for U-Boot'
-	@echo '  uImage.srec  	           - Create an S-record for U-Boot'
+	@echo '* uImage  	           - Alias to bootable U-Boot image'
+	@echo '  uImage.srec	           - Create an S-record for U-Boot'
+	@echo '* uImage.gz	           - Kernel-only image for U-Boot (gzip)'
+	@echo '  uImage.bz2	           - Kernel-only image for U-Boot (bzip2)'
+	@echo '  uImage.lzma	           - Kernel-only image for U-Boot (lzma)'
 endef
 
 CLEAN_FILES += include/asm-sh/machtypes.h
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 2b1af0e..aedd9de 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -160,7 +160,6 @@
 	bool "SH7785LCR"
 	depends on CPU_SUBTYPE_SH7785
 	select SYS_SUPPORTS_PCI
-	select IO_TRAPPED if MMU
 
 config SH_SH7785LCR_29BIT_PHYSMAPS
 	bool "SH7785LCR 29bit physmaps"
@@ -171,6 +170,13 @@
 	  DIP switch(S2-5). If you set the DIP switch for S2-5 = ON,
 	  you can access all on-board device in 29bit address mode.
 
+config SH_SH7785LCR_PT
+	bool "SH7785LCR prototype board on 32-bit MMU mode"
+	depends on SH_SH7785LCR && 32BIT
+	default n
+	help
+	  If you use prototype board, this option is enabled.
+
 config SH_URQUELL
 	bool "Urquell"
 	depends on CPU_SUBTYPE_SH7786
@@ -193,6 +199,20 @@
 	  Renesas "AP-325RXA" support.
 	  Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
 
+config SH_KFR2R09
+	bool "KFR2R09"
+	depends on CPU_SUBTYPE_SH7724
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  "Kit For R2R for 2009" support.
+
+config SH_ECOVEC
+	bool "EcoVec"
+	depends on CPU_SUBTYPE_SH7724
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  Renesas "R0P7724LC0011/21RL (EcoVec)" support.
+
 config SH_SH7763RDP
 	bool "SH7763RDP"
 	depends on CPU_SUBTYPE_SH7763
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index b9c88cc..327d47c 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -188,7 +188,7 @@
 			.name = "LB070WV1",
 			.xres = 800,
 			.yres = 480,
-			.left_margin = 40,
+			.left_margin = 32,
 			.right_margin = 160,
 			.hsync_len = 8,
 			.upper_margin = 63,
@@ -211,7 +211,7 @@
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -227,6 +227,9 @@
 	.dev		= {
 		.platform_data	= &lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 static void camera_power(int val)
@@ -377,6 +380,9 @@
 	.dev		= {
 		.platform_data	= &sh_mobile_ceu_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
 };
 
 struct spi_gpio_platform_data sdcard_cn3_platform_data = {
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 42410a1..e5a8a2f 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -223,6 +223,19 @@
 	.resource	= sm501_resources,
 };
 
+static struct resource i2c_proto_resources[] = {
+	[0] = {
+		.start	= PCA9564_PROTO_32BIT_ADDR,
+		.end	= PCA9564_PROTO_32BIT_ADDR + PCA9564_SIZE - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+	},
+	[1] = {
+		.start	= 12,
+		.end	= 12,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
 static struct resource i2c_resources[] = {
 	[0] = {
 		.start	= PCA9564_ADDR,
@@ -271,6 +284,11 @@
 	i2c_register_board_info(0, sh7785lcr_i2c_devices,
 				ARRAY_SIZE(sh7785lcr_i2c_devices));
 
+	if (mach_is_sh7785lcr_pt()) {
+		i2c_device.resource = i2c_proto_resources;
+		i2c_device.num_resources = ARRAY_SIZE(i2c_proto_resources);
+	}
+
 	return platform_add_devices(sh7785lcr_devices,
 				    ARRAY_SIZE(sh7785lcr_devices));
 }
diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile
new file mode 100644
index 0000000..51f8521
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the R0P7724LC0011/21RL (EcoVec)
+#
+# 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.
+#
+
+obj-y	 := setup.o
\ No newline at end of file
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
new file mode 100644
index 0000000..bbe601d
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <video/sh_mobile_lcdc.h>
+#include <media/sh_mobile_ceu.h>
+#include <asm/heartbeat.h>
+#include <asm/sh_eth.h>
+#include <asm/sh_keysc.h>
+#include <asm/clock.h>
+#include <cpu/sh7724.h>
+
+/*
+ *  Address      Interface        BusWidth
+ *-----------------------------------------
+ *  0x0000_0000  uboot            16bit
+ *  0x0004_0000  Linux romImage   16bit
+ *  0x0014_0000  MTD for Linux    16bit
+ *  0x0400_0000  Internal I/O     16/32bit
+ *  0x0800_0000  DRAM             32bit
+ *  0x1800_0000  MFI              16bit
+ */
+
+/* Heartbeat */
+static unsigned char led_pos[] = { 0, 1, 2, 3 };
+static struct heartbeat_data heartbeat_data = {
+	.regsize = 8,
+	.nr_bits = 4,
+	.bit_pos = led_pos,
+};
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start  = 0xA405012C, /* PTG */
+		.end    = 0xA405012E - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name           = "heartbeat",
+	.id             = -1,
+	.dev = {
+		.platform_data = &heartbeat_data,
+	},
+	.num_resources  = ARRAY_SIZE(heartbeat_resources),
+	.resource       = heartbeat_resources,
+};
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name = "boot loader",
+		.offset = 0,
+		.size = (5 * 1024 * 1024),
+		.mask_flags = MTD_CAP_ROM,
+	}, {
+		.name = "free-area",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0] = {
+		.name	= "NOR Flash",
+		.start	= 0x00000000,
+		.end	= 0x03ffffff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+	.dev		= {
+		.platform_data = &nor_flash_data,
+	},
+};
+
+/* SH Eth */
+#define SH_ETH_ADDR	(0xA4600000)
+#define SH_ETH_MAHR	(SH_ETH_ADDR + 0x1C0)
+#define SH_ETH_MALR	(SH_ETH_ADDR + 0x1C8)
+static struct resource sh_eth_resources[] = {
+	[0] = {
+		.start = SH_ETH_ADDR,
+		.end   = SH_ETH_ADDR + 0x1FC,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = 91,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+struct sh_eth_plat_data sh_eth_plat = {
+	.phy = 0x1f, /* SMSC LAN8700 */
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh_eth_device = {
+	.name = "sh-eth",
+	.id	= 0,
+	.dev = {
+		.platform_data = &sh_eth_plat,
+	},
+	.num_resources = ARRAY_SIZE(sh_eth_resources),
+	.resource = sh_eth_resources,
+};
+
+/* USB0 host */
+void usb0_port_power(int port, int power)
+{
+	gpio_set_value(GPIO_PTB4, power);
+}
+
+static struct r8a66597_platdata usb0_host_data = {
+	.on_chip = 1,
+	.port_power = usb0_port_power,
+};
+
+static struct resource usb0_host_resources[] = {
+	[0] = {
+		.start	= 0xa4d80000,
+		.end	= 0xa4d80124 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device usb0_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usb0_host_data,
+	},
+	.num_resources	= ARRAY_SIZE(usb0_host_resources),
+	.resource	= usb0_host_resources,
+};
+
+/*
+ * USB1
+ *
+ * CN5 can use both host/function,
+ * and we can determine it by checking PTB[3]
+ *
+ * This time only USB1 host is supported.
+ */
+void usb1_port_power(int port, int power)
+{
+	if (!gpio_get_value(GPIO_PTB3)) {
+		printk(KERN_ERR "USB1 function is not supported\n");
+		return;
+	}
+
+	gpio_set_value(GPIO_PTB5, power);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+	.on_chip = 1,
+	.port_power = usb1_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+	[0] = {
+		.start	= 0xa4d90000,
+		.end	= 0xa4d90124 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device usb1_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 1,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usb1_host_data,
+	},
+	.num_resources	= ARRAY_SIZE(usb1_host_resources),
+	.resource	= usb1_host_resources,
+};
+
+/* LCDC */
+static struct sh_mobile_lcdc_info lcdc_info = {
+	.ch[0] = {
+		.interface_type = RGB18,
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.lcd_cfg = {
+			.sync = 0, /* hsync and vsync are active low */
+		},
+		.lcd_size_cfg = { /* 7.0 inch */
+			.width = 152,
+			.height = 91,
+		},
+		.board_cfg = {
+		},
+	}
+};
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000,
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 106,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+	.resource	= lcdc_resources,
+	.dev		= {
+		.platform_data	= &lcdc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+/* CEU0 */
+static struct sh_mobile_ceu_info sh_mobile_ceu0_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu0_resources[] = {
+	[0] = {
+		.name	= "CEU0",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device ceu0_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
+	.num_resources	= ARRAY_SIZE(ceu0_resources),
+	.resource	= ceu0_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu0_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
+};
+
+/* CEU1 */
+static struct sh_mobile_ceu_info sh_mobile_ceu1_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu1_resources[] = {
+	[0] = {
+		.name	= "CEU1",
+		.start	= 0xfe914000,
+		.end	= 0xfe91409f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 63,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device ceu1_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 1, /* "ceu1" clock */
+	.num_resources	= ARRAY_SIZE(ceu1_resources),
+	.resource	= ceu1_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu1_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU1,
+	},
+};
+
+/* I2C device */
+static struct i2c_board_info i2c1_devices[] = {
+	{
+		I2C_BOARD_INFO("r2025sd", 0x32),
+	},
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+	.mode		= SH_KEYSC_MODE_1,
+	.scan_timing	= 3,
+	.delay		= 50,
+	.kycr2_delay	= 100,
+	.keycodes	= { KEY_1, 0, 0, 0, 0,
+			    KEY_2, 0, 0, 0, 0,
+			    KEY_3, 0, 0, 0, 0,
+			    KEY_4, 0, 0, 0, 0,
+			    KEY_5, 0, 0, 0, 0,
+			    KEY_6, 0, 0, 0, 0, },
+};
+
+static struct resource keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0x044b0000,
+		.end    = 0x044b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* keysc0 clock */
+	.num_resources  = ARRAY_SIZE(keysc_resources),
+	.resource       = keysc_resources,
+	.dev	= {
+		.platform_data	= &keysc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
+};
+
+static struct platform_device *ecovec_devices[] __initdata = {
+	&heartbeat_device,
+	&nor_flash_device,
+	&sh_eth_device,
+	&usb0_host_device,
+	&usb1_host_device, /* USB1 host support */
+	&lcdc_device,
+	&ceu0_device,
+	&ceu1_device,
+	&keysc_device,
+};
+
+#define EEPROM_ADDR 0x50
+static u8 mac_read(struct i2c_adapter *a, u8 command)
+{
+	struct i2c_msg msg[2];
+	u8 buf;
+	int ret;
+
+	msg[0].addr  = EEPROM_ADDR;
+	msg[0].flags = 0;
+	msg[0].len   = 1;
+	msg[0].buf   = &command;
+
+	msg[1].addr  = EEPROM_ADDR;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len   = 1;
+	msg[1].buf   = &buf;
+
+	ret = i2c_transfer(a, msg, 2);
+	if (ret < 0) {
+		printk(KERN_ERR "error %d\n", ret);
+		buf = 0xff;
+	}
+
+	return buf;
+}
+
+#define MAC_LEN 6
+static void __init sh_eth_init(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(1);
+	struct clk *eth_clk;
+	u8 mac[MAC_LEN];
+	int i;
+
+	if (!a) {
+		pr_err("can not get I2C 1\n");
+		return;
+	}
+
+	eth_clk = clk_get(NULL, "eth0");
+	if (!eth_clk) {
+		pr_err("can not get eth0 clk\n");
+		return;
+	}
+
+	/* read MAC address frome EEPROM */
+	for (i = 0; i < MAC_LEN; i++) {
+		mac[i] = mac_read(a, 0x10 + i);
+		msleep(10);
+	}
+
+	/* clock enable */
+	clk_enable(eth_clk);
+
+	/* reset sh-eth */
+	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
+
+	/* set MAC addr */
+	ctrl_outl((mac[0] << 24) |
+		  (mac[1] << 16) |
+		  (mac[2] <<  8) |
+		  (mac[3] <<  0), SH_ETH_MAHR);
+	ctrl_outl((mac[4] <<  8) |
+		  (mac[5] <<  0), SH_ETH_MALR);
+
+	clk_put(eth_clk);
+}
+
+#define PORT_HIZA 0xA4050158
+#define IODRIVEA  0xA405018A
+static int __init arch_setup(void)
+{
+	/* enable SCIFA0 */
+	gpio_request(GPIO_FN_SCIF0_TXD, NULL);
+	gpio_request(GPIO_FN_SCIF0_RXD, NULL);
+
+	/* enable debug LED */
+	gpio_request(GPIO_PTG0, NULL);
+	gpio_request(GPIO_PTG1, NULL);
+	gpio_request(GPIO_PTG2, NULL);
+	gpio_request(GPIO_PTG3, NULL);
+	gpio_direction_output(GPIO_PTG0, 0);
+	gpio_direction_output(GPIO_PTG1, 0);
+	gpio_direction_output(GPIO_PTG2, 0);
+	gpio_direction_output(GPIO_PTG3, 0);
+	ctrl_outw((ctrl_inw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
+
+	/* enable SH-Eth */
+	gpio_request(GPIO_PTA1, NULL);
+	gpio_direction_output(GPIO_PTA1, 1);
+	mdelay(20);
+
+	gpio_request(GPIO_FN_RMII_RXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_RXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
+	gpio_request(GPIO_FN_RMII_TX_EN,   NULL);
+	gpio_request(GPIO_FN_RMII_RX_ER,   NULL);
+	gpio_request(GPIO_FN_RMII_CRS_DV,  NULL);
+	gpio_request(GPIO_FN_MDIO,         NULL);
+	gpio_request(GPIO_FN_MDC,          NULL);
+	gpio_request(GPIO_FN_LNKSTA,       NULL);
+
+	/* enable USB */
+	ctrl_outw(0x0000, 0xA4D80000);
+	ctrl_outw(0x0000, 0xA4D90000);
+	gpio_request(GPIO_PTB3,  NULL);
+	gpio_request(GPIO_PTB4,  NULL);
+	gpio_request(GPIO_PTB5,  NULL);
+	gpio_direction_input(GPIO_PTB3);
+	gpio_direction_output(GPIO_PTB4, 0);
+	gpio_direction_output(GPIO_PTB5, 0);
+	ctrl_outw(0x0600, 0xa40501d4);
+	ctrl_outw(0x0600, 0xa4050192);
+
+	/* enable LCDC */
+	gpio_request(GPIO_FN_LCDD23,   NULL);
+	gpio_request(GPIO_FN_LCDD22,   NULL);
+	gpio_request(GPIO_FN_LCDD21,   NULL);
+	gpio_request(GPIO_FN_LCDD20,   NULL);
+	gpio_request(GPIO_FN_LCDD19,   NULL);
+	gpio_request(GPIO_FN_LCDD18,   NULL);
+	gpio_request(GPIO_FN_LCDD17,   NULL);
+	gpio_request(GPIO_FN_LCDD16,   NULL);
+	gpio_request(GPIO_FN_LCDD15,   NULL);
+	gpio_request(GPIO_FN_LCDD14,   NULL);
+	gpio_request(GPIO_FN_LCDD13,   NULL);
+	gpio_request(GPIO_FN_LCDD12,   NULL);
+	gpio_request(GPIO_FN_LCDD11,   NULL);
+	gpio_request(GPIO_FN_LCDD10,   NULL);
+	gpio_request(GPIO_FN_LCDD9,    NULL);
+	gpio_request(GPIO_FN_LCDD8,    NULL);
+	gpio_request(GPIO_FN_LCDD7,    NULL);
+	gpio_request(GPIO_FN_LCDD6,    NULL);
+	gpio_request(GPIO_FN_LCDD5,    NULL);
+	gpio_request(GPIO_FN_LCDD4,    NULL);
+	gpio_request(GPIO_FN_LCDD3,    NULL);
+	gpio_request(GPIO_FN_LCDD2,    NULL);
+	gpio_request(GPIO_FN_LCDD1,    NULL);
+	gpio_request(GPIO_FN_LCDD0,    NULL);
+	gpio_request(GPIO_FN_LCDDISP,  NULL);
+	gpio_request(GPIO_FN_LCDHSYN,  NULL);
+	gpio_request(GPIO_FN_LCDDCK,   NULL);
+	gpio_request(GPIO_FN_LCDVSYN,  NULL);
+	gpio_request(GPIO_FN_LCDDON,   NULL);
+	gpio_request(GPIO_FN_LCDLCLK,  NULL);
+	ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+
+	gpio_request(GPIO_PTE6, NULL);
+	gpio_request(GPIO_PTU1, NULL);
+	gpio_request(GPIO_PTR1, NULL);
+	gpio_request(GPIO_PTA2, NULL);
+	gpio_direction_input(GPIO_PTE6);
+	gpio_direction_output(GPIO_PTU1, 0);
+	gpio_direction_output(GPIO_PTR1, 0);
+	gpio_direction_output(GPIO_PTA2, 0);
+
+	/* I/O buffer drive ability is low */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA);
+
+	if (gpio_get_value(GPIO_PTE6)) {
+		/* DVI */
+		lcdc_info.clock_source			= LCDC_CLK_EXTERNAL;
+		lcdc_info.ch[0].clock_divider		= 1,
+		lcdc_info.ch[0].lcd_cfg.name		= "DVI";
+		lcdc_info.ch[0].lcd_cfg.xres		= 1280;
+		lcdc_info.ch[0].lcd_cfg.yres		= 720;
+		lcdc_info.ch[0].lcd_cfg.left_margin	= 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin	= 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len	= 40;
+		lcdc_info.ch[0].lcd_cfg.upper_margin	= 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin	= 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len	= 5;
+
+		gpio_set_value(GPIO_PTA2, 1);
+		gpio_set_value(GPIO_PTU1, 1);
+	} else {
+		/* Panel */
+
+		lcdc_info.clock_source			= LCDC_CLK_PERIPHERAL;
+		lcdc_info.ch[0].clock_divider		= 2,
+		lcdc_info.ch[0].lcd_cfg.name		= "Panel";
+		lcdc_info.ch[0].lcd_cfg.xres		= 800;
+		lcdc_info.ch[0].lcd_cfg.yres		= 480;
+		lcdc_info.ch[0].lcd_cfg.left_margin	= 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin	= 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len	= 70;
+		lcdc_info.ch[0].lcd_cfg.upper_margin	= 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin	= 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len	= 5;
+
+		gpio_set_value(GPIO_PTR1, 1);
+
+		/* FIXME
+		 *
+		 * LCDDON control is needed for Panel,
+		 * but current sh_mobile_lcdc driver doesn't control it.
+		 * It is temporary correspondence
+		 */
+		gpio_request(GPIO_PTF4, NULL);
+		gpio_direction_output(GPIO_PTF4, 1);
+	}
+
+	/* enable CEU0 */
+	gpio_request(GPIO_FN_VIO0_D15, NULL);
+	gpio_request(GPIO_FN_VIO0_D14, NULL);
+	gpio_request(GPIO_FN_VIO0_D13, NULL);
+	gpio_request(GPIO_FN_VIO0_D12, NULL);
+	gpio_request(GPIO_FN_VIO0_D11, NULL);
+	gpio_request(GPIO_FN_VIO0_D10, NULL);
+	gpio_request(GPIO_FN_VIO0_D9,  NULL);
+	gpio_request(GPIO_FN_VIO0_D8,  NULL);
+	gpio_request(GPIO_FN_VIO0_D7,  NULL);
+	gpio_request(GPIO_FN_VIO0_D6,  NULL);
+	gpio_request(GPIO_FN_VIO0_D5,  NULL);
+	gpio_request(GPIO_FN_VIO0_D4,  NULL);
+	gpio_request(GPIO_FN_VIO0_D3,  NULL);
+	gpio_request(GPIO_FN_VIO0_D2,  NULL);
+	gpio_request(GPIO_FN_VIO0_D1,  NULL);
+	gpio_request(GPIO_FN_VIO0_D0,  NULL);
+	gpio_request(GPIO_FN_VIO0_VD,  NULL);
+	gpio_request(GPIO_FN_VIO0_CLK, NULL);
+	gpio_request(GPIO_FN_VIO0_FLD, NULL);
+	gpio_request(GPIO_FN_VIO0_HD,  NULL);
+	platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20);
+
+	/* enable CEU1 */
+	gpio_request(GPIO_FN_VIO1_D7,  NULL);
+	gpio_request(GPIO_FN_VIO1_D6,  NULL);
+	gpio_request(GPIO_FN_VIO1_D5,  NULL);
+	gpio_request(GPIO_FN_VIO1_D4,  NULL);
+	gpio_request(GPIO_FN_VIO1_D3,  NULL);
+	gpio_request(GPIO_FN_VIO1_D2,  NULL);
+	gpio_request(GPIO_FN_VIO1_D1,  NULL);
+	gpio_request(GPIO_FN_VIO1_D0,  NULL);
+	gpio_request(GPIO_FN_VIO1_FLD, NULL);
+	gpio_request(GPIO_FN_VIO1_HD,  NULL);
+	gpio_request(GPIO_FN_VIO1_VD,  NULL);
+	gpio_request(GPIO_FN_VIO1_CLK, NULL);
+	platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20);
+
+	/* enable KEYSC */
+	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+	gpio_request(GPIO_FN_KEYOUT3,     NULL);
+	gpio_request(GPIO_FN_KEYOUT2,     NULL);
+	gpio_request(GPIO_FN_KEYOUT1,     NULL);
+	gpio_request(GPIO_FN_KEYOUT0,     NULL);
+	gpio_request(GPIO_FN_KEYIN0,      NULL);
+
+	/* enable I2C device */
+	i2c_register_board_info(1, i2c1_devices,
+				ARRAY_SIZE(i2c1_devices));
+
+	return platform_add_devices(ecovec_devices,
+				    ARRAY_SIZE(ecovec_devices));
+}
+arch_initcall(arch_setup);
+
+static int __init devices_setup(void)
+{
+	sh_eth_init();
+	return 0;
+}
+device_initcall(devices_setup);
+
+
+static struct sh_machine_vector mv_ecovec __initmv = {
+	.mv_name	= "R0P7724 (EcoVec)",
+};
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index 1639f89..566e69d 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <net/ax88796.h>
 #include <asm/machvec.h>
 #include <mach/highlander.h>
@@ -60,6 +61,11 @@
 	.resource	= r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+	.xtal = M66592_PLATDATA_XTAL_24MHZ,
+	.vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
 	[0] = {
 		.name	= "m66592_udc",
@@ -81,6 +87,7 @@
 	.dev = {
 		.dma_mask		= NULL,		/* don't use dma */
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
 	.resource	= m66592_usb_peripheral_resources,
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile
new file mode 100644
index 0000000..5d58678
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/Makefile
@@ -0,0 +1,2 @@
+obj-y	 := setup.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC)	+=  lcd_wqvga.o
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
new file mode 100644
index 0000000..8ccb1cc
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -0,0 +1,332 @@
+/*
+ * KFR2R09 LCD panel support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * Register settings based on the out-of-tree t33fb.c driver
+ * Copyright (C) 2008 Lineo Solutions, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <mach/kfr2r09.h>
+#include <cpu/sh7724.h>
+
+/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made
+ * up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is
+ * communicating with the main port of the LCDC using an 18-bit SYS interface.
+ *
+ * The device code for this LCD module is 0x01221517.
+ */
+
+static const unsigned char data_frame_if[] = {
+	0x02, /* WEMODE: 1=cont, 0=one-shot */
+	0x00, 0x00,
+	0x00, /* EPF, DFM */
+	0x02, /* RIM[1] : 1 (18bpp) */
+};
+
+static const unsigned char data_panel[] = {
+	0x0b,
+	0x63, /* 400 lines */
+	0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00,
+};
+
+static const unsigned char data_timing[] = {
+	0x00, 0x00, 0x13, 0x08, 0x08,
+};
+
+static const unsigned char data_timing_src[] = {
+	0x11, 0x01, 0x00, 0x01,
+};
+
+static const unsigned char data_gamma[] = {
+	0x01, 0x02, 0x08, 0x23,	0x03, 0x0c, 0x00, 0x06,	0x00, 0x00,
+	0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00,
+};
+
+static const unsigned char data_power[] = {
+	0x07, 0xc5, 0xdc, 0x02,	0x33, 0x0a,
+};
+
+static unsigned long read_reg(void *sohandle,
+			      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	return so->read_data(sohandle);
+}
+
+static void write_reg(void *sohandle,
+		      struct sh_mobile_lcdc_sys_bus_ops *so,
+		      int i, unsigned long v)
+{
+	if (i)
+		so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */
+	else
+		so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */
+}
+
+static void write_data(void *sohandle,
+		       struct sh_mobile_lcdc_sys_bus_ops *so,
+		       unsigned char const *data, int no_data)
+{
+	int i;
+
+	for (i = 0; i < no_data; i++)
+		write_reg(sohandle, so, 1, data[i]);
+}
+
+static unsigned long read_device_code(void *sohandle,
+				      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	unsigned long device_code;
+
+	/* access protect OFF */
+	write_reg(sohandle, so, 0, 0xb0);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* deep standby OFF */
+	write_reg(sohandle, so, 0, 0xb1);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* device code command */
+	write_reg(sohandle, so, 0, 0xbf);
+	mdelay(50);
+
+	/* dummy read */
+	read_reg(sohandle, so);
+
+	/* read device code */
+	device_code = ((read_reg(sohandle, so) & 0xff) << 24);
+	device_code |= ((read_reg(sohandle, so) & 0xff) << 16);
+	device_code |= ((read_reg(sohandle, so) & 0xff) << 8);
+	device_code |= (read_reg(sohandle, so) & 0xff);
+
+	return device_code;
+}
+
+static void write_memory_start(void *sohandle,
+			       struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	write_reg(sohandle, so, 0, 0x2c);
+}
+
+static void clear_memory(void *sohandle,
+			 struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	int i;
+
+	/* write start */
+	write_memory_start(sohandle, so);
+
+	/* paint it black */
+	for (i = 0; i < (240 * 400); i++)
+		write_reg(sohandle, so, 1, 0x00);
+}
+
+static void display_on(void *sohandle,
+		       struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	/* access protect off */
+	write_reg(sohandle, so, 0, 0xb0);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* exit deep standby mode */
+	write_reg(sohandle, so, 0, 0xb1);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* frame memory I/F */
+	write_reg(sohandle, so, 0, 0xb3);
+	write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if));
+
+	/* display mode and frame memory write mode */
+	write_reg(sohandle, so, 0, 0xb4);
+	write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */
+
+	/* panel */
+	write_reg(sohandle, so, 0, 0xc0);
+	write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel));
+
+	/* timing (normal) */
+	write_reg(sohandle, so, 0, 0xc1);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (partial) */
+	write_reg(sohandle, so, 0, 0xc2);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (idle) */
+	write_reg(sohandle, so, 0, 0xc3);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (source/VCOM/gate driving) */
+	write_reg(sohandle, so, 0, 0xc4);
+	write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src));
+
+	/* gamma (red) */
+	write_reg(sohandle, so, 0, 0xc8);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* gamma (green) */
+	write_reg(sohandle, so, 0, 0xc9);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* gamma (blue) */
+	write_reg(sohandle, so, 0, 0xca);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* power (common) */
+	write_reg(sohandle, so, 0, 0xd0);
+	write_data(sohandle, so, data_power, ARRAY_SIZE(data_power));
+
+	/* VCOM */
+	write_reg(sohandle, so, 0, 0xd1);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x0f);
+	write_reg(sohandle, so, 1, 0x02);
+
+	/* power (normal) */
+	write_reg(sohandle, so, 0, 0xd2);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	/* power (partial) */
+	write_reg(sohandle, so, 0, 0xd3);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	/* power (idle) */
+	write_reg(sohandle, so, 0, 0xd4);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	write_reg(sohandle, so, 0, 0xd8);
+	write_reg(sohandle, so, 1, 0x77);
+	write_reg(sohandle, so, 1, 0x77);
+
+	/* TE signal */
+	write_reg(sohandle, so, 0, 0x35);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* TE signal line */
+	write_reg(sohandle, so, 0, 0x44);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* column address */
+	write_reg(sohandle, so, 0, 0x2a);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0xef);
+
+	/* page address */
+	write_reg(sohandle, so, 0, 0x2b);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x01);
+	write_reg(sohandle, so, 1, 0x8f);
+
+	/* exit sleep mode */
+	write_reg(sohandle, so, 0, 0x11);
+
+	mdelay(120);
+
+	/* clear vram */
+	clear_memory(sohandle, so);
+
+	/* display ON */
+	write_reg(sohandle, so, 0, 0x29);
+	mdelay(1);
+
+	write_memory_start(sohandle, so);
+}
+
+int kfr2r09_lcd_setup(void *board_data, void *sohandle,
+		      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	/* power on */
+	gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+	gpio_set_value(GPIO_PTE4, 0);  /* LCD_RST/ -> L */
+	gpio_set_value(GPIO_PTF4, 1);  /* PROTECT/ -> H */
+	udelay(1100);
+	gpio_set_value(GPIO_PTE4, 1);  /* LCD_RST/ -> H */
+	udelay(10);
+	gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+	mdelay(20);
+
+	if (read_device_code(sohandle, so) != 0x01221517)
+		return -ENODEV;
+
+	pr_info("KFR2R09 WQVGA LCD Module detected.\n");
+
+	display_on(sohandle, so);
+	return 0;
+}
+
+#define CTRL_CKSW       0x10
+#define CTRL_C10        0x20
+#define CTRL_CPSW       0x80
+#define MAIN_MLED4      0x40
+#define MAIN_MSW        0x80
+
+static int kfr2r09_lcd_backlight(int on)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	buf[0] = 0x00;
+	if (on)
+		buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW;
+	else
+		buf[1] = 0;
+
+	msg.addr = 0x75;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0x01;
+	if (on)
+		buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c;
+	else
+		buf[1] = 0;
+
+	msg.addr = 0x75;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
+
+void kfr2r09_lcd_on(void *board_data)
+{
+	kfr2r09_lcd_backlight(1);
+}
+
+void kfr2r09_lcd_off(void *board_data)
+{
+	kfr2r09_lcd_backlight(0);
+}
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
new file mode 100644
index 0000000..c08d33f
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -0,0 +1,386 @@
+/*
+ * KFR2R09 board support code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/usb/r8a66597.h>
+#include <video/sh_mobile_lcdc.h>
+#include <asm/clock.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/sh_keysc.h>
+#include <cpu/sh7724.h>
+#include <mach/kfr2r09.h>
+
+static struct mtd_partition kfr2r09_nor_flash_partitions[] =
+{
+	{
+		.name = "boot",
+		.offset = 0,
+		.size = (4 * 1024 * 1024),
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+	},
+	{
+		.name = "other",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data kfr2r09_nor_flash_data = {
+	.width		= 2,
+	.parts		= kfr2r09_nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(kfr2r09_nor_flash_partitions),
+};
+
+static struct resource kfr2r09_nor_flash_resources[] = {
+	[0] = {
+		.name		= "NOR Flash",
+		.start		= 0x00000000,
+		.end		= 0x03ffffff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device kfr2r09_nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= kfr2r09_nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(kfr2r09_nor_flash_resources),
+	.dev		= {
+		.platform_data = &kfr2r09_nor_flash_data,
+	},
+};
+
+static struct resource kfr2r09_nand_flash_resources[] = {
+	[0] = {
+		.name		= "NAND Flash",
+		.start		= 0x10000000,
+		.end		= 0x1001ffff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device kfr2r09_nand_flash_device = {
+	.name		= "onenand-flash",
+	.resource	= kfr2r09_nand_flash_resources,
+	.num_resources	= ARRAY_SIZE(kfr2r09_nand_flash_resources),
+};
+
+static struct sh_keysc_info kfr2r09_sh_keysc_info = {
+	.mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */
+	.scan_timing = 3,
+	.delay = 10,
+	.keycodes = {
+		KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER,
+		KEY_1, KEY_2, KEY_3, 0, KEY_UP,
+		KEY_4, KEY_5, KEY_6, 0, KEY_LEFT,
+		KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT,
+		KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN,
+		0, 0, 0, 0, 0
+	},
+};
+
+static struct resource kfr2r09_sh_keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0x044b0000,
+		.end    = 0x044b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* "keysc0" clock */
+	.num_resources  = ARRAY_SIZE(kfr2r09_sh_keysc_resources),
+	.resource       = kfr2r09_sh_keysc_resources,
+	.dev	= {
+		.platform_data	= &kfr2r09_sh_keysc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
+};
+
+static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
+	.clock_source = LCDC_CLK_BUS,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.interface_type = SYS18,
+		.clock_divider = 6,
+		.flags = LCDC_FLAGS_DWPOL,
+		.lcd_cfg = {
+			.name = "TX07D34VM0AAA",
+			.xres = 240,
+			.yres = 400,
+			.left_margin = 0,
+			.right_margin = 16,
+			.hsync_len = 8,
+			.upper_margin = 0,
+			.lower_margin = 1,
+			.vsync_len = 1,
+			.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		},
+		.lcd_size_cfg = {
+			.width = 35,
+			.height = 58,
+		},
+		.board_cfg = {
+			.setup_sys = kfr2r09_lcd_setup,
+			.display_on = kfr2r09_lcd_on,
+			.display_off = kfr2r09_lcd_off,
+		},
+		.sys_bus_cfg = {
+			.ldmt2r = 0x07010904,
+			.ldmt3r = 0x14012914,
+			/* set 1s delay to encourage fsync() */
+			.deferred_io_msec = 1000,
+		},
+	}
+};
+
+static struct resource kfr2r09_sh_lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000, /* P4-only space */
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 106,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(kfr2r09_sh_lcdc_resources),
+	.resource	= kfr2r09_sh_lcdc_resources,
+	.dev	= {
+		.platform_data	= &kfr2r09_sh_lcdc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+static struct r8a66597_platdata kfr2r09_usb0_gadget_data = {
+	.on_chip = 1,
+};
+
+static struct resource kfr2r09_usb0_gadget_resources[] = {
+	[0] = {
+		.start	= 0x04d80000,
+		.end	= 0x04d80123,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device kfr2r09_usb0_gadget_device = {
+	.name		= "r8a66597_udc",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data	= &kfr2r09_usb0_gadget_data,
+	},
+	.num_resources	= ARRAY_SIZE(kfr2r09_usb0_gadget_resources),
+	.resource	= kfr2r09_usb0_gadget_resources,
+};
+
+static struct platform_device *kfr2r09_devices[] __initdata = {
+	&kfr2r09_nor_flash_device,
+	&kfr2r09_nand_flash_device,
+	&kfr2r09_sh_keysc_device,
+	&kfr2r09_sh_lcdc_device,
+};
+
+#define BSC_CS0BCR 0xfec10004
+#define BSC_CS0WCR 0xfec10024
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS4WCR 0xfec10030
+#define PORT_MSELCRB 0xa4050182
+
+#ifdef CONFIG_I2C
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	/* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[1] = buf[0] | (1 << 1);
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
+#else
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+	return -ENODEV;
+}
+#endif
+
+static int kfr2r09_usb0_gadget_setup(void)
+{
+	int plugged_in;
+
+	gpio_request(GPIO_PTN4, NULL); /* USB_DET */
+	gpio_direction_input(GPIO_PTN4);
+	plugged_in = gpio_get_value(GPIO_PTN4);
+	if (!plugged_in)
+		return -ENODEV; /* no cable plugged in */
+
+	if (kfr2r09_usb0_gadget_i2c_setup() != 0)
+		return -ENODEV; /* unable to configure using i2c */
+
+	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+	gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */
+	gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */
+	gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */
+	msleep(20); /* wait 20ms to let the clock settle */
+	clk_enable(clk_get(NULL, "usb0"));
+	ctrl_outw(0x0600, 0xa40501d4);
+
+	return 0;
+}
+
+static int __init kfr2r09_devices_setup(void)
+{
+	/* enable SCIF1 serial port for YC401 console support */
+	gpio_request(GPIO_FN_SCIF1_RXD, NULL);
+	gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+
+	/* setup NOR flash at CS0 */
+	ctrl_outl(0x36db0400, BSC_CS0BCR);
+	ctrl_outl(0x00000500, BSC_CS0WCR);
+
+	/* setup NAND flash at CS4 */
+	ctrl_outl(0x36db0400, BSC_CS4BCR);
+	ctrl_outl(0x00000500, BSC_CS4WCR);
+
+	/* setup KEYSC pins */
+	gpio_request(GPIO_FN_KEYOUT0, NULL);
+	gpio_request(GPIO_FN_KEYOUT1, NULL);
+	gpio_request(GPIO_FN_KEYOUT2, NULL);
+	gpio_request(GPIO_FN_KEYOUT3, NULL);
+	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+	gpio_request(GPIO_FN_KEYIN0, NULL);
+	gpio_request(GPIO_FN_KEYIN1, NULL);
+	gpio_request(GPIO_FN_KEYIN2, NULL);
+	gpio_request(GPIO_FN_KEYIN3, NULL);
+	gpio_request(GPIO_FN_KEYIN4, NULL);
+	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+	/* setup LCDC pins for SYS panel */
+	gpio_request(GPIO_FN_LCDD17, NULL);
+	gpio_request(GPIO_FN_LCDD16, NULL);
+	gpio_request(GPIO_FN_LCDD15, NULL);
+	gpio_request(GPIO_FN_LCDD14, NULL);
+	gpio_request(GPIO_FN_LCDD13, NULL);
+	gpio_request(GPIO_FN_LCDD12, NULL);
+	gpio_request(GPIO_FN_LCDD11, NULL);
+	gpio_request(GPIO_FN_LCDD10, NULL);
+	gpio_request(GPIO_FN_LCDD9, NULL);
+	gpio_request(GPIO_FN_LCDD8, NULL);
+	gpio_request(GPIO_FN_LCDD7, NULL);
+	gpio_request(GPIO_FN_LCDD6, NULL);
+	gpio_request(GPIO_FN_LCDD5, NULL);
+	gpio_request(GPIO_FN_LCDD4, NULL);
+	gpio_request(GPIO_FN_LCDD3, NULL);
+	gpio_request(GPIO_FN_LCDD2, NULL);
+	gpio_request(GPIO_FN_LCDD1, NULL);
+	gpio_request(GPIO_FN_LCDD0, NULL);
+	gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */
+	gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */
+	gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */
+	gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */
+	gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */
+	gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */
+	gpio_direction_output(GPIO_PTE4, 1);
+	gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */
+	gpio_direction_output(GPIO_PTF4, 1);
+	gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */
+	gpio_direction_output(GPIO_PTU0, 1);
+
+	/* setup USB function */
+	if (kfr2r09_usb0_gadget_setup() == 0)
+		platform_device_register(&kfr2r09_usb0_gadget_device);
+
+	return platform_add_devices(kfr2r09_devices,
+				    ARRAY_SIZE(kfr2r09_devices));
+}
+device_initcall(kfr2r09_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int kfr2r09_mode_pins(void)
+{
+	/* MD0=1, MD1=1, MD2=0: Clock Mode 3
+	 * MD3=0: 16-bit Area0 Bus Width
+	 * MD5=1: Little Endian
+	 * MD8=1: Test Mode Disabled
+	 */
+	return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_kfr2r09 __initmv = {
+	.mv_name		= "kfr2r09",
+	.mv_mode_pins		= kfr2r09_mode_pins,
+};
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index f9b2e4d..6ed1fd3 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -98,6 +98,9 @@
 	.dev	= {
 		.platform_data	= &sh_keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 static struct mtd_partition migor_nor_flash_partitions[] =
@@ -276,7 +279,7 @@
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -292,6 +295,9 @@
 	.dev	= {
 		.platform_data	= &sh_mobile_lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 static struct clk *camera_clk;
@@ -379,6 +385,9 @@
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
 };
 
 struct spi_gpio_platform_data sdcard_cn9_platform_data = {
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index af84904..3637407 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -22,6 +22,7 @@
 #include <asm/io.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_keysc.h>
+#include <cpu/sh7722.h>
 
 /* Heartbeat */
 static struct heartbeat_data heartbeat_data = {
@@ -137,6 +138,9 @@
 	.dev	= {
 		.platform_data	= &sh_keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 static struct platform_device *se7722_devices[] __initdata = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 15456a0..00973e0 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -39,7 +39,15 @@
  * SW41 : abxx xxxx  -> a = 0 : Analog  monitor
  *                          1 : Digital monitor
  *                      b = 0 : VGA
- *                          1 : SVGA
+ *                          1 : 720p
+ */
+
+/*
+ * about 720p
+ *
+ * When you use 1280 x 720 lcdc output,
+ * you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
+ * and change SW41 to use 720p
  */
 
 /* Heartbeat */
@@ -158,7 +166,7 @@
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000,
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -174,6 +182,9 @@
 	.dev		= {
 		.platform_data	= &lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 /* CEU0 */
@@ -205,6 +216,9 @@
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu0_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
 };
 
 /* CEU1 */
@@ -236,6 +250,9 @@
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu1_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU1,
+	},
 };
 
 /* KEYSC in SoC (Needs SW33-2 set to ON) */
@@ -274,6 +291,9 @@
 	.dev	= {
 		.platform_data	= &keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 /* SH Eth */
@@ -302,15 +322,19 @@
 	},
 	.num_resources = ARRAY_SIZE(sh_eth_resources),
 	.resource = sh_eth_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_ETHER,
+	},
 };
 
 static struct r8a66597_platdata sh7724_usb0_host_data = {
+	.on_chip = 1,
 };
 
 static struct resource sh7724_usb0_host_resources[] = {
 	[0] = {
 		.start	= 0xa4d80000,
-		.end	= 0xa4d800ff,
+		.end	= 0xa4d80124 - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -330,6 +354,38 @@
 	},
 	.num_resources	= ARRAY_SIZE(sh7724_usb0_host_resources),
 	.resource	= sh7724_usb0_host_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USB0,
+	},
+};
+
+static struct r8a66597_platdata sh7724_usb1_gadget_data = {
+	.on_chip = 1,
+};
+
+static struct resource sh7724_usb1_gadget_resources[] = {
+	[0] = {
+		.start	= 0xa4d90000,
+		.end	= 0xa4d90123,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device sh7724_usb1_gadget_device = {
+	.name		= "r8a66597_udc",
+	.id		= 1, /* USB1 */
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &sh7724_usb1_gadget_data,
+	},
+	.num_resources	= ARRAY_SIZE(sh7724_usb1_gadget_resources),
+	.resource	= sh7724_usb1_gadget_resources,
 };
 
 static struct platform_device *ms7724se_devices[] __initdata = {
@@ -342,6 +398,7 @@
 	&keysc_device,
 	&sh_eth_device,
 	&sh7724_usb0_host_device,
+	&sh7724_usb1_gadget_device,
 };
 
 #define EEPROM_OP   0xBA206000
@@ -421,9 +478,38 @@
 	/* turn on USB clocks, use external clock */
 	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
 
+#ifdef CONFIG_PM
+	/* Let LED9 show STATUS2 */
+	gpio_request(GPIO_FN_STATUS2, NULL);
+
+	/* Lit LED10 show STATUS0 */
+	gpio_request(GPIO_FN_STATUS0, NULL);
+
+	/* Lit LED11 show PDSTATUS */
+	gpio_request(GPIO_FN_PDSTATUS, NULL);
+#else
+	/* Lit LED9 */
+	gpio_request(GPIO_PTJ6, NULL);
+	gpio_direction_output(GPIO_PTJ6, 1);
+	gpio_export(GPIO_PTJ6, 0);
+
+	/* Lit LED10 */
+	gpio_request(GPIO_PTJ5, NULL);
+	gpio_direction_output(GPIO_PTJ5, 1);
+	gpio_export(GPIO_PTJ5, 0);
+
+	/* Lit LED11 */
+	gpio_request(GPIO_PTJ7, NULL);
+	gpio_direction_output(GPIO_PTJ7, 1);
+	gpio_export(GPIO_PTJ7, 0);
+#endif
+
 	/* enable USB0 port */
 	ctrl_outw(0x0600, 0xa40501d4);
 
+	/* enable USB1 port */
+	ctrl_outw(0x0600, 0xa4050192);
+
 	/* enable IRQ 0,1,2 */
 	gpio_request(GPIO_FN_INTC_IRQ0, NULL);
 	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
@@ -546,15 +632,15 @@
 	sh_eth_init();
 
 	if (sw & SW41_B) {
-		/* SVGA */
-		lcdc_info.ch[0].lcd_cfg.xres         = 800;
-		lcdc_info.ch[0].lcd_cfg.yres         = 600;
-		lcdc_info.ch[0].lcd_cfg.left_margin  = 142;
-		lcdc_info.ch[0].lcd_cfg.right_margin = 52;
-		lcdc_info.ch[0].lcd_cfg.hsync_len    = 96;
-		lcdc_info.ch[0].lcd_cfg.upper_margin = 24;
-		lcdc_info.ch[0].lcd_cfg.lower_margin = 2;
-		lcdc_info.ch[0].lcd_cfg.vsync_len    = 2;
+		/* 720p */
+		lcdc_info.ch[0].lcd_cfg.xres         = 1280;
+		lcdc_info.ch[0].lcd_cfg.yres         = 720;
+		lcdc_info.ch[0].lcd_cfg.left_margin  = 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin = 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len    = 40;
+		lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len    = 5;
 	} else {
 		/* VGA */
 		lcdc_info.ch[0].lcd_cfg.xres         = 640;
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 8913ae3..efe4cb9 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <asm/ilsel.h>
 
 static struct resource heartbeat_resources[] = {
@@ -89,6 +90,11 @@
 	.resource	= r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+	.xtal = M66592_PLATDATA_XTAL_24MHZ,
+	.vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
 	[0] = {
 		.name	= "m66592_udc",
@@ -109,6 +115,7 @@
 	.dev = {
 		.dma_mask		= NULL,		/* don't use dma */
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
 	.resource	= m66592_usb_peripheral_resources,
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
index aad5edd..541087d 100644
--- a/arch/sh/boot/.gitignore
+++ b/arch/sh/boot/.gitignore
@@ -1,4 +1,3 @@
 zImage
-vmlinux.srec
-uImage
-uImage.srec
+vmlinux*
+uImage*
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 78efb04..a131687 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -20,8 +20,13 @@
 CONFIG_ZERO_PAGE_OFFSET	?= 0x00001000
 CONFIG_ENTRY_OFFSET	?= 0x00001000
 
-targets := zImage vmlinux.srec uImage uImage.srec
-subdir- := compressed
+suffix-$(CONFIG_KERNEL_GZIP)  := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+subdir- := compressed romimage
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -30,6 +35,13 @@
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
+$(obj)/romImage: $(obj)/romimage/vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/romimage $@
+
 KERNEL_MEMORY := 0x00000000
 ifeq ($(CONFIG_PMB_FIXED),y)
 KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
@@ -40,9 +52,6 @@
 		     $$[$(CONFIG_MEMORY_START)]')
 endif
 
-export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
-       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY
-
 KERNEL_LOAD	:= $(shell /bin/bash -c 'printf "0x%08x" \
 		     $$[$(CONFIG_PAGE_OFFSET)  + \
 			$(KERNEL_MEMORY) + \
@@ -55,19 +64,30 @@
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
-		   -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
+		   -C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
 		   -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
-$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
-	$(call if_changed,uimage)
-	@echo '  Image $@ is ready'
-
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
 
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)
 
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzma)
+
+$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
+	$(call if_changed,uimage,bzip2)
+
+$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
+	$(call if_changed,uimage,gzip)
+
+$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
+	$(call if_changed,uimage,lzma)
+
 OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
 $(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
 	$(call if_changed,objcopy)
@@ -76,5 +96,9 @@
 $(obj)/uImage.srec: $(obj)/uImage
 	$(call if_changed,objcopy)
 
-clean-files	+= uImage uImage.srec vmlinux.srec \
-		   vmlinux.bin vmlinux.bin.gz
+$(obj)/uImage: $(obj)/uImage.$(suffix-y)
+	@ln -sf $(notdir $<) $@
+	@echo '  Image $@ is ready'
+
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY suffix-y
diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore
new file mode 100644
index 0000000..2374a83
--- /dev/null
+++ b/arch/sh/boot/compressed/.gitignore
@@ -0,0 +1 @@
+vmlinux.bin.*
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 9531bf1..6182eca 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -5,9 +5,10 @@
 #
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
-		   head_$(BITS).o misc_$(BITS).o piggy.o
+		   vmlinux.bin.bz2 vmlinux.bin.lzma \
+		   head_$(BITS).o misc.o piggy.o
 
-OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o
+OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
 
 ifdef CONFIG_SH_STANDARD_BIOS
 OBJECTS += $(obj)/../../kernel/sh_bios.o
@@ -23,7 +24,7 @@
 
 LIBGCC	:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ifeq ($(CONFIG_MCOUNT),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
@@ -38,10 +39,18 @@
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
 
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+vmlinux.bin.all-y := $(obj)/vmlinux.bin
+
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,lzma)
 
 OBJCOPYFLAGS += -R .empty_zero_page
 
-$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
-	$(call if_changed,as_o_S)
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
+	$(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 06ac31f..02a3093 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -22,7 +22,7 @@
 	bt	clear_bss
 	sub	r0, r2
 	mov.l	bss_start_addr, r0
-	mov	#0xe0, r1
+	mov	#0xffffffe0, r1
 	and	r1, r0			! align cache line
 	mov.l	text_start_addr, r3
 	mov	r0, r1
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644
index 0000000..fd56a71
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.c
@@ -0,0 +1,149 @@
+/*
+ * arch/sh/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/sh_bios.h>
+
+/*
+ * gzip declarations
+ */
+
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+/* cache.c */
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+int cache_control(unsigned int command);
+
+extern char input_data[];
+extern int input_len;
+static unsigned char *output;
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _text;		/* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_HAVE_KERNEL_BZIP2
+#define HEAP_SIZE	0x400000
+#else
+#define HEAP_SIZE	0x10000
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_SH_STANDARD_BIOS
+size_t strlen(const char *s)
+{
+	int i = 0;
+
+	while (*s++)
+		i++;
+	return i;
+}
+
+int puts(const char *s)
+{
+	int len = strlen(s);
+	sh_bios_console_write(s, len);
+	return len;
+}
+#else
+int puts(const char *s)
+{
+	/* This should be updated to use the sh-sci routines */
+	return 0;
+}
+#endif
+
+void* memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+	return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+	return __dest;
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#ifdef CONFIG_SUPERH64
+#define stackalign	8
+#else
+#define stackalign	4
+#endif
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+	unsigned long output_addr;
+
+#ifdef CONFIG_SUPERH64
+	output_addr = (CONFIG_MEMORY_START + 0x2000);
+#else
+	output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
+#ifdef CONFIG_29BIT
+	output_addr |= P2SEG;
+#endif
+#endif
+
+	output = (unsigned char *)output_addr;
+	free_mem_ptr = (unsigned long)&_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+	puts("Uncompressing Linux... ");
+	cache_control(CACHE_ENABLE);
+	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	cache_control(CACHE_DISABLE);
+	puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c
deleted file mode 100644
index efdba6b..0000000
--- a/arch/sh/boot/compressed/misc_32.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SH by Stuart Menefy, Aug 1999
- *
- * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
- */
-
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/page.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-#include <asm/sh_bios.h>
-#endif
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000		/* Window size must be at least 32k, */
-				/* and a power of two */
-
-static uch *inbuf;	     /* input buffer */
-static uch window[WSIZE];    /* Sliding window buffer */
-
-static unsigned insize = 0;  /* valid bytes in inbuf */
-static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;  /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
-#define COMMENT      0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0 /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-int puts(const char *);
-
-extern int _text;		/* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-#ifdef CONFIG_SH_STANDARD_BIOS
-size_t strlen(const char *s)
-{
-	int i = 0;
-
-	while (*s++)
-		i++;
-	return i;
-}
-
-int puts(const char *s)
-{
-	int len = strlen(s);
-	sh_bios_console_write(s, len);
-	return len;
-}
-#else
-int puts(const char *s)
-{
-	/* This should be updated to use the sh-sci routines */
-	return 0;
-}
-#endif
-
-void* memset(void* s, int c, size_t n)
-{
-	int i;
-	char *ss = (char*)s;
-
-	for (i=0;i<n;i++) ss[i] = c;
-	return s;
-}
-
-void* memcpy(void* __dest, __const void* __src,
-			    size_t __n)
-{
-	int i;
-	char *d = (char *)__dest, *s = (char *)__src;
-
-	for (i=0;i<__n;i++) d[i] = s[i];
-	return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-	if (insize != 0) {
-		error("ran out of input data");
-	}
-
-	inbuf = input_data;
-	insize = input_len;
-	inptr = 1;
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, *out, ch;
-
-    in = window;
-    out = &output_data[output_ptr];
-    for (n = 0; n < outcnt; n++) {
-	    ch = *out++ = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    output_ptr += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void error(char *x)
-{
-	puts("\n\n");
-	puts(x);
-	puts("\n\n -- System halted");
-
-	while(1);	/* Halt */
-}
-
-#define STACK_SIZE (4096)
-long user_stack [STACK_SIZE];
-long* stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-	output_data = NULL;
-	output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
-#ifdef CONFIG_29BIT
-	output_ptr |= P2SEG;
-#endif
-	free_mem_ptr = (unsigned long)&_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-	makecrc();
-	puts("Uncompressing Linux... ");
-	gunzip();
-	puts("Ok, booting the kernel.\n");
-}
diff --git a/arch/sh/boot/compressed/misc_64.c b/arch/sh/boot/compressed/misc_64.c
deleted file mode 100644
index 2941657..0000000
--- a/arch/sh/boot/compressed/misc_64.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc_64.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SHmedia from sh by Stuart Menefy, May 2002
- */
-
-#include <asm/uaccess.h>
-
-/* cache.c */
-#define CACHE_ENABLE      0
-#define CACHE_DISABLE     1
-int cache_control(unsigned int command);
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000		/* Window size must be at least 32k, */
-				/* and a power of two */
-
-static uch *inbuf;		/* input buffer */
-static uch window[WSIZE];	/* Sliding window buffer */
-
-static unsigned insize = 0;	/* valid bytes in inbuf */
-static unsigned inptr = 0;	/* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;	/* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01	/* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
-#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
-#define COMMENT      0x10	/* bit 4 set: file comment present */
-#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
-#define RESERVED     0xC0	/* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-static void puts(const char *);
-
-extern int _text;		/* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-void puts(const char *s)
-{
-}
-
-void *memset(void *s, int c, size_t n)
-{
-	int i;
-	char *ss = (char *) s;
-
-	for (i = 0; i < n; i++)
-		ss[i] = c;
-	return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-	int i;
-	char *d = (char *) __dest, *s = (char *) __src;
-
-	for (i = 0; i < __n; i++)
-		d[i] = s[i];
-	return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-	if (insize != 0) {
-		error("ran out of input data\n");
-	}
-
-	inbuf = input_data;
-	insize = input_len;
-	inptr = 1;
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-	ulg c = crc;		/* temporary variable */
-	unsigned n;
-	uch *in, *out, ch;
-
-	in = window;
-	out = &output_data[output_ptr];
-	for (n = 0; n < outcnt; n++) {
-		ch = *out++ = *in++;
-		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
-	}
-	crc = c;
-	bytes_out += (ulg) outcnt;
-	output_ptr += (ulg) outcnt;
-	outcnt = 0;
-	puts(".");
-}
-
-static void error(char *x)
-{
-	puts("\n\n");
-	puts(x);
-	puts("\n\n -- System halted");
-
-	while (1) ;		/* Halt */
-}
-
-#define STACK_SIZE (4096)
-long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
-long *stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-	output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
-	free_mem_ptr = (unsigned long) &_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-	makecrc();
-	puts("Uncompressing Linux... ");
-	cache_control(CACHE_ENABLE);
-	gunzip();
-	puts("\n");
-
-#if 0
-	/* When booting from ROM may want to do something like this if the
-	 * boot loader doesn't.
-	 */
-
-	/* Set up the parameters and command line */
-	{
-		volatile unsigned int *parambase =
-		    (int *) (CONFIG_MEMORY_START + 0x1000);
-
-		parambase[0] = 0x1;	/* MOUNT_ROOT_RDONLY */
-		parambase[1] = 0x0;	/* RAMDISK_FLAGS */
-		parambase[2] = 0x0200;	/* ORIG_ROOT_DEV */
-		parambase[3] = 0x0;	/* LOADER_TYPE */
-		parambase[4] = 0x0;	/* INITRD_START */
-		parambase[5] = 0x0;	/* INITRD_SIZE */
-		parambase[6] = 0;
-
-		strcpy((char *) ((int) parambase + 0x100),
-		       "console=ttySC0,38400");
-	}
-#endif
-
-	puts("Ok, booting the kernel.\n");
-
-	cache_control(CACHE_DISABLE);
-}
diff --git a/arch/sh/boot/compressed/piggy.S b/arch/sh/boot/compressed/piggy.S
deleted file mode 100644
index 5660719..0000000
--- a/arch/sh/boot/compressed/piggy.S
+++ /dev/null
@@ -1,8 +0,0 @@
-	.global	input_len, input_data
-	.data
-input_len:
-	.long	input_data_end - input_data
-input_data:
-	.incbin	"arch/sh/boot/compressed/vmlinux.bin.gz"
-input_data_end:
-	.end
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
new file mode 100644
index 0000000..f02382a
--- /dev/null
+++ b/arch/sh/boot/compressed/vmlinux.scr
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .rodata.compressed : {
+	input_len = .;
+	LONG(input_data_end - input_data) input_data = .;
+	*(.data)
+	output_len = . - 4;
+	input_data_end = .;
+	}
+}
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
new file mode 100644
index 0000000..5806eee
--- /dev/null
+++ b/arch/sh/boot/romimage/Makefile
@@ -0,0 +1,19 @@
+#
+# linux/arch/sh/boot/romimage/Makefile
+#
+# create an image suitable for burning to flash from zImage
+#
+
+targets		:= vmlinux head.o
+
+OBJECTS = $(obj)/head.o
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+	$(call if_changed,ld)
+	@:
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
+	$(call if_changed,ld)
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
new file mode 100644
index 0000000..219bc62
--- /dev/null
+++ b/arch/sh/boot/romimage/head.S
@@ -0,0 +1,10 @@
+/*
+ *  linux/arch/sh/boot/romimage/head.S
+ *
+ * Board specific setup code, executed before zImage loader
+ */
+
+.text
+	.global	romstart
+romstart:
+#include <mach/romimage.h>
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr
new file mode 100644
index 0000000..287c08f
--- /dev/null
+++ b/arch/sh/boot/romimage/vmlinux.scr
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  .text : {
+	*(.data)
+	}
+}
diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig
new file mode 100644
index 0000000..9a22c64
--- /dev/null
+++ b/arch/sh/configs/ecovec24-romimage_defconfig
@@ -0,0 +1,1032 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc7
+# Tue Sep  8 13:56:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=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_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=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
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=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 is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+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_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+# CONFIG_SH_KFR2R09 is not set
+CONFIG_SH_ECOVEC=y
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD 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 is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+# CONFIG_INET_DIAG is not set
+# 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 is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+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 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# 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 is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS 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_NETDEVICES=y
+# 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_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# 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_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET 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_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 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_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER 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
+
+#
+# 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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC 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_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 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_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# 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
+
+#
+# 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+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=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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
+# 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_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=y
+# 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=y
+# 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 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL 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_BERRY_CHARGE 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_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_VST 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_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY 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
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP 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_OCFS2_FS is not set
+# CONFIG_BTRFS_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 is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# 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_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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 is not set
+# 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 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_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP 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_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
new file mode 100644
index 0000000..2050a766
--- /dev/null
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -0,0 +1,1558 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc7
+# Wed Aug 26 09:09:07 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
+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=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=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
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=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_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+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_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+# CONFIG_SH_KFR2R09 is not set
+CONFIG_SH_ECOVEC=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD 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 is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+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 is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+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 is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+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_CONCAT=y
+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
+
+#
+# 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_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 is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA 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=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# 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 is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG 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_NETDEVICES=y
+# 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_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# 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_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET 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_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 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_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER 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
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD 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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC 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_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 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_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_SH_SCI is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# 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
+
+#
+# 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+# CONFIG_SOC_CAMERA_MT9M111 is not set
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_SH_MOBILE_CEU=y
+# CONFIG_V4L_USB_DRIVERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_SH_MOBILE_LCDC=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN 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_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY 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_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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=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_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=y
+# 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=y
+# 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 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL 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_BERRY_CHARGE 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_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_VST 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_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# 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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# 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 is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+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_HUGETLBFS 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_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 is not set
+# CONFIG_UBIFS_FS 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_NILFS2_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 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_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 is not set
+CONFIG_MSDOS_PARTITION=y
+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 is not set
+# 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=y
+# 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 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_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+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_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+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 is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# 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 is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig
new file mode 100644
index 0000000..c0f9263
--- /dev/null
+++ b/arch/sh/configs/kfr2r09-romimage_defconfig
@@ -0,0 +1,774 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 15:09:16 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=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_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=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
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=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 is not set
+# CONFIG_BLOCK is not set
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+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_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+CONFIG_SH_KFR2R09=y
+# CONFIG_SH_ECOVEC is not set
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 quiet"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD 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 is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+# CONFIG_INET_DIAG is not set
+# 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 is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+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 is not set
+# CONFIG_PARPORT is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_NETDEVICES 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
+
+#
+# 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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 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_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# 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
+
+#
+# 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=y
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY 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
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+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
+
+#
+# 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_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+# CONFIG_NLS 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 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_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP 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_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig
new file mode 100644
index 0000000..cef6131
--- /dev/null
+++ b/arch/sh/configs/kfr2r09_defconfig
@@ -0,0 +1,1059 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 21:58:52 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=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
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=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_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_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+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_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+CONFIG_SH_KFR2R09=y
+# CONFIG_SH_ECOVEC is not set
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=tty0 console=ttySC1,115200"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD 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 is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# 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 is not set
+# CONFIG_INET_DIAG is not set
+# 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 is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+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_CONCAT=y
+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
+
+#
+# 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_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 is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM 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 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES 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
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD 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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 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_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# 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
+
+#
+# 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_SH_MOBILE_LCDC=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+CONFIG_LOGO_SUPERH_VGA16=y
+# CONFIG_LOGO_SUPERH_CLUT224 is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=y
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# 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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# 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 is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# 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_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS 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 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_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP 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_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index ca3c88a..2be2d75 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Thu Jun 18 13:11:58 2009
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 15:03:04 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -14,6 +14,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -28,7 +29,9 @@
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -38,6 +41,12 @@
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -86,10 +95,12 @@
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 # CONFIG_STRIP_ASM_SYMS is not set
@@ -106,6 +117,10 @@
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -113,7 +128,7 @@
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -534,7 +549,11 @@
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -686,6 +705,11 @@
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -732,7 +756,44 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+CONFIG_RTC_DRV_DS1302=y
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_RTC_DRV_GENERIC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -754,6 +815,7 @@
 # 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_FILE_LOCKING=y
@@ -856,8 +918,11 @@
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP 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_HAVE_FTRACE_SYSCALLS=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DMA_API_DEBUG is not set
@@ -865,6 +930,7 @@
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
 
 #
 # Security options
@@ -893,5 +959,6 @@
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
 CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 63e9dd3..b91fa8d 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -27,12 +27,12 @@
 	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
 		       CPU_SUBTYPE_SH7760
 	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780  || \
-			CPU_SUBTYPE_SH7785
+			CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7724
 	default "6"
 	help
 	  This allows you to specify the number of channels that the on-chip
-	  DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
-	  SH7750R/SH7751R.
+	  DMAC supports. This will be 4 for SH7750/SH7751/Sh7750S/SH7091 and 8 for the
+	  SH7750R/SH7751R/SH7760, 12 for the SH7723/SH7780/SH7785/SH7724, default is 6.
 
 config NR_DMA_CHANNELS_BOOL
 	depends on SH_DMA
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index 938817e3..a9339a6 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -40,14 +40,19 @@
 	if (inverted)
 		new = ~new;
 
+	new &= hd->mask;
+
 	switch (hd->regsize) {
 	case 32:
+		new |= ioread32(hd->base) & ~hd->mask;
 		iowrite32(new, hd->base);
 		break;
 	case 16:
+		new |= ioread16(hd->base) & ~hd->mask;
 		iowrite16(new, hd->base);
 		break;
 	default:
+		new |= ioread8(hd->base) & ~hd->mask;
 		iowrite8(new, hd->base);
 		break;
 	}
@@ -72,6 +77,7 @@
 {
 	struct resource *res;
 	struct heartbeat_data *hd;
+	int i;
 
 	if (unlikely(pdev->num_resources != 1)) {
 		dev_err(&pdev->dev, "invalid number of resources\n");
@@ -107,6 +113,10 @@
 		hd->nr_bits = ARRAY_SIZE(default_bit_pos);
 	}
 
+	hd->mask = 0;
+	for (i = 0; i < hd->nr_bits; i++)
+		hd->mask |= (1 << hd->bit_pos[i]);
+
 	if (!hd->regsize)
 		hd->regsize = 8;	/* default access size */
 
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 9a1c423..c481df6 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -295,6 +295,8 @@
 			       vma->vm_page_prot);
 }
 
+#ifndef CONFIG_GENERIC_IOMAP
+
 static void __iomem *ioport_map_pci(struct pci_dev *dev,
 				    unsigned long port, unsigned int nr)
 {
@@ -346,6 +348,8 @@
 }
 EXPORT_SYMBOL(pci_iounmap);
 
+#endif /* CONFIG_GENERIC_IOMAP */
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 EXPORT_SYMBOL(pcibios_bus_to_resource);
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 43910cd..e121c30 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,6 +1,6 @@
 include include/asm-generic/Kbuild.asm
 
-header-y += cpu-features.h
+header-y += cachectl.h cpu-features.h
 
 unifdef-y += unistd_32.h
 unifdef-y += unistd_64.h
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index c017180..d02c01b 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -2,6 +2,7 @@
 #define __ASM_SH_BUG_H
 
 #define TRAPA_BUG_OPCODE	0xc33e	/* trapa #0x3e */
+#define BUGFLAG_UNWINDER	(1 << 1)
 
 #ifdef CONFIG_GENERIC_BUG
 #define HAVE_ARCH_BUG
@@ -72,6 +73,36 @@
 	unlikely(__ret_warn_on);				\
 })
 
+#define UNWINDER_BUG()					\
+do {							\
+	__asm__ __volatile__ (				\
+		"1:\t.short %O0\n"			\
+		_EMIT_BUG_ENTRY				\
+		 :					\
+		 : "n" (TRAPA_BUG_OPCODE),		\
+		   "i" (__FILE__),			\
+		   "i" (__LINE__),			\
+		   "i" (BUGFLAG_UNWINDER),		\
+		   "i" (sizeof(struct bug_entry)));	\
+} while (0)
+
+#define UNWINDER_BUG_ON(x) ({					\
+	int __ret_unwinder_on = !!(x);				\
+	if (__builtin_constant_p(__ret_unwinder_on)) {		\
+		if (__ret_unwinder_on)				\
+			UNWINDER_BUG();				\
+	} else {						\
+		if (unlikely(__ret_unwinder_on))		\
+			UNWINDER_BUG();				\
+	}							\
+	unlikely(__ret_unwinder_on);				\
+})
+
+#else
+
+#define UNWINDER_BUG	BUG
+#define UNWINDER_BUG_ON	BUG_ON
+
 #endif /* CONFIG_GENERIC_BUG */
 
 #include <asm-generic/bug.h>
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 4924ff6..46260fc 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -21,25 +21,25 @@
 
 	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
 
-	switch (current_cpu_data.type) {
-	case CPU_SH7619:
+	switch (current_cpu_data.family) {
+	case CPU_FAMILY_SH2:
 		*p++ = '2';
 		break;
-	case CPU_SH7201 ... CPU_MXG:
+	case CPU_FAMILY_SH2A:
 		*p++ = '2';
 		*p++ = 'a';
 		break;
-	case CPU_SH7705 ... CPU_SH7729:
+	case CPU_FAMILY_SH3:
 		*p++ = '3';
 		break;
-	case CPU_SH7750 ... CPU_SH4_501:
+	case CPU_FAMILY_SH4:
 		*p++ = '4';
 		break;
-	case CPU_SH7763 ... CPU_SHX3:
+	case CPU_FAMILY_SH4A:
 		*p++ = '4';
 		*p++ = 'a';
 		break;
-	case CPU_SH7343 ... CPU_SH7366:
+	case CPU_FAMILY_SH4AL_DSP:
 		*p++ = '4';
 		*p++ = 'a';
 		*p++ = 'l';
@@ -48,15 +48,15 @@
 		*p++ = 's';
 		*p++ = 'p';
 		break;
-	case CPU_SH5_101 ... CPU_SH5_103:
+	case CPU_FAMILY_SH5:
 		*p++ = '6';
 		*p++ = '4';
 		break;
-	case CPU_SH_NONE:
+	case CPU_FAMILY_UNKNOWN:
 		/*
-		 * Specifically use CPU_SH_NONE rather than default:,
-		 * so we're able to have the compiler whine about
-		 * unhandled enumerations.
+		 * Specifically use CPU_FAMILY_UNKNOWN rather than
+		 * default:, so we're able to have the compiler whine
+		 * about unhandled enumerations.
 		 */
 		break;
 	}
diff --git a/arch/sh/include/asm/cachectl.h b/arch/sh/include/asm/cachectl.h
new file mode 100644
index 0000000..6ffb4b7
--- /dev/null
+++ b/arch/sh/include/asm/cachectl.h
@@ -0,0 +1,19 @@
+#ifndef _SH_CACHECTL_H
+#define _SH_CACHECTL_H
+
+/* Definitions for the cacheflush system call.  */
+
+#define CACHEFLUSH_D_INVAL	0x1	/* invalidate (without write back) */
+#define CACHEFLUSH_D_WB		0x2	/* write back (without invalidate) */
+#define CACHEFLUSH_D_PURGE	0x3	/* writeback and invalidate */
+
+#define CACHEFLUSH_I		0x4
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE	CACHEFLUSH_I		/* flush instruction cache */
+#define DCACHE	CACHEFLUSH_D_PURGE	/* writeback and flush data cache */
+#define BCACHE	(ICACHE|DCACHE)		/* flush both caches */
+
+#endif /* _SH_CACHECTL_H */
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 4c5462d..c29918f 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -3,45 +3,65 @@
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_CACHE_OFF
+#include <linux/mm.h>
+
 /*
- * Nothing to do when the cache is disabled, initial flush and explicit
- * disabling is handled at CPU init time.
+ * Cache flushing:
  *
- * See arch/sh/kernel/cpu/init.c:cache_init().
+ *  - flush_cache_all() flushes entire cache
+ *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_dup mm(mm) handles cache flushing when forking
+ *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
+ *  - flush_cache_range(vma, start, end) flushes a range of pages
+ *
+ *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
+ *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
+ *  - flush_cache_sigtramp(vaddr) flushes the signal trampoline
  */
-#define p3_cache_init()				do { } while (0)
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_icache_range(start, end)		do { } while (0)
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define __flush_wback_region(start, size)	do { (void)(start); } while (0)
-#define __flush_purge_region(start, size)	do { (void)(start); } while (0)
-#define __flush_invalidate_region(start, size)	do { (void)(start); } while (0)
-#else
-#include <cpu/cacheflush.h>
+extern void (*local_flush_cache_all)(void *args);
+extern void (*local_flush_cache_mm)(void *args);
+extern void (*local_flush_cache_dup_mm)(void *args);
+extern void (*local_flush_cache_page)(void *args);
+extern void (*local_flush_cache_range)(void *args);
+extern void (*local_flush_dcache_page)(void *args);
+extern void (*local_flush_icache_range)(void *args);
+extern void (*local_flush_icache_page)(void *args);
+extern void (*local_flush_cache_sigtramp)(void *args);
 
-/*
- * Consistent DMA requires that the __flush_xxx() primitives must be set
- * for any of the enabled non-coherent caches (most of the UP CPUs),
- * regardless of PIPT or VIPT cache configurations.
- */
+static inline void cache_noop(void *args) { }
 
-/* Flush (write-back only) a region (smaller than a page) */
-extern void __flush_wback_region(void *start, int size);
-/* Flush (write-back & invalidate) a region (smaller than a page) */
-extern void __flush_purge_region(void *start, int size);
-/* Flush (invalidate only) a region (smaller than a page) */
-extern void __flush_invalidate_region(void *start, int size);
-#endif
+extern void (*__flush_wback_region)(void *start, int size);
+extern void (*__flush_purge_region)(void *start, int size);
+extern void (*__flush_invalidate_region)(void *start, int size);
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_dup_mm(struct mm_struct *mm);
+extern void flush_cache_page(struct vm_area_struct *vma,
+				unsigned long addr, unsigned long pfn);
+extern void flush_cache_range(struct vm_area_struct *vma,
+				 unsigned long start, unsigned long end);
+extern void flush_dcache_page(struct page *page);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma,
+				 struct page *page);
+extern void flush_cache_sigtramp(unsigned long address);
+
+struct flusher_data {
+	struct vm_area_struct *vma;
+	unsigned long addr1, addr2;
+};
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+extern void __flush_anon_page(struct page *page, unsigned long);
+
+static inline void flush_anon_page(struct vm_area_struct *vma,
+				   struct page *page, unsigned long vmaddr)
+{
+	if (boot_cpu_data.dcache.n_aliases && PageAnon(page))
+		__flush_anon_page(page, vmaddr);
+}
 
 #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
 static inline void flush_kernel_dcache_page(struct page *page)
@@ -49,7 +69,6 @@
 	flush_dcache_page(page);
 }
 
-#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF)
 extern void copy_to_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
 	unsigned long len);
@@ -57,23 +76,20 @@
 extern void copy_from_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
 	unsigned long len);
-#else
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
-	do {							\
-		flush_cache_page(vma, vaddr, page_to_pfn(page));\
-		memcpy(dst, src, len);				\
-		flush_icache_user_range(vma, page, vaddr, len);	\
-	} while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
-	do {							\
-		flush_cache_page(vma, vaddr, page_to_pfn(page));\
-		memcpy(dst, src, len);				\
-	} while (0)
-#endif
 
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
+
+void kmap_coherent_init(void);
+void *kmap_coherent(struct page *page, unsigned long addr);
+void kunmap_coherent(void *kvaddr);
+
+#define PG_dcache_dirty	PG_arch_1
+
+void cpu_cache_init(void);
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHEFLUSH_H */
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index 8688a88..b16debf 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -3,7 +3,9 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+
+struct dev_archdata {
+};
 
 struct platform_device;
 /* allocate contiguous memory chunk and fill in struct resource */
@@ -12,3 +14,15 @@
 
 void plat_early_device_setup(void);
 
+#define PDEV_ARCHDATA_FLAG_INIT 0
+#define PDEV_ARCHDATA_FLAG_IDLE 1
+#define PDEV_ARCHDATA_FLAG_SUSP 2
+
+struct pdev_archdata {
+	int hwblk_id;
+#ifdef CONFIG_PM_RUNTIME
+	unsigned long flags;
+	struct list_head entry;
+	struct mutex mutex;
+#endif
+};
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index 0c8f8e1..68a5f4c 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -16,6 +16,7 @@
 
 /* DMAOR contorl: The DMAOR access size is different by CPU.*/
 #if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7724)	|| \
     defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
     defined(CONFIG_CPU_SUBTYPE_SH7785)
 #define dmaor_read_reg(n) \
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
new file mode 100644
index 0000000..ced6795
--- /dev/null
+++ b/arch/sh/include/asm/dwarf.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * 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_SH_DWARF_H
+#define __ASM_SH_DWARF_H
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+/*
+ * DWARF expression operations
+ */
+#define DW_OP_addr	0x03
+#define DW_OP_deref	0x06
+#define DW_OP_const1u	0x08
+#define DW_OP_const1s	0x09
+#define DW_OP_const2u	0x0a
+#define DW_OP_const2s	0x0b
+#define DW_OP_const4u	0x0c
+#define DW_OP_const4s	0x0d
+#define DW_OP_const8u	0x0e
+#define DW_OP_const8s	0x0f
+#define DW_OP_constu	0x10
+#define DW_OP_consts	0x11
+#define DW_OP_dup	0x12
+#define DW_OP_drop	0x13
+#define DW_OP_over	0x14
+#define DW_OP_pick	0x15
+#define DW_OP_swap	0x16
+#define DW_OP_rot	0x17
+#define DW_OP_xderef	0x18
+#define DW_OP_abs	0x19
+#define DW_OP_and	0x1a
+#define DW_OP_div	0x1b
+#define DW_OP_minus	0x1c
+#define DW_OP_mod	0x1d
+#define DW_OP_mul	0x1e
+#define DW_OP_neg	0x1f
+#define DW_OP_not	0x20
+#define DW_OP_or	0x21
+#define DW_OP_plus	0x22
+#define DW_OP_plus_uconst	0x23
+#define DW_OP_shl	0x24
+#define DW_OP_shr	0x25
+#define DW_OP_shra	0x26
+#define DW_OP_xor	0x27
+#define DW_OP_skip	0x2f
+#define DW_OP_bra	0x28
+#define DW_OP_eq	0x29
+#define DW_OP_ge	0x2a
+#define DW_OP_gt	0x2b
+#define DW_OP_le	0x2c
+#define DW_OP_lt	0x2d
+#define DW_OP_ne	0x2e
+#define DW_OP_lit0	0x30
+#define DW_OP_lit1	0x31
+#define DW_OP_lit2	0x32
+#define DW_OP_lit3	0x33
+#define DW_OP_lit4	0x34
+#define DW_OP_lit5	0x35
+#define DW_OP_lit6	0x36
+#define DW_OP_lit7	0x37
+#define DW_OP_lit8	0x38
+#define DW_OP_lit9	0x39
+#define DW_OP_lit10	0x3a
+#define DW_OP_lit11	0x3b
+#define DW_OP_lit12	0x3c
+#define DW_OP_lit13	0x3d
+#define DW_OP_lit14	0x3e
+#define DW_OP_lit15	0x3f
+#define DW_OP_lit16	0x40
+#define DW_OP_lit17	0x41
+#define DW_OP_lit18	0x42
+#define DW_OP_lit19	0x43
+#define DW_OP_lit20	0x44
+#define DW_OP_lit21	0x45
+#define DW_OP_lit22	0x46
+#define DW_OP_lit23	0x47
+#define DW_OP_lit24	0x48
+#define DW_OP_lit25	0x49
+#define DW_OP_lit26	0x4a
+#define DW_OP_lit27	0x4b
+#define DW_OP_lit28	0x4c
+#define DW_OP_lit29	0x4d
+#define DW_OP_lit30	0x4e
+#define DW_OP_lit31	0x4f
+#define DW_OP_reg0	0x50
+#define DW_OP_reg1	0x51
+#define DW_OP_reg2	0x52
+#define DW_OP_reg3	0x53
+#define DW_OP_reg4	0x54
+#define DW_OP_reg5	0x55
+#define DW_OP_reg6	0x56
+#define DW_OP_reg7	0x57
+#define DW_OP_reg8	0x58
+#define DW_OP_reg9	0x59
+#define DW_OP_reg10	0x5a
+#define DW_OP_reg11	0x5b
+#define DW_OP_reg12	0x5c
+#define DW_OP_reg13	0x5d
+#define DW_OP_reg14	0x5e
+#define DW_OP_reg15	0x5f
+#define DW_OP_reg16	0x60
+#define DW_OP_reg17	0x61
+#define DW_OP_reg18	0x62
+#define DW_OP_reg19	0x63
+#define DW_OP_reg20	0x64
+#define DW_OP_reg21	0x65
+#define DW_OP_reg22	0x66
+#define DW_OP_reg23	0x67
+#define DW_OP_reg24	0x68
+#define DW_OP_reg25	0x69
+#define DW_OP_reg26	0x6a
+#define DW_OP_reg27	0x6b
+#define DW_OP_reg28	0x6c
+#define DW_OP_reg29	0x6d
+#define DW_OP_reg30	0x6e
+#define DW_OP_reg31	0x6f
+#define DW_OP_breg0	0x70
+#define DW_OP_breg1	0x71
+#define DW_OP_breg2	0x72
+#define DW_OP_breg3	0x73
+#define DW_OP_breg4	0x74
+#define DW_OP_breg5	0x75
+#define DW_OP_breg6	0x76
+#define DW_OP_breg7	0x77
+#define DW_OP_breg8	0x78
+#define DW_OP_breg9	0x79
+#define DW_OP_breg10	0x7a
+#define DW_OP_breg11	0x7b
+#define DW_OP_breg12	0x7c
+#define DW_OP_breg13	0x7d
+#define DW_OP_breg14	0x7e
+#define DW_OP_breg15	0x7f
+#define DW_OP_breg16	0x80
+#define DW_OP_breg17	0x81
+#define DW_OP_breg18	0x82
+#define DW_OP_breg19	0x83
+#define DW_OP_breg20	0x84
+#define DW_OP_breg21	0x85
+#define DW_OP_breg22	0x86
+#define DW_OP_breg23	0x87
+#define DW_OP_breg24	0x88
+#define DW_OP_breg25	0x89
+#define DW_OP_breg26	0x8a
+#define DW_OP_breg27	0x8b
+#define DW_OP_breg28	0x8c
+#define DW_OP_breg29	0x8d
+#define DW_OP_breg30	0x8e
+#define DW_OP_breg31	0x8f
+#define DW_OP_regx	0x90
+#define DW_OP_fbreg	0x91
+#define DW_OP_bregx	0x92
+#define DW_OP_piece	0x93
+#define DW_OP_deref_size	0x94
+#define DW_OP_xderef_size	0x95
+#define DW_OP_nop	0x96
+#define DW_OP_push_object_address	0x97
+#define DW_OP_call2	0x98
+#define DW_OP_call4	0x99
+#define DW_OP_call_ref	0x9a
+#define DW_OP_form_tls_address	0x9b
+#define DW_OP_call_frame_cfa	0x9c
+#define DW_OP_bit_piece	0x9d
+#define DW_OP_lo_user	0xe0
+#define DW_OP_hi_user	0xff
+
+/*
+ * Addresses used in FDE entries in the .eh_frame section may be encoded
+ * using one of the following encodings.
+ */
+#define DW_EH_PE_absptr	0x00
+#define DW_EH_PE_omit	0xff
+#define DW_EH_PE_uleb128	0x01
+#define DW_EH_PE_udata2	0x02
+#define DW_EH_PE_udata4	0x03
+#define DW_EH_PE_udata8	0x04
+#define DW_EH_PE_sleb128	0x09
+#define DW_EH_PE_sdata2	0x0a
+#define DW_EH_PE_sdata4	0x0b
+#define DW_EH_PE_sdata8	0x0c
+#define DW_EH_PE_signed	0x09
+
+#define DW_EH_PE_pcrel	0x10
+
+/*
+ * The architecture-specific register number that contains the return
+ * address in the .debug_frame table.
+ */
+#define DWARF_ARCH_RA_REG	17
+
+#ifndef __ASSEMBLY__
+/*
+ * Read either the frame pointer (r14) or the stack pointer (r15).
+ * NOTE: this MUST be inlined.
+ */
+static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
+{
+	unsigned long value = 0;
+
+	switch (reg) {
+	case 14:
+		__asm__ __volatile__("mov r14, %0\n" : "=r" (value));
+		break;
+	case 15:
+		__asm__ __volatile__("mov r15, %0\n" : "=r" (value));
+		break;
+	default:
+		BUG();
+	}
+
+	return value;
+}
+
+/**
+ *	dwarf_cie - Common Information Entry
+ */
+struct dwarf_cie {
+	unsigned long length;
+	unsigned long cie_id;
+	unsigned char version;
+	const char *augmentation;
+	unsigned int code_alignment_factor;
+	int data_alignment_factor;
+
+	/* Which column in the rule table represents return addr of func. */
+	unsigned int return_address_reg;
+
+	unsigned char *initial_instructions;
+	unsigned char *instructions_end;
+
+	unsigned char encoding;
+
+	unsigned long cie_pointer;
+
+	struct list_head link;
+
+	unsigned long flags;
+#define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
+};
+
+/**
+ *	dwarf_fde - Frame Description Entry
+ */
+struct dwarf_fde {
+	unsigned long length;
+	unsigned long cie_pointer;
+	struct dwarf_cie *cie;
+	unsigned long initial_location;
+	unsigned long address_range;
+	unsigned char *instructions;
+	unsigned char *end;
+	struct list_head link;
+};
+
+/**
+ *	dwarf_frame - DWARF information for a frame in the call stack
+ */
+struct dwarf_frame {
+	struct dwarf_frame *prev, *next;
+
+	unsigned long pc;
+
+	struct list_head reg_list;
+
+	unsigned long cfa;
+
+	/* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
+	unsigned int cfa_register;
+	unsigned int cfa_offset;
+
+	/* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
+	unsigned char *cfa_expr;
+	unsigned int cfa_expr_len;
+
+	unsigned long flags;
+#define DWARF_FRAME_CFA_REG_OFFSET	(1 << 0)
+#define DWARF_FRAME_CFA_REG_EXP		(1 << 1)
+
+	unsigned long return_addr;
+};
+
+/**
+ *	dwarf_reg - DWARF register
+ *	@flags: Describes how to calculate the value of this register
+ */
+struct dwarf_reg {
+	struct list_head link;
+
+	unsigned int number;
+
+	unsigned long addr;
+	unsigned long flags;
+#define DWARF_REG_OFFSET	(1 << 0)
+#define DWARF_VAL_OFFSET	(1 << 1)
+#define DWARF_UNDEFINED		(1 << 2)
+};
+
+/*
+ * Call Frame instruction opcodes.
+ */
+#define DW_CFA_advance_loc	0x40
+#define DW_CFA_offset		0x80
+#define DW_CFA_restore		0xc0
+#define DW_CFA_nop		0x00
+#define DW_CFA_set_loc		0x01
+#define DW_CFA_advance_loc1	0x02
+#define DW_CFA_advance_loc2	0x03
+#define DW_CFA_advance_loc4	0x04
+#define DW_CFA_offset_extended	0x05
+#define DW_CFA_restore_extended	0x06
+#define DW_CFA_undefined	0x07
+#define DW_CFA_same_value	0x08
+#define DW_CFA_register		0x09
+#define DW_CFA_remember_state	0x0a
+#define DW_CFA_restore_state	0x0b
+#define DW_CFA_def_cfa		0x0c
+#define DW_CFA_def_cfa_register	0x0d
+#define DW_CFA_def_cfa_offset	0x0e
+#define DW_CFA_def_cfa_expression	0x0f
+#define DW_CFA_expression	0x10
+#define DW_CFA_offset_extended_sf	0x11
+#define DW_CFA_def_cfa_sf	0x12
+#define DW_CFA_def_cfa_offset_sf	0x13
+#define DW_CFA_val_offset	0x14
+#define DW_CFA_val_offset_sf	0x15
+#define DW_CFA_val_expression	0x16
+#define DW_CFA_lo_user		0x1c
+#define DW_CFA_hi_user		0x3f
+
+/* GNU extension opcodes  */
+#define DW_CFA_GNU_args_size	0x2e
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+
+/*
+ * Some call frame instructions encode their operands in the opcode. We
+ * need some helper functions to extract both the opcode and operands
+ * from an instruction.
+ */
+static inline unsigned int DW_CFA_opcode(unsigned long insn)
+{
+	return (insn & 0xc0);
+}
+
+static inline unsigned int DW_CFA_operand(unsigned long insn)
+{
+	return (insn & 0x3f);
+}
+
+#define DW_EH_FRAME_CIE	0		/* .eh_frame CIE IDs are 0 */
+#define DW_CIE_ID	0xffffffff
+#define DW64_CIE_ID	0xffffffffffffffffULL
+
+/*
+ * DWARF FDE/CIE length field values.
+ */
+#define DW_EXT_LO	0xfffffff0
+#define DW_EXT_HI	0xffffffff
+#define DW_EXT_DWARF64	DW_EXT_HI
+
+extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
+					      struct dwarf_frame *);
+#endif /* !__ASSEMBLY__ */
+
+#define CFI_STARTPROC	.cfi_startproc
+#define CFI_ENDPROC	.cfi_endproc
+#define CFI_DEF_CFA	.cfi_def_cfa
+#define CFI_REGISTER	.cfi_register
+#define CFI_REL_OFFSET	.cfi_rel_offset
+#define CFI_UNDEFINED	.cfi_undefined
+
+#else
+
+/*
+ * Use the asm comment character to ignore the rest of the line.
+ */
+#define CFI_IGNORE	!
+
+#define CFI_STARTPROC	CFI_IGNORE
+#define CFI_ENDPROC	CFI_IGNORE
+#define CFI_DEF_CFA	CFI_IGNORE
+#define CFI_REGISTER	CFI_IGNORE
+#define CFI_REL_OFFSET	CFI_IGNORE
+#define CFI_UNDEFINED	CFI_IGNORE
+
+#ifndef __ASSEMBLY__
+static inline void dwarf_unwinder_init(void)
+{
+}
+#endif
+
+#endif /* CONFIG_DWARF_UNWINDER */
+
+#endif /* __ASM_SH_DWARF_H */
diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S
index 3a4752a..cc43a55 100644
--- a/arch/sh/include/asm/entry-macros.S
+++ b/arch/sh/include/asm/entry-macros.S
@@ -7,7 +7,7 @@
 	.endm
 
 	.macro	sti
-	mov	#0xf0, r11
+	mov	#0xfffffff0, r11
 	extu.b	r11, r11
 	not	r11, r11
 	stc	sr, r10
@@ -31,8 +31,92 @@
 #endif	
 	.endm
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+	.macro	TRACE_IRQS_ON
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+	mov.l	r2, @-r15
+	mov.l	r3, @-r15
+	mov.l	r4, @-r15
+	mov.l	r5, @-r15
+	mov.l	r6, @-r15
+	mov.l	r7, @-r15
+
+	mov.l   7834f, r0
+	jsr	@r0
+	 nop
+
+	mov.l	@r15+, r7
+	mov.l	@r15+, r6
+	mov.l	@r15+, r5
+	mov.l	@r15+, r4
+	mov.l	@r15+, r3
+	mov.l	@r15+, r2
+	mov.l	@r15+, r1
+	mov.l	@r15+, r0
+	mov.l	7834f, r0
+
+	bra	7835f
+	 nop
+	.balign	4
+7834:	.long	trace_hardirqs_on
+7835:
+	.endm
+	.macro	TRACE_IRQS_OFF
+
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+	mov.l	r2, @-r15
+	mov.l	r3, @-r15
+	mov.l	r4, @-r15
+	mov.l	r5, @-r15
+	mov.l	r6, @-r15
+	mov.l	r7, @-r15
+
+	mov.l	7834f, r0
+	jsr	@r0
+	 nop
+
+	mov.l	@r15+, r7
+	mov.l	@r15+, r6
+	mov.l	@r15+, r5
+	mov.l	@r15+, r4
+	mov.l	@r15+, r3
+	mov.l	@r15+, r2
+	mov.l	@r15+, r1
+	mov.l	@r15+, r0
+	mov.l	7834f, r0
+
+	bra	7835f
+	 nop
+	.balign	4
+7834:	.long	trace_hardirqs_off
+7835:
+	.endm
+
+#else
+	.macro	TRACE_IRQS_ON
+	.endm
+
+	.macro	TRACE_IRQS_OFF
+	.endm
+#endif
+
 #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
 # define PREF(x)	pref	@x
 #else
 # define PREF(x)	nop
 #endif
+
+	/*
+	 * Macro for use within assembly. Because the DWARF unwinder
+	 * needs to use the frame register to unwind the stack, we
+	 * need to setup r14 with the value of the stack pointer as
+	 * the return address is usually on the stack somewhere.
+	 */
+	.macro	setup_frame_reg
+#ifdef CONFIG_DWARF_UNWINDER
+	mov	r15, r14
+#endif
+	.endm
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 8fea7d8..12f3a31 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_FUNCTION_TRACER
 
 #define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
+#define FTRACE_SYSCALL_MAX	NR_syscalls
 
 #ifndef __ASSEMBLY__
 extern void mcount(void);
@@ -11,10 +12,13 @@
 #define MCOUNT_ADDR		((long)(mcount))
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-#define CALLER_ADDR		((long)(ftrace_caller))
+#define CALL_ADDR		((long)(ftrace_call))
 #define STUB_ADDR		((long)(ftrace_stub))
+#define GRAPH_ADDR		((long)(ftrace_graph_call))
+#define CALLER_ADDR		((long)(ftrace_caller))
 
-#define MCOUNT_INSN_OFFSET	((STUB_ADDR - CALLER_ADDR) >> 1)
+#define MCOUNT_INSN_OFFSET	((STUB_ADDR - CALL_ADDR) - 4)
+#define GRAPH_INSN_OFFSET	((CALLER_ADDR - GRAPH_ADDR) - 4)
 
 struct dyn_arch_ftrace {
 	/* No extra data needed on sh */
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index 715ee23..a5be4af 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -1,16 +1,9 @@
 #ifndef __ASM_SH_HARDIRQ_H
 #define __ASM_SH_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
-	unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
 extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/include/asm/heartbeat.h b/arch/sh/include/asm/heartbeat.h
index 724a43e..caaafe5 100644
--- a/arch/sh/include/asm/heartbeat.h
+++ b/arch/sh/include/asm/heartbeat.h
@@ -11,6 +11,7 @@
 	unsigned int nr_bits;
 	struct timer_list timer;
 	unsigned int regsize;
+	unsigned int mask;
 	unsigned long flags;
 };
 
diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h
new file mode 100644
index 0000000..5d3ccae
--- /dev/null
+++ b/arch/sh/include/asm/hwblk.h
@@ -0,0 +1,72 @@
+#ifndef __ASM_SH_HWBLK_H
+#define __ASM_SH_HWBLK_H
+
+#include <asm/clock.h>
+#include <asm/io.h>
+
+#define HWBLK_CNT_USAGE 0
+#define HWBLK_CNT_IDLE 1
+#define HWBLK_CNT_DEVICES 2
+#define HWBLK_CNT_NR 3
+
+#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
+
+#define HWBLK_AREA(_flags, _parent)		\
+{						\
+	.flags = _flags,			\
+	.parent = _parent,			\
+}
+
+struct hwblk_area {
+	int cnt[HWBLK_CNT_NR];
+	unsigned char parent;
+	unsigned char flags;
+};
+
+#define HWBLK(_mstp, _bit, _area)		\
+{						\
+	.mstp = (void __iomem *)_mstp,		\
+	.bit = _bit,				\
+	.area = _area,				\
+}
+
+struct hwblk {
+	void __iomem *mstp;
+	unsigned char bit;
+	unsigned char area;
+	int cnt[HWBLK_CNT_NR];
+};
+
+struct hwblk_info {
+	struct hwblk_area *areas;
+	int nr_areas;
+	struct hwblk *hwblks;
+	int nr_hwblks;
+};
+
+/* Should be defined by processor-specific code */
+int arch_hwblk_init(void);
+int arch_hwblk_sleep_mode(void);
+
+int hwblk_register(struct hwblk_info *info);
+int hwblk_init(void);
+
+void hwblk_enable(struct hwblk_info *info, int hwblk);
+void hwblk_disable(struct hwblk_info *info, int hwblk);
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
+
+/* allow clocks to enable and disable hardware blocks */
+#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags)	\
+{							\
+	.name		= _name,			\
+	.id		= _id,				\
+	.parent		= _parent,			\
+	.arch_flags	= _hwblk,			\
+	.flags		= _flags,			\
+}
+
+int sh_hwblk_clk_register(struct clk *clks, int nr);
+
+#endif /* __ASM_SH_HWBLK_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 2534814..5be45ea 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -92,8 +92,12 @@
 
 static inline void ctrl_delay(void)
 {
-#ifdef P2SEG
+#ifdef CONFIG_CPU_SH4
+	__raw_readw(CCN_PVR);
+#elif defined(P2SEG)
 	__raw_readw(P2SEG);
+#else
+#error "Need a dummy address for delay"
 #endif
 }
 
@@ -146,6 +150,7 @@
 #define readl_relaxed(a)	readl(a)
 #define readq_relaxed(a)	readq(a)
 
+#ifndef CONFIG_GENERIC_IOMAP
 /* Simple MMIO */
 #define ioread8(a)		__raw_readb(a)
 #define ioread16(a)		__raw_readw(a)
@@ -166,6 +171,15 @@
 #define iowrite8_rep(a, s, c)	__raw_writesb((a), (s), (c))
 #define iowrite16_rep(a, s, c)	__raw_writesw((a), (s), (c))
 #define iowrite32_rep(a, s, c)	__raw_writesl((a), (s), (c))
+#endif
+
+#define mmio_insb(p,d,c)	__raw_readsb(p,d,c)
+#define mmio_insw(p,d,c)	__raw_readsw(p,d,c)
+#define mmio_insl(p,d,c)	__raw_readsl(p,d,c)
+
+#define mmio_outsb(p,s,c)	__raw_writesb(p,s,c)
+#define mmio_outsw(p,s,c)	__raw_writesw(p,s,c)
+#define mmio_outsl(p,s,c)	__raw_writesl(p,s,c)
 
 /* synco on SH-4A, otherwise a nop */
 #define mmiowb()		wmb()
diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h
index 0b9f896..985219f 100644
--- a/arch/sh/include/asm/kdebug.h
+++ b/arch/sh/include/asm/kdebug.h
@@ -4,6 +4,7 @@
 /* Grossly misnamed. */
 enum die_val {
 	DIE_TRAP,
+	DIE_NMI,
 	DIE_OOPS,
 };
 
diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h
index 72704ed..4235e22 100644
--- a/arch/sh/include/asm/kgdb.h
+++ b/arch/sh/include/asm/kgdb.h
@@ -30,9 +30,6 @@
 	__asm__ __volatile__ ("trapa #0x3c\n");
 }
 
-/* State info */
-extern char in_nmi;		/* Debounce flag to prevent NMI reentry*/
-
 #define BUFMAX                 2048
 
 #define CACHE_FLUSH_IS_SAFE	1
diff --git a/arch/sh/include/asm/lmb.h b/arch/sh/include/asm/lmb.h
new file mode 100644
index 0000000..9b437f6
--- /dev/null
+++ b/arch/sh/include/asm/lmb.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_LMB_H
+#define __ASM_SH_LMB_H
+
+#define LMB_REAL_LIMIT	0
+
+#endif /* __ASM_SH_LMB_H */
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 67d8946..41080b1 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -69,7 +69,7 @@
 		 * We exhaust ASID of this version.
 		 * Flush all TLB and start new cycle.
 		 */
-		flush_tlb_all();
+		local_flush_tlb_all();
 
 #ifdef CONFIG_SUPERH64
 		/*
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 49592c7..81bffc0 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -50,26 +50,24 @@
 extern unsigned long max_low_pfn, min_low_pfn;
 extern unsigned long memory_start, memory_end;
 
-extern void clear_page(void *to);
+static inline unsigned long
+pages_do_alias(unsigned long addr1, unsigned long addr2)
+{
+	return (addr1 ^ addr2) & shm_align_mask;
+}
+
+
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, void *from);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
-	(defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \
-	 defined(CONFIG_SH7705_CACHE_32KB))
 struct page;
 struct vm_area_struct;
-extern void clear_user_page(void *to, unsigned long address, struct page *page);
-extern void copy_user_page(void *to, void *from, unsigned long address,
-			   struct page *page);
-#if defined(CONFIG_CPU_SH4)
+
 extern void copy_user_highpage(struct page *to, struct page *from,
 			       unsigned long vaddr, struct vm_area_struct *vma);
 #define __HAVE_ARCH_COPY_USER_HIGHPAGE
-#endif
-#else
-#define clear_user_page(page, vaddr, pg)	clear_page(page)
-#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
-#endif
+extern void clear_user_highpage(struct page *page, unsigned long vaddr);
+#define clear_user_highpage	clear_user_highpage
 
 /*
  * These are used to make use of C type-checking..
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 2a011b1..4f3efa7 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -36,6 +36,12 @@
 #define	NEFF_SIGN	(1LL << (NEFF - 1))
 #define	NEFF_MASK	(-1LL << NEFF)
 
+static inline unsigned long long neff_sign_extend(unsigned long val)
+{
+	unsigned long long extended = val;
+	return (extended & NEFF_SIGN) ? (extended | NEFF_MASK) : extended;
+}
+
 #ifdef CONFIG_29BIT
 #define NPHYS		29
 #else
@@ -133,27 +139,25 @@
  */
 #define pgtable_cache_init()	do { } while (0)
 
-#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
-	defined(CONFIG_SH7705_CACHE_32KB))
-struct mm_struct;
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-#endif
-
 struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct * vma,
-			     unsigned long address, pte_t pte);
+
+extern void __update_cache(struct vm_area_struct *vma,
+			   unsigned long address, pte_t pte);
+extern void __update_tlb(struct vm_area_struct *vma,
+			 unsigned long address, pte_t pte);
+
+static inline void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	__update_cache(vma, address, pte);
+	__update_tlb(vma, address, pte);
+}
+
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init(void);
 extern void page_table_range_init(unsigned long start, unsigned long end,
 				  pgd_t *pgd);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU)
-extern void kmap_coherent_init(void);
-#else
-#define kmap_coherent_init()	do { } while (0)
-#endif
-
 /* arch/sh/mm/mmap.c */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 72ea209..c0d359c 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -20,7 +20,7 @@
  * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
  *
  * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
- *   Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused.
+ *   Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
  *
  * - On 29 bit platforms, bits 31 to 29 are used for the space attributes
  *   and timing control which (together with bit 0) are moved into the
@@ -52,6 +52,7 @@
 #define _PAGE_PROTNONE	0x200		/* software: if not present  */
 #define _PAGE_ACCESSED	0x400		/* software: page referenced */
 #define _PAGE_FILE	_PAGE_WT	/* software: pagecache or swap? */
+#define _PAGE_SPECIAL	0x800		/* software: special page */
 
 #define _PAGE_SZ_MASK	(_PAGE_SZ0 | _PAGE_SZ1)
 #define _PAGE_PR_MASK	(_PAGE_RW | _PAGE_USER)
@@ -86,6 +87,14 @@
 #define _PAGE_PCC_ATR8	0x60000000	/* Attribute Memory space, 8 bit bus */
 #define _PAGE_PCC_ATR16	0x60000001	/* Attribute Memory space, 6 bit bus */
 
+#ifndef CONFIG_X2TLB
+/* copy the ptea attributes */
+static inline unsigned long copy_ptea_attributes(unsigned long x)
+{
+	return	((x >> 28) & 0xe) | (x & 0x1);
+}
+#endif
+
 /* Mask which drops unused bits from the PTEL value */
 #if defined(CONFIG_CPU_SH3)
 #define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED| \
@@ -148,8 +157,12 @@
 # define _PAGE_SZHUGE	(_PAGE_FLAGS_HARD)
 #endif
 
+/*
+ * Mask of bits that are to be preserved accross pgprot changes.
+ */
 #define _PAGE_CHG_MASK \
-	(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
+	(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
+	 _PAGE_DIRTY | _PAGE_SPECIAL)
 
 #ifndef __ASSEMBLY__
 
@@ -328,7 +341,7 @@
 #define pte_dirty(pte)		((pte).pte_low & _PAGE_DIRTY)
 #define pte_young(pte)		((pte).pte_low & _PAGE_ACCESSED)
 #define pte_file(pte)		((pte).pte_low & _PAGE_FILE)
-#define pte_special(pte)	(0)
+#define pte_special(pte)	((pte).pte_low & _PAGE_SPECIAL)
 
 #ifdef CONFIG_X2TLB
 #define pte_write(pte)		((pte).pte_high & _PAGE_EXT_USER_WRITE)
@@ -358,8 +371,9 @@
 PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
 PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
 PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
+PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
 
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+#define __HAVE_ARCH_PTE_SPECIAL
 
 /*
  * Macro and implementation to make a page protection as uncachable.
@@ -394,13 +408,19 @@
 
 /* to find an entry in a page-table-directory. */
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address)	((mm)->pgd+pgd_index(address))
+#define pgd_offset(mm, address)	((mm)->pgd + pgd_index(address))
+#define __pgd_offset(address)	pgd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address)	pgd_offset(&init_mm, address)
 
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
 /* Find an entry in the third-level page table.. */
 #define pte_index(address)	((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define __pte_offset(address)	pte_index(address)
+
 #define pte_offset_kernel(dir, address) \
 	((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
 #define pte_offset_map(dir, address)		pte_offset_kernel(dir, address)
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index c78990c..17cdbec 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -60,6 +60,9 @@
 /* To find an entry in a kernel PGD. */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
 /*
  * PMD level access routines. Same notes as above.
  */
@@ -80,6 +83,8 @@
 #define pte_index(address) \
 		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 
+#define __pte_offset(address)	pte_index(address)
+
 #define pte_offset_kernel(dir, addr) \
 		((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))
 
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index ff7daaf..017e0c1 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -32,7 +32,7 @@
 
 	/* SH-4A types */
 	CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
-	CPU_SH7723, CPU_SH7724, CPU_SHX3,
+	CPU_SH7723, CPU_SH7724, CPU_SH7757, CPU_SHX3,
 
 	/* SH4AL-DSP types */
 	CPU_SH7343, CPU_SH7722, CPU_SH7366,
@@ -44,6 +44,17 @@
 	CPU_SH_NONE
 };
 
+enum cpu_family {
+	CPU_FAMILY_SH2,
+	CPU_FAMILY_SH2A,
+	CPU_FAMILY_SH3,
+	CPU_FAMILY_SH4,
+	CPU_FAMILY_SH4A,
+	CPU_FAMILY_SH4AL_DSP,
+	CPU_FAMILY_SH5,
+	CPU_FAMILY_UNKNOWN,
+};
+
 /*
  * TLB information structure
  *
@@ -61,7 +72,7 @@
 };
 
 struct sh_cpuinfo {
-	unsigned int type;
+	unsigned int type, family;
 	int cut_major, cut_minor;
 	unsigned long loops_per_jiffy;
 	unsigned long asid_cache;
diff --git a/arch/sh/include/asm/romimage-macros.h b/arch/sh/include/asm/romimage-macros.h
new file mode 100644
index 0000000..ae17a15
--- /dev/null
+++ b/arch/sh/include/asm/romimage-macros.h
@@ -0,0 +1,73 @@
+#ifndef __ROMIMAGE_MACRO_H
+#define __ROMIMAGE_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro	LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro  ED, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.l r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro  EW, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.w r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro  EB, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.b r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro  WAIT, time
+	mov.l  2f, r3
+1 :
+	nop
+	tst     r3, r3
+	bf/s    1b
+	dt      r3
+	bra	3f
+	 nop
+	.align 2
+2 :	.long \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro  DD, addr, addr2, nr
+	mov.l 1f, r1
+	mov.l @r1, r0
+	bra 2f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :
+.endm
+
+#endif /* __ROMIMAGE_MACRO_H */
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
index 01a4076a37..a78701d 100644
--- a/arch/sh/include/asm/sections.h
+++ b/arch/sh/include/asm/sections.h
@@ -7,6 +7,7 @@
 extern long __machvec_start, __machvec_end;
 extern char __uncached_start, __uncached_end;
 extern char _ebss[];
+extern char __start_eh_frame[], __stop_eh_frame[];
 
 #endif /* __ASM_SH_SECTIONS_H */
 
diff --git a/arch/sh/include/asm/sh_keysc.h b/arch/sh/include/asm/sh_keysc.h
index b5a4dd5..4a65b1e 100644
--- a/arch/sh/include/asm/sh_keysc.h
+++ b/arch/sh/include/asm/sh_keysc.h
@@ -7,6 +7,7 @@
 	enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
 	int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
 	int delay;
+	int kycr2_delay;
 	int keycodes[SH_KEYSC_MAXKEYS];
 };
 
diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h
new file mode 100644
index 0000000..7970182
--- /dev/null
+++ b/arch/sh/include/asm/stacktrace.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based on:
+ *	The x86 implementation - arch/x86/include/asm/stacktrace.h
+ */
+#ifndef _ASM_SH_STACKTRACE_H
+#define _ASM_SH_STACKTRACE_H
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+	void (*warning)(void *data, char *msg);
+	/* msg must contain %s for the symbol */
+	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+	void (*address)(void *data, unsigned long address, int reliable);
+	/* On negative return stop dumping */
+	int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+		unsigned long *stack,
+		const struct stacktrace_ops *ops, void *data);
+
+#endif /* _ASM_SH_STACKTRACE_H */
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index b1b9953..5c8ea28 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -10,6 +10,15 @@
 	struct pt_regs user_regs;
 	unsigned long bank1_regs[8];
 };
+
+void sh_mobile_call_standby(unsigned long mode);
+
+#ifdef CONFIG_CPU_IDLE
+void sh_mobile_setup_cpuidle(void);
+#else
+static inline void sh_mobile_setup_cpuidle(void) {}
+#endif
+
 #endif
 
 /* flags passed to assembly suspend code */
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 6f83f2c..7d80df4 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -65,6 +65,7 @@
 	case 3: args[2] = regs->regs[6];
 	case 2: args[1] = regs->regs[5];
 	case 1:	args[0] = regs->regs[4];
+	case 0:
 		break;
 	default:
 		BUG();
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index ab79e1f..b5c5acd 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -14,18 +14,6 @@
 
 #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
 
-#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
-#define __icbi()			\
-{					\
-	unsigned long __addr;		\
-	__addr = 0xa8000000;		\
-	__asm__ __volatile__(		\
-		"icbi   %0\n\t"		\
-		: /* no output */	\
-		: "m" (__m(__addr)));	\
-}
-#endif
-
 /*
  * A brief note on ctrl_barrier(), the control register write barrier.
  *
@@ -44,7 +32,7 @@
 #define mb()		__asm__ __volatile__ ("synco": : :"memory")
 #define rmb()		mb()
 #define wmb()		__asm__ __volatile__ ("synco": : :"memory")
-#define ctrl_barrier()	__icbi()
+#define ctrl_barrier()	__icbi(0xa8000000)
 #define read_barrier_depends()	do { } while(0)
 #else
 #define mb()		__asm__ __volatile__ ("": : :"memory")
@@ -181,6 +169,11 @@
 BUILD_TRAP_HANDLER(singlestep);
 BUILD_TRAP_HANDLER(fpu_error);
 BUILD_TRAP_HANDLER(fpu_state_restore);
+BUILD_TRAP_HANDLER(nmi);
+
+#ifdef CONFIG_BUG
+extern void handle_BUG(struct pt_regs *);
+#endif
 
 #define arch_align_stack(x) (x)
 
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 6c68a51..607d413 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -14,12 +14,12 @@
 			(u32 *)&tsk->thread.dsp_status;			\
 	__asm__ __volatile__ (						\
 		".balign 4\n\t"						\
+		"movs.l	@r2+, a0\n\t"					\
 		"movs.l	@r2+, a1\n\t"					\
 		"movs.l	@r2+, a0g\n\t"					\
 		"movs.l	@r2+, a1g\n\t"					\
 		"movs.l	@r2+, m0\n\t"					\
 		"movs.l	@r2+, m1\n\t"					\
-		"movs.l	@r2+, a0\n\t"					\
 		"movs.l	@r2+, x0\n\t"					\
 		"movs.l	@r2+, x1\n\t"					\
 		"movs.l	@r2+, y0\n\t"					\
@@ -39,20 +39,20 @@
 									\
 	__asm__ __volatile__ (						\
 		".balign 4\n\t"						\
-		"stc.l	mod, @-r2\n\t"				\
+		"stc.l	mod, @-r2\n\t"					\
 		"stc.l	re, @-r2\n\t"					\
 		"stc.l	rs, @-r2\n\t"					\
-		"sts.l	dsr, @-r2\n\t"				\
-		"sts.l	y1, @-r2\n\t"					\
-		"sts.l	y0, @-r2\n\t"					\
-		"sts.l	x1, @-r2\n\t"					\
-		"sts.l	x0, @-r2\n\t"					\
-		"sts.l	a0, @-r2\n\t"					\
-		".word	0xf653		! movs.l	a1, @-r2\n\t"	\
-		".word	0xf6f3		! movs.l	a0g, @-r2\n\t"	\
-		".word	0xf6d3		! movs.l	a1g, @-r2\n\t"	\
-		".word	0xf6c3		! movs.l        m0, @-r2\n\t"	\
-		".word	0xf6e3		! movs.l        m1, @-r2\n\t"	\
+		"sts.l	dsr, @-r2\n\t"					\
+		"movs.l	y1, @-r2\n\t"					\
+		"movs.l	y0, @-r2\n\t"					\
+		"movs.l	x1, @-r2\n\t"					\
+		"movs.l	x0, @-r2\n\t"					\
+		"movs.l	m1, @-r2\n\t"					\
+		"movs.l	m0, @-r2\n\t"					\
+		"movs.l	a1g, @-r2\n\t"					\
+		"movs.l	a0g, @-r2\n\t"					\
+		"movs.l	a1, @-r2\n\t"					\
+		"movs.l	a0, @-r2\n\t"					\
 		: : "r" (__ts2));					\
 } while (0)
 
@@ -63,6 +63,16 @@
 #define __restore_dsp(tsk)	do { } while (0)
 #endif
 
+#if defined(CONFIG_CPU_SH4A)
+#define __icbi(addr)	__asm__ __volatile__ ( "icbi @%0\n\t" : : "r" (addr))
+#else
+#define __icbi(addr)	mb()
+#endif
+
+#define __ocbp(addr)	__asm__ __volatile__ ( "ocbp @%0\n\t" : : "r" (addr))
+#define __ocbi(addr)	__asm__ __volatile__ ( "ocbi @%0\n\t" : : "r" (addr))
+#define __ocbwb(addr)	__asm__ __volatile__ ( "ocbwb @%0\n\t" : : "r" (addr))
+
 struct task_struct *__switch_to(struct task_struct *prev,
 				struct task_struct *next);
 
@@ -198,8 +208,13 @@
 })
 #endif
 
+static inline reg_size_t register_align(void *val)
+{
+	return (unsigned long)(signed long)val;
+}
+
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma);
+			    struct mem_access *ma, int);
 
 asmlinkage void do_address_error(struct pt_regs *regs,
 				 unsigned long writeaccess,
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h
index 943acf5..8e4a03e 100644
--- a/arch/sh/include/asm/system_64.h
+++ b/arch/sh/include/asm/system_64.h
@@ -37,4 +37,14 @@
 #define jump_to_uncached()	do { } while (0)
 #define back_to_cached()	do { } while (0)
 
+#define __icbi(addr)	__asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr))
+#define __ocbp(addr)	__asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr))
+#define __ocbi(addr)	__asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr))
+#define __ocbwb(addr)	__asm__ __volatile__ ( "ocbwb %0, 0\n\t" : : "r" (addr))
+
+static inline reg_size_t register_align(void *val)
+{
+	return (unsigned long long)(signed long long)(signed long)val;
+}
+
 #endif /* __ASM_SH_SYSTEM_64_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index d570ac2..5123bca 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -97,7 +97,7 @@
 
 extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
 extern void free_thread_info(struct thread_info *ti);
- 
+
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
 
 #endif /* __ASSEMBLY__ */
@@ -116,6 +116,7 @@
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SECCOMP		6	/* secure computing */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
+#define TIF_SYSCALL_FTRACE	8	/* for ftrace syscall instrumentation */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
@@ -129,25 +130,27 @@
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_FTRACE	(1 << TIF_SYSCALL_FTRACE)
 #define _TIF_USEDFPU		(1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
 
 /*
- * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
+ * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
  * blow the tst immediate size constraints and need to fix up
  * arch/sh/kernel/entry-common.S.
  */
 
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK	(_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
-				 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
+				 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP    | \
+				 _TIF_SYSCALL_FTRACE)
 
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK	(_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
 				 _TIF_NEED_RESCHED  | _TIF_SYSCALL_AUDIT   | \
 				 _TIF_SINGLESTEP    | _TIF_RESTORE_SIGMASK | \
-				 _TIF_NOTIFY_RESUME)
+				 _TIF_NOTIFY_RESUME | _TIF_SYSCALL_FTRACE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h
index c7f3c94..f8421f7 100644
--- a/arch/sh/include/asm/types.h
+++ b/arch/sh/include/asm/types.h
@@ -11,8 +11,10 @@
 
 #ifdef CONFIG_SUPERH32
 typedef u16 insn_size_t;
+typedef u32 reg_size_t;
 #else
 typedef u32 insn_size_t;
+typedef u64 reg_size_t;
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 61d6ad9..925dd40 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -132,7 +132,7 @@
 #define __NR_clone		120
 #define __NR_setdomainname	121
 #define __NR_uname		122
-#define __NR_modify_ldt		123
+#define __NR_cacheflush		123
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
 #define __NR_sigprocmask	126
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index a751699..2b84bc9 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -137,7 +137,7 @@
 #define __NR_clone		120
 #define __NR_setdomainname	121
 #define __NR_uname		122
-#define __NR_modify_ldt		123
+#define __NR_cacheflush		123
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
 #define __NR_sigprocmask	126
diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h
new file mode 100644
index 0000000..1e65c07
--- /dev/null
+++ b/arch/sh/include/asm/unwinder.h
@@ -0,0 +1,31 @@
+#ifndef _LINUX_UNWINDER_H
+#define _LINUX_UNWINDER_H
+
+#include <asm/stacktrace.h>
+
+struct unwinder {
+	const char *name;
+	struct list_head list;
+	int rating;
+	void (*dump)(struct task_struct *, struct pt_regs *,
+		     unsigned long *, const struct stacktrace_ops *, void *);
+};
+
+extern int unwinder_init(void);
+extern int unwinder_register(struct unwinder *);
+
+extern void unwind_stack(struct task_struct *, struct pt_regs *,
+			 unsigned long *, const struct stacktrace_ops *,
+			 void *);
+
+extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
+			      unsigned long *, const struct stacktrace_ops *,
+			      void *);
+
+/*
+ * Used by fault handling code to signal to the unwinder code that it
+ * should switch to a different unwinder.
+ */
+extern int unwinder_faulted;
+
+#endif /* _LINUX_UNWINDER_H */
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h
new file mode 100644
index 0000000..244ec4a
--- /dev/null
+++ b/arch/sh/include/asm/vmlinux.lds.h
@@ -0,0 +1,17 @@
+#ifndef __ASM_SH_VMLINUX_LDS_H
+#define __ASM_SH_VMLINUX_LDS_H
+
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+#define DWARF_EH_FRAME							\
+	.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {			\
+		  VMLINUX_SYMBOL(__start_eh_frame) = .;			\
+		  *(.eh_frame)						\
+		  VMLINUX_SYMBOL(__stop_eh_frame) = .;			\
+	}
+#else
+#define DWARF_EH_FRAME
+#endif
+
+#endif /* __ASM_SH_VMLINUX_LDS_H */
diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h
index f024fed..2fe7cee 100644
--- a/arch/sh/include/asm/watchdog.h
+++ b/arch/sh/include/asm/watchdog.h
@@ -13,10 +13,18 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <cpu/watchdog.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
-/* 
+#define WTCNT_HIGH	0x5a
+#define WTCSR_HIGH	0xa5
+
+#define WTCSR_CKS2	0x04
+#define WTCSR_CKS1	0x02
+#define WTCSR_CKS0	0x01
+
+#include <cpu/watchdog.h>
+
+/*
  * See cpu-sh2/watchdog.h for explanation of this stupidity..
  */
 #ifndef WTCNT_R
@@ -27,13 +35,6 @@
 #  define WTCSR_R	WTCSR
 #endif
 
-#define WTCNT_HIGH	0x5a
-#define WTCSR_HIGH	0xa5
-
-#define WTCSR_CKS2	0x04
-#define WTCSR_CKS1	0x02
-#define WTCSR_CKS0	0x01
-
 /*
  * CKS0-2 supports a number of clock division ratios. At the time the watchdog
  * is enabled, it defaults to a 41 usec overflow period .. we overload this to
diff --git a/arch/sh/include/cpu-common/cpu/cacheflush.h b/arch/sh/include/cpu-common/cpu/cacheflush.h
deleted file mode 100644
index c3db00b7..0000000
--- a/arch/sh/include/cpu-common/cpu/cacheflush.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * include/asm-sh/cpu-sh2/cacheflush.h
- *
- * Copyright (C) 2003 Paul Mundt
- *
- * 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_CPU_SH2_CACHEFLUSH_H
-#define __ASM_CPU_SH2_CACHEFLUSH_H
-
-/*
- * Cache flushing:
- *
- *  - flush_cache_all() flushes entire cache
- *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
- *  - flush_cache_dup mm(mm) handles cache flushing when forking
- *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
- *  - flush_cache_range(vma, start, end) flushes a range of pages
- *
- *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
- *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
- *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
- *
- *  Caches are indexed (effectively) by physical address on SH-2, so
- *  we don't need them.
- */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-#define flush_icache_range(start, end)		do { } while (0)
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-
-#endif /* __ASM_CPU_SH2_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh2a/cpu/cacheflush.h b/arch/sh/include/cpu-sh2a/cpu/cacheflush.h
deleted file mode 100644
index 3d3b920..0000000
--- a/arch/sh/include/cpu-sh2a/cpu/cacheflush.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ASM_CPU_SH2A_CACHEFLUSH_H
-#define __ASM_CPU_SH2A_CACHEFLUSH_H
-
-/* 
- * Cache flushing:
- *
- *  - flush_cache_all() flushes entire cache
- *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
- *  - flush_cache_dup mm(mm) handles cache flushing when forking
- *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
- *  - flush_cache_range(vma, start, end) flushes a range of pages
- *
- *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
- *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
- *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
- *
- *  Caches are indexed (effectively) by physical address on SH-2, so
- *  we don't need them.
- */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-void flush_icache_range(unsigned long start, unsigned long end);
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-#endif /* __ASM_CPU_SH2A_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/cacheflush.h b/arch/sh/include/cpu-sh3/cpu/cacheflush.h
deleted file mode 100644
index 1ac27aa..0000000
--- a/arch/sh/include/cpu-sh3/cpu/cacheflush.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * include/asm-sh/cpu-sh3/cacheflush.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- *
- * 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_CPU_SH3_CACHEFLUSH_H
-#define __ASM_CPU_SH3_CACHEFLUSH_H
-
-#if defined(CONFIG_SH7705_CACHE_32KB)
-/* SH7705 is an SH3 processor with 32KB cache. This has alias issues like the
- * SH4. Unlike the SH4 this is a unified cache so we need to do some work
- * in mmap when 'exec'ing a new binary
- */
- /* 32KB cache, 4kb PAGE sizes need to check bit 12 */
-#define CACHE_ALIAS 0x00001000
-
-#define PG_mapped	PG_arch_1
-
-void flush_cache_all(void);
-void flush_cache_mm(struct mm_struct *mm);
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-                              unsigned long end);
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
-void flush_dcache_page(struct page *pg);
-void flush_icache_range(unsigned long start, unsigned long end);
-void flush_icache_page(struct vm_area_struct *vma, struct page *page);
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-/* SH3 has unified cache so no special action needed here */
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-
-#else
-#include <cpu-common/cpu/cacheflush.h>
-#endif
-
-#endif /* __ASM_CPU_SH3_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/cacheflush.h b/arch/sh/include/cpu-sh4/cpu/cacheflush.h
deleted file mode 100644
index 065306d..0000000
--- a/arch/sh/include/cpu-sh4/cpu/cacheflush.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * include/asm-sh/cpu-sh4/cacheflush.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
- *
- * 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_CPU_SH4_CACHEFLUSH_H
-#define __ASM_CPU_SH4_CACHEFLUSH_H
-
-/*
- *  Caches are broken on SH-4 (unless we use write-through
- *  caching; in which case they're only semi-broken),
- *  so we need them.
- */
-void flush_cache_all(void);
-void flush_dcache_all(void);
-void flush_cache_mm(struct mm_struct *mm);
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end);
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
-		      unsigned long pfn);
-void flush_dcache_page(struct page *pg);
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-void flush_icache_range(unsigned long start, unsigned long end);
-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
-			     unsigned long addr, int len);
-
-#define flush_icache_page(vma,pg)		do { } while (0)
-
-/* Initialization of P3 area for copy_user_page */
-void p3_cache_init(void);
-
-#define PG_mapped	PG_arch_1
-
-#endif /* __ASM_CPU_SH4_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index 0ed5178..f0886bc 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -16,7 +16,8 @@
 #define DMAE0_IRQ	38
 #define SH_DMAC_BASE0	0xFF608020
 #define SH_DMARS_BASE	0xFF609000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7724)
 #define DMTE0_IRQ	48	/* DMAC0A*/
 #define DMTE4_IRQ	40	/* DMAC0B */
 #define DMTE6_IRQ	42
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index ccf1d99..e1e9096 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -22,6 +22,10 @@
 #define MSTPCR0			0xa4150030
 #define MSTPCR1			0xa4150034
 #define MSTPCR2			0xa4150038
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+#define	FRQCR			0xffc80000
+#define	OSCCR			0xffc80018
+#define	PLLCR			0xffc80024
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
       defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define	FRQCR			0xffc80000
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h
index 738ea43..4856040 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7722.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h
@@ -221,4 +221,18 @@
 	GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM,
+	HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI,
+	HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO,
+	HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
+	HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
+	HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
+	HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
+	HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7722_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h
index 14c8ca9..9b36fae 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7723.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h
@@ -265,4 +265,21 @@
 	GPIO_FN_IDEA1, GPIO_FN_IDEA0,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
+	HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+	HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC,
+	HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+	HWBLK_FLCTL,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
+	HWBLK_SCIF3, HWBLK_SCIF4, HWBLK_SCIF5,
+	HWBLK_MSIOF0, HWBLK_MSIOF1, HWBLK_MERAM, HWBLK_IIC, HWBLK_RTC,
+	HWBLK_ATAPI, HWBLK_ADC, HWBLK_TPU, HWBLK_IRDA, HWBLK_TSIF, HWBLK_ICB,
+	HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_KEYSC, HWBLK_USB,
+	HWBLK_2DG, HWBLK_SIU, HWBLK_VEU2H1, HWBLK_VOU, HWBLK_BEU, HWBLK_CEU,
+	HWBLK_VEU2H0, HWBLK_VPU, HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7723_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index 66fd118..0cd1f71 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -266,4 +266,21 @@
 	GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
+	HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+	HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC,
+	HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
+	HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
+	HWBLK_KEYSC, HWBLK_RTC, HWBLK_IIC0, HWBLK_IIC1,
+	HWBLK_MMC, HWBLK_ETHER, HWBLK_ATAPI, HWBLK_TPU, HWBLK_IRDA,
+	HWBLK_TSIF, HWBLK_USB1, HWBLK_USB0, HWBLK_2DG,
+	HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_VEU1, HWBLK_CEU1, HWBLK_BEU1,
+	HWBLK_2DDMAC, HWBLK_SPU, HWBLK_JPU, HWBLK_VOU,
+	HWBLK_BEU0, HWBLK_CEU0,	HWBLK_VEU0, HWBLK_VPU, HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h
new file mode 100644
index 0000000..f4d267e
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h
@@ -0,0 +1,243 @@
+#ifndef __ASM_SH7757_H__
+#define __ASM_SH7757_H__
+
+enum {
+	/* PTA */
+	GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+	GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+	/* PTB */
+	GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+	GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+	/* PTC */
+	GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
+	GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+
+	/* PTD */
+	GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+	GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+	/* PTE */
+	GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
+	GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+
+	/* PTF */
+	GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
+	GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+
+	/* PTG */
+	GPIO_PTG7, GPIO_PTG6, GPIO_PTG5, GPIO_PTG4,
+	GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+
+	/* PTH */
+	GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
+	GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+	/* PTI */
+	GPIO_PTI7, GPIO_PTI6, GPIO_PTI5, GPIO_PTI4,
+	GPIO_PTI3, GPIO_PTI2, GPIO_PTI1, GPIO_PTI0,
+
+	/* PTJ */
+	GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4,
+	GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+
+	/* PTK */
+	GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
+	GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+	/* PTL */
+	GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
+	GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+
+	/* PTM */
+		   GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+	GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+	/* PTN */
+	GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
+	GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+
+	/* PTO */
+	GPIO_PTO7, GPIO_PTO6, GPIO_PTO5, GPIO_PTO4,
+	GPIO_PTO3, GPIO_PTO2, GPIO_PTO1, GPIO_PTO0,
+
+	/* PTP */
+		   GPIO_PTP6, GPIO_PTP5, GPIO_PTP4,
+	GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+
+	/* PTQ */
+		   GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
+	GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+
+	/* PTR */
+	GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
+	GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+	/* PTS */
+	GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
+	GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+	/* PTT */
+			      GPIO_PTT5, GPIO_PTT4,
+	GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+
+	/* PTU */
+	GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
+	GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+
+	/* PTV */
+	GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
+	GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+	/* PTW */
+	GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
+	GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+
+	/* PTX */
+	GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
+	GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+
+	/* PTY */
+	GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
+	GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+
+	/* PTZ */
+	GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
+	GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+
+
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	GPIO_FN_BS,	GPIO_FN_RDWR,	GPIO_FN_WE1,	GPIO_FN_RDY,
+	GPIO_FN_MD10,	GPIO_FN_MD9,	GPIO_FN_MD8,
+	GPIO_FN_LGPIO7,	GPIO_FN_LGPIO6,	GPIO_FN_LGPIO5,	GPIO_FN_LGPIO4,
+	GPIO_FN_LGPIO3,	GPIO_FN_LGPIO2,	GPIO_FN_LGPIO1,	GPIO_FN_LGPIO0,
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	GPIO_FN_D15,	GPIO_FN_D14,	GPIO_FN_D13,	GPIO_FN_D12,
+	GPIO_FN_D11,	GPIO_FN_D10,	GPIO_FN_D9,	GPIO_FN_D8,
+	GPIO_FN_ET0_MDC,		GPIO_FN_ET0_MDIO,
+	GPIO_FN_ET1_MDC,		GPIO_FN_ET1_MDIO,
+	GPIO_FN_SIM_D,	GPIO_FN_SIM_CLK,		GPIO_FN_SIM_RST,
+	GPIO_FN_WPSZ1,	GPIO_FN_WPSZ0,	GPIO_FN_FWID,	GPIO_FN_FLSHSZ,
+	GPIO_FN_LPC_SPIEN,		GPIO_FN_BASEL,
+
+	/* PTC (mobule: SD) */
+	GPIO_FN_SD_WP,	GPIO_FN_SD_CD,	GPIO_FN_SD_CLK,	GPIO_FN_SD_CMD,
+	GPIO_FN_SD_D3,	GPIO_FN_SD_D2,	GPIO_FN_SD_D1,	GPIO_FN_SD_D0,
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	GPIO_FN_IRQ7,	GPIO_FN_IRQ6,	GPIO_FN_IRQ5,	GPIO_FN_IRQ4,
+	GPIO_FN_IRQ3,	GPIO_FN_IRQ2,	GPIO_FN_IRQ1,	GPIO_FN_IRQ0,
+	GPIO_FN_MD6,	GPIO_FN_MD5,	GPIO_FN_MD3,	GPIO_FN_MD2,
+	GPIO_FN_MD1,	GPIO_FN_MD0,	GPIO_FN_ADTRG1,	GPIO_FN_ADTRG0,
+
+	/* PTE (mobule: EtherC) */
+	GPIO_FN_ET0_CRS_DV,		GPIO_FN_ET0_TXD1,
+	GPIO_FN_ET0_TXD0,		GPIO_FN_ET0_TX_EN,
+	GPIO_FN_ET0_REF_CLK,		GPIO_FN_ET0_RXD1,
+	GPIO_FN_ET0_RXD0,		GPIO_FN_ET0_RX_ER,
+
+	/* PTF (mobule: EtherC) */
+	GPIO_FN_ET1_CRS_DV,		GPIO_FN_ET1_TXD1,
+	GPIO_FN_ET1_TXD0,		GPIO_FN_ET1_TX_EN,
+	GPIO_FN_ET1_REF_CLK,		GPIO_FN_ET1_RXD1,
+	GPIO_FN_ET1_RXD0,		GPIO_FN_ET1_RX_ER,
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	GPIO_FN_STATUS0,		GPIO_FN_STATUS1,
+	GPIO_FN_PWX0,	GPIO_FN_PWX1,	GPIO_FN_PWX2,	GPIO_FN_PWX3,
+	GPIO_FN_SERIRQ,	GPIO_FN_CLKRUN,	GPIO_FN_LPCPD,	GPIO_FN_LDRQ,
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	GPIO_FN_TCLK,	GPIO_FN_RXD4,	GPIO_FN_TXD4,
+	GPIO_FN_SP1_MOSI,		GPIO_FN_SP1_MISO,
+	GPIO_FN_SP1_SCK,		GPIO_FN_SP1_SCK_FB,
+	GPIO_FN_SP1_SS0,		GPIO_FN_SP1_SS1,
+	GPIO_FN_SP0_SS1,
+
+	/* PTI (mobule: INTC) */
+	GPIO_FN_IRQ15,	GPIO_FN_IRQ14,	GPIO_FN_IRQ13,	GPIO_FN_IRQ12,
+	GPIO_FN_IRQ11,	GPIO_FN_IRQ10,	GPIO_FN_IRQ9,	GPIO_FN_IRQ8,
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	GPIO_FN_RXD3,	GPIO_FN_TXD3,	GPIO_FN_RXD2,	GPIO_FN_TXD2,
+	GPIO_FN_COM1_TXD,		GPIO_FN_COM1_RXD,
+	GPIO_FN_COM1_RTS,		GPIO_FN_COM1_CTS,
+
+	/* PTK (mobule: SERMUX) */
+	GPIO_FN_COM2_TXD,		GPIO_FN_COM2_RXD,
+	GPIO_FN_COM2_RTS,		GPIO_FN_COM2_CTS,
+	GPIO_FN_COM2_DTR,		GPIO_FN_COM2_DSR,
+	GPIO_FN_COM2_DCD,		GPIO_FN_COM2_RI,
+
+	/* PTL (mobule: SERMUX) */
+	GPIO_FN_RAC_TXD,		GPIO_FN_RAC_RXD,
+	GPIO_FN_RAC_RTS,		GPIO_FN_RAC_CTS,
+	GPIO_FN_RAC_DTR,		GPIO_FN_RAC_DSR,
+	GPIO_FN_RAC_DCD,		GPIO_FN_RAC_RI,
+
+	/* PTM (mobule: IIC, LPC) */
+	GPIO_FN_SDA6,	GPIO_FN_SCL6,	GPIO_FN_SDA7,	GPIO_FN_SCL7,
+	GPIO_FN_WP,	GPIO_FN_FMS0,	GPIO_FN_FMS1,
+
+	/* PTN (mobule: SCIF234, EVC) */
+	GPIO_FN_SCK2,	GPIO_FN_RTS4,	GPIO_FN_RTS3,	GPIO_FN_RTS2,
+	GPIO_FN_CTS4,	GPIO_FN_CTS3,	GPIO_FN_CTS2,
+	GPIO_FN_EVENT7,	GPIO_FN_EVENT6,	GPIO_FN_EVENT5,	GPIO_FN_EVENT4,
+	GPIO_FN_EVENT3,	GPIO_FN_EVENT2,	GPIO_FN_EVENT1,	GPIO_FN_EVENT0,
+
+	/* PTO (mobule: SGPIO) */
+	GPIO_FN_SGPIO0_CLK,		GPIO_FN_SGPIO0_LOAD,
+	GPIO_FN_SGPIO0_DI,		GPIO_FN_SGPIO0_DO,
+	GPIO_FN_SGPIO1_CLK,		GPIO_FN_SGPIO1_LOAD,
+	GPIO_FN_SGPIO1_DI,		GPIO_FN_SGPIO1_DO,
+
+	/* PTP (mobule: JMC, SCIF234) */
+	GPIO_FN_JMCTCK,	GPIO_FN_JMCTMS,	GPIO_FN_JMCTDO,	GPIO_FN_JMCTDI,
+	GPIO_FN_JMCRST,	GPIO_FN_SCK4,	GPIO_FN_SCK3,
+
+	/* PTQ (mobule: LPC) */
+	GPIO_FN_LAD3,	GPIO_FN_LAD2,	GPIO_FN_LAD1,	GPIO_FN_LAD0,
+	GPIO_FN_LFRAME,	GPIO_FN_LRESET,	GPIO_FN_LCLK,
+
+	/* PTR (mobule: GRA, IIC) */
+	GPIO_FN_DDC3,	GPIO_FN_DDC2,
+	GPIO_FN_SDA8,	GPIO_FN_SCL8,	GPIO_FN_SDA2,	GPIO_FN_SCL2,
+	GPIO_FN_SDA1,	GPIO_FN_SCL1,	GPIO_FN_SDA0,	GPIO_FN_SCL0,
+
+	/* PTS (mobule: GRA, IIC) */
+	GPIO_FN_DDC1,	GPIO_FN_DDC0,
+	GPIO_FN_SDA9,	GPIO_FN_SCL9,	GPIO_FN_SDA5,	GPIO_FN_SCL5,
+	GPIO_FN_SDA4,	GPIO_FN_SCL4,	GPIO_FN_SDA3,	GPIO_FN_SCL3,
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	GPIO_FN_AUDSYNC,		GPIO_FN_AUDCK,
+	GPIO_FN_AUDATA3,		GPIO_FN_AUDATA2,
+	GPIO_FN_AUDATA1,		GPIO_FN_AUDATA0,
+	GPIO_FN_PWX7,	GPIO_FN_PWX6,	GPIO_FN_PWX5,	GPIO_FN_PWX4,
+
+	/* PTU (mobule: LBSC, DMAC) */
+	GPIO_FN_CS6,	GPIO_FN_CS5,	GPIO_FN_CS4,	GPIO_FN_CS0,
+	GPIO_FN_RD,	GPIO_FN_WE0,	GPIO_FN_A25,	GPIO_FN_A24,
+	GPIO_FN_DREQ0,	GPIO_FN_DACK0,
+
+	/* PTV (mobule: LBSC, DMAC) */
+	GPIO_FN_A23,	GPIO_FN_A22,	GPIO_FN_A21,	GPIO_FN_A20,
+	GPIO_FN_A19,	GPIO_FN_A18,	GPIO_FN_A17,	GPIO_FN_A16,
+	GPIO_FN_TEND0,	GPIO_FN_DREQ1,	GPIO_FN_DACK1,	GPIO_FN_TEND1,
+
+	/* PTW (mobule: LBSC) */
+	GPIO_FN_A15,	GPIO_FN_A14,	GPIO_FN_A13,	GPIO_FN_A12,
+	GPIO_FN_A11,	GPIO_FN_A10,	GPIO_FN_A9,	GPIO_FN_A8,
+
+	/* PTX (mobule: LBSC) */
+	GPIO_FN_A7,	GPIO_FN_A6,	GPIO_FN_A5,	GPIO_FN_A4,
+	GPIO_FN_A3,	GPIO_FN_A2,	GPIO_FN_A1,	GPIO_FN_A0,
+
+	/* PTY (mobule: LBSC) */
+	GPIO_FN_D7,	GPIO_FN_D6,	GPIO_FN_D5,	GPIO_FN_D4,
+	GPIO_FN_D3,	GPIO_FN_D2,	GPIO_FN_D1,	GPIO_FN_D0,
+};
+
+#endif /* __ASM_SH7757_H__ */
diff --git a/arch/sh/include/cpu-sh5/cpu/cacheflush.h b/arch/sh/include/cpu-sh5/cpu/cacheflush.h
deleted file mode 100644
index 5a11f0b..0000000
--- a/arch/sh/include/cpu-sh5/cpu/cacheflush.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __ASM_SH_CPU_SH5_CACHEFLUSH_H
-#define __ASM_SH_CPU_SH5_CACHEFLUSH_H
-
-#ifndef __ASSEMBLY__
-
-struct vm_area_struct;
-struct page;
-struct mm_struct;
-
-extern void flush_cache_all(void);
-extern void flush_cache_mm(struct mm_struct *mm);
-extern void flush_cache_sigtramp(unsigned long vaddr);
-extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-			      unsigned long end);
-extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
-extern void flush_dcache_page(struct page *pg);
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
-				    struct page *page, unsigned long addr,
-				    int len);
-
-#define flush_cache_dup_mm(mm)	flush_cache_mm(mm)
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-#define flush_icache_page(vma, page)	do { } while (0)
-void p3_cache_init(void);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_SH_CPU_SH5_CACHEFLUSH_H */
-
diff --git a/arch/sh/include/mach-common/mach/migor.h b/arch/sh/include/mach-common/mach/migor.h
deleted file mode 100644
index e451f02..0000000
--- a/arch/sh/include/mach-common/mach/migor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef __ASM_SH_MIGOR_H
-#define __ASM_SH_MIGOR_H
-
-/*
- * linux/include/asm-sh/migor.h
- *
- * Copyright (C) 2008 Renesas Solutions
- *
- * Portions Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * 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.
- *
- */
-#include <asm/addrspace.h>
-
-/* GPIO */
-#define PORT_PACR 0xa4050100
-#define PORT_PDCR 0xa4050106
-#define PORT_PECR 0xa4050108
-#define PORT_PHCR 0xa405010e
-#define PORT_PJCR 0xa4050110
-#define PORT_PKCR 0xa4050112
-#define PORT_PLCR 0xa4050114
-#define PORT_PMCR 0xa4050116
-#define PORT_PRCR 0xa405011c
-#define PORT_PTCR 0xa4050140
-#define PORT_PUCR 0xa4050142
-#define PORT_PVCR 0xa4050144
-#define PORT_PWCR 0xa4050146
-#define PORT_PXCR 0xa4050148
-#define PORT_PYCR 0xa405014a
-#define PORT_PZCR 0xa405014c
-#define PORT_PADR 0xa4050120
-#define PORT_PHDR 0xa405012e
-#define PORT_PTDR 0xa4050160
-#define PORT_PWDR 0xa4050166
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRC 0xa405015c
-
-#define PORT_MSELCRB 0xa4050182
-
-#define PORT_PSELA 0xa405014e
-#define PORT_PSELB 0xa4050150
-#define PORT_PSELC 0xa4050152
-#define PORT_PSELD 0xa4050154
-#define PORT_PSELE 0xa4050156
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRB 0xa405015a
-#define PORT_HIZCRC 0xa405015c
-
-#define BSC_CS4BCR 0xfec10010
-#define BSC_CS6ABCR 0xfec1001c
-#define BSC_CS4WCR 0xfec10030
-
-#include <video/sh_mobile_lcdc.h>
-
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
-			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-
-#endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h
new file mode 100644
index 0000000..267e241
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/romimage.h
@@ -0,0 +1 @@
+/* do nothing here by default */
diff --git a/arch/sh/include/mach-common/mach/sh7785lcr.h b/arch/sh/include/mach-common/mach/sh7785lcr.h
index 90011d4..1292ae5 100644
--- a/arch/sh/include/mach-common/mach/sh7785lcr.h
+++ b/arch/sh/include/mach-common/mach/sh7785lcr.h
@@ -35,6 +35,8 @@
 #define PCA9564_ADDR		0x06000000	/* I2C */
 #define PCA9564_SIZE		0x00000100
 
+#define PCA9564_PROTO_32BIT_ADDR	0x14000000
+
 #define SM107_MEM_ADDR		0x10000000
 #define SM107_MEM_SIZE		0x00e00000
 #define SM107_REG_ADDR		0x13e00000
diff --git a/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
new file mode 100644
index 0000000..8b8e4fa
--- /dev/null
+++ b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
@@ -0,0 +1,82 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2009 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <morimoto.kuninori@renesas.com>"
+LIST "--------------------------------"
+LIST "zImage (RAM boot)"
+LIST "This script can be used to boot the kernel from RAM via JTAG:"
+LIST "> < partner-jet-setup.txt"
+LIST "> RD zImage, 0xa8800000"
+LIST "> G=0xa8800000"
+LIST "--------------------------------"
+LIST "romImage (Flash boot)"
+LIST "Use the following command to burn the zImage to flash via JTAG:"
+LIST "> RD romImage, 0"
+LIST "--------------------------------"
+
+LIST "disable watchdog"
+EW 0xa4520004, 0xa507
+
+LIST "MMU"
+ED 0xff000010, 0x00000004
+
+LIST "setup clocks"
+ED 0xa4150024, 0x00004000
+ED 0xa4150000, 0x8E003508
+ED 0xa4150004, 0x00000000
+
+WAIT 1
+
+LIST "BSC"
+ED 0xff800020, 0xa5a50000
+ED 0xfec10000, 0x00000013
+ED 0xfec10004, 0x11110400
+ED 0xfec10024, 0x00000440
+
+WAIT 1
+
+LIST "setup sdram"
+ED 0xfd000108, 0x00000181
+ED 0xfd000020, 0x015B0002
+ED 0xfd000030, 0x03061502
+ED 0xfd000034, 0x02020102
+ED 0xfd000038, 0x01090305
+ED 0xfd00003c, 0x00000002
+ED 0xfd000008, 0x00000005
+ED 0xfd000018, 0x00000001
+
+WAIT 1
+
+ED 0xfd000014, 0x00000002
+ED 0xfd000060, 0x00020000
+ED 0xfd000060, 0x00030000
+ED 0xfd000060, 0x00010040
+ED 0xfd000060, 0x00000532
+ED 0xfd000014, 0x00000002
+ED 0xfd000014, 0x00000004
+ED 0xfd000014, 0x00000004
+ED 0xfd000060, 0x00000432
+ED 0xfd000060, 0x000103C0
+ED 0xfd000060, 0x00010040
+
+WAIT 1
+
+ED 0xfd000010, 0x00000001
+ED 0xfd000044, 0x00000613
+ED 0xfd000048, 0x238C003A
+ED 0xfd000014, 0x00000002
+
+LIST "Dummy read"
+DD 0x0c400000, 0x0c400000
+
+ED 0xfd000014, 0x00000002
+ED 0xfd000014, 0x00000004
+ED 0xfd000108, 0x00000080
+ED 0xfd000040, 0x00010000
+
+WAIT 1
+
+LIST "setup cache"
+ED 0xff00001c, 0x0000090b
+
+LIST "disable USB"
+EW 0xA4D80000, 0x0000
diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h
new file mode 100644
index 0000000..1c8787e
--- /dev/null
+++ b/arch/sh/include/mach-ecovec24/mach/romimage.h
@@ -0,0 +1,20 @@
+/* EcoVec board specific boot code:
+ * converts the "partner-jet-script.txt" script into assembly
+ * the assembly code is the first code to be executed in the romImage
+ */
+
+#include <asm/romimage-macros.h>
+#include "partner-jet-setup.txt"
+
+	/* execute icbi after enabling cache */
+	mov.l	1f, r0
+	icbi	@r0
+
+	/* jump to cached area */
+	mova	2f, r0
+	jmp	@r0
+	nop
+
+	.align 2
+1 :	.long 0xa8000000
+2 :
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
new file mode 100644
index 0000000..174374e
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_KFR2R09_H
+#define __ASM_SH_KFR2R09_H
+
+#include <video/sh_mobile_lcdc.h>
+
+#ifdef CONFIG_FB_SH_MOBILE_LCDC
+void kfr2r09_lcd_on(void *board_data);
+void kfr2r09_lcd_off(void *board_data);
+int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+		      struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+#else
+static inline void kfr2r09_lcd_on(void *board_data) {}
+static inline void kfr2r09_lcd_off(void *board_data) {}
+static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+				    struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __ASM_SH_KFR2R09_H */
diff --git a/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
new file mode 100644
index 0000000..3a65503
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
@@ -0,0 +1,143 @@
+LIST "partner-jet-setup.txt - 20090729 Magnus Damm"
+LIST "set up enough of the kfr2r09 hardware to boot the kernel"
+
+LIST "zImage (RAM boot)"
+LIST "This script can be used to boot the kernel from RAM via JTAG:"
+LIST "> < partner-jet-setup.txt"
+LIST "> RD zImage, 0xa8800000"
+LIST "> G=0xa8800000"
+
+LIST "romImage (Flash boot)"
+LIST "Use the following command to burn the zImage to flash via JTAG:"
+LIST "> RD romImage, 0"
+
+LIST "--------------------------------"
+
+LIST "disable watchdog"
+EW 0xa4520004, 0xa507
+
+LIST "invalidate instruction cache"
+ED 0xff00001c, 0x00000800
+
+LIST "invalidate TLBs"
+ED 0xff000010, 0x00000004
+
+LIST "select mode for cs5 + cs6"
+ED 0xff800020, 0xa5a50001
+ED 0xfec10000, 0x0000001b
+
+LIST "setup clocks"
+LIST "The PLL and FLL values are updated here for the optimal"
+LIST "RF frequency and improved reception sensitivity."
+ED 0xa4150004, 0x00000050
+ED 0xa4150000, 0x91053508
+WAIT 1
+ED 0xa4150050, 0x00000340
+ED 0xa4150024, 0x00005000
+
+LIST "setup pins"
+EB 0xa4050120, 0x00
+EB 0xa4050122, 0x00
+EB 0xa4050124, 0x00
+EB 0xa4050126, 0x00
+EB 0xa4050128, 0xA0
+EB 0xa405012A, 0x10
+EB 0xa405012C, 0x00
+EB 0xa405012E, 0x00
+EB 0xa4050130, 0x00
+EB 0xa4050132, 0x00
+EB 0xa4050134, 0x01
+EB 0xa4050136, 0x40
+EB 0xa4050138, 0x00
+EB 0xa405013A, 0x00
+EB 0xa405013C, 0x00
+EB 0xa405013E, 0x20
+EB 0xa4050160, 0x00
+EB 0xa4050162, 0x40
+EB 0xa4050164, 0x03
+EB 0xa4050166, 0x00
+EB 0xa4050168, 0x00
+EB 0xa405016A, 0x00
+EB 0xa405016C, 0x00
+
+EW 0xa405014E, 0x5660
+EW 0xa4050150, 0x0145
+EW 0xa4050152, 0x1550
+EW 0xa4050154, 0x0200
+EW 0xa4050156, 0x0040
+
+EW 0xa4050158, 0x0000
+EW 0xa405015a, 0x0000
+EW 0xa405015c, 0x0000
+EW 0xa405015e, 0x0000
+
+EW 0xa4050180, 0x0000
+EW 0xa4050182, 0x8002
+EW 0xa4050184, 0x0000
+
+EW 0xa405018a, 0x9991
+EW 0xa405018c, 0x8011
+EW 0xa405018e, 0x9550
+
+EW 0xa4050100, 0x0000
+EW 0xa4050102, 0x5540
+EW 0xa4050104, 0x0000
+EW 0xa4050106, 0x0000
+EW 0xa4050108, 0x4550
+EW 0xa405010a, 0x0130
+EW 0xa405010c, 0x0555
+EW 0xa405010e, 0x0000
+EW 0xa4050110, 0x0000
+EW 0xa4050112, 0xAAA8
+EW 0xa4050114, 0x8305
+EW 0xa4050116, 0x10F0
+EW 0xa4050118, 0x0F50
+EW 0xa405011a, 0x0000
+EW 0xa405011c, 0x0000
+EW 0xa405011e, 0x0555
+EW 0xa4050140, 0x0000
+EW 0xa4050142, 0x5141
+EW 0xa4050144, 0x5005
+EW 0xa4050146, 0xAAA9
+EW 0xa4050148, 0xFAA9
+EW 0xa405014a, 0x3000
+EW 0xa405014c, 0x0000
+
+LIST "setup sdram"
+ED 0xFD000108, 0x40000301
+ED 0xFD000020, 0x011B0002
+ED 0xFD000030, 0x03060E02
+ED 0xFD000034, 0x01020102
+ED 0xFD000038, 0x01090406
+ED 0xFD000008, 0x00000004
+ED 0xFD000040, 0x00000001
+ED 0xFD000040, 0x00000000
+ED 0xFD000018, 0x00000001
+
+WAIT 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000060, 0x00000032
+ED 0xFD000060, 0x00020000
+ED 0xFD000014, 0x00000004
+ED 0xFD000014, 0x00000004
+ED 0xFD000010, 0x00000001
+ED 0xFD000044, 0x000004AF
+ED 0xFD000048, 0x20CF0037
+
+LIST "read 16 bytes from sdram"
+DD 0xa8000000, 0xa8000000, 1
+DD 0xa8000004, 0xa8000004, 1
+DD 0xa8000008, 0xa8000008, 1
+DD 0xa800000c, 0xa800000c, 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000014, 0x00000004
+ED 0xFD000108, 0x40000300
+ED 0xFD000040, 0x00010000
+
+LIST "write to internal ram"
+ED 0xfd8007fc, 0
+
+LIST "setup cache"
+ED 0xff00001c, 0x0000090b
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
new file mode 100644
index 0000000..a110823
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h
@@ -0,0 +1,20 @@
+/* kfr2r09 board specific boot code:
+ * converts the "partner-jet-script.txt" script into assembly
+ * the assembly code is the first code to be executed in the romImage
+ */
+
+#include <asm/romimage-macros.h>
+#include "partner-jet-setup.txt"
+
+	/* execute icbi after enabling cache */
+	mov.l	1f, r0
+	icbi	@r0
+
+	/* jump to cached area */
+	mova	2f, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+1:	.long 0xa8000000
+2:
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
new file mode 100644
index 0000000..cee6cb8
--- /dev/null
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_SH_MIGOR_H
+#define __ASM_SH_MIGOR_H
+
+#define PORT_MSELCRB 0xa4050182
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS6ABCR 0xfec1001c
+#define BSC_CS4WCR 0xfec10030
+
+#include <video/sh_mobile_lcdc.h>
+
+int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+
+#endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 349d833..a2d0a40 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -1,5 +1,41 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/kernel/Makefile_32
-else
-include ${srctree}/arch/sh/kernel/Makefile_64
+#
+# Makefile for the Linux/SuperH kernel.
+#
+
+extra-y	:= head_$(BITS).o init_task.o vmlinux.lds
+
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
 endif
+
+obj-y	:= debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o	\
+	   machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o	\
+	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
+	   syscalls_$(BITS).o time.o topology.o traps.o			\
+	   traps_$(BITS).o unwinder.o
+
+obj-y				+= cpu/
+obj-$(CONFIG_VSYSCALL)		+= vsyscall/
+obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
+obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
+obj-$(CONFIG_MODULES)		+= sh_ksyms_$(BITS).o module.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o
+obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
+obj-$(CONFIG_HIBERNATION)	+= swsusp.o
+obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
+
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
deleted file mode 100644
index 9411e3e..0000000
--- a/arch/sh/kernel/Makefile_32
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Makefile for the Linux/SuperH kernel.
-#
-
-extra-y	:= head_32.o init_task.o vmlinux.lds
-
-ifdef CONFIG_FUNCTION_TRACER
-# Do not profile debug and lowlevel utilities
-CFLAGS_REMOVE_ftrace.o = -pg
-endif
-
-obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o			\
-	   machvec.o process_32.o ptrace_32.o setup.o signal_32.o	\
-	   sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o	\
-	   traps.o traps_32.o
-
-obj-y				+= cpu/
-obj-$(CONFIG_VSYSCALL)		+= vsyscall/
-obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
-obj-$(CONFIG_KGDB)		+= kgdb.o
-obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
-obj-$(CONFIG_MODULES)		+= sh_ksyms_32.o module.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
-obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
-obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
-obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
-obj-$(CONFIG_HIBERNATION)	+= swsusp.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
deleted file mode 100644
index 67b9f6c..0000000
--- a/arch/sh/kernel/Makefile_64
+++ /dev/null
@@ -1,19 +0,0 @@
-extra-y	:= head_64.o init_task.o vmlinux.lds
-
-obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
-	   ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
-	   syscalls_64.o time.o topology.o traps.o traps_64.o
-
-obj-y				+= cpu/
-obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
-obj-$(CONFIG_MODULES)		+= sh_ksyms_64.o module.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index 99aceb28..d218e80 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -26,6 +26,7 @@
 	DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
 	DEFINE(TI_PRE_COUNT,	offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
+	DEFINE(TI_SIZE,		sizeof(struct thread_info));
 
 #ifdef CONFIG_HIBERNATION
 	DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index eecad7c..3d6b931 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -19,4 +19,4 @@
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG)	+= clock-cpg.o
 
-obj-y	+= irq/ init.o clock.o
+obj-y	+= irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
new file mode 100644
index 0000000..c0ad7d4
--- /dev/null
+++ b/arch/sh/kernel/cpu/hwblk.c
@@ -0,0 +1,155 @@
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <asm/clock.h>
+
+static DEFINE_SPINLOCK(hwblk_lock);
+
+static void hwblk_area_mod_cnt(struct hwblk_info *info,
+			       int area, int counter, int value, int goal)
+{
+	struct hwblk_area *hap = info->areas + area;
+
+	hap->cnt[counter] += value;
+
+	if (hap->cnt[counter] != goal)
+		return;
+
+	if (hap->flags & HWBLK_AREA_FLAG_PARENT)
+		hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
+}
+
+
+static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+			  int counter, int value, int goal)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+
+	hp->cnt[counter] += value;
+	if (hp->cnt[counter] == goal)
+		hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
+
+	return hp->cnt[counter];
+}
+
+static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+			  int counter, int value, int goal)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+	__hwblk_mod_cnt(info, hwblk, counter, value, goal);
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
+{
+	hwblk_mod_cnt(info, hwblk, counter, 1, 1);
+}
+
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
+{
+	hwblk_mod_cnt(info, hwblk, counter, -1, 0);
+}
+
+void hwblk_enable(struct hwblk_info *info, int hwblk)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+	unsigned long tmp;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+
+	ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
+	if (ret == 1) {
+		tmp = __raw_readl(hp->mstp);
+		tmp &= ~(1 << hp->bit);
+		__raw_writel(tmp, hp->mstp);
+	}
+
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_disable(struct hwblk_info *info, int hwblk)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+	unsigned long tmp;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+
+	ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
+	if (ret == 0) {
+		tmp = __raw_readl(hp->mstp);
+		tmp |= 1 << hp->bit;
+		__raw_writel(tmp, hp->mstp);
+	}
+
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+struct hwblk_info *hwblk_info;
+
+int __init hwblk_register(struct hwblk_info *info)
+{
+	hwblk_info = info;
+	return 0;
+}
+
+int __init __weak arch_hwblk_init(void)
+{
+	return 0;
+}
+
+int __weak arch_hwblk_sleep_mode(void)
+{
+	return SUSP_SH_SLEEP;
+}
+
+int __init hwblk_init(void)
+{
+	return arch_hwblk_init();
+}
+
+/* allow clocks to enable and disable hardware blocks */
+static int sh_hwblk_clk_enable(struct clk *clk)
+{
+	if (!hwblk_info)
+		return -ENOENT;
+
+	hwblk_enable(hwblk_info, clk->arch_flags);
+	return 0;
+}
+
+static void sh_hwblk_clk_disable(struct clk *clk)
+{
+	if (hwblk_info)
+		hwblk_disable(hwblk_info, clk->arch_flags);
+}
+
+static struct clk_ops sh_hwblk_clk_ops = {
+	.enable		= sh_hwblk_clk_enable,
+	.disable	= sh_hwblk_clk_disable,
+	.recalc		= followparent_recalc,
+};
+
+int __init sh_hwblk_clk_register(struct clk *clks, int nr)
+{
+	struct clk *clkp;
+	int ret = 0;
+	int k;
+
+	for (k = 0; !ret && (k < nr); k++) {
+		clkp = clks + k;
+		clkp->ops = &sh_hwblk_clk_ops;
+		ret |= clk_register(clkp);
+	}
+
+	return ret;
+}
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index ad85421..e932ebe 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -3,7 +3,7 @@
  *
  * CPU init code
  *
- * Copyright (C) 2002 - 2007  Paul Mundt
+ * Copyright (C) 2002 - 2009  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -62,6 +62,37 @@
 #define speculative_execution_init()	do { } while (0)
 #endif
 
+#ifdef CONFIG_CPU_SH4A
+#define EXPMASK			0xff2f0004
+#define EXPMASK_RTEDS		(1 << 0)
+#define EXPMASK_BRDSSLP		(1 << 1)
+#define EXPMASK_MMCAW		(1 << 4)
+
+static void __init expmask_init(void)
+{
+	unsigned long expmask = __raw_readl(EXPMASK);
+
+	/*
+	 * Future proofing.
+	 *
+	 * Disable support for slottable sleep instruction
+	 * and non-nop instructions in the rte delay slot.
+	 */
+	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
+
+	/*
+	 * Enable associative writes to the memory-mapped cache array
+	 * until the cache flush ops have been rewritten.
+	 */
+	expmask |= EXPMASK_MMCAW;
+
+	__raw_writel(expmask, EXPMASK);
+	ctrl_barrier();
+}
+#else
+#define expmask_init()	do { } while (0)
+#endif
+
 /* 2nd-level cache init */
 void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
 {
@@ -268,11 +299,9 @@
 	cache_init();
 
 	if (raw_smp_processor_id() == 0) {
-#ifdef CONFIG_MMU
 		shm_align_mask = max_t(unsigned long,
 				       current_cpu_data.dcache.way_size - 1,
 				       PAGE_SIZE - 1);
-#endif
 
 		/* Boot CPU sets the cache shape */
 		detect_cache_shape();
@@ -321,4 +350,5 @@
 #endif
 
 	speculative_execution_init();
+	expmask_init();
 }
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 808d99a..c1508a9 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -35,6 +35,7 @@
 	unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
 	/* Set the priority in IPR to 0 */
 	__raw_writew(__raw_readw(addr) & (0xffff ^ (0xf << p->shift)), addr);
+	(void)__raw_readw(addr);	/* Read back to flush write posting */
 }
 
 static void enable_ipr_irq(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index becc54c45..c8a4331 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -227,8 +227,9 @@
 	mov.l	@r15+, r14
 	add	#8,r15
 	lds.l	@r15+, pr
+	mov.l	@r15+,r15
 	rte
-	 mov.l	@r15+,r15
+	 nop
 	.align	2
 1:	.long	gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index 5916d90..1db6d888 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -29,6 +29,7 @@
 	 */
 	boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
 	boot_cpu_data.icache = boot_cpu_data.dcache;
+	boot_cpu_data.family = CPU_FAMILY_SH2;
 
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index ab3903e..222742d 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -176,8 +176,9 @@
 	movml.l	@r15+,r14
 	add	#8,r15
 	lds.l	@r15+, pr
+	mov.l	@r15+,r15
 	rte
-	 mov.l	@r15+,r15
+	 nop
 	.align	2
 1:	.long	gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index e098e2f..6825d65 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -15,6 +15,8 @@
 
 int __init detect_cpu_and_cache_system(void)
 {
+	boot_cpu_data.family			= CPU_FAMILY_SH2A;
+
 	/* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
 	boot_cpu_data.flags			|= CPU_HAS_OP32;
 
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
index fa30b60..e874950 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
@@ -22,13 +22,6 @@
 static int ifc_divisors[]    = { 1, 2, 4, 1, 3, 1, 1, 1 };
 static int pfc_divisors[]    = { 1, 2, 4, 1, 3, 6, 1, 1 };
 
-static void set_bus_parent(struct clk *clk)
-{
-	struct clk *bus_clk = clk_get(NULL, "bus_clk");
-	clk->parent = bus_clk;
-	clk_put(bus_clk);
-}
-
 static void master_clk_init(struct clk *clk)
 {
 	int frqcr = ctrl_inw(FRQCR);
@@ -50,9 +43,6 @@
 }
 
 static struct clk_ops sh7709_module_clk_ops = {
-#ifdef CLOCK_MODE_0_1_2_7
-	.init		= set_bus_parent,
-#endif
 	.recalc		= module_clk_recalc,
 };
 
@@ -78,7 +68,6 @@
 }
 
 static struct clk_ops sh7709_cpu_clk_ops = {
-	.init		= set_bus_parent,
 	.recalc		= cpu_clk_recalc,
 };
 
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 3cb531f..0151933 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -53,10 +53,6 @@
  *	syscall #
  *
  */
-#if defined(CONFIG_KGDB)
-NMI_VEC = 0x1c0			! Must catch early for debounce
-#endif
-
 /* Offsets to the stack */
 OFF_R0  =  0		/* Return value. New ABI also arg4 */
 OFF_R1  =  4     	/* New ABI: arg5 */
@@ -71,7 +67,6 @@
 OFF_SR	=  (16*4+8)
 OFF_TRA	=  (16*4+6*4)
 
-
 #define k0	r0
 #define k1	r1
 #define k2	r2
@@ -113,34 +108,34 @@
 #if defined(CONFIG_MMU)
 	.align	2
 ENTRY(tlb_miss_load)
-	bra	call_dpf
+	bra	call_handle_tlbmiss
 	 mov	#0, r5
 
 	.align	2
 ENTRY(tlb_miss_store)
-	bra	call_dpf
+	bra	call_handle_tlbmiss
 	 mov	#1, r5
 
 	.align	2
 ENTRY(initial_page_write)
-	bra	call_dpf
-	 mov	#1, r5
+	bra	call_handle_tlbmiss
+	 mov	#2, r5
 
 	.align	2
 ENTRY(tlb_protection_violation_load)
-	bra	call_dpf
+	bra	call_do_page_fault
 	 mov	#0, r5
 
 	.align	2
 ENTRY(tlb_protection_violation_store)
-	bra	call_dpf
+	bra	call_do_page_fault
 	 mov	#1, r5
 
-call_dpf:
+call_handle_tlbmiss:
+	setup_frame_reg
 	mov.l	1f, r0
 	mov	r5, r8
 	mov.l	@r0, r6
-	mov	r6, r9
 	mov.l	2f, r0
 	sts	pr, r10
 	jsr	@r0
@@ -151,16 +146,25 @@
 	 lds	r10, pr
 	rts
 	 nop
-0:	mov.l	3f, r0
-	mov	r9, r6
+0:
 	mov	r8, r5
+call_do_page_fault:
+	mov.l	1f, r0
+	mov.l	@r0, r6
+
+	sti
+
+	mov.l	3f, r0
+	mov.l	4f, r1
+	mov	r15, r4
 	jmp	@r0
-	 mov	r15, r4
+	 lds	r1, pr
 
 	.align 2
 1:	.long	MMU_TEA
-2:	.long	__do_page_fault
+2:	.long	handle_tlbmiss
 3:	.long	do_page_fault
+4:	.long	ret_from_exception
 
 	.align	2
 ENTRY(address_error_load)
@@ -256,7 +260,7 @@
 	!
 	! Calculate new SR value
 	mov	k3, k2			! original SR value
-	mov	#0xf0, k1
+	mov	#0xfffffff0, k1
 	extu.b	k1, k1
 	not	k1, k1
 	and	k1, k2			! Mask original SR value
@@ -272,21 +276,12 @@
 6:	or	k0, k2			! Set the IMASK-bits
 	ldc	k2, ssr
 	!
-#if defined(CONFIG_KGDB)
-	! Clear in_nmi
-	mov.l	6f, k0
-	mov	#0, k1
-	mov.b	k1, @k0
-#endif
 	mov	k4, r15
 	rte
 	 nop
 
 	.align	2
 5:	.long	0x00001000	! DSP
-#ifdef CONFIG_KGDB
-6:	.long	in_nmi
-#endif
 7:	.long	0x30000000
 
 ! common exception handler
@@ -478,23 +473,6 @@
 !
 	.balign 	512,0,512
 ENTRY(handle_interrupt)
-#if defined(CONFIG_KGDB)
-	mov.l	2f, k2
-	! Debounce (filter nested NMI)
-	mov.l	@k2, k0
-	mov.l	9f, k1
-	cmp/eq	k1, k0
-	bf	11f
-	mov.l	10f, k1
-	tas.b	@k1
-	bt	11f
-	rte
-	 nop
-	.align	2
-9:	.long	NMI_VEC
-10:	.long	in_nmi
-11:
-#endif /* defined(CONFIG_KGDB) */
 	sts	pr, k3		! save original pr value in k3
 	mova	exception_data, k0
 
@@ -507,13 +485,49 @@
 	bsr	save_regs	! needs original pr value in k3
 	 mov	#-1, k2		! default vector kept in k2
 
+	setup_frame_reg
+
+	stc	sr, r0	! get status register
+	shlr2	r0
+	and	#0x3c, r0
+	cmp/eq	#0x3c, r0
+	bf	9f
+	TRACE_IRQS_OFF
+9:
+
 	! Setup return address and jump to do_IRQ
 	mov.l	4f, r9		! fetch return address
 	lds	r9, pr		! put return address in pr
 	mov.l	2f, r4
 	mov.l	3f, r9
 	mov.l	@r4, r4		! pass INTEVT vector as arg0
+
+	shlr2	r4
+	shlr	r4
+	mov	r4, r0		! save vector->jmp table offset for later
+
+	shlr2	r4		! vector to IRQ# conversion
+	add	#-0x10, r4
+
+	cmp/pz	r4		! is it a valid IRQ?
+	bt	10f
+
+	/*
+	 * We got here as a result of taking the INTEVT path for something
+	 * that isn't a valid hard IRQ, therefore we bypass the do_IRQ()
+	 * path and special case the event dispatch instead.  This is the
+	 * expected path for the NMI (and any other brilliantly implemented
+	 * exception), which effectively wants regular exception dispatch
+	 * but is unfortunately reported through INTEVT rather than
+	 * EXPEVT.  Grr.
+	 */
+	mov.l	6f, r9
+	mov.l	@(r0, r9), r9
 	jmp	@r9
+	 mov	r15, r8		! trap handlers take saved regs in r8
+
+10:
+	jmp	@r9		! Off to do_IRQ() we go.
 	 mov	r15, r5		! pass saved registers as arg1
 
 ENTRY(exception_none)
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index e5a0de3..46610c3 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -48,9 +48,7 @@
 	.long	system_call	! Unconditional Trap	 /* 160 */
 	.long	exception_error	! reserved_instruction (filled by trap_init) /* 180 */
 	.long	exception_error	! illegal_slot_instruction (filled by trap_init) /*1A0*/
-ENTRY(nmi_slot)
-	.long	kgdb_handle_exception	/* 1C0 */	! Allow trap to debugger
-ENTRY(user_break_point_trap)
+	.long	nmi_trap_handler	/* 1C0 */	! Allow trap to debugger
 	.long	break_point_trap	/* 1E0 */
 
 	/*
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 10f2a76..f9c7df6 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -107,5 +107,7 @@
 	boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
 	boot_cpu_data.icache = boot_cpu_data.dcache;
 
+	boot_cpu_data.family = CPU_FAMILY_SH3;
+
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 6c78d0a..d36f0c4 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -57,8 +57,12 @@
 	 * Setup some generic flags we can probe on SH-4A parts
 	 */
 	if (((pvr >> 16) & 0xff) == 0x10) {
-		if ((cvr & 0x10000000) == 0)
+		boot_cpu_data.family = CPU_FAMILY_SH4A;
+
+		if ((cvr & 0x10000000) == 0) {
 			boot_cpu_data.flags |= CPU_HAS_DSP;
+			boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP;
+		}
 
 		boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
 		boot_cpu_data.cut_major = pvr & 0x7f;
@@ -68,6 +72,7 @@
 	} else {
 		/* And some SH-4 defaults.. */
 		boot_cpu_data.flags |= CPU_HAS_PTEA;
+		boot_cpu_data.family = CPU_FAMILY_SH4;
 	}
 
 	/* FPU detection works for everyone */
@@ -139,8 +144,15 @@
 		}
 		break;
 	case 0x300b:
-		boot_cpu_data.type = CPU_SH7724;
-		boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
+		switch (prr) {
+		case 0x20:
+			boot_cpu_data.type = CPU_SH7724;
+			boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
+			break;
+		case 0x50:
+			boot_cpu_data.type = CPU_SH7757;
+			break;
+		}
 		break;
 	case 0x4000:	/* 1st cut */
 	case 0x4001:	/* 2nd cut */
@@ -173,9 +185,6 @@
 		boot_cpu_data.dcache.ways = 2;
 
 		break;
-	default:
-		boot_cpu_data.type = CPU_SH_NONE;
-		break;
 	}
 
 	/*
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index ebdd391..490d5dc 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -3,6 +3,7 @@
 #
 
 # CPU subtype setup
+obj-$(CONFIG_CPU_SUBTYPE_SH7757)	+= setup-sh7757.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7763)	+= setup-sh7763.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7770)	+= setup-sh7770.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= setup-sh7780.o
@@ -19,15 +20,16 @@
 smp-$(CONFIG_CPU_SHX3)			:= smp-shx3.o
 
 # Primary on-chip clocks (common)
+clock-$(CONFIG_CPU_SUBTYPE_SH7757)	:= clock-sh7757.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7763)	:= clock-sh7763.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7770)	:= clock-sh7770.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7780)	:= clock-sh7780.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7785)	:= clock-sh7785.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7786)	:= clock-sh7786.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7343)	:= clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722)	:= clock-sh7722.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7723)	:= clock-sh7723.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7724)	:= clock-sh7724.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722)	:= clock-sh7722.o hwblk-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7723)	:= clock-sh7723.o hwblk-sh7723.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7724)	:= clock-sh7724.o hwblk-sh7724.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7366)	:= clock-sh7366.o
 clock-$(CONFIG_CPU_SUBTYPE_SHX3)	:= clock-shx3.o
 
@@ -35,6 +37,7 @@
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7722)	:= pinmux-sh7722.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7723)	:= pinmux-sh7723.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7724)	:= pinmux-sh7724.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7757)	:= pinmux-sh7757.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 40f8593..ea38b55 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
 
 /* SH7722 registers */
 #define FRQCR		0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define DLLFRQ		0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,35 +139,37 @@
 	SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
+#define R_CLK &r_clk
+#define P_CLK &div4_clks[DIV4_P]
+#define B_CLK &div4_clks[DIV4_B]
+#define U_CLK &div4_clks[DIV4_U]
 
 static struct clk mstp_clks[] = {
-	MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
-	MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
-	MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
+	SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
 
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 8, 0),
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
 
-	MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
-	MSTP("keysc0", &r_clk, MSTPCR2, 14, 0),
-	MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 9, 0),
-	MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
-	MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
+	SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0),
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -191,7 +192,7 @@
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index e67c267..20a31c2 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
 
 /* SH7723 registers */
 #define FRQCR		0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define DLLFRQ		0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,60 +139,64 @@
 	SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define U_CLK (&div4_clks[DIV4_U])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
 	/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
-	MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-	MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-	MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-	MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 28, 1, 1, 0),
-	MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-	MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-	MSTP("intc0", &div4_clks[DIV4_I], MSTPCR0, 22, 1, 1, 0),
-	MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-	MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-	MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-	MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-	MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-	MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 11, 0, 1, 0),
-	MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-	MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-	MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-	MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-	MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-	MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
-	MSTP("meram0", &div4_clks[DIV4_SH], MSTPCR0, 0, 1, 1, 0),
+	SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+	SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+	SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+	SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+	SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+	SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+	SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+	SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+	SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+	SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
+	SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0),
 
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 8, 0, 0, 0),
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
 
-	MSTP("atapi0", &div4_clks[DIV4_SH], MSTPCR2, 28, 0, 1, 0),
-	MSTP("adc0", &div4_clks[DIV4_P], MSTPCR2, 27, 0, 1, 0),
-	MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-	MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-	MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-	MSTP("icb0", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-	MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-	MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-	MSTP("keysc0", &r_clk, MSTPCR2, 14, 0, 0, 0),
-	MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 11, 0, 1, 0),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 10, 0, 1, 1),
-	MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0, 1, 0),
-	MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+	SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0),
+	SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0),
+	SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+	SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+	SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+	SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+	SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+	SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -216,7 +219,7 @@
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 5d5c9b9..dfe9192 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
 
 /* SH7724 registers */
 #define FRQCRA		0xa4150000
@@ -31,9 +33,6 @@
 #define FCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define SPUCLKCR	0xa415003c
 #define FLLFRQ		0xa4150050
 #define LSTATS		0xa4150060
@@ -128,7 +127,7 @@
 	&div3_clk,
 };
 
-static int divisors[] = { 2, 0, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
 
 static struct clk_div_mult_table div4_table = {
 	.divisors = divisors,
@@ -156,64 +155,67 @@
 	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
-	MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-	MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-	MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-	MSTP("rs0", &div4_clks[DIV4_B], MSTPCR0, 28, 1, 1, 0),
-	MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-	MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 26, 1, 1, 0),
-	MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-	MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 1, 1, 0),
-	MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-	MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-	MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-	MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-	MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-	MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-	MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-	MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-	MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-	MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-	MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
+	SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+	SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+	SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+	SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+	SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+	SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+	SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+	SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+	SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
 
-	MSTP("keysc0", &r_clk, MSTPCR1, 12, 0, 0, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 11, 0, 0, 0),
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-	MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0, 1, 0),
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0),
+	SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0),
 
-	MSTP("mmc0", &div4_clks[DIV4_B], MSTPCR2, 29, 0, 1, 0),
-	MSTP("eth0", &div4_clks[DIV4_B], MSTPCR2, 28, 0, 1, 0),
-	MSTP("atapi0", &div4_clks[DIV4_B], MSTPCR2, 26, 0, 1, 0),
-	MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-	MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-	MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-	MSTP("usb1", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-	MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 20, 0, 1, 1),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 19, 0, 1, 1),
-	MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-	MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-	MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 15, 1, 1, 1),
-	MSTP("ceu1", &div4_clks[DIV4_B], MSTPCR2, 13, 0, 1, 1),
-	MSTP("beu1", &div4_clks[DIV4_B], MSTPCR2, 12, 0, 1, 1),
-	MSTP("2ddmac0", &div4_clks[DIV4_SH], MSTPCR2, 10, 0, 1, 1),
-	MSTP("spu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0, 1, 0),
-	MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+	SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0),
+	SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0),
+	SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0),
+	SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+	SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+	SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+	SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0),
+	SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+	SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+	SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, 0),
+	SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0),
+	SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0),
+	SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0),
+	SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0),
+	SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -236,7 +238,7 @@
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
new file mode 100644
index 0000000..ddc235c
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -0,0 +1,130 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh7757.c
+ *
+ * SH7757 support for the clock framework
+ *
+ *  Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+
+static int ifc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int sfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int bfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int p1fc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			       16, 1, 1, 32, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate = CONFIG_SH_PCLK_FREQ * 16;
+}
+
+static struct clk_ops sh7757_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = ctrl_inl(FRQCR) & 0x0000000f;
+	clk->rate = clk->parent->rate / p1fc_divisors[idx];
+}
+
+static struct clk_ops sh7757_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f;
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7757_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f;
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7757_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7757_clk_ops[] = {
+	&sh7757_master_clk_ops,
+	&sh7757_module_clk_ops,
+	&sh7757_bus_clk_ops,
+	&sh7757_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7757_clk_ops))
+		*ops = sh7757_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f;
+	clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7757_shyway_clk_ops = {
+	.recalc		= shyway_clk_recalc,
+};
+
+static struct clk sh7757_shyway_clk = {
+	.name		= "shyway_clk",
+	.flags		= CLK_ENABLE_ON_INIT,
+	.ops		= &sh7757_shyway_clk_ops,
+};
+
+/*
+ * Additional sh7757-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7757_onchip_clocks[] = {
+	&sh7757_shyway_clk,
+};
+
+static int __init sh7757_clk_init(void)
+{
+	struct clk *clk = clk_get(NULL, "master_clk");
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh7757_onchip_clocks); i++) {
+		struct clk *clkp = sh7757_onchip_clocks[i];
+
+		clkp->parent = clk;
+		clk_register(clkp);
+		clk_enable(clkp);
+	}
+
+	/*
+	 * Now that we have the rest of the clocks registered, we need to
+	 * force the parent clock to propagate so that these clocks will
+	 * automatically figure out their rate. We cheat by handing the
+	 * parent clock its current rate and forcing child propagation.
+	 */
+	clk_set_rate(clk, clk_get_rate(clk));
+
+	clk_put(clk);
+
+	return 0;
+}
+
+arch_initcall(sh7757_clk_init);
+
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
new file mode 100644
index 0000000..a288b5d
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
@@ -0,0 +1,106 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
+ *
+ * SH7722 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
+
+/* SH7722 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7722 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7722_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7722_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
+	[HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+	[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
+	[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
+	[HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+	[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+	[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7722_hwblk_info = {
+	.areas = sh7722_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
+	.hwblks = sh7722_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7722_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
new file mode 100644
index 0000000..a7f4684
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
@@ -0,0 +1,117 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
+ *
+ * SH7723 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
+
+/* SH7723 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7723 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7723_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7723_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+	[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
+	[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+	[HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
+	[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+	[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+	[HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
+
+	[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+	[HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+	[HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+	[HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
+	[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+	[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+	[HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+	[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+	[HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7723_hwblk_info = {
+	.areas = sh7723_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
+	.hwblks = sh7723_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7723_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
new file mode 100644
index 0000000..1613ad6
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
@@ -0,0 +1,121 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
+ *
+ * SH7724 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
+
+/* SH7724 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7724 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7724_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7724_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+	[HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
+	[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+	[HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+	[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+	[HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
+	[HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
+
+	[HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
+	[HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+	[HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+	[HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
+	[HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
+	[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+	[HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
+	[HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
+	[HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
+	[HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+	[HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+	[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7724_hwblk_info = {
+	.areas = sh7724_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
+	.hwblks = sh7724_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7724_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
new file mode 100644
index 0000000..ed23b15
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
@@ -0,0 +1,2019 @@
+/*
+ * SH7757 (A0 step) Pinmux
+ *
+ *  Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ *  Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * Based on SH7757 Pinmux
+ *  Copyright (C) 2008  Magnus Damm
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7757.h>
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+	PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+	PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+	PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+	PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+	PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA,
+	PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+	PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+	PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+	PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA,
+	PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+	PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+	PTG7_DATA, PTG6_DATA, PTG5_DATA, PTG4_DATA,
+	PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+	PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+	PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+	PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
+	PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA,
+	PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+	PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
+	PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+	PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+	PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+	PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
+	PTM6_DATA, PTM5_DATA, PTM4_DATA,
+	PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+	PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+	PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
+	PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
+	PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA,
+	PTP6_DATA, PTP5_DATA, PTP4_DATA,
+	PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
+	PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+	PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
+	PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+	PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+	PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+	PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+	PTT5_DATA, PTT4_DATA,
+	PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+	PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+	PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+	PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+	PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+	PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+	PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA,
+	PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+	PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA,
+	PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+	PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA,
+	PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+	PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA,
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+	PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+	PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+	PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+	PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN,
+	PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN,
+	PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN,
+	PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN,
+	PTE7_IN, PTE6_IN, PTE5_IN, PTE4_IN,
+	PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN,
+	PTF7_IN, PTF6_IN, PTF5_IN, PTF4_IN,
+	PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN,
+	PTG7_IN, PTG6_IN, PTG5_IN, PTG4_IN,
+	PTG3_IN, PTG2_IN, PTG1_IN, PTG0_IN,
+	PTH7_IN, PTH6_IN, PTH5_IN, PTH4_IN,
+	PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
+	PTI7_IN, PTI6_IN, PTI5_IN, PTI4_IN,
+	PTI3_IN, PTI2_IN, PTI1_IN, PTI0_IN,
+	PTJ7_IN, PTJ6_IN, PTJ5_IN, PTJ4_IN,
+	PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
+	PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
+	PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
+	PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+	PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
+	PTM6_IN, PTM5_IN, PTM4_IN,
+	PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+	PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+	PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
+	PTO7_IN, PTO6_IN, PTO5_IN, PTO4_IN,
+	PTO3_IN, PTO2_IN, PTO1_IN, PTO0_IN,
+	PTP6_IN, PTP5_IN, PTP4_IN,
+	PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
+	PTQ6_IN, PTQ5_IN, PTQ4_IN,
+	PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
+	PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
+	PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
+	PTS7_IN, PTS6_IN, PTS5_IN, PTS4_IN,
+	PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
+	PTT5_IN, PTT4_IN,
+	PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
+	PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN,
+	PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+	PTV7_IN, PTV6_IN, PTV5_IN, PTV4_IN,
+	PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+	PTW7_IN, PTW6_IN, PTW5_IN, PTW4_IN,
+	PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN,
+	PTX7_IN, PTX6_IN, PTX5_IN, PTX4_IN,
+	PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN,
+	PTY7_IN, PTY6_IN, PTY5_IN, PTY4_IN,
+	PTY3_IN, PTY2_IN, PTY1_IN, PTY0_IN,
+	PTZ7_IN, PTZ6_IN, PTZ5_IN, PTZ4_IN,
+	PTZ3_IN, PTZ2_IN, PTZ1_IN, PTZ0_IN,
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU,
+	PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
+	PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU,
+	PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
+	PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU,
+	PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU,
+	PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU,
+	PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU,
+	PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU,
+	PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU,
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT,
+	PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT,
+	PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+	PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+	PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT,
+	PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT,
+	PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT,
+	PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+	PTE7_OUT, PTE6_OUT, PTE5_OUT, PTE4_OUT,
+	PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT,
+	PTF7_OUT, PTF6_OUT, PTF5_OUT, PTF4_OUT,
+	PTF3_OUT, PTF2_OUT, PTF1_OUT, PTF0_OUT,
+	PTG7_OUT, PTG6_OUT, PTG5_OUT, PTG4_OUT,
+	PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+	PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT,
+	PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+	PTI7_OUT, PTI6_OUT, PTI5_OUT, PTI4_OUT,
+	PTI3_OUT, PTI2_OUT, PTI1_OUT, PTI0_OUT,
+	PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
+	PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
+	PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
+	PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
+	PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+	PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
+	PTM6_OUT, PTM5_OUT, PTM4_OUT,
+	PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+	PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+	PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
+	PTO7_OUT, PTO6_OUT, PTO5_OUT, PTO4_OUT,
+	PTO3_OUT, PTO2_OUT, PTO1_OUT, PTO0_OUT,
+	PTP6_OUT, PTP5_OUT, PTP4_OUT,
+	PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
+	PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+	PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
+	PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
+	PTR3_OUT, PTR2_OUT, PTR1_OUT, PTR0_OUT,
+	PTS7_OUT, PTS6_OUT, PTS5_OUT, PTS4_OUT,
+	PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
+	PTT5_OUT, PTT4_OUT,
+	PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
+	PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT,
+	PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
+	PTV7_OUT, PTV6_OUT, PTV5_OUT, PTV4_OUT,
+	PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+	PTW7_OUT, PTW6_OUT, PTW5_OUT, PTW4_OUT,
+	PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT,
+	PTX7_OUT, PTX6_OUT, PTX5_OUT, PTX4_OUT,
+	PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT,
+	PTY7_OUT, PTY6_OUT, PTY5_OUT, PTY4_OUT,
+	PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT,
+	PTZ7_OUT, PTZ6_OUT, PTZ5_OUT, PTZ4_OUT,
+	PTZ3_OUT, PTZ2_OUT, PTZ1_OUT, PTZ0_OUT,
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN,
+	PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN,
+	PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN,
+	PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN,
+	PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN,
+	PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN,
+	PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN,
+	PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN,
+	PTE7_FN, PTE6_FN, PTE5_FN, PTE4_FN,
+	PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN,
+	PTF7_FN, PTF6_FN, PTF5_FN, PTF4_FN,
+	PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN,
+	PTG7_FN, PTG6_FN, PTG5_FN, PTG4_FN,
+	PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN,
+	PTH7_FN, PTH6_FN, PTH5_FN, PTH4_FN,
+	PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
+	PTI7_FN, PTI6_FN, PTI5_FN, PTI4_FN,
+	PTI3_FN, PTI2_FN, PTI1_FN, PTI0_FN,
+	PTJ7_FN, PTJ6_FN, PTJ5_FN, PTJ4_FN,
+	PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
+	PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
+	PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
+	PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+	PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
+	PTM6_FN, PTM5_FN, PTM4_FN,
+	PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
+	PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+	PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
+	PTO7_FN, PTO6_FN, PTO5_FN, PTO4_FN,
+	PTO3_FN, PTO2_FN, PTO1_FN, PTO0_FN,
+	PTP6_FN, PTP5_FN, PTP4_FN,
+	PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
+	PTQ6_FN, PTQ5_FN, PTQ4_FN,
+	PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
+	PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
+	PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
+	PTS7_FN, PTS6_FN, PTS5_FN, PTS4_FN,
+	PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
+	PTT5_FN, PTT4_FN,
+	PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
+	PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN,
+	PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
+	PTV7_FN, PTV6_FN, PTV5_FN, PTV4_FN,
+	PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN,
+	PTW7_FN, PTW6_FN, PTW5_FN, PTW4_FN,
+	PTW3_FN, PTW2_FN, PTW1_FN, PTW0_FN,
+	PTX7_FN, PTX6_FN, PTX5_FN, PTX4_FN,
+	PTX3_FN, PTX2_FN, PTX1_FN, PTX0_FN,
+	PTY7_FN, PTY6_FN, PTY5_FN, PTY4_FN,
+	PTY3_FN, PTY2_FN, PTY1_FN, PTY0_FN,
+	PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
+	PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
+
+	PS0_15_FN1, PS0_15_FN3,
+	PS0_14_FN1, PS0_14_FN3,
+	PS0_13_FN1, PS0_13_FN3,
+	PS0_12_FN1, PS0_12_FN3,
+	PS0_7_FN1, PS0_7_FN2,
+	PS0_6_FN1, PS0_6_FN2,
+	PS0_5_FN1, PS0_5_FN2,
+	PS0_4_FN1, PS0_4_FN2,
+	PS0_3_FN1, PS0_3_FN2,
+	PS0_2_FN1, PS0_2_FN2,
+	PS0_1_FN1, PS0_1_FN2,
+
+	PS1_7_FN1, PS1_7_FN3,
+	PS1_6_FN1, PS1_6_FN3,
+
+	PS2_13_FN1, PS2_13_FN3,
+	PS2_12_FN1, PS2_12_FN3,
+	PS2_1_FN1, PS2_1_FN2,
+	PS2_0_FN1, PS2_0_FN2,
+
+	PS4_15_FN1, PS4_15_FN2,
+	PS4_14_FN1, PS4_14_FN2,
+	PS4_13_FN1, PS4_13_FN2,
+	PS4_12_FN1, PS4_12_FN2,
+	PS4_11_FN1, PS4_11_FN2,
+	PS4_10_FN1, PS4_10_FN2,
+	PS4_9_FN1, PS4_9_FN2,
+	PS4_3_FN1, PS4_3_FN2,
+	PS4_2_FN1, PS4_2_FN2,
+	PS4_1_FN1, PS4_1_FN2,
+	PS4_0_FN1, PS4_0_FN2,
+
+	PS5_9_FN1, PS5_9_FN2,
+	PS5_8_FN1, PS5_8_FN2,
+	PS5_7_FN1, PS5_7_FN2,
+	PS5_6_FN1, PS5_6_FN2,
+	PS5_5_FN1, PS5_5_FN2,
+	PS5_4_FN1, PS5_4_FN2,
+
+	/* AN15 to 8 : EVENT15 to 8 */
+	PS6_7_FN_AN, PS6_7_FN_EV,
+	PS6_6_FN_AN, PS6_6_FN_EV,
+	PS6_5_FN_AN, PS6_5_FN_EV,
+	PS6_4_FN_AN, PS6_4_FN_EV,
+	PS6_3_FN_AN, PS6_3_FN_EV,
+	PS6_2_FN_AN, PS6_2_FN_EV,
+	PS6_1_FN_AN, PS6_1_FN_EV,
+	PS6_0_FN_AN, PS6_0_FN_EV,
+
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	BS_MARK,	RDWR_MARK,	WE1_MARK,	RDY_MARK,
+	MD10_MARK,	MD9_MARK,	MD8_MARK,
+	LGPIO7_MARK,	LGPIO6_MARK,	LGPIO5_MARK,	LGPIO4_MARK,
+	LGPIO3_MARK,	LGPIO2_MARK,	LGPIO1_MARK,	LGPIO0_MARK,
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	D15_MARK,	D14_MARK,	D13_MARK,	D12_MARK,
+	D11_MARK,	D10_MARK,	D9_MARK,	D8_MARK,
+	ET0_MDC_MARK,	ET0_MDIO_MARK,	ET1_MDC_MARK,	ET1_MDIO_MARK,
+	SIM_D_MARK,	SIM_CLK_MARK,	SIM_RST_MARK,
+	WPSZ1_MARK,	WPSZ0_MARK,	FWID_MARK,	FLSHSZ_MARK,
+	LPC_SPIEN_MARK,	BASEL_MARK,
+
+	/* PTC (mobule: SD) */
+	SD_WP_MARK,	SD_CD_MARK,	SD_CLK_MARK,	SD_CMD_MARK,
+	SD_D3_MARK,	SD_D2_MARK,	SD_D1_MARK,	SD_D0_MARK,
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	IRQ7_MARK,	IRQ6_MARK,	IRQ5_MARK,	IRQ4_MARK,
+	IRQ3_MARK,	IRQ2_MARK,	IRQ1_MARK,	IRQ0_MARK,
+	MD6_MARK,	MD5_MARK,	MD3_MARK,	MD2_MARK,
+	MD1_MARK,	MD0_MARK,	ADTRG1_MARK,	ADTRG0_MARK,
+
+	/* PTE (mobule: EtherC) */
+	ET0_CRS_DV_MARK,	ET0_TXD1_MARK,
+	ET0_TXD0_MARK,		ET0_TX_EN_MARK,
+	ET0_REF_CLK_MARK,	ET0_RXD1_MARK,
+	ET0_RXD0_MARK,		ET0_RX_ER_MARK,
+
+	/* PTF (mobule: EtherC) */
+	ET1_CRS_DV_MARK,	ET1_TXD1_MARK,
+	ET1_TXD0_MARK,		ET1_TX_EN_MARK,
+	ET1_REF_CLK_MARK,	ET1_RXD1_MARK,
+	ET1_RXD0_MARK,		ET1_RX_ER_MARK,
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	STATUS0_MARK,	STATUS1_MARK,
+	PWX0_MARK,	PWX1_MARK,	PWX2_MARK,	PWX3_MARK,
+	SERIRQ_MARK,	CLKRUN_MARK,	LPCPD_MARK,	LDRQ_MARK,
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	TCLK_MARK,	RXD4_MARK,	TXD4_MARK,
+	SP1_MOSI_MARK,	SP1_MISO_MARK,	SP1_SCK_MARK,	SP1_SCK_FB_MARK,
+	SP1_SS0_MARK,	SP1_SS1_MARK,	SP0_SS1_MARK,
+
+	/* PTI (mobule: INTC) */
+	IRQ15_MARK,	IRQ14_MARK,	IRQ13_MARK,	IRQ12_MARK,
+	IRQ11_MARK,	IRQ10_MARK,	IRQ9_MARK,	IRQ8_MARK,
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	RXD3_MARK,	TXD3_MARK,	RXD2_MARK,	TXD2_MARK,
+	COM1_TXD_MARK,	COM1_RXD_MARK,	COM1_RTS_MARK,	COM1_CTS_MARK,
+
+	/* PTK (mobule: SERMUX) */
+	COM2_TXD_MARK,	COM2_RXD_MARK,	COM2_RTS_MARK,	COM2_CTS_MARK,
+	COM2_DTR_MARK,	COM2_DSR_MARK,	COM2_DCD_MARK,	COM2_RI_MARK,
+
+	/* PTL (mobule: SERMUX) */
+	RAC_TXD_MARK,	RAC_RXD_MARK,	RAC_RTS_MARK,	RAC_CTS_MARK,
+	RAC_DTR_MARK,	RAC_DSR_MARK,	RAC_DCD_MARK,	RAC_RI_MARK,
+
+	/* PTM (mobule: IIC, LPC) */
+	SDA6_MARK,	SCL6_MARK,	SDA7_MARK,	SCL7_MARK,
+	WP_MARK,	FMS0_MARK,	FMS1_MARK,
+
+	/* PTN (mobule: SCIF234, EVC) */
+	SCK2_MARK,	RTS4_MARK,	RTS3_MARK,	RTS2_MARK,
+	CTS4_MARK,	CTS3_MARK,	CTS2_MARK,
+	EVENT7_MARK,	EVENT6_MARK,	EVENT5_MARK,	EVENT4_MARK,
+	EVENT3_MARK,	EVENT2_MARK,	EVENT1_MARK,	EVENT0_MARK,
+
+	/* PTO (mobule: SGPIO) */
+	SGPIO0_CLK_MARK,	SGPIO0_LOAD_MARK,
+	SGPIO0_DI_MARK,		SGPIO0_DO_MARK,
+	SGPIO1_CLK_MARK,	SGPIO1_LOAD_MARK,
+	SGPIO1_DI_MARK,		SGPIO1_DO_MARK,
+
+	/* PTP (mobule: JMC, SCIF234) */
+	JMCTCK_MARK,	JMCTMS_MARK,	JMCTDO_MARK,	JMCTDI_MARK,
+	JMCRST_MARK,	SCK4_MARK,	SCK3_MARK,
+
+	/* PTQ (mobule: LPC) */
+	LAD3_MARK,	LAD2_MARK,	LAD1_MARK,	LAD0_MARK,
+	LFRAME_MARK,	LRESET_MARK,	LCLK_MARK,
+
+	/* PTR (mobule: GRA, IIC) */
+	DDC3_MARK,	DDC2_MARK,
+	SDA8_MARK,	SCL8_MARK,	SDA2_MARK,	SCL2_MARK,
+	SDA1_MARK,	SCL1_MARK,	SDA0_MARK,	SCL0_MARK,
+
+	/* PTS (mobule: GRA, IIC) */
+	DDC1_MARK,	DDC0_MARK,
+	SDA9_MARK,	SCL9_MARK,	SDA5_MARK,	SCL5_MARK,
+	SDA4_MARK,	SCL4_MARK,	SDA3_MARK,	SCL3_MARK,
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	AUDSYNC_MARK,		AUDCK_MARK,
+	AUDATA3_MARK,		AUDATA2_MARK,
+	AUDATA1_MARK,		AUDATA0_MARK,
+	PWX7_MARK,	PWX6_MARK,	PWX5_MARK,	PWX4_MARK,
+
+	/* PTU (mobule: LBSC, DMAC) */
+	CS6_MARK,	CS5_MARK,	CS4_MARK,	CS0_MARK,
+	RD_MARK,	WE0_MARK,	A25_MARK,	A24_MARK,
+	DREQ0_MARK,	DACK0_MARK,
+
+	/* PTV (mobule: LBSC, DMAC) */
+	A23_MARK,	A22_MARK,	A21_MARK,	A20_MARK,
+	A19_MARK,	A18_MARK,	A17_MARK,	A16_MARK,
+	TEND0_MARK,	DREQ1_MARK,	DACK1_MARK,	TEND1_MARK,
+
+	/* PTW (mobule: LBSC) */
+	A15_MARK,	A14_MARK,	A13_MARK,	A12_MARK,
+	A11_MARK,	A10_MARK,	A9_MARK,	A8_MARK,
+
+	/* PTX (mobule: LBSC) */
+	A7_MARK,	A6_MARK,	A5_MARK,	A4_MARK,
+	A3_MARK,	A2_MARK,	A1_MARK,	A0_MARK,
+
+	/* PTY (mobule: LBSC) */
+	D7_MARK,	D6_MARK,	D5_MARK,	D4_MARK,
+	D3_MARK,	D2_MARK,	D1_MARK,	D0_MARK,
+	PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+	/* PTA GPIO */
+	PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT),
+	PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT),
+	PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT),
+	PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT),
+	PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT),
+	PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT),
+	PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT),
+	PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT),
+
+	/* PTB GPIO */
+	PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT),
+	PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT),
+	PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT),
+	PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT),
+	PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT),
+	PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT),
+	PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT),
+	PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT),
+
+	/* PTC GPIO */
+	PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT),
+	PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT),
+	PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT),
+	PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT),
+	PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT),
+	PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT),
+	PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT),
+	PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT),
+
+	/* PTD GPIO */
+	PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT),
+	PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT),
+	PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT),
+	PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT),
+	PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT),
+	PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT),
+	PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT),
+	PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
+
+	/* PTE GPIO */
+	PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
+	PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
+	PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
+	PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT),
+	PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT),
+	PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT),
+
+	/* PTF GPIO */
+	PINMUX_DATA(PTF7_DATA, PTF7_IN, PTF7_OUT),
+	PINMUX_DATA(PTF6_DATA, PTF6_IN, PTF6_OUT),
+	PINMUX_DATA(PTF5_DATA, PTF5_IN, PTF5_OUT),
+	PINMUX_DATA(PTF4_DATA, PTF4_IN, PTF4_OUT),
+	PINMUX_DATA(PTF3_DATA, PTF3_IN, PTF3_OUT),
+	PINMUX_DATA(PTF2_DATA, PTF2_IN, PTF2_OUT),
+	PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_OUT),
+	PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT),
+
+	/* PTG GPIO */
+	PINMUX_DATA(PTG7_DATA, PTG7_IN, PTG7_OUT),
+	PINMUX_DATA(PTG6_DATA, PTG6_IN, PTG6_OUT),
+	PINMUX_DATA(PTG5_DATA, PTG5_IN, PTG5_OUT),
+	PINMUX_DATA(PTG4_DATA, PTG4_IN, PTG4_OUT),
+	PINMUX_DATA(PTG3_DATA, PTG3_IN, PTG3_OUT),
+	PINMUX_DATA(PTG2_DATA, PTG2_IN, PTG2_OUT),
+	PINMUX_DATA(PTG1_DATA, PTG1_IN, PTG1_OUT),
+	PINMUX_DATA(PTG0_DATA, PTG0_IN, PTG0_OUT),
+
+	/* PTH GPIO */
+	PINMUX_DATA(PTH7_DATA, PTH7_IN, PTH7_OUT),
+	PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT),
+	PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT),
+	PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT),
+	PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT),
+	PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT),
+	PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT),
+	PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT),
+
+	/* PTI GPIO */
+	PINMUX_DATA(PTI7_DATA, PTI7_IN, PTI7_OUT),
+	PINMUX_DATA(PTI6_DATA, PTI6_IN, PTI6_OUT),
+	PINMUX_DATA(PTI5_DATA, PTI5_IN, PTI5_OUT),
+	PINMUX_DATA(PTI4_DATA, PTI4_IN, PTI4_OUT),
+	PINMUX_DATA(PTI3_DATA, PTI3_IN, PTI3_OUT),
+	PINMUX_DATA(PTI2_DATA, PTI2_IN, PTI2_OUT),
+	PINMUX_DATA(PTI1_DATA, PTI1_IN, PTI1_OUT),
+	PINMUX_DATA(PTI0_DATA, PTI0_IN, PTI0_OUT),
+
+	/* PTJ GPIO */
+	PINMUX_DATA(PTJ7_DATA, PTJ7_IN, PTJ7_OUT),
+	PINMUX_DATA(PTJ6_DATA, PTJ6_IN, PTJ6_OUT),
+	PINMUX_DATA(PTJ5_DATA, PTJ5_IN, PTJ5_OUT),
+	PINMUX_DATA(PTJ4_DATA, PTJ4_IN, PTJ4_OUT),
+	PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT),
+	PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT),
+	PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT),
+	PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT),
+
+	/* PTK GPIO */
+	PINMUX_DATA(PTK7_DATA, PTK7_IN, PTK7_OUT),
+	PINMUX_DATA(PTK6_DATA, PTK6_IN, PTK6_OUT),
+	PINMUX_DATA(PTK5_DATA, PTK5_IN, PTK5_OUT),
+	PINMUX_DATA(PTK4_DATA, PTK4_IN, PTK4_OUT),
+	PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT),
+	PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT),
+	PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT),
+	PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT),
+
+	/* PTL GPIO */
+	PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT),
+	PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT),
+	PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT),
+	PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT),
+	PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT),
+	PINMUX_DATA(PTL2_DATA, PTL2_IN, PTL2_OUT),
+	PINMUX_DATA(PTL1_DATA, PTL1_IN, PTL1_OUT),
+	PINMUX_DATA(PTL0_DATA, PTL0_IN, PTL0_OUT),
+
+	/* PTM GPIO */
+	PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT),
+	PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT),
+	PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT),
+	PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT),
+	PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT),
+	PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT),
+	PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT),
+
+	/* PTN GPIO */
+	PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT),
+	PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT),
+	PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT),
+	PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT),
+	PINMUX_DATA(PTN3_DATA, PTN3_IN, PTN3_OUT),
+	PINMUX_DATA(PTN2_DATA, PTN2_IN, PTN2_OUT),
+	PINMUX_DATA(PTN1_DATA, PTN1_IN, PTN1_OUT),
+	PINMUX_DATA(PTN0_DATA, PTN0_IN, PTN0_OUT),
+
+	/* PTO GPIO */
+	PINMUX_DATA(PTO7_DATA, PTO7_IN, PTO7_OUT),
+	PINMUX_DATA(PTO6_DATA, PTO6_IN, PTO6_OUT),
+	PINMUX_DATA(PTO5_DATA, PTO5_IN, PTO5_OUT),
+	PINMUX_DATA(PTO4_DATA, PTO4_IN, PTO4_OUT),
+	PINMUX_DATA(PTO3_DATA, PTO3_IN, PTO3_OUT),
+	PINMUX_DATA(PTO2_DATA, PTO2_IN, PTO2_OUT),
+	PINMUX_DATA(PTO1_DATA, PTO1_IN, PTO1_OUT),
+	PINMUX_DATA(PTO0_DATA, PTO0_IN, PTO0_OUT),
+
+	/* PTQ GPIO */
+	PINMUX_DATA(PTQ6_DATA, PTQ6_IN, PTQ6_OUT),
+	PINMUX_DATA(PTQ5_DATA, PTQ5_IN, PTQ5_OUT),
+	PINMUX_DATA(PTQ4_DATA, PTQ4_IN, PTQ4_OUT),
+	PINMUX_DATA(PTQ3_DATA, PTQ3_IN, PTQ3_OUT),
+	PINMUX_DATA(PTQ2_DATA, PTQ2_IN, PTQ2_OUT),
+	PINMUX_DATA(PTQ1_DATA, PTQ1_IN, PTQ1_OUT),
+	PINMUX_DATA(PTQ0_DATA, PTQ0_IN, PTQ0_OUT),
+
+	/* PTR GPIO */
+	PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT),
+	PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT),
+	PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT),
+	PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT),
+	PINMUX_DATA(PTR3_DATA, PTR3_IN, PTR3_OUT),
+	PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_OUT),
+	PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT),
+	PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT),
+
+	/* PTS GPIO */
+	PINMUX_DATA(PTS7_DATA, PTS7_IN, PTS7_OUT),
+	PINMUX_DATA(PTS6_DATA, PTS6_IN, PTS6_OUT),
+	PINMUX_DATA(PTS5_DATA, PTS5_IN, PTS5_OUT),
+	PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT),
+	PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT),
+	PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT),
+	PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT),
+	PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
+
+	/* PTT GPIO */
+	PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
+	PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
+	PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
+	PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT),
+	PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT),
+	PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT),
+
+	/* PTU GPIO */
+	PINMUX_DATA(PTU7_DATA, PTU7_IN, PTU7_OUT),
+	PINMUX_DATA(PTU6_DATA, PTU6_IN, PTU6_OUT),
+	PINMUX_DATA(PTU5_DATA, PTU5_IN, PTU5_OUT),
+	PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT),
+	PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT),
+	PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT),
+	PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT),
+	PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT),
+
+	/* PTV GPIO */
+	PINMUX_DATA(PTV7_DATA, PTV7_IN, PTV7_OUT),
+	PINMUX_DATA(PTV6_DATA, PTV6_IN, PTV6_OUT),
+	PINMUX_DATA(PTV5_DATA, PTV5_IN, PTV5_OUT),
+	PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT),
+	PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT),
+	PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT),
+	PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT),
+	PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT),
+
+	/* PTW GPIO */
+	PINMUX_DATA(PTW7_DATA, PTW7_IN, PTW7_OUT),
+	PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_OUT),
+	PINMUX_DATA(PTW5_DATA, PTW5_IN, PTW5_OUT),
+	PINMUX_DATA(PTW4_DATA, PTW4_IN, PTW4_OUT),
+	PINMUX_DATA(PTW3_DATA, PTW3_IN, PTW3_OUT),
+	PINMUX_DATA(PTW2_DATA, PTW2_IN, PTW2_OUT),
+	PINMUX_DATA(PTW1_DATA, PTW1_IN, PTW1_OUT),
+	PINMUX_DATA(PTW0_DATA, PTW0_IN, PTW0_OUT),
+
+	/* PTX GPIO */
+	PINMUX_DATA(PTX7_DATA, PTX7_IN, PTX7_OUT),
+	PINMUX_DATA(PTX6_DATA, PTX6_IN, PTX6_OUT),
+	PINMUX_DATA(PTX5_DATA, PTX5_IN, PTX5_OUT),
+	PINMUX_DATA(PTX4_DATA, PTX4_IN, PTX4_OUT),
+	PINMUX_DATA(PTX3_DATA, PTX3_IN, PTX3_OUT),
+	PINMUX_DATA(PTX2_DATA, PTX2_IN, PTX2_OUT),
+	PINMUX_DATA(PTX1_DATA, PTX1_IN, PTX1_OUT),
+	PINMUX_DATA(PTX0_DATA, PTX0_IN, PTX0_OUT),
+
+	/* PTY GPIO */
+	PINMUX_DATA(PTY7_DATA, PTY7_IN, PTY7_OUT),
+	PINMUX_DATA(PTY6_DATA, PTY6_IN, PTY6_OUT),
+	PINMUX_DATA(PTY5_DATA, PTY5_IN, PTY5_OUT),
+	PINMUX_DATA(PTY4_DATA, PTY4_IN, PTY4_OUT),
+	PINMUX_DATA(PTY3_DATA, PTY3_IN, PTY3_OUT),
+	PINMUX_DATA(PTY2_DATA, PTY2_IN, PTY2_OUT),
+	PINMUX_DATA(PTY1_DATA, PTY1_IN, PTY1_OUT),
+	PINMUX_DATA(PTY0_DATA, PTY0_IN, PTY0_OUT),
+
+	/* PTZ GPIO */
+	PINMUX_DATA(PTZ7_DATA, PTZ7_IN, PTZ7_OUT),
+	PINMUX_DATA(PTZ6_DATA, PTZ6_IN, PTZ6_OUT),
+	PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_OUT),
+	PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_OUT),
+	PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_OUT),
+	PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_OUT),
+	PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_OUT),
+	PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT),
+
+	/* PTA FN */
+	PINMUX_DATA(BS_MARK, PS0_15_FN1, PTA7_FN),
+	PINMUX_DATA(LGPIO7_MARK, PS0_15_FN3, PTA7_FN),
+	PINMUX_DATA(RDWR_MARK, PS0_14_FN1, PTA6_FN),
+	PINMUX_DATA(LGPIO6_MARK, PS0_14_FN3, PTA6_FN),
+	PINMUX_DATA(WE1_MARK, PS0_13_FN1, PTA5_FN),
+	PINMUX_DATA(LGPIO5_MARK, PS0_13_FN3, PTA5_FN),
+	PINMUX_DATA(RDY_MARK, PS0_12_FN1, PTA4_FN),
+	PINMUX_DATA(LGPIO4_MARK, PS0_12_FN3, PTA4_FN),
+	PINMUX_DATA(LGPIO3_MARK, PTA3_FN),
+	PINMUX_DATA(LGPIO2_MARK, PTA2_FN),
+	PINMUX_DATA(LGPIO1_MARK, PTA1_FN),
+	PINMUX_DATA(LGPIO0_MARK, PTA0_FN),
+
+	/* PTB FN */
+	PINMUX_DATA(D15_MARK, PS0_7_FN1, PTB7_FN),
+	PINMUX_DATA(ET0_MDC_MARK, PS0_7_FN2, PTB7_FN),
+	PINMUX_DATA(D14_MARK, PS0_6_FN1, PTB6_FN),
+	PINMUX_DATA(ET0_MDIO_MARK, PS0_6_FN2, PTB6_FN),
+	PINMUX_DATA(D13_MARK, PS0_5_FN1, PTB5_FN),
+	PINMUX_DATA(ET1_MDC_MARK, PS0_5_FN2, PTB5_FN),
+	PINMUX_DATA(D12_MARK, PS0_4_FN1, PTB4_FN),
+	PINMUX_DATA(ET1_MDIO_MARK, PS0_4_FN2, PTB4_FN),
+	PINMUX_DATA(D11_MARK, PS0_3_FN1, PTB3_FN),
+	PINMUX_DATA(SIM_D_MARK, PS0_3_FN2, PTB3_FN),
+	PINMUX_DATA(D10_MARK, PS0_2_FN1, PTB2_FN),
+	PINMUX_DATA(SIM_CLK_MARK, PS0_2_FN2, PTB2_FN),
+	PINMUX_DATA(D9_MARK, PS0_1_FN1, PTB1_FN),
+	PINMUX_DATA(SIM_RST_MARK, PS0_1_FN2, PTB1_FN),
+	PINMUX_DATA(D8_MARK, PTB0_FN),
+
+	/* PTC FN */
+	PINMUX_DATA(SD_WP_MARK, PTC7_FN),
+	PINMUX_DATA(SD_CD_MARK, PTC6_FN),
+	PINMUX_DATA(SD_CLK_MARK, PTC5_FN),
+	PINMUX_DATA(SD_CMD_MARK, PTC4_FN),
+	PINMUX_DATA(SD_D3_MARK, PTC3_FN),
+	PINMUX_DATA(SD_D2_MARK, PTC2_FN),
+	PINMUX_DATA(SD_D1_MARK, PTC1_FN),
+	PINMUX_DATA(SD_D0_MARK, PTC0_FN),
+
+	/* PTD FN */
+	PINMUX_DATA(IRQ7_MARK, PS1_7_FN1, PTD7_FN),
+	PINMUX_DATA(ADTRG1_MARK, PS1_7_FN3, PTD7_FN),
+	PINMUX_DATA(IRQ6_MARK, PS1_6_FN1, PTD6_FN),
+	PINMUX_DATA(ADTRG0_MARK, PS1_6_FN3, PTD6_FN),
+	PINMUX_DATA(IRQ5_MARK, PTD5_FN),
+	PINMUX_DATA(IRQ4_MARK, PTD4_FN),
+	PINMUX_DATA(IRQ3_MARK, PTD3_FN),
+	PINMUX_DATA(IRQ2_MARK, PTD2_FN),
+	PINMUX_DATA(IRQ1_MARK, PTD1_FN),
+	PINMUX_DATA(IRQ0_MARK, PTD0_FN),
+
+	/* PTE FN */
+	PINMUX_DATA(ET0_CRS_DV_MARK, PTE7_FN),
+	PINMUX_DATA(ET0_TXD1_MARK, PTE6_FN),
+	PINMUX_DATA(ET0_TXD0_MARK, PTE5_FN),
+	PINMUX_DATA(ET0_TX_EN_MARK, PTE4_FN),
+	PINMUX_DATA(ET0_REF_CLK_MARK, PTE3_FN),
+	PINMUX_DATA(ET0_RXD1_MARK, PTE2_FN),
+	PINMUX_DATA(ET0_RXD0_MARK, PTE1_FN),
+	PINMUX_DATA(ET0_RX_ER_MARK, PTE0_FN),
+
+	/* PTF FN */
+	PINMUX_DATA(ET1_CRS_DV_MARK, PTF7_FN),
+	PINMUX_DATA(ET1_TXD1_MARK, PTF6_FN),
+	PINMUX_DATA(ET1_TXD0_MARK, PTF5_FN),
+	PINMUX_DATA(ET1_TX_EN_MARK, PTF4_FN),
+	PINMUX_DATA(ET1_REF_CLK_MARK, PTF3_FN),
+	PINMUX_DATA(ET1_RXD1_MARK, PTF2_FN),
+	PINMUX_DATA(ET1_RXD0_MARK, PTF1_FN),
+	PINMUX_DATA(ET1_RX_ER_MARK, PTF0_FN),
+
+	/* PTG FN */
+	PINMUX_DATA(PWX0_MARK, PTG7_FN),
+	PINMUX_DATA(PWX1_MARK, PTG6_FN),
+	PINMUX_DATA(STATUS0_MARK, PS2_13_FN1, PTG5_FN),
+	PINMUX_DATA(PWX2_MARK, PS2_13_FN3, PTG5_FN),
+	PINMUX_DATA(STATUS1_MARK, PS2_12_FN1, PTG4_FN),
+	PINMUX_DATA(PWX3_MARK, PS2_12_FN3, PTG4_FN),
+	PINMUX_DATA(SERIRQ_MARK, PTG3_FN),
+	PINMUX_DATA(CLKRUN_MARK, PTG2_FN),
+	PINMUX_DATA(LPCPD_MARK, PTG1_FN),
+	PINMUX_DATA(LDRQ_MARK, PTG0_FN),
+
+	/* PTH FN */
+	PINMUX_DATA(SP1_MOSI_MARK, PTH7_FN),
+	PINMUX_DATA(SP1_MISO_MARK, PTH6_FN),
+	PINMUX_DATA(SP1_SCK_MARK, PTH5_FN),
+	PINMUX_DATA(SP1_SCK_FB_MARK, PTH4_FN),
+	PINMUX_DATA(SP1_SS0_MARK, PTH3_FN),
+	PINMUX_DATA(TCLK_MARK, PTH2_FN),
+	PINMUX_DATA(RXD4_MARK, PS2_1_FN1, PTH1_FN),
+	PINMUX_DATA(SP1_SS1_MARK, PS2_1_FN2, PTH1_FN),
+	PINMUX_DATA(TXD4_MARK, PS2_0_FN1, PTH0_FN),
+	PINMUX_DATA(SP0_SS1_MARK, PS2_0_FN2, PTH0_FN),
+
+	/* PTI FN */
+	PINMUX_DATA(IRQ15_MARK, PTI7_FN),
+	PINMUX_DATA(IRQ14_MARK, PTI6_FN),
+	PINMUX_DATA(IRQ13_MARK, PTI5_FN),
+	PINMUX_DATA(IRQ12_MARK, PTI4_FN),
+	PINMUX_DATA(IRQ11_MARK, PTI3_FN),
+	PINMUX_DATA(IRQ10_MARK, PTI2_FN),
+	PINMUX_DATA(IRQ9_MARK, PTI1_FN),
+	PINMUX_DATA(IRQ8_MARK, PTI0_FN),
+
+	/* PTJ FN */
+	PINMUX_DATA(RXD3_MARK, PTJ7_FN),
+	PINMUX_DATA(TXD3_MARK, PTJ6_FN),
+	PINMUX_DATA(RXD2_MARK, PTJ5_FN),
+	PINMUX_DATA(TXD2_MARK, PTJ4_FN),
+	PINMUX_DATA(COM1_TXD_MARK, PTJ3_FN),
+	PINMUX_DATA(COM1_RXD_MARK, PTJ2_FN),
+	PINMUX_DATA(COM1_RTS_MARK, PTJ1_FN),
+	PINMUX_DATA(COM1_CTS_MARK, PTJ0_FN),
+
+	/* PTK FN */
+	PINMUX_DATA(COM2_TXD_MARK, PTK7_FN),
+	PINMUX_DATA(COM2_RXD_MARK, PTK6_FN),
+	PINMUX_DATA(COM2_RTS_MARK, PTK5_FN),
+	PINMUX_DATA(COM2_CTS_MARK, PTK4_FN),
+	PINMUX_DATA(COM2_DTR_MARK, PTK3_FN),
+	PINMUX_DATA(COM2_DSR_MARK, PTK2_FN),
+	PINMUX_DATA(COM2_DCD_MARK, PTK1_FN),
+	PINMUX_DATA(COM2_RI_MARK, PTK0_FN),
+
+	/* PTL FN */
+	PINMUX_DATA(RAC_TXD_MARK, PTL7_FN),
+	PINMUX_DATA(RAC_RXD_MARK, PTL6_FN),
+	PINMUX_DATA(RAC_RTS_MARK, PTL5_FN),
+	PINMUX_DATA(RAC_CTS_MARK, PTL4_FN),
+	PINMUX_DATA(RAC_DTR_MARK, PTL3_FN),
+	PINMUX_DATA(RAC_DSR_MARK, PTL2_FN),
+	PINMUX_DATA(RAC_DCD_MARK, PTL1_FN),
+	PINMUX_DATA(RAC_RI_MARK, PTL0_FN),
+
+	/* PTM FN */
+	PINMUX_DATA(WP_MARK, PTM6_FN),
+	PINMUX_DATA(FMS0_MARK, PTM5_FN),
+	PINMUX_DATA(FMS1_MARK, PTM4_FN),
+	PINMUX_DATA(SDA6_MARK, PTM3_FN),
+	PINMUX_DATA(SCL6_MARK, PTM2_FN),
+	PINMUX_DATA(SDA7_MARK, PTM1_FN),
+	PINMUX_DATA(SCL7_MARK, PTM0_FN),
+
+	/* PTN FN */
+	PINMUX_DATA(SCK2_MARK, PS4_15_FN1, PTN7_FN),
+	PINMUX_DATA(EVENT7_MARK, PS4_15_FN2, PTN7_FN),
+	PINMUX_DATA(RTS4_MARK, PS4_14_FN1, PTN6_FN),
+	PINMUX_DATA(EVENT6_MARK, PS4_14_FN2, PTN6_FN),
+	PINMUX_DATA(RTS3_MARK, PS4_13_FN1, PTN5_FN),
+	PINMUX_DATA(EVENT5_MARK, PS4_13_FN2, PTN5_FN),
+	PINMUX_DATA(RTS2_MARK, PS4_12_FN1, PTN4_FN),
+	PINMUX_DATA(EVENT4_MARK, PS4_12_FN2, PTN4_FN),
+	PINMUX_DATA(CTS4_MARK, PS4_11_FN1, PTN3_FN),
+	PINMUX_DATA(EVENT3_MARK, PS4_11_FN2, PTN3_FN),
+	PINMUX_DATA(CTS3_MARK, PS4_10_FN1, PTN2_FN),
+	PINMUX_DATA(EVENT2_MARK, PS4_10_FN2, PTN2_FN),
+	PINMUX_DATA(CTS2_MARK, PS4_9_FN1, PTN1_FN),
+	PINMUX_DATA(EVENT1_MARK, PS4_9_FN2, PTN1_FN),
+	PINMUX_DATA(EVENT0_MARK, PTN0_FN),
+
+	/* PTO FN */
+	PINMUX_DATA(SGPIO0_CLK_MARK, PTO7_FN),
+	PINMUX_DATA(SGPIO0_LOAD_MARK, PTO6_FN),
+	PINMUX_DATA(SGPIO0_DI_MARK, PTO5_FN),
+	PINMUX_DATA(SGPIO0_DO_MARK, PTO4_FN),
+	PINMUX_DATA(SGPIO1_CLK_MARK, PTO3_FN),
+	PINMUX_DATA(SGPIO1_LOAD_MARK, PTO2_FN),
+	PINMUX_DATA(SGPIO1_DI_MARK, PTO1_FN),
+	PINMUX_DATA(SGPIO1_DO_MARK, PTO0_FN),
+
+	/* PTP FN */
+	PINMUX_DATA(JMCTCK_MARK, PTP6_FN),
+	PINMUX_DATA(JMCTMS_MARK, PTP5_FN),
+	PINMUX_DATA(JMCTDO_MARK, PTP4_FN),
+	PINMUX_DATA(JMCTDI_MARK, PTP3_FN),
+	PINMUX_DATA(JMCRST_MARK, PTP2_FN),
+	PINMUX_DATA(SCK4_MARK, PTP1_FN),
+	PINMUX_DATA(SCK3_MARK, PTP0_FN),
+
+	/* PTQ FN */
+	PINMUX_DATA(LAD3_MARK, PTQ6_FN),
+	PINMUX_DATA(LAD2_MARK, PTQ5_FN),
+	PINMUX_DATA(LAD1_MARK, PTQ4_FN),
+	PINMUX_DATA(LAD0_MARK, PTQ3_FN),
+	PINMUX_DATA(LFRAME_MARK, PTQ2_FN),
+	PINMUX_DATA(SCK4_MARK, PTQ1_FN),
+	PINMUX_DATA(SCK3_MARK, PTQ0_FN),
+
+	/* PTR FN */
+	PINMUX_DATA(SDA8_MARK, PTR7_FN),	/* DDC3? */
+	PINMUX_DATA(SCL8_MARK, PTR6_FN),	/* DDC2? */
+	PINMUX_DATA(SDA2_MARK, PTR5_FN),
+	PINMUX_DATA(SCL2_MARK, PTR4_FN),
+	PINMUX_DATA(SDA1_MARK, PTR3_FN),
+	PINMUX_DATA(SCL1_MARK, PTR2_FN),
+	PINMUX_DATA(SDA0_MARK, PTR1_FN),
+	PINMUX_DATA(SCL0_MARK, PTR0_FN),
+
+	/* PTS FN */
+	PINMUX_DATA(SDA9_MARK, PTS7_FN),	/* DDC1? */
+	PINMUX_DATA(SCL9_MARK, PTS6_FN),	/* DDC0? */
+	PINMUX_DATA(SDA5_MARK, PTS5_FN),
+	PINMUX_DATA(SCL5_MARK, PTS4_FN),
+	PINMUX_DATA(SDA4_MARK, PTS3_FN),
+	PINMUX_DATA(SCL4_MARK, PTS2_FN),
+	PINMUX_DATA(SDA3_MARK, PTS1_FN),
+	PINMUX_DATA(SCL3_MARK, PTS0_FN),
+
+	/* PTT FN */
+	PINMUX_DATA(AUDSYNC_MARK, PTS5_FN),
+	PINMUX_DATA(AUDCK_MARK, PTS4_FN),
+	PINMUX_DATA(AUDATA3_MARK, PS4_3_FN1, PTS3_FN),
+	PINMUX_DATA(PWX7_MARK, PS4_3_FN2, PTS3_FN),
+	PINMUX_DATA(AUDATA2_MARK, PS4_2_FN1, PTS2_FN),
+	PINMUX_DATA(PWX6_MARK, PS4_2_FN2, PTS2_FN),
+	PINMUX_DATA(AUDATA1_MARK, PS4_1_FN1, PTS1_FN),
+	PINMUX_DATA(PWX5_MARK, PS4_1_FN2, PTS1_FN),
+	PINMUX_DATA(AUDATA0_MARK, PS4_0_FN1, PTS0_FN),
+	PINMUX_DATA(PWX4_MARK, PS4_0_FN2, PTS0_FN),
+
+	/* PTU FN */
+	PINMUX_DATA(CS6_MARK, PTU7_FN),
+	PINMUX_DATA(CS5_MARK, PTU6_FN),
+	PINMUX_DATA(CS4_MARK, PTU5_FN),
+	PINMUX_DATA(CS0_MARK, PTU4_FN),
+	PINMUX_DATA(RD_MARK, PTU3_FN),
+	PINMUX_DATA(WE0_MARK, PTU2_FN),
+	PINMUX_DATA(A25_MARK, PS5_9_FN1, PTU1_FN),
+	PINMUX_DATA(DREQ0_MARK, PS5_9_FN2, PTU1_FN),
+	PINMUX_DATA(A24_MARK, PS5_8_FN1, PTU0_FN),
+	PINMUX_DATA(DACK0_MARK, PS5_8_FN2, PTU0_FN),
+
+	/* PTV FN */
+	PINMUX_DATA(A23_MARK, PS5_7_FN1, PTV7_FN),
+	PINMUX_DATA(TEND0_MARK, PS5_7_FN2, PTV7_FN),
+	PINMUX_DATA(A22_MARK, PS5_6_FN1, PTV6_FN),
+	PINMUX_DATA(DREQ1_MARK, PS5_6_FN2, PTV6_FN),
+	PINMUX_DATA(A21_MARK, PS5_5_FN1, PTV5_FN),
+	PINMUX_DATA(DACK1_MARK, PS5_5_FN2, PTV5_FN),
+	PINMUX_DATA(A20_MARK, PS5_4_FN1, PTV4_FN),
+	PINMUX_DATA(TEND1_MARK, PS5_4_FN2, PTV4_FN),
+	PINMUX_DATA(A19_MARK, PTV3_FN),
+	PINMUX_DATA(A18_MARK, PTV2_FN),
+	PINMUX_DATA(A17_MARK, PTV1_FN),
+	PINMUX_DATA(A16_MARK, PTV0_FN),
+
+	/* PTW FN */
+	PINMUX_DATA(A15_MARK, PTW7_FN),
+	PINMUX_DATA(A14_MARK, PTW6_FN),
+	PINMUX_DATA(A13_MARK, PTW5_FN),
+	PINMUX_DATA(A12_MARK, PTW4_FN),
+	PINMUX_DATA(A11_MARK, PTW3_FN),
+	PINMUX_DATA(A10_MARK, PTW2_FN),
+	PINMUX_DATA(A9_MARK, PTW1_FN),
+	PINMUX_DATA(A8_MARK, PTW0_FN),
+
+	/* PTX FN */
+	PINMUX_DATA(A7_MARK, PTX7_FN),
+	PINMUX_DATA(A6_MARK, PTX6_FN),
+	PINMUX_DATA(A5_MARK, PTX5_FN),
+	PINMUX_DATA(A4_MARK, PTX4_FN),
+	PINMUX_DATA(A3_MARK, PTX3_FN),
+	PINMUX_DATA(A2_MARK, PTX2_FN),
+	PINMUX_DATA(A1_MARK, PTX1_FN),
+	PINMUX_DATA(A0_MARK, PTX0_FN),
+
+	/* PTY FN */
+	PINMUX_DATA(D7_MARK, PTY7_FN),
+	PINMUX_DATA(D6_MARK, PTY6_FN),
+	PINMUX_DATA(D5_MARK, PTY5_FN),
+	PINMUX_DATA(D4_MARK, PTY4_FN),
+	PINMUX_DATA(D3_MARK, PTY3_FN),
+	PINMUX_DATA(D2_MARK, PTY2_FN),
+	PINMUX_DATA(D1_MARK, PTY1_FN),
+	PINMUX_DATA(D0_MARK, PTY0_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	/* PTA */
+	PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+	PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+	PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+	PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+	PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+	PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+	PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+	PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+	/* PTB */
+	PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+	PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+	PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+	PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+	PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+	PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+	PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+	PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+	/* PTC */
+	PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+	PINMUX_GPIO(GPIO_PTC6, PTC6_DATA),
+	PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+	PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+	PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+	PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+	PINMUX_GPIO(GPIO_PTC1, PTC1_DATA),
+	PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+	/* PTD */
+	PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+	PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+	PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+	PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+	PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+	PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+	PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+	PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+	/* PTE */
+	PINMUX_GPIO(GPIO_PTE7, PTE7_DATA),
+	PINMUX_GPIO(GPIO_PTE6, PTE6_DATA),
+	PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+	PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+	PINMUX_GPIO(GPIO_PTE3, PTE3_DATA),
+	PINMUX_GPIO(GPIO_PTE2, PTE2_DATA),
+	PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+	PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+	/* PTF */
+	PINMUX_GPIO(GPIO_PTF7, PTF7_DATA),
+	PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+	PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+	PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+	PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+	PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+	PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+	PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+	/* PTG */
+	PINMUX_GPIO(GPIO_PTG7, PTG7_DATA),
+	PINMUX_GPIO(GPIO_PTG6, PTG6_DATA),
+	PINMUX_GPIO(GPIO_PTG5, PTG5_DATA),
+	PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+	PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+	PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+	PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+	PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+	/* PTH */
+	PINMUX_GPIO(GPIO_PTH7, PTH7_DATA),
+	PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+	PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+	PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+	PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+	PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+	PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+	PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+	/* PTI */
+	PINMUX_GPIO(GPIO_PTI7, PTI7_DATA),
+	PINMUX_GPIO(GPIO_PTI6, PTI6_DATA),
+	PINMUX_GPIO(GPIO_PTI5, PTI5_DATA),
+	PINMUX_GPIO(GPIO_PTI4, PTI4_DATA),
+	PINMUX_GPIO(GPIO_PTI3, PTI3_DATA),
+	PINMUX_GPIO(GPIO_PTI2, PTI2_DATA),
+	PINMUX_GPIO(GPIO_PTI1, PTI1_DATA),
+	PINMUX_GPIO(GPIO_PTI0, PTI0_DATA),
+
+	/* PTJ */
+	PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
+	PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
+	PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+	PINMUX_GPIO(GPIO_PTJ4, PTJ4_DATA),
+	PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA),
+	PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA),
+	PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+	PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+	/* PTK */
+	PINMUX_GPIO(GPIO_PTK7, PTK7_DATA),
+	PINMUX_GPIO(GPIO_PTK6, PTK6_DATA),
+	PINMUX_GPIO(GPIO_PTK5, PTK5_DATA),
+	PINMUX_GPIO(GPIO_PTK4, PTK4_DATA),
+	PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+	PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+	PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+	PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+	/* PTL */
+	PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+	PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+	PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+	PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+	PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+	PINMUX_GPIO(GPIO_PTL2, PTL2_DATA),
+	PINMUX_GPIO(GPIO_PTL1, PTL1_DATA),
+	PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
+
+	/* PTM */
+	PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+	PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+	PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+	PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+	PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+	PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+	PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+	/* PTN */
+	PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
+	PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
+	PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
+	PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
+	PINMUX_GPIO(GPIO_PTN3, PTN3_DATA),
+	PINMUX_GPIO(GPIO_PTN2, PTN2_DATA),
+	PINMUX_GPIO(GPIO_PTN1, PTN1_DATA),
+	PINMUX_GPIO(GPIO_PTN0, PTN0_DATA),
+
+	/* PTO */
+	PINMUX_GPIO(GPIO_PTO7, PTO7_DATA),
+	PINMUX_GPIO(GPIO_PTO6, PTO6_DATA),
+	PINMUX_GPIO(GPIO_PTO5, PTO5_DATA),
+	PINMUX_GPIO(GPIO_PTO4, PTO4_DATA),
+	PINMUX_GPIO(GPIO_PTO3, PTO3_DATA),
+	PINMUX_GPIO(GPIO_PTO2, PTO2_DATA),
+	PINMUX_GPIO(GPIO_PTO1, PTO1_DATA),
+	PINMUX_GPIO(GPIO_PTO0, PTO0_DATA),
+
+	/* PTP */
+	PINMUX_GPIO(GPIO_PTP6, PTP6_DATA),
+	PINMUX_GPIO(GPIO_PTP5, PTP5_DATA),
+	PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
+	PINMUX_GPIO(GPIO_PTP3, PTP3_DATA),
+	PINMUX_GPIO(GPIO_PTP2, PTP2_DATA),
+	PINMUX_GPIO(GPIO_PTP1, PTP1_DATA),
+	PINMUX_GPIO(GPIO_PTP0, PTP0_DATA),
+
+	/* PTQ */
+	PINMUX_GPIO(GPIO_PTQ6, PTQ6_DATA),
+	PINMUX_GPIO(GPIO_PTQ5, PTQ5_DATA),
+	PINMUX_GPIO(GPIO_PTQ4, PTQ4_DATA),
+	PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA),
+	PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA),
+	PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA),
+	PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA),
+
+	/* PTR */
+	PINMUX_GPIO(GPIO_PTR7, PTR7_DATA),
+	PINMUX_GPIO(GPIO_PTR6, PTR6_DATA),
+	PINMUX_GPIO(GPIO_PTR5, PTR5_DATA),
+	PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+	PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+	PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+	PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+	PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+	/* PTS */
+	PINMUX_GPIO(GPIO_PTS7, PTS7_DATA),
+	PINMUX_GPIO(GPIO_PTS6, PTS6_DATA),
+	PINMUX_GPIO(GPIO_PTS5, PTS5_DATA),
+	PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+	PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+	PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+	PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+	PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+	/* PTT */
+	PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
+	PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+	PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+	PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+	PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+	PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+	/* PTU */
+	PINMUX_GPIO(GPIO_PTU7, PTU7_DATA),
+	PINMUX_GPIO(GPIO_PTU6, PTU6_DATA),
+	PINMUX_GPIO(GPIO_PTU5, PTU5_DATA),
+	PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+	PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+	PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+	PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+	PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+	/* PTV */
+	PINMUX_GPIO(GPIO_PTV7, PTV7_DATA),
+	PINMUX_GPIO(GPIO_PTV6, PTV6_DATA),
+	PINMUX_GPIO(GPIO_PTV5, PTV5_DATA),
+	PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+	PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+	PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+	PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+	PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+	/* PTW */
+	PINMUX_GPIO(GPIO_PTW7, PTW7_DATA),
+	PINMUX_GPIO(GPIO_PTW6, PTW6_DATA),
+	PINMUX_GPIO(GPIO_PTW5, PTW5_DATA),
+	PINMUX_GPIO(GPIO_PTW4, PTW4_DATA),
+	PINMUX_GPIO(GPIO_PTW3, PTW3_DATA),
+	PINMUX_GPIO(GPIO_PTW2, PTW2_DATA),
+	PINMUX_GPIO(GPIO_PTW1, PTW1_DATA),
+	PINMUX_GPIO(GPIO_PTW0, PTW0_DATA),
+
+	/* PTX */
+	PINMUX_GPIO(GPIO_PTX7, PTX7_DATA),
+	PINMUX_GPIO(GPIO_PTX6, PTX6_DATA),
+	PINMUX_GPIO(GPIO_PTX5, PTX5_DATA),
+	PINMUX_GPIO(GPIO_PTX4, PTX4_DATA),
+	PINMUX_GPIO(GPIO_PTX3, PTX3_DATA),
+	PINMUX_GPIO(GPIO_PTX2, PTX2_DATA),
+	PINMUX_GPIO(GPIO_PTX1, PTX1_DATA),
+	PINMUX_GPIO(GPIO_PTX0, PTX0_DATA),
+
+	/* PTY */
+	PINMUX_GPIO(GPIO_PTY7, PTY7_DATA),
+	PINMUX_GPIO(GPIO_PTY6, PTY6_DATA),
+	PINMUX_GPIO(GPIO_PTY5, PTY5_DATA),
+	PINMUX_GPIO(GPIO_PTY4, PTY4_DATA),
+	PINMUX_GPIO(GPIO_PTY3, PTY3_DATA),
+	PINMUX_GPIO(GPIO_PTY2, PTY2_DATA),
+	PINMUX_GPIO(GPIO_PTY1, PTY1_DATA),
+	PINMUX_GPIO(GPIO_PTY0, PTY0_DATA),
+
+	/* PTZ */
+	PINMUX_GPIO(GPIO_PTZ7, PTZ7_DATA),
+	PINMUX_GPIO(GPIO_PTZ6, PTZ6_DATA),
+	PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA),
+	PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA),
+	PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA),
+	PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA),
+	PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
+	PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
+
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+	PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK),
+	PINMUX_GPIO(GPIO_FN_WE1, WE1_MARK),
+	PINMUX_GPIO(GPIO_FN_RDY, RDY_MARK),
+	PINMUX_GPIO(GPIO_FN_MD10, MD10_MARK),
+	PINMUX_GPIO(GPIO_FN_MD9, MD9_MARK),
+	PINMUX_GPIO(GPIO_FN_MD8, MD8_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
+	PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
+	PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
+	PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
+	PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
+	PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
+	PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
+	PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDIO_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDIO_MARK),
+	PINMUX_GPIO(GPIO_FN_WPSZ1, WPSZ1_MARK),
+	PINMUX_GPIO(GPIO_FN_WPSZ0, WPSZ0_MARK),
+	PINMUX_GPIO(GPIO_FN_FWID, FWID_MARK),
+	PINMUX_GPIO(GPIO_FN_FLSHSZ, FLSHSZ_MARK),
+	PINMUX_GPIO(GPIO_FN_LPC_SPIEN, LPC_SPIEN_MARK),
+	PINMUX_GPIO(GPIO_FN_BASEL, BASEL_MARK),
+
+	/* PTC (mobule: SD) */
+	PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_MD6, MD6_MARK),
+	PINMUX_GPIO(GPIO_FN_MD5, MD5_MARK),
+	PINMUX_GPIO(GPIO_FN_MD3, MD3_MARK),
+	PINMUX_GPIO(GPIO_FN_MD2, MD2_MARK),
+	PINMUX_GPIO(GPIO_FN_MD1, MD1_MARK),
+	PINMUX_GPIO(GPIO_FN_MD0, MD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
+
+	/* PTE (mobule: EtherC) */
+	PINMUX_GPIO(GPIO_FN_ET0_CRS_DV, ET0_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TXD1, ET0_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TXD0, ET0_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TX_EN, ET0_TX_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_REF_CLK, ET0_REF_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RXD1, ET0_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RXD0, ET0_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RX_ER, ET0_RX_ER_MARK),
+
+	/* PTF (mobule: EtherC) */
+	PINMUX_GPIO(GPIO_FN_ET1_CRS_DV, ET1_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TXD1, ET1_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TXD0, ET1_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TX_EN, ET1_TX_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_REF_CLK, ET1_REF_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RXD1, ET1_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RXD0, ET1_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RX_ER, ET1_RX_ER_MARK),
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+	PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX0, PWX0_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX1, PWX1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX2, PWX2_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX3, PWX3_MARK),
+	PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK),
+	PINMUX_GPIO(GPIO_FN_CLKRUN, CLKRUN_MARK),
+	PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK),
+	PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK),
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_MOSI, SP1_MOSI_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_MISO, SP1_MISO_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SCK, SP1_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SCK_FB, SP1_SCK_FB_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SS0, SP1_SS0_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SS1, SP1_SS1_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+
+	/* PTI (mobule: INTC) */
+	PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
+
+	/* PTK (mobule: SERMUX) */
+	PINMUX_GPIO(GPIO_FN_COM2_TXD, COM2_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RXD, COM2_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RTS, COM2_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_CTS, COM2_CTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DTR, COM2_DTR_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DSR, COM2_DSR_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DCD, COM2_DCD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+
+	/* PTL (mobule: SERMUX) */
+	PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RXD, RAC_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RTS, RAC_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_CTS, RAC_CTS_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DTR, RAC_DTR_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DSR, RAC_DSR_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DCD, RAC_DCD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+
+	/* PTM (mobule: IIC, LPC) */
+	PINMUX_GPIO(GPIO_FN_SDA6, SDA6_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL6, SCL6_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA7, SDA7_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL7, SCL7_MARK),
+	PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
+	PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
+	PINMUX_GPIO(GPIO_FN_FMS1, FMS1_MARK),
+
+	/* PTN (mobule: SCIF234, EVC) */
+	PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+
+	/* PTO (mobule: SGPIO) */
+	PINMUX_GPIO(GPIO_FN_SGPIO0_CLK, SGPIO0_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_LOAD, SGPIO0_LOAD_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_DI, SGPIO0_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_DO, SGPIO0_DO_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+
+	/* PTP (mobule: JMC, SCIF234) */
+	PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCRST, JMCRST_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+
+	/* PTQ (mobule: LPC) */
+	PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD2, LAD2_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD1, LAD1_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD0, LAD0_MARK),
+	PINMUX_GPIO(GPIO_FN_LFRAME, LFRAME_MARK),
+	PINMUX_GPIO(GPIO_FN_LRESET, LRESET_MARK),
+	PINMUX_GPIO(GPIO_FN_LCLK, LCLK_MARK),
+
+	/* PTR (mobule: GRA, IIC) */
+	PINMUX_GPIO(GPIO_FN_DDC3, DDC3_MARK),
+	PINMUX_GPIO(GPIO_FN_DDC2, DDC2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA8, SDA8_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL8, SCL8_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK),
+
+	/* PTS (mobule: GRA, IIC) */
+	PINMUX_GPIO(GPIO_FN_DDC1, DDC1_MARK),
+	PINMUX_GPIO(GPIO_FN_DDC0, DDC0_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA9, SDA9_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL9, SCL9_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA5, SDA5_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL5, SCL5_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA4, SDA4_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL4, SCL4_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK),
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX7, PWX7_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX6, PWX6_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX5, PWX5_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX4, PWX4_MARK),
+
+	/* PTU (mobule: LBSC, DMAC) */
+	PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+	PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+	PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+	PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
+	PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
+	PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
+	PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+	PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+
+	/* PTV (mobule: LBSC, DMAC) */
+	PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+	PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+	PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
+	PINMUX_GPIO(GPIO_FN_A20, A20_MARK),
+	PINMUX_GPIO(GPIO_FN_A19, A19_MARK),
+	PINMUX_GPIO(GPIO_FN_A18, A18_MARK),
+	PINMUX_GPIO(GPIO_FN_A17, A17_MARK),
+	PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+
+	/* PTW (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
+	PINMUX_GPIO(GPIO_FN_A15, A15_MARK),
+	PINMUX_GPIO(GPIO_FN_A14, A14_MARK),
+	PINMUX_GPIO(GPIO_FN_A13, A13_MARK),
+	PINMUX_GPIO(GPIO_FN_A12, A12_MARK),
+	PINMUX_GPIO(GPIO_FN_A11, A11_MARK),
+	PINMUX_GPIO(GPIO_FN_A10, A10_MARK),
+	PINMUX_GPIO(GPIO_FN_A9, A9_MARK),
+	PINMUX_GPIO(GPIO_FN_A8, A8_MARK),
+
+	/* PTX (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_A7, A7_MARK),
+	PINMUX_GPIO(GPIO_FN_A6, A6_MARK),
+	PINMUX_GPIO(GPIO_FN_A5, A5_MARK),
+	PINMUX_GPIO(GPIO_FN_A4, A4_MARK),
+	PINMUX_GPIO(GPIO_FN_A3, A3_MARK),
+	PINMUX_GPIO(GPIO_FN_A2, A2_MARK),
+	PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
+	PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+
+	/* PTY (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
+	PINMUX_GPIO(GPIO_FN_D6, D6_MARK),
+	PINMUX_GPIO(GPIO_FN_D5, D5_MARK),
+	PINMUX_GPIO(GPIO_FN_D4, D4_MARK),
+	PINMUX_GPIO(GPIO_FN_D3, D3_MARK),
+	PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
+	PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
+	PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+ };
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("PACR", 0xffec0000, 16, 2) {
+		PTA7_FN, PTA7_OUT, PTA7_IN, 0,
+		PTA6_FN, PTA6_OUT, PTA6_IN, 0,
+		PTA5_FN, PTA5_OUT, PTA5_IN, 0,
+		PTA4_FN, PTA4_OUT, PTA4_IN, 0,
+		PTA3_FN, PTA3_OUT, PTA3_IN, 0,
+		PTA2_FN, PTA2_OUT, PTA2_IN, 0,
+		PTA1_FN, PTA1_OUT, PTA1_IN, 0,
+		PTA0_FN, PTA0_OUT, PTA0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PBCR", 0xffec0002, 16, 2) {
+		PTB7_FN, PTB7_OUT, PTB7_IN, 0,
+		PTB6_FN, PTB6_OUT, PTB6_IN, 0,
+		PTB5_FN, PTB5_OUT, PTB5_IN, 0,
+		PTB4_FN, PTB4_OUT, PTB4_IN, 0,
+		PTB3_FN, PTB3_OUT, PTB3_IN, 0,
+		PTB2_FN, PTB2_OUT, PTB2_IN, 0,
+		PTB1_FN, PTB1_OUT, PTB1_IN, 0,
+		PTB0_FN, PTB0_OUT, PTB0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PCCR", 0xffec0004, 16, 2) {
+		PTC7_FN, PTC7_OUT, PTC7_IN, 0,
+		PTC6_FN, PTC6_OUT, PTC6_IN, 0,
+		PTC5_FN, PTC5_OUT, PTC5_IN, 0,
+		PTC4_FN, PTC4_OUT, PTC4_IN, 0,
+		PTC3_FN, PTC3_OUT, PTC3_IN, 0,
+		PTC2_FN, PTC2_OUT, PTC2_IN, 0,
+		PTC1_FN, PTC1_OUT, PTC1_IN, 0,
+		PTC0_FN, PTC0_OUT, PTC0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PDCR", 0xffec0006, 16, 2) {
+		PTD7_FN, PTD7_OUT, PTD7_IN, 0,
+		PTD6_FN, PTD6_OUT, PTD6_IN, 0,
+		PTD5_FN, PTD5_OUT, PTD5_IN, 0,
+		PTD4_FN, PTD4_OUT, PTD4_IN, 0,
+		PTD3_FN, PTD3_OUT, PTD3_IN, 0,
+		PTD2_FN, PTD2_OUT, PTD2_IN, 0,
+		PTD1_FN, PTD1_OUT, PTD1_IN, 0,
+		PTD0_FN, PTD0_OUT, PTD0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PECR", 0xffec0008, 16, 2) {
+		PTE7_FN, PTE7_OUT, PTE7_IN, 0,
+		PTE6_FN, PTE6_OUT, PTE6_IN, 0,
+		PTE5_FN, PTE5_OUT, PTE5_IN, 0,
+		PTE4_FN, PTE4_OUT, PTE4_IN, 0,
+		PTE3_FN, PTE3_OUT, PTE3_IN, 0,
+		PTE2_FN, PTE2_OUT, PTE2_IN, 0,
+		PTE1_FN, PTE1_OUT, PTE1_IN, 0,
+		PTE0_FN, PTE0_OUT, PTE0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PFCR", 0xffec000a, 16, 2) {
+		PTF7_FN, PTF7_OUT, PTF7_IN, 0,
+		PTF6_FN, PTF6_OUT, PTF6_IN, 0,
+		PTF5_FN, PTF5_OUT, PTF5_IN, 0,
+		PTF4_FN, PTF4_OUT, PTF4_IN, 0,
+		PTF3_FN, PTF3_OUT, PTF3_IN, 0,
+		PTF2_FN, PTF2_OUT, PTF2_IN, 0,
+		PTF1_FN, PTF1_OUT, PTF1_IN, 0,
+		PTF0_FN, PTF0_OUT, PTF0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PGCR", 0xffec000c, 16, 2) {
+		PTG7_FN, PTG7_OUT, PTG7_IN, 0,
+		PTG6_FN, PTG6_OUT, PTG6_IN, 0,
+		PTG5_FN, PTG5_OUT, PTG5_IN, 0,
+		PTG4_FN, PTG4_OUT, PTG4_IN, 0,
+		PTG3_FN, PTG3_OUT, PTG3_IN, 0,
+		PTG2_FN, PTG2_OUT, PTG2_IN, 0,
+		PTG1_FN, PTG1_OUT, PTG1_IN, 0,
+		PTG0_FN, PTG0_OUT, PTG0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PHCR", 0xffec000e, 16, 2) {
+		PTH7_FN, PTH7_OUT, PTH7_IN, 0,
+		PTH6_FN, PTH6_OUT, PTH6_IN, 0,
+		PTH5_FN, PTH5_OUT, PTH5_IN, 0,
+		PTH4_FN, PTH4_OUT, PTH4_IN, 0,
+		PTH3_FN, PTH3_OUT, PTH3_IN, 0,
+		PTH2_FN, PTH2_OUT, PTH2_IN, 0,
+		PTH1_FN, PTH1_OUT, PTH1_IN, 0,
+		PTH0_FN, PTH0_OUT, PTH0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PICR", 0xffec0010, 16, 2) {
+		PTI7_FN, PTI7_OUT, PTI7_IN, 0,
+		PTI6_FN, PTI6_OUT, PTI6_IN, 0,
+		PTI5_FN, PTI5_OUT, PTI5_IN, 0,
+		PTI4_FN, PTI4_OUT, PTI4_IN, 0,
+		PTI3_FN, PTI3_OUT, PTI3_IN, 0,
+		PTI2_FN, PTI2_OUT, PTI2_IN, 0,
+		PTI1_FN, PTI1_OUT, PTI1_IN, 0,
+		PTI0_FN, PTI0_OUT, PTI0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PJCR", 0xffec0012, 16, 2) {
+		PTJ7_FN, PTJ7_OUT, PTJ7_IN, 0,
+		PTJ6_FN, PTJ6_OUT, PTJ6_IN, 0,
+		PTJ5_FN, PTJ5_OUT, PTJ5_IN, 0,
+		PTJ4_FN, PTJ4_OUT, PTJ4_IN, 0,
+		PTJ3_FN, PTJ3_OUT, PTJ3_IN, 0,
+		PTJ2_FN, PTJ2_OUT, PTJ2_IN, 0,
+		PTJ1_FN, PTJ1_OUT, PTJ1_IN, 0,
+		PTJ0_FN, PTJ0_OUT, PTJ0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PKCR", 0xffec0014, 16, 2) {
+		PTK7_FN, PTK7_OUT, PTK7_IN, 0,
+		PTK6_FN, PTK6_OUT, PTK6_IN, 0,
+		PTK5_FN, PTK5_OUT, PTK5_IN, 0,
+		PTK4_FN, PTK4_OUT, PTK4_IN, 0,
+		PTK3_FN, PTK3_OUT, PTK3_IN, 0,
+		PTK2_FN, PTK2_OUT, PTK2_IN, 0,
+		PTK1_FN, PTK1_OUT, PTK1_IN, 0,
+		PTK0_FN, PTK0_OUT, PTK0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PLCR", 0xffec0016, 16, 2) {
+		PTL7_FN, PTL7_OUT, PTL7_IN, 0,
+		PTL6_FN, PTL6_OUT, PTL6_IN, 0,
+		PTL5_FN, PTL5_OUT, PTL5_IN, 0,
+		PTL4_FN, PTL4_OUT, PTL4_IN, 0,
+		PTL3_FN, PTL3_OUT, PTL3_IN, 0,
+		PTL2_FN, PTL2_OUT, PTL2_IN, 0,
+		PTL1_FN, PTL1_OUT, PTL1_IN, 0,
+		PTL0_FN, PTL0_OUT, PTL0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PMCR", 0xffec0018, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTM6_FN, PTM6_OUT, PTM6_IN, 0,
+		PTM5_FN, PTM5_OUT, PTM5_IN, 0,
+		PTM4_FN, PTM4_OUT, PTM4_IN, 0,
+		PTM3_FN, PTM3_OUT, PTM3_IN, 0,
+		PTM2_FN, PTM2_OUT, PTM2_IN, 0,
+		PTM1_FN, PTM1_OUT, PTM1_IN, 0,
+		PTM0_FN, PTM0_OUT, PTM0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PNCR", 0xffec001a, 16, 2) {
+		PTN7_FN, PTN7_OUT, PTN7_IN, 0,
+		PTN6_FN, PTN6_OUT, PTN6_IN, 0,
+		PTN5_FN, PTN5_OUT, PTN5_IN, 0,
+		PTN4_FN, PTN4_OUT, PTN4_IN, 0,
+		PTN3_FN, PTN3_OUT, PTN3_IN, 0,
+		PTN2_FN, PTN2_OUT, PTN2_IN, 0,
+		PTN1_FN, PTN1_OUT, PTN1_IN, 0,
+		PTN0_FN, PTN0_OUT, PTN0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("POCR", 0xffec001c, 16, 2) {
+		PTO7_FN, PTO7_OUT, PTO7_IN, 0,
+		PTO6_FN, PTO6_OUT, PTO6_IN, 0,
+		PTO5_FN, PTO5_OUT, PTO5_IN, 0,
+		PTO4_FN, PTO4_OUT, PTO4_IN, 0,
+		PTO3_FN, PTO3_OUT, PTO3_IN, 0,
+		PTO2_FN, PTO2_OUT, PTO2_IN, 0,
+		PTO1_FN, PTO1_OUT, PTO1_IN, 0,
+		PTO0_FN, PTO0_OUT, PTO0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PPCR", 0xffec001e, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTP6_FN, PTP6_OUT, PTP6_IN, 0,
+		PTP5_FN, PTP5_OUT, PTP5_IN, 0,
+		PTP4_FN, PTP4_OUT, PTP4_IN, 0,
+		PTP3_FN, PTP3_OUT, PTP3_IN, 0,
+		PTP2_FN, PTP2_OUT, PTP2_IN, 0,
+		PTP1_FN, PTP1_OUT, PTP1_IN, 0,
+		PTP0_FN, PTP0_OUT, PTP0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PQCR", 0xffec0020, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTQ6_FN, PTQ6_OUT, PTQ6_IN, 0,
+		PTQ5_FN, PTQ5_OUT, PTQ5_IN, 0,
+		PTQ4_FN, PTQ4_OUT, PTQ4_IN, 0,
+		PTQ3_FN, PTQ3_OUT, PTQ3_IN, 0,
+		PTQ2_FN, PTQ2_OUT, PTQ2_IN, 0,
+		PTQ1_FN, PTQ1_OUT, PTQ1_IN, 0,
+		PTQ0_FN, PTQ0_OUT, PTQ0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PRCR", 0xffec0022, 16, 2) {
+		PTR7_FN, PTR7_OUT, PTR7_IN, 0,
+		PTR6_FN, PTR6_OUT, PTR6_IN, 0,
+		PTR5_FN, PTR5_OUT, PTR5_IN, 0,
+		PTR4_FN, PTR4_OUT, PTR4_IN, 0,
+		PTR3_FN, PTR3_OUT, PTR3_IN, 0,
+		PTR2_FN, PTR2_OUT, PTR2_IN, 0,
+		PTR1_FN, PTR1_OUT, PTR1_IN, 0,
+		PTR0_FN, PTR0_OUT, PTR0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PSCR", 0xffec0024, 16, 2) {
+		PTS7_FN, PTS7_OUT, PTS7_IN, 0,
+		PTS6_FN, PTS6_OUT, PTS6_IN, 0,
+		PTS5_FN, PTS5_OUT, PTS5_IN, 0,
+		PTS4_FN, PTS4_OUT, PTS4_IN, 0,
+		PTS3_FN, PTS3_OUT, PTS3_IN, 0,
+		PTS2_FN, PTS2_OUT, PTS2_IN, 0,
+		PTS1_FN, PTS1_OUT, PTS1_IN, 0,
+		PTS0_FN, PTS0_OUT, PTS0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PTCR", 0xffec0026, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTT5_FN, PTT5_OUT, PTT5_IN, 0,
+		PTT4_FN, PTT4_OUT, PTT4_IN, 0,
+		PTT3_FN, PTT3_OUT, PTT3_IN, 0,
+		PTT2_FN, PTT2_OUT, PTT2_IN, 0,
+		PTT1_FN, PTT1_OUT, PTT1_IN, 0,
+		PTT0_FN, PTT0_OUT, PTT0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PUCR", 0xffec0028, 16, 2) {
+		PTU7_FN, PTU7_OUT, PTU7_IN, PTU7_IN_PU,
+		PTU6_FN, PTU6_OUT, PTU6_IN, PTU6_IN_PU,
+		PTU5_FN, PTU5_OUT, PTU5_IN, PTU5_IN_PU,
+		PTU4_FN, PTU4_OUT, PTU4_IN, PTU4_IN_PU,
+		PTU3_FN, PTU3_OUT, PTU3_IN, PTU3_IN_PU,
+		PTU2_FN, PTU2_OUT, PTU2_IN, PTU2_IN_PU,
+		PTU1_FN, PTU1_OUT, PTU1_IN, PTU1_IN_PU,
+		PTU0_FN, PTU0_OUT, PTU0_IN, PTU0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PVCR", 0xffec002a, 16, 2) {
+		PTV7_FN, PTV7_OUT, PTV7_IN, PTV7_IN_PU,
+		PTV6_FN, PTV6_OUT, PTV6_IN, PTV6_IN_PU,
+		PTV5_FN, PTV5_OUT, PTV5_IN, PTV5_IN_PU,
+		PTV4_FN, PTV4_OUT, PTV4_IN, PTV4_IN_PU,
+		PTV3_FN, PTV3_OUT, PTV3_IN, PTV3_IN_PU,
+		PTV2_FN, PTV2_OUT, PTV2_IN, PTV2_IN_PU,
+		PTV1_FN, PTV1_OUT, PTV1_IN, PTV1_IN_PU,
+		PTV0_FN, PTV0_OUT, PTV0_IN, PTV0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PWCR", 0xffec002c, 16, 2) {
+		PTW7_FN, PTW7_OUT, PTW7_IN, PTW7_IN_PU,
+		PTW6_FN, PTW6_OUT, PTW6_IN, PTW6_IN_PU,
+		PTW5_FN, PTW5_OUT, PTW5_IN, PTW5_IN_PU,
+		PTW4_FN, PTW4_OUT, PTW4_IN, PTW4_IN_PU,
+		PTW3_FN, PTW3_OUT, PTW3_IN, PTW3_IN_PU,
+		PTW2_FN, PTW2_OUT, PTW2_IN, PTW2_IN_PU,
+		PTW1_FN, PTW1_OUT, PTW1_IN, PTW1_IN_PU,
+		PTW0_FN, PTW0_OUT, PTW0_IN, PTW0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PXCR", 0xffec002e, 16, 2) {
+		PTX7_FN, PTX7_OUT, PTX7_IN, PTX7_IN_PU,
+		PTX6_FN, PTX6_OUT, PTX6_IN, PTX6_IN_PU,
+		PTX5_FN, PTX5_OUT, PTX5_IN, PTX5_IN_PU,
+		PTX4_FN, PTX4_OUT, PTX4_IN, PTX4_IN_PU,
+		PTX3_FN, PTX3_OUT, PTX3_IN, PTX3_IN_PU,
+		PTX2_FN, PTX2_OUT, PTX2_IN, PTX2_IN_PU,
+		PTX1_FN, PTX1_OUT, PTX1_IN, PTX1_IN_PU,
+		PTX0_FN, PTX0_OUT, PTX0_IN, PTX0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PYCR", 0xffec0030, 16, 2) {
+		PTY7_FN, PTY7_OUT, PTY7_IN, PTY7_IN_PU,
+		PTY6_FN, PTY6_OUT, PTY6_IN, PTY6_IN_PU,
+		PTY5_FN, PTY5_OUT, PTY5_IN, PTY5_IN_PU,
+		PTY4_FN, PTY4_OUT, PTY4_IN, PTY4_IN_PU,
+		PTY3_FN, PTY3_OUT, PTY3_IN, PTY3_IN_PU,
+		PTY2_FN, PTY2_OUT, PTY2_IN, PTY2_IN_PU,
+		PTY1_FN, PTY1_OUT, PTY1_IN, PTY1_IN_PU,
+		PTY0_FN, PTY0_OUT, PTY0_IN, PTY0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PZCR", 0xffec0032, 16, 2) {
+		0, PTZ7_OUT, PTZ7_IN, 0,
+		0, PTZ6_OUT, PTZ6_IN, 0,
+		0, PTZ5_OUT, PTZ5_IN, 0,
+		0, PTZ4_OUT, PTZ4_IN, 0,
+		0, PTZ3_OUT, PTZ3_IN, 0,
+		0, PTZ2_OUT, PTZ2_IN, 0,
+		0, PTZ1_OUT, PTZ1_IN, 0,
+		0, PTZ0_OUT, PTZ0_IN, 0 }
+	},
+
+	{ PINMUX_CFG_REG("PSEL0", 0xffec0070, 16, 1) {
+		PS0_15_FN3, PS0_15_FN1,
+		PS0_14_FN3, PS0_14_FN1,
+		PS0_13_FN3, PS0_13_FN1,
+		PS0_12_FN3, PS0_12_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS0_7_FN2, PS0_7_FN1,
+		PS0_6_FN2, PS0_6_FN1,
+		PS0_5_FN2, PS0_5_FN1,
+		PS0_4_FN2, PS0_4_FN1,
+		PS0_3_FN2, PS0_3_FN1,
+		PS0_2_FN2, PS0_2_FN1,
+		PS0_1_FN2, PS0_1_FN1,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL1", 0xffec0072, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS1_7_FN1, PS1_7_FN3,
+		PS1_6_FN1, PS1_6_FN3,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL2", 0xffec0074, 16, 1) {
+		0, 0,
+		0, 0,
+		PS2_13_FN3, PS2_13_FN1,
+		PS2_12_FN3, PS2_12_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS2_1_FN1, PS2_1_FN2,
+		PS2_0_FN1, PS2_0_FN2, }
+	},
+	{ PINMUX_CFG_REG("PSEL4", 0xffec0078, 16, 1) {
+		PS4_15_FN2, PS4_15_FN1,
+		PS4_14_FN2, PS4_14_FN1,
+		PS4_13_FN2, PS4_13_FN1,
+		PS4_12_FN2, PS4_12_FN1,
+		PS4_11_FN2, PS4_11_FN1,
+		PS4_10_FN2, PS4_10_FN1,
+		PS4_9_FN2, PS4_9_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS4_3_FN2, PS4_3_FN1,
+		PS4_2_FN2, PS4_2_FN1,
+		PS4_1_FN2, PS4_1_FN1,
+		PS4_0_FN2, PS4_0_FN1, }
+	},
+	{ PINMUX_CFG_REG("PSEL5", 0xffec007a, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS5_9_FN1, PS5_9_FN2,
+		PS5_8_FN1, PS5_8_FN2,
+		PS5_7_FN1, PS5_7_FN2,
+		PS5_6_FN1, PS5_6_FN2,
+		PS5_5_FN1, PS5_5_FN2,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS6_7_FN_AN, PS6_7_FN_EV,
+		PS6_6_FN_AN, PS6_6_FN_EV,
+		PS6_5_FN_AN, PS6_5_FN_EV,
+		PS6_4_FN_AN, PS6_4_FN_EV,
+		PS6_3_FN_AN, PS6_3_FN_EV,
+		PS6_2_FN_AN, PS6_2_FN_EV,
+		PS6_1_FN_AN, PS6_1_FN_EV,
+		PS6_0_FN_AN, PS6_0_FN_EV, }
+	},
+	{}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PADR", 0xffec0034, 8) {
+		PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+		PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+	},
+	{ PINMUX_DATA_REG("PBDR", 0xffec0036, 8) {
+		PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+		PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+	},
+	{ PINMUX_DATA_REG("PCDR", 0xffec0038, 8) {
+		PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+		PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA }
+	},
+	{ PINMUX_DATA_REG("PDDR", 0xffec003a, 8) {
+		PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+		PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+	},
+	{ PINMUX_DATA_REG("PEDR", 0xffec003c, 8) {
+		PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+		PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA }
+	},
+	{ PINMUX_DATA_REG("PFDR", 0xffec003e, 8) {
+		PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+		PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+	},
+	{ PINMUX_DATA_REG("PGDR", 0xffec0040, 8) {
+		PTG7_DATA, PTG6_DATA, PTG5_DATA, PTG4_DATA,
+		PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+	},
+	{ PINMUX_DATA_REG("PHDR", 0xffec0042, 8) {
+		PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+		PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+	},
+	{ PINMUX_DATA_REG("PIDR", 0xffec0044, 8) {
+		PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
+		PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA }
+	},
+	{ PINMUX_DATA_REG("PJDR", 0xffec0046, 8) {
+		PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+		PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
+	},
+	{ PINMUX_DATA_REG("PKDR", 0xffec0048, 8) {
+		PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+		PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+	},
+	{ PINMUX_DATA_REG("PLDR", 0xffec004a, 8) {
+		PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+		PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
+	},
+	{ PINMUX_DATA_REG("PMDR", 0xffec004c, 8) {
+		0, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+		PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+	},
+	{ PINMUX_DATA_REG("PNDR", 0xffec004e, 8) {
+		PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+		PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
+	},
+	{ PINMUX_DATA_REG("PODR", 0xffec0050, 8) {
+		PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
+		PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA }
+	},
+	{ PINMUX_DATA_REG("PPDR", 0xffec0052, 8) {
+		0, PTP6_DATA, PTP5_DATA, PTP4_DATA,
+		PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
+	},
+	{ PINMUX_DATA_REG("PQDR", 0xffec0054, 8) {
+		0, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+		PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA }
+	},
+	{ PINMUX_DATA_REG("PRDR", 0xffec0056, 8) {
+		PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+		PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+	},
+	{ PINMUX_DATA_REG("PSDR", 0xffec0058, 8) {
+		PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+		PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+	},
+	{ PINMUX_DATA_REG("PTDR", 0xffec005a, 8) {
+		0, 0, PTT5_DATA, PTT4_DATA,
+		PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+	},
+	{ PINMUX_DATA_REG("PUDR", 0xffec005c, 8) {
+		PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+		PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+	},
+	{ PINMUX_DATA_REG("PVDR", 0xffec005e, 8) {
+		PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+		PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+	},
+	{ PINMUX_DATA_REG("PWDR", 0xffec0060, 8) {
+		PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+		PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA }
+	},
+	{ PINMUX_DATA_REG("PXDR", 0xffec0062, 8) {
+		PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+		PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA }
+	},
+	{ PINMUX_DATA_REG("PYDR", 0xffec0064, 8) {
+		PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+		PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA }
+	},
+	{ PINMUX_DATA_REG("PZDR", 0xffec0066, 8) {
+		PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+		PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA }
+	},
+	{ },
+};
+
+static struct pinmux_info sh7757_pinmux_info = {
+	.name = "sh7757_pfc",
+	.reserved_id = PINMUX_RESERVED,
+	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.first_gpio = GPIO_PTA7,
+	.last_gpio = GPIO_FN_D0,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+	return register_pinmux(&sh7757_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 1a956b1..4a9010b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -40,7 +40,7 @@
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-	/* This set zero to all members */
+	.on_chip = 1,
 };
 
 static struct resource usb_host_resources[] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index cda76eb..3509775 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -13,9 +13,11 @@
 #include <linux/serial_sci.h>
 #include <linux/mm.h>
 #include <linux/uio_driver.h>
+#include <linux/usb/m66592.h>
 #include <linux/sh_timer.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7722.h>
 
 static struct resource rtc_resources[] = {
 	[0] = {
@@ -45,11 +47,18 @@
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
+};
+
+static struct m66592_platdata usbf_platdata = {
+	.on_chip = 1,
 };
 
 static struct resource usbf_resources[] = {
 	[0] = {
-		.name	= "m66592_udc",
+		.name	= "USBF",
 		.start	= 0x04480000,
 		.end	= 0x044800FF,
 		.flags	= IORESOURCE_MEM,
@@ -67,9 +76,13 @@
 	.dev = {
 		.dma_mask		= NULL,
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(usbf_resources),
 	.resource	= usbf_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USBF,
+	},
 };
 
 static struct resource iic_resources[] = {
@@ -91,6 +104,9 @@
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC,
+	},
 };
 
 static struct uio_info vpu_platform_data = {
@@ -119,6 +135,9 @@
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 static struct uio_info veu_platform_data = {
@@ -147,6 +166,9 @@
 	},
 	.resource	= veu_resources,
 	.num_resources	= ARRAY_SIZE(veu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU,
+	},
 };
 
 static struct uio_info jpu_platform_data = {
@@ -175,6 +197,9 @@
 	},
 	.resource	= jpu_resources,
 	.num_resources	= ARRAY_SIZE(jpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_JPU,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -207,6 +232,9 @@
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -238,6 +266,9 @@
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -269,6 +300,9 @@
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -299,6 +333,9 @@
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct plat_sci_port sci_platform_data[] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index b45dace..4caa5a7 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7723.h>
 
 static struct uio_info vpu_platform_data = {
 	.name = "VPU5",
@@ -45,6 +46,9 @@
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 static struct uio_info veu0_platform_data = {
@@ -73,6 +77,9 @@
 	},
 	.resource	= veu0_resources,
 	.num_resources	= ARRAY_SIZE(veu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU2H0,
+	},
 };
 
 static struct uio_info veu1_platform_data = {
@@ -101,6 +108,9 @@
 	},
 	.resource	= veu1_resources,
 	.num_resources	= ARRAY_SIZE(veu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU2H1,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -133,6 +143,9 @@
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -164,6 +177,9 @@
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -195,6 +211,9 @@
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -225,6 +244,9 @@
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu3_platform_data = {
@@ -255,6 +277,9 @@
 	},
 	.resource	= tmu3_resources,
 	.num_resources	= ARRAY_SIZE(tmu3_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu4_platform_data = {
@@ -285,6 +310,9 @@
 	},
 	.resource	= tmu4_resources,
 	.num_resources	= ARRAY_SIZE(tmu4_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu5_platform_data = {
@@ -315,6 +343,9 @@
 	},
 	.resource	= tmu5_resources,
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct plat_sci_port sci_platform_data[] = {
@@ -395,10 +426,13 @@
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-	/* This set zero to all members */
+	.on_chip = 1,
 };
 
 static struct resource sh7723_usb_host_resources[] = {
@@ -424,6 +458,9 @@
 	},
 	.num_resources	= ARRAY_SIZE(sh7723_usb_host_resources),
 	.resource	= sh7723_usb_host_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USB,
+	},
 };
 
 static struct resource iic_resources[] = {
@@ -445,6 +482,9 @@
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC,
+	},
 };
 
 static struct platform_device *sh7723_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index a04edaa..f3851fd 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7724.h>
 
 /* Serial */
 static struct plat_sci_port sci_platform_data[] = {
@@ -103,6 +104,9 @@
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
 };
 
 /* I2C0 */
@@ -125,6 +129,9 @@
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic0_resources),
 	.resource       = iic0_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC0,
+	},
 };
 
 /* I2C1 */
@@ -147,6 +154,9 @@
 	.id             = 1, /* "i2c1" clock */
 	.num_resources  = ARRAY_SIZE(iic1_resources),
 	.resource       = iic1_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC1,
+	},
 };
 
 /* VPU */
@@ -176,6 +186,9 @@
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 /* VEU0 */
@@ -205,6 +218,9 @@
 	},
 	.resource	= veu0_resources,
 	.num_resources	= ARRAY_SIZE(veu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU0,
+	},
 };
 
 /* VEU1 */
@@ -234,6 +250,9 @@
 	},
 	.resource	= veu1_resources,
 	.num_resources	= ARRAY_SIZE(veu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU1,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -266,6 +285,9 @@
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -297,6 +319,9 @@
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -328,6 +353,9 @@
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -358,6 +386,9 @@
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 
@@ -389,6 +420,9 @@
 	},
 	.resource	= tmu3_resources,
 	.num_resources	= ARRAY_SIZE(tmu3_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu4_platform_data = {
@@ -419,6 +453,9 @@
 	},
 	.resource	= tmu4_resources,
 	.num_resources	= ARRAY_SIZE(tmu4_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu5_platform_data = {
@@ -449,6 +486,9 @@
 	},
 	.resource	= tmu5_resources,
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 /* JPU */
@@ -478,6 +518,9 @@
 	},
 	.resource	= jpu_resources,
 	.num_resources	= ARRAY_SIZE(jpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_JPU,
+	},
 };
 
 static struct platform_device *sh7724_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
new file mode 100644
index 0000000..c470e15
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -0,0 +1,513 @@
+/*
+ * SH7757 Setup
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ *  based on setup-sh7785.c : Copyright (C) 2007  Paul Mundt
+ *
+ * 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.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/sh_timer.h>
+
+static struct sh_timer_config tmu0_platform_data = {
+	.name = "TMU0",
+	.channel_offset = 0x04,
+	.timer_bit = 0,
+	.clk = "peripheral_clk",
+	.clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+	[0] = {
+		.name	= "TMU0",
+		.start	= 0xfe430008,
+		.end	= 0xfe430013,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 28,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu0_device = {
+	.name		= "sh_tmu",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &tmu0_platform_data,
+	},
+	.resource	= tmu0_resources,
+	.num_resources	= ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+	.name = "TMU1",
+	.channel_offset = 0x10,
+	.timer_bit = 1,
+	.clk = "peripheral_clk",
+	.clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+	[0] = {
+		.name	= "TMU1",
+		.start	= 0xfe430014,
+		.end	= 0xfe43001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 29,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu1_device = {
+	.name		= "sh_tmu",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &tmu1_platform_data,
+	},
+	.resource	= tmu1_resources,
+	.num_resources	= ARRAY_SIZE(tmu1_resources),
+};
+
+static struct plat_sci_port sci_platform_data[] = {
+	{
+		.mapbase	= 0xfe4b0000,		/* SCIF2 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 40, 40, 40, 40 },
+	}, {
+		.mapbase	= 0xfe4c0000,		/* SCIF3 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 76, 76, 76, 76 },
+	}, {
+		.mapbase	= 0xfe4d0000,		/* SCIF4 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 104, 104, 104, 104 },
+	}, {
+		.flags = 0,
+	}
+};
+
+static struct platform_device sci_device = {
+	.name		= "sh-sci",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= sci_platform_data,
+	},
+};
+
+static struct platform_device *sh7757_devices[] __initdata = {
+	&tmu0_device,
+	&tmu1_device,
+	&sci_device,
+};
+
+static int __init sh7757_devices_setup(void)
+{
+	return platform_add_devices(sh7757_devices,
+				    ARRAY_SIZE(sh7757_devices));
+}
+arch_initcall(sh7757_devices_setup);
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+
+	IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
+
+	IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
+	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+
+	SDHI,
+	DVC,
+	IRQ8, IRQ9, IRQ10,
+	WDT0,
+	TMU0, TMU1, TMU2, TMU2_TICPI,
+	HUDI,
+
+	ARC4,
+	DMAC0,
+	IRQ11,
+	SCIF2,
+	DMAC1_6,
+	USB0,
+	IRQ12,
+	JMC,
+	SPI1,
+	IRQ13, IRQ14,
+	USB1,
+	TMR01, TMR23, TMR45,
+	WDT1,
+	FRT,
+	LPC,
+	SCIF0, SCIF1, SCIF3,
+	PECI0I, PECI1I, PECI2I,
+	IRQ15,
+	ETHERC,
+	SPI0,
+	ADC1,
+	DMAC1_8,
+	SIM,
+	TMU3, TMU4, TMU5,
+	ADC0,
+	SCIF4,
+	IIC0_0, IIC0_1, IIC0_2, IIC0_3,
+	IIC1_0, IIC1_1, IIC1_2, IIC1_3,
+	IIC2_0, IIC2_1, IIC2_2, IIC2_3,
+	IIC3_0, IIC3_1, IIC3_2, IIC3_3,
+	IIC4_0, IIC4_1, IIC4_2, IIC4_3,
+	IIC5_0, IIC5_1, IIC5_2, IIC5_3,
+	IIC6_0, IIC6_1, IIC6_2, IIC6_3,
+	IIC7_0, IIC7_1, IIC7_2, IIC7_3,
+	IIC8_0, IIC8_1, IIC8_2, IIC8_3,
+	IIC9_0, IIC9_1, IIC9_2, IIC9_3,
+	PCIINTA,
+	PCIE,
+	SGPIO,
+
+	/* interrupt groups */
+
+	TMU012, TMU345,
+};
+
+static struct intc_vect vectors[] __initdata = {
+	INTC_VECT(SDHI, 0x480), INTC_VECT(SDHI, 0x04a0),
+	INTC_VECT(SDHI, 0x4c0),
+	INTC_VECT(DVC, 0x4e0),
+	INTC_VECT(IRQ8, 0x500), INTC_VECT(IRQ9, 0x520),
+	INTC_VECT(IRQ10, 0x540),
+	INTC_VECT(WDT0, 0x560),
+	INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
+	INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
+	INTC_VECT(HUDI, 0x600),
+	INTC_VECT(ARC4, 0x620),
+	INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
+	INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
+	INTC_VECT(DMAC0, 0x6c0),
+	INTC_VECT(IRQ11, 0x6e0),
+	INTC_VECT(SCIF2, 0x700), INTC_VECT(SCIF2, 0x720),
+	INTC_VECT(SCIF2, 0x740), INTC_VECT(SCIF2, 0x760),
+	INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
+	INTC_VECT(DMAC1_6, 0x7c0), INTC_VECT(DMAC1_6, 0x7e0),
+	INTC_VECT(USB0, 0x840),
+	INTC_VECT(IRQ12, 0x880),
+	INTC_VECT(JMC, 0x8a0),
+	INTC_VECT(SPI1, 0x8c0),
+	INTC_VECT(IRQ13, 0x8e0), INTC_VECT(IRQ14, 0x900),
+	INTC_VECT(USB1, 0x920),
+	INTC_VECT(TMR01, 0xa00), INTC_VECT(TMR23, 0xa20),
+	INTC_VECT(TMR45, 0xa40),
+	INTC_VECT(WDT1, 0xa60),
+	INTC_VECT(FRT, 0xa80),
+	INTC_VECT(LPC, 0xaa0), INTC_VECT(LPC, 0xac0),
+	INTC_VECT(LPC, 0xae0), INTC_VECT(LPC, 0xb00),
+	INTC_VECT(LPC, 0xb20),
+	INTC_VECT(SCIF0, 0xb40), INTC_VECT(SCIF1, 0xb60),
+	INTC_VECT(SCIF3, 0xb80), INTC_VECT(SCIF3, 0xba0),
+	INTC_VECT(SCIF3, 0xbc0), INTC_VECT(SCIF3, 0xbe0),
+	INTC_VECT(PECI0I, 0xc00), INTC_VECT(PECI1I, 0xc20),
+	INTC_VECT(PECI2I, 0xc40),
+	INTC_VECT(IRQ15, 0xc60),
+	INTC_VECT(ETHERC, 0xc80), INTC_VECT(ETHERC, 0xca0),
+	INTC_VECT(SPI0, 0xcc0),
+	INTC_VECT(ADC1, 0xce0),
+	INTC_VECT(DMAC1_8, 0xd00), INTC_VECT(DMAC1_8, 0xd20),
+	INTC_VECT(DMAC1_8, 0xd40), INTC_VECT(DMAC1_8, 0xd60),
+	INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
+	INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
+	INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
+	INTC_VECT(TMU5, 0xe40),
+	INTC_VECT(ADC0, 0xe60),
+	INTC_VECT(SCIF4, 0xf00), INTC_VECT(SCIF4, 0xf20),
+	INTC_VECT(SCIF4, 0xf40), INTC_VECT(SCIF4, 0xf60),
+	INTC_VECT(IIC0_0, 0x1400), INTC_VECT(IIC0_1, 0x1420),
+	INTC_VECT(IIC0_2, 0x1440), INTC_VECT(IIC0_3, 0x1460),
+	INTC_VECT(IIC1_0, 0x1480), INTC_VECT(IIC1_1, 0x14e0),
+	INTC_VECT(IIC1_2, 0x1500), INTC_VECT(IIC1_3, 0x1520),
+	INTC_VECT(IIC2_0, 0x1540), INTC_VECT(IIC2_1, 0x1560),
+	INTC_VECT(IIC2_2, 0x1580), INTC_VECT(IIC2_3, 0x1600),
+	INTC_VECT(IIC3_0, 0x1620), INTC_VECT(IIC3_1, 0x1640),
+	INTC_VECT(IIC3_2, 0x16e0), INTC_VECT(IIC3_3, 0x1700),
+	INTC_VECT(IIC4_0, 0x17c0), INTC_VECT(IIC4_1, 0x1800),
+	INTC_VECT(IIC4_2, 0x1820), INTC_VECT(IIC4_3, 0x1840),
+	INTC_VECT(IIC5_0, 0x1860), INTC_VECT(IIC5_1, 0x1880),
+	INTC_VECT(IIC5_2, 0x18a0), INTC_VECT(IIC5_3, 0x18c0),
+	INTC_VECT(IIC6_0, 0x18e0), INTC_VECT(IIC6_1, 0x1900),
+	INTC_VECT(IIC6_2, 0x1920), INTC_VECT(IIC6_3, 0x1980),
+	INTC_VECT(IIC7_0, 0x19a0), INTC_VECT(IIC7_1, 0x1a00),
+	INTC_VECT(IIC7_2, 0x1a20), INTC_VECT(IIC7_3, 0x1a40),
+	INTC_VECT(IIC8_0, 0x1a60), INTC_VECT(IIC8_1, 0x1a80),
+	INTC_VECT(IIC8_2, 0x1aa0), INTC_VECT(IIC8_3, 0x1b40),
+	INTC_VECT(IIC9_0, 0x1b60), INTC_VECT(IIC9_1, 0x1b80),
+	INTC_VECT(IIC9_2, 0x1c00), INTC_VECT(IIC9_3, 0x1c20),
+	INTC_VECT(PCIINTA, 0x1ce0),
+	INTC_VECT(PCIE, 0x1e00),
+	INTC_VECT(SGPIO, 0x1f80),
+	INTC_VECT(SGPIO, 0x1fa0),
+};
+
+static struct intc_group groups[] __initdata = {
+	INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
+	INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+	{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+
+	{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
+	  { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	    IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	    IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	    IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
+	    IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	    IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	    IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	    IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
+
+	{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
+	  { 0, 0, 0, 0, 0, 0, 0, 0,
+	    0, DMAC1_8, 0, PECI0I, LPC, FRT, WDT1, TMR45,
+	    TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0,
+	    HUDI, 0, WDT0, SCIF3, SCIF2, SDHI, TMU345, TMU012
+	     } },
+
+	{ 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
+	  { IRQ15, IRQ14, IRQ13, IRQ12, IRQ11, IRQ10, SCIF4, ETHERC,
+	    IRQ9, IRQ8, SCIF1, SCIF0, USB0, 0, 0, USB1,
+	    ADC1, 0, DMAC1_6, ADC0, SPI0, SIM, PECI2I, PECI1I,
+	    ARC4, 0, SPI1, JMC, 0, 0, 0, DVC
+	     } },
+
+	{ 0xffd10038, 0xffd1003c, 32, /* INT2MSKR2 / INT2MSKCR2 */
+	  { IIC4_1, IIC4_2, IIC5_0, 0, 0, 0, SGPIO, 0,
+	    0, 0, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
+	    IIC7_2, IIC7_1, IIC6_3, IIC0_0, IIC0_1, IIC0_2, IIC0_3, IIC3_1,
+	    IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, PCIE, IIC2_2
+	     } },
+
+	{ 0xffd100d0, 0xff1400d4, 32, /* INT2MSKR3 / INT2MSKCR4 */
+	  { 0, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, 0, 0,
+	    IIC1_3, IIC1_2, IIC9_0, IIC8_3, IIC4_3, IIC7_0, 0, IIC6_2,
+	    PCIINTA, 0, IIC4_0, 0, 0, 0, 0, IIC9_3,
+	    IIC3_0, 0, IIC5_3, IIC5_2, 0, 0, 0, IIC1_1
+	     } },
+};
+
+#define INTPRI		0xffd00010
+#define INT2PRI0	0xffd40000
+#define INT2PRI1	0xffd40004
+#define INT2PRI2	0xffd40008
+#define INT2PRI3	0xffd4000c
+#define INT2PRI4	0xffd40010
+#define INT2PRI5	0xffd40014
+#define INT2PRI6	0xffd40018
+#define INT2PRI7	0xffd4001c
+#define INT2PRI8	0xffd400a0
+#define INT2PRI9	0xffd400a4
+#define INT2PRI10	0xffd400a8
+#define INT2PRI11	0xffd400ac
+#define INT2PRI12	0xffd400b0
+#define INT2PRI13	0xffd400b4
+#define INT2PRI14	0xffd400b8
+#define INT2PRI15	0xffd400bc
+#define INT2PRI16	0xffd10000
+#define INT2PRI17	0xffd10004
+#define INT2PRI18	0xffd10008
+#define INT2PRI19	0xffd1000c
+#define INT2PRI20	0xffd10010
+#define INT2PRI21	0xffd10014
+#define INT2PRI22	0xffd10018
+#define INT2PRI23	0xffd1001c
+#define INT2PRI24	0xffd100a0
+#define INT2PRI25	0xffd100a4
+#define INT2PRI26	0xffd100a8
+#define INT2PRI27	0xffd100ac
+#define INT2PRI28	0xffd100b0
+#define INT2PRI29	0xffd100b4
+#define INT2PRI30	0xffd100b8
+#define INT2PRI31	0xffd100bc
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+	{ INTPRI, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
+			      IRQ4, IRQ5, IRQ6, IRQ7 } },
+
+	{ INT2PRI0, 0, 32, 8, { TMU0, TMU1, TMU2, TMU2_TICPI } },
+	{ INT2PRI1, 0, 32, 8, { TMU3, TMU4, TMU5, SDHI } },
+	{ INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, WDT0, IRQ8 } },
+	{ INT2PRI3, 0, 32, 8, { HUDI, DMAC0, ADC0, IRQ9 } },
+	{ INT2PRI4, 0, 32, 8, { IRQ10, 0, TMR01, TMR23 } },
+	{ INT2PRI5, 0, 32, 8, { TMR45, WDT1, FRT, LPC } },
+	{ INT2PRI6, 0, 32, 8, { PECI0I, ETHERC, DMAC1_8, 0 } },
+	{ INT2PRI7, 0, 32, 8, { SCIF4, 0, IRQ11, IRQ12 } },
+	{ INT2PRI8, 0, 32, 8, { 0, 0, 0, DVC } },
+	{ INT2PRI9, 0, 32, 8, { ARC4, 0, SPI1, JMC } },
+	{ INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2I, PECI1I } },
+	{ INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC1_6, IRQ14 } },
+	{ INT2PRI12, 0, 32, 8, { USB0, 0, IRQ15, USB1 } },
+	{ INT2PRI13, 0, 32, 8, { 0, 0, SCIF1, SCIF0 } },
+
+	{ INT2PRI16, 0, 32, 8, { IIC2_2, 0, 0, 0 } },
+	{ INT2PRI17, 0, 32, 8, { PCIE, 0, 0, IIC1_0 } },
+	{ INT2PRI18, 0, 32, 8, { IIC3_3, IIC9_1, IIC2_1, IIC1_2 } },
+	{ INT2PRI19, 0, 32, 8, { IIC2_3, IIC3_1, 0, IIC1_3 } },
+	{ INT2PRI20, 0, 32, 8, { IIC2_0, IIC6_3, IIC7_1, IIC7_2 } },
+	{ INT2PRI21, 0, 32, 8, { IIC7_3, IIC8_0, IIC8_1, IIC8_2 } },
+	{ INT2PRI22, 0, 32, 8, { IIC9_2, 0, 0, 0 } },
+	{ INT2PRI23, 0, 32, 8, { 0, SGPIO, IIC3_2, IIC5_1 } },
+	{ INT2PRI24, 0, 32, 8, { 0, 0, 0, IIC1_1 } },
+	{ INT2PRI25, 0, 32, 8, { IIC3_0, 0, IIC5_3, IIC5_2 } },
+	{ INT2PRI26, 0, 32, 8, { 0, 0, 0, IIC9_3 } },
+	{ INT2PRI27, 0, 32, 8, { PCIINTA, IIC6_0, IIC4_0, IIC6_1 } },
+	{ INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, 0, IIC6_2 } },
+	{ INT2PRI29, 0, 32, 8, { 0, 0, IIC9_0, IIC8_3 } },
+	{ INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, 0 } },
+	{ INT2PRI31, 0, 32, 8, { IIC0_0, IIC0_1, IIC0_2, IIC0_3 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups,
+			 mask_registers, prio_registers, NULL);
+
+/* Support for external interrupt pins in IRQ mode */
+static struct intc_vect vectors_irq0123[] __initdata = {
+	INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
+	INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
+};
+
+static struct intc_vect vectors_irq4567[] __initdata = {
+	INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
+	INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+	{ 0xffd0001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
+					    IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+	{ 0xffd00024, 0, 32, /* INTREQ */
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7757-irq0123",
+			     vectors_irq0123, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7757-irq4567",
+			     vectors_irq4567, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+/* External interrupt pins in IRL mode */
+static struct intc_vect vectors_irl0123[] __initdata = {
+	INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
+	INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
+	INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
+	INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
+	INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
+	INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
+	INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
+	INTC_VECT(IRL0_HHHL, 0x3c0),
+};
+
+static struct intc_vect vectors_irl4567[] __initdata = {
+	INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
+	INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
+	INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
+	INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
+	INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
+	INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
+	INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
+	INTC_VECT(IRL4_HHHL, 0xcc0),
+};
+
+static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7757-irl0123", vectors_irl0123,
+			 NULL, mask_registers, NULL, NULL);
+
+static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7757-irl4567", vectors_irl4567,
+			 NULL, mask_registers, NULL, NULL);
+
+#define INTC_ICR0	0xffd00000
+#define INTC_INTMSK0	0xffd00044
+#define INTC_INTMSK1	0xffd00048
+#define INTC_INTMSK2	0xffd40080
+#define INTC_INTMSKCLR1	0xffd00068
+#define INTC_INTMSKCLR2	0xffd40084
+
+void __init plat_irq_setup(void)
+{
+	/* disable IRQ3-0 + IRQ7-4 */
+	ctrl_outl(0xff000000, INTC_INTMSK0);
+
+	/* disable IRL3-0 + IRL7-4 */
+	ctrl_outl(0xc0000000, INTC_INTMSK1);
+	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+
+	/* select IRL mode for IRL3-0 + IRL7-4 */
+	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+
+	/* disable holding function, ie enable "SH-4 Mode" */
+	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+
+	register_intc_controller(&intc_desc);
+}
+
+void __init plat_irq_setup_pins(int mode)
+{
+	switch (mode) {
+	case IRQ_MODE_IRQ7654:
+		/* select IRQ mode for IRL7-4 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq4567);
+		break;
+	case IRQ_MODE_IRQ3210:
+		/* select IRQ mode for IRL3-0 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq0123);
+		break;
+	case IRQ_MODE_IRL7654:
+		/* enable IRL7-4 but don't provide any masking */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL3210:
+		/* enable IRL0-3 but don't provide any masking */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL7654_MASK:
+		/* enable IRL7-4 and mask using cpu intc controller */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl4567);
+		break;
+	case IRQ_MODE_IRL3210_MASK:
+		/* enable IRL0-3 and mask using cpu intc controller */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl0123);
+		break;
+	default:
+		BUG();
+	}
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 07f0789..e848443 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -268,11 +268,7 @@
 	UNUSED = 0,
 
 	/* interrupt sources */
-	IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
-	IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
-	IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
-	IRL_HHLL, IRL_HHLH, IRL_HHHL,
-	IRQ0, IRQ1, IRQ2, IRQ3,
+	IRL, IRQ0, IRQ1, IRQ2, IRQ3,
 	HUDII,
 	TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
 	PCII0, PCII1, PCII2, PCII3, PCII4,
@@ -287,10 +283,7 @@
 	DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
 	DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
 	IIC, VIN0, VIN1, VCORE0, ATAPI,
-	DTU0_TEND, DTU0_AE, DTU0_TMISS,
-	DTU1_TEND, DTU1_AE, DTU1_TMISS,
-	DTU2_TEND, DTU2_AE, DTU2_TMISS,
-	DTU3_TEND, DTU3_AE, DTU3_TMISS,
+	DTU0, DTU1, DTU2, DTU3,
 	FE0, FE1,
 	GPIO0, GPIO1, GPIO2, GPIO3,
 	PAM, IRM,
@@ -298,8 +291,8 @@
 	INTICI4, INTICI5, INTICI6, INTICI7,
 
 	/* interrupt groups */
-	IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
-	DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3,
+	PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
+	DMAC0, DMAC1,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -332,14 +325,14 @@
 	INTC_VECT(IIC, 0xae0),
 	INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
 	INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
-	INTC_VECT(DTU0_TEND, 0xc00), INTC_VECT(DTU0_AE, 0xc20),
-	INTC_VECT(DTU0_TMISS, 0xc40),
-	INTC_VECT(DTU1_TEND, 0xc60), INTC_VECT(DTU1_AE, 0xc80),
-	INTC_VECT(DTU1_TMISS, 0xca0),
-	INTC_VECT(DTU2_TEND, 0xcc0), INTC_VECT(DTU2_AE, 0xce0),
-	INTC_VECT(DTU2_TMISS, 0xd00),
-	INTC_VECT(DTU3_TEND, 0xd20), INTC_VECT(DTU3_AE, 0xd40),
-	INTC_VECT(DTU3_TMISS, 0xd60),
+	INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
+	INTC_VECT(DTU0, 0xc40),
+	INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
+	INTC_VECT(DTU1, 0xca0),
+	INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
+	INTC_VECT(DTU2, 0xd00),
+	INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
+	INTC_VECT(DTU3, 0xd60),
 	INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
 	INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
 	INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
@@ -351,10 +344,6 @@
 };
 
 static struct intc_group groups[] __initdata = {
-	INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
-		   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
-		   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
-		   IRL_HHLL, IRL_HHLH, IRL_HHHL),
 	INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
 	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
 	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
@@ -364,10 +353,6 @@
 		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
 	INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
 		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
-	INTC_GROUP(DTU0, DTU0_TEND, DTU0_AE, DTU0_TMISS),
-	INTC_GROUP(DTU1, DTU1_TEND, DTU1_AE, DTU1_TMISS),
-	INTC_GROUP(DTU2, DTU2_TEND, DTU2_AE, DTU2_TMISS),
-	INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
@@ -434,14 +419,14 @@
 
 /* External interrupt pins in IRL mode */
 static struct intc_vect vectors_irl[] __initdata = {
-	INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
-	INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
-	INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
-	INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
-	INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
-	INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
-	INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
-	INTC_VECT(IRL_HHHL, 0x3c0),
+	INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220),
+	INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260),
+	INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0),
+	INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0),
+	INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320),
+	INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360),
+	INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0),
+	INTC_VECT(IRL, 0x3c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 2b6b0d5..185ec39 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -57,6 +57,8 @@
 {
 	int i;
 
+	local_timer_setup(0);
+
 	BUILD_BUG_ON(SMP_MSG_NR >= 8);
 
 	for (i = 0; i < SMP_MSG_NR; i++)
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c
index 92ad844..521d05b 100644
--- a/arch/sh/kernel/cpu/sh5/probe.c
+++ b/arch/sh/kernel/cpu/sh5/probe.c
@@ -34,6 +34,8 @@
 		/* CPU.VCR aliased at CIR address on SH5-101 */
 		boot_cpu_data.type = CPU_SH5_101;
 
+	boot_cpu_data.family = CPU_FAMILY_SH5;
+
 	/*
 	 * First, setup some sane values for the I-cache.
 	 */
diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile
index 08bfa7c..a39f88e 100644
--- a/arch/sh/kernel/cpu/shmobile/Makefile
+++ b/arch/sh/kernel/cpu/shmobile/Makefile
@@ -4,3 +4,5 @@
 
 # Power Management & Sleep mode
 obj-$(CONFIG_PM)	+= pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE)	+= cpuidle.o
+obj-$(CONFIG_PM_RUNTIME)	+= pm_runtime.o
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
new file mode 100644
index 0000000..1c504bd
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -0,0 +1,113 @@
+/*
+ * arch/sh/kernel/cpu/shmobile/cpuidle.c
+ *
+ * Cpuidle support code for SuperH Mobile
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/cpuidle.h>
+#include <asm/suspend.h>
+#include <asm/uaccess.h>
+#include <asm/hwblk.h>
+
+static unsigned long cpuidle_mode[] = {
+	SUSP_SH_SLEEP, /* regular sleep mode */
+	SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
+	SUSP_SH_STANDBY | SUSP_SH_SF, /* software standby mode + self refresh */
+};
+
+static int cpuidle_sleep_enter(struct cpuidle_device *dev,
+			       struct cpuidle_state *state)
+{
+	unsigned long allowed_mode = arch_hwblk_sleep_mode();
+	ktime_t before, after;
+	int requested_state = state - &dev->states[0];
+	int allowed_state;
+	int k;
+
+	/* convert allowed mode to allowed state */
+	for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
+		if (cpuidle_mode[k] == allowed_mode)
+			break;
+
+	allowed_state = k;
+
+	/* take the following into account for sleep mode selection:
+	 * - allowed_state: best mode allowed by hardware (clock deps)
+	 * - requested_state: best mode allowed by software (latencies)
+	 */
+	k = min_t(int, allowed_state, requested_state);
+
+	dev->last_state = &dev->states[k];
+	before = ktime_get();
+	sh_mobile_call_standby(cpuidle_mode[k]);
+	after = ktime_get();
+	return ktime_to_ns(ktime_sub(after, before)) >> 10;
+}
+
+static struct cpuidle_device cpuidle_dev;
+static struct cpuidle_driver cpuidle_driver = {
+	.name =		"sh_idle",
+	.owner =	THIS_MODULE,
+};
+
+void sh_mobile_setup_cpuidle(void)
+{
+	struct cpuidle_device *dev = &cpuidle_dev;
+	struct cpuidle_state *state;
+	int i;
+
+	cpuidle_register_driver(&cpuidle_driver);
+
+	for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+		dev->states[i].name[0] = '\0';
+		dev->states[i].desc[0] = '\0';
+	}
+
+	i = CPUIDLE_DRIVER_STATE_START;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
+	strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
+	state->exit_latency = 1;
+	state->target_residency = 1 * 2;
+	state->power_usage = 3;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_SHALLOW;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	dev->safe_state = state;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+	strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
+	state->exit_latency = 100;
+	state->target_residency = 1 * 2;
+	state->power_usage = 1;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+	strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
+	state->exit_latency = 2300;
+	state->target_residency = 1 * 2;
+	state->power_usage = 1;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	dev->state_count = i;
+
+	cpuidle_register_device(dev);
+}
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index 8c067adf..ee3c2aa 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
+ * arch/sh/kernel/cpu/shmobile/pm.c
  *
  * Power management support code for SuperH Mobile
  *
@@ -32,40 +32,20 @@
  *
  * R-standby mode is unsupported, but will be added in the future
  * U-standby mode is low priority since it needs bootloader hacks
- *
- * All modes should be tied in with cpuidle. But before that can
- * happen we need to keep track of enabled hardware blocks so we
- * can avoid entering sleep modes that stop clocks to hardware
- * blocks that are in use even though the cpu core is idle.
  */
 
+#define ILRAM_BASE 0xe5200000
+
 extern const unsigned char sh_mobile_standby[];
 extern const unsigned int sh_mobile_standby_size;
 
-static void sh_mobile_call_standby(unsigned long mode)
+void sh_mobile_call_standby(unsigned long mode)
 {
-	extern void *vbr_base;
-	void *onchip_mem = (void *)0xe5200000; /* ILRAM */
-	void (*standby_onchip_mem)(unsigned long) = onchip_mem;
-
-	/* Note: Wake up from sleep may generate exceptions!
-	 * Setup VBR to point to on-chip ram if self-refresh is
-	 * going to be used.
-	 */
-	if (mode & SUSP_SH_SF)
-		asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
-
-	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
-	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
-	wmb();
-	ctrl_barrier();
+	void *onchip_mem = (void *)ILRAM_BASE;
+	void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem;
 
 	/* Let assembly snippet in on-chip memory handle the rest */
-	standby_onchip_mem(mode);
-
-	/* Put VBR back in System RAM again */
-	if (mode & SUSP_SH_SF)
-		asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+	standby_onchip_mem(mode, ILRAM_BASE);
 }
 
 static int sh_pm_enter(suspend_state_t state)
@@ -85,7 +65,15 @@
 
 static int __init sh_pm_init(void)
 {
+	void *onchip_mem = (void *)ILRAM_BASE;
+
+	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
+	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
+	wmb();
+	ctrl_barrier();
+
 	suspend_set_ops(&sh_pm_ops);
+	sh_mobile_setup_cpuidle();
 	return 0;
 }
 
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
new file mode 100644
index 0000000..7c615b1
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
@@ -0,0 +1,303 @@
+/*
+ * arch/sh/kernel/cpu/shmobile/pm_runtime.c
+ *
+ * Runtime PM support code for SuperH Mobile
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <asm/hwblk.h>
+
+static DEFINE_SPINLOCK(hwblk_lock);
+static LIST_HEAD(hwblk_idle_list);
+static struct work_struct hwblk_work;
+
+extern struct hwblk_info *hwblk_info;
+
+static void platform_pm_runtime_not_idle(struct platform_device *pdev)
+{
+	unsigned long flags;
+
+	/* remove device from idle list */
+	spin_lock_irqsave(&hwblk_lock, flags);
+	if (test_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags)) {
+		list_del(&pdev->archdata.entry);
+		__clear_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
+	}
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+static int __platform_pm_runtime_resume(struct platform_device *pdev)
+{
+	struct device *d = &pdev->dev;
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = -ENOSYS;
+
+	dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
+
+	if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) {
+		hwblk_enable(hwblk_info, hwblk);
+		ret = 0;
+
+		if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
+			ret = d->driver->pm->runtime_resume(d);
+			if (!ret)
+				clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
+			else
+				hwblk_disable(hwblk_info, hwblk);
+		}
+	}
+
+	dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+static int __platform_pm_runtime_suspend(struct platform_device *pdev)
+{
+	struct device *d = &pdev->dev;
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = -ENOSYS;
+
+	dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
+
+	if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) {
+		BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
+
+		hwblk_enable(hwblk_info, hwblk);
+		ret = d->driver->pm->runtime_suspend(d);
+		hwblk_disable(hwblk_info, hwblk);
+
+		if (!ret) {
+			set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
+			platform_pm_runtime_not_idle(pdev);
+			hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+		}
+	}
+
+	dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+static void platform_pm_runtime_work(struct work_struct *work)
+{
+	struct platform_device *pdev;
+	unsigned long flags;
+	int ret;
+
+	/* go through the idle list and suspend one device at a time */
+	do {
+		spin_lock_irqsave(&hwblk_lock, flags);
+		if (list_empty(&hwblk_idle_list))
+			pdev = NULL;
+		else
+			pdev = list_first_entry(&hwblk_idle_list,
+						struct platform_device,
+						archdata.entry);
+		spin_unlock_irqrestore(&hwblk_lock, flags);
+
+		if (pdev) {
+			mutex_lock(&pdev->archdata.mutex);
+			ret = __platform_pm_runtime_suspend(pdev);
+
+			/* at this point the platform device may be:
+			 * suspended: ret = 0, FLAG_SUSP set, clock stopped
+			 * failed: ret < 0, FLAG_IDLE set, clock stopped
+			 */
+			mutex_unlock(&pdev->archdata.mutex);
+		} else {
+			ret = -ENODEV;
+		}
+	} while (!ret);
+}
+
+/* this function gets called from cpuidle context when all devices in the
+ * main power domain are unused but some are counted as idle, ie the hwblk
+ * counter values are (HWBLK_CNT_USAGE == 0) && (HWBLK_CNT_IDLE != 0)
+ */
+void platform_pm_runtime_suspend_idle(void)
+{
+	queue_work(pm_wq, &hwblk_work);
+}
+
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pdev_archdata *ad = &pdev->archdata;
+	unsigned long flags;
+	int hwblk = ad->hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_suspend() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed */
+	might_sleep();
+
+	/* catch misconfigured drivers not starting with resume */
+	if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* serialize */
+	mutex_lock(&ad->mutex);
+
+	/* disable clock */
+	hwblk_disable(hwblk_info, hwblk);
+
+	/* put device on idle list */
+	spin_lock_irqsave(&hwblk_lock, flags);
+	list_add_tail(&pdev->archdata.entry, &hwblk_idle_list);
+	__set_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+
+	/* increase idle count */
+	hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+
+	/* at this point the platform device is:
+	 * idle: ret = 0, FLAG_IDLE set, clock stopped
+	 */
+	mutex_unlock(&ad->mutex);
+
+out:
+	dev_dbg(dev, "platform_pm_runtime_suspend() [%d] returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_resume() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed */
+	might_sleep();
+
+	/* serialize */
+	mutex_lock(&ad->mutex);
+
+	/* make sure device is removed from idle list */
+	platform_pm_runtime_not_idle(pdev);
+
+	/* decrease idle count */
+	if (!test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags) &&
+	    !test_bit(PDEV_ARCHDATA_FLAG_SUSP, &pdev->archdata.flags))
+		hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+
+	/* resume the device if needed */
+	ret = __platform_pm_runtime_resume(pdev);
+
+	/* the driver has been initialized now, so clear the init flag */
+	clear_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+
+	/* at this point the platform device may be:
+	 * resumed: ret = 0, flags = 0, clock started
+	 * failed: ret < 0, FLAG_SUSP set, clock stopped
+	 */
+	mutex_unlock(&ad->mutex);
+out:
+	dev_dbg(dev, "platform_pm_runtime_resume() [%d] returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int hwblk = pdev->archdata.hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_idle() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed, use pm_runtime_put()! */
+	might_sleep();
+
+	/* suspend synchronously to disable clocks immediately */
+	ret = pm_runtime_suspend(dev);
+out:
+	dev_dbg(dev, "platform_pm_runtime_idle() [%d] done!\n", hwblk);
+	return ret;
+}
+
+static int platform_bus_notify(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct platform_device *pdev = to_platform_device(dev);
+	int hwblk = pdev->archdata.hwblk_id;
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		return 0;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		INIT_LIST_HEAD(&pdev->archdata.entry);
+		mutex_init(&pdev->archdata.mutex);
+		/* platform devices without drivers should be disabled */
+		hwblk_enable(hwblk_info, hwblk);
+		hwblk_disable(hwblk_info, hwblk);
+		/* make sure driver re-inits itself once */
+		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+		break;
+	/* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
+	case BUS_NOTIFY_BOUND_DRIVER:
+		/* keep track of number of devices in use per hwblk */
+		hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		/* keep track of number of devices in use per hwblk */
+		hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
+		/* make sure driver re-inits itself once */
+		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+		break;
+	case BUS_NOTIFY_DEL_DEVICE:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block platform_bus_notifier = {
+	.notifier_call = platform_bus_notify
+};
+
+static int __init sh_pm_runtime_init(void)
+{
+	INIT_WORK(&hwblk_work, platform_pm_runtime_work);
+
+	bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
+	return 0;
+}
+core_initcall(sh_pm_runtime_init);
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index baf2d7d..a439e6c 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -16,19 +16,52 @@
 #include <asm/asm-offsets.h>
 #include <asm/suspend.h>
 
+/*
+ * Kernel mode register usage, see entry.S:
+ *	k0	scratch
+ *	k1	scratch
+ *	k4	scratch
+ */
+#define k0	r0
+#define k1	r1
+#define k4	r4
+
 /* manage self-refresh and enter standby mode.
  * this code will be copied to on-chip memory and executed from there.
  */
 
 	.balign 	4096,0,4096
 ENTRY(sh_mobile_standby)
+
+	/* save original vbr */
+	stc	vbr, r1
+	mova	saved_vbr, r0
+	mov.l	r1, @r0
+
+	/* point vbr to our on-chip memory page */
+	ldc	r5, vbr
+
+	/* save return address */
+	mova	saved_spc, r0
+	sts	pr, r5
+	mov.l	r5, @r0
+
+	/* save sr */
+	mova	saved_sr, r0
+	stc	sr, r5
+	mov.l	r5, @r0
+
+	/* save mode flags */
+	mova	saved_mode, r0
+	mov.l	r4, @r0
+
+	/* put mode flags in r0 */
 	mov	r4, r0
 
 	tst	#SUSP_SH_SF, r0
 	bt	skip_set_sf
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 	/* DBSC: put memory in self-refresh mode */
-
 	mov.l	dben_reg, r4
 	mov.l	dben_data0, r1
 	mov.l	r1, @r4
@@ -60,14 +93,6 @@
 #endif
 
 skip_set_sf:
-	tst	#SUSP_SH_SLEEP, r0
-	bt	test_standby
-
-	/* set mode to "sleep mode" */
-	bra	do_sleep
-	 mov	#0x00, r1
-
-test_standby:
 	tst	#SUSP_SH_STANDBY, r0
 	bt	test_rstandby
 
@@ -85,77 +110,107 @@
 
 test_ustandby:
 	tst	#SUSP_SH_USTANDBY, r0
-	bt	done_sleep
+	bt	force_sleep
 
 	/* set mode to "u-standby mode" */
-	mov	#0x10, r1
+	bra	do_sleep
+	 mov	#0x10, r1
 
-	/* fall-through */
+force_sleep:
+
+	/* set mode to "sleep mode" */
+	mov	#0x00, r1
 
 do_sleep:
 	/* setup and enter selected standby mode */
 	mov.l	5f, r4
 	mov.l	r1, @r4
+again:
 	sleep
+	bra	again
+	 nop
+
+restore_jump_vbr:
+	/* setup spc with return address to c code */
+	mov.l	saved_spc, k0
+	ldc	k0, spc
+
+	/* restore vbr */
+	mov.l	saved_vbr, k0
+	ldc	k0, vbr
+
+	/* setup ssr with saved sr */
+	mov.l	saved_sr, k0
+	ldc	k0, ssr
+
+	/* get mode flags */
+	mov.l	saved_mode, k0
 
 done_sleep:
 	/* reset standby mode to sleep mode */
-	mov.l	5f, r4
-	mov	#0x00, r1
-	mov.l	r1, @r4
+	mov.l	5f, k4
+	mov	#0x00, k1
+	mov.l	k1, @k4
 
-	tst	#SUSP_SH_SF, r0
+	tst	#SUSP_SH_SF, k0
 	bt	skip_restore_sf
 
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 	/* DBSC: put memory in auto-refresh mode */
+	mov.l	dbrfpdn0_reg, k4
+	mov.l	dbrfpdn0_data0, k1
+	mov.l	k1, @k4
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data0, r1
-	mov.l	r1, @r4
-
-	/* sleep 140 ns */
+	nop /* sleep 140 ns */
 	nop
 	nop
 	nop
-	nop
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data0, r1
-	mov.l	r1, @r4
+	mov.l	dbcmdcnt_reg, k4
+	mov.l	dbcmdcnt_data0, k1
+	mov.l	k1, @k4
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data1, r1
-	mov.l	r1, @r4
+	mov.l	dbcmdcnt_reg, k4
+	mov.l	dbcmdcnt_data1, k1
+	mov.l	k1, @k4
 
-	mov.l	dben_reg, r4
-	mov.l	dben_data1, r1
-	mov.l	r1, @r4
+	mov.l	dben_reg, k4
+	mov.l	dben_data1, k1
+	mov.l	k1, @k4
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data2, r1
-	mov.l	r1, @r4
+	mov.l	dbrfpdn0_reg, k4
+	mov.l	dbrfpdn0_data2, k1
+	mov.l	k1, @k4
 #else
 	/* SBSC: set auto-refresh mode */
-	mov.l	1f, r4
-	mov.l	@r4, r2
-	mov.l   4f, r3
-	and	r3, r2
-	mov.l	r2, @r4
-	mov.l	6f, r4
-	mov.l	7f, r1
-	mov.l	8f, r2
-	mov.l	@r4, r3
-	mov	#-1, r4
-	add	r4, r3
-	or	r2, r3
-	mov.l	r3, @r1
+	mov.l	1f, k4
+	mov.l	@k4, k0
+	mov.l   4f, k1
+	and	k1, k0
+	mov.l	k0, @k4
+	mov.l	6f, k4
+	mov.l	8f, k0
+	mov.l	@k4, k1
+	mov	#-1, k4
+	add	k4, k1
+	or	k1, k0
+	mov.l	7f, k1
+	mov.l	k0, @k1
 #endif
 skip_restore_sf:
-	rts
+	/* jump to vbr vector */
+	mov.l	saved_vbr, k0
+	mov.l	offset_vbr, k4
+	add	k4, k0
+	jmp	@k0
 	 nop
 
 	.balign 4
+saved_mode:	.long	0
+saved_spc:	.long	0
+saved_sr:	.long	0
+saved_vbr:	.long	0
+offset_vbr:	.long	0x600
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 dben_reg:	.long	0xfd000010 /* DBEN */
 dben_data0:	.long	0
@@ -178,12 +233,12 @@
 7:	.long   0xfe400018 /* RTCNT */
 8:	.long   0xa55a0000
 
+
 /* interrupt vector @ 0x600 */
 	.balign 	0x400,0,0x400
 	.long	0xdeadbeef
 	.balign 	0x200,0,0x200
-	/* sh7722 will end up here in sleep mode */
-	rte
+	bra	restore_jump_vbr
 	 nop
 sh_mobile_standby_end:
 
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index e0590ff..dce4f3f 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -82,7 +82,8 @@
 
 	cpuclk = clk_get(NULL, "cpu_clk");
 	if (IS_ERR(cpuclk)) {
-		printk(KERN_ERR "cpufreq: couldn't get CPU clk\n");
+		printk(KERN_ERR "cpufreq: couldn't get CPU#%d clk\n",
+		       policy->cpu);
 		return PTR_ERR(cpuclk);
 	}
 
@@ -95,22 +96,21 @@
 	policy->min		= policy->cpuinfo.min_freq;
 	policy->max		= policy->cpuinfo.max_freq;
 
-
 	/*
 	 * Catch the cases where the clock framework hasn't been wired up
 	 * properly to support scaling.
 	 */
 	if (unlikely(policy->min == policy->max)) {
 		printk(KERN_ERR "cpufreq: clock framework rate rounding "
-		       "not supported on this CPU.\n");
+		       "not supported on CPU#%d.\n", policy->cpu);
 
 		clk_put(cpuclk);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "cpufreq: Frequencies - Minimum %u.%03u MHz, "
+	printk(KERN_INFO "cpufreq: CPU#%d Frequencies - Minimum %u.%03u MHz, "
 	       "Maximum %u.%03u MHz.\n",
-	       policy->min / 1000, policy->min % 1000,
+	       policy->cpu, policy->min / 1000, policy->min % 1000,
 	       policy->max / 1000, policy->max % 1000);
 
 	return 0;
diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c
new file mode 100644
index 0000000..6f5ad15
--- /dev/null
+++ b/arch/sh/kernel/dumpstack.c
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
+ *  Copyright (C) 2009  Matt Fleming
+ */
+#include <linux/kallsyms.h>
+#include <linux/ftrace.h>
+#include <linux/debug_locks.h>
+#include <asm/unwinder.h>
+#include <asm/stacktrace.h>
+
+void printk_address(unsigned long address, int reliable)
+{
+	printk(" [<%p>] %s%pS\n", (void *) address,
+			reliable ? "" : "? ", (void *) address);
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+			const struct stacktrace_ops *ops,
+			struct thread_info *tinfo, int *graph)
+{
+	struct task_struct *task = tinfo->task;
+	unsigned long ret_addr;
+	int index = task->curr_ret_stack;
+
+	if (addr != (unsigned long)return_to_handler)
+		return;
+
+	if (!task->ret_stack || index < *graph)
+		return;
+
+	index -= *graph;
+	ret_addr = task->ret_stack[index].ret;
+
+	ops->address(data, ret_addr, 1);
+
+	(*graph)++;
+}
+#else
+static inline void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+			const struct stacktrace_ops *ops,
+			struct thread_info *tinfo, int *graph)
+{ }
+#endif
+
+void
+stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
+		  unsigned long *sp, const struct stacktrace_ops *ops,
+		  void *data)
+{
+	struct thread_info *context;
+	int graph = 0;
+
+	context = (struct thread_info *)
+		((unsigned long)sp & (~(THREAD_SIZE - 1)));
+
+	while (!kstack_end(sp)) {
+		unsigned long addr = *sp++;
+
+		if (__kernel_text_address(addr)) {
+			ops->address(data, addr, 1);
+
+			print_ftrace_graph_addr(addr, data, ops,
+						context, &graph);
+		}
+	}
+}
+
+static void
+print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+	printk(data);
+	print_symbol(msg, symbol);
+	printk("\n");
+}
+
+static void print_trace_warning(void *data, char *msg)
+{
+	printk("%s%s\n", (char *)data, msg);
+}
+
+static int print_trace_stack(void *data, char *name)
+{
+	printk("%s <%s> ", (char *)data, name);
+	return 0;
+}
+
+/*
+ * Print one address/symbol entries per line.
+ */
+static void print_trace_address(void *data, unsigned long addr, int reliable)
+{
+	printk(data);
+	printk_address(addr, reliable);
+}
+
+static const struct stacktrace_ops print_trace_ops = {
+	.warning = print_trace_warning,
+	.warning_symbol = print_trace_warning_symbol,
+	.stack = print_trace_stack,
+	.address = print_trace_address,
+};
+
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+		struct pt_regs *regs)
+{
+	if (regs && user_mode(regs))
+		return;
+
+	printk("\nCall trace:\n");
+
+	unwind_stack(tsk, regs, sp, &print_trace_ops, "");
+
+	printk("\n");
+
+	if (!tsk)
+		tsk = current;
+
+	debug_show_held_locks(tsk);
+}
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
new file mode 100644
index 0000000..bc4d8d7
--- /dev/null
+++ b/arch/sh/kernel/dwarf.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * 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.
+ *
+ * This is an implementation of a DWARF unwinder. Its main purpose is
+ * for generating stacktrace information. Based on the DWARF 3
+ * specification from http://www.dwarfstd.org.
+ *
+ * TODO:
+ *	- DWARF64 doesn't work.
+ *	- Registers with DWARF_VAL_OFFSET rules aren't handled properly.
+ */
+
+/* #define DEBUG */
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/mempool.h>
+#include <linux/mm.h>
+#include <asm/dwarf.h>
+#include <asm/unwinder.h>
+#include <asm/sections.h>
+#include <asm/unaligned.h>
+#include <asm/dwarf.h>
+#include <asm/stacktrace.h>
+
+/* Reserve enough memory for two stack frames */
+#define DWARF_FRAME_MIN_REQ	2
+/* ... with 4 registers per frame. */
+#define DWARF_REG_MIN_REQ	(DWARF_FRAME_MIN_REQ * 4)
+
+static struct kmem_cache *dwarf_frame_cachep;
+static mempool_t *dwarf_frame_pool;
+
+static struct kmem_cache *dwarf_reg_cachep;
+static mempool_t *dwarf_reg_pool;
+
+static LIST_HEAD(dwarf_cie_list);
+static DEFINE_SPINLOCK(dwarf_cie_lock);
+
+static LIST_HEAD(dwarf_fde_list);
+static DEFINE_SPINLOCK(dwarf_fde_lock);
+
+static struct dwarf_cie *cached_cie;
+
+/**
+ *	dwarf_frame_alloc_reg - allocate memory for a DWARF register
+ *	@frame: the DWARF frame whose list of registers we insert on
+ *	@reg_num: the register number
+ *
+ *	Allocate space for, and initialise, a dwarf reg from
+ *	dwarf_reg_pool and insert it onto the (unsorted) linked-list of
+ *	dwarf registers for @frame.
+ *
+ *	Return the initialised DWARF reg.
+ */
+static struct dwarf_reg *dwarf_frame_alloc_reg(struct dwarf_frame *frame,
+					       unsigned int reg_num)
+{
+	struct dwarf_reg *reg;
+
+	reg = mempool_alloc(dwarf_reg_pool, GFP_ATOMIC);
+	if (!reg) {
+		printk(KERN_WARNING "Unable to allocate a DWARF register\n");
+		/*
+		 * Let's just bomb hard here, we have no way to
+		 * gracefully recover.
+		 */
+		UNWINDER_BUG();
+	}
+
+	reg->number = reg_num;
+	reg->addr = 0;
+	reg->flags = 0;
+
+	list_add(&reg->link, &frame->reg_list);
+
+	return reg;
+}
+
+static void dwarf_frame_free_regs(struct dwarf_frame *frame)
+{
+	struct dwarf_reg *reg, *n;
+
+	list_for_each_entry_safe(reg, n, &frame->reg_list, link) {
+		list_del(&reg->link);
+		mempool_free(reg, dwarf_reg_pool);
+	}
+}
+
+/**
+ *	dwarf_frame_reg - return a DWARF register
+ *	@frame: the DWARF frame to search in for @reg_num
+ *	@reg_num: the register number to search for
+ *
+ *	Lookup and return the dwarf reg @reg_num for this frame. Return
+ *	NULL if @reg_num is an register invalid number.
+ */
+static struct dwarf_reg *dwarf_frame_reg(struct dwarf_frame *frame,
+					 unsigned int reg_num)
+{
+	struct dwarf_reg *reg;
+
+	list_for_each_entry(reg, &frame->reg_list, link) {
+		if (reg->number == reg_num)
+			return reg;
+	}
+
+	return NULL;
+}
+
+/**
+ *	dwarf_read_addr - read dwarf data
+ *	@src: source address of data
+ *	@dst: destination address to store the data to
+ *
+ *	Read 'n' bytes from @src, where 'n' is the size of an address on
+ *	the native machine. We return the number of bytes read, which
+ *	should always be 'n'. We also have to be careful when reading
+ *	from @src and writing to @dst, because they can be arbitrarily
+ *	aligned. Return 'n' - the number of bytes read.
+ */
+static inline int dwarf_read_addr(unsigned long *src, unsigned long *dst)
+{
+	u32 val = get_unaligned(src);
+	put_unaligned(val, dst);
+	return sizeof(unsigned long *);
+}
+
+/**
+ *	dwarf_read_uleb128 - read unsigned LEB128 data
+ *	@addr: the address where the ULEB128 data is stored
+ *	@ret: address to store the result
+ *
+ *	Decode an unsigned LEB128 encoded datum. The algorithm is taken
+ *	from Appendix C of the DWARF 3 spec. For information on the
+ *	encodings refer to section "7.6 - Variable Length Data". Return
+ *	the number of bytes read.
+ */
+static inline unsigned long dwarf_read_uleb128(char *addr, unsigned int *ret)
+{
+	unsigned int result;
+	unsigned char byte;
+	int shift, count;
+
+	result = 0;
+	shift = 0;
+	count = 0;
+
+	while (1) {
+		byte = __raw_readb(addr);
+		addr++;
+		count++;
+
+		result |= (byte & 0x7f) << shift;
+		shift += 7;
+
+		if (!(byte & 0x80))
+			break;
+	}
+
+	*ret = result;
+
+	return count;
+}
+
+/**
+ *	dwarf_read_leb128 - read signed LEB128 data
+ *	@addr: the address of the LEB128 encoded data
+ *	@ret: address to store the result
+ *
+ *	Decode signed LEB128 data. The algorithm is taken from Appendix
+ *	C of the DWARF 3 spec. Return the number of bytes read.
+ */
+static inline unsigned long dwarf_read_leb128(char *addr, int *ret)
+{
+	unsigned char byte;
+	int result, shift;
+	int num_bits;
+	int count;
+
+	result = 0;
+	shift = 0;
+	count = 0;
+
+	while (1) {
+		byte = __raw_readb(addr);
+		addr++;
+		result |= (byte & 0x7f) << shift;
+		shift += 7;
+		count++;
+
+		if (!(byte & 0x80))
+			break;
+	}
+
+	/* The number of bits in a signed integer. */
+	num_bits = 8 * sizeof(result);
+
+	if ((shift < num_bits) && (byte & 0x40))
+		result |= (-1 << shift);
+
+	*ret = result;
+
+	return count;
+}
+
+/**
+ *	dwarf_read_encoded_value - return the decoded value at @addr
+ *	@addr: the address of the encoded value
+ *	@val: where to write the decoded value
+ *	@encoding: the encoding with which we can decode @addr
+ *
+ *	GCC emits encoded address in the .eh_frame FDE entries. Decode
+ *	the value at @addr using @encoding. The decoded value is written
+ *	to @val and the number of bytes read is returned.
+ */
+static int dwarf_read_encoded_value(char *addr, unsigned long *val,
+				    char encoding)
+{
+	unsigned long decoded_addr = 0;
+	int count = 0;
+
+	switch (encoding & 0x70) {
+	case DW_EH_PE_absptr:
+		break;
+	case DW_EH_PE_pcrel:
+		decoded_addr = (unsigned long)addr;
+		break;
+	default:
+		pr_debug("encoding=0x%x\n", (encoding & 0x70));
+		UNWINDER_BUG();
+	}
+
+	if ((encoding & 0x07) == 0x00)
+		encoding |= DW_EH_PE_udata4;
+
+	switch (encoding & 0x0f) {
+	case DW_EH_PE_sdata4:
+	case DW_EH_PE_udata4:
+		count += 4;
+		decoded_addr += get_unaligned((u32 *)addr);
+		__raw_writel(decoded_addr, val);
+		break;
+	default:
+		pr_debug("encoding=0x%x\n", encoding);
+		UNWINDER_BUG();
+	}
+
+	return count;
+}
+
+/**
+ *	dwarf_entry_len - return the length of an FDE or CIE
+ *	@addr: the address of the entry
+ *	@len: the length of the entry
+ *
+ *	Read the initial_length field of the entry and store the size of
+ *	the entry in @len. We return the number of bytes read. Return a
+ *	count of 0 on error.
+ */
+static inline int dwarf_entry_len(char *addr, unsigned long *len)
+{
+	u32 initial_len;
+	int count;
+
+	initial_len = get_unaligned((u32 *)addr);
+	count = 4;
+
+	/*
+	 * An initial length field value in the range DW_LEN_EXT_LO -
+	 * DW_LEN_EXT_HI indicates an extension, and should not be
+	 * interpreted as a length. The only extension that we currently
+	 * understand is the use of DWARF64 addresses.
+	 */
+	if (initial_len >= DW_EXT_LO && initial_len <= DW_EXT_HI) {
+		/*
+		 * The 64-bit length field immediately follows the
+		 * compulsory 32-bit length field.
+		 */
+		if (initial_len == DW_EXT_DWARF64) {
+			*len = get_unaligned((u64 *)addr + 4);
+			count = 12;
+		} else {
+			printk(KERN_WARNING "Unknown DWARF extension\n");
+			count = 0;
+		}
+	} else
+		*len = initial_len;
+
+	return count;
+}
+
+/**
+ *	dwarf_lookup_cie - locate the cie
+ *	@cie_ptr: pointer to help with lookup
+ */
+static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
+{
+	struct dwarf_cie *cie;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+
+	/*
+	 * We've cached the last CIE we looked up because chances are
+	 * that the FDE wants this CIE.
+	 */
+	if (cached_cie && cached_cie->cie_pointer == cie_ptr) {
+		cie = cached_cie;
+		goto out;
+	}
+
+	list_for_each_entry(cie, &dwarf_cie_list, link) {
+		if (cie->cie_pointer == cie_ptr) {
+			cached_cie = cie;
+			break;
+		}
+	}
+
+	/* Couldn't find the entry in the list. */
+	if (&cie->link == &dwarf_cie_list)
+		cie = NULL;
+out:
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+	return cie;
+}
+
+/**
+ *	dwarf_lookup_fde - locate the FDE that covers pc
+ *	@pc: the program counter
+ */
+struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
+{
+	struct dwarf_fde *fde;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+
+	list_for_each_entry(fde, &dwarf_fde_list, link) {
+		unsigned long start, end;
+
+		start = fde->initial_location;
+		end = fde->initial_location + fde->address_range;
+
+		if (pc >= start && pc < end)
+			break;
+	}
+
+	/* Couldn't find the entry in the list. */
+	if (&fde->link == &dwarf_fde_list)
+		fde = NULL;
+
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+	return fde;
+}
+
+/**
+ *	dwarf_cfa_execute_insns - execute instructions to calculate a CFA
+ *	@insn_start: address of the first instruction
+ *	@insn_end: address of the last instruction
+ *	@cie: the CIE for this function
+ *	@fde: the FDE for this function
+ *	@frame: the instructions calculate the CFA for this frame
+ *	@pc: the program counter of the address we're interested in
+ *
+ *	Execute the Call Frame instruction sequence starting at
+ *	@insn_start and ending at @insn_end. The instructions describe
+ *	how to calculate the Canonical Frame Address of a stackframe.
+ *	Store the results in @frame.
+ */
+static int dwarf_cfa_execute_insns(unsigned char *insn_start,
+				   unsigned char *insn_end,
+				   struct dwarf_cie *cie,
+				   struct dwarf_fde *fde,
+				   struct dwarf_frame *frame,
+				   unsigned long pc)
+{
+	unsigned char insn;
+	unsigned char *current_insn;
+	unsigned int count, delta, reg, expr_len, offset;
+	struct dwarf_reg *regp;
+
+	current_insn = insn_start;
+
+	while (current_insn < insn_end && frame->pc <= pc) {
+		insn = __raw_readb(current_insn++);
+
+		/*
+		 * Firstly, handle the opcodes that embed their operands
+		 * in the instructions.
+		 */
+		switch (DW_CFA_opcode(insn)) {
+		case DW_CFA_advance_loc:
+			delta = DW_CFA_operand(insn);
+			delta *= cie->code_alignment_factor;
+			frame->pc += delta;
+			continue;
+			/* NOTREACHED */
+		case DW_CFA_offset:
+			reg = DW_CFA_operand(insn);
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->addr = offset;
+			regp->flags |= DWARF_REG_OFFSET;
+			continue;
+			/* NOTREACHED */
+		case DW_CFA_restore:
+			reg = DW_CFA_operand(insn);
+			continue;
+			/* NOTREACHED */
+		}
+
+		/*
+		 * Secondly, handle the opcodes that don't embed their
+		 * operands in the instruction.
+		 */
+		switch (insn) {
+		case DW_CFA_nop:
+			continue;
+		case DW_CFA_advance_loc1:
+			delta = *current_insn++;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_advance_loc2:
+			delta = get_unaligned((u16 *)current_insn);
+			current_insn += 2;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_advance_loc4:
+			delta = get_unaligned((u32 *)current_insn);
+			current_insn += 4;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_offset_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			break;
+		case DW_CFA_restore_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			break;
+		case DW_CFA_undefined:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_UNDEFINED;
+			break;
+		case DW_CFA_def_cfa:
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_register);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_offset);
+			current_insn += count;
+
+			frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+			break;
+		case DW_CFA_def_cfa_register:
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_register);
+			current_insn += count;
+			frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+			break;
+		case DW_CFA_def_cfa_offset:
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			frame->cfa_offset = offset;
+			break;
+		case DW_CFA_def_cfa_expression:
+			count = dwarf_read_uleb128(current_insn, &expr_len);
+			current_insn += count;
+
+			frame->cfa_expr = current_insn;
+			frame->cfa_expr_len = expr_len;
+			current_insn += expr_len;
+
+			frame->flags |= DWARF_FRAME_CFA_REG_EXP;
+			break;
+		case DW_CFA_offset_extended_sf:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_leb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_REG_OFFSET;
+			regp->addr = offset;
+			break;
+		case DW_CFA_val_offset:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_leb128(current_insn, &offset);
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_VAL_OFFSET;
+			regp->addr = offset;
+			break;
+		case DW_CFA_GNU_args_size:
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			break;
+		case DW_CFA_GNU_negative_offset_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn, &offset);
+			offset *= cie->data_alignment_factor;
+
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_REG_OFFSET;
+			regp->addr = -offset;
+			break;
+		default:
+			pr_debug("unhandled DWARF instruction 0x%x\n", insn);
+			UNWINDER_BUG();
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *	dwarf_unwind_stack - recursively unwind the stack
+ *	@pc: address of the function to unwind
+ *	@prev: struct dwarf_frame of the previous stackframe on the callstack
+ *
+ *	Return a struct dwarf_frame representing the most recent frame
+ *	on the callstack. Each of the lower (older) stack frames are
+ *	linked via the "prev" member.
+ */
+struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
+					struct dwarf_frame *prev)
+{
+	struct dwarf_frame *frame;
+	struct dwarf_cie *cie;
+	struct dwarf_fde *fde;
+	struct dwarf_reg *reg;
+	unsigned long addr;
+
+	/*
+	 * If this is the first invocation of this recursive function we
+	 * need get the contents of a physical register to get the CFA
+	 * in order to begin the virtual unwinding of the stack.
+	 *
+	 * NOTE: the return address is guaranteed to be setup by the
+	 * time this function makes its first function call.
+	 */
+	if (!pc && !prev)
+		pc = (unsigned long)current_text_addr();
+
+	frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
+	if (!frame) {
+		printk(KERN_ERR "Unable to allocate a dwarf frame\n");
+		UNWINDER_BUG();
+	}
+
+	INIT_LIST_HEAD(&frame->reg_list);
+	frame->flags = 0;
+	frame->prev = prev;
+	frame->return_addr = 0;
+
+	fde = dwarf_lookup_fde(pc);
+	if (!fde) {
+		/*
+		 * This is our normal exit path - the one that stops the
+		 * recursion. There's two reasons why we might exit
+		 * here,
+		 *
+		 *	a) pc has no asscociated DWARF frame info and so
+		 *	we don't know how to unwind this frame. This is
+		 *	usually the case when we're trying to unwind a
+		 *	frame that was called from some assembly code
+		 *	that has no DWARF info, e.g. syscalls.
+		 *
+		 *	b) the DEBUG info for pc is bogus. There's
+		 *	really no way to distinguish this case from the
+		 *	case above, which sucks because we could print a
+		 *	warning here.
+		 */
+		goto bail;
+	}
+
+	cie = dwarf_lookup_cie(fde->cie_pointer);
+
+	frame->pc = fde->initial_location;
+
+	/* CIE initial instructions */
+	dwarf_cfa_execute_insns(cie->initial_instructions,
+				cie->instructions_end, cie, fde,
+				frame, pc);
+
+	/* FDE instructions */
+	dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
+				fde, frame, pc);
+
+	/* Calculate the CFA */
+	switch (frame->flags) {
+	case DWARF_FRAME_CFA_REG_OFFSET:
+		if (prev) {
+			reg = dwarf_frame_reg(prev, frame->cfa_register);
+			UNWINDER_BUG_ON(!reg);
+			UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET);
+
+			addr = prev->cfa + reg->addr;
+			frame->cfa = __raw_readl(addr);
+
+		} else {
+			/*
+			 * Again, this is the first invocation of this
+			 * recurisve function. We need to physically
+			 * read the contents of a register in order to
+			 * get the Canonical Frame Address for this
+			 * function.
+			 */
+			frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
+		}
+
+		frame->cfa += frame->cfa_offset;
+		break;
+	default:
+		UNWINDER_BUG();
+	}
+
+	reg = dwarf_frame_reg(frame, DWARF_ARCH_RA_REG);
+
+	/*
+	 * If we haven't seen the return address register or the return
+	 * address column is undefined then we must assume that this is
+	 * the end of the callstack.
+	 */
+	if (!reg || reg->flags == DWARF_UNDEFINED)
+		goto bail;
+
+	UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET);
+
+	addr = frame->cfa + reg->addr;
+	frame->return_addr = __raw_readl(addr);
+
+	return frame;
+
+bail:
+	dwarf_frame_free_regs(frame);
+	mempool_free(frame, dwarf_frame_pool);
+	return NULL;
+}
+
+static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
+			   unsigned char *end)
+{
+	struct dwarf_cie *cie;
+	unsigned long flags;
+	int count;
+
+	cie = kzalloc(sizeof(*cie), GFP_KERNEL);
+	if (!cie)
+		return -ENOMEM;
+
+	cie->length = len;
+
+	/*
+	 * Record the offset into the .eh_frame section
+	 * for this CIE. It allows this CIE to be
+	 * quickly and easily looked up from the
+	 * corresponding FDE.
+	 */
+	cie->cie_pointer = (unsigned long)entry;
+
+	cie->version = *(char *)p++;
+	UNWINDER_BUG_ON(cie->version != 1);
+
+	cie->augmentation = p;
+	p += strlen(cie->augmentation) + 1;
+
+	count = dwarf_read_uleb128(p, &cie->code_alignment_factor);
+	p += count;
+
+	count = dwarf_read_leb128(p, &cie->data_alignment_factor);
+	p += count;
+
+	/*
+	 * Which column in the rule table contains the
+	 * return address?
+	 */
+	if (cie->version == 1) {
+		cie->return_address_reg = __raw_readb(p);
+		p++;
+	} else {
+		count = dwarf_read_uleb128(p, &cie->return_address_reg);
+		p += count;
+	}
+
+	if (cie->augmentation[0] == 'z') {
+		unsigned int length, count;
+		cie->flags |= DWARF_CIE_Z_AUGMENTATION;
+
+		count = dwarf_read_uleb128(p, &length);
+		p += count;
+
+		UNWINDER_BUG_ON((unsigned char *)p > end);
+
+		cie->initial_instructions = p + length;
+		cie->augmentation++;
+	}
+
+	while (*cie->augmentation) {
+		/*
+		 * "L" indicates a byte showing how the
+		 * LSDA pointer is encoded. Skip it.
+		 */
+		if (*cie->augmentation == 'L') {
+			p++;
+			cie->augmentation++;
+		} else if (*cie->augmentation == 'R') {
+			/*
+			 * "R" indicates a byte showing
+			 * how FDE addresses are
+			 * encoded.
+			 */
+			cie->encoding = *(char *)p++;
+			cie->augmentation++;
+		} else if (*cie->augmentation == 'P') {
+			/*
+			 * "R" indicates a personality
+			 * routine in the CIE
+			 * augmentation.
+			 */
+			UNWINDER_BUG();
+		} else if (*cie->augmentation == 'S') {
+			UNWINDER_BUG();
+		} else {
+			/*
+			 * Unknown augmentation. Assume
+			 * 'z' augmentation.
+			 */
+			p = cie->initial_instructions;
+			UNWINDER_BUG_ON(!p);
+			break;
+		}
+	}
+
+	cie->initial_instructions = p;
+	cie->instructions_end = end;
+
+	/* Add to list */
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+	list_add_tail(&cie->link, &dwarf_cie_list);
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+	return 0;
+}
+
+static int dwarf_parse_fde(void *entry, u32 entry_type,
+			   void *start, unsigned long len,
+			   unsigned char *end)
+{
+	struct dwarf_fde *fde;
+	struct dwarf_cie *cie;
+	unsigned long flags;
+	int count;
+	void *p = start;
+
+	fde = kzalloc(sizeof(*fde), GFP_KERNEL);
+	if (!fde)
+		return -ENOMEM;
+
+	fde->length = len;
+
+	/*
+	 * In a .eh_frame section the CIE pointer is the
+	 * delta between the address within the FDE
+	 */
+	fde->cie_pointer = (unsigned long)(p - entry_type - 4);
+
+	cie = dwarf_lookup_cie(fde->cie_pointer);
+	fde->cie = cie;
+
+	if (cie->encoding)
+		count = dwarf_read_encoded_value(p, &fde->initial_location,
+						 cie->encoding);
+	else
+		count = dwarf_read_addr(p, &fde->initial_location);
+
+	p += count;
+
+	if (cie->encoding)
+		count = dwarf_read_encoded_value(p, &fde->address_range,
+						 cie->encoding & 0x0f);
+	else
+		count = dwarf_read_addr(p, &fde->address_range);
+
+	p += count;
+
+	if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) {
+		unsigned int length;
+		count = dwarf_read_uleb128(p, &length);
+		p += count + length;
+	}
+
+	/* Call frame instructions. */
+	fde->instructions = p;
+	fde->end = end;
+
+	/* Add to list. */
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+	list_add_tail(&fde->link, &dwarf_fde_list);
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+	return 0;
+}
+
+static void dwarf_unwinder_dump(struct task_struct *task,
+				struct pt_regs *regs,
+				unsigned long *sp,
+				const struct stacktrace_ops *ops,
+				void *data)
+{
+	struct dwarf_frame *frame, *_frame;
+	unsigned long return_addr;
+
+	_frame = NULL;
+	return_addr = 0;
+
+	while (1) {
+		frame = dwarf_unwind_stack(return_addr, _frame);
+
+		if (_frame) {
+			dwarf_frame_free_regs(_frame);
+			mempool_free(_frame, dwarf_frame_pool);
+		}
+
+		_frame = frame;
+
+		if (!frame || !frame->return_addr)
+			break;
+
+		return_addr = frame->return_addr;
+		ops->address(data, return_addr, 1);
+	}
+}
+
+static struct unwinder dwarf_unwinder = {
+	.name = "dwarf-unwinder",
+	.dump = dwarf_unwinder_dump,
+	.rating = 150,
+};
+
+static void dwarf_unwinder_cleanup(void)
+{
+	struct dwarf_cie *cie;
+	struct dwarf_fde *fde;
+
+	/*
+	 * Deallocate all the memory allocated for the DWARF unwinder.
+	 * Traverse all the FDE/CIE lists and remove and free all the
+	 * memory associated with those data structures.
+	 */
+	list_for_each_entry(cie, &dwarf_cie_list, link)
+		kfree(cie);
+
+	list_for_each_entry(fde, &dwarf_fde_list, link)
+		kfree(fde);
+
+	kmem_cache_destroy(dwarf_reg_cachep);
+	kmem_cache_destroy(dwarf_frame_cachep);
+}
+
+/**
+ *	dwarf_unwinder_init - initialise the dwarf unwinder
+ *
+ *	Build the data structures describing the .dwarf_frame section to
+ *	make it easier to lookup CIE and FDE entries. Because the
+ *	.eh_frame section is packed as tightly as possible it is not
+ *	easy to lookup the FDE for a given PC, so we build a list of FDE
+ *	and CIE entries that make it easier.
+ */
+static int __init dwarf_unwinder_init(void)
+{
+	u32 entry_type;
+	void *p, *entry;
+	int count, err = 0;
+	unsigned long len;
+	unsigned int c_entries, f_entries;
+	unsigned char *end;
+	INIT_LIST_HEAD(&dwarf_cie_list);
+	INIT_LIST_HEAD(&dwarf_fde_list);
+
+	c_entries = 0;
+	f_entries = 0;
+	entry = &__start_eh_frame;
+
+	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
+			sizeof(struct dwarf_frame), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
+			sizeof(struct dwarf_reg), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ,
+					  mempool_alloc_slab,
+					  mempool_free_slab,
+					  dwarf_frame_cachep);
+
+	dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
+					 mempool_alloc_slab,
+					 mempool_free_slab,
+					 dwarf_reg_cachep);
+
+	while ((char *)entry < __stop_eh_frame) {
+		p = entry;
+
+		count = dwarf_entry_len(p, &len);
+		if (count == 0) {
+			/*
+			 * We read a bogus length field value. There is
+			 * nothing we can do here apart from disabling
+			 * the DWARF unwinder. We can't even skip this
+			 * entry and move to the next one because 'len'
+			 * tells us where our next entry is.
+			 */
+			goto out;
+		} else
+			p += count;
+
+		/* initial length does not include itself */
+		end = p + len;
+
+		entry_type = get_unaligned((u32 *)p);
+		p += 4;
+
+		if (entry_type == DW_EH_FRAME_CIE) {
+			err = dwarf_parse_cie(entry, p, len, end);
+			if (err < 0)
+				goto out;
+			else
+				c_entries++;
+		} else {
+			err = dwarf_parse_fde(entry, entry_type, p, len, end);
+			if (err < 0)
+				goto out;
+			else
+				f_entries++;
+		}
+
+		entry = (char *)entry + len + 4;
+	}
+
+	printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
+	       c_entries, f_entries);
+
+	err = unwinder_register(&dwarf_unwinder);
+	if (err)
+		goto out;
+
+	return 0;
+
+out:
+	printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err);
+	dwarf_unwinder_cleanup();
+	return -EINVAL;
+}
+early_initcall(dwarf_unwinder_init);
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index a952dcf..81a4614 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -134,7 +134,7 @@
 	sci_out(&scif_port, SCFCR, 0x0030);	/* TTRG=b'11 */
 	sci_out(&scif_port, SCSCR, 0x0030);	/* TE, RE */
 }
-#elif defined(CONFIG_CPU_SH4)
+#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
 #define DEFAULT_BAUD 115200
 /*
  * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
@@ -220,8 +220,7 @@
 		early_console = &scif_console;
 
 #if !defined(CONFIG_SH_STANDARD_BIOS)
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
 		scif_sercon_init(buf + 6);
 #endif
 #endif
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index d62359c..68d9223 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -43,9 +43,10 @@
  *	syscall #
  *
  */
+#include <asm/dwarf.h>
 
 #if defined(CONFIG_PREEMPT)
-#  define preempt_stop()	cli
+#  define preempt_stop()	cli ; TRACE_IRQS_OFF
 #else
 #  define preempt_stop()
 #  define resume_kernel		__restore_all
@@ -55,11 +56,7 @@
 	.align	2
 ENTRY(exception_error)
 	!
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	2f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 	mov.l	1f, r0
 	jmp	@r0
@@ -67,18 +64,15 @@
 
 	.align	2
 1:	.long	do_exception_error
-#ifdef CONFIG_TRACE_IRQFLAGS
-2:	.long	trace_hardirqs_on
-#endif
 
 	.align	2
 ret_from_exception:
+	CFI_STARTPROC simple
+	CFI_DEF_CFA r14, 0
+	CFI_REL_OFFSET 17, 64
+	CFI_REL_OFFSET 15, 0
+	CFI_REL_OFFSET 14, 56
 	preempt_stop()
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	4f, r0
-	jsr	@r0
-	 nop
-#endif
 ENTRY(ret_from_irq)
 	!
 	mov	#OFF_SR, r0
@@ -93,6 +87,7 @@
 	 nop
 ENTRY(resume_kernel)
 	cli
+	TRACE_IRQS_OFF
 	mov.l	@(TI_PRE_COUNT,r8), r0	! current_thread_info->preempt_count
 	tst	r0, r0
 	bf	noresched
@@ -103,8 +98,9 @@
 
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0		! get status register
-	and	#0xf0, r0		! interrupts off (exception path)?
-	cmp/eq	#0xf0, r0
+	shlr	r0
+	and	#(0xf0>>1), r0		! interrupts off (exception path)?
+	cmp/eq	#(0xf0>>1), r0
 	bt	noresched
 	mov.l	3f, r0
 	jsr	@r0			! call preempt_schedule_irq
@@ -125,13 +121,9 @@
 ENTRY(resume_userspace)
 	! r8: current_thread_info
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OfF
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_WORK_MASK, r0
+	tst	#(_TIF_WORK_MASK & 0xff), r0
 	bt/s	__restore_all
 	 tst	#_TIF_NEED_RESCHED, r0
 
@@ -156,14 +148,10 @@
 	jsr	@r1				! schedule
 	 nop
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OFF
 	!
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_WORK_MASK, r0
+	tst	#(_TIF_WORK_MASK & 0xff), r0
 	bt	__restore_all
 	bra	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
@@ -172,23 +160,15 @@
 1:	.long	schedule
 2:	.long	do_notify_resume
 3:	.long	resume_userspace
-#ifdef CONFIG_TRACE_IRQFLAGS
-4:	.long	trace_hardirqs_on
-5:	.long	trace_hardirqs_off
-#endif
 
 	.align	2
 syscall_exit_work:
 	! r0: current_thread_info->flags
 	! r8: current_thread_info
-	tst	#_TIF_WORK_SYSCALL_MASK, r0
+	tst	#(_TIF_WORK_SYSCALL_MASK & 0xff), r0
 	bt/s	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 	mov	r15, r4
 	mov.l	8f, r0			! do_syscall_trace_leave
@@ -226,12 +206,25 @@
 	 mov.l	r0, @(OFF_R0,r15)	! Return value
 
 __restore_all:
-	mov.l	1f, r0
+	mov	#OFF_SR, r0
+	mov.l	@(r0,r15), r0	! get status register
+
+	shlr2	r0
+	and	#0x3c, r0
+	cmp/eq	#0x3c, r0
+	bt	1f
+	TRACE_IRQS_ON
+	bra	2f
+	 nop
+1:
+	TRACE_IRQS_OFF
+2:
+	mov.l	3f, r0
 	jmp	@r0
 	 nop
 
 	.align	2
-1:	.long	restore_all
+3:	.long	restore_all
 
 	.align	2
 syscall_badsys:			! Bad syscall number
@@ -259,6 +252,7 @@
 	 nop
 	bra	__restore_all
 	 nop
+	CFI_ENDPROC
 
 	.align	2
 1:	.long	debug_trap_table
@@ -304,6 +298,7 @@
  * system calls and debug traps through their respective jump tables.
  */
 ENTRY(system_call)
+	setup_frame_reg
 #if !defined(CONFIG_CPU_SH2)
 	mov.l	1f, r9
 	mov.l	@r9, r8		! Read from TRA (Trap Address) Register
@@ -321,18 +316,18 @@
 	bt/s	debug_trap		! it's a debug trap..
 	 nop
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r10
-	jsr	@r10
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 
 	!
 	get_current_thread_info r8, r10
 	mov.l	@(TI_FLAGS,r8), r8
-	mov	#_TIF_WORK_SYSCALL_MASK, r10
+	mov	#(_TIF_WORK_SYSCALL_MASK & 0xff), r10
+	mov	#(_TIF_WORK_SYSCALL_MASK >> 8), r9
 	tst	r10, r8
+	shll8	r9
+	bf	syscall_trace_entry
+	tst	r9, r8
 	bf	syscall_trace_entry
 	!
 	mov.l	2f, r8			! Number of syscalls
@@ -351,15 +346,15 @@
 	!
 syscall_exit:
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	6f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OFF
 	!
 	get_current_thread_info r8, r0
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_ALLWORK_MASK, r0
+	tst	#(_TIF_ALLWORK_MASK & 0xff), r0
+	mov	#(_TIF_ALLWORK_MASK >> 8), r1
+	bf	syscall_exit_work
+	shlr8	r0
+	tst	r0, r1
 	bf	syscall_exit_work
 	bra	__restore_all
 	 nop
@@ -369,9 +364,5 @@
 #endif
 2:	.long	NR_syscalls
 3:	.long	sys_call_table
-#ifdef CONFIG_TRACE_IRQFLAGS
-5:	.long	trace_hardirqs_on
-6:	.long	trace_hardirqs_off
-#endif
 7:	.long	do_syscall_trace_enter
 8:	.long	do_syscall_trace_leave
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 066f37d..a3dcc6d 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -16,9 +16,13 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/kernel.h>
 #include <asm/ftrace.h>
 #include <asm/cacheflush.h>
+#include <asm/unistd.h>
+#include <trace/syscall.h>
 
+#ifdef CONFIG_DYNAMIC_FTRACE
 static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
 
 static unsigned char ftrace_nop[4];
@@ -131,3 +135,187 @@
 
 	return 0;
 }
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+static int ftrace_mod(unsigned long ip, unsigned long old_addr,
+		      unsigned long new_addr)
+{
+	unsigned char code[MCOUNT_INSN_SIZE];
+
+	if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+
+	if (old_addr != __raw_readl((unsigned long *)code))
+		return -EINVAL;
+
+	__raw_writel(new_addr, ip);
+	return 0;
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	unsigned long ip, old_addr, new_addr;
+
+	ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+	old_addr = (unsigned long)(&skip_trace);
+	new_addr = (unsigned long)(&ftrace_graph_caller);
+
+	return ftrace_mod(ip, old_addr, new_addr);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned long ip, old_addr, new_addr;
+
+	ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+	old_addr = (unsigned long)(&ftrace_graph_caller);
+	new_addr = (unsigned long)(&skip_trace);
+
+	return ftrace_mod(ip, old_addr, new_addr);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in the current thread info.
+ *
+ * This is the main routine for the function graph tracer. The function
+ * graph tracer essentially works like this:
+ *
+ * parent is the stack address containing self_addr's return address.
+ * We pull the real return address out of parent and store it in
+ * current's ret_stack. Then, we replace the return address on the stack
+ * with the address of return_to_handler. self_addr is the function that
+ * called mcount.
+ *
+ * When self_addr returns, it will jump to return_to_handler which calls
+ * ftrace_return_to_handler. ftrace_return_to_handler will pull the real
+ * return address off of current's ret_stack and jump to it.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+	unsigned long old;
+	int faulted, err;
+	struct ftrace_graph_ent trace;
+	unsigned long return_hooker = (unsigned long)&return_to_handler;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	/*
+	 * Protect against fault, even if it shouldn't
+	 * happen. This tool is too much intrusive to
+	 * ignore such a protection.
+	 */
+	__asm__ __volatile__(
+		"1:						\n\t"
+		"mov.l		@%2, %0				\n\t"
+		"2:						\n\t"
+		"mov.l		%3, @%2				\n\t"
+		"mov		#0, %1				\n\t"
+		"3:						\n\t"
+		".section .fixup, \"ax\"			\n\t"
+		"4:						\n\t"
+		"mov.l		5f, %0				\n\t"
+		"jmp		@%0				\n\t"
+		" mov		#1, %1				\n\t"
+		".balign 4					\n\t"
+		"5:	.long 3b				\n\t"
+		".previous					\n\t"
+		".section __ex_table,\"a\"			\n\t"
+		".long 1b, 4b					\n\t"
+		".long 2b, 4b					\n\t"
+		".previous					\n\t"
+		: "=&r" (old), "=r" (faulted)
+		: "r" (parent), "r" (return_hooker)
+	);
+
+	if (unlikely(faulted)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		return;
+	}
+
+	err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
+	if (err == -EBUSY) {
+		__raw_writel(old, parent);
+		return;
+	}
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		__raw_writel(old, parent);
+	}
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned long __start_syscalls_metadata[];
+extern unsigned long __stop_syscalls_metadata[];
+extern unsigned long *sys_call_table;
+
+static struct syscall_metadata **syscalls_metadata;
+
+static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
+{
+	struct syscall_metadata *start;
+	struct syscall_metadata *stop;
+	char str[KSYM_SYMBOL_LEN];
+
+
+	start = (struct syscall_metadata *)__start_syscalls_metadata;
+	stop = (struct syscall_metadata *)__stop_syscalls_metadata;
+	kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
+
+	for ( ; start < stop; start++) {
+		if (start->name && !strcmp(start->name, str))
+			return start;
+	}
+
+	return NULL;
+}
+
+struct syscall_metadata *syscall_nr_to_meta(int nr)
+{
+	if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
+		return NULL;
+
+	return syscalls_metadata[nr];
+}
+
+void arch_init_ftrace_syscalls(void)
+{
+	int i;
+	struct syscall_metadata *meta;
+	unsigned long **psys_syscall_table = &sys_call_table;
+	static atomic_t refs;
+
+	if (atomic_inc_return(&refs) != 1)
+		goto end;
+
+	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+					FTRACE_SYSCALL_MAX, GFP_KERNEL);
+	if (!syscalls_metadata) {
+		WARN_ON(1);
+		return;
+	}
+
+	for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
+		meta = find_syscall_meta(psys_syscall_table[i]);
+		syscalls_metadata[i] = meta;
+	}
+	return;
+
+	/* Paranoid: avoid overflow */
+end:
+	atomic_dec(&refs);
+}
+#endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 4f85fff..4770c24 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -1,12 +1,9 @@
 /*
- * linux/arch/sh/kernel/io.c
+ * arch/sh/kernel/io.c - Machine independent I/O functions.
  *
- * Copyright (C) 2000  Stuart Menefy
+ * Copyright (C) 2000 - 2009  Stuart Menefy
  * Copyright (C) 2005  Paul Mundt
  *
- * Provide real functions which expand to whatever the header file defined.
- * Also definitions of machine independent IO functions.
- *
  * 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.
@@ -18,33 +15,87 @@
 
 /*
  * Copy data from IO memory space to "real" memory space.
- * This needs to be optimized.
  */
 void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned long count)
 {
-	unsigned char *p = to;
-        while (count) {
-                count--;
-                *p = readb(from);
-                p++;
-                from++;
-        }
+	/*
+	 * Would it be worthwhile doing byte and long transfers first
+	 * to try and get aligned?
+	 */
+#ifdef CONFIG_CPU_SH4
+	if ((count >= 0x20) &&
+	     (((u32)to & 0x1f) == 0) && (((u32)from & 0x3) == 0)) {
+		int tmp2, tmp3, tmp4, tmp5, tmp6;
+
+		__asm__ __volatile__(
+			"1:			\n\t"
+			"mov.l	@%7+, r0	\n\t"
+			"mov.l	@%7+, %2	\n\t"
+			"movca.l r0, @%0	\n\t"
+			"mov.l	@%7+, %3	\n\t"
+			"mov.l	@%7+, %4	\n\t"
+			"mov.l	@%7+, %5	\n\t"
+			"mov.l	@%7+, %6	\n\t"
+			"mov.l	@%7+, r7	\n\t"
+			"mov.l	@%7+, r0	\n\t"
+			"mov.l	%2, @(0x04,%0)	\n\t"
+			"mov	#0x20, %2	\n\t"
+			"mov.l	%3, @(0x08,%0)	\n\t"
+			"sub	%2, %1		\n\t"
+			"mov.l	%4, @(0x0c,%0)	\n\t"
+			"cmp/hi	%1, %2		! T if 32 > count	\n\t"
+			"mov.l	%5, @(0x10,%0)	\n\t"
+			"mov.l	%6, @(0x14,%0)	\n\t"
+			"mov.l	r7, @(0x18,%0)	\n\t"
+			"mov.l	r0, @(0x1c,%0)	\n\t"
+			"bf.s	1b		\n\t"
+			" add	#0x20, %0	\n\t"
+			: "=&r" (to), "=&r" (count),
+			  "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4),
+			  "=&r" (tmp5), "=&r" (tmp6), "=&r" (from)
+			: "7"(from), "0" (to), "1" (count)
+			: "r0", "r7", "t", "memory");
+	}
+#endif
+
+	if ((((u32)to | (u32)from) & 0x3) == 0) {
+		for (; count > 3; count -= 4) {
+			*(u32 *)to = *(volatile u32 *)from;
+			to += 4;
+			from += 4;
+		}
+	}
+
+	for (; count > 0; count--) {
+		*(u8 *)to = *(volatile u8 *)from;
+		to++;
+		from++;
+	}
+
+	mb();
 }
 EXPORT_SYMBOL(memcpy_fromio);
 
 /*
  * Copy data from "real" memory space to IO memory space.
- * This needs to be optimized.
  */
 void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count)
 {
-	const unsigned char *p = from;
-        while (count) {
-                count--;
-                writeb(*p, to);
-                p++;
-                to++;
-        }
+	if ((((u32)to | (u32)from) & 0x3) == 0) {
+		for ( ; count > 3; count -= 4) {
+			*(volatile u32 *)to = *(u32 *)from;
+			to += 4;
+			from += 4;
+		}
+	}
+
+	for (; count > 0; count--) {
+		*(volatile u8 *)to = *(u8 *)from;
+		to++;
+		from++;
+	}
+
+	mb();
 }
 EXPORT_SYMBOL(memcpy_toio);
 
@@ -62,6 +113,8 @@
 }
 EXPORT_SYMBOL(memset_io);
 
+#ifndef CONFIG_GENERIC_IOMAP
+
 void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
 	void __iomem *ret;
@@ -79,3 +132,5 @@
 	sh_mv.mv_ioport_unmap(addr);
 }
 EXPORT_SYMBOL(ioport_unmap);
+
+#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 5a7f554..4ff5072 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -73,35 +73,19 @@
 
 void generic_insb(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u8 *port_addr;
-	u8 *buf = dst;
-
-	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
-	while (count--)
-		*buf++ = *port_addr;
+	__raw_readsb(__ioport_map(port, 1), dst, count);
+	dummy_read();
 }
 
 void generic_insw(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u16 *port_addr;
-	u16 *buf = dst;
-
-	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
-	while (count--)
-		*buf++ = *port_addr;
-
+	__raw_readsw(__ioport_map(port, 2), dst, count);
 	dummy_read();
 }
 
 void generic_insl(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u32 *port_addr;
-	u32 *buf = dst;
-
-	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
-	while (count--)
-		*buf++ = *port_addr;
-
+	__raw_readsl(__ioport_map(port, 4), dst, count);
 	dummy_read();
 }
 
@@ -145,37 +129,19 @@
  */
 void generic_outsb(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u8 *port_addr;
-	const u8 *buf = src;
-
-	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
-
-	while (count--)
-		*port_addr = *buf++;
+	__raw_writesb(__ioport_map(port, 1), src, count);
+	dummy_read();
 }
 
 void generic_outsw(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u16 *port_addr;
-	const u16 *buf = src;
-
-	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
-
-	while (count--)
-		*port_addr = *buf++;
-
+	__raw_writesw(__ioport_map(port, 2), src, count);
 	dummy_read();
 }
 
 void generic_outsl(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u32 *port_addr;
-	const u32 *buf = src;
-
-	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
-	while (count--)
-		*port_addr = *buf++;
-
+	__raw_writesl(__ioport_map(port, 4), src, count);
 	dummy_read();
 }
 
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 77dfecb..69be603 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -112,14 +112,15 @@
 	struct trapped_io *tiop;
 	struct resource *res;
 	int k, len;
+	unsigned long flags;
 
-	spin_lock_irq(&trapped_lock);
+	spin_lock_irqsave(&trapped_lock, flags);
 	list_for_each_entry(tiop, list, list) {
 		voffs = 0;
 		for (k = 0; k < tiop->num_resources; k++) {
 			res = tiop->resource + k;
 			if (res->start == offset) {
-				spin_unlock_irq(&trapped_lock);
+				spin_unlock_irqrestore(&trapped_lock, flags);
 				return tiop->virt_base + voffs;
 			}
 
@@ -127,7 +128,7 @@
 			voffs += roundup(len, PAGE_SIZE);
 		}
 	}
-	spin_unlock_irq(&trapped_lock);
+	spin_unlock_irqrestore(&trapped_lock, flags);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(match_trapped_io_handler);
@@ -283,7 +284,8 @@
 		return 0;
 	}
 
-	tmp = handle_unaligned_access(instruction, regs, &trapped_io_access);
+	tmp = handle_unaligned_access(instruction, regs,
+				      &trapped_io_access, 1);
 	set_fs(oldfs);
 	return tmp == 0;
 }
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 3d09062..60f8af4 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -114,24 +114,7 @@
 #endif
 
 	irq_enter();
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-	/* Debugging check for stack overflow: is there less than 1KB free? */
-	{
-		long sp;
-
-		__asm__ __volatile__ ("and r15, %0" :
-					"=r" (sp) : "0" (THREAD_SIZE - 1));
-
-		if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
-			printk("do_IRQ: stack overflow: %ld\n",
-			       sp - sizeof(struct thread_info));
-			dump_stack();
-		}
-	}
-#endif
-
-	irq = irq_demux(intc_evt2irq(irq));
+	irq = irq_demux(irq);
 
 #ifdef CONFIG_IRQSTACKS
 	curctx = (union irq_ctx *)current_thread_info();
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 305aad7..3e532d0 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -15,8 +15,6 @@
 #include <linux/io.h>
 #include <asm/cacheflush.h>
 
-char in_nmi = 0;	/* Set during NMI to prevent re-entry */
-
 /* Macros for single step instruction identification */
 #define OPCODE_BT(op)		(((op) & 0xff00) == 0x8900)
 #define OPCODE_BF(op)		(((op) & 0xff00) == 0x8b00)
@@ -195,8 +193,6 @@
 	regs->gbr = gdb_regs[GDB_GBR];
 	regs->mach = gdb_regs[GDB_MACH];
 	regs->macl = gdb_regs[GDB_MACL];
-
-	__asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
 }
 
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
index 96e8eae..0b04e7d 100644
--- a/arch/sh/kernel/localtimer.c
+++ b/arch/sh/kernel/localtimer.c
@@ -22,6 +22,7 @@
 #include <linux/jiffies.h>
 #include <linux/percpu.h>
 #include <linux/clockchips.h>
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 
 static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
@@ -33,7 +34,9 @@
 {
 	struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
 
+	irq_enter();
 	clk->event_handler(clk);
+	irq_exit();
 }
 
 static void dummy_timer_set_mode(enum clock_event_mode mode,
@@ -46,8 +49,10 @@
 	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
 
 	clk->name		= "dummy_timer";
-	clk->features		= CLOCK_EVT_FEAT_DUMMY;
-	clk->rating		= 200;
+	clk->features		= CLOCK_EVT_FEAT_ONESHOT |
+				  CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_DUMMY;
+	clk->rating		= 400;
 	clk->mult		= 1;
 	clk->set_mode		= dummy_timer_set_mode;
 	clk->broadcast		= smp_timer_broadcast;
diff --git a/arch/sh/kernel/nmi_debug.c b/arch/sh/kernel/nmi_debug.c
new file mode 100644
index 0000000..ff0abbd
--- /dev/null
+++ b/arch/sh/kernel/nmi_debug.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * 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/delay.h>
+#include <linux/kdebug.h>
+#include <linux/notifier.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+
+enum nmi_action {
+	NMI_SHOW_STATE	= 1 << 0,
+	NMI_SHOW_REGS	= 1 << 1,
+	NMI_DIE		= 1 << 2,
+	NMI_DEBOUNCE	= 1 << 3,
+};
+
+static unsigned long nmi_actions;
+
+static int nmi_debug_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	struct die_args *args = data;
+
+	if (likely(val != DIE_NMI))
+		return NOTIFY_DONE;
+
+	if (nmi_actions & NMI_SHOW_STATE)
+		show_state();
+	if (nmi_actions & NMI_SHOW_REGS)
+		show_regs(args->regs);
+	if (nmi_actions & NMI_DEBOUNCE)
+		mdelay(10);
+	if (nmi_actions & NMI_DIE)
+		return NOTIFY_BAD;
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block nmi_debug_nb = {
+	.notifier_call = nmi_debug_notify,
+};
+
+static int __init nmi_debug_setup(char *str)
+{
+	char *p, *sep;
+
+	register_die_notifier(&nmi_debug_nb);
+
+	if (*str != '=')
+		return 0;
+
+	for (p = str + 1; *p; p = sep + 1) {
+		sep = strchr(p, ',');
+		if (sep)
+			*sep = 0;
+		if (strcmp(p, "state") == 0)
+			nmi_actions |= NMI_SHOW_STATE;
+		else if (strcmp(p, "regs") == 0)
+			nmi_actions |= NMI_SHOW_REGS;
+		else if (strcmp(p, "debounce") == 0)
+			nmi_actions |= NMI_DEBOUNCE;
+		else if (strcmp(p, "die") == 0)
+			nmi_actions |= NMI_DIE;
+		else
+			printk(KERN_WARNING "NMI: Unrecognized action `%s'\n",
+				p);
+		if (!sep)
+			break;
+	}
+
+	return 0;
+}
+__setup("nmi_debug", nmi_debug_setup);
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 92d7740..0673c47 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -23,6 +23,7 @@
 #include <linux/tick.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/ftrace.h>
 #include <linux/preempt.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -31,15 +32,35 @@
 #include <asm/ubc.h>
 #include <asm/fpu.h>
 #include <asm/syscalls.h>
+#include <asm/watchdog.h>
 
 int ubc_usercnt = 0;
 
+#ifdef CONFIG_32BIT
+static void watchdog_trigger_immediate(void)
+{
+	sh_wdt_write_cnt(0xFF);
+	sh_wdt_write_csr(0xC2);
+}
+
+void machine_restart(char * __unused)
+{
+	local_irq_disable();
+
+	/* Use watchdog timer to trigger reset */
+	watchdog_trigger_immediate();
+
+	while (1)
+		cpu_sleep();
+}
+#else
 void machine_restart(char * __unused)
 {
 	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
 	asm volatile("ldc %0, sr\n\t"
 		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
 }
+#endif
 
 void machine_halt(void)
 {
@@ -264,8 +285,8 @@
  *	switch_to(x,y) should switch tasks from x to y.
  *
  */
-struct task_struct *__switch_to(struct task_struct *prev,
-				struct task_struct *next)
+__notrace_funcgraph struct task_struct *
+__switch_to(struct task_struct *prev, struct task_struct *next)
 {
 #if defined(CONFIG_SH_FPU)
 	unlazy_fpu(prev, task_pt_regs(prev));
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 24de742..1192398 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -425,7 +425,6 @@
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct pt_regs *childregs;
-	unsigned long long se;			/* Sign extension */
 
 #ifdef CONFIG_SH_FPU
 	if(last_task_used_math == current) {
@@ -441,11 +440,19 @@
 
 	*childregs = *regs;
 
+	/*
+	 * Sign extend the edited stack.
+	 * Note that thread.pc and thread.pc will stay
+	 * 32-bit wide and context switch must take care
+	 * of NEFF sign extension.
+	 */
 	if (user_mode(regs)) {
-		childregs->regs[15] = usp;
+		childregs->regs[15] = neff_sign_extend(usp);
 		p->thread.uregs = childregs;
 	} else {
-		childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+		childregs->regs[15] =
+			neff_sign_extend((unsigned long)task_stack_page(p) +
+					 THREAD_SIZE);
 	}
 
 	childregs->regs[9] = 0; /* Set return value for child */
@@ -454,17 +461,6 @@
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.pc = (unsigned long) ret_from_fork;
 
-	/*
-	 * Sign extend the edited stack.
-         * Note that thread.pc and thread.pc will stay
-	 * 32-bit wide and context switch must take care
-	 * of NEFF sign extension.
-	 */
-
-	se = childregs->regs[15];
-	se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se;
-	childregs->regs[15] = se;
-
 	return 0;
 }
 
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 3392e83..f4f58e4 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -34,6 +34,8 @@
 #include <asm/syscalls.h>
 #include <asm/fpu.h>
 
+#include <trace/syscall.h>
+
 /*
  * This routine will get a word off of the process kernel stack.
  */
@@ -459,6 +461,11 @@
 		 */
 		ret = -1L;
 
+#ifdef CONFIG_FTRACE_SYSCALLS
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_enter(regs);
+#endif
+
 	if (unlikely(current->audit_context))
 		audit_syscall_entry(audit_arch(), regs->regs[3],
 				    regs->regs[4], regs->regs[5],
@@ -475,6 +482,11 @@
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
 				   regs->regs[0]);
 
+#ifdef CONFIG_FTRACE_SYSCALLS
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_exit(regs);
+#endif
+
 	step = test_thread_flag(TIF_SINGLESTEP);
 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, step);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index dd38338..f9d44f8 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -30,6 +30,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/lmb.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
@@ -48,6 +49,7 @@
 struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
 	[0] = {
 		.type			= CPU_SH_NONE,
+		.family			= CPU_FAMILY_UNKNOWN,
 		.loops_per_jiffy	= 10000000,
 	},
 };
@@ -233,39 +235,45 @@
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
 	unsigned long bootmap_size;
+	unsigned long bootmap_pages, bootmem_paddr;
+	u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
+	int i;
+
+	bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+	bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
 	/*
 	 * Find a proper area for the bootmem bitmap. After this
 	 * bootstrap step all allocations (until the page allocator
 	 * is intact) must be done via bootmem_alloc().
 	 */
-	bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 bootmem_paddr >> PAGE_SHIFT,
 					 min_low_pfn, max_low_pfn);
 
-	__add_active_range(0, min_low_pfn, max_low_pfn);
+	/* Add active regions with valid PFNs. */
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		unsigned long start_pfn, end_pfn;
+		start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+		end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+		__add_active_range(0, start_pfn, end_pfn);
+	}
+
+	/*
+	 * Add all physical memory to the bootmem map and mark each
+	 * area as present.
+	 */
 	register_bootmem_low_pages();
 
-	node_set_online(0);
-
-	/*
-	 * Reserve the kernel text and
-	 * Reserve the bootmem bitmap. We do this in two steps (first step
-	 * was init_bootmem()), because this catches the (definitely buggy)
-	 * case of us accidentally initializing the bootmem allocator with
-	 * an invalid RAM area.
-	 */
-	reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
-			(PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
-			(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
-			BOOTMEM_DEFAULT);
-
-	/*
-	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
-	 */
-	if (CONFIG_ZERO_PAGE_OFFSET != 0)
-		reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+	/* Reserve the sections we're already using. */
+	for (i = 0; i < lmb.reserved.cnt; i++)
+		reserve_bootmem(lmb.reserved.region[i].base,
+				lmb_size_bytes(&lmb.reserved, i),
 				BOOTMEM_DEFAULT);
 
+	node_set_online(0);
+
 	sparse_memory_present_with_active_regions(0);
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -296,12 +304,37 @@
 static void __init setup_memory(void)
 {
 	unsigned long start_pfn;
+	u64 base = min_low_pfn << PAGE_SHIFT;
+	u64 size = (max_low_pfn << PAGE_SHIFT) - base;
 
 	/*
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards:
 	 */
 	start_pfn = PFN_UP(__pa(_end));
+
+	lmb_add(base, size);
+
+	/*
+	 * Reserve the kernel text and
+	 * Reserve the bootmem bitmap. We do this in two steps (first step
+	 * was init_bootmem()), because this catches the (definitely buggy)
+	 * case of us accidentally initializing the bootmem allocator with
+	 * an invalid RAM area.
+	 */
+	lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+		    (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
+		    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
+
+	/*
+	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+	 */
+	if (CONFIG_ZERO_PAGE_OFFSET != 0)
+		lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
+
+	lmb_analyze();
+	lmb_dump_all();
+
 	setup_bootmem_allocator(start_pfn);
 }
 #else
@@ -372,10 +405,14 @@
 	if (!memory_end)
 		memory_end = memory_start + __MEMORY_SIZE;
 
-#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERWRITE
 	strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
 #else
 	strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
+#ifdef CONFIG_CMDLINE_EXTEND
+	strlcat(command_line, " ", sizeof(command_line));
+	strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
+#endif
 #endif
 
 	/* Save unparsed command line copy for /proc/cmdline */
@@ -402,6 +439,7 @@
 	nodes_clear(node_online_map);
 
 	/* Setup bootmem with available RAM */
+	lmb_init();
 	setup_memory();
 	sparse_init();
 
@@ -448,7 +486,7 @@
 	[CPU_SH7763]	= "SH7763",	[CPU_SH7770]	= "SH7770",
 	[CPU_SH7780]	= "SH7780",	[CPU_SH7781]	= "SH7781",
 	[CPU_SH7343]	= "SH7343",	[CPU_SH7785]	= "SH7785",
-	[CPU_SH7786]	= "SH7786",
+	[CPU_SH7786]	= "SH7786",	[CPU_SH7757]	= "SH7757",
 	[CPU_SH7722]	= "SH7722",	[CPU_SHX3]	= "SH-X3",
 	[CPU_SH5_101]	= "SH5-101",	[CPU_SH5_103]	= "SH5-103",
 	[CPU_MXG]	= "MX-G",	[CPU_SH7723]	= "SH7723",
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index fcc5de3..8dbe26b 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -101,20 +101,14 @@
 EXPORT_SYMBOL(flush_dcache_page);
 #endif
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
-	(defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
-EXPORT_SYMBOL(clear_user_page);
-#endif
-
-#ifdef CONFIG_FUNCTION_TRACER
-EXPORT_SYMBOL(mcount);
+#ifdef CONFIG_MCOUNT
+DECLARE_EXPORT(mcount);
 #endif
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
 #ifdef CONFIG_IPV6
 EXPORT_SYMBOL(csum_ipv6_magic);
 #endif
-EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(_ebss);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index f5bd156..d008e17 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -30,14 +30,6 @@
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU)
-EXPORT_SYMBOL(clear_user_page);
-#endif
-
-#ifndef CONFIG_CACHE_OFF
-EXPORT_SYMBOL(flush_dcache_page);
-#endif
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
@@ -52,7 +44,6 @@
 EXPORT_SYMBOL(__get_user_asm_q);
 EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 04a2188..6729703 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -41,6 +41,16 @@
 };
 
 /*
+ * The following define adds a 64 byte gap between the signal
+ * stack frame and previous contents of the stack.  This allows
+ * frame unwinding in a function epilogue but only if a frame
+ * pointer is used in the function.  This is necessary because
+ * current gcc compilers (<4.3) do not generate unwind info on
+ * SH for function epilogues.
+ */
+#define UNWINDGUARD 64
+
+/*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 asmlinkage int
@@ -327,7 +337,7 @@
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
-	return (void __user *)((sp - frame_size) & -8ul);
+	return (void __user *)((sp - (frame_size+UNWINDGUARD)) & -8ul);
 }
 
 /* These symbols are defined with the addresses in the vsyscall page.
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 9e5c9b1..74793c8 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -561,13 +561,11 @@
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
-		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
-
 		/*
 		 * On SH5 all edited pointers are subject to NEFF
 		 */
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			ka->sa.sa_restorer | 0x1);
 	} else {
 		/*
 		 * Different approach on SH5.
@@ -580,9 +578,8 @@
 		 * . being code, linker turns ShMedia bit on, always
 		 *   dereference index -1.
 		 */
-		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			frame->retcode | 0x01);
 
 		if (__copy_to_user(frame->retcode,
 			(void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
@@ -596,9 +593,7 @@
 	 * Set up registers for signal handler.
 	 * All edited pointers are subject to NEFF.
 	 */
-	regs->regs[REG_SP] = (unsigned long) frame;
-	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
-		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
 
         /* FIXME:
@@ -613,8 +608,7 @@
 	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 	regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 
-	regs->pc = (unsigned long) ka->sa.sa_handler;
-	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+	regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
 
 	set_fs(USER_DS);
 
@@ -676,13 +670,11 @@
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
-		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
-
 		/*
 		 * On SH5 all edited pointers are subject to NEFF
 		 */
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			ka->sa.sa_restorer | 0x1);
 	} else {
 		/*
 		 * Different approach on SH5.
@@ -695,15 +687,14 @@
 		 * . being code, linker turns ShMedia bit on, always
 		 *   dereference index -1.
 		 */
-
-		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			frame->retcode | 0x01);
 
 		if (__copy_to_user(frame->retcode,
 			(void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
 			goto give_sigsegv;
 
+		/* Cohere the trampoline with the I-cache. */
 		flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
 	}
 
@@ -711,14 +702,11 @@
 	 * Set up registers for signal handler.
 	 * All edited pointers are subject to NEFF.
 	 */
-	regs->regs[REG_SP] = (unsigned long) frame;
-	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
-		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
 	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
 	regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
-	regs->pc = (unsigned long) ka->sa.sa_handler;
-	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+	regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
 
 	set_fs(USER_DS);
 
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 1a2a5eb..c2e45c4 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -13,47 +13,93 @@
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
+#include <asm/stacktrace.h>
+
+static void save_stack_warning(void *data, char *msg)
+{
+}
+
+static void
+save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int save_stack_stack(void *data, char *name)
+{
+	return 0;
+}
 
 /*
  * Save stack-backtrace addresses into a stack_trace buffer.
  */
+static void save_stack_address(void *data, unsigned long addr, int reliable)
+{
+	struct stack_trace *trace = data;
+
+	if (!reliable)
+		return;
+
+	if (trace->skip > 0) {
+		trace->skip--;
+		return;
+	}
+
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops = {
+	.warning = save_stack_warning,
+	.warning_symbol = save_stack_warning_symbol,
+	.stack = save_stack_stack,
+	.address = save_stack_address,
+};
+
 void save_stack_trace(struct stack_trace *trace)
 {
 	unsigned long *sp = (unsigned long *)current_stack_pointer;
 
-	while (!kstack_end(sp)) {
-		unsigned long addr = *sp++;
-
-		if (__kernel_text_address(addr)) {
-			if (trace->skip > 0)
-				trace->skip--;
-			else
-				trace->entries[trace->nr_entries++] = addr;
-			if (trace->nr_entries >= trace->max_entries)
-				break;
-		}
-	}
+	unwind_stack(current, NULL, sp,  &save_stack_ops, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 EXPORT_SYMBOL_GPL(save_stack_trace);
 
+static void
+save_stack_address_nosched(void *data, unsigned long addr, int reliable)
+{
+	struct stack_trace *trace = (struct stack_trace *)data;
+
+	if (!reliable)
+		return;
+
+	if (in_sched_functions(addr))
+		return;
+
+	if (trace->skip > 0) {
+		trace->skip--;
+		return;
+	}
+
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops_nosched = {
+	.warning = save_stack_warning,
+	.warning_symbol = save_stack_warning_symbol,
+	.stack = save_stack_stack,
+	.address = save_stack_address_nosched,
+};
+
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
 	unsigned long *sp = (unsigned long *)tsk->thread.sp;
 
-	while (!kstack_end(sp)) {
-		unsigned long addr = *sp++;
-
-		if (__kernel_text_address(addr)) {
-			if (in_sched_functions(addr))
-				break;
-			if (trace->skip > 0)
-				trace->skip--;
-			else
-				trace->entries[trace->nr_entries++] = addr;
-			if (trace->nr_entries >= trace->max_entries)
-				break;
-		}
-	}
+	unwind_stack(current, NULL, sp,  &save_stack_ops_nosched, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 90d00e4..8aa5d1c 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -25,6 +25,8 @@
 #include <asm/syscalls.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <asm/cacheflush.h>
+#include <asm/cachectl.h>
 
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
@@ -179,6 +181,47 @@
 	return -EINVAL;
 }
 
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
+{
+	struct vm_area_struct *vma;
+
+	if ((op <= 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I)))
+		return -EINVAL;
+
+	/*
+	 * Verify that the specified address region actually belongs
+	 * to this process.
+	 */
+	if (addr + len < addr)
+		return -EFAULT;
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma (current->mm, addr);
+	if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
+		up_read(&current->mm->mmap_sem);
+		return -EFAULT;
+	}
+
+	switch (op & CACHEFLUSH_D_PURGE) {
+		case CACHEFLUSH_D_INVAL:
+			__flush_invalidate_region((void *)addr, len);
+			break;
+		case CACHEFLUSH_D_WB:
+			__flush_wback_region((void *)addr, len);
+			break;
+		case CACHEFLUSH_D_PURGE:
+			__flush_purge_region((void *)addr, len);
+			break;
+	}
+
+	if (op & CACHEFLUSH_I)
+		flush_cache_all();
+
+	up_read(&current->mm->mmap_sem);
+	return 0;
+}
+
 asmlinkage int sys_uname(struct old_utsname __user *name)
 {
 	int err;
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index f9e21fa..16ba225 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -139,7 +139,7 @@
 	.long sys_clone		/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_cacheflush	/* x86: sys_modify_ldt */
 	.long sys_adjtimex
 	.long sys_mprotect		/* 125 */
 	.long sys_sigprocmask
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index bf420b6..af6fb74 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -143,7 +143,7 @@
 	.long sys_clone			/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_cacheflush	/* x86: sys_modify_ldt */
 	.long sys_adjtimex
 	.long sys_mprotect		/* 125 */
 	.long sys_sigprocmask
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 9b352a1..632aff5 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/rtc.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
 #include <asm/rtc.h>
 
 /* Dummy RTC ops */
@@ -91,21 +92,8 @@
 
 void (*board_time_init)(void);
 
-void __init time_init(void)
+static void __init sh_late_time_init(void)
 {
-	if (board_time_init)
-		board_time_init();
-
-	clk_init();
-
-	rtc_sh_get_time(&xtime);
-	set_normalized_timespec(&wall_to_monotonic,
-				-xtime.tv_sec, -xtime.tv_nsec);
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-	local_timer_setup(smp_processor_id());
-#endif
-
 	/*
 	 * Make sure all compiled-in early timers register themselves.
 	 *
@@ -118,3 +106,18 @@
 	early_platform_driver_register_all("earlytimer");
 	early_platform_driver_probe("earlytimer", 2, 0);
 }
+
+void __init time_init(void)
+{
+	if (board_time_init)
+		board_time_init();
+
+	hwblk_init();
+	clk_init();
+
+	rtc_sh_get_time(&xtime);
+	set_normalized_timespec(&wall_to_monotonic,
+				-xtime.tv_sec, -xtime.tv_nsec);
+
+	late_time_init = sh_late_time_init;
+}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index b3e0067..a8396f3 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,18 +5,33 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
+#include <linux/hardirq.h>
+#include <asm/unwinder.h>
 #include <asm/system.h>
 
 #ifdef CONFIG_BUG
-static void handle_BUG(struct pt_regs *regs)
+void handle_BUG(struct pt_regs *regs)
 {
+	const struct bug_entry *bug;
+	unsigned long bugaddr = regs->pc;
 	enum bug_trap_type tt;
-	tt = report_bug(regs->pc, regs);
+
+	if (!is_valid_bugaddr(bugaddr))
+		goto invalid;
+
+	bug = find_bug(bugaddr);
+
+	/* Switch unwinders when unwind_stack() is called */
+	if (bug->flags & BUGFLAG_UNWINDER)
+		unwinder_faulted = 1;
+
+	tt = report_bug(bugaddr, regs);
 	if (tt == BUG_TRAP_TYPE_WARN) {
-		regs->pc += instruction_size(regs->pc);
+		regs->pc += instruction_size(bugaddr);
 		return;
 	}
 
+invalid:
 	die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
 }
 
@@ -28,8 +43,10 @@
 		return 0;
 	if (probe_kernel_address((insn_size_t *)addr, opcode))
 		return 0;
+	if (opcode == TRAPA_BUG_OPCODE)
+		return 1;
 
-	return opcode == TRAPA_BUG_OPCODE;
+	return 0;
 }
 #endif
 
@@ -75,3 +92,23 @@
 
 	force_sig(SIGTRAP, current);
 }
+
+BUILD_TRAP_HANDLER(nmi)
+{
+	TRAP_HANDLER_DECL;
+
+	nmi_enter();
+
+	switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
+	case NOTIFY_OK:
+	case NOTIFY_STOP:
+		break;
+	case NOTIFY_BAD:
+		die("Fatal Non-Maskable Interrupt", regs, SIGINT);
+	default:
+		printk(KERN_ALERT "Got NMI, but nobody cared. Ignoring...\n");
+		break;
+	}
+
+	nmi_exit();
+}
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 2b77277..583ace5 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -24,6 +24,7 @@
 #include <linux/kdebug.h>
 #include <linux/kexec.h>
 #include <linux/limits.h>
+#include <linux/proc_fs.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/fpu.h>
@@ -44,6 +45,87 @@
 #define TRAP_ILLEGAL_SLOT_INST	13
 #endif
 
+static unsigned long se_user;
+static unsigned long se_sys;
+static unsigned long se_skipped;
+static unsigned long se_half;
+static unsigned long se_word;
+static unsigned long se_dword;
+static unsigned long se_multi;
+/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
+   valid! */
+static int se_usermode = 3;
+/* 0: no warning 1: print a warning message */
+static int se_kernmode_warn = 1;
+
+#ifdef CONFIG_PROC_FS
+static const char *se_usermode_action[] = {
+	"ignored",
+	"warn",
+	"fixup",
+	"fixup+warn",
+	"signal",
+	"signal+warn"
+};
+
+static int
+proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
+		    void *data)
+{
+	char *p = page;
+	int len;
+
+	p += sprintf(p, "User:\t\t%lu\n", se_user);
+	p += sprintf(p, "System:\t\t%lu\n", se_sys);
+	p += sprintf(p, "Skipped:\t%lu\n", se_skipped);
+	p += sprintf(p, "Half:\t\t%lu\n", se_half);
+	p += sprintf(p, "Word:\t\t%lu\n", se_word);
+	p += sprintf(p, "DWord:\t\t%lu\n", se_dword);
+	p += sprintf(p, "Multi:\t\t%lu\n", se_multi);
+	p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode,
+			se_usermode_action[se_usermode]);
+	p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+			se_kernmode_warn ? "+warn" : "");
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+static int proc_alignment_write(struct file *file, const char __user *buffer,
+				unsigned long count, void *data)
+{
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '5')
+			se_usermode = mode - '0';
+	}
+	return count;
+}
+
+static int proc_alignment_kern_write(struct file *file, const char __user *buffer,
+				     unsigned long count, void *data)
+{
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '1')
+			se_kernmode_warn = mode - '0';
+	}
+	return count;
+}
+#endif
+
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p;
@@ -136,6 +218,7 @@
 			regs->pc = fixup->fixup;
 			return;
 		}
+
 		die(str, regs, err);
 	}
 }
@@ -193,6 +276,13 @@
 
 	count = 1<<(instruction&3);
 
+	switch (count) {
+	case 1: se_half  += 1; break;
+	case 2: se_word  += 1; break;
+	case 4: se_dword += 1; break;
+	case 8: se_multi += 1; break; /* ??? */
+	}
+
 	ret = -EFAULT;
 	switch (instruction>>12) {
 	case 0: /* mov.[bwl] to/from memory via r0+rn */
@@ -358,15 +448,8 @@
 #define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
 #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
 
-/*
- * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
- * opcodes..
- */
-
-static int handle_unaligned_notify_count = 10;
-
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma)
+			    struct mem_access *ma, int expected)
 {
 	u_int rm;
 	int ret, index;
@@ -374,15 +457,13 @@
 	index = (instruction>>8)&15;	/* 0x0F00 */
 	rm = regs->regs[index];
 
-	/* shout about the first ten userspace fixups */
-	if (user_mode(regs) && handle_unaligned_notify_count>0) {
-		handle_unaligned_notify_count--;
-
-		printk(KERN_NOTICE "Fixing up unaligned userspace access "
+	/* shout about fixups */
+	if (!expected && printk_ratelimit())
+		printk(KERN_NOTICE "Fixing up unaligned %s access "
 		       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+		       user_mode(regs) ? "userspace" : "kernel",
 		       current->comm, task_pid_nr(current),
 		       (void *)regs->pc, instruction);
-	}
 
 	ret = -EFAULT;
 	switch (instruction&0xF000) {
@@ -538,6 +619,36 @@
 
 		local_irq_enable();
 
+		se_user += 1;
+
+#ifndef CONFIG_CPU_SH2A
+		set_fs(USER_DS);
+		if (copy_from_user(&instruction, (u16 *)(regs->pc & ~1), 2)) {
+			set_fs(oldfs);
+			goto uspace_segv;
+		}
+		set_fs(oldfs);
+
+		/* shout about userspace fixups */
+		if (se_usermode & 1)
+			printk(KERN_NOTICE "Unaligned userspace access "
+			       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			       current->comm, current->pid, (void *)regs->pc,
+			       instruction);
+#endif
+
+		if (se_usermode & 2)
+			goto fixup;
+
+		if (se_usermode & 4)
+			goto uspace_segv;
+		else {
+			/* ignore */
+			regs->pc += instruction_size(instruction);
+			return;
+		}
+
+fixup:
 		/* bad PC is not something we can fix */
 		if (regs->pc & 1) {
 			si_code = BUS_ADRALN;
@@ -545,17 +656,8 @@
 		}
 
 		set_fs(USER_DS);
-		if (copy_from_user(&instruction, (void __user *)(regs->pc),
-				   sizeof(instruction))) {
-			/* Argh. Fault on the instruction itself.
-			   This should never happen non-SMP
-			*/
-			set_fs(oldfs);
-			goto uspace_segv;
-		}
-
 		tmp = handle_unaligned_access(instruction, regs,
-					      &user_mem_access);
+					      &user_mem_access, 0);
 		set_fs(oldfs);
 
 		if (tmp==0)
@@ -571,6 +673,14 @@
 		info.si_addr = (void __user *)address;
 		force_sig_info(SIGBUS, &info, current);
 	} else {
+		se_sys += 1;
+
+		if (se_kernmode_warn)
+			printk(KERN_NOTICE "Unaligned kernel access "
+			       "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			       current->comm, current->pid, (void *)regs->pc,
+			       instruction);
+
 		if (regs->pc & 1)
 			die("unaligned program counter", regs, error_code);
 
@@ -584,7 +694,8 @@
 			die("insn faulting in do_address_error", regs, 0);
 		}
 
-		handle_unaligned_access(instruction, regs, &user_mem_access);
+		handle_unaligned_access(instruction, regs,
+					&user_mem_access, 0);
 		set_fs(oldfs);
 	}
 }
@@ -858,30 +969,6 @@
 	per_cpu_trap_init();
 }
 
-void show_trace(struct task_struct *tsk, unsigned long *sp,
-		struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	if (regs && user_mode(regs))
-		return;
-
-	printk("\nCall trace:\n");
-
-	while (!kstack_end(sp)) {
-		addr = *sp++;
-		if (kernel_text_address(addr))
-			print_ip_sym(addr);
-	}
-
-	printk("\n");
-
-	if (!tsk)
-		tsk = current;
-
-	debug_show_held_locks(tsk);
-}
-
 void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
 	unsigned long stack;
@@ -904,3 +991,38 @@
 	show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
+
+#ifdef CONFIG_PROC_FS
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+	struct proc_dir_entry *dir, *res;
+
+	dir = proc_mkdir("cpu", NULL);
+	if (!dir)
+		return -ENOMEM;
+
+	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir);
+	if (!res)
+		return -ENOMEM;
+
+	res->read_proc = proc_alignment_read;
+	res->write_proc = proc_alignment_write;
+
+        res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir);
+        if (!res)
+                return -ENOMEM;
+
+        res->read_proc = proc_alignment_read;
+        res->write_proc = proc_alignment_kern_write;
+
+	return 0;
+}
+
+fs_initcall(alignment_init);
+#endif
diff --git a/arch/sh/kernel/unwinder.c b/arch/sh/kernel/unwinder.c
new file mode 100644
index 0000000..468889d
--- /dev/null
+++ b/arch/sh/kernel/unwinder.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based, in part, on kernel/time/clocksource.c.
+ *
+ * This file provides arbitration code for stack unwinders.
+ *
+ * Multiple stack unwinders can be available on a system, usually with
+ * the most accurate unwinder being the currently active one.
+ */
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <asm/unwinder.h>
+#include <asm/atomic.h>
+
+/*
+ * This is the most basic stack unwinder an architecture can
+ * provide. For architectures without reliable frame pointers, e.g.
+ * RISC CPUs, it can be implemented by looking through the stack for
+ * addresses that lie within the kernel text section.
+ *
+ * Other CPUs, e.g. x86, can use their frame pointer register to
+ * construct more accurate stack traces.
+ */
+static struct list_head unwinder_list;
+static struct unwinder stack_reader = {
+	.name = "stack-reader",
+	.dump = stack_reader_dump,
+	.rating = 50,
+	.list = {
+		.next = &unwinder_list,
+		.prev = &unwinder_list,
+	},
+};
+
+/*
+ * "curr_unwinder" points to the stack unwinder currently in use. This
+ * is the unwinder with the highest rating.
+ *
+ * "unwinder_list" is a linked-list of all available unwinders, sorted
+ * by rating.
+ *
+ * All modifications of "curr_unwinder" and "unwinder_list" must be
+ * performed whilst holding "unwinder_lock".
+ */
+static struct unwinder *curr_unwinder = &stack_reader;
+
+static struct list_head unwinder_list = {
+	.next = &stack_reader.list,
+	.prev = &stack_reader.list,
+};
+
+static DEFINE_SPINLOCK(unwinder_lock);
+
+/**
+ * select_unwinder - Select the best registered stack unwinder.
+ *
+ * Private function. Must hold unwinder_lock when called.
+ *
+ * Select the stack unwinder with the best rating. This is useful for
+ * setting up curr_unwinder.
+ */
+static struct unwinder *select_unwinder(void)
+{
+	struct unwinder *best;
+
+	if (list_empty(&unwinder_list))
+		return NULL;
+
+	best = list_entry(unwinder_list.next, struct unwinder, list);
+	if (best == curr_unwinder)
+		return NULL;
+
+	return best;
+}
+
+/*
+ * Enqueue the stack unwinder sorted by rating.
+ */
+static int unwinder_enqueue(struct unwinder *ops)
+{
+	struct list_head *tmp, *entry = &unwinder_list;
+
+	list_for_each(tmp, &unwinder_list) {
+		struct unwinder *o;
+
+		o = list_entry(tmp, struct unwinder, list);
+		if (o == ops)
+			return -EBUSY;
+		/* Keep track of the place, where to insert */
+		if (o->rating >= ops->rating)
+			entry = tmp;
+	}
+	list_add(&ops->list, entry);
+
+	return 0;
+}
+
+/**
+ * unwinder_register - Used to install new stack unwinder
+ * @u: unwinder to be registered
+ *
+ * Install the new stack unwinder on the unwinder list, which is sorted
+ * by rating.
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ */
+int unwinder_register(struct unwinder *u)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&unwinder_lock, flags);
+	ret = unwinder_enqueue(u);
+	if (!ret)
+		curr_unwinder = select_unwinder();
+	spin_unlock_irqrestore(&unwinder_lock, flags);
+
+	return ret;
+}
+
+int unwinder_faulted = 0;
+
+/*
+ * Unwind the call stack and pass information to the stacktrace_ops
+ * functions. Also handle the case where we need to switch to a new
+ * stack dumper because the current one faulted unexpectedly.
+ */
+void unwind_stack(struct task_struct *task, struct pt_regs *regs,
+		  unsigned long *sp, const struct stacktrace_ops *ops,
+		  void *data)
+{
+	unsigned long flags;
+
+	/*
+	 * The problem with unwinders with high ratings is that they are
+	 * inherently more complicated than the simple ones with lower
+	 * ratings. We are therefore more likely to fault in the
+	 * complicated ones, e.g. hitting BUG()s. If we fault in the
+	 * code for the current stack unwinder we try to downgrade to
+	 * one with a lower rating.
+	 *
+	 * Hopefully this will give us a semi-reliable stacktrace so we
+	 * can diagnose why curr_unwinder->dump() faulted.
+	 */
+	if (unwinder_faulted) {
+		spin_lock_irqsave(&unwinder_lock, flags);
+
+		/* Make sure no one beat us to changing the unwinder */
+		if (unwinder_faulted && !list_is_singular(&unwinder_list)) {
+			list_del(&curr_unwinder->list);
+			curr_unwinder = select_unwinder();
+
+			unwinder_faulted = 0;
+		}
+
+		spin_unlock_irqrestore(&unwinder_lock, flags);
+	}
+
+	curr_unwinder->dump(task, regs, sp, ops, data);
+}
+EXPORT_SYMBOL_GPL(unwind_stack);
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 0ce254b..a1e4ec2 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -12,7 +12,7 @@
 
 #include <asm/thread_info.h>
 #include <asm/cache.h>
-#include <asm-generic/vmlinux.lds.h>
+#include <asm/vmlinux.lds.h>
 
 ENTRY(_start)
 SECTIONS
@@ -50,12 +50,7 @@
 		_etext = .;		/* End of text section */
 	} = 0x0009
 
-	. = ALIGN(16);		/* Exception table */
-	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-	}
+	EXCEPTION_TABLE(16)
 
 	NOTES
 	RO_DATA(PAGE_SIZE)
@@ -71,69 +66,16 @@
 		__uncached_end = .;
 	}
 
-	. = ALIGN(THREAD_SIZE);
-	.data : AT(ADDR(.data) - LOAD_OFFSET) {		/* Data */
-		*(.data.init_task)
-
-		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.cacheline_aligned)
-
-		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.read_mostly)
-
-		. = ALIGN(PAGE_SIZE);
-		*(.data.page_aligned)
-
-		__nosave_begin = .;
-		*(.data.nosave)
-		. = ALIGN(PAGE_SIZE);
-		__nosave_end = .;
-
-		DATA_DATA
-		CONSTRUCTORS
-	}
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
 	_edata = .;			/* End of data section */
 
+	DWARF_EH_FRAME
+
 	. = ALIGN(PAGE_SIZE);		/* Init code and data */
-	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-		__init_begin = .;
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-	}
-
-	.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA }
-
-	. = ALIGN(16);
-	.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-	}
-
-	.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-	}
-
-	.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-	}
-
-	SECURITY_INIT
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	. = ALIGN(PAGE_SIZE);
-	.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-	}
-#endif
+	__init_begin = .;
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(16)
 
 	. = ALIGN(4);
 	.machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
@@ -152,25 +94,13 @@
 	.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
 
 	. = ALIGN(PAGE_SIZE);
-	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-		__init_end = .;
-		__bss_start = .;		/* BSS */
-		*(.bss.page_aligned)
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4);
-		_ebss = .;			/* uClinux MTD sucks */
-		_end = . ;
-	}
+	__init_end = .;
+	BSS_SECTION(0, PAGE_SIZE, 4)
+	_ebss = .;			/* uClinux MTD sucks */
+	_end = . ;
 
 	STABS_DEBUG
 	DWARF_DEBUG
 
-	/*
-	 * When something in the kernel is NOT compiled as a module, the
-	 * module cleanup code and data are put into these segments. Both
-	 * can then be thrown away, as cleanup code is never called unless
-	 * it's a module.
-	 */
 	DISCARDS
 }
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index aaea580..a969b47 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -23,8 +23,8 @@
 memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
-lib-$(CONFIG_MMU)		+= copy_page.o clear_page.o
-lib-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
+lib-$(CONFIG_MMU)		+= copy_page.o __clear_user.o
+lib-$(CONFIG_MCOUNT)		+= mcount.o
 lib-y				+= $(memcpy-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/__clear_user.S
similarity index 75%
rename from arch/sh/lib/clear_page.S
rename to arch/sh/lib/__clear_user.S
index 8342bfb..db1dca7 100644
--- a/arch/sh/lib/clear_page.S
+++ b/arch/sh/lib/__clear_user.S
@@ -8,56 +8,10 @@
 #include <linux/linkage.h>
 #include <asm/page.h>
 
-/*
- * clear_page
- * @to: P1 address
- *
- * void clear_page(void *to)
- */
-
-/*
- * r0 --- scratch
- * r4 --- to
- * r5 --- to + PAGE_SIZE
- */
-ENTRY(clear_page)
-	mov	r4,r5
-	mov.l	.Llimit,r0
-	add	r0,r5
-	mov	#0,r0
-	!
-1:
-#if defined(CONFIG_CPU_SH4)
-	movca.l	r0,@r4
-	mov	r4,r1
-#else
-	mov.l	r0,@r4
-#endif
-	add	#32,r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-#if defined(CONFIG_CPU_SH4)
-	ocbwb	@r1
-#endif
-	cmp/eq	r5,r4
-	bf/s	1b
-	 add	#28,r4
-	!
-	rts
-	 nop
-
-	.balign 4
-.Llimit:	.long	(PAGE_SIZE-28)
-
 ENTRY(__clear_user)
 	!
 	mov	#0, r0
-	mov	#0xe0, r1	! 0xffffffe0
+	mov	#0xffffffe0, r1
 	!
 	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
 	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S
index 43de7e8..9d7b8bc 100644
--- a/arch/sh/lib/copy_page.S
+++ b/arch/sh/lib/copy_page.S
@@ -30,7 +30,9 @@
 	mov	r4,r10
 	mov	r5,r11
 	mov	r5,r8
-	mov.l	.Lpsz,r0
+	mov	#(PAGE_SIZE >> 10), r0
+	shll8	r0
+	shll2	r0
 	add	r0,r8
 	!
 1:	mov.l	@r11+,r0
@@ -43,7 +45,6 @@
 	mov.l	@r11+,r7
 #if defined(CONFIG_CPU_SH4)
 	movca.l	r0,@r10
-	mov	r10,r0
 #else
 	mov.l	r0,@r10
 #endif
@@ -55,9 +56,6 @@
 	mov.l	r3,@-r10
 	mov.l	r2,@-r10
 	mov.l	r1,@-r10
-#if defined(CONFIG_CPU_SH4)
-	ocbwb	@r0
-#endif
 	cmp/eq	r11,r8
 	bf/s	1b
 	 add	#28,r10
@@ -68,9 +66,6 @@
 	rts
 	 nop
 
-	.balign 4
-.Lpsz:	.long	PAGE_SIZE
-
 /*
  * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
  * Return the number of bytes NOT copied
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
index f3ddd21..faa8f86 100644
--- a/arch/sh/lib/delay.c
+++ b/arch/sh/lib/delay.c
@@ -21,13 +21,14 @@
 
 inline void __const_udelay(unsigned long xloops)
 {
+	xloops *= 4;
 	__asm__("dmulu.l	%0, %2\n\t"
 		"sts	mach, %0"
 		: "=r" (xloops)
 		: "0" (xloops),
-		  "r" (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy)
+		  "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))
 		: "macl", "mach");
-	__delay(xloops);
+	__delay(++xloops);
 }
 
 void __udelay(unsigned long usecs)
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
index 110fbfe..84a5776 100644
--- a/arch/sh/lib/mcount.S
+++ b/arch/sh/lib/mcount.S
@@ -1,14 +1,16 @@
 /*
  * arch/sh/lib/mcount.S
  *
- *  Copyright (C) 2008  Paul Mundt
- *  Copyright (C) 2008  Matt Fleming
+ *  Copyright (C) 2008, 2009  Paul Mundt
+ *  Copyright (C) 2008, 2009  Matt Fleming
  *
  * 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.
  */
 #include <asm/ftrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
 
 #define MCOUNT_ENTER()		\
 	mov.l	r4, @-r15;	\
@@ -28,6 +30,55 @@
 	rts;			\
 	 mov.l	@r15+, r4
 
+#ifdef CONFIG_STACK_DEBUG
+/*
+ * Perform diagnostic checks on the state of the kernel stack.
+ *
+ * Check for stack overflow. If there is less than 1KB free
+ * then it has overflowed.
+ *
+ * Make sure the stack pointer contains a valid address. Valid
+ * addresses for kernel stacks are anywhere after the bss
+ * (after _ebss) and anywhere in init_thread_union (init_stack).
+ */
+#define STACK_CHECK()					\
+	mov	#(THREAD_SIZE >> 10), r0;		\
+	shll8	r0;					\
+	shll2	r0;					\
+							\
+	/* r1 = sp & (THREAD_SIZE - 1) */		\
+	mov	#-1, r1;				\
+	add	r0, r1;					\
+	and	r15, r1;				\
+							\
+	mov	#TI_SIZE, r3;				\
+	mov	#(STACK_WARN >> 8), r2;			\
+	shll8	r2;					\
+	add	r3, r2;					\
+							\
+	/* Is the stack overflowing? */			\
+	cmp/hi	r2, r1;					\
+	bf	stack_panic;				\
+							\
+	/* If sp > _ebss then we're OK. */		\
+	mov.l	.L_ebss, r1;				\
+	cmp/hi	r1, r15;				\
+	bt	1f;					\
+							\
+	/* If sp < init_stack, we're not OK. */		\
+	mov.l	.L_init_thread_union, r1;		\
+	cmp/hs	r1, r15;				\
+	bf	stack_panic;				\
+							\
+	/* If sp > init_stack && sp < _ebss, not OK. */	\
+	add	r0, r1;					\
+	cmp/hs	r1, r15;				\
+	bt	stack_panic;				\
+1:
+#else
+#define STACK_CHECK()
+#endif /* CONFIG_STACK_DEBUG */
+
 	.align 2
 	.globl	_mcount
 	.type	_mcount,@function
@@ -35,6 +86,19 @@
 	.type	mcount,@function
 _mcount:
 mcount:
+	STACK_CHECK()
+
+#ifndef CONFIG_FUNCTION_TRACER
+	rts
+	 nop
+#else
+#ifndef CONFIG_DYNAMIC_FTRACE
+	mov.l	.Lfunction_trace_stop, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bf	ftrace_stub
+#endif
+
 	MCOUNT_ENTER()
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -52,16 +116,69 @@
 	jsr	@r6
 	 nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	mov.l   .Lftrace_graph_return, r6
+	mov.l   .Lftrace_stub, r7
+	cmp/eq  r6, r7
+	bt      1f
+
+	mov.l   .Lftrace_graph_caller, r0
+	jmp     @r0
+	 nop
+
+1:
+	mov.l	.Lftrace_graph_entry, r6
+	mov.l	.Lftrace_graph_entry_stub, r7
+	cmp/eq	r6, r7
+	bt	skip_trace
+
+	mov.l   .Lftrace_graph_caller, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+.Lftrace_graph_return:
+	.long   ftrace_graph_return
+.Lftrace_graph_entry:
+	.long   ftrace_graph_entry
+.Lftrace_graph_entry_stub:
+	.long   ftrace_graph_entry_stub
+.Lftrace_graph_caller:
+	.long   ftrace_graph_caller
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+	.globl skip_trace
 skip_trace:
 	MCOUNT_LEAVE()
 
 	.align 2
 .Lftrace_trace_function:
-	.long	ftrace_trace_function
+	.long   ftrace_trace_function
 
 #ifdef CONFIG_DYNAMIC_FTRACE
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * NOTE: Do not move either ftrace_graph_call or ftrace_caller
+ * as this will affect the calculation of GRAPH_INSN_OFFSET.
+ */
+	.globl ftrace_graph_call
+ftrace_graph_call:
+	mov.l	.Lskip_trace, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+.Lskip_trace:
+	.long	skip_trace
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
 	.globl ftrace_caller
 ftrace_caller:
+	mov.l	.Lfunction_trace_stop, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bf	ftrace_stub
+
 	MCOUNT_ENTER()
 
 	.globl ftrace_call
@@ -70,9 +187,18 @@
 	jsr	@r6
 	 nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	bra	ftrace_graph_call
+	 nop
+#else
 	MCOUNT_LEAVE()
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
+	.align 2
+.Lfunction_trace_stop:
+	.long	function_trace_stop
+
 /*
  * NOTE: From here on the locations of the .Lftrace_stub label and
  * ftrace_stub itself are fixed. Adding additional data here will skew
@@ -80,7 +206,6 @@
  * Place new labels either after the ftrace_stub body, or before
  * ftrace_caller. You have been warned.
  */
-	.align 2
 .Lftrace_stub:
 	.long	ftrace_stub
 
@@ -88,3 +213,98 @@
 ftrace_stub:
 	rts
 	 nop
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.globl	ftrace_graph_caller
+ftrace_graph_caller:
+	mov.l	2f, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bt	1f
+
+	mov.l	3f, r1
+	jmp	@r1
+	 nop
+1:
+	/*
+	 * MCOUNT_ENTER() pushed 5 registers onto the stack, so
+	 * the stack address containing our return address is
+	 * r15 + 20.
+	 */
+	mov	#20, r0
+	add	r15, r0
+	mov	r0, r4
+
+	mov.l	.Lprepare_ftrace_return, r0
+	jsr	@r0
+	 nop
+
+	MCOUNT_LEAVE()
+
+	.align 2
+2:	.long	function_trace_stop
+3:	.long	skip_trace
+.Lprepare_ftrace_return:
+	.long	prepare_ftrace_return
+
+	.globl	return_to_handler
+return_to_handler:
+	/*
+	 * Save the return values.
+	 */
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+
+	mov	#0, r4
+
+	mov.l	.Lftrace_return_to_handler, r0
+	jsr	@r0
+	 nop
+
+	/*
+	 * The return value from ftrace_return_handler has the real
+	 * address that we should return to.
+	 */
+	lds	r0, pr
+	mov.l	@r15+, r1
+	rts
+	 mov.l	@r15+, r0
+
+
+	.align 2
+.Lftrace_return_to_handler:
+	.long	ftrace_return_to_handler
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#ifdef CONFIG_STACK_DEBUG
+	.globl	stack_panic
+stack_panic:
+	mov.l	.Ldump_stack, r0
+	jsr	@r0
+	 nop
+
+	mov.l	.Lpanic, r0
+	jsr	@r0
+	 mov.l	.Lpanic_s, r4
+
+	rts
+	 nop
+
+	.align 2
+.L_ebss:
+	.long	_ebss
+.L_init_thread_union:
+	.long	init_thread_union
+.Lpanic:
+	.long	panic
+.Lpanic_s:
+	.long	.Lpanic_str
+.Ldump_stack:
+	.long	dump_stack
+
+	.section	.rodata
+	.align 2
+.Lpanic_str:
+	.string "Stack error"
+#endif /* CONFIG_STACK_DEBUG */
diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile
index 334bb2d..1fee75a 100644
--- a/arch/sh/lib64/Makefile
+++ b/arch/sh/lib64/Makefile
@@ -11,7 +11,7 @@
 
 # Panic should really be compiled as PIC
 lib-y  := udelay.o dbg.o panic.o memcpy.o memset.o \
-	  copy_user_memcpy.o copy_page.o clear_page.o strcpy.o strlen.o
+	  copy_user_memcpy.o copy_page.o strcpy.o strlen.o
 
 # Extracted from libgcc
 lib-y	+= udivsi3.o udivdi3.o sdivsi3.o
diff --git a/arch/sh/lib64/clear_page.S b/arch/sh/lib64/clear_page.S
deleted file mode 100644
index 007ab48..0000000
--- a/arch/sh/lib64/clear_page.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-   Copyright 2003 Richard Curnow, SuperH (UK) Ltd.
-
-   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.
-
-   Tight version of memset for the case of just clearing a page.  It turns out
-   that having the alloco's spaced out slightly due to the increment/branch
-   pair causes them to contend less for access to the cache.  Similarly,
-   keeping the stores apart from the allocos causes less contention.  => Do two
-   separate loops.  Do multiple stores per loop to amortise the
-   increment/branch cost a little.
-
-   Parameters:
-   r2 : source effective address (start of page)
-
-   Always clears 4096 bytes.
-
-   Note : alloco guarded by synco to avoid TAKum03020 erratum
-
-*/
-
-	.section .text..SHmedia32,"ax"
-	.little
-
-	.balign 8
-	.global clear_page
-clear_page:
-	pta/l 1f, tr1
-	pta/l 2f, tr2
-	ptabs/l r18, tr0
-
-	movi 4096, r7
-	add  r2, r7, r7
-	add  r2, r63, r6
-1:
-	alloco r6, 0
-	synco	! TAKum03020
-	addi	r6, 32, r6
-	bgt/l	r7, r6, tr1
-
-	add  r2, r63, r6
-2:
-	st.q  r6,   0, r63
-	st.q  r6,   8, r63
-	st.q  r6,  16, r63
-	st.q  r6,  24, r63
-	addi r6, 32, r6
-	bgt/l r7, r6, tr2
-
-	blink tr0, r63
-
-
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 2795618..64dc1ad 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -82,7 +82,7 @@
 
 config PMB_ENABLE
 	bool "Support 32-bit physical addressing through PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
 	select 32BIT
 	default y
 	help
@@ -97,7 +97,7 @@
 
 config PMB
 	bool "PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
 	select 32BIT
 	help
 	  If you say Y here, physical addressing will be extended to
@@ -106,7 +106,8 @@
 
 config PMB_FIXED
 	bool "fixed PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || \
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \
+					   CPU_SUBTYPE_SH7780 || \
 					   CPU_SUBTYPE_SH7785)
 	select 32BIT
 	help
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 9f4bc3d..3759bf8 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -1,5 +1,65 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/mm/Makefile_32
-else
-include ${srctree}/arch/sh/mm/Makefile_64
+#
+# Makefile for the Linux SuperH-specific parts of the memory manager.
+#
+
+obj-y			:= cache.o init.o consistent.o mmap.o
+
+cacheops-$(CONFIG_CPU_SH2)		:= cache-sh2.o
+cacheops-$(CONFIG_CPU_SH2A)		:= cache-sh2a.o
+cacheops-$(CONFIG_CPU_SH3)		:= cache-sh3.o
+cacheops-$(CONFIG_CPU_SH4)		:= cache-sh4.o flush-sh4.o
+cacheops-$(CONFIG_CPU_SH5)		:= cache-sh5.o flush-sh4.o
+cacheops-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
+
+obj-y			+= $(cacheops-y)
+
+mmu-y			:= nommu.o extable_32.o
+mmu-$(CONFIG_MMU)	:= extable_$(BITS).o fault_$(BITS).o \
+			   ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o
+
+obj-y			+= $(mmu-y)
+obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
+
+ifdef CONFIG_DEBUG_FS
+obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
 endif
+
+ifdef CONFIG_MMU
+tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
+tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
+tlb-$(CONFIG_CPU_SH5)		:= tlb-sh5.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
+obj-y				+= $(tlb-y)
+endif
+
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_PMB)		+= pmb.o
+obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
+obj-$(CONFIG_NUMA)		+= numa.o
+
+# Special flags for fault_64.o.  This puts restrictions on the number of
+# caller-save registers that the compiler can target when building this file.
+# This is required because the code is called from a context in entry.S where
+# very few registers have been saved in the exception handler (for speed
+# reasons).
+# The caller save registers that have been saved and which can be used are
+# r2,r3,r4,r5 : argument passing
+# r15, r18 : SP and LINK
+# tr0-4 : allow all caller-save TR's.  The compiler seems to be able to make
+#         use of them, so it's probably beneficial to performance to save them
+#         and have them available for it.
+#
+# The resources not listed below are callee save, i.e. the compiler is free to
+# use any of them and will spill them to the stack itself.
+
+CFLAGS_fault_64.o += -ffixed-r7 \
+	-ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
+	-ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
+	-ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
+	-ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
+	-ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \
+	-ffixed-r41 -ffixed-r42 -ffixed-r43  \
+	-ffixed-r60 -ffixed-r61 -ffixed-r62 \
+	-fomit-frame-pointer
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
deleted file mode 100644
index 986a1e0..0000000
--- a/arch/sh/mm/Makefile_32
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Makefile for the Linux SuperH-specific parts of the memory manager.
-#
-
-obj-y			:= init.o extable_32.o consistent.o mmap.o
-
-ifndef CONFIG_CACHE_OFF
-cache-$(CONFIG_CPU_SH2)		:= cache-sh2.o
-cache-$(CONFIG_CPU_SH2A)	:= cache-sh2a.o
-cache-$(CONFIG_CPU_SH3)		:= cache-sh3.o
-cache-$(CONFIG_CPU_SH4)		:= cache-sh4.o
-cache-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
-endif
-
-obj-y			+= $(cache-y)
-
-mmu-y			:= tlb-nommu.o pg-nommu.o
-mmu-$(CONFIG_MMU)	:= fault_32.o tlbflush_32.o ioremap_32.o
-
-obj-y			+= $(mmu-y)
-obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
-
-ifdef CONFIG_DEBUG_FS
-obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
-endif
-
-ifdef CONFIG_MMU
-tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
-tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
-tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
-obj-y				+= $(tlb-y)
-ifndef CONFIG_CACHE_OFF
-obj-$(CONFIG_CPU_SH4)		+= pg-sh4.o
-obj-$(CONFIG_SH7705_CACHE_32KB)	+= pg-sh7705.o
-endif
-endif
-
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB)		+= pmb.o
-obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
-obj-$(CONFIG_NUMA)		+= numa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
deleted file mode 100644
index 2863ffb..0000000
--- a/arch/sh/mm/Makefile_64
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Makefile for the Linux SuperH-specific parts of the memory manager.
-#
-
-obj-y			:= init.o consistent.o mmap.o
-
-mmu-y			:= tlb-nommu.o pg-nommu.o extable_32.o
-mmu-$(CONFIG_MMU)	:= fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \
-			   extable_64.o
-
-ifndef CONFIG_CACHE_OFF
-obj-y			+= cache-sh5.o
-endif
-
-obj-y			+= $(mmu-y)
-obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
-
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_NUMA)		+= numa.o
-
-EXTRA_CFLAGS += -Werror
-
-# Special flags for fault_64.o.  This puts restrictions on the number of
-# caller-save registers that the compiler can target when building this file.
-# This is required because the code is called from a context in entry.S where
-# very few registers have been saved in the exception handler (for speed
-# reasons).
-# The caller save registers that have been saved and which can be used are
-# r2,r3,r4,r5 : argument passing
-# r15, r18 : SP and LINK
-# tr0-4 : allow all caller-save TR's.  The compiler seems to be able to make
-#         use of them, so it's probably beneficial to performance to save them
-#         and have them available for it.
-#
-# The resources not listed below are callee save, i.e. the compiler is free to
-# use any of them and will spill them to the stack itself.
-
-CFLAGS_fault_64.o += -ffixed-r7 \
-	-ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
-	-ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
-	-ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
-	-ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
-	-ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \
-	-ffixed-r41 -ffixed-r42 -ffixed-r43  \
-	-ffixed-r60 -ffixed-r61 -ffixed-r62 \
-	-fomit-frame-pointer
diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c
index c4e80d2..699a71f 100644
--- a/arch/sh/mm/cache-sh2.c
+++ b/arch/sh/mm/cache-sh2.c
@@ -16,7 +16,7 @@
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
-void __flush_wback_region(void *start, int size)
+static void sh2__flush_wback_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -37,7 +37,7 @@
 	}
 }
 
-void __flush_purge_region(void *start, int size)
+static void sh2__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -51,7 +51,7 @@
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 }
 
-void __flush_invalidate_region(void *start, int size)
+static void sh2__flush_invalidate_region(void *start, int size)
 {
 #ifdef CONFIG_CACHE_WRITEBACK
 	/*
@@ -82,3 +82,10 @@
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 #endif
 }
+
+void __init sh2_cache_init(void)
+{
+	__flush_wback_region		= sh2__flush_wback_region;
+	__flush_purge_region		= sh2__flush_purge_region;
+	__flush_invalidate_region	= sh2__flush_invalidate_region;
+}
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 24d86a7..975899d 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,7 +15,7 @@
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
-void __flush_wback_region(void *start, int size)
+static void sh2a__flush_wback_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -44,7 +44,7 @@
 	local_irq_restore(flags);
 }
 
-void __flush_purge_region(void *start, int size)
+static void sh2a__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -65,7 +65,7 @@
 	local_irq_restore(flags);
 }
 
-void __flush_invalidate_region(void *start, int size)
+static void sh2a__flush_invalidate_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -97,13 +97,15 @@
 }
 
 /* WBack O-Cache and flush I-Cache */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh2a_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
 	unsigned long v;
 	unsigned long flags;
 
-	start = start & ~(L1_CACHE_BYTES-1);
-	end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
+	start = data->addr1 & ~(L1_CACHE_BYTES-1);
+	end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
 
 	local_irq_save(flags);
 	jump_to_uncached();
@@ -127,3 +129,12 @@
 	back_to_cached();
 	local_irq_restore(flags);
 }
+
+void __init sh2a_cache_init(void)
+{
+	local_flush_icache_range	= sh2a_flush_icache_range;
+
+	__flush_wback_region		= sh2a__flush_wback_region;
+	__flush_purge_region		= sh2a__flush_purge_region;
+	__flush_invalidate_region	= sh2a__flush_invalidate_region;
+}
diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c
index 6d1dbec..faef80c 100644
--- a/arch/sh/mm/cache-sh3.c
+++ b/arch/sh/mm/cache-sh3.c
@@ -32,7 +32,7 @@
  * SIZE: Size of the region.
  */
 
-void __flush_wback_region(void *start, int size)
+static void sh3__flush_wback_region(void *start, int size)
 {
 	unsigned long v, j;
 	unsigned long begin, end;
@@ -71,7 +71,7 @@
  * START: Virtual Address (U0, P1, or P3)
  * SIZE: Size of the region.
  */
-void __flush_purge_region(void *start, int size)
+static void sh3__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -90,11 +90,16 @@
 	}
 }
 
-/*
- * No write back please
- *
- * Except I don't think there's any way to avoid the writeback. So we
- * just alias it to __flush_purge_region(). dwmw2.
- */
-void __flush_invalidate_region(void *start, int size)
-	__attribute__((alias("__flush_purge_region")));
+void __init sh3_cache_init(void)
+{
+	__flush_wback_region = sh3__flush_wback_region;
+	__flush_purge_region = sh3__flush_purge_region;
+
+	/*
+	 * No write back please
+	 *
+	 * Except I don't think there's any way to avoid the writeback.
+	 * So we just alias it to sh3__flush_purge_region(). dwmw2.
+	 */
+	__flush_invalidate_region = sh3__flush_purge_region;
+}
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 5cfe08d..b2453bb 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
@@ -25,13 +26,6 @@
 #define MAX_DCACHE_PAGES	64	/* XXX: Tune for ways */
 #define MAX_ICACHE_PAGES	32
 
-static void __flush_dcache_segment_1way(unsigned long start,
-					unsigned long extent);
-static void __flush_dcache_segment_2way(unsigned long start,
-					unsigned long extent);
-static void __flush_dcache_segment_4way(unsigned long start,
-					unsigned long extent);
-
 static void __flush_cache_4096(unsigned long addr, unsigned long phys,
 			       unsigned long exec_offset);
 
@@ -43,182 +37,56 @@
 static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
 	(void (*)(unsigned long, unsigned long))0xdeadbeef;
 
-static void compute_alias(struct cache_info *c)
-{
-	c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
-	c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
-}
-
-static void __init emit_cache_params(void)
-{
-	printk("PVR=%08x CVR=%08x PRR=%08x\n",
-		ctrl_inl(CCN_PVR),
-		ctrl_inl(CCN_CVR),
-		ctrl_inl(CCN_PRR));
-	printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-		boot_cpu_data.icache.ways,
-		boot_cpu_data.icache.sets,
-		boot_cpu_data.icache.way_incr);
-	printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-		boot_cpu_data.icache.entry_mask,
-		boot_cpu_data.icache.alias_mask,
-		boot_cpu_data.icache.n_aliases);
-	printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-		boot_cpu_data.dcache.ways,
-		boot_cpu_data.dcache.sets,
-		boot_cpu_data.dcache.way_incr);
-	printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-		boot_cpu_data.dcache.entry_mask,
-		boot_cpu_data.dcache.alias_mask,
-		boot_cpu_data.dcache.n_aliases);
-
-	/*
-	 * Emit Secondary Cache parameters if the CPU has a probed L2.
-	 */
-	if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
-		printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-			boot_cpu_data.scache.ways,
-			boot_cpu_data.scache.sets,
-			boot_cpu_data.scache.way_incr);
-		printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-			boot_cpu_data.scache.entry_mask,
-			boot_cpu_data.scache.alias_mask,
-			boot_cpu_data.scache.n_aliases);
-	}
-
-	if (!__flush_dcache_segment_fn)
-		panic("unknown number of cache ways\n");
-}
-
-/*
- * SH-4 has virtually indexed and physically tagged cache.
- */
-void __init p3_cache_init(void)
-{
-	compute_alias(&boot_cpu_data.icache);
-	compute_alias(&boot_cpu_data.dcache);
-	compute_alias(&boot_cpu_data.scache);
-
-	switch (boot_cpu_data.dcache.ways) {
-	case 1:
-		__flush_dcache_segment_fn = __flush_dcache_segment_1way;
-		break;
-	case 2:
-		__flush_dcache_segment_fn = __flush_dcache_segment_2way;
-		break;
-	case 4:
-		__flush_dcache_segment_fn = __flush_dcache_segment_4way;
-		break;
-	default:
-		__flush_dcache_segment_fn = NULL;
-		break;
-	}
-
-	emit_cache_params();
-}
-
-/*
- * Write back the dirty D-caches, but not invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_wback_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbwb	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
-
-/*
- * Write back the dirty D-caches and invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_purge_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbp	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
-
-/*
- * No write back please
- */
-void __flush_invalidate_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbi	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
-
 /*
  * Write back the range of D-cache, and purge the I-cache.
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format,
  * signal handler code and kprobes code
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh4_flush_icache_range(void *args)
 {
-	int icacheaddr;
+	struct flusher_data *data = args;
+	unsigned long start, end;
 	unsigned long flags, v;
 	int i;
 
-       /* If there are too many pages then just blow the caches */
-        if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
-                flush_cache_all();
-       } else {
-               /* selectively flush d-cache then invalidate the i-cache */
-               /* this is inefficient, so only use for small ranges */
-               start &= ~(L1_CACHE_BYTES-1);
-               end += L1_CACHE_BYTES-1;
-               end &= ~(L1_CACHE_BYTES-1);
+	start = data->addr1;
+	end = data->addr2;
 
-               local_irq_save(flags);
-               jump_to_uncached();
-
-               for (v = start; v < end; v+=L1_CACHE_BYTES) {
-                       asm volatile("ocbwb     %0"
-                                    : /* no output */
-                                    : "m" (__m(v)));
-
-                       icacheaddr = CACHE_IC_ADDRESS_ARRAY | (
-                                       v & cpu_data->icache.entry_mask);
-
-                       for (i = 0; i < cpu_data->icache.ways;
-                               i++, icacheaddr += cpu_data->icache.way_incr)
-                                       /* Clear i-cache line valid-bit */
-                                       ctrl_outl(0, icacheaddr);
-               }
-
-		back_to_cached();
-		local_irq_restore(flags);
+	/* If there are too many pages then just blow away the caches */
+	if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
+		local_flush_cache_all(NULL);
+		return;
 	}
+
+	/*
+	 * Selectively flush d-cache then invalidate the i-cache.
+	 * This is inefficient, so only use this for small ranges.
+	 */
+	start &= ~(L1_CACHE_BYTES-1);
+	end += L1_CACHE_BYTES-1;
+	end &= ~(L1_CACHE_BYTES-1);
+
+	local_irq_save(flags);
+	jump_to_uncached();
+
+	for (v = start; v < end; v += L1_CACHE_BYTES) {
+		unsigned long icacheaddr;
+
+		__ocbwb(v);
+
+		icacheaddr = CACHE_IC_ADDRESS_ARRAY | (v &
+				cpu_data->icache.entry_mask);
+
+		/* Clear i-cache line valid-bit */
+		for (i = 0; i < cpu_data->icache.ways; i++) {
+			__raw_writel(0, icacheaddr);
+			icacheaddr += cpu_data->icache.way_incr;
+		}
+	}
+
+	back_to_cached();
+	local_irq_restore(flags);
 }
 
 static inline void flush_cache_4096(unsigned long start,
@@ -244,9 +112,17 @@
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
  */
-void flush_dcache_page(struct page *page)
+static void sh4_flush_dcache_page(void *arg)
 {
-	if (test_bit(PG_mapped, &page->flags)) {
+	struct page *page = arg;
+#ifndef CONFIG_SMP
+	struct address_space *mapping = page_mapping(page);
+
+	if (mapping && !mapping_mapped(mapping))
+		set_bit(PG_dcache_dirty, &page->flags);
+	else
+#endif
+	{
 		unsigned long phys = PHYSADDR(page_address(page));
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
 		int i, n;
@@ -282,13 +158,13 @@
 	local_irq_restore(flags);
 }
 
-void flush_dcache_all(void)
+static inline void flush_dcache_all(void)
 {
 	(*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
 	wmb();
 }
 
-void flush_cache_all(void)
+static void sh4_flush_cache_all(void *unused)
 {
 	flush_dcache_all();
 	flush_icache_all();
@@ -380,8 +256,13 @@
  *
  * Caller takes mm->mmap_sem.
  */
-void flush_cache_mm(struct mm_struct *mm)
+static void sh4_flush_cache_mm(void *arg)
 {
+	struct mm_struct *mm = arg;
+
+	if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
+		return;
+
 	/*
 	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
 	 * the cache is physically tagged, the data can just be left in there.
@@ -417,12 +298,21 @@
  * ADDR: Virtual Address (U0 address)
  * PFN: Physical page number
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
-		      unsigned long pfn)
+static void sh4_flush_cache_page(void *args)
 {
-	unsigned long phys = pfn << PAGE_SHIFT;
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long address, pfn, phys;
 	unsigned int alias_mask;
 
+	vma = data->vma;
+	address = data->addr1;
+	pfn = data->addr2;
+	phys = pfn << PAGE_SHIFT;
+
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+		return;
+
 	alias_mask = boot_cpu_data.dcache.alias_mask;
 
 	/* We only need to flush D-cache when we have alias */
@@ -462,9 +352,19 @@
  * Flushing the cache lines for U0 only isn't enough.
  * We need to flush for P1 too, which may contain aliases.
  */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
+static void sh4_flush_cache_range(void *args)
 {
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long start, end;
+
+	vma = data->vma;
+	start = data->addr1;
+	end = data->addr2;
+
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+		return;
+
 	/*
 	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
 	 * the cache is physically tagged, the data can just be left in there.
@@ -492,20 +392,6 @@
 	}
 }
 
-/*
- * flush_icache_user_range
- * @vma: VMA of the process
- * @page: page
- * @addr: U0 address
- * @len: length of the range (< page size)
- */
-void flush_icache_user_range(struct vm_area_struct *vma,
-			     struct page *page, unsigned long addr, int len)
-{
-	flush_cache_page(vma, addr, page_to_pfn(page));
-	mb();
-}
-
 /**
  * __flush_cache_4096
  *
@@ -581,7 +467,49 @@
  * Break the 1, 2 and 4 way variants of this out into separate functions to
  * avoid nearly all the overhead of having the conditional stuff in the function
  * bodies (+ the 1 and 2 way cases avoid saving any registers too).
+ *
+ * We want to eliminate unnecessary bus transactions, so this code uses
+ * a non-obvious technique.
+ *
+ * Loop over a cache way sized block of, one cache line at a time. For each
+ * line, use movca.a to cause the current cache line contents to be written
+ * back, but without reading anything from main memory. However this has the
+ * side effect that the cache is now caching that memory location. So follow
+ * this with a cache invalidate to mark the cache line invalid. And do all
+ * this with interrupts disabled, to avoid the cache line being accidently
+ * evicted while it is holding garbage.
+ *
+ * This also breaks in a number of circumstances:
+ * - if there are modifications to the region of memory just above
+ *   empty_zero_page (for example because a breakpoint has been placed
+ *   there), then these can be lost.
+ *
+ *   This is because the the memory address which the cache temporarily
+ *   caches in the above description is empty_zero_page. So the
+ *   movca.l hits the cache (it is assumed that it misses, or at least
+ *   isn't dirty), modifies the line and then invalidates it, losing the
+ *   required change.
+ *
+ * - If caches are disabled or configured in write-through mode, then
+ *   the movca.l writes garbage directly into memory.
  */
+static void __flush_dcache_segment_writethrough(unsigned long start,
+					        unsigned long extent_per_way)
+{
+	unsigned long addr;
+	int i;
+
+	addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask);
+
+	while (extent_per_way) {
+		for (i = 0; i < cpu_data->dcache.ways; i++)
+			__raw_writel(0, addr + cpu_data->dcache.way_incr * i);
+
+		addr += cpu_data->dcache.linesz;
+		extent_per_way -= cpu_data->dcache.linesz;
+	}
+}
+
 static void __flush_dcache_segment_1way(unsigned long start,
 					unsigned long extent_per_way)
 {
@@ -773,3 +701,47 @@
 		a3 += linesz;
 	} while (a0 < a0e);
 }
+
+extern void __weak sh4__flush_region_init(void);
+
+/*
+ * SH-4 has virtually indexed and physically tagged cache.
+ */
+void __init sh4_cache_init(void)
+{
+	unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT);
+
+	printk("PVR=%08x CVR=%08x PRR=%08x\n",
+		ctrl_inl(CCN_PVR),
+		ctrl_inl(CCN_CVR),
+		ctrl_inl(CCN_PRR));
+
+	if (wt_enabled)
+		__flush_dcache_segment_fn = __flush_dcache_segment_writethrough;
+	else {
+		switch (boot_cpu_data.dcache.ways) {
+		case 1:
+			__flush_dcache_segment_fn = __flush_dcache_segment_1way;
+			break;
+		case 2:
+			__flush_dcache_segment_fn = __flush_dcache_segment_2way;
+			break;
+		case 4:
+			__flush_dcache_segment_fn = __flush_dcache_segment_4way;
+			break;
+		default:
+			panic("unknown number of cache ways\n");
+			break;
+		}
+	}
+
+	local_flush_icache_range	= sh4_flush_icache_range;
+	local_flush_dcache_page		= sh4_flush_dcache_page;
+	local_flush_cache_all		= sh4_flush_cache_all;
+	local_flush_cache_mm		= sh4_flush_cache_mm;
+	local_flush_cache_dup_mm	= sh4_flush_cache_mm;
+	local_flush_cache_page		= sh4_flush_cache_page;
+	local_flush_cache_range		= sh4_flush_cache_range;
+
+	sh4__flush_region_init();
+}
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c
index 8676209..467ff8e 100644
--- a/arch/sh/mm/cache-sh5.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -20,23 +20,11 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
+extern void __weak sh4__flush_region_init(void);
+
 /* Wired TLB entry for the D-cache */
 static unsigned long long dtlb_cache_slot;
 
-void __init p3_cache_init(void)
-{
-	/* Reserve a slot for dcache colouring in the DTLB */
-	dtlb_cache_slot	= sh64_get_wired_dtlb_entry();
-}
-
-#ifdef CONFIG_DCACHE_DISABLED
-#define sh64_dcache_purge_all()					do { } while (0)
-#define sh64_dcache_purge_coloured_phy_page(paddr, eaddr)	do { } while (0)
-#define sh64_dcache_purge_user_range(mm, start, end)		do { } while (0)
-#define sh64_dcache_purge_phy_page(paddr)			do { } while (0)
-#define sh64_dcache_purge_virt_page(mm, eaddr)			do { } while (0)
-#endif
-
 /*
  * The following group of functions deal with mapping and unmapping a
  * temporary page into a DTLB slot that has been set aside for exclusive
@@ -56,7 +44,6 @@
 	local_irq_enable();
 }
 
-#ifndef CONFIG_ICACHE_DISABLED
 static inline void sh64_icache_inv_all(void)
 {
 	unsigned long long addr, flag, data;
@@ -214,52 +201,6 @@
 	}
 }
 
-/*
- * Invalidate a small range of user context I-cache, not necessarily page
- * (or even cache-line) aligned.
- *
- * Since this is used inside ptrace, the ASID in the mm context typically
- * won't match current_asid.  We'll have to switch ASID to do this.  For
- * safety, and given that the range will be small, do all this under cli.
- *
- * Note, there is a hazard that the ASID in mm->context is no longer
- * actually associated with mm, i.e. if the mm->context has started a new
- * cycle since mm was last active.  However, this is just a performance
- * issue: all that happens is that we invalidate lines belonging to
- * another mm, so the owning process has to refill them when that mm goes
- * live again.  mm itself can't have any cache entries because there will
- * have been a flush_cache_all when the new mm->context cycle started.
- */
-static void sh64_icache_inv_user_small_range(struct mm_struct *mm,
-						unsigned long start, int len)
-{
-	unsigned long long eaddr = start;
-	unsigned long long eaddr_end = start + len;
-	unsigned long current_asid, mm_asid;
-	unsigned long flags;
-	unsigned long long epage_start;
-
-	/*
-	 * Align to start of cache line.  Otherwise, suppose len==8 and
-	 * start was at 32N+28 : the last 4 bytes wouldn't get invalidated.
-	 */
-	eaddr = L1_CACHE_ALIGN(start);
-	eaddr_end = start + len;
-
-	mm_asid = cpu_asid(smp_processor_id(), mm);
-	local_irq_save(flags);
-	current_asid = switch_and_save_asid(mm_asid);
-
-	epage_start = eaddr & PAGE_MASK;
-
-	while (eaddr < eaddr_end) {
-		__asm__ __volatile__("icbi %0, 0" : : "r" (eaddr));
-		eaddr += L1_CACHE_BYTES;
-	}
-	switch_and_save_asid(current_asid);
-	local_irq_restore(flags);
-}
-
 static void sh64_icache_inv_current_user_range(unsigned long start, unsigned long end)
 {
 	/* The icbi instruction never raises ITLBMISS.  i.e. if there's not a
@@ -287,9 +228,7 @@
 		addr += L1_CACHE_BYTES;
 	}
 }
-#endif /* !CONFIG_ICACHE_DISABLED */
 
-#ifndef CONFIG_DCACHE_DISABLED
 /* Buffer used as the target of alloco instructions to purge data from cache
    sets by natural eviction. -- RPC */
 #define DUMMY_ALLOCO_AREA_SIZE ((L1_CACHE_BYTES << 10) + (1024 * 4))
@@ -541,59 +480,10 @@
 }
 
 /*
- * Purge the range of addresses from the D-cache.
- *
- * The addresses lie in the superpage mapping. There's no harm if we
- * overpurge at either end - just a small performance loss.
- */
-void __flush_purge_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr <= ullend) {
-		__asm__ __volatile__ ("ocbp %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-
-void __flush_wback_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr < ullend) {
-		__asm__ __volatile__ ("ocbwb %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-
-void __flush_invalidate_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr < ullend) {
-		__asm__ __volatile__ ("ocbi %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-#endif /* !CONFIG_DCACHE_DISABLED */
-
-/*
  * Invalidate the entire contents of both caches, after writing back to
  * memory any dirty data from the D-cache.
  */
-void flush_cache_all(void)
+static void sh5_flush_cache_all(void *unused)
 {
 	sh64_dcache_purge_all();
 	sh64_icache_inv_all();
@@ -620,7 +510,7 @@
  * I-cache.  This is similar to the lack of action needed in
  * flush_tlb_mm - see fault.c.
  */
-void flush_cache_mm(struct mm_struct *mm)
+static void sh5_flush_cache_mm(void *unused)
 {
 	sh64_dcache_purge_all();
 }
@@ -632,13 +522,18 @@
  *
  * Note, 'end' is 1 byte beyond the end of the range to flush.
  */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
+static void sh5_flush_cache_range(void *args)
 {
-	struct mm_struct *mm = vma->vm_mm;
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long start, end;
 
-	sh64_dcache_purge_user_range(mm, start, end);
-	sh64_icache_inv_user_page_range(mm, start, end);
+	vma = data->vma;
+	start = data->addr1;
+	end = data->addr2;
+
+	sh64_dcache_purge_user_range(vma->vm_mm, start, end);
+	sh64_icache_inv_user_page_range(vma->vm_mm, start, end);
 }
 
 /*
@@ -650,16 +545,23 @@
  *
  * Note, this is called with pte lock held.
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr,
-		      unsigned long pfn)
+static void sh5_flush_cache_page(void *args)
 {
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long eaddr, pfn;
+
+	vma = data->vma;
+	eaddr = data->addr1;
+	pfn = data->addr2;
+
 	sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);
 
 	if (vma->vm_flags & VM_EXEC)
 		sh64_icache_inv_user_page(vma, eaddr);
 }
 
-void flush_dcache_page(struct page *page)
+static void sh5_flush_dcache_page(void *page)
 {
 	sh64_dcache_purge_phy_page(page_to_phys(page));
 	wmb();
@@ -673,162 +575,47 @@
  * mapping, therefore it's guaranteed that there no cache entries for
  * the range in cache sets of the wrong colour.
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh5_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
+
+	start = data->addr1;
+	end = data->addr2;
+
 	__flush_purge_region((void *)start, end);
 	wmb();
 	sh64_icache_inv_kernel_range(start, end);
 }
 
 /*
- * Flush the range of user (defined by vma->vm_mm) address space starting
- * at 'addr' for 'len' bytes from the cache.  The range does not straddle
- * a page boundary, the unique physical page containing the range is
- * 'page'.  This seems to be used mainly for invalidating an address
- * range following a poke into the program text through the ptrace() call
- * from another process (e.g. for BRK instruction insertion).
- */
-void flush_icache_user_range(struct vm_area_struct *vma,
-			struct page *page, unsigned long addr, int len)
-{
-
-	sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr);
-	mb();
-
-	if (vma->vm_flags & VM_EXEC)
-		sh64_icache_inv_user_small_range(vma->vm_mm, addr, len);
-}
-
-/*
  * For the address range [start,end), write back the data from the
  * D-cache and invalidate the corresponding region of the I-cache for the
  * current process.  Used to flush signal trampolines on the stack to
  * make them executable.
  */
-void flush_cache_sigtramp(unsigned long vaddr)
+static void sh5_flush_cache_sigtramp(void *vaddr)
 {
-	unsigned long end = vaddr + L1_CACHE_BYTES;
+	unsigned long end = (unsigned long)vaddr + L1_CACHE_BYTES;
 
-	__flush_wback_region((void *)vaddr, L1_CACHE_BYTES);
+	__flush_wback_region(vaddr, L1_CACHE_BYTES);
 	wmb();
-	sh64_icache_inv_current_user_range(vaddr, end);
+	sh64_icache_inv_current_user_range((unsigned long)vaddr, end);
 }
 
-#ifdef CONFIG_MMU
-/*
- * These *MUST* lie in an area of virtual address space that's otherwise
- * unused.
- */
-#define UNIQUE_EADDR_START 0xe0000000UL
-#define UNIQUE_EADDR_END   0xe8000000UL
-
-/*
- * Given a physical address paddr, and a user virtual address user_eaddr
- * which will eventually be mapped to it, create a one-off kernel-private
- * eaddr mapped to the same paddr.  This is used for creating special
- * destination pages for copy_user_page and clear_user_page.
- */
-static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr,
-					    unsigned long paddr)
+void __init sh5_cache_init(void)
 {
-	static unsigned long current_pointer = UNIQUE_EADDR_START;
-	unsigned long coloured_pointer;
+	local_flush_cache_all		= sh5_flush_cache_all;
+	local_flush_cache_mm		= sh5_flush_cache_mm;
+	local_flush_cache_dup_mm	= sh5_flush_cache_mm;
+	local_flush_cache_page		= sh5_flush_cache_page;
+	local_flush_cache_range		= sh5_flush_cache_range;
+	local_flush_dcache_page		= sh5_flush_dcache_page;
+	local_flush_icache_range	= sh5_flush_icache_range;
+	local_flush_cache_sigtramp	= sh5_flush_cache_sigtramp;
 
-	if (current_pointer == UNIQUE_EADDR_END) {
-		sh64_dcache_purge_all();
-		current_pointer = UNIQUE_EADDR_START;
-	}
+	/* Reserve a slot for dcache colouring in the DTLB */
+	dtlb_cache_slot	= sh64_get_wired_dtlb_entry();
 
-	coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) |
-				(user_eaddr & CACHE_OC_SYN_MASK);
-	sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr);
-
-	current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS);
-
-	return coloured_pointer;
+	sh4__flush_region_init();
 }
-
-static void sh64_copy_user_page_coloured(void *to, void *from,
-					 unsigned long address)
-{
-	void *coloured_to;
-
-	/*
-	 * Discard any existing cache entries of the wrong colour.  These are
-	 * present quite often, if the kernel has recently used the page
-	 * internally, then given it up, then it's been allocated to the user.
-	 */
-	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to);
-
-	coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to));
-	copy_page(from, coloured_to);
-
-	sh64_teardown_dtlb_cache_slot();
-}
-
-static void sh64_clear_user_page_coloured(void *to, unsigned long address)
-{
-	void *coloured_to;
-
-	/*
-	 * Discard any existing kernel-originated lines of the wrong
-	 * colour (as above)
-	 */
-	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to);
-
-	coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to));
-	clear_page(coloured_to);
-
-	sh64_teardown_dtlb_cache_slot();
-}
-
-/*
- * 'from' and 'to' are kernel virtual addresses (within the superpage
- * mapping of the physical RAM).  'address' is the user virtual address
- * where the copy 'to' will be mapped after.  This allows a custom
- * mapping to be used to ensure that the new copy is placed in the
- * right cache sets for the user to see it without having to bounce it
- * out via memory.  Note however : the call to flush_page_to_ram in
- * (generic)/mm/memory.c:(break_cow) undoes all this good work in that one
- * very important case!
- *
- * TBD : can we guarantee that on every call, any cache entries for
- * 'from' are in the same colour sets as 'address' also?  i.e. is this
- * always used just to deal with COW?  (I suspect not).
- *
- * There are two possibilities here for when the page 'from' was last accessed:
- * - by the kernel : this is OK, no purge required.
- * - by the/a user (e.g. for break_COW) : need to purge.
- *
- * If the potential user mapping at 'address' is the same colour as
- * 'from' there is no need to purge any cache lines from the 'from'
- * page mapped into cache sets of colour 'address'.  (The copy will be
- * accessing the page through 'from').
- */
-void copy_user_page(void *to, void *from, unsigned long address,
-		    struct page *page)
-{
-	if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0)
-		sh64_dcache_purge_coloured_phy_page(__pa(from), address);
-
-	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0)
-		copy_page(to, from);
-	else
-		sh64_copy_user_page_coloured(to, from, address);
-}
-
-/*
- * 'to' is a kernel virtual address (within the superpage mapping of the
- * physical RAM).  'address' is the user virtual address where the 'to'
- * page will be mapped after.  This allows a custom mapping to be used to
- * ensure that the new copy is placed in the right cache sets for the
- * user to see it without having to bounce it out via memory.
- */
-void clear_user_page(void *to, unsigned long address, struct page *page)
-{
-	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0)
-		clear_page(to);
-	else
-		sh64_clear_user_page_coloured(to, address);
-}
-#endif
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 22dacc7..2cadee2 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 #include <linux/threads.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
@@ -63,15 +64,21 @@
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format.
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh7705_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
+
+	start = data->addr1;
+	end = data->addr2;
+
 	__flush_wback_region((void *)start, end - start);
 }
 
 /*
  * Writeback&Invalidate the D-cache of the page
  */
-static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
+static void __flush_dcache_page(unsigned long phys)
 {
 	unsigned long ways, waysize, addrstart;
 	unsigned long flags;
@@ -126,13 +133,18 @@
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
  */
-void flush_dcache_page(struct page *page)
+static void sh7705_flush_dcache_page(void *arg)
 {
-	if (test_bit(PG_mapped, &page->flags))
+	struct page *page = arg;
+	struct address_space *mapping = page_mapping(page);
+
+	if (mapping && !mapping_mapped(mapping))
+		set_bit(PG_dcache_dirty, &page->flags);
+	else
 		__flush_dcache_page(PHYSADDR(page_address(page)));
 }
 
-void __uses_jump_to_uncached flush_cache_all(void)
+static void sh7705_flush_cache_all(void *args)
 {
 	unsigned long flags;
 
@@ -144,44 +156,16 @@
 	local_irq_restore(flags);
 }
 
-void flush_cache_mm(struct mm_struct *mm)
-{
-	/* Is there any good way? */
-	/* XXX: possibly call flush_cache_range for each vm area */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches.
- *
- * START, END: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
-{
-
-	/*
-	 * We could call flush_cache_page for the pages of these range,
-	 * but it's not efficient (scan the caches all the time...).
-	 *
-	 * We can't use A-bit magic, as there's the case we don't have
-	 * valid entry on TLB.
-	 */
-	flush_cache_all();
-}
-
 /*
  * Write back and invalidate I/D-caches for the page.
  *
  * ADDRESS: Virtual Address (U0 address)
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
-		      unsigned long pfn)
+static void sh7705_flush_cache_page(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long pfn = data->addr2;
+
 	__flush_dcache_page(pfn << PAGE_SHIFT);
 }
 
@@ -193,7 +177,19 @@
  * Not entirely sure why this is necessary on SH3 with 32K cache but
  * without it we get occasional "Memory fault" when loading a program.
  */
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+static void sh7705_flush_icache_page(void *page)
 {
 	__flush_purge_region(page_address(page), PAGE_SIZE);
 }
+
+void __init sh7705_cache_init(void)
+{
+	local_flush_icache_range	= sh7705_flush_icache_range;
+	local_flush_dcache_page		= sh7705_flush_dcache_page;
+	local_flush_cache_all		= sh7705_flush_cache_all;
+	local_flush_cache_mm		= sh7705_flush_cache_all;
+	local_flush_cache_dup_mm	= sh7705_flush_cache_all;
+	local_flush_cache_range		= sh7705_flush_cache_all;
+	local_flush_cache_page		= sh7705_flush_cache_page;
+	local_flush_icache_page		= sh7705_flush_icache_page;
+}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
new file mode 100644
index 0000000..35c37b7
--- /dev/null
+++ b/arch/sh/mm/cache.c
@@ -0,0 +1,316 @@
+/*
+ * arch/sh/mm/cache.c
+ *
+ * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
+ * Copyright (C) 2002 - 2009  Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void (*local_flush_cache_all)(void *args) = cache_noop;
+void (*local_flush_cache_mm)(void *args) = cache_noop;
+void (*local_flush_cache_dup_mm)(void *args) = cache_noop;
+void (*local_flush_cache_page)(void *args) = cache_noop;
+void (*local_flush_cache_range)(void *args) = cache_noop;
+void (*local_flush_dcache_page)(void *args) = cache_noop;
+void (*local_flush_icache_range)(void *args) = cache_noop;
+void (*local_flush_icache_page)(void *args) = cache_noop;
+void (*local_flush_cache_sigtramp)(void *args) = cache_noop;
+
+void (*__flush_wback_region)(void *start, int size);
+void (*__flush_purge_region)(void *start, int size);
+void (*__flush_invalidate_region)(void *start, int size);
+
+static inline void noop__flush_region(void *start, int size)
+{
+}
+
+static inline void cacheop_on_each_cpu(void (*func) (void *info), void *info,
+                                   int wait)
+{
+	preempt_disable();
+	smp_call_function(func, info, wait);
+	func(info);
+	preempt_enable();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+		       unsigned long vaddr, void *dst, const void *src,
+		       unsigned long len)
+{
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+	    !test_bit(PG_dcache_dirty, &page->flags)) {
+		void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(vto, src, len);
+		kunmap_coherent(vto);
+	} else {
+		memcpy(dst, src, len);
+		if (boot_cpu_data.dcache.n_aliases)
+			set_bit(PG_dcache_dirty, &page->flags);
+	}
+
+	if (vma->vm_flags & VM_EXEC)
+		flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+			 unsigned long vaddr, void *dst, const void *src,
+			 unsigned long len)
+{
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+	    !test_bit(PG_dcache_dirty, &page->flags)) {
+		void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(dst, vfrom, len);
+		kunmap_coherent(vfrom);
+	} else {
+		memcpy(dst, src, len);
+		if (boot_cpu_data.dcache.n_aliases)
+			set_bit(PG_dcache_dirty, &page->flags);
+	}
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+			unsigned long vaddr, struct vm_area_struct *vma)
+{
+	void *vfrom, *vto;
+
+	vto = kmap_atomic(to, KM_USER1);
+
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
+	    !test_bit(PG_dcache_dirty, &from->flags)) {
+		vfrom = kmap_coherent(from, vaddr);
+		copy_page(vto, vfrom);
+		kunmap_coherent(vfrom);
+	} else {
+		vfrom = kmap_atomic(from, KM_USER0);
+		copy_page(vto, vfrom);
+		kunmap_atomic(vfrom, KM_USER0);
+	}
+
+	if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+		__flush_purge_region(vto, PAGE_SIZE);
+
+	kunmap_atomic(vto, KM_USER1);
+	/* Make sure this page is cleared on other CPU's too before using it */
+	smp_wmb();
+}
+EXPORT_SYMBOL(copy_user_highpage);
+
+void clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+	void *kaddr = kmap_atomic(page, KM_USER0);
+
+	clear_page(kaddr);
+
+	if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK))
+		__flush_purge_region(kaddr, PAGE_SIZE);
+
+	kunmap_atomic(kaddr, KM_USER0);
+}
+EXPORT_SYMBOL(clear_user_highpage);
+
+void __update_cache(struct vm_area_struct *vma,
+		    unsigned long address, pte_t pte)
+{
+	struct page *page;
+	unsigned long pfn = pte_pfn(pte);
+
+	if (!boot_cpu_data.dcache.n_aliases)
+		return;
+
+	page = pfn_to_page(pfn);
+	if (pfn_valid(pfn) && page_mapping(page)) {
+		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+		if (dirty) {
+			unsigned long addr = (unsigned long)page_address(page);
+
+			if (pages_do_alias(addr, address & PAGE_MASK))
+				__flush_purge_region((void *)addr, PAGE_SIZE);
+		}
+	}
+}
+
+void __flush_anon_page(struct page *page, unsigned long vmaddr)
+{
+	unsigned long addr = (unsigned long) page_address(page);
+
+	if (pages_do_alias(addr, vmaddr)) {
+		if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+		    !test_bit(PG_dcache_dirty, &page->flags)) {
+			void *kaddr;
+
+			kaddr = kmap_coherent(page, vmaddr);
+			/* XXX.. For now kunmap_coherent() does a purge */
+			/* __flush_purge_region((void *)kaddr, PAGE_SIZE); */
+			kunmap_coherent(kaddr);
+		} else
+			__flush_purge_region((void *)addr, PAGE_SIZE);
+	}
+}
+
+void flush_cache_all(void)
+{
+	cacheop_on_each_cpu(local_flush_cache_all, NULL, 1);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	cacheop_on_each_cpu(local_flush_cache_mm, mm, 1);
+}
+
+void flush_cache_dup_mm(struct mm_struct *mm)
+{
+	cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1);
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
+		      unsigned long pfn)
+{
+	struct flusher_data data;
+
+	data.vma = vma;
+	data.addr1 = addr;
+	data.addr2 = pfn;
+
+	cacheop_on_each_cpu(local_flush_cache_page, (void *)&data, 1);
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
+		       unsigned long end)
+{
+	struct flusher_data data;
+
+	data.vma = vma;
+	data.addr1 = start;
+	data.addr2 = end;
+
+	cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1);
+}
+
+void flush_dcache_page(struct page *page)
+{
+	cacheop_on_each_cpu(local_flush_dcache_page, page, 1);
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flusher_data data;
+
+	data.vma = NULL;
+	data.addr1 = start;
+	data.addr2 = end;
+
+	cacheop_on_each_cpu(local_flush_icache_range, (void *)&data, 1);
+}
+
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	/* Nothing uses the VMA, so just pass the struct page along */
+	cacheop_on_each_cpu(local_flush_icache_page, page, 1);
+}
+
+void flush_cache_sigtramp(unsigned long address)
+{
+	cacheop_on_each_cpu(local_flush_cache_sigtramp, (void *)address, 1);
+}
+
+static void compute_alias(struct cache_info *c)
+{
+	c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
+	c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
+}
+
+static void __init emit_cache_params(void)
+{
+	printk(KERN_NOTICE "I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+		boot_cpu_data.icache.ways,
+		boot_cpu_data.icache.sets,
+		boot_cpu_data.icache.way_incr);
+	printk(KERN_NOTICE "I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+		boot_cpu_data.icache.entry_mask,
+		boot_cpu_data.icache.alias_mask,
+		boot_cpu_data.icache.n_aliases);
+	printk(KERN_NOTICE "D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+		boot_cpu_data.dcache.ways,
+		boot_cpu_data.dcache.sets,
+		boot_cpu_data.dcache.way_incr);
+	printk(KERN_NOTICE "D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+		boot_cpu_data.dcache.entry_mask,
+		boot_cpu_data.dcache.alias_mask,
+		boot_cpu_data.dcache.n_aliases);
+
+	/*
+	 * Emit Secondary Cache parameters if the CPU has a probed L2.
+	 */
+	if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
+		printk(KERN_NOTICE "S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+			boot_cpu_data.scache.ways,
+			boot_cpu_data.scache.sets,
+			boot_cpu_data.scache.way_incr);
+		printk(KERN_NOTICE "S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+			boot_cpu_data.scache.entry_mask,
+			boot_cpu_data.scache.alias_mask,
+			boot_cpu_data.scache.n_aliases);
+	}
+}
+
+void __init cpu_cache_init(void)
+{
+	compute_alias(&boot_cpu_data.icache);
+	compute_alias(&boot_cpu_data.dcache);
+	compute_alias(&boot_cpu_data.scache);
+
+	__flush_wback_region		= noop__flush_region;
+	__flush_purge_region		= noop__flush_region;
+	__flush_invalidate_region	= noop__flush_region;
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH2) {
+		extern void __weak sh2_cache_init(void);
+
+		sh2_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH2A) {
+		extern void __weak sh2a_cache_init(void);
+
+		sh2a_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH3) {
+		extern void __weak sh3_cache_init(void);
+
+		sh3_cache_init();
+
+		if ((boot_cpu_data.type == CPU_SH7705) &&
+		    (boot_cpu_data.dcache.sets == 512)) {
+			extern void __weak sh7705_cache_init(void);
+
+			sh7705_cache_init();
+		}
+	}
+
+	if ((boot_cpu_data.family == CPU_FAMILY_SH4) ||
+	    (boot_cpu_data.family == CPU_FAMILY_SH4A) ||
+	    (boot_cpu_data.family == CPU_FAMILY_SH4AL_DSP)) {
+		extern void __weak sh4_cache_init(void);
+
+		sh4_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH5) {
+		extern void __weak sh5_cache_init(void);
+
+		sh5_cache_init();
+	}
+
+	emit_cache_params();
+}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 7192594..781b413 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -2,7 +2,7 @@
  * Page fault handler for SH with an MMU.
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2003 - 2008  Paul Mundt
+ *  Copyright (C) 2003 - 2009  Paul Mundt
  *
  *  Based on linux/arch/i386/mm/fault.c:
  *   Copyright (C) 1995  Linus Torvalds
@@ -25,18 +25,91 @@
 {
 	int ret = 0;
 
-#ifdef CONFIG_KPROBES
-	if (!user_mode(regs)) {
+	if (kprobes_built_in() && !user_mode(regs)) {
 		preempt_disable();
 		if (kprobe_running() && kprobe_fault_handler(regs, trap))
 			ret = 1;
 		preempt_enable();
 	}
-#endif
 
 	return ret;
 }
 
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+{
+	unsigned index = pgd_index(address);
+	pgd_t *pgd_k;
+	pud_t *pud, *pud_k;
+	pmd_t *pmd, *pmd_k;
+
+	pgd += index;
+	pgd_k = init_mm.pgd + index;
+
+	if (!pgd_present(*pgd_k))
+		return NULL;
+
+	pud = pud_offset(pgd, address);
+	pud_k = pud_offset(pgd_k, address);
+	if (!pud_present(*pud_k))
+		return NULL;
+
+	pmd = pmd_offset(pud, address);
+	pmd_k = pmd_offset(pud_k, address);
+	if (!pmd_present(*pmd_k))
+		return NULL;
+
+	if (!pmd_present(*pmd))
+		set_pmd(pmd, *pmd_k);
+	else {
+		/*
+		 * The page tables are fully synchronised so there must
+		 * be another reason for the fault. Return NULL here to
+		 * signal that we have not taken care of the fault.
+		 */
+		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+		return NULL;
+	}
+
+	return pmd_k;
+}
+
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+	pgd_t *pgd_k;
+	pmd_t *pmd_k;
+	pte_t *pte_k;
+
+	/* Make sure we are in vmalloc/module/P3 area: */
+	if (!(address >= VMALLOC_START && address < P3_ADDR_MAX))
+		return -1;
+
+	/*
+	 * Synchronize this task's top level page-table
+	 * with the 'reference' page table.
+	 *
+	 * Do _not_ use "current" here. We might be inside
+	 * an interrupt in the middle of a task switch..
+	 */
+	pgd_k = get_TTB();
+	pmd_k = vmalloc_sync_one(pgd_k, address);
+	if (!pmd_k)
+		return -1;
+
+	pte_k = pte_offset_kernel(pmd_k, address);
+	if (!pte_present(*pte_k))
+		return -1;
+
+	return 0;
+}
+
+static int fault_in_kernel_space(unsigned long address)
+{
+	return address >= TASK_SIZE;
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -46,6 +119,7 @@
 					unsigned long writeaccess,
 					unsigned long address)
 {
+	unsigned long vec;
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct * vma;
@@ -53,59 +127,30 @@
 	int fault;
 	siginfo_t info;
 
-	/*
-	 * We don't bother with any notifier callbacks here, as they are
-	 * all handled through the __do_page_fault() fast-path.
-	 */
-
 	tsk = current;
+	mm = tsk->mm;
 	si_code = SEGV_MAPERR;
+	vec = lookup_exception_vector();
 
-	if (unlikely(address >= TASK_SIZE)) {
-		/*
-		 * Synchronize this task's top level page-table
-		 * with the 'reference' page table.
-		 *
-		 * Do _not_ use "tsk" here. We might be inside
-		 * an interrupt in the middle of a task switch..
-		 */
-		int offset = pgd_index(address);
-		pgd_t *pgd, *pgd_k;
-		pud_t *pud, *pud_k;
-		pmd_t *pmd, *pmd_k;
-
-		pgd = get_TTB() + offset;
-		pgd_k = swapper_pg_dir + offset;
-
-		if (!pgd_present(*pgd)) {
-			if (!pgd_present(*pgd_k))
-				goto bad_area_nosemaphore;
-			set_pgd(pgd, *pgd_k);
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (unlikely(fault_in_kernel_space(address))) {
+		if (vmalloc_fault(address) >= 0)
 			return;
-		}
-
-		pud = pud_offset(pgd, address);
-		pud_k = pud_offset(pgd_k, address);
-
-		if (!pud_present(*pud)) {
-			if (!pud_present(*pud_k))
-				goto bad_area_nosemaphore;
-			set_pud(pud, *pud_k);
+		if (notify_page_fault(regs, vec))
 			return;
-		}
 
-		pmd = pmd_offset(pud, address);
-		pmd_k = pmd_offset(pud_k, address);
-		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
-			goto bad_area_nosemaphore;
-		set_pmd(pmd, *pmd_k);
-
-		return;
+		goto bad_area_nosemaphore;
 	}
 
-	mm = tsk->mm;
-
-	if (unlikely(notify_page_fault(regs, lookup_exception_vector())))
+	if (unlikely(notify_page_fault(regs, vec)))
 		return;
 
 	/* Only enable interrupts if they were on before the fault */
@@ -115,8 +160,8 @@
 	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
 	/*
-	 * If we're in an interrupt or have no user
-	 * context, we must not take the fault..
+	 * If we're in an interrupt, have no user context or are running
+	 * in an atomic region then we must not take the fault:
 	 */
 	if (in_atomic() || !mm)
 		goto no_context;
@@ -132,10 +177,11 @@
 		goto bad_area;
 	if (expand_stack(vma, address))
 		goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
+
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
 good_area:
 	si_code = SEGV_ACCERR;
 	if (writeaccess) {
@@ -173,10 +219,10 @@
 	up_read(&mm->mmap_sem);
 	return;
 
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
 bad_area:
 	up_read(&mm->mmap_sem);
 
@@ -272,16 +318,15 @@
 /*
  * Called with interrupts disabled.
  */
-asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
-					 unsigned long writeaccess,
-					 unsigned long address)
+asmlinkage int __kprobes
+handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
+	       unsigned long address)
 {
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t entry;
-	int ret = 1;
 
 	/*
 	 * We don't take page faults for P1, P2, and parts of P4, these
@@ -292,40 +337,41 @@
 		pgd = pgd_offset_k(address);
 	} else {
 		if (unlikely(address >= TASK_SIZE || !current->mm))
-			goto out;
+			return 1;
 
 		pgd = pgd_offset(current->mm, address);
 	}
 
 	pud = pud_offset(pgd, address);
 	if (pud_none_or_clear_bad(pud))
-		goto out;
+		return 1;
 	pmd = pmd_offset(pud, address);
 	if (pmd_none_or_clear_bad(pmd))
-		goto out;
+		return 1;
 	pte = pte_offset_kernel(pmd, address);
 	entry = *pte;
 	if (unlikely(pte_none(entry) || pte_not_present(entry)))
-		goto out;
+		return 1;
 	if (unlikely(writeaccess && !pte_write(entry)))
-		goto out;
+		return 1;
 
 	if (writeaccess)
 		entry = pte_mkdirty(entry);
 	entry = pte_mkyoung(entry);
 
+	set_pte(pte, entry);
+
 #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SMP)
 	/*
-	 * ITLB is not affected by "ldtlb" instruction.
-	 * So, we need to flush the entry by ourselves.
+	 * SH-4 does not set MMUCR.RC to the corresponding TLB entry in
+	 * the case of an initial page write exception, so we need to
+	 * flush it in order to avoid potential TLB entry duplication.
 	 */
-	local_flush_tlb_one(get_asid(), address & PAGE_MASK);
+	if (writeaccess == 2)
+		local_flush_tlb_one(get_asid(), address & PAGE_MASK);
 #endif
 
-	set_pte(pte, entry);
 	update_mmu_cache(NULL, address, entry);
 
-	ret = 0;
-out:
-	return ret;
+	return 0;
 }
diff --git a/arch/sh/mm/fault_64.c b/arch/sh/mm/fault_64.c
index bd63b96..2b356ce 100644
--- a/arch/sh/mm/fault_64.c
+++ b/arch/sh/mm/fault_64.c
@@ -56,16 +56,7 @@
 	/*
 	 * Set PTEH register
 	 */
-	pteh = address & MMU_VPN_MASK;
-
-	/* Sign extend based on neff. */
-#if (NEFF == 32)
-	/* Faster sign extension */
-	pteh = (unsigned long long)(signed long long)(signed long)pteh;
-#else
-	/* General case */
-	pteh = (pteh & NEFF_SIGN) ? (pteh | NEFF_MASK) : pteh;
-#endif
+	pteh = neff_sign_extend(address & MMU_VPN_MASK);
 
 	/* Set the ASID. */
 	pteh |= get_asid() << PTEH_ASID_SHIFT;
diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c
new file mode 100644
index 0000000..cef4026
--- /dev/null
+++ b/arch/sh/mm/flush-sh4.c
@@ -0,0 +1,108 @@
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+static void sh4__flush_wback_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+
+	while (cnt) {
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+static void sh4__flush_purge_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+	while (cnt) {
+		__ocbp(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+/*
+ * No write back please
+ */
+static void sh4__flush_invalidate_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+
+	while (cnt) {
+		__ocbi(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+void __init sh4__flush_region_init(void)
+{
+	__flush_wback_region		= sh4__flush_wback_region;
+	__flush_invalidate_region	= sh4__flush_invalidate_region;
+	__flush_purge_region		= sh4__flush_purge_region;
+}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index fe532ae..edc842f 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -106,27 +106,31 @@
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
-	int pgd_idx;
+	pte_t *pte;
+	int i, j, k;
 	unsigned long vaddr;
 
-	vaddr = start & PMD_MASK;
-	end = (end + PMD_SIZE - 1) & PMD_MASK;
-	pgd_idx = pgd_index(vaddr);
-	pgd = pgd_base + pgd_idx;
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pud_offset(vaddr);
+	k = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
 
-	for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
-		BUG_ON(pgd_none(*pgd));
-		pud = pud_offset(pgd, 0);
-		BUG_ON(pud_none(*pud));
-		pmd = pmd_offset(pud, 0);
-
-		if (!pmd_present(*pmd)) {
-			pte_t *pte_table;
-			pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
-			pmd_populate_kernel(&init_mm, pmd, pte_table);
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pud = (pud_t *)pgd;
+		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+			pmd = (pmd_t *)pud;
+			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+				if (pmd_none(*pmd)) {
+					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+					pmd_populate_kernel(&init_mm, pmd, pte);
+					BUG_ON(pte != pte_offset_kernel(pmd, 0));
+				}
+				vaddr += PMD_SIZE;
+			}
+			k = 0;
 		}
-
-		vaddr += PMD_SIZE;
+		j = 0;
 	}
 }
 #endif	/* CONFIG_MMU */
@@ -137,7 +141,7 @@
 void __init paging_init(void)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
-	unsigned long vaddr;
+	unsigned long vaddr, end;
 	int nid;
 
 	/* We don't need to map the kernel through the TLB, as
@@ -155,7 +159,8 @@
 	 * pte's will be filled in by __set_fixmap().
 	 */
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	page_table_range_init(vaddr, 0, swapper_pg_dir);
+	end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
+	page_table_range_init(vaddr, end, swapper_pg_dir);
 
 	kmap_coherent_init();
 
@@ -210,6 +215,9 @@
 			high_memory = node_high_memory;
 	}
 
+	/* Set this up early, so we can take care of the zero page */
+	cpu_cache_init();
+
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 	__flush_wback_region(empty_zero_page, PAGE_SIZE);
@@ -230,8 +238,6 @@
 		datasize >> 10,
 		initsize >> 10);
 
-	p3_cache_init();
-
 	/* Initialize the vDSO */
 	vsyscall_init();
 }
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index da2f418..c325061 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -57,14 +57,6 @@
 	if (is_pci_memory_fixed_range(phys_addr, size))
 		return (void __iomem *)phys_addr;
 
-#if !defined(CONFIG_PMB_FIXED)
-	/*
-	 * Don't allow anybody to remap normal RAM that we're using..
-	 */
-	if (phys_addr < virt_to_phys(high_memory))
-		return NULL;
-#endif
-
 	/*
 	 * Mappings have to be page-aligned
 	 */
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
index 828c859..b16843d 100644
--- a/arch/sh/mm/ioremap_64.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -94,7 +94,6 @@
 static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
 				      const char *name, unsigned long flags)
 {
-	static int printed_full;
 	struct xresource *xres;
 	struct resource *res;
 	char *tack;
@@ -108,11 +107,8 @@
 		tack = xres->xname;
 		res = &xres->xres;
 	} else {
-		if (!printed_full) {
-			printk(KERN_NOTICE "%s: done with statics, "
+		printk_once(KERN_NOTICE "%s: done with statics, "
 			       "switching to kmalloc\n", __func__);
-			printed_full = 1;
-		}
 		tlen = strlen(name);
 		tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
 		if (!tack)
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
new file mode 100644
index 0000000..16e01b5
--- /dev/null
+++ b/arch/sh/mm/kmap.c
@@ -0,0 +1,65 @@
+/*
+ * arch/sh/mm/kmap.c
+ *
+ * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
+ * Copyright (C) 2002 - 2009  Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+#define kmap_get_fixmap_pte(vaddr)                                     \
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
+static pte_t *kmap_coherent_pte;
+
+void __init kmap_coherent_init(void)
+{
+	unsigned long vaddr;
+
+	/* cache the first coherent kmap pte */
+	vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+	kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+
+void *kmap_coherent(struct page *page, unsigned long addr)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	BUG_ON(test_bit(PG_dcache_dirty, &page->flags));
+
+	pagefault_disable();
+
+	idx = FIX_CMAP_END -
+		((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT);
+	vaddr = __fix_to_virt(idx);
+
+	BUG_ON(!pte_none(*(kmap_coherent_pte - idx)));
+	set_pte(kmap_coherent_pte - idx, mk_pte(page, PAGE_KERNEL));
+
+	return (void *)vaddr;
+}
+
+void kunmap_coherent(void *kvaddr)
+{
+	if (kvaddr >= (void *)FIXADDR_START) {
+		unsigned long vaddr = (unsigned long)kvaddr & PAGE_MASK;
+		enum fixed_addresses idx = __virt_to_fix(vaddr);
+
+		/* XXX.. Kill this later, here for sanity at the moment.. */
+		__flush_purge_region((void *)vaddr, PAGE_SIZE);
+
+		pte_clear(&init_mm, vaddr, kmap_coherent_pte - idx);
+		local_flush_tlb_one(get_asid(), vaddr);
+	}
+
+	pagefault_enable();
+}
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 1b5fdfb..d2984fa 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -14,10 +14,10 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
-#ifdef CONFIG_MMU
 unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
 EXPORT_SYMBOL(shm_align_mask);
 
+#ifdef CONFIG_MMU
 /*
  * To avoid cache aliases, we map the shared page with same color.
  */
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
new file mode 100644
index 0000000..ac16c05
--- /dev/null
+++ b/arch/sh/mm/nommu.c
@@ -0,0 +1,96 @@
+/*
+ * arch/sh/mm/nommu.c
+ *
+ * Various helper routines and stubs for MMUless SH.
+ *
+ * Copyright (C) 2002 - 2009 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+/*
+ * Nothing too terribly exciting here ..
+ */
+void copy_page(void *to, void *from)
+{
+	memcpy(to, from, PAGE_SIZE);
+}
+
+__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n)
+{
+	memcpy(to, from, n);
+	return 0;
+}
+
+__kernel_size_t __clear_user(void *to, __kernel_size_t n)
+{
+	memset(to, 0, n);
+	return 0;
+}
+
+void local_flush_tlb_all(void)
+{
+	BUG();
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+			    unsigned long end)
+{
+	BUG();
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	BUG();
+}
+
+void local_flush_tlb_one(unsigned long asid, unsigned long page)
+{
+	BUG();
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+}
+
+void __init kmap_coherent_init(void)
+{
+}
+
+void *kmap_coherent(struct page *page, unsigned long addr)
+{
+	BUG();
+	return NULL;
+}
+
+void kunmap_coherent(void *kvaddr)
+{
+	BUG();
+}
+
+void __init page_table_range_init(unsigned long start, unsigned long end,
+				  pgd_t *pgd_base)
+{
+}
+
+void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+{
+}
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 095d93b..9b784fd 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -9,6 +9,7 @@
  */
 #include <linux/module.h>
 #include <linux/bootmem.h>
+#include <linux/lmb.h>
 #include <linux/mm.h>
 #include <linux/numa.h>
 #include <linux/pfn.h>
@@ -26,6 +27,15 @@
 void __init setup_memory(void)
 {
 	unsigned long free_pfn = PFN_UP(__pa(_end));
+	u64 base = min_low_pfn << PAGE_SHIFT;
+	u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
+
+	lmb_add(base, size);
+
+	/* Reserve the LMB regions used by the kernel, initrd, etc.. */
+	lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+		    (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
+		    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
 
 	/*
 	 * Node 0 sets up its pgdat at the first available pfn,
@@ -45,24 +55,23 @@
 
 void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 {
-	unsigned long bootmap_pages, bootmap_start, bootmap_size;
-	unsigned long start_pfn, free_pfn, end_pfn;
+	unsigned long bootmap_pages;
+	unsigned long start_pfn, end_pfn;
+	unsigned long bootmem_paddr;
 
 	/* Don't allow bogus node assignment */
 	BUG_ON(nid > MAX_NUMNODES || nid == 0);
 
-	/*
-	 * The free pfn starts at the beginning of the range, and is
-	 * advanced as necessary for pgdat and node map allocations.
-	 */
-	free_pfn = start_pfn = start >> PAGE_SHIFT;
+	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
+	lmb_add(start, end - start);
+
 	__add_active_range(nid, start_pfn, end_pfn);
 
 	/* Node-local pgdat */
-	NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
-	free_pfn += PFN_UP(sizeof(struct pglist_data));
+	NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
+					     SMP_CACHE_BYTES, end_pfn));
 	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
 	NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
@@ -71,16 +80,17 @@
 
 	/* Node-local bootmap */
 	bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	bootmap_start = (unsigned long)pfn_to_kaddr(free_pfn);
-	bootmap_size = init_bootmem_node(NODE_DATA(nid), free_pfn, start_pfn,
-				    end_pfn);
+	bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
+				       PAGE_SIZE, end_pfn);
+	init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
+			  start_pfn, end_pfn);
 
 	free_bootmem_with_active_regions(nid, end_pfn);
 
 	/* Reserve the pgdat and bootmap space with the bootmem allocator */
 	reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT,
 			     sizeof(struct pglist_data), BOOTMEM_DEFAULT);
-	reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT,
+	reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr,
 			     bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 
 	/* It's up */
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
deleted file mode 100644
index 91ed4e6..0000000
--- a/arch/sh/mm/pg-nommu.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * arch/sh/mm/pg-nommu.c
- *
- * clear_page()/copy_page() implementation for MMUless SH.
- *
- * Copyright (C) 2003  Paul Mundt
- *
- * 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.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-void copy_page(void *to, void *from)
-{
-	memcpy(to, from, PAGE_SIZE);
-}
-
-void clear_page(void *to)
-{
-	memset(to, 0, PAGE_SIZE);
-}
-
-__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n)
-{
-	memcpy(to, from, n);
-	return 0;
-}
-
-__kernel_size_t __clear_user(void *to, __kernel_size_t n)
-{
-	memset(to, 0, n);
-	return 0;
-}
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
deleted file mode 100644
index 2fe14da..0000000
--- a/arch/sh/mm/pg-sh4.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * arch/sh/mm/pg-sh4.c
- *
- * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2002 - 2007  Paul Mundt
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/fs.h>
-#include <linux/highmem.h>
-#include <linux/module.h>
-#include <asm/mmu_context.h>
-#include <asm/cacheflush.h>
-
-#define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
-
-#define kmap_get_fixmap_pte(vaddr)                                     \
-	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
-
-static pte_t *kmap_coherent_pte;
-
-void __init kmap_coherent_init(void)
-{
-	unsigned long vaddr;
-
-	/* cache the first coherent kmap pte */
-	vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
-	kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
-}
-
-static inline void *kmap_coherent(struct page *page, unsigned long addr)
-{
-	enum fixed_addresses idx;
-	unsigned long vaddr, flags;
-	pte_t pte;
-
-	inc_preempt_count();
-
-	idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT;
-	vaddr = __fix_to_virt(FIX_CMAP_END - idx);
-	pte = mk_pte(page, PAGE_KERNEL);
-
-	local_irq_save(flags);
-	flush_tlb_one(get_asid(), vaddr);
-	local_irq_restore(flags);
-
-	update_mmu_cache(NULL, vaddr, pte);
-
-	set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
-
-	return (void *)vaddr;
-}
-
-static inline void kunmap_coherent(struct page *page)
-{
-	dec_preempt_count();
-	preempt_check_resched();
-}
-
-/*
- * clear_user_page
- * @to: P1 address
- * @address: U0 address to be mapped
- * @page: page (virt_to_page(to))
- */
-void clear_user_page(void *to, unsigned long address, struct page *page)
-{
-	__set_bit(PG_mapped, &page->flags);
-
-	clear_page(to);
-	if ((((address & PAGE_MASK) ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_wback_region(to, PAGE_SIZE);
-}
-
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
-		       unsigned long vaddr, void *dst, const void *src,
-		       unsigned long len)
-{
-	void *vto;
-
-	__set_bit(PG_mapped, &page->flags);
-
-	vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
-	memcpy(vto, src, len);
-	kunmap_coherent(vto);
-
-	if (vma->vm_flags & VM_EXEC)
-		flush_cache_page(vma, vaddr, page_to_pfn(page));
-}
-
-void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
-			 unsigned long vaddr, void *dst, const void *src,
-			 unsigned long len)
-{
-	void *vfrom;
-
-	__set_bit(PG_mapped, &page->flags);
-
-	vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
-	memcpy(dst, vfrom, len);
-	kunmap_coherent(vfrom);
-}
-
-void copy_user_highpage(struct page *to, struct page *from,
-			unsigned long vaddr, struct vm_area_struct *vma)
-{
-	void *vfrom, *vto;
-
-	__set_bit(PG_mapped, &to->flags);
-
-	vto = kmap_atomic(to, KM_USER1);
-	vfrom = kmap_coherent(from, vaddr);
-	copy_page(vto, vfrom);
-	kunmap_coherent(vfrom);
-
-	if (((vaddr ^ (unsigned long)vto) & CACHE_ALIAS))
-		__flush_wback_region(vto, PAGE_SIZE);
-
-	kunmap_atomic(vto, KM_USER1);
-	/* Make sure this page is cleared on other CPU's too before using it */
-	smp_wmb();
-}
-EXPORT_SYMBOL(copy_user_highpage);
-
-/*
- * For SH-4, we have our own implementation for ptep_get_and_clear
- */
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = *ptep;
-
-	pte_clear(mm, addr, ptep);
-	if (!pte_not_present(pte)) {
-		unsigned long pfn = pte_pfn(pte);
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-			struct address_space *mapping = page_mapping(page);
-			if (!mapping || !mapping_writably_mapped(mapping))
-				__clear_bit(PG_mapped, &page->flags);
-		}
-	}
-	return pte;
-}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
deleted file mode 100644
index eaf2514..0000000
--- a/arch/sh/mm/pg-sh7705.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * arch/sh/mm/pg-sh7705.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
- * Copyright (C) 2004  Alex Song
- *
- * 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.
- *
- */
-
-#include <linux/init.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/threads.h>
-#include <linux/fs.h>
-#include <asm/addrspace.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/mmu_context.h>
-#include <asm/cacheflush.h>
-
-static inline void __flush_purge_virtual_region(void *p1, void *virt, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-	unsigned long p1_begin;
-
-
-	begin = L1_CACHE_ALIGN((unsigned long)virt);
-	end = L1_CACHE_ALIGN((unsigned long)virt + size);
-
-	p1_begin = (unsigned long)p1 & ~(L1_CACHE_BYTES - 1);
-
-	/* do this the slow way as we may not have TLB entries
-	 * for virt yet. */
-	for (v = begin; v < end; v += L1_CACHE_BYTES) {
-		unsigned long p;
-	        unsigned long ways, addr;
-
-		p = __pa(p1_begin);
-
-	        ways = current_cpu_data.dcache.ways;
-		addr = CACHE_OC_ADDRESS_ARRAY;
-
-		do {
-			unsigned long data;
-
-			addr |= (v & current_cpu_data.dcache.entry_mask);
-
-			data = ctrl_inl(addr);
-			if ((data & CACHE_PHYSADDR_MASK) ==
-			       (p & CACHE_PHYSADDR_MASK)) {
-				data &= ~(SH_CACHE_UPDATED|SH_CACHE_VALID);
-				ctrl_outl(data, addr);
-			}
-
-			addr += current_cpu_data.dcache.way_incr;
-		} while (--ways);
-
-		p1_begin += L1_CACHE_BYTES;
-	}
-}
-
-/*
- * clear_user_page
- * @to: P1 address
- * @address: U0 address to be mapped
- */
-void clear_user_page(void *to, unsigned long address, struct page *pg)
-{
-	struct page *page = virt_to_page(to);
-
-	__set_bit(PG_mapped, &page->flags);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
-		clear_page(to);
-		__flush_wback_region(to, PAGE_SIZE);
-	} else {
-		__flush_purge_virtual_region(to,
-					     (void *)(address & 0xfffff000),
-					     PAGE_SIZE);
-		clear_page(to);
-		__flush_wback_region(to, PAGE_SIZE);
-	}
-}
-
-/*
- * copy_user_page
- * @to: P1 address
- * @from: P1 address
- * @address: U0 address to be mapped
- */
-void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
-{
-	struct page *page = virt_to_page(to);
-
-
-	__set_bit(PG_mapped, &page->flags);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
-		copy_page(to, from);
-		__flush_wback_region(to, PAGE_SIZE);
-	} else {
-		__flush_purge_virtual_region(to,
-					     (void *)(address & 0xfffff000),
-					     PAGE_SIZE);
-		copy_page(to, from);
-		__flush_wback_region(to, PAGE_SIZE);
-	}
-}
-
-/*
- * For SH7705, we have our own implementation for ptep_get_and_clear
- * Copied from pg-sh4.c
- */
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = *ptep;
-
-	pte_clear(mm, addr, ptep);
-	if (!pte_not_present(pte)) {
-		unsigned long pfn = pte_pfn(pte);
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-			struct address_space *mapping = page_mapping(page);
-			if (!mapping || !mapping_writably_mapped(mapping))
-				__clear_bit(PG_mapped, &page->flags);
-		}
-	}
-
-	return pte;
-}
-
diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c
deleted file mode 100644
index 71c742b..0000000
--- a/arch/sh/mm/tlb-nommu.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * arch/sh/mm/tlb-nommu.c
- *
- * TLB Operations for MMUless SH.
- *
- * Copyright (C) 2002 Paul Mundt
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-
-/*
- * Nothing too terribly exciting here ..
- */
-void local_flush_tlb_all(void)
-{
-	BUG();
-}
-
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
-	BUG();
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
-			    unsigned long end)
-{
-	BUG();
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	BUG();
-}
-
-void local_flush_tlb_one(unsigned long asid, unsigned long page)
-{
-	BUG();
-}
-
-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
-{
-	BUG();
-}
-
-void __init page_table_range_init(unsigned long start, unsigned long end,
-				  pgd_t *pgd_base)
-{
-}
-
-void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-{
-}
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
index 2aab3ea..409b7c2 100644
--- a/arch/sh/mm/tlb-pteaex.c
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -16,34 +16,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#ifndef CONFIG_CACHE_OFF
-	{
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-
-			if (!test_bit(PG_mapped, &page->flags)) {
-				unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-				__flush_wback_region((void *)P1SEGADDR(phys),
-						     PAGE_SIZE);
-				__set_bit(PG_mapped, &page->flags);
-			}
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 17cb7c3..ace8e6d 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -27,32 +27,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#if defined(CONFIG_SH7705_CACHE_32KB)
-	{
-		struct page *page = pte_page(pte);
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
-			unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-
-			__flush_wback_region((void *)P1SEGADDR(phys),
-					     PAGE_SIZE);
-			__set_bit(PG_mapped, &page->flags);
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
@@ -93,4 +77,3 @@
 	for (i = 0; i < ways; i++)
 		ctrl_outl(data, addr + (i << 8));
 }
-
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index f0c7b73..8cf550e 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -15,34 +15,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#ifndef CONFIG_CACHE_OFF
-	{
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-
-			if (!test_bit(PG_mapped, &page->flags)) {
-				unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-				__flush_wback_region((void *)P1SEGADDR(phys),
-						     PAGE_SIZE);
-				__set_bit(PG_mapped, &page->flags);
-			}
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
@@ -61,9 +43,12 @@
 	 */
 	ctrl_outl(pte.pte_high, MMU_PTEA);
 #else
-	if (cpu_data->flags & CPU_HAS_PTEA)
-		/* TODO: make this look less hacky */
-		ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
+	if (cpu_data->flags & CPU_HAS_PTEA) {
+		/* The last 3 bits and the first one of pteval contains
+		 * the PTEA timing control and space attribute bits
+		 */
+		ctrl_outl(copy_ptea_attributes(pteval), MMU_PTEA);
+	}
 #endif
 
 	/* Set PTEL register */
diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c
index dae1312..fdb64e4 100644
--- a/arch/sh/mm/tlb-sh5.c
+++ b/arch/sh/mm/tlb-sh5.c
@@ -117,26 +117,15 @@
  * Load up a virtual<->physical translation for @eaddr<->@paddr in the
  * pre-allocated TLB slot @config_addr (see sh64_get_wired_dtlb_entry).
  */
-inline void sh64_setup_tlb_slot(unsigned long long config_addr,
-				unsigned long eaddr,
-				unsigned long asid,
-				unsigned long paddr)
+void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
+			 unsigned long asid, unsigned long paddr)
 {
 	unsigned long long pteh, ptel;
 
-	/* Sign extension */
-#if (NEFF == 32)
-	pteh = (unsigned long long)(signed long long)(signed long) eaddr;
-#else
-#error "Can't sign extend more than 32 bits yet"
-#endif
+	pteh = neff_sign_extend(eaddr);
 	pteh &= PAGE_MASK;
 	pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
-#if (NEFF == 32)
-	ptel = (unsigned long long)(signed long long)(signed long) paddr;
-#else
-#error "Can't sign extend more than 32 bits yet"
-#endif
+	ptel = neff_sign_extend(paddr);
 	ptel &= PAGE_MASK;
 	ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE);
 
@@ -152,5 +141,5 @@
  *
  * Teardown any existing mapping in the TLB slot @config_addr.
  */
-inline void sh64_teardown_tlb_slot(unsigned long long config_addr)
+void sh64_teardown_tlb_slot(unsigned long long config_addr)
 	__attribute__ ((alias("__flush_tlb_slot")));
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 3ce40ea..2dcc485 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -329,22 +329,6 @@
 		goto no_context;
 }
 
-void update_mmu_cache(struct vm_area_struct * vma,
-			unsigned long address, pte_t pte)
-{
-	/*
-	 * This appears to get called once for every pte entry that gets
-	 * established => I don't think it's efficient to try refilling the
-	 * TLBs with the pages - some may not get accessed even.  Also, for
-	 * executable pages, it is impossible to determine reliably here which
-	 * TLB they should be mapped into (or both even).
-	 *
-	 * So, just do nothing here and handle faults on demand.  In the
-	 * TLBMISS handling case, the refill is now done anyway after the pte
-	 * has been fixed up, so that deals with most useful cases.
-	 */
-}
-
 void local_flush_tlb_one(unsigned long asid, unsigned long page)
 {
 	unsigned long long match, pteh=0, lpage;
@@ -353,7 +337,7 @@
 	/*
 	 * Sign-extend based on neff.
 	 */
-	lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page;
+	lpage = neff_sign_extend(page);
 	match = (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
 	match |= lpage;
 
@@ -482,3 +466,7 @@
         /* FIXME: Optimize this later.. */
         flush_tlb_all();
 }
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+}
diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c
index 9499a29..2bc74de 100644
--- a/arch/sh/oprofile/backtrace.c
+++ b/arch/sh/oprofile/backtrace.c
@@ -17,9 +17,43 @@
 #include <linux/sched.h>
 #include <linux/kallsyms.h>
 #include <linux/mm.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/sections.h>
+#include <asm/stacktrace.h>
+
+static void backtrace_warning_symbol(void *data, char *msg,
+				     unsigned long symbol)
+{
+	/* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+	/* Ignore warnings */
+}
+
+static int backtrace_stack(void *data, char *name)
+{
+	/* Yes, we want all stacks */
+	return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+	unsigned int *depth = data;
+
+	if ((*depth)--)
+		oprofile_add_trace(addr);
+}
+
+static struct stacktrace_ops backtrace_ops = {
+	.warning = backtrace_warning,
+	.warning_symbol = backtrace_warning_symbol,
+	.stack = backtrace_stack,
+	.address = backtrace_address,
+};
 
 /* Limit to stop backtracing too far. */
 static int backtrace_limit = 20;
@@ -47,50 +81,6 @@
 	return stackaddr;
 }
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->regs[15] value if valid
- * .             .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * |             |
- * .             .
- * |             |
- * --------------- ???
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
-{
-	unsigned long stack = (unsigned long)regs;
-	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-	return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
-}
-
-static unsigned long *
-kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	/*
-	 * If not a valid kernel address, keep going till we find one
-	 * or the SP stops being a valid address.
-	 */
-	do {
-		addr = *stackaddr++;
-		oprofile_add_trace(addr);
-	} while (valid_kernel_stack(stackaddr, regs));
-
-	return stackaddr;
-}
-
 void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
 	unsigned long *stackaddr;
@@ -103,9 +93,9 @@
 
 	stackaddr = (unsigned long *)regs->regs[15];
 	if (!user_mode(regs)) {
-		while (depth-- && valid_kernel_stack(stackaddr, regs))
-			stackaddr = kernel_backtrace(stackaddr, regs);
-
+		if (depth)
+			unwind_stack(NULL, regs, stackaddr,
+				     &backtrace_ops, &depth);
 		return;
 	}
 
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index fec3a53..6639b25 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -53,6 +53,9 @@
 AP325RXA		SH_AP325RXA
 SH7763RDP		SH_SH7763RDP
 SH7785LCR		SH_SH7785LCR
+SH7785LCR_PT		SH_SH7785LCR_PT
 URQUELL			SH_URQUELL
 ESPT			SH_ESPT
 POLARIS			SH_POLARIS
+KFR2R09			SH_KFR2R09
+ECOVEC			SH_ECOVEC
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 820487d..86a9d4e 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
+#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -165,7 +166,8 @@
 	u_int32_t denom;
 	u_int32_t tmp;
 
-	/* Make sure the clock is enabled */
+	/* Wake up device and enable clock */
+	pm_runtime_get_sync(pd->dev);
 	clk_enable(pd->clk);
 
 	/* Get clock rate after clock is enabled */
@@ -213,8 +215,9 @@
 	/* Disable channel */
 	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
 
-	/* Disable clock */
+	/* Disable clock and mark device as idle */
 	clk_disable(pd->clk);
+	pm_runtime_put_sync(pd->dev);
 }
 
 static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
@@ -572,6 +575,19 @@
 		goto err_irq;
 	}
 
+	/* Enable Runtime PM for this device.
+	 *
+	 * Also tell the Runtime PM core to ignore children
+	 * for this device since it is valid for us to suspend
+	 * this I2C master driver even though the slave devices
+	 * on the I2C bus may not be suspended.
+	 *
+	 * The state of the I2C hardware bus is unaffected by
+	 * the Runtime PM state.
+	 */
+	pm_suspend_ignore_children(&dev->dev, true);
+	pm_runtime_enable(&dev->dev);
+
 	/* setup the private data */
 	adap = &pd->adap;
 	i2c_set_adapdata(adap, pd);
@@ -614,14 +630,33 @@
 	iounmap(pd->reg);
 	sh_mobile_i2c_hook_irqs(dev, 0);
 	clk_put(pd->clk);
+	pm_runtime_disable(&dev->dev);
 	kfree(pd);
 	return 0;
 }
 
+static int sh_mobile_i2c_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
+	.runtime_suspend = sh_mobile_i2c_runtime_nop,
+	.runtime_resume = sh_mobile_i2c_runtime_nop,
+};
+
 static struct platform_driver sh_mobile_i2c_driver = {
 	.driver		= {
 		.name		= "i2c-sh_mobile",
 		.owner		= THIS_MODULE,
+		.pm		= &sh_mobile_i2c_dev_pm_ops,
 	},
 	.probe		= sh_mobile_i2c_probe,
 	.remove		= sh_mobile_i2c_remove,
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 0714bf2..887af79 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -80,6 +80,9 @@
 		iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8),
 			  priv->iomem_base + KYCR2_OFFS);
 
+		if (pdata->kycr2_delay)
+			udelay(pdata->kycr2_delay);
+
 		keys ^= ~0;
 		keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
 			       sh_keysc_mode[pdata->mode].keyout)) - 1;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index e86878d..61c47b8 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -30,7 +30,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -86,7 +86,6 @@
 
 	unsigned int irq;
 	void __iomem *base;
-	struct clk *clk;
 	unsigned long video_limit;
 
 	/* lock used to protect videobuf */
@@ -361,7 +360,7 @@
 	if (ret)
 		goto err;
 
-	clk_enable(pcdev->clk);
+	pm_runtime_get_sync(ici->dev);
 
 	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
 	while (ceu_read(pcdev, CSTSR) & 1)
@@ -395,7 +394,7 @@
 	}
 	spin_unlock_irqrestore(&pcdev->lock, flags);
 
-	clk_disable(pcdev->clk);
+	pm_runtime_put_sync(ici->dev);
 
 	icd->ops->release(icd);
 
@@ -798,7 +797,6 @@
 	struct sh_mobile_ceu_dev *pcdev;
 	struct resource *res;
 	void __iomem *base;
-	char clk_name[8];
 	unsigned int irq;
 	int err = 0;
 
@@ -862,13 +860,9 @@
 		goto exit_release_mem;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id);
-	pcdev->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(pcdev->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		err = PTR_ERR(pcdev->clk);
-		goto exit_free_irq;
-	}
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_resume(&pdev->dev);
 
 	pcdev->ici.priv = pcdev;
 	pcdev->ici.dev = &pdev->dev;
@@ -878,12 +872,10 @@
 
 	err = soc_camera_host_register(&pcdev->ici);
 	if (err)
-		goto exit_free_clk;
+		goto exit_free_irq;
 
 	return 0;
 
-exit_free_clk:
-	clk_put(pcdev->clk);
 exit_free_irq:
 	free_irq(pcdev->irq, pcdev);
 exit_release_mem:
@@ -904,7 +896,6 @@
 					struct sh_mobile_ceu_dev, ici);
 
 	soc_camera_host_unregister(soc_host);
-	clk_put(pcdev->clk);
 	free_irq(pcdev->irq, pcdev);
 	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
 		dma_release_declared_memory(&pdev->dev);
@@ -913,9 +904,27 @@
 	return 0;
 }
 
+static int sh_mobile_ceu_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
+	.runtime_suspend = sh_mobile_ceu_runtime_nop,
+	.runtime_resume = sh_mobile_ceu_runtime_nop,
+};
+
 static struct platform_driver sh_mobile_ceu_driver = {
 	.driver 	= {
 		.name	= "sh_mobile_ceu",
+		.pm	= &sh_mobile_ceu_dev_pm_ops,
 	},
 	.probe		= sh_mobile_ceu_probe,
 	.remove		= sh_mobile_ceu_remove,
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 1845566..d490628 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -1,26 +1,25 @@
 /*
  * Dallas DS1302 RTC Support
  *
- *  Copyright (C) 2002  David McCullough
- *  Copyright (C) 2003 - 2007  Paul Mundt
+ *  Copyright (C) 2002 David McCullough
+ *  Copyright (C) 2003 - 2007 Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
- * License version 2.  See the file "COPYING" in the main directory of
+ * License version 2. See the file "COPYING" in the main directory of
  * this archive for more details.
  */
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/time.h>
 #include <linux/rtc.h>
-#include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/bcd.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME	"rtc-ds1302"
-#define DRV_VERSION	"0.1.0"
+#define DRV_VERSION	"0.1.1"
 
 #define	RTC_CMD_READ	0x81		/* Read command */
 #define	RTC_CMD_WRITE	0x80		/* Write command */
@@ -47,11 +46,6 @@
 #error "Add support for your platform"
 #endif
 
-struct ds1302_rtc {
-	struct rtc_device *rtc_dev;
-	spinlock_t lock;
-};
-
 static void ds1302_sendbits(unsigned int val)
 {
 	int i;
@@ -103,10 +97,6 @@
 
 static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	struct ds1302_rtc *rtc = dev_get_drvdata(dev);
-
-	spin_lock_irq(&rtc->lock);
-
 	tm->tm_sec	= bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
 	tm->tm_min	= bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
 	tm->tm_hour	= bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
@@ -118,26 +108,17 @@
 	if (tm->tm_year < 70)
 		tm->tm_year += 100;
 
-	spin_unlock_irq(&rtc->lock);
-
 	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__func__,
 		tm->tm_sec, tm->tm_min, tm->tm_hour,
 		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
 
-	if (rtc_valid_tm(tm) < 0)
-		dev_err(dev, "invalid date\n");
-
-	return 0;
+	return rtc_valid_tm(tm);
 }
 
 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	struct ds1302_rtc *rtc = dev_get_drvdata(dev);
-
-	spin_lock_irq(&rtc->lock);
-
 	/* Stop RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
 
@@ -152,8 +133,6 @@
 	/* Start RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
 
-	spin_unlock_irq(&rtc->lock);
-
 	return 0;
 }
 
@@ -170,9 +149,7 @@
 		if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
 			return -EFAULT;
 
-		spin_lock_irq(&rtc->lock);
 		ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
-		spin_unlock_irq(&rtc->lock);
 		return 0;
 	}
 #endif
@@ -187,10 +164,9 @@
 	.ioctl		= ds1302_rtc_ioctl,
 };
 
-static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
+static int __init ds1302_rtc_probe(struct platform_device *pdev)
 {
-	struct ds1302_rtc *rtc;
-	int ret;
+	struct rtc_device *rtc;
 
 	/* Reset */
 	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
@@ -200,37 +176,23 @@
 	if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
 		return -ENODEV;
 
-	rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL);
-	if (unlikely(!rtc))
-		return -ENOMEM;
-
-	spin_lock_init(&rtc->lock);
-	rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev,
+	rtc = rtc_device_register("ds1302", &pdev->dev,
 					   &ds1302_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
-		ret = PTR_ERR(rtc->rtc_dev);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
 	platform_set_drvdata(pdev, rtc);
 
 	return 0;
-out:
-	kfree(rtc);
-	return ret;
 }
 
 static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
 {
-	struct ds1302_rtc *rtc = platform_get_drvdata(pdev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
 
-	if (likely(rtc->rtc_dev))
-		rtc_device_unregister(rtc->rtc_dev);
-
+	rtc_device_unregister(rtc);
 	platform_set_drvdata(pdev, NULL);
 
-	kfree(rtc);
-
 	return 0;
 }
 
@@ -239,13 +201,12 @@
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
-	.probe		= ds1302_rtc_probe,
-	.remove		= __devexit_p(ds1302_rtc_remove),
+	.remove		= __exit_p(ds1302_rtc_remove),
 };
 
 static int __init ds1302_rtc_init(void)
 {
-	return platform_driver_register(&ds1302_platform_driver);
+	return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
 }
 
 static void __exit ds1302_rtc_exit(void)
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index d7310ad..e6ed540 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -29,7 +29,7 @@
 #include <asm/rtc.h>
 
 #define DRV_NAME	"sh-rtc"
-#define DRV_VERSION	"0.2.2"
+#define DRV_VERSION	"0.2.3"
 
 #define RTC_REG(r)	((r) * rtc_reg_size)
 
@@ -215,7 +215,7 @@
 	return IRQ_RETVAL(ret);
 }
 
-static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
+static int sh_rtc_irq_set_state(struct device *dev, int enable)
 {
 	struct sh_rtc *rtc = dev_get_drvdata(dev);
 	unsigned int tmp;
@@ -225,17 +225,22 @@
 	tmp = readb(rtc->regbase + RCR2);
 
 	if (enable) {
+		rtc->periodic_freq |= PF_KOU;
 		tmp &= ~RCR2_PEF;	/* Clear PES bit */
 		tmp |= (rtc->periodic_freq & ~PF_HP);	/* Set PES2-0 */
-	} else
+	} else {
+		rtc->periodic_freq &= ~PF_KOU;
 		tmp &= ~(RCR2_PESMASK | RCR2_PEF);
+	}
 
 	writeb(tmp, rtc->regbase + RCR2);
 
 	spin_unlock_irq(&rtc->lock);
+
+	return 0;
 }
 
-static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq)
+static int sh_rtc_irq_set_freq(struct device *dev, int freq)
 {
 	struct sh_rtc *rtc = dev_get_drvdata(dev);
 	int tmp, ret = 0;
@@ -278,10 +283,8 @@
 		ret = -ENOTSUPP;
 	}
 
-	if (ret == 0) {
+	if (ret == 0)
 		rtc->periodic_freq |= tmp;
-		rtc->rtc_dev->irq_freq = freq;
-	}
 
 	spin_unlock_irq(&rtc->lock);
 	return ret;
@@ -346,10 +349,6 @@
 	unsigned int ret = 0;
 
 	switch (cmd) {
-	case RTC_PIE_OFF:
-	case RTC_PIE_ON:
-		sh_rtc_setpie(dev, cmd == RTC_PIE_ON);
-		break;
 	case RTC_AIE_OFF:
 	case RTC_AIE_ON:
 		sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
@@ -362,13 +361,6 @@
 		rtc->periodic_freq |= PF_OXS;
 		sh_rtc_setcie(dev, 1);
 		break;
-	case RTC_IRQP_READ:
-		ret = put_user(rtc->rtc_dev->irq_freq,
-			       (unsigned long __user *)arg);
-		break;
-	case RTC_IRQP_SET:
-		ret = sh_rtc_setfreq(dev, arg);
-		break;
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -602,28 +594,6 @@
 	return 0;
 }
 
-static int sh_rtc_irq_set_state(struct device *dev, int enabled)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_rtc *rtc = platform_get_drvdata(pdev);
-
-	if (enabled) {
-		rtc->periodic_freq |= PF_KOU;
-		return sh_rtc_ioctl(dev, RTC_PIE_ON, 0);
-	} else {
-		rtc->periodic_freq &= ~PF_KOU;
-		return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0);
-	}
-}
-
-static int sh_rtc_irq_set_freq(struct device *dev, int freq)
-{
-	if (!is_power_of_2(freq))
-		return -EINVAL;
-
-	return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
-}
-
 static struct rtc_class_ops sh_rtc_ops = {
 	.ioctl		= sh_rtc_ioctl,
 	.read_time	= sh_rtc_read_time,
@@ -635,7 +605,7 @@
 	.proc		= sh_rtc_proc,
 };
 
-static int __devinit sh_rtc_probe(struct platform_device *pdev)
+static int __init sh_rtc_probe(struct platform_device *pdev)
 {
 	struct sh_rtc *rtc;
 	struct resource *res;
@@ -702,13 +672,6 @@
 
 	clk_enable(rtc->clk);
 
-	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
-					   &sh_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
-		ret = PTR_ERR(rtc->rtc_dev);
-		goto err_unmap;
-	}
-
 	rtc->capabilities = RTC_DEF_CAPABILITIES;
 	if (pdev->dev.platform_data) {
 		struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data;
@@ -720,10 +683,6 @@
 		rtc->capabilities |= pinfo->capabilities;
 	}
 
-	rtc->rtc_dev->max_user_freq = 256;
-
-	platform_set_drvdata(pdev, rtc);
-
 	if (rtc->carry_irq <= 0) {
 		/* register shared periodic/carry/alarm irq */
 		ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
@@ -767,13 +726,26 @@
 		}
 	}
 
+	platform_set_drvdata(pdev, rtc);
+
 	/* everything disabled by default */
-	rtc->periodic_freq = 0;
-	rtc->rtc_dev->irq_freq = 0;
-	sh_rtc_setpie(&pdev->dev, 0);
+	sh_rtc_irq_set_freq(&pdev->dev, 0);
+	sh_rtc_irq_set_state(&pdev->dev, 0);
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
+	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
+					   &sh_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc_dev)) {
+		ret = PTR_ERR(rtc->rtc_dev);
+		free_irq(rtc->periodic_irq, rtc);
+		free_irq(rtc->carry_irq, rtc);
+		free_irq(rtc->alarm_irq, rtc);
+		goto err_unmap;
+	}
+
+	rtc->rtc_dev->max_user_freq = 256;
+
 	/* reset rtc to epoch 0 if time is invalid */
 	if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
 		rtc_time_to_tm(0, &r);
@@ -795,14 +767,13 @@
 	return ret;
 }
 
-static int __devexit sh_rtc_remove(struct platform_device *pdev)
+static int __exit sh_rtc_remove(struct platform_device *pdev)
 {
 	struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
-	if (likely(rtc->rtc_dev))
-		rtc_device_unregister(rtc->rtc_dev);
+	rtc_device_unregister(rtc->rtc_dev);
+	sh_rtc_irq_set_state(&pdev->dev, 0);
 
-	sh_rtc_setpie(&pdev->dev, 0);
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
@@ -813,9 +784,8 @@
 		free_irq(rtc->alarm_irq, rtc);
 	}
 
-	release_resource(rtc->res);
-
 	iounmap(rtc->regbase);
+	release_resource(rtc->res);
 
 	clk_disable(rtc->clk);
 	clk_put(rtc->clk);
@@ -867,13 +837,12 @@
 		.owner	= THIS_MODULE,
 		.pm	= &sh_rtc_dev_pm_ops,
 	},
-	.probe		= sh_rtc_probe,
-	.remove		= __devexit_p(sh_rtc_remove),
+	.remove		= __exit_p(sh_rtc_remove),
 };
 
 static int __init sh_rtc_init(void)
 {
-	return platform_driver_register(&sh_rtc_platform_driver);
+	return platform_driver_probe(&sh_rtc_platform_driver, sh_rtc_probe);
 }
 
 static void __exit sh_rtc_exit(void)
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 8e2feb5..32dc2fc 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -272,7 +272,8 @@
 		__raw_writew(data, PSCR);
 	}
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7763) || \
       defined(CONFIG_CPU_SUBTYPE_SH7780) || \
       defined(CONFIG_CPU_SUBTYPE_SH7785) || \
       defined(CONFIG_CPU_SUBTYPE_SH7786) || \
@@ -662,10 +663,11 @@
 static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	unsigned long flags;
 
-	spin_lock_irq(&port->lock);
+	spin_lock_irqsave(&port->lock, flags);
 	sci_transmit_chars(port);
-	spin_unlock_irq(&port->lock);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 38072c1..3e2fcf9 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -112,6 +112,13 @@
 #elif defined(CONFIG_H8S2678)
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+# define SCSPTR0 0xfe4b0020
+# define SCSPTR1 0xfe4b0020
+# define SCSPTR2 0xfe4b0020
+# define SCIF_ORER 0x0001
+# define SCSCR_INIT(port)	0x38
+# define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
 # define SCSPTR0 0xffe00024 /* 16 bit SCIF */
 # define SCSPTR1 0xffe08024 /* 16 bit SCIF */
@@ -562,6 +569,16 @@
 		return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
 	return 1;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+	if (port->mapbase == 0xfe4b0000)
+		return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0;
+	if (port->mapbase == 0xfe4c0000)
+		return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0;
+	if (port->mapbase == 0xfe4d0000)
+		return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0;
+}
 #elif defined(CONFIG_CPU_SUBTYPE_SH7760)
 static inline int sci_rxd_in(struct uart_port *port)
 {
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 3dd231a..559b5fe 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -77,7 +77,7 @@
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
 	struct irq_chip *chip = get_irq_chip(irq);
-	return (void *)((char *)chip - offsetof(struct intc_desc_int, chip));
+	return container_of(chip, struct intc_desc_int, chip);
 }
 
 static inline unsigned int set_field(unsigned int value,
@@ -95,16 +95,19 @@
 static void write_8(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writeb(set_field(0, data, h), addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
 }
 
 static void write_16(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writew(set_field(0, data, h), addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
 }
 
 static void write_32(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writel(set_field(0, data, h), addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
 }
 
 static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
@@ -112,6 +115,7 @@
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writeb(set_field(__raw_readb(addr), data, h), addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -120,6 +124,7 @@
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writew(set_field(__raw_readw(addr), data, h), addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -128,6 +133,7 @@
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writel(set_field(__raw_readl(addr), data, h), addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -657,16 +663,9 @@
 	return 0;
 }
 
-static unsigned char *intc_evt2irq_table;
-
-unsigned int intc_evt2irq(unsigned int vector)
+static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned int irq = evt2irq(vector);
-
-	if (intc_evt2irq_table && intc_evt2irq_table[irq])
-		irq = intc_evt2irq_table[irq];
-
-	return irq;
+	generic_handle_irq((unsigned int)get_irq_data(irq));
 }
 
 void __init register_intc_controller(struct intc_desc *desc)
@@ -739,34 +738,6 @@
 
 	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
 
-	/* keep the first vector only if same enum is used multiple times */
-	for (i = 0; i < desc->nr_vectors; i++) {
-		struct intc_vect *vect = desc->vectors + i;
-		int first_irq = evt2irq(vect->vect);
-
-		if (!vect->enum_id)
-			continue;
-
-		for (k = i + 1; k < desc->nr_vectors; k++) {
-			struct intc_vect *vect2 = desc->vectors + k;
-
-			if (vect->enum_id != vect2->enum_id)
-				continue;
-
-			vect2->enum_id = 0;
-
-			if (!intc_evt2irq_table)
-				intc_evt2irq_table = kzalloc(NR_IRQS, GFP_NOWAIT);
-
-			if (!intc_evt2irq_table) {
-				pr_warning("intc: cannot allocate evt2irq!\n");
-				continue;
-			}
-
-			intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq;
-		}
-	}
-
 	/* register the vectors one by one */
 	for (i = 0; i < desc->nr_vectors; i++) {
 		struct intc_vect *vect = desc->vectors + i;
@@ -778,11 +749,37 @@
 
 		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
 		if (unlikely(!irq_desc)) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+			pr_info("can't get irq_desc for %d\n", irq);
 			continue;
 		}
 
 		intc_register_irq(desc, d, vect->enum_id, irq);
+
+		for (k = i + 1; k < desc->nr_vectors; k++) {
+			struct intc_vect *vect2 = desc->vectors + k;
+			unsigned int irq2 = evt2irq(vect2->vect);
+
+			if (vect->enum_id != vect2->enum_id)
+				continue;
+
+			/*
+			 * In the case of multi-evt handling and sparse
+			 * IRQ support, each vector still needs to have
+			 * its own backing irq_desc.
+			 */
+			irq_desc = irq_to_desc_alloc_node(irq2, numa_node_id());
+			if (unlikely(!irq_desc)) {
+				pr_info("can't get irq_desc for %d\n", irq2);
+				continue;
+			}
+
+			vect2->enum_id = 0;
+
+			/* redirect this interrupts to the first one */
+			set_irq_chip_and_handler_name(irq2, &d->chip,
+					intc_redirect_irq, "redirect");
+			set_irq_data(irq2, (void *)irq);
+		}
 	}
 }
 
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 3f06818..02347c5 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -20,6 +20,7 @@
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
+#include <linux/pm_runtime.h>
 
 #define DRIVER_NAME "uio_pdrv_genirq"
 
@@ -27,8 +28,27 @@
 	struct uio_info *uioinfo;
 	spinlock_t lock;
 	unsigned long flags;
+	struct platform_device *pdev;
 };
 
+static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode)
+{
+	struct uio_pdrv_genirq_platdata *priv = info->priv;
+
+	/* Wait until the Runtime PM code has woken up the device */
+	pm_runtime_get_sync(&priv->pdev->dev);
+	return 0;
+}
+
+static int uio_pdrv_genirq_release(struct uio_info *info, struct inode *inode)
+{
+	struct uio_pdrv_genirq_platdata *priv = info->priv;
+
+	/* Tell the Runtime PM code that the device has become idle */
+	pm_runtime_put_sync(&priv->pdev->dev);
+	return 0;
+}
+
 static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
 {
 	struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
@@ -97,6 +117,7 @@
 	priv->uioinfo = uioinfo;
 	spin_lock_init(&priv->lock);
 	priv->flags = 0; /* interrupt is enabled to begin with */
+	priv->pdev = pdev;
 
 	uiomem = &uioinfo->mem[0];
 
@@ -136,8 +157,17 @@
 	uioinfo->irq_flags |= IRQF_DISABLED;
 	uioinfo->handler = uio_pdrv_genirq_handler;
 	uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
+	uioinfo->open = uio_pdrv_genirq_open;
+	uioinfo->release = uio_pdrv_genirq_release;
 	uioinfo->priv = priv;
 
+	/* Enable Runtime PM for this device:
+	 * The device starts in suspended state to allow the hardware to be
+	 * turned off by default. The Runtime PM bus code should power on the
+	 * hardware and enable clocks at open().
+	 */
+	pm_runtime_enable(&pdev->dev);
+
 	ret = uio_register_device(&pdev->dev, priv->uioinfo);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to register uio device\n");
@@ -157,16 +187,40 @@
 	struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);
 
 	uio_unregister_device(priv->uioinfo);
+	pm_runtime_disable(&pdev->dev);
 	kfree(priv);
 	return 0;
 }
 
+static int uio_pdrv_genirq_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * In this driver pm_runtime_get_sync() and pm_runtime_put_sync()
+	 * are used at open() and release() time. This allows the
+	 * Runtime PM code to turn off power to the device while the
+	 * device is unused, ie before open() and after release().
+	 *
+	 * This Runtime PM callback does not need to save or restore
+	 * any registers since user space is responsbile for hardware
+	 * register reinitialization after open().
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
+	.runtime_suspend = uio_pdrv_genirq_runtime_nop,
+	.runtime_resume = uio_pdrv_genirq_runtime_nop,
+};
+
 static struct platform_driver uio_pdrv_genirq = {
 	.probe = uio_pdrv_genirq_probe,
 	.remove = uio_pdrv_genirq_remove,
 	.driver = {
 		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
+		.pm = &uio_pdrv_genirq_dev_pm_ops,
 	},
 };
 
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7f8e83a..9f986b4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -251,6 +251,24 @@
 	default y if USB_ETH
 	default y if USB_G_SERIAL
 
+config USB_GADGET_R8A66597
+	boolean "Renesas R8A66597 USB Peripheral Controller"
+	select USB_GADGET_DUALSPEED
+	help
+	   R8A66597 is a discrete USB host and peripheral controller chip that
+	   supports both full and high speed USB 2.0 data transfers.
+	   It has nine configurable endpoints, and endpoint zero.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "r8a66597_udc" and force all
+	   gadget drivers to also be dynamically linked.
+
+config USB_R8A66597
+	tristate
+	depends on USB_GADGET_R8A66597
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
 config USB_GADGET_PXA27X
 	boolean "PXA 27x"
 	depends on ARCH_PXA && (PXA27x || PXA3xx)
@@ -360,16 +378,6 @@
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config SUPERH_BUILT_IN_M66592
-	boolean "Enable SuperH built-in USB like the M66592"
-	depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
-	help
-	   SH7722 has USB like the M66592.
-
-	   The transfer rate is very slow when use "Ethernet Gadget".
-	   However, this problem is improved if change a value of
-	   NET_IP_ALIGN to 4.
-
 #
 # Controllers available only in discrete form (and all PCI controllers)
 #
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index e6017e6b..9d7b87c 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -23,6 +23,7 @@
 fsl_usb2_udc-objs		+= fsl_mx3_udc.o
 endif
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
+obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 obj-$(CONFIG_USB_CI13XXX)	+= ci13xxx_udc.o
 obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 8e0e9a0..f2d270b 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -173,6 +173,12 @@
 // CONFIG_USB_GADGET_AU1X00
 // ...
 
+#ifdef CONFIG_USB_GADGET_R8A66597
+#define	gadget_is_r8a66597(g)	!strcmp("r8a66597_udc", (g)->name)
+#else
+#define	gadget_is_r8a66597(g)	0
+#endif
+
 
 /**
  * usb_gadget_controller_number - support bcdDevice id convention
@@ -239,6 +245,8 @@
 		return 0x23;
 	else if (gadget_is_langwell(gadget))
 		return 0x24;
+	else if (gadget_is_r8a66597(gadget))
+		return 0x25;
 	return -ENOENT;
 }
 
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 43dcf9e..a8c8543 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -25,44 +25,18 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
-
+#include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
 #include "m66592-udc.h"
 
-
 MODULE_DESCRIPTION("M66592 USB gadget driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
 MODULE_ALIAS("platform:m66592_udc");
 
-#define DRIVER_VERSION	"18 Oct 2007"
-
-/* module parameters */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-static unsigned short endian = M66592_LITTLE;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
-#else
-static unsigned short clock = M66592_XTAL24;
-module_param(clock, ushort, 0644);
-MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
-		"(default=16384)");
-
-static unsigned short vif = M66592_LDRV;
-module_param(vif, ushort, 0644);
-MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
-
-static unsigned short endian;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
-
-static unsigned short irq_sense = M66592_INTL;
-module_param(irq_sense, ushort, 0644);
-MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
-		"(default=2)");
-#endif
+#define DRIVER_VERSION	"21 July 2009"
 
 static const char udc_name[] = "m66592_udc";
 static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@
 static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
 {
 	struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
+	unsigned short mbw;
 
 	if (ep->use_dma)
 		return;
@@ -252,7 +227,12 @@
 
 	ndelay(450);
 
-	m66592_bset(m66592, M66592_MBW, ep->fifosel);
+	if (m66592->pdata->on_chip)
+		mbw = M66592_MBW_32;
+	else
+		mbw = M66592_MBW_16;
+
+	m66592_bset(m66592, mbw, ep->fifosel);
 }
 
 static int pipe_buffer_setting(struct m66592 *m66592,
@@ -276,24 +256,27 @@
 		buf_bsize = 0;
 		break;
 	case M66592_BULK:
-		bufnum = m66592->bi_bufnum +
-			 (info->pipe - M66592_BASE_PIPENUM_BULK) * 16;
-		m66592->bi_bufnum += 16;
+		/* isochronous pipes may be used as bulk pipes */
+		if (info->pipe > M66592_BASE_PIPENUM_BULK)
+			bufnum = info->pipe - M66592_BASE_PIPENUM_BULK;
+		else
+			bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC;
+
+		bufnum = M66592_BASE_BUFNUM + (bufnum * 16);
 		buf_bsize = 7;
 		pipecfg |= M66592_DBLB;
 		if (!info->dir_in)
 			pipecfg |= M66592_SHTNAK;
 		break;
 	case M66592_ISO:
-		bufnum = m66592->bi_bufnum +
+		bufnum = M66592_BASE_BUFNUM +
 			 (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
-		m66592->bi_bufnum += 16;
 		buf_bsize = 7;
 		break;
 	}
-	if (m66592->bi_bufnum > M66592_MAX_BUFNUM) {
-		pr_err("m66592 pipe memory is insufficient(%d)\n",
-				m66592->bi_bufnum);
+
+	if (buf_bsize && ((bufnum + 16) >= M66592_MAX_BUFNUM)) {
+		pr_err("m66592 pipe memory is insufficient\n");
 		return -ENOMEM;
 	}
 
@@ -313,17 +296,6 @@
 	if (info->pipe == 0)
 		return;
 
-	switch (info->type) {
-	case M66592_BULK:
-		if (is_bulk_pipe(info->pipe))
-			m66592->bi_bufnum -= 16;
-		break;
-	case M66592_ISO:
-		if (is_isoc_pipe(info->pipe))
-			m66592->bi_bufnum -= 16;
-		break;
-	}
-
 	if (is_bulk_pipe(info->pipe)) {
 		m66592->bulk--;
 	} else if (is_interrupt_pipe(info->pipe))
@@ -340,6 +312,7 @@
 static void pipe_initialize(struct m66592_ep *ep)
 {
 	struct m66592 *m66592 = ep->m66592;
+	unsigned short mbw;
 
 	m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
 
@@ -351,7 +324,12 @@
 
 		ndelay(450);
 
-		m66592_bset(m66592, M66592_MBW, ep->fifosel);
+		if (m66592->pdata->on_chip)
+			mbw = M66592_MBW_32;
+		else
+			mbw = M66592_MBW_16;
+
+		m66592_bset(m66592, mbw, ep->fifosel);
 	}
 }
 
@@ -367,15 +345,13 @@
 			ep->fifosel = M66592_D0FIFOSEL;
 			ep->fifoctr = M66592_D0FIFOCTR;
 			ep->fifotrn = M66592_D0FIFOTRN;
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-		} else if (m66592->num_dma == 1) {
+		} else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
 			m66592->num_dma++;
 			ep->use_dma = 1;
 			ep->fifoaddr = M66592_D1FIFO;
 			ep->fifosel = M66592_D1FIFOSEL;
 			ep->fifoctr = M66592_D1FIFOCTR;
 			ep->fifotrn = M66592_D1FIFOTRN;
-#endif
 		} else {
 			ep->use_dma = 0;
 			ep->fifoaddr = M66592_CFIFO;
@@ -620,76 +596,120 @@
 	}
 }
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
 static void init_controller(struct m66592 *m66592)
 {
-	m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);		/* High spd */
-	m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-	m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-	m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+	unsigned int endian;
 
-	/* This is a workaound for SH7722 2nd cut */
-	m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
-	m66592_bset(m66592, 0x1000, M66592_TESTMODE);
-	m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
+	if (m66592->pdata->on_chip) {
+		if (m66592->pdata->endian)
+			endian = 0; /* big endian */
+		else
+			endian = M66592_LITTLE; /* little endian */
 
-	m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
+		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
+		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
 
-	m66592_write(m66592, 0, M66592_CFBCFG);
-	m66592_write(m66592, 0, M66592_D0FBCFG);
-	m66592_bset(m66592, endian, M66592_CFBCFG);
-	m66592_bset(m66592, endian, M66592_D0FBCFG);
+		/* This is a workaound for SH7722 2nd cut */
+		m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
+		m66592_bset(m66592, 0x1000, M66592_TESTMODE);
+		m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
+
+		m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
+
+		m66592_write(m66592, 0, M66592_CFBCFG);
+		m66592_write(m66592, 0, M66592_D0FBCFG);
+		m66592_bset(m66592, endian, M66592_CFBCFG);
+		m66592_bset(m66592, endian, M66592_D0FBCFG);
+	} else {
+		unsigned int clock, vif, irq_sense;
+
+		if (m66592->pdata->endian)
+			endian = M66592_BIGEND; /* big endian */
+		else
+			endian = 0; /* little endian */
+
+		if (m66592->pdata->vif)
+			vif = M66592_LDRV; /* 3.3v */
+		else
+			vif = 0; /* 1.5v */
+
+		switch (m66592->pdata->xtal) {
+		case M66592_PLATDATA_XTAL_12MHZ:
+			clock = M66592_XTAL12;
+			break;
+		case M66592_PLATDATA_XTAL_24MHZ:
+			clock = M66592_XTAL24;
+			break;
+		case M66592_PLATDATA_XTAL_48MHZ:
+			clock = M66592_XTAL48;
+			break;
+		default:
+			pr_warning("m66592-udc: xtal configuration error\n");
+			clock = 0;
+		}
+
+		switch (m66592->irq_trigger) {
+		case IRQF_TRIGGER_LOW:
+			irq_sense = M66592_INTL;
+			break;
+		case IRQF_TRIGGER_FALLING:
+			irq_sense = 0;
+			break;
+		default:
+			pr_warning("m66592-udc: irq trigger config error\n");
+			irq_sense = 0;
+		}
+
+		m66592_bset(m66592,
+			    (vif & M66592_LDRV) | (endian & M66592_BIGEND),
+			    M66592_PINCFG);
+		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
+		m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
+			    M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+
+		m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+
+		msleep(3);
+
+		m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+
+		msleep(1);
+
+		m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+
+		m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
+		m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
+			     M66592_DMA0CFG);
+	}
 }
-#else	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
-static void init_controller(struct m66592 *m66592)
-{
-	m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
-			M66592_PINCFG);
-	m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);		/* High spd */
-	m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
-
-	m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-	m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-	m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
-
-	m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
-
-	msleep(3);
-
-	m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
-
-	msleep(1);
-
-	m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
-
-	m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
-	m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
-			M66592_DMA0CFG);
-}
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
 static void disable_controller(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+	if (!m66592->pdata->on_chip) {
+		m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
+	}
 }
 
 static void m66592_start_xclock(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
 	u16 tmp;
 
-	tmp = m66592_read(m66592, M66592_SYSCFG);
-	if (!(tmp & M66592_XCKE))
-		m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+	if (!m66592->pdata->on_chip) {
+		tmp = m66592_read(m66592, M66592_SYSCFG);
+		if (!(tmp & M66592_XCKE))
+			m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+	}
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1177,8 +1197,7 @@
 	intsts0 = m66592_read(m66592, M66592_INTSTS0);
 	intenb0 = m66592_read(m66592, M66592_INTENB0);
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	if (!intsts0 && !intenb0) {
+	if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
 		/*
 		 * When USB clock stops, it cannot read register. Even if a
 		 * clock stops, the interrupt occurs. So this driver turn on
@@ -1188,7 +1207,6 @@
 		intsts0 = m66592_read(m66592, M66592_INTSTS0);
 		intenb0 = m66592_read(m66592, M66592_INTENB0);
 	}
-#endif
 
 	savepipe = m66592_read(m66592, M66592_CFIFOSEL);
 
@@ -1534,9 +1552,11 @@
 	iounmap(m66592->reg);
 	free_irq(platform_get_irq(pdev, 0), m66592);
 	m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	clk_disable(m66592->clk);
-	clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		clk_disable(m66592->clk);
+		clk_put(m66592->clk);
+	}
 #endif
 	kfree(m66592);
 	return 0;
@@ -1548,11 +1568,10 @@
 
 static int __init m66592_probe(struct platform_device *pdev)
 {
-	struct resource *res;
-	int irq;
+	struct resource *res, *ires;
 	void __iomem *reg = NULL;
 	struct m66592 *m66592 = NULL;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	char clk_name[8];
 #endif
 	int ret = 0;
@@ -1565,10 +1584,11 @@
 		goto clean_up;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
 		ret = -ENODEV;
-		pr_err("platform_get_irq error.\n");
+		dev_err(&pdev->dev,
+			"platform_get_resource IORESOURCE_IRQ error.\n");
 		goto clean_up;
 	}
 
@@ -1579,6 +1599,12 @@
 		goto clean_up;
 	}
 
+	if (pdev->dev.platform_data == NULL) {
+		dev_err(&pdev->dev, "no platform data\n");
+		ret = -ENODEV;
+		goto clean_up;
+	}
+
 	/* initialize ucd */
 	m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
 	if (m66592 == NULL) {
@@ -1586,6 +1612,9 @@
 		goto clean_up;
 	}
 
+	m66592->pdata = pdev->dev.platform_data;
+	m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
 	spin_lock_init(&m66592->lock);
 	dev_set_drvdata(&pdev->dev, m66592);
 
@@ -1603,24 +1632,25 @@
 	m66592->timer.data = (unsigned long)m66592;
 	m66592->reg = reg;
 
-	m66592->bi_bufnum = M66592_BASE_BUFNUM;
-
-	ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
+	ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
 			udc_name, m66592);
 	if (ret < 0) {
 		pr_err("request_irq error (%d)\n", ret);
 		goto clean_up;
 	}
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
-	m66592->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(m66592->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(m66592->clk);
-		goto clean_up2;
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
+		m66592->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(m66592->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(m66592->clk);
+			goto clean_up2;
+		}
+		clk_enable(m66592->clk);
 	}
-	clk_enable(m66592->clk);
 #endif
 	INIT_LIST_HEAD(&m66592->gadget.ep_list);
 	m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1662,12 +1692,14 @@
 	return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	clk_disable(m66592->clk);
-	clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		clk_disable(m66592->clk);
+		clk_put(m66592->clk);
+	}
 clean_up2:
 #endif
-	free_irq(irq, m66592);
+	free_irq(ires->start, m66592);
 clean_up:
 	if (m66592) {
 		if (m66592->ep0_req)
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index 286ce07..8b960de 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -23,10 +23,12 @@
 #ifndef __M66592_UDC_H__
 #define __M66592_UDC_H__
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
+#include <linux/usb/m66592.h>
+
 #define M66592_SYSCFG		0x00
 #define M66592_XTAL		0xC000	/* b15-14: Crystal selection */
 #define   M66592_XTAL48		 0x8000		/* 48MHz */
@@ -76,11 +78,11 @@
 #define   M66592_P_TST_J	 0x0001		/* PERI TEST J */
 #define   M66592_P_TST_NORMAL	 0x0000		/* PERI Normal Mode */
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+/* built-in registers */
 #define M66592_CFBCFG		0x0A
 #define M66592_D0FBCFG		0x0C
 #define M66592_LITTLE		0x0100	/* b8: Little endian mode */
-#else
+/* external chip case */
 #define M66592_PINCFG		0x0A
 #define M66592_LDRV		0x8000	/* b15: Drive Current Adjust */
 #define M66592_BIGEND		0x0100	/* b8: Big endian mode */
@@ -100,8 +102,8 @@
 #define M66592_PKTM		0x0020	/* b5: Packet mode */
 #define M66592_DENDE		0x0010	/* b4: Dend enable */
 #define M66592_OBUS		0x0004	/* b2: OUTbus mode */
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
+/* common case */
 #define M66592_CFIFO		0x10
 #define M66592_D0FIFO		0x14
 #define M66592_D1FIFO		0x18
@@ -113,13 +115,9 @@
 #define M66592_REW		0x4000	/* b14: Buffer rewind */
 #define M66592_DCLRM		0x2000	/* b13: DMA buffer clear mode */
 #define M66592_DREQE		0x1000	/* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-#define M66592_MBW		0x0800	/* b11: Maximum bit width for FIFO */
-#else
-#define M66592_MBW		0x0400	/* b10: Maximum bit width for FIFO */
-#define   M66592_MBW_8		 0x0000   /*  8bit */
-#define   M66592_MBW_16		 0x0400   /* 16bit */
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
+#define M66592_MBW_8		0x0000   /*  8bit */
+#define M66592_MBW_16		0x0400   /* 16bit */
+#define M66592_MBW_32		0x0800   /* 32bit */
 #define M66592_TRENB		0x0200	/* b9: Transaction counter enable */
 #define M66592_TRCLR		0x0100	/* b8: Transaction counter clear */
 #define M66592_DEZPM		0x0080	/* b7: Zero-length packet mode */
@@ -480,9 +478,11 @@
 struct m66592 {
 	spinlock_t		lock;
 	void __iomem		*reg;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	struct clk *clk;
 #endif
+	struct m66592_platdata	*pdata;
+	unsigned long		irq_trigger;
 
 	struct usb_gadget		gadget;
 	struct usb_gadget_driver	*driver;
@@ -506,7 +506,6 @@
 	int interrupt;
 	int isochronous;
 	int num_dma;
-	int bi_bufnum;	/* bulk and isochronous's bufnum */
 };
 
 #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget)
@@ -547,13 +546,13 @@
 {
 	unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	len = (len + 3) / 4;
-	insl(fifoaddr, buf, len);
-#else
-	len = (len + 1) / 2;
-	insw(fifoaddr, buf, len);
-#endif
+	if (m66592->pdata->on_chip) {
+		len = (len + 3) / 4;
+		insl(fifoaddr, buf, len);
+	} else {
+		len = (len + 1) / 2;
+		insw(fifoaddr, buf, len);
+	}
 }
 
 static inline void m66592_write(struct m66592 *m66592, u16 val,
@@ -567,33 +566,34 @@
 		void *buf, unsigned long len)
 {
 	unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	unsigned long count;
-	unsigned char *pb;
-	int i;
 
-	count = len / 4;
-	outsl(fifoaddr, buf, count);
+	if (m66592->pdata->on_chip) {
+		unsigned long count;
+		unsigned char *pb;
+		int i;
 
-	if (len & 0x00000003) {
-		pb = buf + count * 4;
-		for (i = 0; i < (len & 0x00000003); i++) {
-			if (m66592_read(m66592, M66592_CFBCFG))	/* little */
-				outb(pb[i], fifoaddr + (3 - i));
-			else
-				outb(pb[i], fifoaddr + i);
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			pb = buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (m66592_read(m66592, M66592_CFBCFG))	/* le */
+					outb(pb[i], fifoaddr + (3 - i));
+				else
+					outb(pb[i], fifoaddr + i);
+			}
+		}
+	} else {
+		unsigned long odd = len & 0x0001;
+
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (odd) {
+			unsigned char *p = buf + len*2;
+			outb(*p, fifoaddr);
 		}
 	}
-#else
-	unsigned long odd = len & 0x0001;
-
-	len = len / 2;
-	outsw(fifoaddr, buf, len);
-	if (odd) {
-		unsigned char *p = buf + len*2;
-		outb(*p, fifoaddr);
-	}
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 }
 
 static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
new file mode 100644
index 0000000..e220fb8
--- /dev/null
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -0,0 +1,1689 @@
+/*
+ * R8A66597 UDC (USB gadget)
+ *
+ * Copyright (C) 2006-2009 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.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; 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include "r8a66597-udc.h"
+
+#define DRIVER_VERSION	"2009-08-18"
+
+static const char udc_name[] = "r8a66597_udc";
+static const char *r8a66597_ep_name[] = {
+	"ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7",
+	"ep8", "ep9",
+};
+
+static void disable_controller(struct r8a66597 *r8a66597);
+static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req);
+static void irq_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req);
+static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
+			gfp_t gfp_flags);
+
+static void transfer_complete(struct r8a66597_ep *ep,
+		struct r8a66597_request *req, int status);
+
+/*-------------------------------------------------------------------------*/
+static inline u16 get_usb_speed(struct r8a66597 *r8a66597)
+{
+	return r8a66597_read(r8a66597, DVSTCTR0) & RHST;
+}
+
+static void enable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+		unsigned long reg)
+{
+	u16 tmp;
+
+	tmp = r8a66597_read(r8a66597, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE,
+			INTENB0);
+	r8a66597_bset(r8a66597, (1 << pipenum), reg);
+	r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+static void disable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+		unsigned long reg)
+{
+	u16 tmp;
+
+	tmp = r8a66597_read(r8a66597, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE,
+			INTENB0);
+	r8a66597_bclr(r8a66597, (1 << pipenum), reg);
+	r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+static void r8a66597_usb_connect(struct r8a66597 *r8a66597)
+{
+	r8a66597_bset(r8a66597, CTRE, INTENB0);
+	r8a66597_bset(r8a66597, BEMPE | BRDYE, INTENB0);
+
+	r8a66597_bset(r8a66597, DPRPU, SYSCFG0);
+}
+
+static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	r8a66597_bclr(r8a66597, CTRE, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | BRDYE, INTENB0);
+	r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+
+	r8a66597->gadget.speed = USB_SPEED_UNKNOWN;
+	spin_unlock(&r8a66597->lock);
+	r8a66597->driver->disconnect(&r8a66597->gadget);
+	spin_lock(&r8a66597->lock);
+
+	disable_controller(r8a66597);
+	INIT_LIST_HEAD(&r8a66597->ep[0].queue);
+}
+
+static inline u16 control_reg_get_pid(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 pid = 0;
+	unsigned long offset;
+
+	if (pipenum == 0)
+		pid = r8a66597_read(r8a66597, DCPCTR) & PID;
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		pid = r8a66597_read(r8a66597, offset) & PID;
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+	return pid;
+}
+
+static inline void control_reg_set_pid(struct r8a66597 *r8a66597, u16 pipenum,
+		u16 pid)
+{
+	unsigned long offset;
+
+	if (pipenum == 0)
+		r8a66597_mdfy(r8a66597, pid, PID, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		r8a66597_mdfy(r8a66597, pid, PID, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+}
+
+static inline void pipe_start(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_BUF);
+}
+
+static inline void pipe_stop(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_NAK);
+}
+
+static inline void pipe_stall(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_STALL);
+}
+
+static inline u16 control_reg_get(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 ret = 0;
+	unsigned long offset;
+
+	if (pipenum == 0)
+		ret = r8a66597_read(r8a66597, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		ret = r8a66597_read(r8a66597, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+	return ret;
+}
+
+static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	unsigned long offset;
+
+	pipe_stop(r8a66597, pipenum);
+
+	if (pipenum == 0)
+		r8a66597_bset(r8a66597, SQCLR, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		r8a66597_bset(r8a66597, SQCLR, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum);
+}
+
+static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 tmp;
+	int size;
+
+	if (pipenum == 0) {
+		tmp = r8a66597_read(r8a66597, DCPCFG);
+		if ((tmp & R8A66597_CNTMD) != 0)
+			size = 256;
+		else {
+			tmp = r8a66597_read(r8a66597, DCPMAXP);
+			size = tmp & MAXP;
+		}
+	} else {
+		r8a66597_write(r8a66597, pipenum, PIPESEL);
+		tmp = r8a66597_read(r8a66597, PIPECFG);
+		if ((tmp & R8A66597_CNTMD) != 0) {
+			tmp = r8a66597_read(r8a66597, PIPEBUF);
+			size = ((tmp >> 10) + 1) * 64;
+		} else {
+			tmp = r8a66597_read(r8a66597, PIPEMAXP);
+			size = tmp & MXPS;
+		}
+	}
+
+	return size;
+}
+
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip)
+		return MBW_32;
+	else
+		return MBW_16;
+}
+
+static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum];
+
+	if (ep->use_dma)
+		return;
+
+	r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel);
+
+	ndelay(450);
+
+	r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel);
+}
+
+static int pipe_buffer_setting(struct r8a66597 *r8a66597,
+		struct r8a66597_pipe_info *info)
+{
+	u16 bufnum = 0, buf_bsize = 0;
+	u16 pipecfg = 0;
+
+	if (info->pipe == 0)
+		return -EINVAL;
+
+	r8a66597_write(r8a66597, info->pipe, PIPESEL);
+
+	if (info->dir_in)
+		pipecfg |= R8A66597_DIR;
+	pipecfg |= info->type;
+	pipecfg |= info->epnum;
+	switch (info->type) {
+	case R8A66597_INT:
+		bufnum = 4 + (info->pipe - R8A66597_BASE_PIPENUM_INT);
+		buf_bsize = 0;
+		break;
+	case R8A66597_BULK:
+		/* isochronous pipes may be used as bulk pipes */
+		if (info->pipe > R8A66597_BASE_PIPENUM_BULK)
+			bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK;
+		else
+			bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC;
+
+		bufnum = R8A66597_BASE_BUFNUM + (bufnum * 16);
+		buf_bsize = 7;
+		pipecfg |= R8A66597_DBLB;
+		if (!info->dir_in)
+			pipecfg |= R8A66597_SHTNAK;
+		break;
+	case R8A66597_ISO:
+		bufnum = R8A66597_BASE_BUFNUM +
+			 (info->pipe - R8A66597_BASE_PIPENUM_ISOC) * 16;
+		buf_bsize = 7;
+		break;
+	}
+
+	if (buf_bsize && ((bufnum + 16) >= R8A66597_MAX_BUFNUM)) {
+		pr_err(KERN_ERR "r8a66597 pipe memory is insufficient\n");
+		return -ENOMEM;
+	}
+
+	r8a66597_write(r8a66597, pipecfg, PIPECFG);
+	r8a66597_write(r8a66597, (buf_bsize << 10) | (bufnum), PIPEBUF);
+	r8a66597_write(r8a66597, info->maxpacket, PIPEMAXP);
+	if (info->interval)
+		info->interval--;
+	r8a66597_write(r8a66597, info->interval, PIPEPERI);
+
+	return 0;
+}
+
+static void pipe_buffer_release(struct r8a66597 *r8a66597,
+				struct r8a66597_pipe_info *info)
+{
+	if (info->pipe == 0)
+		return;
+
+	if (is_bulk_pipe(info->pipe))
+		r8a66597->bulk--;
+	else if (is_interrupt_pipe(info->pipe))
+		r8a66597->interrupt--;
+	else if (is_isoc_pipe(info->pipe)) {
+		r8a66597->isochronous--;
+		if (info->type == R8A66597_BULK)
+			r8a66597->bulk--;
+	} else
+		printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n",
+				info->pipe);
+}
+
+static void pipe_initialize(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	r8a66597_mdfy(r8a66597, 0, CURPIPE, ep->fifosel);
+
+	r8a66597_write(r8a66597, ACLRM, ep->pipectr);
+	r8a66597_write(r8a66597, 0, ep->pipectr);
+	r8a66597_write(r8a66597, SQCLR, ep->pipectr);
+	if (ep->use_dma) {
+		r8a66597_mdfy(r8a66597, ep->pipenum, CURPIPE, ep->fifosel);
+
+		ndelay(450);
+
+		r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel);
+	}
+}
+
+static void r8a66597_ep_setting(struct r8a66597 *r8a66597,
+				struct r8a66597_ep *ep,
+				const struct usb_endpoint_descriptor *desc,
+				u16 pipenum, int dma)
+{
+	ep->use_dma = 0;
+	ep->fifoaddr = CFIFO;
+	ep->fifosel = CFIFOSEL;
+	ep->fifoctr = CFIFOCTR;
+	ep->fifotrn = 0;
+
+	ep->pipectr = get_pipectr_addr(pipenum);
+	ep->pipenum = pipenum;
+	ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+	r8a66597->pipenum2ep[pipenum] = ep;
+	r8a66597->epaddr2ep[desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK]
+		= ep;
+	INIT_LIST_HEAD(&ep->queue);
+}
+
+static void r8a66597_ep_release(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 pipenum = ep->pipenum;
+
+	if (pipenum == 0)
+		return;
+
+	if (ep->use_dma)
+		r8a66597->num_dma--;
+	ep->pipenum = 0;
+	ep->busy = 0;
+	ep->use_dma = 0;
+}
+
+static int alloc_pipe_config(struct r8a66597_ep *ep,
+		const struct usb_endpoint_descriptor *desc)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	struct r8a66597_pipe_info info;
+	int dma = 0;
+	unsigned char *counter;
+	int ret;
+
+	ep->desc = desc;
+
+	if (ep->pipenum)	/* already allocated pipe  */
+		return 0;
+
+	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_BULK:
+		if (r8a66597->bulk >= R8A66597_MAX_NUM_BULK) {
+			if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) {
+				printk(KERN_ERR "bulk pipe is insufficient\n");
+				return -ENODEV;
+			} else {
+				info.pipe = R8A66597_BASE_PIPENUM_ISOC
+						+ r8a66597->isochronous;
+				counter = &r8a66597->isochronous;
+			}
+		} else {
+			info.pipe = R8A66597_BASE_PIPENUM_BULK + r8a66597->bulk;
+			counter = &r8a66597->bulk;
+		}
+		info.type = R8A66597_BULK;
+		dma = 1;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		if (r8a66597->interrupt >= R8A66597_MAX_NUM_INT) {
+			printk(KERN_ERR "interrupt pipe is insufficient\n");
+			return -ENODEV;
+		}
+		info.pipe = R8A66597_BASE_PIPENUM_INT + r8a66597->interrupt;
+		info.type = R8A66597_INT;
+		counter = &r8a66597->interrupt;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) {
+			printk(KERN_ERR "isochronous pipe is insufficient\n");
+			return -ENODEV;
+		}
+		info.pipe = R8A66597_BASE_PIPENUM_ISOC + r8a66597->isochronous;
+		info.type = R8A66597_ISO;
+		counter = &r8a66597->isochronous;
+		break;
+	default:
+		printk(KERN_ERR "unexpect xfer type\n");
+		return -EINVAL;
+	}
+	ep->type = info.type;
+
+	info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	info.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+	info.interval = desc->bInterval;
+	if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+		info.dir_in = 1;
+	else
+		info.dir_in = 0;
+
+	ret = pipe_buffer_setting(r8a66597, &info);
+	if (ret < 0) {
+		printk(KERN_ERR "pipe_buffer_setting fail\n");
+		return ret;
+	}
+
+	(*counter)++;
+	if ((counter == &r8a66597->isochronous) && info.type == R8A66597_BULK)
+		r8a66597->bulk++;
+
+	r8a66597_ep_setting(r8a66597, ep, desc, info.pipe, dma);
+	pipe_initialize(ep);
+
+	return 0;
+}
+
+static int free_pipe_config(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	struct r8a66597_pipe_info info;
+
+	info.pipe = ep->pipenum;
+	info.type = ep->type;
+	pipe_buffer_release(r8a66597, &info);
+	r8a66597_ep_release(ep);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void pipe_irq_enable(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	enable_irq_ready(r8a66597, pipenum);
+	enable_irq_nrdy(r8a66597, pipenum);
+}
+
+static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	disable_irq_ready(r8a66597, pipenum);
+	disable_irq_nrdy(r8a66597, pipenum);
+}
+
+/* if complete is true, gadget driver complete function is not call */
+static void control_end(struct r8a66597 *r8a66597, unsigned ccpl)
+{
+	r8a66597->ep[0].internal_ccpl = ccpl;
+	pipe_start(r8a66597, 0);
+	r8a66597_bset(r8a66597, CCPL, DCPCTR);
+}
+
+static void start_ep0_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, ep->pipenum);
+	r8a66597_mdfy(r8a66597, ISEL, (ISEL | CURPIPE), CFIFOSEL);
+	r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+	if (req->req.length == 0) {
+		r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+		pipe_start(r8a66597, 0);
+		transfer_complete(ep, req, 0);
+	} else {
+		r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
+		irq_ep0_write(ep, req);
+	}
+}
+
+static void start_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 tmp;
+
+	pipe_change(r8a66597, ep->pipenum);
+	disable_irq_empty(r8a66597, ep->pipenum);
+	pipe_start(r8a66597, ep->pipenum);
+
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0))
+		pipe_irq_enable(r8a66597, ep->pipenum);
+	else
+		irq_packet_write(ep, req);
+}
+
+static void start_packet_read(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 pipenum = ep->pipenum;
+
+	if (ep->pipenum == 0) {
+		r8a66597_mdfy(r8a66597, 0, (ISEL | CURPIPE), CFIFOSEL);
+		r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+		pipe_start(r8a66597, pipenum);
+		pipe_irq_enable(r8a66597, pipenum);
+	} else {
+		if (ep->use_dma) {
+			r8a66597_bset(r8a66597, TRCLR, ep->fifosel);
+			pipe_change(r8a66597, pipenum);
+			r8a66597_bset(r8a66597, TRENB, ep->fifosel);
+			r8a66597_write(r8a66597,
+				(req->req.length + ep->ep.maxpacket - 1)
+					/ ep->ep.maxpacket,
+				ep->fifotrn);
+		}
+		pipe_start(r8a66597, pipenum);	/* trigger once */
+		pipe_irq_enable(r8a66597, pipenum);
+	}
+}
+
+static void start_packet(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	if (ep->desc->bEndpointAddress & USB_DIR_IN)
+		start_packet_write(ep, req);
+	else
+		start_packet_read(ep, req);
+}
+
+static void start_ep0(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	u16 ctsq;
+
+	ctsq = r8a66597_read(ep->r8a66597, INTSTS0) & CTSQ;
+
+	switch (ctsq) {
+	case CS_RDDS:
+		start_ep0_write(ep, req);
+		break;
+	case CS_WRDS:
+		start_packet_read(ep, req);
+		break;
+
+	case CS_WRND:
+		control_end(ep->r8a66597, 0);
+		break;
+	default:
+		printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq);
+		break;
+	}
+}
+
+static void init_controller(struct r8a66597 *r8a66597)
+{
+	u16 vif = r8a66597->pdata->vif ? LDRV : 0;
+	u16 irq_sense = r8a66597->irq_sense_low ? INTL : 0;
+	u16 endian = r8a66597->pdata->endian ? BIGEND : 0;
+
+	if (r8a66597->pdata->on_chip) {
+		r8a66597_bset(r8a66597, 0x04, SYSCFG1);
+		r8a66597_bset(r8a66597, HSE, SYSCFG0);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+		r8a66597_bset(r8a66597, USBE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, irq_sense, INTENB1);
+		r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR,
+				DMA0CFG);
+	} else {
+		r8a66597_bset(r8a66597, vif | endian, PINCFG);
+		r8a66597_bset(r8a66597, HSE, SYSCFG0);		/* High spd */
+		r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
+				XTAL, SYSCFG0);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+		r8a66597_bset(r8a66597, USBE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+
+		msleep(3);
+
+		r8a66597_bset(r8a66597, PLLC, SYSCFG0);
+
+		msleep(1);
+
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, irq_sense, INTENB1);
+		r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR,
+			       DMA0CFG);
+	}
+}
+
+static void disable_controller(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip) {
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		/* disable interrupts */
+		r8a66597_write(r8a66597, 0, INTENB0);
+		r8a66597_write(r8a66597, 0, INTENB1);
+		r8a66597_write(r8a66597, 0, BRDYENB);
+		r8a66597_write(r8a66597, 0, BEMPENB);
+		r8a66597_write(r8a66597, 0, NRDYENB);
+
+		/* clear status */
+		r8a66597_write(r8a66597, 0, BRDYSTS);
+		r8a66597_write(r8a66597, 0, NRDYSTS);
+		r8a66597_write(r8a66597, 0, BEMPSTS);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+
+	} else {
+		r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+		udelay(1);
+		r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+		udelay(1);
+		udelay(1);
+		r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+	}
+}
+
+static void r8a66597_start_xclock(struct r8a66597 *r8a66597)
+{
+	u16 tmp;
+
+	if (!r8a66597->pdata->on_chip) {
+		tmp = r8a66597_read(r8a66597, SYSCFG0);
+		if (!(tmp & XCKE))
+			r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+	}
+}
+
+static struct r8a66597_request *get_request_from_ep(struct r8a66597_ep *ep)
+{
+	return list_entry(ep->queue.next, struct r8a66597_request, queue);
+}
+
+/*-------------------------------------------------------------------------*/
+static void transfer_complete(struct r8a66597_ep *ep,
+		struct r8a66597_request *req, int status)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	int restart = 0;
+
+	if (unlikely(ep->pipenum == 0)) {
+		if (ep->internal_ccpl) {
+			ep->internal_ccpl = 0;
+			return;
+		}
+	}
+
+	list_del_init(&req->queue);
+	if (ep->r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		req->req.status = -ESHUTDOWN;
+	else
+		req->req.status = status;
+
+	if (!list_empty(&ep->queue))
+		restart = 1;
+
+	spin_unlock(&ep->r8a66597->lock);
+	req->req.complete(&ep->ep, &req->req);
+	spin_lock(&ep->r8a66597->lock);
+
+	if (restart) {
+		req = get_request_from_ep(ep);
+		if (ep->desc)
+			start_packet(ep, req);
+	}
+}
+
+static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	int i;
+	u16 tmp;
+	unsigned bufsize;
+	size_t size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, pipenum);
+	r8a66597_bset(r8a66597, ISEL, ep->fifosel);
+
+	i = 0;
+	do {
+		tmp = r8a66597_read(r8a66597, ep->fifoctr);
+		if (i++ > 100000) {
+			printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus"
+				"conflict. please power off this controller.");
+			return;
+		}
+		ndelay(1);
+	} while ((tmp & FRDY) == 0);
+
+	/* prepare parameters */
+	bufsize = get_buffer_size(r8a66597, pipenum);
+	buf = req->req.buf + req->req.actual;
+	size = min(bufsize, req->req.length - req->req.actual);
+
+	/* write fifo */
+	if (req->req.buf) {
+		if (size > 0)
+			r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size);
+		if ((size == 0) || ((size % ep->ep.maxpacket) != 0))
+			r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+	}
+
+	/* update parameters */
+	req->req.actual += size;
+
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		disable_irq_ready(r8a66597, pipenum);
+		disable_irq_empty(r8a66597, pipenum);
+	} else {
+		disable_irq_ready(r8a66597, pipenum);
+		enable_irq_empty(r8a66597, pipenum);
+	}
+	pipe_start(r8a66597, pipenum);
+}
+
+static void irq_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	u16 tmp;
+	unsigned bufsize;
+	size_t size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, pipenum);
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0)) {
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum);
+		return;
+	}
+
+	/* prepare parameters */
+	bufsize = get_buffer_size(r8a66597, pipenum);
+	buf = req->req.buf + req->req.actual;
+	size = min(bufsize, req->req.length - req->req.actual);
+
+	/* write fifo */
+	if (req->req.buf) {
+		r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size);
+		if ((size == 0)
+				|| ((size % ep->ep.maxpacket) != 0)
+				|| ((bufsize != ep->ep.maxpacket)
+					&& (bufsize > size)))
+			r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+	}
+
+	/* update parameters */
+	req->req.actual += size;
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		disable_irq_ready(r8a66597, pipenum);
+		enable_irq_empty(r8a66597, pipenum);
+	} else {
+		disable_irq_empty(r8a66597, pipenum);
+		pipe_irq_enable(r8a66597, pipenum);
+	}
+}
+
+static void irq_packet_read(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	u16 tmp;
+	int rcv_len, bufsize, req_len;
+	int size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	int finish = 0;
+
+	pipe_change(r8a66597, pipenum);
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0)) {
+		req->req.status = -EPIPE;
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		printk(KERN_ERR "read fifo not ready");
+		return;
+	}
+
+	/* prepare parameters */
+	rcv_len = tmp & DTLN;
+	bufsize = get_buffer_size(r8a66597, pipenum);
+
+	buf = req->req.buf + req->req.actual;
+	req_len = req->req.length - req->req.actual;
+	if (rcv_len < bufsize)
+		size = min(rcv_len, req_len);
+	else
+		size = min(bufsize, req_len);
+
+	/* update parameters */
+	req->req.actual += size;
+
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		finish = 1;
+	}
+
+	/* read fifo */
+	if (req->req.buf) {
+		if (size == 0)
+			r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+		else
+			r8a66597_read_fifo(r8a66597, ep->fifoaddr, buf, size);
+
+	}
+
+	if ((ep->pipenum != 0) && finish)
+		transfer_complete(ep, req, 0);
+}
+
+static void irq_pipe_ready(struct r8a66597 *r8a66597, u16 status, u16 enb)
+{
+	u16 check;
+	u16 pipenum;
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+
+	if ((status & BRDY0) && (enb & BRDY0)) {
+		r8a66597_write(r8a66597, ~BRDY0, BRDYSTS);
+		r8a66597_mdfy(r8a66597, 0, CURPIPE, CFIFOSEL);
+
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		irq_packet_read(ep, req);
+	} else {
+		for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+			check = 1 << pipenum;
+			if ((status & check) && (enb & check)) {
+				r8a66597_write(r8a66597, ~check, BRDYSTS);
+				ep = r8a66597->pipenum2ep[pipenum];
+				req = get_request_from_ep(ep);
+				if (ep->desc->bEndpointAddress & USB_DIR_IN)
+					irq_packet_write(ep, req);
+				else
+					irq_packet_read(ep, req);
+			}
+		}
+	}
+}
+
+static void irq_pipe_empty(struct r8a66597 *r8a66597, u16 status, u16 enb)
+{
+	u16 tmp;
+	u16 check;
+	u16 pipenum;
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+
+	if ((status & BEMP0) && (enb & BEMP0)) {
+		r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
+
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		irq_ep0_write(ep, req);
+	} else {
+		for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+			check = 1 << pipenum;
+			if ((status & check) && (enb & check)) {
+				r8a66597_write(r8a66597, ~check, BEMPSTS);
+				tmp = control_reg_get(r8a66597, pipenum);
+				if ((tmp & INBUFM) == 0) {
+					disable_irq_empty(r8a66597, pipenum);
+					pipe_irq_disable(r8a66597, pipenum);
+					pipe_stop(r8a66597, pipenum);
+					ep = r8a66597->pipenum2ep[pipenum];
+					req = get_request_from_ep(ep);
+					if (!list_empty(&ep->queue))
+						transfer_complete(ep, req, 0);
+				}
+			}
+		}
+	}
+}
+
+static void get_status(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	struct r8a66597_ep *ep;
+	u16 pid;
+	u16 status = 0;
+	u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		status = 1 << USB_DEVICE_SELF_POWERED;
+		break;
+	case USB_RECIP_INTERFACE:
+		status = 0;
+		break;
+	case USB_RECIP_ENDPOINT:
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		pid = control_reg_get_pid(r8a66597, ep->pipenum);
+		if (pid == PID_STALL)
+			status = 1 << USB_ENDPOINT_HALT;
+		else
+			status = 0;
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		return;		/* exit */
+	}
+
+	r8a66597->ep0_data = cpu_to_le16(status);
+	r8a66597->ep0_req->buf = &r8a66597->ep0_data;
+	r8a66597->ep0_req->length = 2;
+	/* AV: what happens if we get called again before that gets through? */
+	spin_unlock(&r8a66597->lock);
+	r8a66597_queue(r8a66597->gadget.ep0, r8a66597->ep0_req, GFP_KERNEL);
+	spin_lock(&r8a66597->lock);
+}
+
+static void clear_feature(struct r8a66597 *r8a66597,
+				struct usb_ctrlrequest *ctrl)
+{
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_INTERFACE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_ENDPOINT: {
+		struct r8a66597_ep *ep;
+		struct r8a66597_request *req;
+		u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		if (!ep->wedge) {
+			pipe_stop(r8a66597, ep->pipenum);
+			control_reg_sqclr(r8a66597, ep->pipenum);
+			spin_unlock(&r8a66597->lock);
+			usb_ep_clear_halt(&ep->ep);
+			spin_lock(&r8a66597->lock);
+		}
+
+		control_end(r8a66597, 1);
+
+		req = get_request_from_ep(ep);
+		if (ep->busy) {
+			ep->busy = 0;
+			if (list_empty(&ep->queue))
+				break;
+			start_packet(ep, req);
+		} else if (!list_empty(&ep->queue))
+			pipe_start(r8a66597, ep->pipenum);
+		}
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		break;
+	}
+}
+
+static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+{
+
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_INTERFACE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_ENDPOINT: {
+		struct r8a66597_ep *ep;
+		u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		pipe_stall(r8a66597, ep->pipenum);
+
+		control_end(r8a66597, 1);
+		}
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		break;
+	}
+}
+
+/* if return value is true, call class driver's setup() */
+static int setup_packet(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+{
+	u16 *p = (u16 *)ctrl;
+	unsigned long offset = USBREQ;
+	int i, ret = 0;
+
+	/* read fifo */
+	r8a66597_write(r8a66597, ~VALID, INTSTS0);
+
+	for (i = 0; i < 4; i++)
+		p[i] = r8a66597_read(r8a66597, offset + i*2);
+
+	/* check request */
+	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+		switch (ctrl->bRequest) {
+		case USB_REQ_GET_STATUS:
+			get_status(r8a66597, ctrl);
+			break;
+		case USB_REQ_CLEAR_FEATURE:
+			clear_feature(r8a66597, ctrl);
+			break;
+		case USB_REQ_SET_FEATURE:
+			set_feature(r8a66597, ctrl);
+			break;
+		default:
+			ret = 1;
+			break;
+		}
+	} else
+		ret = 1;
+	return ret;
+}
+
+static void r8a66597_update_usb_speed(struct r8a66597 *r8a66597)
+{
+	u16 speed = get_usb_speed(r8a66597);
+
+	switch (speed) {
+	case HSMODE:
+		r8a66597->gadget.speed = USB_SPEED_HIGH;
+		break;
+	case FSMODE:
+		r8a66597->gadget.speed = USB_SPEED_FULL;
+		break;
+	default:
+		r8a66597->gadget.speed = USB_SPEED_UNKNOWN;
+		printk(KERN_ERR "USB speed unknown\n");
+	}
+}
+
+static void irq_device_state(struct r8a66597 *r8a66597)
+{
+	u16 dvsq;
+
+	dvsq = r8a66597_read(r8a66597, INTSTS0) & DVSQ;
+	r8a66597_write(r8a66597, ~DVST, INTSTS0);
+
+	if (dvsq == DS_DFLT) {
+		/* bus reset */
+		r8a66597->driver->disconnect(&r8a66597->gadget);
+		r8a66597_update_usb_speed(r8a66597);
+	}
+	if (r8a66597->old_dvsq == DS_CNFG && dvsq != DS_CNFG)
+		r8a66597_update_usb_speed(r8a66597);
+	if ((dvsq == DS_CNFG || dvsq == DS_ADDS)
+			&& r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		r8a66597_update_usb_speed(r8a66597);
+
+	r8a66597->old_dvsq = dvsq;
+}
+
+static void irq_control_stage(struct r8a66597 *r8a66597)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	struct usb_ctrlrequest ctrl;
+	u16 ctsq;
+
+	ctsq = r8a66597_read(r8a66597, INTSTS0) & CTSQ;
+	r8a66597_write(r8a66597, ~CTRT, INTSTS0);
+
+	switch (ctsq) {
+	case CS_IDST: {
+		struct r8a66597_ep *ep;
+		struct r8a66597_request *req;
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		transfer_complete(ep, req, 0);
+		}
+		break;
+
+	case CS_RDDS:
+	case CS_WRDS:
+	case CS_WRND:
+		if (setup_packet(r8a66597, &ctrl)) {
+			spin_unlock(&r8a66597->lock);
+			if (r8a66597->driver->setup(&r8a66597->gadget, &ctrl)
+				< 0)
+				pipe_stall(r8a66597, 0);
+			spin_lock(&r8a66597->lock);
+		}
+		break;
+	case CS_RDSS:
+	case CS_WRSS:
+		control_end(r8a66597, 0);
+		break;
+	default:
+		printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq);
+		break;
+	}
+}
+
+static irqreturn_t r8a66597_irq(int irq, void *_r8a66597)
+{
+	struct r8a66597 *r8a66597 = _r8a66597;
+	u16 intsts0;
+	u16 intenb0;
+	u16 brdysts, nrdysts, bempsts;
+	u16 brdyenb, nrdyenb, bempenb;
+	u16 savepipe;
+	u16 mask0;
+
+	spin_lock(&r8a66597->lock);
+
+	intsts0 = r8a66597_read(r8a66597, INTSTS0);
+	intenb0 = r8a66597_read(r8a66597, INTENB0);
+
+	savepipe = r8a66597_read(r8a66597, CFIFOSEL);
+
+	mask0 = intsts0 & intenb0;
+	if (mask0) {
+		brdysts = r8a66597_read(r8a66597, BRDYSTS);
+		nrdysts = r8a66597_read(r8a66597, NRDYSTS);
+		bempsts = r8a66597_read(r8a66597, BEMPSTS);
+		brdyenb = r8a66597_read(r8a66597, BRDYENB);
+		nrdyenb = r8a66597_read(r8a66597, NRDYENB);
+		bempenb = r8a66597_read(r8a66597, BEMPENB);
+
+		if (mask0 & VBINT) {
+			r8a66597_write(r8a66597,  0xffff & ~VBINT,
+					INTSTS0);
+			r8a66597_start_xclock(r8a66597);
+
+			/* start vbus sampling */
+			r8a66597->old_vbus = r8a66597_read(r8a66597, INTSTS0)
+					& VBSTS;
+			r8a66597->scount = R8A66597_MAX_SAMPLING;
+
+			mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+		}
+		if (intsts0 & DVSQ)
+			irq_device_state(r8a66597);
+
+		if ((intsts0 & BRDY) && (intenb0 & BRDYE)
+				&& (brdysts & brdyenb))
+			irq_pipe_ready(r8a66597, brdysts, brdyenb);
+		if ((intsts0 & BEMP) && (intenb0 & BEMPE)
+				&& (bempsts & bempenb))
+			irq_pipe_empty(r8a66597, bempsts, bempenb);
+
+		if (intsts0 & CTRT)
+			irq_control_stage(r8a66597);
+	}
+
+	r8a66597_write(r8a66597, savepipe, CFIFOSEL);
+
+	spin_unlock(&r8a66597->lock);
+	return IRQ_HANDLED;
+}
+
+static void r8a66597_timer(unsigned long _r8a66597)
+{
+	struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
+	unsigned long flags;
+	u16 tmp;
+
+	spin_lock_irqsave(&r8a66597->lock, flags);
+	tmp = r8a66597_read(r8a66597, SYSCFG0);
+	if (r8a66597->scount > 0) {
+		tmp = r8a66597_read(r8a66597, INTSTS0) & VBSTS;
+		if (tmp == r8a66597->old_vbus) {
+			r8a66597->scount--;
+			if (r8a66597->scount == 0) {
+				if (tmp == VBSTS)
+					r8a66597_usb_connect(r8a66597);
+				else
+					r8a66597_usb_disconnect(r8a66597);
+			} else {
+				mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+			}
+		} else {
+			r8a66597->scount = R8A66597_MAX_SAMPLING;
+			r8a66597->old_vbus = tmp;
+			mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+		}
+	}
+	spin_unlock_irqrestore(&r8a66597->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+static int r8a66597_enable(struct usb_ep *_ep,
+			 const struct usb_endpoint_descriptor *desc)
+{
+	struct r8a66597_ep *ep;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	return alloc_pipe_config(ep, desc);
+}
+
+static int r8a66597_disable(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	BUG_ON(!ep);
+
+	while (!list_empty(&ep->queue)) {
+		req = get_request_from_ep(ep);
+		spin_lock_irqsave(&ep->r8a66597->lock, flags);
+		transfer_complete(ep, req, -ECONNRESET);
+		spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+	}
+
+	pipe_irq_disable(ep->r8a66597, ep->pipenum);
+	return free_pipe_config(ep);
+}
+
+static struct usb_request *r8a66597_alloc_request(struct usb_ep *_ep,
+						gfp_t gfp_flags)
+{
+	struct r8a66597_request *req;
+
+	req = kzalloc(sizeof(struct r8a66597_request), gfp_flags);
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void r8a66597_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct r8a66597_request *req;
+
+	req = container_of(_req, struct r8a66597_request, req);
+	kfree(req);
+}
+
+static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
+			gfp_t gfp_flags)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+	int request = 0;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = container_of(_req, struct r8a66597_request, req);
+
+	if (ep->r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+
+	if (list_empty(&ep->queue))
+		request = 1;
+
+	list_add_tail(&req->queue, &ep->queue);
+	req->req.actual = 0;
+	req->req.status = -EINPROGRESS;
+
+	if (ep->desc == NULL)	/* control */
+		start_ep0(ep, req);
+	else {
+		if (request && !ep->busy)
+			start_packet(ep, req);
+	}
+
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return 0;
+}
+
+static int r8a66597_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = container_of(_req, struct r8a66597_request, req);
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (!list_empty(&ep->queue))
+		transfer_complete(ep, req, -ECONNRESET);
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return 0;
+}
+
+static int r8a66597_set_halt(struct usb_ep *_ep, int value)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+	int ret = 0;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = get_request_from_ep(ep);
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (!list_empty(&ep->queue)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+	if (value) {
+		ep->busy = 1;
+		pipe_stall(ep->r8a66597, ep->pipenum);
+	} else {
+		ep->busy = 0;
+		ep->wedge = 0;
+		pipe_stop(ep->r8a66597, ep->pipenum);
+	}
+
+out:
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+	return ret;
+}
+
+static int r8a66597_set_wedge(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+
+	if (!ep || !ep->desc)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	ep->wedge = 1;
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return usb_ep_set_halt(_ep);
+}
+
+static void r8a66597_fifo_flush(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (list_empty(&ep->queue) && !ep->busy) {
+		pipe_stop(ep->r8a66597, ep->pipenum);
+		r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
+	}
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+}
+
+static struct usb_ep_ops r8a66597_ep_ops = {
+	.enable		= r8a66597_enable,
+	.disable	= r8a66597_disable,
+
+	.alloc_request	= r8a66597_alloc_request,
+	.free_request	= r8a66597_free_request,
+
+	.queue		= r8a66597_queue,
+	.dequeue	= r8a66597_dequeue,
+
+	.set_halt	= r8a66597_set_halt,
+	.set_wedge	= r8a66597_set_wedge,
+	.fifo_flush	= r8a66597_fifo_flush,
+};
+
+/*-------------------------------------------------------------------------*/
+static struct r8a66597 *the_controller;
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+	struct r8a66597 *r8a66597 = the_controller;
+	int retval;
+
+	if (!driver
+			|| driver->speed != USB_SPEED_HIGH
+			|| !driver->bind
+			|| !driver->setup)
+		return -EINVAL;
+	if (!r8a66597)
+		return -ENODEV;
+	if (r8a66597->driver)
+		return -EBUSY;
+
+	/* hook up the driver */
+	driver->driver.bus = NULL;
+	r8a66597->driver = driver;
+	r8a66597->gadget.dev.driver = &driver->driver;
+
+	retval = device_add(&r8a66597->gadget.dev);
+	if (retval) {
+		printk(KERN_ERR "device_add error (%d)\n", retval);
+		goto error;
+	}
+
+	retval = driver->bind(&r8a66597->gadget);
+	if (retval) {
+		printk(KERN_ERR "bind to driver error (%d)\n", retval);
+		device_del(&r8a66597->gadget.dev);
+		goto error;
+	}
+
+	r8a66597_bset(r8a66597, VBSE, INTENB0);
+	if (r8a66597_read(r8a66597, INTSTS0) & VBSTS) {
+		r8a66597_start_xclock(r8a66597);
+		/* start vbus sampling */
+		r8a66597->old_vbus = r8a66597_read(r8a66597,
+					 INTSTS0) & VBSTS;
+		r8a66597->scount = R8A66597_MAX_SAMPLING;
+		mod_timer(&r8a66597->timer, jiffies + msecs_to_jiffies(50));
+	}
+
+	return 0;
+
+error:
+	r8a66597->driver = NULL;
+	r8a66597->gadget.dev.driver = NULL;
+
+	return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+	struct r8a66597 *r8a66597 = the_controller;
+	unsigned long flags;
+
+	if (driver != r8a66597->driver || !driver->unbind)
+		return -EINVAL;
+
+	spin_lock_irqsave(&r8a66597->lock, flags);
+	if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN)
+		r8a66597_usb_disconnect(r8a66597);
+	spin_unlock_irqrestore(&r8a66597->lock, flags);
+
+	r8a66597_bclr(r8a66597, VBSE, INTENB0);
+
+	driver->unbind(&r8a66597->gadget);
+
+	init_controller(r8a66597);
+	disable_controller(r8a66597);
+
+	device_del(&r8a66597->gadget.dev);
+	r8a66597->driver = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/*-------------------------------------------------------------------------*/
+static int r8a66597_get_frame(struct usb_gadget *_gadget)
+{
+	struct r8a66597 *r8a66597 = gadget_to_r8a66597(_gadget);
+	return r8a66597_read(r8a66597, FRMNUM) & 0x03FF;
+}
+
+static struct usb_gadget_ops r8a66597_gadget_ops = {
+	.get_frame		= r8a66597_get_frame,
+};
+
+static int __exit r8a66597_remove(struct platform_device *pdev)
+{
+	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+
+	del_timer_sync(&r8a66597->timer);
+	iounmap((void *)r8a66597->reg);
+	free_irq(platform_get_irq(pdev, 0), r8a66597);
+	r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		clk_disable(r8a66597->clk);
+		clk_put(r8a66597->clk);
+	}
+#endif
+	kfree(r8a66597);
+	return 0;
+}
+
+static void nop_completion(struct usb_ep *ep, struct usb_request *r)
+{
+}
+
+static int __init r8a66597_probe(struct platform_device *pdev)
+{
+#ifdef CONFIG_HAVE_CLK
+	char clk_name[8];
+#endif
+	struct resource *res, *ires;
+	int irq;
+	void __iomem *reg = NULL;
+	struct r8a66597 *r8a66597 = NULL;
+	int ret = 0;
+	int i;
+	unsigned long irq_trigger;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		printk(KERN_ERR "platform_get_resource error.\n");
+		goto clean_up;
+	}
+
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	irq = ires->start;
+	irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
+	if (irq < 0) {
+		ret = -ENODEV;
+		printk(KERN_ERR "platform_get_irq error.\n");
+		goto clean_up;
+	}
+
+	reg = ioremap(res->start, resource_size(res));
+	if (reg == NULL) {
+		ret = -ENOMEM;
+		printk(KERN_ERR "ioremap error.\n");
+		goto clean_up;
+	}
+
+	/* initialize ucd */
+	r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
+	if (r8a66597 == NULL) {
+		printk(KERN_ERR "kzalloc error\n");
+		goto clean_up;
+	}
+
+	spin_lock_init(&r8a66597->lock);
+	dev_set_drvdata(&pdev->dev, r8a66597);
+	r8a66597->pdata = pdev->dev.platform_data;
+	r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
+
+	r8a66597->gadget.ops = &r8a66597_gadget_ops;
+	device_initialize(&r8a66597->gadget.dev);
+	dev_set_name(&r8a66597->gadget.dev, "gadget");
+	r8a66597->gadget.is_dualspeed = 1;
+	r8a66597->gadget.dev.parent = &pdev->dev;
+	r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
+	r8a66597->gadget.dev.release = pdev->dev.release;
+	r8a66597->gadget.name = udc_name;
+
+	init_timer(&r8a66597->timer);
+	r8a66597->timer.function = r8a66597_timer;
+	r8a66597->timer.data = (unsigned long)r8a66597;
+	r8a66597->reg = (unsigned long)reg;
+
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
+		r8a66597->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(r8a66597->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(r8a66597->clk);
+			goto clean_up;
+		}
+		clk_enable(r8a66597->clk);
+	}
+#endif
+
+	disable_controller(r8a66597); /* make sure controller is disabled */
+
+	ret = request_irq(irq, r8a66597_irq, IRQF_DISABLED | IRQF_SHARED,
+			udc_name, r8a66597);
+	if (ret < 0) {
+		printk(KERN_ERR "request_irq error (%d)\n", ret);
+		goto clean_up2;
+	}
+
+	INIT_LIST_HEAD(&r8a66597->gadget.ep_list);
+	r8a66597->gadget.ep0 = &r8a66597->ep[0].ep;
+	INIT_LIST_HEAD(&r8a66597->gadget.ep0->ep_list);
+	for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) {
+		struct r8a66597_ep *ep = &r8a66597->ep[i];
+
+		if (i != 0) {
+			INIT_LIST_HEAD(&r8a66597->ep[i].ep.ep_list);
+			list_add_tail(&r8a66597->ep[i].ep.ep_list,
+					&r8a66597->gadget.ep_list);
+		}
+		ep->r8a66597 = r8a66597;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->ep.name = r8a66597_ep_name[i];
+		ep->ep.ops = &r8a66597_ep_ops;
+		ep->ep.maxpacket = 512;
+	}
+	r8a66597->ep[0].ep.maxpacket = 64;
+	r8a66597->ep[0].pipenum = 0;
+	r8a66597->ep[0].fifoaddr = CFIFO;
+	r8a66597->ep[0].fifosel = CFIFOSEL;
+	r8a66597->ep[0].fifoctr = CFIFOCTR;
+	r8a66597->ep[0].fifotrn = 0;
+	r8a66597->ep[0].pipectr = get_pipectr_addr(0);
+	r8a66597->pipenum2ep[0] = &r8a66597->ep[0];
+	r8a66597->epaddr2ep[0] = &r8a66597->ep[0];
+
+	the_controller = r8a66597;
+
+	r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep,
+							GFP_KERNEL);
+	if (r8a66597->ep0_req == NULL)
+		goto clean_up3;
+	r8a66597->ep0_req->complete = nop_completion;
+
+	init_controller(r8a66597);
+
+	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
+	return 0;
+
+clean_up3:
+	free_irq(irq, r8a66597);
+clean_up2:
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		clk_disable(r8a66597->clk);
+		clk_put(r8a66597->clk);
+	}
+#endif
+clean_up:
+	if (r8a66597) {
+		if (r8a66597->ep0_req)
+			r8a66597_free_request(&r8a66597->ep[0].ep,
+						r8a66597->ep0_req);
+		kfree(r8a66597);
+	}
+	if (reg)
+		iounmap(reg);
+
+	return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct platform_driver r8a66597_driver = {
+	.remove =	__exit_p(r8a66597_remove),
+	.driver		= {
+		.name =	(char *) udc_name,
+	},
+};
+
+static int __init r8a66597_udc_init(void)
+{
+	return platform_driver_probe(&r8a66597_driver, r8a66597_probe);
+}
+module_init(r8a66597_udc_init);
+
+static void __exit r8a66597_udc_cleanup(void)
+{
+	platform_driver_unregister(&r8a66597_driver);
+}
+module_exit(r8a66597_udc_cleanup);
+
+MODULE_DESCRIPTION("R8A66597 USB gadget driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yoshihiro Shimoda");
+
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
new file mode 100644
index 0000000..03087e7
--- /dev/null
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -0,0 +1,256 @@
+/*
+ * R8A66597 UDC
+ *
+ * Copyright (C) 2007-2009 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.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; 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __R8A66597_H__
+#define __R8A66597_H__
+
+#ifdef CONFIG_HAVE_CLK
+#include <linux/clk.h>
+#endif
+
+#include <linux/usb/r8a66597.h>
+
+#define R8A66597_MAX_SAMPLING	10
+
+#define R8A66597_MAX_NUM_PIPE	8
+#define R8A66597_MAX_NUM_BULK	3
+#define R8A66597_MAX_NUM_ISOC	2
+#define R8A66597_MAX_NUM_INT	2
+
+#define R8A66597_BASE_PIPENUM_BULK	3
+#define R8A66597_BASE_PIPENUM_ISOC	1
+#define R8A66597_BASE_PIPENUM_INT	6
+
+#define R8A66597_BASE_BUFNUM	6
+#define R8A66597_MAX_BUFNUM	0x4F
+
+#define is_bulk_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
+#define is_interrupt_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
+#define is_isoc_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
+
+struct r8a66597_pipe_info {
+	u16	pipe;
+	u16	epnum;
+	u16	maxpacket;
+	u16	type;
+	u16	interval;
+	u16	dir_in;
+};
+
+struct r8a66597_request {
+	struct usb_request	req;
+	struct list_head	queue;
+};
+
+struct r8a66597_ep {
+	struct usb_ep		ep;
+	struct r8a66597		*r8a66597;
+
+	struct list_head	queue;
+	unsigned		busy:1;
+	unsigned		wedge:1;
+	unsigned		internal_ccpl:1;	/* use only control */
+
+	/* this member can able to after r8a66597_enable */
+	unsigned		use_dma:1;
+	u16			pipenum;
+	u16			type;
+	const struct usb_endpoint_descriptor	*desc;
+	/* register address */
+	unsigned char		fifoaddr;
+	unsigned char		fifosel;
+	unsigned char		fifoctr;
+	unsigned char		fifotrn;
+	unsigned char		pipectr;
+};
+
+struct r8a66597 {
+	spinlock_t		lock;
+	unsigned long		reg;
+
+#ifdef CONFIG_HAVE_CLK
+	struct clk *clk;
+#endif
+	struct r8a66597_platdata	*pdata;
+
+	struct usb_gadget		gadget;
+	struct usb_gadget_driver	*driver;
+
+	struct r8a66597_ep	ep[R8A66597_MAX_NUM_PIPE];
+	struct r8a66597_ep	*pipenum2ep[R8A66597_MAX_NUM_PIPE];
+	struct r8a66597_ep	*epaddr2ep[16];
+
+	struct timer_list	timer;
+	struct usb_request	*ep0_req;	/* for internal request */
+	u16			ep0_data;	/* for internal request */
+	u16			old_vbus;
+	u16			scount;
+	u16			old_dvsq;
+
+	/* pipe config */
+	unsigned char bulk;
+	unsigned char interrupt;
+	unsigned char isochronous;
+	unsigned char num_dma;
+
+	unsigned irq_sense_low:1;
+};
+
+#define gadget_to_r8a66597(_gadget)	\
+		container_of(_gadget, struct r8a66597, gadget)
+#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
+
+static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
+{
+	return inw(r8a66597->reg + offset);
+}
+
+static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
+				      unsigned long offset, u16 *buf,
+				      int len)
+{
+	if (r8a66597->pdata->on_chip) {
+		unsigned long fifoaddr = r8a66597->reg + offset;
+		unsigned long count;
+		union {
+			unsigned long dword;
+			unsigned char byte[4];
+		} data;
+		unsigned char *pb;
+		int i;
+
+		count = len / 4;
+		insl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			data.dword = inl(fifoaddr);
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++)
+				pb[i] = data.byte[i];
+		}
+	} else {
+		len = (len + 1) / 2;
+		insw(r8a66597->reg + offset, buf, len);
+	}
+}
+
+static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
+				  unsigned long offset)
+{
+	outw(val, r8a66597->reg + offset);
+}
+
+static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
+				       unsigned long offset, u16 *buf,
+				       int len)
+{
+	unsigned long fifoaddr = r8a66597->reg + offset;
+
+	if (r8a66597->pdata->on_chip) {
+		unsigned long count;
+		unsigned char *pb;
+		int i;
+
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
+					outb(pb[i], fifoaddr + i);
+				else
+					outb(pb[i], fifoaddr + 3 - i);
+			}
+		}
+	} else {
+		int odd = len & 0x0001;
+
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (unlikely(odd)) {
+			buf = &buf[len];
+			outb((unsigned char)*buf, fifoaddr);
+		}
+	}
+}
+
+static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
+				 u16 val, u16 pat, unsigned long offset)
+{
+	u16 tmp;
+	tmp = r8a66597_read(r8a66597, offset);
+	tmp = tmp & (~pat);
+	tmp = tmp | val;
+	r8a66597_write(r8a66597, tmp, offset);
+}
+
+static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
+{
+	u16 clock = 0;
+
+	switch (pdata->xtal) {
+	case R8A66597_PLATDATA_XTAL_12MHZ:
+		clock = XTAL12;
+		break;
+	case R8A66597_PLATDATA_XTAL_24MHZ:
+		clock = XTAL24;
+		break;
+	case R8A66597_PLATDATA_XTAL_48MHZ:
+		clock = XTAL48;
+		break;
+	default:
+		printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
+		break;
+	}
+
+	return clock;
+}
+
+#define r8a66597_bclr(r8a66597, val, offset)	\
+			r8a66597_mdfy(r8a66597, 0, val, offset)
+#define r8a66597_bset(r8a66597, val, offset)	\
+			r8a66597_mdfy(r8a66597, val, 0, offset)
+
+#define get_pipectr_addr(pipenum)	(PIPE1CTR + (pipenum - 1) * 2)
+
+#define enable_irq_ready(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define disable_irq_ready(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define enable_irq_empty(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define disable_irq_empty(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define enable_irq_nrdy(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, NRDYENB)
+#define disable_irq_nrdy(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, NRDYENB)
+
+#endif	/* __R8A66597_H__ */
+
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1a920c7..f21ca7d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -336,13 +336,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called r8a66597-hcd.
 
-config SUPERH_ON_CHIP_R8A66597
-	boolean "Enable SuperH on-chip R8A66597 USB"
-	depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
-	help
-	   This driver enables support for the on-chip R8A66597 in the
-	   SH7366, SH7723 and SH7724 processors.
-
 config USB_WHCI_HCD
 	tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index e18f749..749b537 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -91,43 +91,43 @@
 	u16 tmp;
 	int i = 0;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-	clk_enable(r8a66597->clk);
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		clk_enable(r8a66597->clk);
 #endif
-	do {
-		r8a66597_write(r8a66597, SCKE, SYSCFG0);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 1000) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & SCKE) != SCKE);
-	r8a66597_write(r8a66597, 0x04, 0x02);
-#else
-	do {
-		r8a66597_write(r8a66597, USBE, SYSCFG0);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 1000) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & USBE) != USBE);
-	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
-	r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
-			SYSCFG0);
+		do {
+			r8a66597_write(r8a66597, SCKE, SYSCFG0);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 1000) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & SCKE) != SCKE);
+		r8a66597_write(r8a66597, 0x04, 0x02);
+	} else {
+		do {
+			r8a66597_write(r8a66597, USBE, SYSCFG0);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 1000) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & USBE) != USBE);
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
+			      XTAL, SYSCFG0);
 
-	i = 0;
-	r8a66597_bset(r8a66597, XCKE, SYSCFG0);
-	do {
-		msleep(1);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 500) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & SCKE) != SCKE);
-#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
+		i = 0;
+		r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+		do {
+			msleep(1);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 500) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & SCKE) != SCKE);
+	}
 
 	return 0;
 }
@@ -136,15 +136,16 @@
 {
 	r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
 	udelay(1);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-	clk_disable(r8a66597->clk);
+
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		clk_disable(r8a66597->clk);
 #endif
-#else
-	r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
-	r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
-	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
-#endif
+	} else {
+		r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+		r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+	}
 }
 
 static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
@@ -205,7 +206,7 @@
 
 	r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_enable_port(r8a66597, port);
 
 	return 0;
@@ -218,7 +219,7 @@
 	r8a66597_write(r8a66597, 0, INTENB0);
 	r8a66597_write(r8a66597, 0, INTSTS0);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_disable_port(r8a66597, port);
 
 	r8a66597_clock_disable(r8a66597);
@@ -249,11 +250,12 @@
 	return ((strlen(devpath) >= 4) ? 1 : 0);
 }
 
-static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
+static void get_port_number(struct r8a66597 *r8a66597,
+			    char *devpath, u16 *root_port, u16 *hub_port)
 {
 	if (root_port) {
 		*root_port = (devpath[0] & 0x0F) - 1;
-		if (*root_port >= R8A66597_MAX_ROOT_HUB)
+		if (*root_port >= r8a66597->max_root_hub)
 			printk(KERN_ERR "r8a66597: Illegal root port number.\n");
 	}
 	if (hub_port)
@@ -355,7 +357,8 @@
 	INIT_LIST_HEAD(&dev->device_list);
 	list_add_tail(&dev->device_list, &r8a66597->child_device);
 
-	get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
+	get_port_number(r8a66597, urb->dev->devpath,
+			&dev->root_port, &dev->hub_port);
 	if (!is_child_device(urb->dev->devpath))
 		r8a66597->root_hub[dev->root_port].dev = dev;
 
@@ -420,7 +423,7 @@
 	list_del(&dev->device_list);
 	kfree(dev);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		if (r8a66597->root_hub[port].dev == dev) {
 			r8a66597->root_hub[port].dev = NULL;
 			break;
@@ -495,10 +498,20 @@
 		r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
 }
 
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip)
+		return MBW_32;
+	else
+		return MBW_16;
+}
+
 /* this function must be called with interrupt disabled */
 static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
 {
-	r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
+	unsigned short mbw = mbw_value(r8a66597);
+
+	r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
 	r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
 }
 
@@ -506,11 +519,13 @@
 static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
 					 struct r8a66597_pipe *pipe)
 {
-	cfifo_change(r8a66597, 0);
-	r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
-	r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
+	unsigned short mbw = mbw_value(r8a66597);
 
-	r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
+	cfifo_change(r8a66597, 0);
+	r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
+	r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
+
+	r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
 		      pipe->fifosel);
 	r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
 }
@@ -742,9 +757,13 @@
 				     struct r8a66597_pipe *pipe,
 				     struct urb *urb)
 {
-#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	int i;
 	struct r8a66597_pipe_info *info = &pipe->info;
+	unsigned short mbw = mbw_value(r8a66597);
+
+	/* pipe dma is only for external controlles */
+	if (r8a66597->pdata->on_chip)
+		return;
 
 	if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
 		for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
@@ -763,8 +782,8 @@
 			set_pipe_reg_addr(pipe, i);
 
 			cfifo_change(r8a66597, 0);
-			r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
-				      MBW | CURPIPE, pipe->fifosel);
+			r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
+				      mbw | CURPIPE, pipe->fifosel);
 
 			r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
 					  pipe->info.pipenum);
@@ -772,7 +791,6 @@
 			break;
 		}
 	}
-#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
 }
 
 /* this function must be called with interrupt disabled */
@@ -1769,7 +1787,7 @@
 
 	spin_lock_irqsave(&r8a66597->lock, flags);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_root_hub_control(r8a66597, port);
 
 	spin_unlock_irqrestore(&r8a66597->lock, flags);
@@ -1807,7 +1825,7 @@
 	u16 root_port, hub_port;
 
 	if (usb_address == 0) {
-		get_port_number(urb->dev->devpath,
+		get_port_number(r8a66597, urb->dev->devpath,
 				&root_port, &hub_port);
 		set_devadd_reg(r8a66597, 0,
 			       get_r8a66597_usb_speed(urb->dev->speed),
@@ -2082,7 +2100,7 @@
 
 	*buf = 0;	/* initialize (no change) */
 
-	for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
+	for (i = 0; i < r8a66597->max_root_hub; i++) {
 		if (r8a66597->root_hub[i].port & 0xffff0000)
 			*buf |= 1 << (i + 1);
 	}
@@ -2097,11 +2115,11 @@
 {
 	desc->bDescriptorType = 0x29;
 	desc->bHubContrCurrent = 0;
-	desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
+	desc->bNbrPorts = r8a66597->max_root_hub;
 	desc->bDescLength = 9;
 	desc->bPwrOn2PwrGood = 0;
 	desc->wHubCharacteristics = cpu_to_le16(0x0011);
-	desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
+	desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
 	desc->bitmap[1] = ~0;
 }
 
@@ -2129,7 +2147,7 @@
 		}
 		break;
 	case ClearPortFeature:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		if (wLength != 0)
 			goto error;
@@ -2162,12 +2180,12 @@
 		*buf = 0x00;
 		break;
 	case GetPortStatus:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		*(__le32 *)buf = cpu_to_le32(rh->port);
 		break;
 	case SetPortFeature:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		if (wLength != 0)
 			goto error;
@@ -2216,7 +2234,7 @@
 
 	dbg("%s", __func__);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 		unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2247,7 +2265,7 @@
 
 	dbg("%s", __func__);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 		unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2305,16 +2323,16 @@
 };
 
 #if defined(CONFIG_PM)
-static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
+static int r8a66597_suspend(struct device *dev)
 {
-	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	int port;
 
 	dbg("%s", __func__);
 
 	disable_controller(r8a66597);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 
 		rh->port = 0x00000000;
@@ -2323,9 +2341,9 @@
 	return 0;
 }
 
-static int r8a66597_resume(struct platform_device *pdev)
+static int r8a66597_resume(struct device *dev)
 {
-	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	struct usb_hcd		*hcd = r8a66597_to_hcd(r8a66597);
 
 	dbg("%s", __func__);
@@ -2335,9 +2353,17 @@
 
 	return 0;
 }
+
+static struct dev_pm_ops r8a66597_dev_pm_ops = {
+	.suspend = r8a66597_suspend,
+	.resume = r8a66597_resume,
+	.poweroff = r8a66597_suspend,
+	.restore = r8a66597_resume,
+};
+
+#define R8A66597_DEV_PM_OPS	(&r8a66597_dev_pm_ops)
 #else	/* if defined(CONFIG_PM) */
-#define r8a66597_suspend	NULL
-#define r8a66597_resume		NULL
+#define R8A66597_DEV_PM_OPS	NULL
 #endif
 
 static int __init_or_module r8a66597_remove(struct platform_device *pdev)
@@ -2348,8 +2374,9 @@
 	del_timer_sync(&r8a66597->rh_timer);
 	usb_remove_hcd(hcd);
 	iounmap((void *)r8a66597->reg);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip)
+		clk_put(r8a66597->clk);
 #endif
 	usb_put_hcd(hcd);
 	return 0;
@@ -2357,7 +2384,7 @@
 
 static int __devinit r8a66597_probe(struct platform_device *pdev)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	char clk_name[8];
 #endif
 	struct resource *res = NULL, *ires;
@@ -2419,15 +2446,20 @@
 	r8a66597->pdata = pdev->dev.platform_data;
 	r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
-	r8a66597->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(r8a66597->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(r8a66597->clk);
-		goto clean_up2;
-	}
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
+		r8a66597->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(r8a66597->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(r8a66597->clk);
+			goto clean_up2;
+		}
 #endif
+		r8a66597->max_root_hub = 1;
+	} else
+		r8a66597->max_root_hub = 2;
 
 	spin_lock_init(&r8a66597->lock);
 	init_timer(&r8a66597->rh_timer);
@@ -2457,8 +2489,9 @@
 	return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip)
+		clk_put(r8a66597->clk);
 clean_up2:
 #endif
 	usb_put_hcd(hcd);
@@ -2473,11 +2506,10 @@
 static struct platform_driver r8a66597_driver = {
 	.probe =	r8a66597_probe,
 	.remove =	r8a66597_remove,
-	.suspend =	r8a66597_suspend,
-	.resume =	r8a66597_resume,
 	.driver		= {
 		.name = (char *) hcd_name,
 		.owner	= THIS_MODULE,
+		.pm	= R8A66597_DEV_PM_OPS,
 	},
 };
 
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index d72680b4..228e3fb 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -26,390 +26,16 @@
 #ifndef __R8A66597_H__
 #define __R8A66597_H__
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
 #include <linux/usb/r8a66597.h>
 
-#define SYSCFG0		0x00
-#define SYSCFG1		0x02
-#define SYSSTS0		0x04
-#define SYSSTS1		0x06
-#define DVSTCTR0	0x08
-#define DVSTCTR1	0x0A
-#define TESTMODE	0x0C
-#define PINCFG		0x0E
-#define DMA0CFG		0x10
-#define DMA1CFG		0x12
-#define CFIFO		0x14
-#define D0FIFO		0x18
-#define D1FIFO		0x1C
-#define CFIFOSEL	0x20
-#define CFIFOCTR	0x22
-#define CFIFOSIE	0x24
-#define D0FIFOSEL	0x28
-#define D0FIFOCTR	0x2A
-#define D1FIFOSEL	0x2C
-#define D1FIFOCTR	0x2E
-#define INTENB0		0x30
-#define INTENB1		0x32
-#define INTENB2		0x34
-#define BRDYENB		0x36
-#define NRDYENB		0x38
-#define BEMPENB		0x3A
-#define SOFCFG		0x3C
-#define INTSTS0		0x40
-#define INTSTS1		0x42
-#define INTSTS2		0x44
-#define BRDYSTS		0x46
-#define NRDYSTS		0x48
-#define BEMPSTS		0x4A
-#define FRMNUM		0x4C
-#define UFRMNUM		0x4E
-#define USBADDR		0x50
-#define USBREQ		0x54
-#define USBVAL		0x56
-#define USBINDX		0x58
-#define USBLENG		0x5A
-#define DCPCFG		0x5C
-#define DCPMAXP		0x5E
-#define DCPCTR		0x60
-#define PIPESEL		0x64
-#define PIPECFG		0x68
-#define PIPEBUF		0x6A
-#define PIPEMAXP	0x6C
-#define PIPEPERI	0x6E
-#define PIPE1CTR	0x70
-#define PIPE2CTR	0x72
-#define PIPE3CTR	0x74
-#define PIPE4CTR	0x76
-#define PIPE5CTR	0x78
-#define PIPE6CTR	0x7A
-#define PIPE7CTR	0x7C
-#define PIPE8CTR	0x7E
-#define PIPE9CTR	0x80
-#define PIPE1TRE	0x90
-#define PIPE1TRN	0x92
-#define PIPE2TRE	0x94
-#define PIPE2TRN	0x96
-#define PIPE3TRE	0x98
-#define PIPE3TRN	0x9A
-#define PIPE4TRE	0x9C
-#define	PIPE4TRN	0x9E
-#define	PIPE5TRE	0xA0
-#define	PIPE5TRN	0xA2
-#define DEVADD0		0xD0
-#define DEVADD1		0xD2
-#define DEVADD2		0xD4
-#define DEVADD3		0xD6
-#define DEVADD4		0xD8
-#define DEVADD5		0xDA
-#define DEVADD6		0xDC
-#define DEVADD7		0xDE
-#define DEVADD8		0xE0
-#define DEVADD9		0xE2
-#define DEVADDA		0xE4
-
-/* System Configuration Control Register */
-#define	XTAL		0xC000	/* b15-14: Crystal selection */
-#define	  XTAL48	 0x8000	  /* 48MHz */
-#define	  XTAL24	 0x4000	  /* 24MHz */
-#define	  XTAL12	 0x0000	  /* 12MHz */
-#define	XCKE		0x2000	/* b13: External clock enable */
-#define	PLLC		0x0800	/* b11: PLL control */
-#define	SCKE		0x0400	/* b10: USB clock enable */
-#define	PCSDIS		0x0200	/* b9: not CS wakeup */
-#define	LPSME		0x0100	/* b8: Low power sleep mode */
-#define	HSE		0x0080	/* b7: Hi-speed enable */
-#define	DCFM		0x0040	/* b6: Controller function select  */
-#define	DRPD		0x0020	/* b5: D+/- pull down control */
-#define	DPRPU		0x0010	/* b4: D+ pull up control */
-#define	USBE		0x0001	/* b0: USB module operation enable */
-
-/* System Configuration Status Register */
-#define	OVCBIT		0x8000	/* b15-14: Over-current bit */
-#define	OVCMON		0xC000	/* b15-14: Over-current monitor */
-#define	SOFEA		0x0020	/* b5: SOF monitor */
-#define	IDMON		0x0004	/* b3: ID-pin monitor */
-#define	LNST		0x0003	/* b1-0: D+, D- line status */
-#define	  SE1		 0x0003	  /* SE1 */
-#define	  FS_KSTS	 0x0002	  /* Full-Speed K State */
-#define	  FS_JSTS	 0x0001	  /* Full-Speed J State */
-#define	  LS_JSTS	 0x0002	  /* Low-Speed J State */
-#define	  LS_KSTS	 0x0001	  /* Low-Speed K State */
-#define	  SE0		 0x0000	  /* SE0 */
-
-/* Device State Control Register */
-#define	EXTLP0		0x0400	/* b10: External port */
-#define	VBOUT		0x0200	/* b9: VBUS output */
-#define	WKUP		0x0100	/* b8: Remote wakeup */
-#define	RWUPE		0x0080	/* b7: Remote wakeup sense */
-#define	USBRST		0x0040	/* b6: USB reset enable */
-#define	RESUME		0x0020	/* b5: Resume enable */
-#define	UACT		0x0010	/* b4: USB bus enable */
-#define	RHST		0x0007	/* b1-0: Reset handshake status */
-#define	  HSPROC	 0x0004	  /* HS handshake is processing */
-#define	  HSMODE	 0x0003	  /* Hi-Speed mode */
-#define	  FSMODE	 0x0002	  /* Full-Speed mode */
-#define	  LSMODE	 0x0001	  /* Low-Speed mode */
-#define	  UNDECID	 0x0000	  /* Undecided */
-
-/* Test Mode Register */
-#define	UTST			0x000F	/* b3-0: Test select */
-#define	  H_TST_PACKET		 0x000C	  /* HOST TEST Packet */
-#define	  H_TST_SE0_NAK		 0x000B	  /* HOST TEST SE0 NAK */
-#define	  H_TST_K		 0x000A	  /* HOST TEST K */
-#define	  H_TST_J		 0x0009	  /* HOST TEST J */
-#define	  H_TST_NORMAL		 0x0000	  /* HOST Normal Mode */
-#define	  P_TST_PACKET		 0x0004	  /* PERI TEST Packet */
-#define	  P_TST_SE0_NAK		 0x0003	  /* PERI TEST SE0 NAK */
-#define	  P_TST_K		 0x0002	  /* PERI TEST K */
-#define	  P_TST_J		 0x0001	  /* PERI TEST J */
-#define	  P_TST_NORMAL		 0x0000	  /* PERI Normal Mode */
-
-/* Data Pin Configuration Register */
-#define	LDRV			0x8000	/* b15: Drive Current Adjust */
-#define	  VIF1			  0x0000		/* VIF = 1.8V */
-#define	  VIF3			  0x8000		/* VIF = 3.3V */
-#define	INTA			0x0001	/* b1: USB INT-pin active */
-
-/* DMAx Pin Configuration Register */
-#define	DREQA			0x4000	/* b14: Dreq active select */
-#define	BURST			0x2000	/* b13: Burst mode */
-#define	DACKA			0x0400	/* b10: Dack active select */
-#define	DFORM			0x0380	/* b9-7: DMA mode select */
-#define	  CPU_ADR_RD_WR		 0x0000	  /* Address + RD/WR mode (CPU bus) */
-#define	  CPU_DACK_RD_WR	 0x0100	  /* DACK + RD/WR mode (CPU bus) */
-#define	  CPU_DACK_ONLY		 0x0180	  /* DACK only mode (CPU bus) */
-#define	  SPLIT_DACK_ONLY	 0x0200	  /* DACK only mode (SPLIT bus) */
-#define	DENDA			0x0040	/* b6: Dend active select */
-#define	PKTM			0x0020	/* b5: Packet mode */
-#define	DENDE			0x0010	/* b4: Dend enable */
-#define	OBUS			0x0004	/* b2: OUTbus mode */
-
-/* CFIFO/DxFIFO Port Select Register */
-#define	RCNT		0x8000	/* b15: Read count mode */
-#define	REW		0x4000	/* b14: Buffer rewind */
-#define	DCLRM		0x2000	/* b13: DMA buffer clear mode */
-#define	DREQE		0x1000	/* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define	MBW		0x0800
-#else
-#define	MBW		0x0400	/* b10: Maximum bit width for FIFO access */
-#endif
-#define	  MBW_8		 0x0000	  /*  8bit */
-#define	  MBW_16	 0x0400	  /* 16bit */
-#define	BIGEND		0x0100	/* b8: Big endian mode */
-#define	  BYTE_LITTLE	 0x0000		/* little dendian */
-#define	  BYTE_BIG	 0x0100		/* big endifan */
-#define	ISEL		0x0020	/* b5: DCP FIFO port direction select */
-#define	CURPIPE		0x000F	/* b2-0: PIPE select */
-
-/* CFIFO/DxFIFO Port Control Register */
-#define	BVAL		0x8000	/* b15: Buffer valid flag */
-#define	BCLR		0x4000	/* b14: Buffer clear */
-#define	FRDY		0x2000	/* b13: FIFO ready */
-#define	DTLN		0x0FFF	/* b11-0: FIFO received data length */
-
-/* Interrupt Enable Register 0 */
-#define	VBSE	0x8000	/* b15: VBUS interrupt */
-#define	RSME	0x4000	/* b14: Resume interrupt */
-#define	SOFE	0x2000	/* b13: Frame update interrupt */
-#define	DVSE	0x1000	/* b12: Device state transition interrupt */
-#define	CTRE	0x0800	/* b11: Control transfer stage transition interrupt */
-#define	BEMPE	0x0400	/* b10: Buffer empty interrupt */
-#define	NRDYE	0x0200	/* b9: Buffer not ready interrupt */
-#define	BRDYE	0x0100	/* b8: Buffer ready interrupt */
-
-/* Interrupt Enable Register 1 */
-#define	OVRCRE		0x8000	/* b15: Over-current interrupt */
-#define	BCHGE		0x4000	/* b14: USB us chenge interrupt */
-#define	DTCHE		0x1000	/* b12: Detach sense interrupt */
-#define	ATTCHE		0x0800	/* b11: Attach sense interrupt */
-#define	EOFERRE		0x0040	/* b6: EOF error interrupt */
-#define	SIGNE		0x0020	/* b5: SETUP IGNORE interrupt */
-#define	SACKE		0x0010	/* b4: SETUP ACK interrupt */
-
-/* BRDY Interrupt Enable/Status Register */
-#define	BRDY9		0x0200	/* b9: PIPE9 */
-#define	BRDY8		0x0100	/* b8: PIPE8 */
-#define	BRDY7		0x0080	/* b7: PIPE7 */
-#define	BRDY6		0x0040	/* b6: PIPE6 */
-#define	BRDY5		0x0020	/* b5: PIPE5 */
-#define	BRDY4		0x0010	/* b4: PIPE4 */
-#define	BRDY3		0x0008	/* b3: PIPE3 */
-#define	BRDY2		0x0004	/* b2: PIPE2 */
-#define	BRDY1		0x0002	/* b1: PIPE1 */
-#define	BRDY0		0x0001	/* b1: PIPE0 */
-
-/* NRDY Interrupt Enable/Status Register */
-#define	NRDY9		0x0200	/* b9: PIPE9 */
-#define	NRDY8		0x0100	/* b8: PIPE8 */
-#define	NRDY7		0x0080	/* b7: PIPE7 */
-#define	NRDY6		0x0040	/* b6: PIPE6 */
-#define	NRDY5		0x0020	/* b5: PIPE5 */
-#define	NRDY4		0x0010	/* b4: PIPE4 */
-#define	NRDY3		0x0008	/* b3: PIPE3 */
-#define	NRDY2		0x0004	/* b2: PIPE2 */
-#define	NRDY1		0x0002	/* b1: PIPE1 */
-#define	NRDY0		0x0001	/* b1: PIPE0 */
-
-/* BEMP Interrupt Enable/Status Register */
-#define	BEMP9		0x0200	/* b9: PIPE9 */
-#define	BEMP8		0x0100	/* b8: PIPE8 */
-#define	BEMP7		0x0080	/* b7: PIPE7 */
-#define	BEMP6		0x0040	/* b6: PIPE6 */
-#define	BEMP5		0x0020	/* b5: PIPE5 */
-#define	BEMP4		0x0010	/* b4: PIPE4 */
-#define	BEMP3		0x0008	/* b3: PIPE3 */
-#define	BEMP2		0x0004	/* b2: PIPE2 */
-#define	BEMP1		0x0002	/* b1: PIPE1 */
-#define	BEMP0		0x0001	/* b0: PIPE0 */
-
-/* SOF Pin Configuration Register */
-#define	TRNENSEL	0x0100	/* b8: Select transaction enable period */
-#define	BRDYM		0x0040	/* b6: BRDY clear timing */
-#define	INTL		0x0020	/* b5: Interrupt sense select */
-#define	EDGESTS		0x0010	/* b4:  */
-#define	SOFMODE		0x000C	/* b3-2: SOF pin select */
-#define	  SOF_125US	 0x0008	  /* SOF OUT 125us Frame Signal */
-#define	  SOF_1MS	 0x0004	  /* SOF OUT 1ms Frame Signal */
-#define	  SOF_DISABLE	 0x0000	  /* SOF OUT Disable */
-
-/* Interrupt Status Register 0 */
-#define	VBINT	0x8000	/* b15: VBUS interrupt */
-#define	RESM	0x4000	/* b14: Resume interrupt */
-#define	SOFR	0x2000	/* b13: SOF frame update interrupt */
-#define	DVST	0x1000	/* b12: Device state transition interrupt */
-#define	CTRT	0x0800	/* b11: Control transfer stage transition interrupt */
-#define	BEMP	0x0400	/* b10: Buffer empty interrupt */
-#define	NRDY	0x0200	/* b9: Buffer not ready interrupt */
-#define	BRDY	0x0100	/* b8: Buffer ready interrupt */
-#define	VBSTS	0x0080	/* b7: VBUS input port */
-#define	DVSQ	0x0070	/* b6-4: Device state */
-#define	  DS_SPD_CNFG	 0x0070	  /* Suspend Configured */
-#define	  DS_SPD_ADDR	 0x0060	  /* Suspend Address */
-#define	  DS_SPD_DFLT	 0x0050	  /* Suspend Default */
-#define	  DS_SPD_POWR	 0x0040	  /* Suspend Powered */
-#define	  DS_SUSP	 0x0040	  /* Suspend */
-#define	  DS_CNFG	 0x0030	  /* Configured */
-#define	  DS_ADDS	 0x0020	  /* Address */
-#define	  DS_DFLT	 0x0010	  /* Default */
-#define	  DS_POWR	 0x0000	  /* Powered */
-#define	DVSQS		0x0030	/* b5-4: Device state */
-#define	VALID		0x0008	/* b3: Setup packet detected flag */
-#define	CTSQ		0x0007	/* b2-0: Control transfer stage */
-#define	  CS_SQER	 0x0006	  /* Sequence error */
-#define	  CS_WRND	 0x0005	  /* Control write nodata status stage */
-#define	  CS_WRSS	 0x0004	  /* Control write status stage */
-#define	  CS_WRDS	 0x0003	  /* Control write data stage */
-#define	  CS_RDSS	 0x0002	  /* Control read status stage */
-#define	  CS_RDDS	 0x0001	  /* Control read data stage */
-#define	  CS_IDST	 0x0000	  /* Idle or setup stage */
-
-/* Interrupt Status Register 1 */
-#define	OVRCR		0x8000	/* b15: Over-current interrupt */
-#define	BCHG		0x4000	/* b14: USB bus chenge interrupt */
-#define	DTCH		0x1000	/* b12: Detach sense interrupt */
-#define	ATTCH		0x0800	/* b11: Attach sense interrupt */
-#define	EOFERR		0x0040	/* b6: EOF-error interrupt */
-#define	SIGN		0x0020	/* b5: Setup ignore interrupt */
-#define	SACK		0x0010	/* b4: Setup acknowledge interrupt */
-
-/* Frame Number Register */
-#define	OVRN		0x8000	/* b15: Overrun error */
-#define	CRCE		0x4000	/* b14: Received data error */
-#define	FRNM		0x07FF	/* b10-0: Frame number */
-
-/* Micro Frame Number Register */
-#define	UFRNM		0x0007	/* b2-0: Micro frame number */
-
-/* Default Control Pipe Maxpacket Size Register */
-/* Pipe Maxpacket Size Register */
-#define	DEVSEL	0xF000	/* b15-14: Device address select */
-#define	MAXP	0x007F	/* b6-0: Maxpacket size of default control pipe */
-
-/* Default Control Pipe Control Register */
-#define	BSTS		0x8000	/* b15: Buffer status */
-#define	SUREQ		0x4000	/* b14: Send USB request  */
-#define	CSCLR		0x2000	/* b13: complete-split status clear */
-#define	CSSTS		0x1000	/* b12: complete-split status */
-#define	SUREQCLR	0x0800	/* b11: stop setup request */
-#define	SQCLR		0x0100	/* b8: Sequence toggle bit clear */
-#define	SQSET		0x0080	/* b7: Sequence toggle bit set */
-#define	SQMON		0x0040	/* b6: Sequence toggle bit monitor */
-#define	PBUSY		0x0020	/* b5: pipe busy */
-#define	PINGE		0x0010	/* b4: ping enable */
-#define	CCPL		0x0004	/* b2: Enable control transfer complete */
-#define	PID		0x0003	/* b1-0: Response PID */
-#define	  PID_STALL11	 0x0003	  /* STALL */
-#define	  PID_STALL	 0x0002	  /* STALL */
-#define	  PID_BUF	 0x0001	  /* BUF */
-#define	  PID_NAK	 0x0000	  /* NAK */
-
-/* Pipe Window Select Register */
-#define	PIPENM		0x0007	/* b2-0: Pipe select */
-
-/* Pipe Configuration Register */
-#define	R8A66597_TYP	0xC000	/* b15-14: Transfer type */
-#define	  R8A66597_ISO	 0xC000		  /* Isochronous */
-#define	  R8A66597_INT	 0x8000		  /* Interrupt */
-#define	  R8A66597_BULK	 0x4000		  /* Bulk */
-#define	R8A66597_BFRE	0x0400	/* b10: Buffer ready interrupt mode select */
-#define	R8A66597_DBLB	0x0200	/* b9: Double buffer mode select */
-#define	R8A66597_CNTMD	0x0100	/* b8: Continuous transfer mode select */
-#define	R8A66597_SHTNAK	0x0080	/* b7: Transfer end NAK */
-#define	R8A66597_DIR	0x0010	/* b4: Transfer direction select */
-#define	R8A66597_EPNUM	0x000F	/* b3-0: Eendpoint number select */
-
-/* Pipe Buffer Configuration Register */
-#define	BUFSIZE		0x7C00	/* b14-10: Pipe buffer size */
-#define	BUFNMB		0x007F	/* b6-0: Pipe buffer number */
-#define	PIPE0BUF	256
-#define	PIPExBUF	64
-
-/* Pipe Maxpacket Size Register */
-#define	MXPS		0x07FF	/* b10-0: Maxpacket size */
-
-/* Pipe Cycle Configuration Register */
-#define	IFIS	0x1000	/* b12: Isochronous in-buffer flush mode select */
-#define	IITV	0x0007	/* b2-0: Isochronous interval */
-
-/* Pipex Control Register */
-#define	BSTS	0x8000	/* b15: Buffer status */
-#define	INBUFM	0x4000	/* b14: IN buffer monitor (Only for PIPE1 to 5) */
-#define	CSCLR	0x2000	/* b13: complete-split status clear */
-#define	CSSTS	0x1000	/* b12: complete-split status */
-#define	ATREPM	0x0400	/* b10: Auto repeat mode */
-#define	ACLRM	0x0200	/* b9: Out buffer auto clear mode */
-#define	SQCLR	0x0100	/* b8: Sequence toggle bit clear */
-#define	SQSET	0x0080	/* b7: Sequence toggle bit set */
-#define	SQMON	0x0040	/* b6: Sequence toggle bit monitor */
-#define	PBUSY	0x0020	/* b5: pipe busy */
-#define	PID	0x0003	/* b1-0: Response PID */
-
-/* PIPExTRE */
-#define	TRENB		0x0200	/* b9: Transaction counter enable */
-#define	TRCLR		0x0100	/* b8: Transaction counter clear */
-
-/* PIPExTRN */
-#define	TRNCNT		0xFFFF	/* b15-0: Transaction counter */
-
-/* DEVADDx */
-#define	UPPHUB		0x7800
-#define	HUBPORT		0x0700
-#define	USBSPD		0x00C0
-#define	RTPORT		0x0001
-
 #define R8A66597_MAX_NUM_PIPE		10
 #define R8A66597_BUF_BSIZE		8
 #define R8A66597_MAX_DEVICE		10
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define R8A66597_MAX_ROOT_HUB		1
-#else
 #define R8A66597_MAX_ROOT_HUB		2
-#endif
 #define R8A66597_MAX_SAMPLING		5
 #define R8A66597_RH_POLL_TIME		10
 #define R8A66597_MAX_DMA_CHANNEL	2
@@ -487,7 +113,7 @@
 struct r8a66597 {
 	spinlock_t lock;
 	unsigned long reg;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	struct clk *clk;
 #endif
 	struct r8a66597_platdata	*pdata;
@@ -504,6 +130,7 @@
 	unsigned short interval_map;
 	unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
 	unsigned char dma_map;
+	unsigned int max_root_hub;
 
 	struct list_head child_device;
 	unsigned long child_connect_map[4];
@@ -550,21 +177,22 @@
 				      unsigned long offset, u16 *buf,
 				      int len)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	unsigned long fifoaddr = r8a66597->reg + offset;
 	unsigned long count;
 
-	count = len / 4;
-	insl(fifoaddr, buf, count);
+	if (r8a66597->pdata->on_chip) {
+		count = len / 4;
+		insl(fifoaddr, buf, count);
 
-	if (len & 0x00000003) {
-		unsigned long tmp = inl(fifoaddr);
-		memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
+		if (len & 0x00000003) {
+			unsigned long tmp = inl(fifoaddr);
+			memcpy((unsigned char *)buf + count * 4, &tmp,
+			       len & 0x03);
+		}
+	} else {
+		len = (len + 1) / 2;
+		insw(fifoaddr, buf, len);
 	}
-#else
-	len = (len + 1) / 2;
-	insw(r8a66597->reg + offset, buf, len);
-#endif
 }
 
 static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
@@ -578,33 +206,33 @@
 				       int len)
 {
 	unsigned long fifoaddr = r8a66597->reg + offset;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	unsigned long count;
 	unsigned char *pb;
 	int i;
 
-	count = len / 4;
-	outsl(fifoaddr, buf, count);
+	if (r8a66597->pdata->on_chip) {
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
 
-	if (len & 0x00000003) {
-		pb = (unsigned char *)buf + count * 4;
-		for (i = 0; i < (len & 0x00000003); i++) {
-			if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
-				outb(pb[i], fifoaddr + i);
-			else
-				outb(pb[i], fifoaddr + 3 - i);
+		if (len & 0x00000003) {
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
+					outb(pb[i], fifoaddr + i);
+				else
+					outb(pb[i], fifoaddr + 3 - i);
+			}
+		}
+	} else {
+		int odd = len & 0x0001;
+
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (unlikely(odd)) {
+			buf = &buf[len];
+			outb((unsigned char)*buf, fifoaddr);
 		}
 	}
-#else
-	int odd = len & 0x0001;
-
-	len = len / 2;
-	outsw(fifoaddr, buf, len);
-	if (unlikely(odd)) {
-		buf = &buf[len];
-		outb((unsigned char)*buf, fifoaddr);
-	}
-#endif
 }
 
 static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1999b18..49f2c4b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1867,7 +1867,7 @@
 
 config FB_SH_MOBILE_LCDC
 	tristate "SuperH Mobile LCDC framebuffer support"
-	depends on FB && SUPERH
+	depends on FB && SUPERH && HAVE_CLK
 	select FB_SYS_FILLRECT
 	select FB_SYS_COPYAREA
 	select FB_SYS_IMAGEBLIT
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 07f22b6..3ad5157 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
@@ -22,35 +23,8 @@
 #include <asm/atomic.h>
 
 #define PALETTE_NR 16
-
-struct sh_mobile_lcdc_priv;
-struct sh_mobile_lcdc_chan {
-	struct sh_mobile_lcdc_priv *lcdc;
-	unsigned long *reg_offs;
-	unsigned long ldmt1r_value;
-	unsigned long enabled; /* ME and SE in LDCNT2R */
-	struct sh_mobile_lcdc_chan_cfg cfg;
-	u32 pseudo_palette[PALETTE_NR];
-	struct fb_info *info;
-	dma_addr_t dma_handle;
-	struct fb_deferred_io defio;
-	struct scatterlist *sglist;
-	unsigned long frame_end;
-	wait_queue_head_t frame_end_wait;
-};
-
-struct sh_mobile_lcdc_priv {
-	void __iomem *base;
-	int irq;
-#ifdef CONFIG_HAVE_CLK
-	atomic_t clk_usecnt;
-	struct clk *dot_clk;
-	struct clk *clk;
-#endif
-	unsigned long lddckr;
-	struct sh_mobile_lcdc_chan ch[2];
-	int started;
-};
+#define SIDE_B_OFFSET 0x1000
+#define MIRROR_OFFSET 0x2000
 
 /* shared registers */
 #define _LDDCKR 0x410
@@ -59,17 +33,30 @@
 #define _LDSR 0x46c
 #define _LDCNT1R 0x470
 #define _LDCNT2R 0x474
+#define _LDRCNTR 0x478
 #define _LDDDSR 0x47c
 #define _LDDWD0R 0x800
 #define _LDDRDR 0x840
 #define _LDDWAR 0x900
 #define _LDDRAR 0x904
 
+/* shared registers and their order for context save/restore */
+static int lcdc_shared_regs[] = {
+	_LDDCKR,
+	_LDDCKSTPR,
+	_LDINTR,
+	_LDDDSR,
+	_LDCNT1R,
+	_LDCNT2R,
+};
+#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
+
 /* per-channel registers */
 enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
-       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
+       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
+       NR_CH_REGS };
 
-static unsigned long lcdc_offs_mainlcd[] = {
+static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
 	[LDDCKPAT1R] = 0x400,
 	[LDDCKPAT2R] = 0x404,
 	[LDMT1R] = 0x418,
@@ -87,7 +74,7 @@
 	[LDPMR] = 0x460,
 };
 
-static unsigned long lcdc_offs_sublcd[] = {
+static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
 	[LDDCKPAT1R] = 0x408,
 	[LDDCKPAT2R] = 0x40c,
 	[LDMT1R] = 0x600,
@@ -110,12 +97,80 @@
 #define DISPLAY_BEU	0x00000008
 #define LCDC_ENABLE	0x00000001
 #define LDINTR_FE	0x00000400
+#define LDINTR_VSE	0x00000200
+#define LDINTR_VEE	0x00000100
 #define LDINTR_FS	0x00000004
+#define LDINTR_VSS	0x00000002
+#define LDINTR_VES	0x00000001
+#define LDRCNTR_SRS	0x00020000
+#define LDRCNTR_SRC	0x00010000
+#define LDRCNTR_MRS	0x00000002
+#define LDRCNTR_MRC	0x00000001
+
+struct sh_mobile_lcdc_priv;
+struct sh_mobile_lcdc_chan {
+	struct sh_mobile_lcdc_priv *lcdc;
+	unsigned long *reg_offs;
+	unsigned long ldmt1r_value;
+	unsigned long enabled; /* ME and SE in LDCNT2R */
+	struct sh_mobile_lcdc_chan_cfg cfg;
+	u32 pseudo_palette[PALETTE_NR];
+	unsigned long saved_ch_regs[NR_CH_REGS];
+	struct fb_info *info;
+	dma_addr_t dma_handle;
+	struct fb_deferred_io defio;
+	struct scatterlist *sglist;
+	unsigned long frame_end;
+	unsigned long pan_offset;
+	unsigned long new_pan_offset;
+	wait_queue_head_t frame_end_wait;
+};
+
+struct sh_mobile_lcdc_priv {
+	void __iomem *base;
+	int irq;
+	atomic_t hw_usecnt;
+	struct device *dev;
+	struct clk *dot_clk;
+	unsigned long lddckr;
+	struct sh_mobile_lcdc_chan ch[2];
+	unsigned long saved_shared_regs[NR_SHARED_REGS];
+	int started;
+};
+
+static bool banked(int reg_nr)
+{
+	switch (reg_nr) {
+	case LDMT1R:
+	case LDMT2R:
+	case LDMT3R:
+	case LDDFR:
+	case LDSM1R:
+	case LDSA1R:
+	case LDMLSR:
+	case LDHCNR:
+	case LDHSYNR:
+	case LDVLNR:
+	case LDVSYNR:
+		return true;
+	}
+	return false;
+}
 
 static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
 			    int reg_nr, unsigned long data)
 {
 	iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
+	if (banked(reg_nr))
+		iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
+			  SIDE_B_OFFSET);
+}
+
+static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
+			    int reg_nr, unsigned long data)
+{
+	iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
+		  MIRROR_OFFSET);
 }
 
 static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
@@ -156,6 +211,7 @@
 	lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static void lcdc_sys_write_data(void *handle, unsigned long data)
@@ -165,6 +221,7 @@
 	lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static unsigned long lcdc_sys_read_data(void *handle)
@@ -175,8 +232,9 @@
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 	udelay(1);
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 
-	return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff;
+	return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff;
 }
 
 struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
@@ -185,11 +243,10 @@
 	lcdc_sys_read_data,
 };
 
-#ifdef CONFIG_HAVE_CLK
 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 {
-	if (atomic_inc_and_test(&priv->clk_usecnt)) {
-		clk_enable(priv->clk);
+	if (atomic_inc_and_test(&priv->hw_usecnt)) {
+		pm_runtime_get_sync(priv->dev);
 		if (priv->dot_clk)
 			clk_enable(priv->dot_clk);
 	}
@@ -197,16 +254,12 @@
 
 static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 {
-	if (atomic_sub_return(1, &priv->clk_usecnt) == -1) {
+	if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
 		if (priv->dot_clk)
 			clk_disable(priv->dot_clk);
-		clk_disable(priv->clk);
+		pm_runtime_put(priv->dev);
 	}
 }
-#else
-static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
-static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
-#endif
 
 static int sh_mobile_lcdc_sginit(struct fb_info *info,
 				  struct list_head *pagelist)
@@ -255,30 +308,52 @@
 	struct sh_mobile_lcdc_priv *priv = data;
 	struct sh_mobile_lcdc_chan *ch;
 	unsigned long tmp;
+	unsigned long ldintr;
 	int is_sub;
 	int k;
 
 	/* acknowledge interrupt */
-	tmp = lcdc_read(priv, _LDINTR);
-	tmp &= 0xffffff00; /* mask in high 24 bits */
-	tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
+	ldintr = tmp = lcdc_read(priv, _LDINTR);
+	/*
+	 * disable further VSYNC End IRQs, preserve all other enabled IRQs,
+	 * write 0 to bits 0-6 to ack all triggered IRQs.
+	 */
+	tmp &= 0xffffff00 & ~LDINTR_VEE;
 	lcdc_write(priv, _LDINTR, tmp);
 
 	/* figure out if this interrupt is for main or sub lcd */
 	is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
 
-	/* wake up channel and disable clocks*/
+	/* wake up channel and disable clocks */
 	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 		ch = &priv->ch[k];
 
 		if (!ch->enabled)
 			continue;
 
-		if (is_sub == lcdc_chan_is_sublcd(ch)) {
-			ch->frame_end = 1;
-			wake_up(&ch->frame_end_wait);
+		/* Frame Start */
+		if (ldintr & LDINTR_FS) {
+			if (is_sub == lcdc_chan_is_sublcd(ch)) {
+				ch->frame_end = 1;
+				wake_up(&ch->frame_end_wait);
 
-			sh_mobile_lcdc_clk_off(priv);
+				sh_mobile_lcdc_clk_off(priv);
+			}
+		}
+
+		/* VSYNC End */
+		if (ldintr & LDINTR_VES) {
+			unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
+			/* Set the source address for the next refresh */
+			lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
+					       ch->new_pan_offset);
+			if (lcdc_chan_is_sublcd(ch))
+				lcdc_write(ch->lcdc, _LDRCNTR,
+					   ldrcntr ^ LDRCNTR_SRS);
+			else
+				lcdc_write(ch->lcdc, _LDRCNTR,
+					   ldrcntr ^ LDRCNTR_MRS);
+			ch->pan_offset = ch->new_pan_offset;
 		}
 	}
 
@@ -520,7 +595,6 @@
 		board_cfg = &ch->cfg.board_cfg;
 		if (board_cfg->display_off)
 			board_cfg->display_off(board_cfg->board_data);
-
 	}
 
 	/* stop the lcdc */
@@ -579,9 +653,6 @@
 				       int clock_source,
 				       struct sh_mobile_lcdc_priv *priv)
 {
-#ifdef CONFIG_HAVE_CLK
-	char clk_name[8];
-#endif
 	char *str;
 	int icksel;
 
@@ -595,25 +666,21 @@
 
 	priv->lddckr = icksel << 16;
 
-#ifdef CONFIG_HAVE_CLK
-	atomic_set(&priv->clk_usecnt, -1);
-	snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
-	priv->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(priv->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		return PTR_ERR(priv->clk);
-	}
-	
 	if (str) {
 		priv->dot_clk = clk_get(&pdev->dev, str);
 		if (IS_ERR(priv->dot_clk)) {
 			dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
-			clk_put(priv->clk);
 			return PTR_ERR(priv->dot_clk);
 		}
 	}
-#endif
+	atomic_set(&priv->hw_usecnt, -1);
 
+	/* Runtime PM support involves two step for this driver:
+	 * 1) Enable Runtime PM
+	 * 2) Force Runtime PM Resume since hardware is accessed from probe()
+	 */
+	pm_runtime_enable(priv->dev);
+	pm_runtime_resume(priv->dev);
 	return 0;
 }
 
@@ -646,6 +713,9 @@
 	.type =		FB_TYPE_PACKED_PIXELS,
 	.visual =	FB_VISUAL_TRUECOLOR,
 	.accel =	FB_ACCEL_NONE,
+	.xpanstep =	0,
+	.ypanstep =	1,
+	.ywrapstep =	0,
 };
 
 static void sh_mobile_lcdc_fillrect(struct fb_info *info,
@@ -669,13 +739,38 @@
 	sh_mobile_lcdc_deferred_io_touch(info);
 }
 
+static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
+				     struct fb_info *info)
+{
+	struct sh_mobile_lcdc_chan *ch = info->par;
+
+	if (info->var.xoffset == var->xoffset &&
+	    info->var.yoffset == var->yoffset)
+		return 0;	/* No change, do nothing */
+
+	ch->new_pan_offset = (var->yoffset * info->fix.line_length) +
+		(var->xoffset * (info->var.bits_per_pixel / 8));
+
+	if (ch->new_pan_offset != ch->pan_offset) {
+		unsigned long ldintr;
+		ldintr = lcdc_read(ch->lcdc, _LDINTR);
+		ldintr |= LDINTR_VEE;
+		lcdc_write(ch->lcdc, _LDINTR, ldintr);
+		sh_mobile_lcdc_deferred_io_touch(info);
+	}
+
+	return 0;
+}
+
 static struct fb_ops sh_mobile_lcdc_ops = {
+	.owner          = THIS_MODULE,
 	.fb_setcolreg	= sh_mobile_lcdc_setcolreg,
 	.fb_read        = fb_sys_read,
 	.fb_write       = fb_sys_write,
 	.fb_fillrect	= sh_mobile_lcdc_fillrect,
 	.fb_copyarea	= sh_mobile_lcdc_copyarea,
 	.fb_imageblit	= sh_mobile_lcdc_imageblit,
+	.fb_pan_display = sh_mobile_fb_pan_display,
 };
 
 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -731,9 +826,59 @@
 	return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
 }
 
+static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
+	struct sh_mobile_lcdc_chan *ch;
+	int k, n;
+
+	/* save per-channel registers */
+	for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
+		ch = &p->ch[k];
+		if (!ch->enabled)
+			continue;
+		for (n = 0; n < NR_CH_REGS; n++)
+			ch->saved_ch_regs[n] = lcdc_read_chan(ch, n);
+	}
+
+	/* save shared registers */
+	for (n = 0; n < NR_SHARED_REGS; n++)
+		p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]);
+
+	/* turn off LCDC hardware */
+	lcdc_write(p, _LDCNT1R, 0);
+	return 0;
+}
+
+static int sh_mobile_lcdc_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
+	struct sh_mobile_lcdc_chan *ch;
+	int k, n;
+
+	/* restore per-channel registers */
+	for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
+		ch = &p->ch[k];
+		if (!ch->enabled)
+			continue;
+		for (n = 0; n < NR_CH_REGS; n++)
+			lcdc_write_chan(ch, n, ch->saved_ch_regs[n]);
+	}
+
+	/* restore shared registers */
+	for (n = 0; n < NR_SHARED_REGS; n++)
+		lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]);
+
+	return 0;
+}
+
 static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
 	.suspend = sh_mobile_lcdc_suspend,
 	.resume = sh_mobile_lcdc_resume,
+	.runtime_suspend = sh_mobile_lcdc_runtime_suspend,
+	.runtime_resume = sh_mobile_lcdc_runtime_resume,
 };
 
 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -778,6 +923,7 @@
 	}
 
 	priv->irq = i;
+	priv->dev = &pdev->dev;
 	platform_set_drvdata(pdev, priv);
 	pdata = pdev->dev.platform_data;
 
@@ -792,6 +938,8 @@
 			goto err1;
 		}
 		init_waitqueue_head(&priv->ch[i].frame_end_wait);
+		priv->ch[j].pan_offset = 0;
+		priv->ch[j].new_pan_offset = 0;
 
 		switch (pdata->ch[i].chan) {
 		case LCDC_CHAN_MAINLCD:
@@ -834,7 +982,9 @@
 		info = priv->ch[i].info;
 		info->fbops = &sh_mobile_lcdc_ops;
 		info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
-		info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
+		info->var.yres = cfg->lcd_cfg.yres;
+		/* Default Y virtual resolution is 2x panel size */
+		info->var.yres_virtual = info->var.yres * 2;
 		info->var.width = cfg->lcd_size_cfg.width;
 		info->var.height = cfg->lcd_size_cfg.height;
 		info->var.activate = FB_ACTIVATE_NOW;
@@ -844,7 +994,8 @@
 
 		info->fix = sh_mobile_lcdc_fix;
 		info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
-		info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres;
+		info->fix.smem_len = info->fix.line_length *
+			info->var.yres_virtual;
 
 		buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
 					 &priv->ch[i].dma_handle, GFP_KERNEL);
@@ -947,11 +1098,10 @@
 		framebuffer_release(info);
 	}
 
-#ifdef CONFIG_HAVE_CLK
 	if (priv->dot_clk)
 		clk_put(priv->dot_clk);
-	clk_put(priv->clk);
-#endif
+
+	pm_runtime_disable(priv->dev);
 
 	if (priv->base)
 		iounmap(priv->base);
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index eb1423a..68e212f 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -85,7 +85,6 @@
 }
 #endif
 
-unsigned int intc_evt2irq(unsigned int vector);
 void __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h
new file mode 100644
index 0000000..cda9625
--- /dev/null
+++ b/include/linux/usb/m66592.h
@@ -0,0 +1,44 @@
+/*
+ * M66592 driver platform data
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __LINUX_USB_M66592_H
+#define __LINUX_USB_M66592_H
+
+#define M66592_PLATDATA_XTAL_12MHZ	0x01
+#define M66592_PLATDATA_XTAL_24MHZ	0x02
+#define M66592_PLATDATA_XTAL_48MHZ	0x03
+
+struct m66592_platdata {
+	/* one = on chip controller, zero = external controller */
+	unsigned	on_chip:1;
+
+	/* one = big endian, zero = little endian */
+	unsigned	endian:1;
+
+	/* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */
+	unsigned	xtal:2;
+
+	/* (external controller only) one = 3.3V, zero = 1.5V */
+	unsigned	vif:1;
+
+};
+
+#endif /* __LINUX_USB_M66592_H */
+
diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h
index e9f0384..26d2167 100644
--- a/include/linux/usb/r8a66597.h
+++ b/include/linux/usb/r8a66597.h
@@ -28,9 +28,12 @@
 #define R8A66597_PLATDATA_XTAL_48MHZ	0x03
 
 struct r8a66597_platdata {
-	/* This ops can controll port power instead of DVSTCTR register. */
+	/* This callback can control port power instead of DVSTCTR register. */
 	void (*port_power)(int port, int power);
 
+	/* set one = on chip controller, set zero = external controller */
+	unsigned	on_chip:1;
+
 	/* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */
 	unsigned	xtal:2;
 
@@ -40,5 +43,373 @@
 	/* set one = big endian, set zero = little endian */
 	unsigned	endian:1;
 };
-#endif
+
+/* Register definitions */
+#define SYSCFG0		0x00
+#define SYSCFG1		0x02
+#define SYSSTS0		0x04
+#define SYSSTS1		0x06
+#define DVSTCTR0	0x08
+#define DVSTCTR1	0x0A
+#define TESTMODE	0x0C
+#define PINCFG		0x0E
+#define DMA0CFG		0x10
+#define DMA1CFG		0x12
+#define CFIFO		0x14
+#define D0FIFO		0x18
+#define D1FIFO		0x1C
+#define CFIFOSEL	0x20
+#define CFIFOCTR	0x22
+#define CFIFOSIE	0x24
+#define D0FIFOSEL	0x28
+#define D0FIFOCTR	0x2A
+#define D1FIFOSEL	0x2C
+#define D1FIFOCTR	0x2E
+#define INTENB0		0x30
+#define INTENB1		0x32
+#define INTENB2		0x34
+#define BRDYENB		0x36
+#define NRDYENB		0x38
+#define BEMPENB		0x3A
+#define SOFCFG		0x3C
+#define INTSTS0		0x40
+#define INTSTS1		0x42
+#define INTSTS2		0x44
+#define BRDYSTS		0x46
+#define NRDYSTS		0x48
+#define BEMPSTS		0x4A
+#define FRMNUM		0x4C
+#define UFRMNUM		0x4E
+#define USBADDR		0x50
+#define USBREQ		0x54
+#define USBVAL		0x56
+#define USBINDX		0x58
+#define USBLENG		0x5A
+#define DCPCFG		0x5C
+#define DCPMAXP		0x5E
+#define DCPCTR		0x60
+#define PIPESEL		0x64
+#define PIPECFG		0x68
+#define PIPEBUF		0x6A
+#define PIPEMAXP	0x6C
+#define PIPEPERI	0x6E
+#define PIPE1CTR	0x70
+#define PIPE2CTR	0x72
+#define PIPE3CTR	0x74
+#define PIPE4CTR	0x76
+#define PIPE5CTR	0x78
+#define PIPE6CTR	0x7A
+#define PIPE7CTR	0x7C
+#define PIPE8CTR	0x7E
+#define PIPE9CTR	0x80
+#define PIPE1TRE	0x90
+#define PIPE1TRN	0x92
+#define PIPE2TRE	0x94
+#define PIPE2TRN	0x96
+#define PIPE3TRE	0x98
+#define PIPE3TRN	0x9A
+#define PIPE4TRE	0x9C
+#define	PIPE4TRN	0x9E
+#define	PIPE5TRE	0xA0
+#define	PIPE5TRN	0xA2
+#define DEVADD0		0xD0
+#define DEVADD1		0xD2
+#define DEVADD2		0xD4
+#define DEVADD3		0xD6
+#define DEVADD4		0xD8
+#define DEVADD5		0xDA
+#define DEVADD6		0xDC
+#define DEVADD7		0xDE
+#define DEVADD8		0xE0
+#define DEVADD9		0xE2
+#define DEVADDA		0xE4
+
+/* System Configuration Control Register */
+#define	XTAL		0xC000	/* b15-14: Crystal selection */
+#define	  XTAL48	 0x8000	  /* 48MHz */
+#define	  XTAL24	 0x4000	  /* 24MHz */
+#define	  XTAL12	 0x0000	  /* 12MHz */
+#define	XCKE		0x2000	/* b13: External clock enable */
+#define	PLLC		0x0800	/* b11: PLL control */
+#define	SCKE		0x0400	/* b10: USB clock enable */
+#define	PCSDIS		0x0200	/* b9: not CS wakeup */
+#define	LPSME		0x0100	/* b8: Low power sleep mode */
+#define	HSE		0x0080	/* b7: Hi-speed enable */
+#define	DCFM		0x0040	/* b6: Controller function select  */
+#define	DRPD		0x0020	/* b5: D+/- pull down control */
+#define	DPRPU		0x0010	/* b4: D+ pull up control */
+#define	USBE		0x0001	/* b0: USB module operation enable */
+
+/* System Configuration Status Register */
+#define	OVCBIT		0x8000	/* b15-14: Over-current bit */
+#define	OVCMON		0xC000	/* b15-14: Over-current monitor */
+#define	SOFEA		0x0020	/* b5: SOF monitor */
+#define	IDMON		0x0004	/* b3: ID-pin monitor */
+#define	LNST		0x0003	/* b1-0: D+, D- line status */
+#define	  SE1		 0x0003	  /* SE1 */
+#define	  FS_KSTS	 0x0002	  /* Full-Speed K State */
+#define	  FS_JSTS	 0x0001	  /* Full-Speed J State */
+#define	  LS_JSTS	 0x0002	  /* Low-Speed J State */
+#define	  LS_KSTS	 0x0001	  /* Low-Speed K State */
+#define	  SE0		 0x0000	  /* SE0 */
+
+/* Device State Control Register */
+#define	EXTLP0		0x0400	/* b10: External port */
+#define	VBOUT		0x0200	/* b9: VBUS output */
+#define	WKUP		0x0100	/* b8: Remote wakeup */
+#define	RWUPE		0x0080	/* b7: Remote wakeup sense */
+#define	USBRST		0x0040	/* b6: USB reset enable */
+#define	RESUME		0x0020	/* b5: Resume enable */
+#define	UACT		0x0010	/* b4: USB bus enable */
+#define	RHST		0x0007	/* b1-0: Reset handshake status */
+#define	  HSPROC	 0x0004	  /* HS handshake is processing */
+#define	  HSMODE	 0x0003	  /* Hi-Speed mode */
+#define	  FSMODE	 0x0002	  /* Full-Speed mode */
+#define	  LSMODE	 0x0001	  /* Low-Speed mode */
+#define	  UNDECID	 0x0000	  /* Undecided */
+
+/* Test Mode Register */
+#define	UTST			0x000F	/* b3-0: Test select */
+#define	  H_TST_PACKET		 0x000C	  /* HOST TEST Packet */
+#define	  H_TST_SE0_NAK		 0x000B	  /* HOST TEST SE0 NAK */
+#define	  H_TST_K		 0x000A	  /* HOST TEST K */
+#define	  H_TST_J		 0x0009	  /* HOST TEST J */
+#define	  H_TST_NORMAL		 0x0000	  /* HOST Normal Mode */
+#define	  P_TST_PACKET		 0x0004	  /* PERI TEST Packet */
+#define	  P_TST_SE0_NAK		 0x0003	  /* PERI TEST SE0 NAK */
+#define	  P_TST_K		 0x0002	  /* PERI TEST K */
+#define	  P_TST_J		 0x0001	  /* PERI TEST J */
+#define	  P_TST_NORMAL		 0x0000	  /* PERI Normal Mode */
+
+/* Data Pin Configuration Register */
+#define	LDRV			0x8000	/* b15: Drive Current Adjust */
+#define	  VIF1			  0x0000		/* VIF = 1.8V */
+#define	  VIF3			  0x8000		/* VIF = 3.3V */
+#define	INTA			0x0001	/* b1: USB INT-pin active */
+
+/* DMAx Pin Configuration Register */
+#define	DREQA			0x4000	/* b14: Dreq active select */
+#define	BURST			0x2000	/* b13: Burst mode */
+#define	DACKA			0x0400	/* b10: Dack active select */
+#define	DFORM			0x0380	/* b9-7: DMA mode select */
+#define	  CPU_ADR_RD_WR		 0x0000	  /* Address + RD/WR mode (CPU bus) */
+#define	  CPU_DACK_RD_WR	 0x0100	  /* DACK + RD/WR mode (CPU bus) */
+#define	  CPU_DACK_ONLY		 0x0180	  /* DACK only mode (CPU bus) */
+#define	  SPLIT_DACK_ONLY	 0x0200	  /* DACK only mode (SPLIT bus) */
+#define	DENDA			0x0040	/* b6: Dend active select */
+#define	PKTM			0x0020	/* b5: Packet mode */
+#define	DENDE			0x0010	/* b4: Dend enable */
+#define	OBUS			0x0004	/* b2: OUTbus mode */
+
+/* CFIFO/DxFIFO Port Select Register */
+#define	RCNT		0x8000	/* b15: Read count mode */
+#define	REW		0x4000	/* b14: Buffer rewind */
+#define	DCLRM		0x2000	/* b13: DMA buffer clear mode */
+#define	DREQE		0x1000	/* b12: DREQ output enable */
+#define	  MBW_8		 0x0000	  /*  8bit */
+#define	  MBW_16	 0x0400	  /* 16bit */
+#define	  MBW_32	 0x0800   /* 32bit */
+#define	BIGEND		0x0100	/* b8: Big endian mode */
+#define	  BYTE_LITTLE	 0x0000		/* little dendian */
+#define	  BYTE_BIG	 0x0100		/* big endifan */
+#define	ISEL		0x0020	/* b5: DCP FIFO port direction select */
+#define	CURPIPE		0x000F	/* b2-0: PIPE select */
+
+/* CFIFO/DxFIFO Port Control Register */
+#define	BVAL		0x8000	/* b15: Buffer valid flag */
+#define	BCLR		0x4000	/* b14: Buffer clear */
+#define	FRDY		0x2000	/* b13: FIFO ready */
+#define	DTLN		0x0FFF	/* b11-0: FIFO received data length */
+
+/* Interrupt Enable Register 0 */
+#define	VBSE	0x8000	/* b15: VBUS interrupt */
+#define	RSME	0x4000	/* b14: Resume interrupt */
+#define	SOFE	0x2000	/* b13: Frame update interrupt */
+#define	DVSE	0x1000	/* b12: Device state transition interrupt */
+#define	CTRE	0x0800	/* b11: Control transfer stage transition interrupt */
+#define	BEMPE	0x0400	/* b10: Buffer empty interrupt */
+#define	NRDYE	0x0200	/* b9: Buffer not ready interrupt */
+#define	BRDYE	0x0100	/* b8: Buffer ready interrupt */
+
+/* Interrupt Enable Register 1 */
+#define	OVRCRE		0x8000	/* b15: Over-current interrupt */
+#define	BCHGE		0x4000	/* b14: USB us chenge interrupt */
+#define	DTCHE		0x1000	/* b12: Detach sense interrupt */
+#define	ATTCHE		0x0800	/* b11: Attach sense interrupt */
+#define	EOFERRE		0x0040	/* b6: EOF error interrupt */
+#define	SIGNE		0x0020	/* b5: SETUP IGNORE interrupt */
+#define	SACKE		0x0010	/* b4: SETUP ACK interrupt */
+
+/* BRDY Interrupt Enable/Status Register */
+#define	BRDY9		0x0200	/* b9: PIPE9 */
+#define	BRDY8		0x0100	/* b8: PIPE8 */
+#define	BRDY7		0x0080	/* b7: PIPE7 */
+#define	BRDY6		0x0040	/* b6: PIPE6 */
+#define	BRDY5		0x0020	/* b5: PIPE5 */
+#define	BRDY4		0x0010	/* b4: PIPE4 */
+#define	BRDY3		0x0008	/* b3: PIPE3 */
+#define	BRDY2		0x0004	/* b2: PIPE2 */
+#define	BRDY1		0x0002	/* b1: PIPE1 */
+#define	BRDY0		0x0001	/* b1: PIPE0 */
+
+/* NRDY Interrupt Enable/Status Register */
+#define	NRDY9		0x0200	/* b9: PIPE9 */
+#define	NRDY8		0x0100	/* b8: PIPE8 */
+#define	NRDY7		0x0080	/* b7: PIPE7 */
+#define	NRDY6		0x0040	/* b6: PIPE6 */
+#define	NRDY5		0x0020	/* b5: PIPE5 */
+#define	NRDY4		0x0010	/* b4: PIPE4 */
+#define	NRDY3		0x0008	/* b3: PIPE3 */
+#define	NRDY2		0x0004	/* b2: PIPE2 */
+#define	NRDY1		0x0002	/* b1: PIPE1 */
+#define	NRDY0		0x0001	/* b1: PIPE0 */
+
+/* BEMP Interrupt Enable/Status Register */
+#define	BEMP9		0x0200	/* b9: PIPE9 */
+#define	BEMP8		0x0100	/* b8: PIPE8 */
+#define	BEMP7		0x0080	/* b7: PIPE7 */
+#define	BEMP6		0x0040	/* b6: PIPE6 */
+#define	BEMP5		0x0020	/* b5: PIPE5 */
+#define	BEMP4		0x0010	/* b4: PIPE4 */
+#define	BEMP3		0x0008	/* b3: PIPE3 */
+#define	BEMP2		0x0004	/* b2: PIPE2 */
+#define	BEMP1		0x0002	/* b1: PIPE1 */
+#define	BEMP0		0x0001	/* b0: PIPE0 */
+
+/* SOF Pin Configuration Register */
+#define	TRNENSEL	0x0100	/* b8: Select transaction enable period */
+#define	BRDYM		0x0040	/* b6: BRDY clear timing */
+#define	INTL		0x0020	/* b5: Interrupt sense select */
+#define	EDGESTS		0x0010	/* b4:  */
+#define	SOFMODE		0x000C	/* b3-2: SOF pin select */
+#define	  SOF_125US	 0x0008	  /* SOF OUT 125us Frame Signal */
+#define	  SOF_1MS	 0x0004	  /* SOF OUT 1ms Frame Signal */
+#define	  SOF_DISABLE	 0x0000	  /* SOF OUT Disable */
+
+/* Interrupt Status Register 0 */
+#define	VBINT	0x8000	/* b15: VBUS interrupt */
+#define	RESM	0x4000	/* b14: Resume interrupt */
+#define	SOFR	0x2000	/* b13: SOF frame update interrupt */
+#define	DVST	0x1000	/* b12: Device state transition interrupt */
+#define	CTRT	0x0800	/* b11: Control transfer stage transition interrupt */
+#define	BEMP	0x0400	/* b10: Buffer empty interrupt */
+#define	NRDY	0x0200	/* b9: Buffer not ready interrupt */
+#define	BRDY	0x0100	/* b8: Buffer ready interrupt */
+#define	VBSTS	0x0080	/* b7: VBUS input port */
+#define	DVSQ	0x0070	/* b6-4: Device state */
+#define	  DS_SPD_CNFG	 0x0070	  /* Suspend Configured */
+#define	  DS_SPD_ADDR	 0x0060	  /* Suspend Address */
+#define	  DS_SPD_DFLT	 0x0050	  /* Suspend Default */
+#define	  DS_SPD_POWR	 0x0040	  /* Suspend Powered */
+#define	  DS_SUSP	 0x0040	  /* Suspend */
+#define	  DS_CNFG	 0x0030	  /* Configured */
+#define	  DS_ADDS	 0x0020	  /* Address */
+#define	  DS_DFLT	 0x0010	  /* Default */
+#define	  DS_POWR	 0x0000	  /* Powered */
+#define	DVSQS		0x0030	/* b5-4: Device state */
+#define	VALID		0x0008	/* b3: Setup packet detected flag */
+#define	CTSQ		0x0007	/* b2-0: Control transfer stage */
+#define	  CS_SQER	 0x0006	  /* Sequence error */
+#define	  CS_WRND	 0x0005	  /* Control write nodata status stage */
+#define	  CS_WRSS	 0x0004	  /* Control write status stage */
+#define	  CS_WRDS	 0x0003	  /* Control write data stage */
+#define	  CS_RDSS	 0x0002	  /* Control read status stage */
+#define	  CS_RDDS	 0x0001	  /* Control read data stage */
+#define	  CS_IDST	 0x0000	  /* Idle or setup stage */
+
+/* Interrupt Status Register 1 */
+#define	OVRCR		0x8000	/* b15: Over-current interrupt */
+#define	BCHG		0x4000	/* b14: USB bus chenge interrupt */
+#define	DTCH		0x1000	/* b12: Detach sense interrupt */
+#define	ATTCH		0x0800	/* b11: Attach sense interrupt */
+#define	EOFERR		0x0040	/* b6: EOF-error interrupt */
+#define	SIGN		0x0020	/* b5: Setup ignore interrupt */
+#define	SACK		0x0010	/* b4: Setup acknowledge interrupt */
+
+/* Frame Number Register */
+#define	OVRN		0x8000	/* b15: Overrun error */
+#define	CRCE		0x4000	/* b14: Received data error */
+#define	FRNM		0x07FF	/* b10-0: Frame number */
+
+/* Micro Frame Number Register */
+#define	UFRNM		0x0007	/* b2-0: Micro frame number */
+
+/* Default Control Pipe Maxpacket Size Register */
+/* Pipe Maxpacket Size Register */
+#define	DEVSEL	0xF000	/* b15-14: Device address select */
+#define	MAXP	0x007F	/* b6-0: Maxpacket size of default control pipe */
+
+/* Default Control Pipe Control Register */
+#define	BSTS		0x8000	/* b15: Buffer status */
+#define	SUREQ		0x4000	/* b14: Send USB request  */
+#define	CSCLR		0x2000	/* b13: complete-split status clear */
+#define	CSSTS		0x1000	/* b12: complete-split status */
+#define	SUREQCLR	0x0800	/* b11: stop setup request */
+#define	SQCLR		0x0100	/* b8: Sequence toggle bit clear */
+#define	SQSET		0x0080	/* b7: Sequence toggle bit set */
+#define	SQMON		0x0040	/* b6: Sequence toggle bit monitor */
+#define	PBUSY		0x0020	/* b5: pipe busy */
+#define	PINGE		0x0010	/* b4: ping enable */
+#define	CCPL		0x0004	/* b2: Enable control transfer complete */
+#define	PID		0x0003	/* b1-0: Response PID */
+#define	  PID_STALL11	 0x0003	  /* STALL */
+#define	  PID_STALL	 0x0002	  /* STALL */
+#define	  PID_BUF	 0x0001	  /* BUF */
+#define	  PID_NAK	 0x0000	  /* NAK */
+
+/* Pipe Window Select Register */
+#define	PIPENM		0x0007	/* b2-0: Pipe select */
+
+/* Pipe Configuration Register */
+#define	R8A66597_TYP	0xC000	/* b15-14: Transfer type */
+#define	  R8A66597_ISO	 0xC000		  /* Isochronous */
+#define	  R8A66597_INT	 0x8000		  /* Interrupt */
+#define	  R8A66597_BULK	 0x4000		  /* Bulk */
+#define	R8A66597_BFRE	0x0400	/* b10: Buffer ready interrupt mode select */
+#define	R8A66597_DBLB	0x0200	/* b9: Double buffer mode select */
+#define	R8A66597_CNTMD	0x0100	/* b8: Continuous transfer mode select */
+#define	R8A66597_SHTNAK	0x0080	/* b7: Transfer end NAK */
+#define	R8A66597_DIR	0x0010	/* b4: Transfer direction select */
+#define	R8A66597_EPNUM	0x000F	/* b3-0: Eendpoint number select */
+
+/* Pipe Buffer Configuration Register */
+#define	BUFSIZE		0x7C00	/* b14-10: Pipe buffer size */
+#define	BUFNMB		0x007F	/* b6-0: Pipe buffer number */
+#define	PIPE0BUF	256
+#define	PIPExBUF	64
+
+/* Pipe Maxpacket Size Register */
+#define	MXPS		0x07FF	/* b10-0: Maxpacket size */
+
+/* Pipe Cycle Configuration Register */
+#define	IFIS	0x1000	/* b12: Isochronous in-buffer flush mode select */
+#define	IITV	0x0007	/* b2-0: Isochronous interval */
+
+/* Pipex Control Register */
+#define	BSTS	0x8000	/* b15: Buffer status */
+#define	INBUFM	0x4000	/* b14: IN buffer monitor (Only for PIPE1 to 5) */
+#define	CSCLR	0x2000	/* b13: complete-split status clear */
+#define	CSSTS	0x1000	/* b12: complete-split status */
+#define	ATREPM	0x0400	/* b10: Auto repeat mode */
+#define	ACLRM	0x0200	/* b9: Out buffer auto clear mode */
+#define	SQCLR	0x0100	/* b8: Sequence toggle bit clear */
+#define	SQSET	0x0080	/* b7: Sequence toggle bit set */
+#define	SQMON	0x0040	/* b6: Sequence toggle bit monitor */
+#define	PBUSY	0x0020	/* b5: pipe busy */
+#define	PID	0x0003	/* b1-0: Response PID */
+
+/* PIPExTRE */
+#define	TRENB		0x0200	/* b9: Transaction counter enable */
+#define	TRCLR		0x0100	/* b8: Transaction counter clear */
+
+/* PIPExTRN */
+#define	TRNCNT		0xFFFF	/* b15-0: Transaction counter */
+
+/* DEVADDx */
+#define	UPPHUB		0x7800
+#define	HUBPORT		0x0700
+#define	USBSPD		0x00C0
+#define	RTPORT		0x0001
+
+#endif /* __LINUX_USB_R8A66597_H */