Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (110 commits)
  sh: i2c-sh7760: Replase from ctrl_* to __raw_*
  sh: clkfwk: Shuffle around to match the intc split up.
  sh: clkfwk: modify for_each_frequency end condition
  sh: fix clk_get() error handling
  sh: clkfwk: Fix fault in frequency iterator.
  sh: clkfwk: Add a helper for rate rounding by divisor ranges.
  sh: clkfwk: Abstract rate rounding helper.
  sh: clkfwk: support clock remapping.
  sh: pci: Convert to upper/lower_32_bits() helpers.
  sh: mach-sdk7786: Add support for the FPGA SRAM.
  sh: Provide a generic SRAM pool for tiny memories.
  sh: pci: Support secondary FPGA-driven PCIe clocks on SDK7786.
  sh: pci: Support slot 4 routing on SDK7786.
  sh: Fix up PMB locking.
  sh: mach-sdk7786: Add support for fpga gpios.
  sh: use pr_fmt for clock framework, too.
  sh: remove name and id from struct clk
  sh: free-without-alloc fix for sh_mobile_lcdcfb
  sh: perf: Set up perf_max_events.
  sh: perf: Support SH-X3 hardware counters.
  ...

Fix up trivial conflicts (perf_max_events got removed) in arch/sh/kernel/perf_event.c
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 35b6879..0f40fc3 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -24,6 +24,7 @@
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_REGS_AND_STACK_ACCESS_API
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	help
@@ -46,7 +47,7 @@
 	select HAVE_ARCH_KGDB
 	select HAVE_HW_BREAKPOINT
 	select HAVE_MIXED_BREAKPOINTS_REGS
-	select PERF_EVENTS if HAVE_HW_BREAKPOINT
+	select PERF_EVENTS
 	select ARCH_HIBERNATION_POSSIBLE if MMU
 
 config SUPERH64
@@ -471,6 +472,7 @@
 	select CPU_SH4A
 	select CPU_SHX3
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+	select ARCH_REQUIRE_GPIOLIB
 
 # SH4AL-DSP Processor Support
 
@@ -575,7 +577,7 @@
 config SH_CLK_CPG_LEGACY
 	depends on SH_CLK_CPG
 	def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
-		      !CPU_SUBTYPE_SH7786
+		      !CPU_SHX3 && !CPU_SUBTYPE_SH7757
 
 config SH_CLK_MD
 	int "CPU Mode Pin Setting"
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 07b35ca..9c94711 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -155,6 +155,8 @@
 	depends on CPU_SUBTYPE_SH7786
 	select SYS_SUPPORTS_PCI
 	select NO_IOPORT if !PCI
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select HAVE_SRAM_POOL
 	help
 	  Select SDK7786 if configuring for a Renesas Technology Europe
 	  SH7786-65nm board.
@@ -165,6 +167,11 @@
 	select SYS_SUPPORTS_PCI
 	select IO_TRAPPED if MMU
 
+config SH_SH7757LCR
+	bool "SH7757LCR"
+	depends on CPU_SUBTYPE_SH7757
+	select ARCH_REQUIRE_GPIOLIB
+
 config SH_SH7785LCR
 	bool "SH7785LCR"
 	depends on CPU_SUBTYPE_SH7785
@@ -309,6 +316,17 @@
 	help
 	  Select if configuring for an SMSC Polaris development board
 
+config SH_SH2007
+	bool "SH-2007 board"
+	select NO_IOPORT
+	depends on CPU_SUBTYPE_SH7780
+	help
+	  SH-2007 is a single-board computer based around SH7780 chip
+	  intended for embedded applications.
+	  It has an Ethernet interface (SMC9118), direct connected
+	  Compact Flash socket, two serial ports and PC-104 bus.
+	  More information at <http://sh2000.sh-linux.org>.
+
 endmenu
 
 source "arch/sh/boards/mach-r2d/Kconfig"
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 4f90f9b..38ef655 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -2,6 +2,7 @@
 # Specific board support, not covered by a mach group.
 #
 obj-$(CONFIG_SH_MAGIC_PANEL_R2)	+= board-magicpanelr2.o
+obj-$(CONFIG_SH_SH2007)		+= board-sh2007.o
 obj-$(CONFIG_SH_SH7785LCR)	+= board-sh7785lcr.o
 obj-$(CONFIG_SH_URQUELL)	+= board-urquell.o
 obj-$(CONFIG_SH_SHMIN)		+= board-shmin.o
@@ -9,3 +10,4 @@
 obj-$(CONFIG_SH_ESPT)		+= board-espt.o
 obj-$(CONFIG_SH_POLARIS)	+= board-polaris.o
 obj-$(CONFIG_SH_TITAN)		+= board-titan.o
+obj-$(CONFIG_SH_SH7757LCR)	+= board-sh7757lcr.o
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c
new file mode 100644
index 0000000..b90b78f
--- /dev/null
+++ b/arch/sh/boards/board-sh2007.c
@@ -0,0 +1,133 @@
+/*
+ * SH-2007 board support.
+ *
+ * Copyright (C) 2003, 2004  SUGIOKA Toshinobu
+ * Copyright (C) 2010  Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <mach/sh2007.h>
+
+struct smsc911x_platform_config smc911x_info = {
+	.flags		= SMSC911X_USE_32BIT,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct resource smsc9118_0_resources[] = {
+	[0] = {
+		.start	= SMC0_BASE,
+		.end	= SMC0_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= evt2irq(0x240),
+		.end	= evt2irq(0x240),
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct resource smsc9118_1_resources[] = {
+	[0] = {
+		.start	= SMC1_BASE,
+		.end	= SMC1_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= evt2irq(0x280),
+		.end	= evt2irq(0x280),
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smsc9118_0_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smsc9118_0_resources),
+	.resource	= smsc9118_0_resources,
+	.dev = {
+		.platform_data = &smc911x_info,
+	},
+};
+
+static struct platform_device smsc9118_1_device = {
+	.name		= "smsc911x",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(smsc9118_1_resources),
+	.resource	= smsc9118_1_resources,
+	.dev = {
+		.platform_data = &smc911x_info,
+	},
+};
+
+static struct resource cf_resources[] = {
+	[0] = {
+		.start	= CF_BASE + CF_OFFSET,
+		.end	= CF_BASE + CF_OFFSET + 0x0f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= CF_BASE + CF_OFFSET + 0x206,
+		.end	= CF_BASE + CF_OFFSET + 0x20f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= evt2irq(0x2c0),
+		.end	= evt2irq(0x2c0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cf_device  = {
+	.name		= "pata_platform",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(cf_resources),
+	.resource	= cf_resources,
+};
+
+static struct platform_device *sh2007_devices[] __initdata = {
+	&smsc9118_0_device,
+	&smsc9118_1_device,
+	&cf_device,
+};
+
+static int __init sh2007_io_init(void)
+{
+	platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices));
+	return 0;
+}
+subsys_initcall(sh2007_io_init);
+
+static void __init sh2007_init_irq(void)
+{
+	plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init sh2007_setup(char **cmdline_p)
+{
+	printk(KERN_INFO "SH-2007 Setup...");
+
+	/* setup wait control registers for area 5 */
+	__raw_writel(CS5BCR_D, CS5BCR);
+	__raw_writel(CS5WCR_D, CS5WCR);
+	__raw_writel(CS5PCR_D, CS5PCR);
+
+	printk(KERN_INFO " done.\n");
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_sh2007 __initmv = {
+	.mv_setup		= sh2007_setup,
+	.mv_name		= "sh2007",
+	.mv_init_irq		= sh2007_init_irq,
+};
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
new file mode 100644
index 0000000..c475f10
--- /dev/null
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -0,0 +1,374 @@
+/*
+ * Renesas R0P7757LC0012RL Support.
+ *
+ * Copyright (C) 2009 - 2010  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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/io.h>
+#include <cpu/sh7757.h>
+#include <asm/sh_eth.h>
+#include <asm/heartbeat.h>
+
+static struct resource heartbeat_resource = {
+	.start	= 0xffec005c,	/* PUDR */
+	.end	= 0xffec005c,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+	.bit_pos	= heartbeat_bit_pos,
+	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
+	.flags		= HEARTBEAT_INVERTED,
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= &heartbeat_data,
+	},
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
+};
+
+/* Fast Ethernet */
+static struct resource sh_eth0_resources[] = {
+	{
+		.start  = 0xfef00000,
+		.end    = 0xfef001ff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = 84,
+		.end    = 84,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct sh_eth_plat_data sh7757_eth0_pdata = {
+	.phy = 1,
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth0_device = {
+	.name		= "sh-eth",
+	.resource	= sh_eth0_resources,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(sh_eth0_resources),
+	.dev		= {
+		.platform_data = &sh7757_eth0_pdata,
+	},
+};
+
+static struct resource sh_eth1_resources[] = {
+	{
+		.start  = 0xfef00800,
+		.end    = 0xfef009ff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = 84,
+		.end    = 84,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct sh_eth_plat_data sh7757_eth1_pdata = {
+	.phy = 1,
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth1_device = {
+	.name		= "sh-eth",
+	.resource	= sh_eth1_resources,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(sh_eth1_resources),
+	.dev		= {
+		.platform_data = &sh7757_eth1_pdata,
+	},
+};
+
+static struct platform_device *sh7757lcr_devices[] __initdata = {
+	&heartbeat_device,
+	&sh7757_eth0_device,
+	&sh7757_eth1_device,
+};
+
+static int __init sh7757lcr_devices_setup(void)
+{
+	/* RGMII (PTA) */
+	gpio_request(GPIO_FN_ET0_MDC, NULL);
+	gpio_request(GPIO_FN_ET0_MDIO, NULL);
+	gpio_request(GPIO_FN_ET1_MDC, NULL);
+	gpio_request(GPIO_FN_ET1_MDIO, NULL);
+
+	/* ONFI (PTB, PTZ) */
+	gpio_request(GPIO_FN_ON_NRE, NULL);
+	gpio_request(GPIO_FN_ON_NWE, NULL);
+	gpio_request(GPIO_FN_ON_NWP, NULL);
+	gpio_request(GPIO_FN_ON_NCE0, NULL);
+	gpio_request(GPIO_FN_ON_R_B0, NULL);
+	gpio_request(GPIO_FN_ON_ALE, NULL);
+	gpio_request(GPIO_FN_ON_CLE, NULL);
+
+	gpio_request(GPIO_FN_ON_DQ7, NULL);
+	gpio_request(GPIO_FN_ON_DQ6, NULL);
+	gpio_request(GPIO_FN_ON_DQ5, NULL);
+	gpio_request(GPIO_FN_ON_DQ4, NULL);
+	gpio_request(GPIO_FN_ON_DQ3, NULL);
+	gpio_request(GPIO_FN_ON_DQ2, NULL);
+	gpio_request(GPIO_FN_ON_DQ1, NULL);
+	gpio_request(GPIO_FN_ON_DQ0, NULL);
+
+	/* IRQ8 to 0 (PTB, PTC) */
+	gpio_request(GPIO_FN_IRQ8, NULL);
+	gpio_request(GPIO_FN_IRQ7, NULL);
+	gpio_request(GPIO_FN_IRQ6, NULL);
+	gpio_request(GPIO_FN_IRQ5, NULL);
+	gpio_request(GPIO_FN_IRQ4, NULL);
+	gpio_request(GPIO_FN_IRQ3, NULL);
+	gpio_request(GPIO_FN_IRQ2, NULL);
+	gpio_request(GPIO_FN_IRQ1, NULL);
+	gpio_request(GPIO_FN_IRQ0, NULL);
+
+	/* SPI0 (PTD) */
+	gpio_request(GPIO_FN_SP0_MOSI, NULL);
+	gpio_request(GPIO_FN_SP0_MISO, NULL);
+	gpio_request(GPIO_FN_SP0_SCK, NULL);
+	gpio_request(GPIO_FN_SP0_SCK_FB, NULL);
+	gpio_request(GPIO_FN_SP0_SS0, NULL);
+	gpio_request(GPIO_FN_SP0_SS1, NULL);
+	gpio_request(GPIO_FN_SP0_SS2, NULL);
+	gpio_request(GPIO_FN_SP0_SS3, NULL);
+
+	/* RMII 0/1 (PTE, PTF) */
+	gpio_request(GPIO_FN_RMII0_CRS_DV, NULL);
+	gpio_request(GPIO_FN_RMII0_TXD1, NULL);
+	gpio_request(GPIO_FN_RMII0_TXD0, NULL);
+	gpio_request(GPIO_FN_RMII0_TXEN, NULL);
+	gpio_request(GPIO_FN_RMII0_REFCLK, NULL);
+	gpio_request(GPIO_FN_RMII0_RXD1, NULL);
+	gpio_request(GPIO_FN_RMII0_RXD0, NULL);
+	gpio_request(GPIO_FN_RMII0_RX_ER, NULL);
+	gpio_request(GPIO_FN_RMII1_CRS_DV, NULL);
+	gpio_request(GPIO_FN_RMII1_TXD1, NULL);
+	gpio_request(GPIO_FN_RMII1_TXD0, NULL);
+	gpio_request(GPIO_FN_RMII1_TXEN, NULL);
+	gpio_request(GPIO_FN_RMII1_REFCLK, NULL);
+	gpio_request(GPIO_FN_RMII1_RXD1, NULL);
+	gpio_request(GPIO_FN_RMII1_RXD0, NULL);
+	gpio_request(GPIO_FN_RMII1_RX_ER, NULL);
+
+	/* eMMC (PTG) */
+	gpio_request(GPIO_FN_MMCCLK, NULL);
+	gpio_request(GPIO_FN_MMCCMD, NULL);
+	gpio_request(GPIO_FN_MMCDAT7, NULL);
+	gpio_request(GPIO_FN_MMCDAT6, NULL);
+	gpio_request(GPIO_FN_MMCDAT5, NULL);
+	gpio_request(GPIO_FN_MMCDAT4, NULL);
+	gpio_request(GPIO_FN_MMCDAT3, NULL);
+	gpio_request(GPIO_FN_MMCDAT2, NULL);
+	gpio_request(GPIO_FN_MMCDAT1, NULL);
+	gpio_request(GPIO_FN_MMCDAT0, NULL);
+
+	/* LPC (PTG, PTH, PTQ, PTU) */
+	gpio_request(GPIO_FN_SERIRQ, NULL);
+	gpio_request(GPIO_FN_LPCPD, NULL);
+	gpio_request(GPIO_FN_LDRQ, NULL);
+	gpio_request(GPIO_FN_WP, NULL);
+	gpio_request(GPIO_FN_FMS0, NULL);
+	gpio_request(GPIO_FN_LAD3, NULL);
+	gpio_request(GPIO_FN_LAD2, NULL);
+	gpio_request(GPIO_FN_LAD1, NULL);
+	gpio_request(GPIO_FN_LAD0, NULL);
+	gpio_request(GPIO_FN_LFRAME, NULL);
+	gpio_request(GPIO_FN_LRESET, NULL);
+	gpio_request(GPIO_FN_LCLK, NULL);
+	gpio_request(GPIO_FN_LGPIO7, NULL);
+	gpio_request(GPIO_FN_LGPIO6, NULL);
+	gpio_request(GPIO_FN_LGPIO5, NULL);
+	gpio_request(GPIO_FN_LGPIO4, NULL);
+
+	/* SPI1 (PTH) */
+	gpio_request(GPIO_FN_SP1_MOSI, NULL);
+	gpio_request(GPIO_FN_SP1_MISO, NULL);
+	gpio_request(GPIO_FN_SP1_SCK, NULL);
+	gpio_request(GPIO_FN_SP1_SCK_FB, NULL);
+	gpio_request(GPIO_FN_SP1_SS0, NULL);
+	gpio_request(GPIO_FN_SP1_SS1, NULL);
+
+	/* SDHI (PTI) */
+	gpio_request(GPIO_FN_SD_WP, NULL);
+	gpio_request(GPIO_FN_SD_CD, NULL);
+	gpio_request(GPIO_FN_SD_CLK, NULL);
+	gpio_request(GPIO_FN_SD_CMD, NULL);
+	gpio_request(GPIO_FN_SD_D3, NULL);
+	gpio_request(GPIO_FN_SD_D2, NULL);
+	gpio_request(GPIO_FN_SD_D1, NULL);
+	gpio_request(GPIO_FN_SD_D0, NULL);
+
+	/* SCIF3/4 (PTJ, PTW) */
+	gpio_request(GPIO_FN_RTS3, NULL);
+	gpio_request(GPIO_FN_CTS3, NULL);
+	gpio_request(GPIO_FN_TXD3, NULL);
+	gpio_request(GPIO_FN_RXD3, NULL);
+	gpio_request(GPIO_FN_RTS4, NULL);
+	gpio_request(GPIO_FN_RXD4, NULL);
+	gpio_request(GPIO_FN_TXD4, NULL);
+	gpio_request(GPIO_FN_CTS4, NULL);
+
+	/* SERMUX (PTK, PTL, PTO, PTV) */
+	gpio_request(GPIO_FN_COM2_TXD, NULL);
+	gpio_request(GPIO_FN_COM2_RXD, NULL);
+	gpio_request(GPIO_FN_COM2_RTS, NULL);
+	gpio_request(GPIO_FN_COM2_CTS, NULL);
+	gpio_request(GPIO_FN_COM2_DTR, NULL);
+	gpio_request(GPIO_FN_COM2_DSR, NULL);
+	gpio_request(GPIO_FN_COM2_DCD, NULL);
+	gpio_request(GPIO_FN_COM2_RI, NULL);
+	gpio_request(GPIO_FN_RAC_RXD, NULL);
+	gpio_request(GPIO_FN_RAC_RTS, NULL);
+	gpio_request(GPIO_FN_RAC_CTS, NULL);
+	gpio_request(GPIO_FN_RAC_DTR, NULL);
+	gpio_request(GPIO_FN_RAC_DSR, NULL);
+	gpio_request(GPIO_FN_RAC_DCD, NULL);
+	gpio_request(GPIO_FN_RAC_TXD, NULL);
+	gpio_request(GPIO_FN_COM1_TXD, NULL);
+	gpio_request(GPIO_FN_COM1_RXD, NULL);
+	gpio_request(GPIO_FN_COM1_RTS, NULL);
+	gpio_request(GPIO_FN_COM1_CTS, NULL);
+
+	writeb(0x10, 0xfe470000);	/* SMR0: SerMux mode 0 */
+
+	/* IIC (PTM, PTR, PTS) */
+	gpio_request(GPIO_FN_SDA7, NULL);
+	gpio_request(GPIO_FN_SCL7, NULL);
+	gpio_request(GPIO_FN_SDA6, NULL);
+	gpio_request(GPIO_FN_SCL6, NULL);
+	gpio_request(GPIO_FN_SDA5, NULL);
+	gpio_request(GPIO_FN_SCL5, NULL);
+	gpio_request(GPIO_FN_SDA4, NULL);
+	gpio_request(GPIO_FN_SCL4, NULL);
+	gpio_request(GPIO_FN_SDA3, NULL);
+	gpio_request(GPIO_FN_SCL3, NULL);
+	gpio_request(GPIO_FN_SDA2, NULL);
+	gpio_request(GPIO_FN_SCL2, NULL);
+	gpio_request(GPIO_FN_SDA1, NULL);
+	gpio_request(GPIO_FN_SCL1, NULL);
+	gpio_request(GPIO_FN_SDA0, NULL);
+	gpio_request(GPIO_FN_SCL0, NULL);
+
+	/* USB (PTN) */
+	gpio_request(GPIO_FN_VBUS_EN, NULL);
+	gpio_request(GPIO_FN_VBUS_OC, NULL);
+
+	/* SGPIO1/0 (PTN, PTO) */
+	gpio_request(GPIO_FN_SGPIO1_CLK, NULL);
+	gpio_request(GPIO_FN_SGPIO1_LOAD, NULL);
+	gpio_request(GPIO_FN_SGPIO1_DI, NULL);
+	gpio_request(GPIO_FN_SGPIO1_DO, NULL);
+	gpio_request(GPIO_FN_SGPIO0_CLK, NULL);
+	gpio_request(GPIO_FN_SGPIO0_LOAD, NULL);
+	gpio_request(GPIO_FN_SGPIO0_DI, NULL);
+	gpio_request(GPIO_FN_SGPIO0_DO, NULL);
+
+	/* WDT (PTN) */
+	gpio_request(GPIO_FN_SUB_CLKIN, NULL);
+
+	/* System (PTT) */
+	gpio_request(GPIO_FN_STATUS1, NULL);
+	gpio_request(GPIO_FN_STATUS0, NULL);
+
+	/* PWMX (PTT) */
+	gpio_request(GPIO_FN_PWMX1, NULL);
+	gpio_request(GPIO_FN_PWMX0, NULL);
+
+	/* R-SPI (PTV) */
+	gpio_request(GPIO_FN_R_SPI_MOSI, NULL);
+	gpio_request(GPIO_FN_R_SPI_MISO, NULL);
+	gpio_request(GPIO_FN_R_SPI_RSPCK, NULL);
+	gpio_request(GPIO_FN_R_SPI_SSL0, NULL);
+	gpio_request(GPIO_FN_R_SPI_SSL1, NULL);
+
+	/* EVC (PTV, PTW) */
+	gpio_request(GPIO_FN_EVENT7, NULL);
+	gpio_request(GPIO_FN_EVENT6, NULL);
+	gpio_request(GPIO_FN_EVENT5, NULL);
+	gpio_request(GPIO_FN_EVENT4, NULL);
+	gpio_request(GPIO_FN_EVENT3, NULL);
+	gpio_request(GPIO_FN_EVENT2, NULL);
+	gpio_request(GPIO_FN_EVENT1, NULL);
+	gpio_request(GPIO_FN_EVENT0, NULL);
+
+	/* LED for heartbeat */
+	gpio_request(GPIO_PTU3, NULL);
+	gpio_direction_output(GPIO_PTU3, 1);
+	gpio_request(GPIO_PTU2, NULL);
+	gpio_direction_output(GPIO_PTU2, 1);
+	gpio_request(GPIO_PTU1, NULL);
+	gpio_direction_output(GPIO_PTU1, 1);
+	gpio_request(GPIO_PTU0, NULL);
+	gpio_direction_output(GPIO_PTU0, 1);
+
+	/* control for MDIO of Gigabit Ethernet */
+	gpio_request(GPIO_PTT4, NULL);
+	gpio_direction_output(GPIO_PTT4, 1);
+
+	/* control for eMMC */
+	gpio_request(GPIO_PTT7, NULL);		/* eMMC_RST# */
+	gpio_direction_output(GPIO_PTT7, 0);
+	gpio_request(GPIO_PTT6, NULL);		/* eMMC_INDEX# */
+	gpio_direction_output(GPIO_PTT6, 0);
+	gpio_request(GPIO_PTT5, NULL);		/* eMMC_PRST# */
+	gpio_direction_output(GPIO_PTT5, 1);
+
+	/* General platform */
+	return platform_add_devices(sh7757lcr_devices,
+				    ARRAY_SIZE(sh7757lcr_devices));
+}
+arch_initcall(sh7757lcr_devices_setup);
+
+/* Initialize IRQ setting */
+void __init init_sh7757lcr_IRQ(void)
+{
+	plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+	plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+/* Initialize the board */
+static void __init sh7757lcr_setup(char **cmdline_p)
+{
+	printk(KERN_INFO "Renesas R0P7757LC0012RL support.\n");
+}
+
+static int sh7757lcr_mode_pins(void)
+{
+	int value = 0;
+
+	/* These are the factory default settings of S3 (Low active).
+	 * If you change these dip switches then you will need to
+	 * adjust the values below as well.
+	 */
+	value |= MODE_PIN0;	/* Clock Mode: 1 */
+
+	return value;
+}
+
+/* The Machine Vector */
+static struct sh_machine_vector mv_sh7757lcr __initmv = {
+	.mv_name		= "SH7757LCR",
+	.mv_setup		= sh7757lcr_setup,
+	.mv_init_irq		= init_sh7757lcr_IRQ,
+	.mv_mode_pins		= sh7757lcr_mode_pins,
+};
+
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 1d7b495..71a3368 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -1248,14 +1248,14 @@
 
 	/* set SPU2 clock to 83.4 MHz */
 	clk = clk_get(NULL, "spu_clk");
-	if (clk) {
+	if (!IS_ERR(clk)) {
 		clk_set_rate(clk, clk_round_rate(clk, 83333333));
 		clk_put(clk);
 	}
 
 	/* change parent of FSI B */
 	clk = clk_get(NULL, "fsib_clk");
-	if (clk) {
+	if (!IS_ERR(clk)) {
 		clk_register(&fsimckb_clk);
 		clk_set_parent(clk, &fsimckb_clk);
 		clk_set_rate(clk, 11000);
@@ -1273,7 +1273,7 @@
 
 	/* set VPU clock to 166 MHz */
 	clk = clk_get(NULL, "vpu_clk");
-	if (clk) {
+	if (!IS_ERR(clk)) {
 		clk_set_rate(clk, clk_round_rate(clk, 166000000));
 		clk_put(clk);
 	}
diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile
index a29f19e..23ff7d4 100644
--- a/arch/sh/boards/mach-sdk7786/Makefile
+++ b/arch/sh/boards/mach-sdk7786/Makefile
@@ -1 +1,4 @@
-obj-y	:= setup.o fpga.o irq.o
+obj-y	:= fpga.o irq.o setup.o
+
+obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
+obj-$(CONFIG_HAVE_SRAM_POOL)	+= sram.o
diff --git a/arch/sh/boards/mach-sdk7786/gpio.c b/arch/sh/boards/mach-sdk7786/gpio.c
new file mode 100644
index 0000000..f71ce09
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * SDK7786 FPGA USRGPIR Support.
+ *
+ * Copyright (C) 2010  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/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/fpga.h>
+
+#define NR_FPGA_GPIOS	8
+
+static const char *usrgpir_gpio_names[NR_FPGA_GPIOS] = {
+	"in0", "in1", "in2", "in3", "in4", "in5", "in6", "in7",
+};
+
+static int usrgpir_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	/* always in */
+	return 0;
+}
+
+static int usrgpir_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+	return !!(fpga_read_reg(USRGPIR) & (1 << gpio));
+}
+
+static struct gpio_chip usrgpir_gpio_chip = {
+	.label			= "sdk7786-fpga",
+	.names			= usrgpir_gpio_names,
+	.direction_input	= usrgpir_gpio_direction_input,
+	.get			= usrgpir_gpio_get,
+	.base			= -1, /* don't care */
+	.ngpio			= NR_FPGA_GPIOS,
+};
+
+static int __init usrgpir_gpio_setup(void)
+{
+	return gpiochip_add(&usrgpir_gpio_chip);
+}
+device_initcall(usrgpir_gpio_setup);
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
index 2ec1ea5..7e0c4e3 100644
--- a/arch/sh/boards/mach-sdk7786/setup.c
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -20,6 +20,8 @@
 #include <asm/machvec.h>
 #include <asm/heartbeat.h>
 #include <asm/sizes.h>
+#include <asm/clock.h>
+#include <asm/clkdev.h>
 #include <asm/reboot.h>
 #include <asm/smp-ops.h>
 
@@ -140,6 +142,45 @@
 	return fpga_read_reg(MODSWR);
 }
 
+/*
+ * FPGA-driven PCIe clocks
+ *
+ * Historically these include the oscillator, clock B (slots 2/3/4) and
+ * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
+ * everything under a single PCIe clocks enable bit that happens to map
+ * to the same bit position as the oscillator bit for earlier FPGA
+ * versions.
+ *
+ * Given that the legacy clocks have the side-effect of shutting the CPU
+ * off through the FPGA along with the PCI slots, we simply leave them in
+ * their initial state and don't bother registering them with the clock
+ * framework.
+ */
+static int sdk7786_pcie_clk_enable(struct clk *clk)
+{
+	fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
+	return 0;
+}
+
+static void sdk7786_pcie_clk_disable(struct clk *clk)
+{
+	fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
+}
+
+static struct clk_ops sdk7786_pcie_clk_ops = {
+	.enable		= sdk7786_pcie_clk_enable,
+	.disable	= sdk7786_pcie_clk_disable,
+};
+
+static struct clk sdk7786_pcie_clk = {
+	.ops		= &sdk7786_pcie_clk_ops,
+};
+
+static struct clk_lookup sdk7786_pcie_cl = {
+	.con_id		= "pcie_plat_clk",
+	.clk		= &sdk7786_pcie_clk,
+};
+
 static int sdk7786_clk_init(void)
 {
 	struct clk *clk;
@@ -158,7 +199,18 @@
 	ret = clk_set_rate(clk, 33333333);
 	clk_put(clk);
 
-	return ret;
+	/*
+	 * Setup the FPGA clocks.
+	 */
+	ret = clk_register(&sdk7786_pcie_clk);
+	if (unlikely(ret)) {
+		pr_err("FPGA clock registration failed\n");
+		return ret;
+	}
+
+	clkdev_add(&sdk7786_pcie_cl);
+
+	return 0;
 }
 
 static void sdk7786_restart(char *cmd)
diff --git a/arch/sh/boards/mach-sdk7786/sram.c b/arch/sh/boards/mach-sdk7786/sram.c
new file mode 100644
index 0000000..c81c3ab
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/sram.c
@@ -0,0 +1,72 @@
+/*
+ * SDK7786 FPGA SRAM Support.
+ *
+ * Copyright (C) 2010  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.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+#include <asm/sram.h>
+#include <asm/sizes.h>
+
+static int __init fpga_sram_init(void)
+{
+	unsigned long phys;
+	unsigned int area;
+	void __iomem *vaddr;
+	int ret;
+	u16 data;
+
+	/* Enable FPGA SRAM */
+	data = fpga_read_reg(LCLASR);
+	data |= LCLASR_FRAMEN;
+	fpga_write_reg(data, LCLASR);
+
+	/*
+	 * FPGA_SEL determines the area mapping
+	 */
+	area = (data & LCLASR_FPGA_SEL_MASK) >> LCLASR_FPGA_SEL_SHIFT;
+	if (unlikely(area == LCLASR_AREA_MASK)) {
+		pr_err("FPGA memory unmapped.\n");
+		return -ENXIO;
+	}
+
+	/*
+	 * The memory itself occupies a 2KiB range at the top of the area
+	 * immediately below the system registers.
+	 */
+	phys = (area << 26) + SZ_64M - SZ_4K;
+
+	/*
+	 * The FPGA SRAM resides in translatable physical space, so set
+	 * up a mapping prior to inserting it in to the pool.
+	 */
+	vaddr = ioremap(phys, SZ_2K);
+	if (unlikely(!vaddr)) {
+		pr_err("Failed remapping FPGA memory.\n");
+		return -ENXIO;
+	}
+
+	pr_info("Adding %dKiB of FPGA memory at 0x%08lx-0x%08lx "
+		"(area %d) to pool.\n",
+		SZ_2K >> 10, phys, phys + SZ_2K - 1, area);
+
+	ret = gen_pool_add(sram_pool, (unsigned long)vaddr, SZ_2K, -1);
+	if (unlikely(ret < 0)) {
+		pr_err("Failed adding memory\n");
+		iounmap(vaddr);
+		return ret;
+	}
+
+	return 0;
+}
+postcore_initcall(fpga_sram_init);
diff --git a/arch/sh/boards/mach-x3proto/Makefile b/arch/sh/boards/mach-x3proto/Makefile
index 983e455..708c21c 100644
--- a/arch/sh/boards/mach-x3proto/Makefile
+++ b/arch/sh/boards/mach-x3proto/Makefile
@@ -1 +1,3 @@
 obj-y += setup.o ilsel.o
+
+obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c
new file mode 100644
index 0000000..594adf7
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -0,0 +1,135 @@
+/*
+ * arch/sh/boards/mach-x3proto/gpio.c
+ *
+ * Renesas SH-X3 Prototype Baseboard GPIO Support.
+ *
+ * Copyright (C) 2010  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.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
+
+#define KEYCTLR	0xb81c0000
+#define KEYOUTR	0xb81c0002
+#define KEYDETR 0xb81c0004
+
+static DEFINE_SPINLOCK(x3proto_gpio_lock);
+static unsigned int x3proto_gpio_irq_map[NR_BASEBOARD_GPIOS] = { 0, };
+
+static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	unsigned long flags;
+	unsigned int data;
+
+	spin_lock_irqsave(&x3proto_gpio_lock, flags);
+	data = __raw_readw(KEYCTLR);
+	data |= (1 << gpio);
+	__raw_writew(data, KEYCTLR);
+	spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
+
+	return 0;
+}
+
+static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+	return !!(__raw_readw(KEYDETR) & (1 << gpio));
+}
+
+static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+	return x3proto_gpio_irq_map[gpio];
+}
+
+static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = get_irq_desc_chip(desc);
+	unsigned long mask;
+	int pin;
+
+	chip->mask_ack(irq);
+
+	mask = __raw_readw(KEYDETR);
+
+	for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
+		generic_handle_irq(x3proto_gpio_to_irq(NULL, pin));
+
+	chip->unmask(irq);
+}
+
+struct gpio_chip x3proto_gpio_chip = {
+	.label			= "x3proto-gpio",
+	.direction_input	= x3proto_gpio_direction_input,
+	.get			= x3proto_gpio_get,
+	.to_irq			= x3proto_gpio_to_irq,
+	.base			= -1,
+	.ngpio			= NR_BASEBOARD_GPIOS,
+};
+
+int __init x3proto_gpio_setup(void)
+{
+	int ilsel;
+	int ret, i;
+
+	ilsel = ilsel_enable(ILSEL_KEY);
+	if (unlikely(ilsel < 0))
+		return ilsel;
+
+	ret = gpiochip_add(&x3proto_gpio_chip);
+	if (unlikely(ret))
+		goto err_gpio;
+
+	for (i = 0; i < NR_BASEBOARD_GPIOS; i++) {
+		unsigned long flags;
+		int irq = create_irq();
+
+		if (unlikely(irq < 0)) {
+			ret = -EINVAL;
+			goto err_irq;
+		}
+
+		spin_lock_irqsave(&x3proto_gpio_lock, flags);
+		x3proto_gpio_irq_map[i] = irq;
+		set_irq_chip_and_handler_name(irq, &dummy_irq_chip,
+					handle_simple_irq, "gpio");
+		spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
+	}
+
+	pr_info("registering '%s' support, handling GPIOs %u -> %u, "
+		"bound to IRQ %u\n",
+		x3proto_gpio_chip.label, x3proto_gpio_chip.base,
+		x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio,
+		ilsel);
+
+	set_irq_chained_handler(ilsel, x3proto_gpio_irq_handler);
+	set_irq_wake(ilsel, 1);
+
+	return 0;
+
+err_irq:
+	for (; i >= 0; --i)
+		if (x3proto_gpio_irq_map[i])
+			destroy_irq(x3proto_gpio_irq_map[i]);
+
+	ret = gpiochip_remove(&x3proto_gpio_chip);
+	if (unlikely(ret))
+		pr_err("Failed deregistering GPIO\n");
+
+err_gpio:
+	synchronize_irq(ilsel);
+
+	ilsel_disable(ILSEL_KEY);
+
+	return ret;
+}
diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c
index 5c98427..95e3461 100644
--- a/arch/sh/boards/mach-x3proto/ilsel.c
+++ b/arch/sh/boards/mach-x3proto/ilsel.c
@@ -1,20 +1,22 @@
 /*
- * arch/sh/boards/renesas/x3proto/ilsel.c
+ * arch/sh/boards/mach-x3proto/ilsel.c
  *
  * Helper routines for SH-X3 proto board ILSEL.
  *
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2010  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.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/bitmap.h>
 #include <linux/io.h>
-#include <asm/ilsel.h>
+#include <mach/ilsel.h>
 
 /*
  * ILSEL is split across:
@@ -64,6 +66,8 @@
 	unsigned int tmp, shift;
 	unsigned long addr;
 
+	pr_notice("enabling ILSEL set %d\n", set);
+
 	addr = mk_ilsel_addr(bit);
 	shift = mk_ilsel_shift(bit);
 
@@ -92,8 +96,10 @@
 {
 	unsigned int bit;
 
-	/* Aliased sources must use ilsel_enable_fixed() */
-	BUG_ON(set > ILSEL_KEY);
+	if (unlikely(set > ILSEL_KEY)) {
+		pr_err("Aliased sources must use ilsel_enable_fixed()\n");
+		return -EINVAL;
+	}
 
 	do {
 		bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS);
@@ -140,6 +146,8 @@
 	unsigned long addr;
 	unsigned int tmp;
 
+	pr_notice("disabling ILSEL set %d\n", irq);
+
 	addr = mk_ilsel_addr(irq);
 
 	tmp = __raw_readw(addr);
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 102bf56..d682e2b 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -1,9 +1,9 @@
 /*
- * arch/sh/boards/renesas/x3proto/setup.c
+ * arch/sh/boards/mach-x3proto/setup.c
  *
  * Renesas SH-X3 Prototype Board Support.
  *
- * Copyright (C) 2007 - 2008 Paul Mundt
+ * Copyright (C) 2007 - 2010  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
@@ -16,9 +16,13 @@
 #include <linux/smc91x.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/input.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/m66592.h>
-#include <asm/ilsel.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
 #include <asm/smp-ops.h>
 
 static struct resource heartbeat_resources[] = {
@@ -122,15 +126,128 @@
 	.resource	= m66592_usb_peripheral_resources,
 };
 
+static struct gpio_keys_button baseboard_buttons[NR_BASEBOARD_GPIOS] = {
+	{
+		.desc		= "key44",
+		.code		= KEY_POWER,
+		.active_low	= 1,
+		.wakeup		= 1,
+	}, {
+		.desc		= "key43",
+		.code		= KEY_SUSPEND,
+		.active_low	= 1,
+		.wakeup		= 1,
+	}, {
+		.desc		= "key42",
+		.code		= KEY_KATAKANAHIRAGANA,
+		.active_low	= 1,
+	}, {
+		.desc		= "key41",
+		.code		= KEY_SWITCHVIDEOMODE,
+		.active_low	= 1,
+	}, {
+		.desc		= "key34",
+		.code		= KEY_F12,
+		.active_low	= 1,
+	}, {
+		.desc		= "key33",
+		.code		= KEY_F11,
+		.active_low	= 1,
+	}, {
+		.desc		= "key32",
+		.code		= KEY_F10,
+		.active_low	= 1,
+	}, {
+		.desc		= "key31",
+		.code		= KEY_F9,
+		.active_low	= 1,
+	}, {
+		.desc		= "key24",
+		.code		= KEY_F8,
+		.active_low	= 1,
+	}, {
+		.desc		= "key23",
+		.code		= KEY_F7,
+		.active_low	= 1,
+	}, {
+		.desc		= "key22",
+		.code		= KEY_F6,
+		.active_low	= 1,
+	}, {
+		.desc		= "key21",
+		.code		= KEY_F5,
+		.active_low	= 1,
+	}, {
+		.desc		= "key14",
+		.code		= KEY_F4,
+		.active_low	= 1,
+	}, {
+		.desc		= "key13",
+		.code		= KEY_F3,
+		.active_low	= 1,
+	}, {
+		.desc		= "key12",
+		.code		= KEY_F2,
+		.active_low	= 1,
+	}, {
+		.desc		= "key11",
+		.code		= KEY_F1,
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data baseboard_buttons_data = {
+	.buttons	= baseboard_buttons,
+	.nbuttons	= ARRAY_SIZE(baseboard_buttons),
+};
+
+static struct platform_device baseboard_buttons_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &baseboard_buttons_data,
+	},
+};
+
 static struct platform_device *x3proto_devices[] __initdata = {
 	&heartbeat_device,
 	&smc91x_device,
 	&r8a66597_usb_host_device,
 	&m66592_usb_peripheral_device,
+	&baseboard_buttons_device,
 };
 
+static void __init x3proto_init_irq(void)
+{
+	plat_irq_setup_pins(IRQ_MODE_IRL3210);
+
+	/* Set ICR0.LVLMODE */
+	__raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
+}
+
 static int __init x3proto_devices_setup(void)
 {
+	int ret, i;
+
+	/*
+	 * IRLs are only needed for ILSEL mappings, so flip over the INTC
+	 * pins at a later point to enable the GPIOs to settle.
+	 */
+	x3proto_init_irq();
+
+	/*
+	 * Now that ILSELs are available, set up the baseboard GPIOs.
+	 */
+	ret = x3proto_gpio_setup();
+	if (unlikely(ret))
+		return ret;
+
+	/*
+	 * Propagate dynamic GPIOs for the baseboard button device.
+	 */
+	for (i = 0; i < ARRAY_SIZE(baseboard_buttons); i++)
+		baseboard_buttons[i].gpio = x3proto_gpio_chip.base + i;
+
 	r8a66597_usb_host_resources[1].start =
 		r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
 
@@ -145,14 +262,6 @@
 }
 device_initcall(x3proto_devices_setup);
 
-static void __init x3proto_init_irq(void)
-{
-	plat_irq_setup_pins(IRQ_MODE_IRL3210);
-
-	/* Set ICR0.LVLMODE */
-	__raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
-}
-
 static void __init x3proto_setup(char **cmdline_p)
 {
 	register_smp_ops(&shx3_smp_ops);
@@ -161,5 +270,4 @@
 static struct sh_machine_vector mv_x3proto __initmv = {
 	.mv_name		= "x3proto",
 	.mv_setup		= x3proto_setup,
-	.mv_init_irq		= x3proto_init_irq,
 };
diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 200c1d4..3e15032 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -91,7 +91,9 @@
 end_addr:
 	.long	_end
 init_sr:
-	.long	0x400000F0	/* Privileged mode, Bank=0, Block=0, IMASK=0xF */
+	.long	0x500000F0	/* Privileged mode, Bank=0, Block=1, IMASK=0xF */
+kexec_magic:
+	.long	0x400000F0	/* magic used by kexec to parse zImage format */
 init_stack_addr:
 	.long	stack_start
 decompress_kernel_addr:
diff --git a/arch/sh/cchips/hd6446x/Makefile b/arch/sh/cchips/hd6446x/Makefile
index 9682e3a..59c3483 100644
--- a/arch/sh/cchips/hd6446x/Makefile
+++ b/arch/sh/cchips/hd6446x/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_HD64461)	+= hd64461.o
 
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 238d683..e533512 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -3,7 +3,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_KALLSYMS is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index b3bf11b..67e1506 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 3cdee4f..ec243ca 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -2,7 +2,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig
index 021633b..5fcb17b 100644
--- a/arch/sh/configs/ecovec24-romimage_defconfig
+++ b/arch/sh/configs/ecovec24-romimage_defconfig
@@ -5,7 +5,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_KALLSYMS is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 365f231..e1077a0 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -5,7 +5,6 @@
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
index ca7fc1b..67cb109 100644
--- a/arch/sh/configs/espt_defconfig
+++ b/arch/sh/configs/espt_defconfig
@@ -3,7 +3,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 45c18a3..496edcd 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -3,7 +3,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig
index d4268b1..029a506 100644
--- a/arch/sh/configs/kfr2r09-romimage_defconfig
+++ b/arch/sh/configs/kfr2r09-romimage_defconfig
@@ -5,7 +5,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_KALLSYMS is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig
index ad5d296..fac13de 100644
--- a/arch/sh/configs/kfr2r09_defconfig
+++ b/arch/sh/configs/kfr2r09_defconfig
@@ -5,7 +5,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_KALLSYMS is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index 14e658e..3670e93 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index 6be7eaa..e3c0894 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 4d61b77..9479872 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -5,7 +5,6 @@
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_AUDIT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 0e32a24..f1d2e1b 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index c19fcdf..9ad904a 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -3,7 +3,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
index 984e3fe..f3d5d9f 100644
--- a/arch/sh/configs/polaris_defconfig
+++ b/arch/sh/configs/polaris_defconfig
@@ -7,7 +7,6 @@
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_AUDIT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index e8b5472..920b847 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -4,7 +4,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index fd88480..c77da6b 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -8,7 +8,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index a42f7c2..a3d0810 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 742aa61..b1a04f3 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index aed394d..ae11158 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -6,7 +6,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 7a7e138..be9c474 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -3,7 +3,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index 3620a7f..1248635 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -5,7 +5,6 @@
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_BUG is not set
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index fe22f59..c3ba6e8 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -5,7 +5,6 @@
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_BUG is not set
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index b9b64c3..ae998c7 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -4,7 +4,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PROFILING=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig
index 03e7367..ed35093 100644
--- a/arch/sh/configs/se7724_defconfig
+++ b/arch/sh/configs/se7724_defconfig
@@ -3,7 +3,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_KALLSYMS is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index 1a686b6..912c985 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -5,7 +5,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_HOTPLUG is not set
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index 7e03451..75c92fc 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -2,7 +2,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 4cfc4de..c8c5e7f 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -3,7 +3,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index b95dc76..2051821 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -3,7 +3,6 @@
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig
new file mode 100644
index 0000000..0d2f414
--- /dev/null
+++ b/arch/sh/configs/sh2007_defconfig
@@ -0,0 +1,212 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_IKCONFIG=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_CPU_SUBTYPE_SH7780=y
+CONFIG_MEMORY_SIZE=0x08000000
+# CONFIG_VSYSCALL is not set
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SH_SH2007=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
+CONFIG_NR_DMA_CHANNELS_BOOL=y
+CONFIG_HZ_100=y
+CONFIG_CMDLINE_OVERWRITE=y
+CONFIG_CMDLINE="console=ttySC1,115200 ip=dhcp root=/dev/nfs rw nfsroot=/nfs/rootfs,rsize=1024,wsize=1024 earlyprintk=sh-sci.1"
+CONFIG_PCCARD=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPIP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NET_PKTGEN=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_CDROM_PKTCDVD=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=y
+CONFIG_SCSI_SRP_ATTRS=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_EQUALIZER=y
+CONFIG_TUN=y
+CONFIG_VETH=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SH_WDT=y
+CONFIG_SSB=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_DMADEVICES=y
+CONFIG_TIMB_DMA=y
+CONFIG_EXT3_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=932
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SH_STANDARD_BIOS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index b804641..f92ad17 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -3,7 +3,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig
new file mode 100644
index 0000000..273f3fa
--- /dev/null
+++ b/arch/sh/configs/sh7757lcr_defconfig
@@ -0,0 +1,85 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_CPU_SUBTYPE_SH7757=y
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x0f000000
+CONFIG_PMB=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SH_SH7757LCR=y
+CONFIG_HEARTBEAT=y
+CONFIG_SECCOMP=y
+CONFIG_CMDLINE_OVERWRITE=y
+CONFIG_CMDLINE="console=ttySC2,115200 root=/dev/nfs ip=dhcp"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_SQUASHFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index 3618767..4795364 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -3,7 +3,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index ee6b81f..51561f5 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -4,7 +4,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_MODULES=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index bb4f60c..3f92d37 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -15,7 +15,6 @@
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index f38c983..7eae4e5 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_HOTPLUG is not set
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 7007d00c6..b58dfc5 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,6 +1,5 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 45c309f..0f55891 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -5,7 +5,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index e107d42..2d288b8 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -4,7 +4,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PROFILING=y
 CONFIG_MODULES=y
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index 4a27722..f46848f 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -412,8 +412,8 @@
 static int __init dma_api_init(void)
 {
 	printk(KERN_NOTICE "DMA: Registering DMA API.\n");
-	create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
-	return 0;
+	return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0)
+		    ? 0 : -ENOMEM;
 }
 subsys_initcall(dma_api_init);
 
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 4a59e68..82f0a33 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_SH_SH03)			+= fixups-sh03.o
 obj-$(CONFIG_SH_HIGHLANDER)		+= fixups-r7780rp.o
 obj-$(CONFIG_SH_SH7785LCR)		+= fixups-r7780rp.o
+obj-$(CONFIG_SH_SDK7786)		+= fixups-sdk7786.o
 obj-$(CONFIG_SH_SDK7780)		+= fixups-sdk7780.o
 obj-$(CONFIG_SH_7780_SOLUTION_ENGINE)	+= fixups-sdk7780.o
 obj-$(CONFIG_SH_TITAN)			+= fixups-titan.o
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c
new file mode 100644
index 0000000..0e18ee3
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sdk7786.c
@@ -0,0 +1,67 @@
+/*
+ * SDK7786 FPGA PCIe mux handling
+ *
+ * Copyright (C) 2010  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.
+ */
+#define pr_fmt(fmt) "PCI: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <mach/fpga.h>
+
+/*
+ * The SDK7786 FPGA supports mangling of most of the slots in some way or
+ * another. Slots 3/4 are special in that only one can be supported at a
+ * time, and both appear on port 3 to the PCI bus scan. Enabling slot 4
+ * (the horizontal edge connector) will disable slot 3 entirely.
+ *
+ * Misconfigurations can be detected through the FPGA via the slot
+ * resistors to determine card presence. Hotplug remains unsupported.
+ */
+static unsigned int slot4en __devinitdata;
+
+char *__devinit pcibios_setup(char *str)
+{
+	if (strcmp(str, "slot4en") == 0) {
+		slot4en = 1;
+		return NULL;
+	}
+
+	return str;
+}
+
+static int __init sdk7786_pci_init(void)
+{
+	u16 data = fpga_read_reg(PCIECR);
+
+	/*
+	 * Enable slot #4 if it's been specified on the command line.
+	 *
+	 * Optionally reroute if slot #4 has a card present while slot #3
+	 * does not, regardless of command line value.
+	 *
+	 * Card presence is logically inverted.
+	 */
+	slot4en ?: (!(data & PCIECR_PRST4) && (data & PCIECR_PRST3));
+	if (slot4en) {
+		pr_info("Activating PCIe slot#4 (disabling slot#3)\n");
+
+		data &= ~PCIECR_PCIEMUX1;
+		fpga_write_reg(data, PCIECR);
+
+		/* Warn about forced rerouting if slot#3 is occupied */
+		if ((data & PCIECR_PRST3) == 0) {
+			pr_warning("Unreachable card detected in slot#3\n");
+			return -EBUSY;
+		}
+	} else
+		pr_info("PCIe slot#4 disabled\n");
+
+	return 0;
+}
+postcore_initcall(sdk7786_pci_init);
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 0b81999..b623420 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -9,6 +9,7 @@
  */
 #include <linux/pci.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 #include <asm/addrspace.h>
 #include "pci-sh4.h"
 
@@ -18,8 +19,6 @@
 #define CONFIG_CMD(bus, devfn, where) \
 	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
 
-static DEFINE_SPINLOCK(sh4_pci_lock);
-
 /*
  * Functions for accessing PCI configuration space with type 1 accesses
  */
@@ -34,10 +33,10 @@
 	 * PCIPDR may only be accessed as 32 bit words,
 	 * so we must do byte alignment by hand
 	 */
-	spin_lock_irqsave(&sh4_pci_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
 	data = pci_read_reg(chan, SH4_PCIPDR);
-	spin_unlock_irqrestore(&sh4_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
 	switch (size) {
 	case 1:
@@ -69,10 +68,10 @@
 	int shift;
 	u32 data;
 
-	spin_lock_irqsave(&sh4_pci_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
 	data = pci_read_reg(chan, SH4_PCIPDR);
-	spin_unlock_irqrestore(&sh4_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
 	switch (size) {
 	case 1:
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 48f594b..1284210 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -1,7 +1,7 @@
 /*
  * Generic SH7786 PCI-Express operations.
  *
- *  Copyright (C) 2009  Paul Mundt
+ *  Copyright (C) 2009 - 2010  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License v2. See the file "COPYING" in the main directory of this archive
@@ -19,37 +19,72 @@
 	PCI_ACCESS_WRITE,
 };
 
-static DEFINE_SPINLOCK(sh7786_pcie_lock);
-
 static int sh7786_pcie_config_access(unsigned char access_type,
 		struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
 {
 	struct pci_channel *chan = bus->sysdata;
-	int dev, func;
+	int dev, func, type, reg;
 
 	dev = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
+	type = !!bus->parent;
+	reg = where & ~3;
 
 	if (bus->number > 255 || dev > 31 || func > 7)
 		return PCIBIOS_FUNC_NOT_SUPPORTED;
-	if (devfn)
-		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * While each channel has its own memory-mapped extended config
+	 * space, it's generally only accessible when in endpoint mode.
+	 * When in root complex mode, the controller is unable to target
+	 * itself with either type 0 or type 1 accesses, and indeed, any
+	 * controller initiated target transfer to its own config space
+	 * result in a completer abort.
+	 *
+	 * Each channel effectively only supports a single device, but as
+	 * the same channel <-> device access works for any PCI_SLOT()
+	 * value, we cheat a bit here and bind the controller's config
+	 * space to devfn 0 in order to enable self-enumeration. In this
+	 * case the regular PAR/PDR path is sidelined and the mangled
+	 * config access itself is initiated as a SuperHyway transaction.
+	 */
+	if (pci_is_root_bus(bus)) {
+		if (dev == 0) {
+			if (access_type == PCI_ACCESS_READ)
+				*data = pci_read_reg(chan, PCI_REG(reg));
+			else
+				pci_write_reg(chan, *data, PCI_REG(reg));
+
+			return PCIBIOS_SUCCESSFUL;
+		} else if (dev > 1)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/* Clear errors */
+	pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR);
 
 	/* Set the PIO address */
 	pci_write_reg(chan, (bus->number << 24) | (dev << 19) |
-				(func << 16) | (where & ~3), SH4A_PCIEPAR);
+				(func << 16) | reg, SH4A_PCIEPAR);
 
 	/* Enable the configuration access */
-	pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR);
+	pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR);
+
+	/* Check for errors */
+	if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Check for master and target aborts */
+	if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	if (access_type == PCI_ACCESS_READ)
 		*data = pci_read_reg(chan, SH4A_PCIEPDR);
 	else
 		pci_write_reg(chan, *data, SH4A_PCIEPDR);
 
-	/* Check for master and target aborts */
-	if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	/* Disable the configuration access */
+	pci_write_reg(chan, 0, SH4A_PCIEPCTLR);
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -66,11 +101,13 @@
 	else if ((size == 4) && (where & 3))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	spin_lock_irqsave(&sh7786_pcie_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
 					devfn, where, &data);
-	if (ret != PCIBIOS_SUCCESSFUL)
+	if (ret != PCIBIOS_SUCCESSFUL) {
+		*val = 0xffffffff;
 		goto out;
+	}
 
 	if (size == 1)
 		*val = (data >> ((where & 3) << 3)) & 0xff;
@@ -84,7 +121,7 @@
 		devfn, where, size, (unsigned long)*val);
 
 out:
-	spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	return ret;
 }
 
@@ -100,7 +137,7 @@
 	else if ((size == 4) && (where & 3))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	spin_lock_irqsave(&sh7786_pcie_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
 					devfn, where, &data);
 	if (ret != PCIBIOS_SUCCESSFUL)
@@ -124,7 +161,7 @@
 	ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus,
 					devfn, where, &data);
 out:
-	spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	return ret;
 }
 
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index f98141b..86adb1e 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -81,7 +81,7 @@
 	unsigned int id;
 	u32 word, reg;
 
-	printk(KERN_NOTICE "PCI: Starting intialization.\n");
+	printk(KERN_NOTICE "PCI: Starting initialization.\n");
 
 	chan->reg_base = 0xfe200000;
 
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index ffdcbf1..edb7cca 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -246,7 +246,7 @@
 	const char *type;
 	int ret, i;
 
-	printk(KERN_NOTICE "PCI: Starting intialization.\n");
+	printk(KERN_NOTICE "PCI: Starting initialization.\n");
 
 	chan->reg_base = 0xfe040000;
 
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 205dcbe..1742e2c 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -12,12 +12,6 @@
 #ifndef _PCI_SH7780_H_
 #define _PCI_SH7780_H_
 
-#define PCI_VENDOR_ID_RENESAS		0x1912
-#define PCI_DEVICE_ID_RENESAS_SH7781	0x0001
-#define PCI_DEVICE_ID_RENESAS_SH7780	0x0002
-#define PCI_DEVICE_ID_RENESAS_SH7763	0x0004
-#define PCI_DEVICE_ID_RENESAS_SH7785	0x0007
-
 /* SH7780 Control Registers */
 #define	PCIECR			0xFE000008
 #define PCIECR_ENBL		0x01
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 1e9598d..60ee09a 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 
 unsigned long PCIBIOS_MIN_IO = 0x0000;
 unsigned long PCIBIOS_MIN_MEM = 0;
@@ -56,6 +57,11 @@
 	}
 }
 
+/*
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
+ */
+DEFINE_RAW_SPINLOCK(pci_config_lock);
 static DEFINE_MUTEX(pci_scan_mutex);
 
 int __devinit register_pci_controller(struct pci_channel *hose)
@@ -233,40 +239,7 @@
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
-		/* Only set up the requested stuff */
-		if (!(mask & (1<<idx)))
-			continue;
-
-		r = &dev->resource[idx];
-		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
-			continue;
-		if ((idx == PCI_ROM_RESOURCE) &&
-				(!(r->flags & IORESOURCE_ROM_ENABLE)))
-			continue;
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available "
-			       "because of resource collisions\n",
-			       pci_name(dev));
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: Enabling device %s (%04x -> %04x)\n",
-		       pci_name(dev), old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
+	return pci_enable_resources(dev, mask);
 }
 
 /*
@@ -295,7 +268,7 @@
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
 
-char * __devinit pcibios_setup(char *str)
+char * __devinit __weak pcibios_setup(char *str)
 {
 	return str;
 }
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 68cb9b0..96e9b05 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -13,11 +13,14 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
 #include "pcie-sh7786.h"
 #include <asm/sizes.h>
 
 struct sh7786_pcie_port {
 	struct pci_channel	*hose;
+	struct clk		*fclk, phy_clk;
 	unsigned int		index;
 	int			endpoint;
 	int			link;
@@ -51,6 +54,7 @@
 		.name	= "PCIe0 MEM 2",
 		.start	= 0xfe100000,
 		.end	= 0xfe100000 + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
 	},
 };
 
@@ -74,6 +78,7 @@
 		.name	= "PCIe1 MEM 2",
 		.start	= 0xfe300000,
 		.end	= 0xfe300000 + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
 	},
 };
 
@@ -82,6 +87,7 @@
 		.name	= "PCIe2 IO",
 		.start	= 0xfc800000,
 		.end	= 0xfc800000 + SZ_4M - 1,
+		.flags	= IORESOURCE_IO,
 	}, {
 		.name	= "PCIe2 MEM 0",
 		.start	= 0x80000000,
@@ -96,6 +102,7 @@
 		.name	= "PCIe2 MEM 2",
 		.start	= 0xfcd00000,
 		.end	= 0xfcd00000 + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
 	},
 };
 
@@ -117,7 +124,29 @@
 	DEFINE_CONTROLLER(0xfcc00000, 2),
 };
 
-static int phy_wait_for_ack(struct pci_channel *chan)
+static struct clk fixed_pciexclkp = {
+	.rate = 100000000,	/* 100 MHz reference clock */
+};
+
+static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
+{
+	/*
+	 * Prevent enumeration of root complex resources.
+	 */
+	if (pci_is_root_bus(dev->bus) && dev->devfn == 0) {
+		int i;
+
+		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+			dev->resource[i].start	= 0;
+			dev->resource[i].end	= 0;
+			dev->resource[i].flags	= 0;
+		}
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786,
+			 sh7786_pci_fixup);
+
+static int __init phy_wait_for_ack(struct pci_channel *chan)
 {
 	unsigned int timeout = 100;
 
@@ -131,7 +160,7 @@
 	return -ETIMEDOUT;
 }
 
-static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
+static int __init pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
 {
 	unsigned int timeout = 100;
 
@@ -145,19 +174,14 @@
 	return -ETIMEDOUT;
 }
 
-static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
-			  unsigned int lane, unsigned int data)
+static void __init phy_write_reg(struct pci_channel *chan, unsigned int addr,
+				 unsigned int lane, unsigned int data)
 {
-	unsigned long phyaddr, ctrl;
+	unsigned long phyaddr;
 
 	phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) +
 			((addr & 0xff) << BITS_ADR);
 
-	/* Enable clock */
-	ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
-	ctrl |= (1 << BITS_CKE);
-	pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
-
 	/* Set write data */
 	pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR);
 	pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR);
@@ -165,20 +189,74 @@
 	phy_wait_for_ack(chan);
 
 	/* Clear command */
+	pci_write_reg(chan, 0, SH4A_PCIEPHYDOUTR);
 	pci_write_reg(chan, 0, SH4A_PCIEPHYADRR);
 
 	phy_wait_for_ack(chan);
-
-	/* Disable clock */
-	ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
-	ctrl &= ~(1 << BITS_CKE);
-	pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
 }
 
-static int phy_init(struct pci_channel *chan)
+static int __init pcie_clk_init(struct sh7786_pcie_port *port)
 {
+	struct pci_channel *chan = port->hose;
+	struct clk *clk;
+	char fclk_name[16];
+	int ret;
+
+	/*
+	 * First register the fixed clock
+	 */
+	ret = clk_register(&fixed_pciexclkp);
+	if (unlikely(ret != 0))
+		return ret;
+
+	/*
+	 * Grab the port's function clock, which the PHY clock depends
+	 * on. clock lookups don't help us much at this point, since no
+	 * dev_id is available this early. Lame.
+	 */
+	snprintf(fclk_name, sizeof(fclk_name), "pcie%d_fck", port->index);
+
+	port->fclk = clk_get(NULL, fclk_name);
+	if (IS_ERR(port->fclk)) {
+		ret = PTR_ERR(port->fclk);
+		goto err_fclk;
+	}
+
+	clk_enable(port->fclk);
+
+	/*
+	 * And now, set up the PHY clock
+	 */
+	clk = &port->phy_clk;
+
+	memset(clk, 0, sizeof(struct clk));
+
+	clk->parent = &fixed_pciexclkp;
+	clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR);
+	clk->enable_bit = BITS_CKE;
+
+	ret = sh_clk_mstp32_register(clk, 1);
+	if (unlikely(ret < 0))
+		goto err_phy;
+
+	return 0;
+
+err_phy:
+	clk_disable(port->fclk);
+	clk_put(port->fclk);
+err_fclk:
+	clk_unregister(&fixed_pciexclkp);
+
+	return ret;
+}
+
+static int __init phy_init(struct sh7786_pcie_port *port)
+{
+	struct pci_channel *chan = port->hose;
 	unsigned int timeout = 100;
 
+	clk_enable(&port->phy_clk);
+
 	/* Initialize the phy */
 	phy_write_reg(chan, 0x60, 0xf, 0x004b008b);
 	phy_write_reg(chan, 0x61, 0xf, 0x00007b41);
@@ -187,9 +265,13 @@
 	phy_write_reg(chan, 0x66, 0xf, 0x00000010);
 	phy_write_reg(chan, 0x74, 0xf, 0x0007001c);
 	phy_write_reg(chan, 0x79, 0xf, 0x01fc000d);
+	phy_write_reg(chan, 0xb0, 0xf, 0x00000610);
 
 	/* Deassert Standby */
-	phy_write_reg(chan, 0x67, 0xf, 0x00000400);
+	phy_write_reg(chan, 0x67, 0x1, 0x00000400);
+
+	/* Disable clock */
+	clk_disable(&port->phy_clk);
 
 	while (timeout--) {
 		if (pci_read_reg(chan, SH4A_PCIEPHYSR))
@@ -201,22 +283,33 @@
 	return -ETIMEDOUT;
 }
 
-static int pcie_init(struct sh7786_pcie_port *port)
+static void __init pcie_reset(struct sh7786_pcie_port *port)
+{
+	struct pci_channel *chan = port->hose;
+
+	pci_write_reg(chan, 1, SH4A_PCIESRSTR);
+	pci_write_reg(chan, 0, SH4A_PCIETCTLR);
+	pci_write_reg(chan, 0, SH4A_PCIESRSTR);
+	pci_write_reg(chan, 0, SH4A_PCIETXVC0SR);
+}
+
+static int __init pcie_init(struct sh7786_pcie_port *port)
 {
 	struct pci_channel *chan = port->hose;
 	unsigned int data;
 	phys_addr_t memphys;
 	size_t memsize;
-	int ret, i;
+	int ret, i, win;
 
 	/* Begin initialization */
-	pci_write_reg(chan, 0, SH4A_PCIETCTLR);
+	pcie_reset(port);
 
-	/* Initialize as type1. */
-	data = pci_read_reg(chan, SH4A_PCIEPCICONF3);
-	data &= ~(0x7f << 16);
-	data |= PCI_HEADER_TYPE_BRIDGE << 16;
-	pci_write_reg(chan, data, SH4A_PCIEPCICONF3);
+	/*
+	 * Initial header for port config space is type 1, set the device
+	 * class to match. Hardware takes care of propagating the IDSETR
+	 * settings, so there is no need to bother with a quirk.
+	 */
+	pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1);
 
 	/* Initialize default capabilities. */
 	data = pci_read_reg(chan, SH4A_PCIEEXPCAP0);
@@ -268,30 +361,33 @@
 	 * LAR1/LAMR1.
 	 */
 	if (memsize > SZ_512M) {
-		__raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1);
-		__raw_writel(((memsize - SZ_512M) - SZ_256) | 1,
-			     chan->reg_base + SH4A_PCIELAMR1);
+		pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1);
+		pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
+			      SH4A_PCIELAMR1);
 		memsize = SZ_512M;
 	} else {
 		/*
 		 * Otherwise just zero it out and disable it.
 		 */
-		__raw_writel(0, chan->reg_base + SH4A_PCIELAR1);
-		__raw_writel(0, chan->reg_base + SH4A_PCIELAMR1);
+		pci_write_reg(chan, 0, SH4A_PCIELAR1);
+		pci_write_reg(chan, 0, SH4A_PCIELAMR1);
 	}
 
 	/*
 	 * LAR0/LAMR0 covers up to the first 512MB, which is enough to
 	 * cover all of lowmem on most platforms.
 	 */
-	__raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0);
-	__raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0);
+	pci_write_reg(chan, memphys, SH4A_PCIELAR0);
+	pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);
 
 	/* Finish initialization */
 	data = pci_read_reg(chan, SH4A_PCIETCTLR);
 	data |= 0x1;
 	pci_write_reg(chan, data, SH4A_PCIETCTLR);
 
+	/* Let things settle down a bit.. */
+	mdelay(100);
+
 	/* Enable DL_Active Interrupt generation */
 	data = pci_read_reg(chan, SH4A_PCIEDLINTENR);
 	data |= PCIEDLINTENR_DLL_ACT_ENABLE;
@@ -302,9 +398,12 @@
 	data |= PCIEMACCTLR_SCR_DIS | (0xff << 16);
 	pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
 
+	/*
+	 * This will timeout if we don't have a link, but we permit the
+	 * port to register anyways in order to support hotplug on future
+	 * hardware.
+	 */
 	ret = pci_wait_for_irq(chan, MASK_INT_TX_CTRL);
-	if (unlikely(ret != 0))
-		return -ENODEV;
 
 	data = pci_read_reg(chan, SH4A_PCIEPCICONF1);
 	data &= ~(PCI_STATUS_DEVSEL_MASK << 16);
@@ -317,35 +416,48 @@
 
 	wmb();
 
-	data = pci_read_reg(chan, SH4A_PCIEMACSR);
-	printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n",
-	       port->index, (data >> 20) & 0x3f);
+	if (ret == 0) {
+		data = pci_read_reg(chan, SH4A_PCIEMACSR);
+		printk(KERN_NOTICE "PCI: PCIe#%d x%d link detected\n",
+		       port->index, (data >> 20) & 0x3f);
+	} else
+		printk(KERN_NOTICE "PCI: PCIe#%d link down\n",
+		       port->index);
 
-
-	for (i = 0; i < chan->nr_resources; i++) {
+	for (i = win = 0; i < chan->nr_resources; i++) {
 		struct resource *res = chan->resources + i;
 		resource_size_t size;
-		u32 enable_mask;
+		u32 mask;
 
-		pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i));
+		/*
+		 * We can't use the 32-bit mode windows in legacy 29-bit
+		 * mode, so just skip them entirely.
+		 */
+		if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode())
+			continue;
 
-		size = resource_size(res);
+		pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win));
 
 		/*
 		 * The PAMR mask is calculated in units of 256kB, which
 		 * keeps things pretty simple.
 		 */
-		__raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
-			     chan->reg_base + SH4A_PCIEPAMR(i));
+		size = resource_size(res);
+		mask = (roundup_pow_of_two(size) / SZ_256K) - 1;
+		pci_write_reg(chan, mask << 18, SH4A_PCIEPAMR(win));
 
-		pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i));
-		pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i));
+		pci_write_reg(chan, upper_32_bits(res->start),
+			      SH4A_PCIEPARH(win));
+		pci_write_reg(chan, lower_32_bits(res->start),
+			      SH4A_PCIEPARL(win));
 
-		enable_mask = MASK_PARE;
+		mask = MASK_PARE;
 		if (res->flags & IORESOURCE_IO)
-			enable_mask |= MASK_SPC;
+			mask |= MASK_SPC;
 
-		pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i));
+		pci_write_reg(chan, mask, SH4A_PCIEPTCTLR(win));
+
+		win++;
 	}
 
 	return 0;
@@ -356,26 +468,33 @@
         return 71;
 }
 
-static int sh7786_pcie_core_init(void)
+static int __init sh7786_pcie_core_init(void)
 {
 	/* Return the number of ports */
 	return test_mode_pin(MODE_PIN12) ? 3 : 2;
 }
 
-static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
+static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
 {
 	int ret;
 
-	ret = phy_init(port->hose);
-	if (unlikely(ret < 0))
-		return ret;
-
 	/*
 	 * Check if we are configured in endpoint or root complex mode,
 	 * this is a fixed pin setting that applies to all PCIe ports.
 	 */
 	port->endpoint = test_mode_pin(MODE_PIN11);
 
+	/*
+	 * Setup clocks, needed both for PHY and PCIe registers.
+	 */
+	ret = pcie_clk_init(port);
+	if (unlikely(ret < 0))
+		return ret;
+
+	ret = phy_init(port);
+	if (unlikely(ret < 0))
+		return ret;
+
 	ret = pcie_init(port);
 	if (unlikely(ret < 0))
 		return ret;
@@ -390,9 +509,10 @@
 
 static int __init sh7786_pcie_init(void)
 {
+	struct clk *platclk;
 	int ret = 0, i;
 
-	printk(KERN_NOTICE "PCI: Starting intialization.\n");
+	printk(KERN_NOTICE "PCI: Starting initialization.\n");
 
 	sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops;
 
@@ -407,6 +527,22 @@
 	if (unlikely(!sh7786_pcie_ports))
 		return -ENOMEM;
 
+	/*
+	 * Fetch any optional platform clock associated with this block.
+	 *
+	 * This is a rather nasty hack for boards with spec-mocking FPGAs
+	 * that have a secondary set of clocks outside of the on-chip
+	 * ones that need to be accounted for before there is any chance
+	 * of touching the existing MSTP bits or CPG clocks.
+	 */
+	platclk = clk_get(NULL, "pcie_plat_clk");
+	if (IS_ERR(platclk)) {
+		/* Sane hardware should probably get a WARN_ON.. */
+		platclk = NULL;
+	}
+
+	clk_enable(platclk);
+
 	printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);
 
 	for (i = 0; i < nr_ports; i++) {
@@ -419,8 +555,11 @@
 		ret |= sh7786_pcie_hwops->port_init_hw(port);
 	}
 
-	if (unlikely(ret))
+	if (unlikely(ret)) {
+		clk_disable(platclk);
+		clk_put(platclk);
 		return ret;
+	}
 
 	return 0;
 }
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h
index 90a6992..1ee054e 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.h
+++ b/arch/sh/drivers/pci/pcie-sh7786.h
@@ -55,8 +55,11 @@
 #define		BITS_ERRRCV	(0)		/* 0 ERRRCV 0 */
 #define		MASK_ERRRCV	(1<<BITS_ERRRCV)
 
+/*	PCIEENBLR	 */
+#define	SH4A_PCIEENBLR		(0x000008)	/* R/W - 0x0000 0001 32 */
+
 /*	PCIEECR		*/
-#define	SH4A_PCIEECR		(0x000008)	/* R/W - 0x0000 0000 32 */
+#define	SH4A_PCIEECR		(0x00000C)	/* R/W - 0x0000 0000 32 */
 #define		BITS_ENBL	(0)	/* 0 ENBL 0 R/W */
 #define		MASK_ENBL	(1<<BITS_ENBL)
 
@@ -113,6 +116,27 @@
 #define		BITS_MDATA	(0)
 #define		MASK_MDATA	(0xffffffff<<BITS_MDATA)
 
+/*	PCIEUNLOCKCR	*/
+#define	SH4A_PCIEUNLOCKCR	(0x000048)	/* R/W - 0x0000 0000 32 */
+
+/*	PCIEIDR		*/
+#define	SH4A_PCIEIDR		(0x000060)	/* R/W - 0x0101 1101 32 */
+
+/*	PCIEDBGCTLR	*/
+#define	SH4A_PCIEDBGCTLR	(0x000100)	/* R/W - 0x0000 0000 32 */
+
+/*	PCIEINTXR	*/
+#define	SH4A_PCIEINTXR		(0x004000)	/* R/W - 0x0000 0000 32 */
+
+/*	PCIERMSGR	*/
+#define	SH4A_PCIERMSGR		(0x004010)	/* R/W - 0x0000 0000 32 */
+
+/*	PCIERSTR	*/
+#define SH4A_PCIERSTR(x)	(0x008000 + ((x) * 0x4)) /* R/W - 0x0000 0000 32 */
+
+/*	PCIESRSTR	 */
+#define SH4A_PCIESRSTR		(0x008040)	/* R/W - 0x0000 0000 32 */
+
 /*	PCIEPHYCTLR	*/
 #define	SH4A_PCIEPHYCTLR	(0x010000)	/* R/W - 0x0000 0000 32 */
 #define		BITS_CKE	(0)
@@ -121,6 +145,9 @@
 /*	PCIERMSGIER	*/
 #define	SH4A_PCIERMSGIER	(0x004040)	/* R/W - 0x0000 0000 32 */
 
+/*	PCIEPHYCTLR	*/
+#define SH4A_PCIEPHYCTLR	(0x010000)	/* R/W - 0x0000 0000 32 */
+
 /*	PCIEPHYADRR	*/
 #define	SH4A_PCIEPHYADRR	(0x010004)	/* R/W - 0x0000 0000 32 */
 #define		BITS_ACK	(24)			// Rev1.171
@@ -152,7 +179,7 @@
 #define		MASK_CFINT	(1<<BITS_CFINT)
 
 /*	PCIETSTR	*/
-#define	SH4A_PCIETSTR		(0x020004)	/* R/W R/W 0x0000 0000 32  */
+#define	SH4A_PCIETSTR		(0x020004)	/* R 0x0000 0000 32  */
 
 /*	PCIEINTR	*/
 #define	SH4A_PCIEINTR		(0x020008)	/* R/W R/W 0x0000 0000 32  */
@@ -236,6 +263,9 @@
 #define		BITS_INTPM			(8)
 #define		MASK_INTPM			(1<<BITS_INTPM)
 
+/*	PCIEEH0R	*/
+#define SH4A_PCIEEHR(x)		(0x020010 + ((x) * 0x4)) /* R - 0x0000 0000 32 */
+
 /*	PCIEAIR	 */
 #define	SH4A_PCIEAIR		(SH4A_PCIE_BASE + 0x020010)	/* R/W R/W 0xxxxx xxxx 32 */
 
@@ -244,6 +274,25 @@
 
 /*	 PCIEERRFR	 */								// Rev1.18
 #define	SH4A_PCIEERRFR		(0x020020)		/* R/W R/W 0xxxxx xxxx 32 */	// Rev1.18
+
+/*	PCIEERRFER	*/
+#define SH4A_PCIEERRFER		(0x020024)		/* R/W R/W 0x0000 0000 32 */
+
+/*	PCIEERRFR2	*/
+#define SH4A_PCIEERRFR2		(0x020028)		/* R/W R/W 0x0000 0000 32 */
+
+/*	PCIEMSIR	*/
+#define SH4A_PCIEMSIR		(0x020040)		/* R/W - 0x0000 0000 32 */
+
+/*	PCIEMSIFR	*/
+#define SH4A_PCIEMSIFR		(0x020044)		/* R/W R/W 0x0000 0000 32 */
+
+/*	PCIEPWRCTLR	*/
+#define SH4A_PCIEPWRCTLR	(0x020100)		/* R/W - 0x0000 0000 32 */
+
+/*	PCIEPCCTLR	*/
+#define SH4A_PCIEPCCTLR		(0x020180)		/* R/W - 0x0000 0000 32 */
+
 											// Rev1.18
 /*	PCIELAR0	*/
 #define	SH4A_PCIELAR0		(0x020200)	/* R/W R/W 0x0000 0000 32 */
@@ -352,6 +401,7 @@
 #define	SH4A_PCIEDMCCR0		(0x021120)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMCC2R0	(0x021124)	/* R/W R/W 0x0000 0000 - */
 #define	SH4A_PCIEDMCCCR0	(0x021128)	/* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR0	(0x02112C)	/* R/W - 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAR1		(0x021140)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAHR1	(0x021144)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMDAR1		(0x021148)	/* R/W R/W 0x0000 0000 32 */
@@ -363,6 +413,7 @@
 #define	SH4A_PCIEDMCCR1		(0x021160)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMCC2R1	(0x021164)	/* R/W R/W 0x0000 0000 - */
 #define	SH4A_PCIEDMCCCR1	(0x021168)	/* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR1	(0x02116C)	/* R/W - 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAR2		(0x021180)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAHR2	(0x021184)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMDAR2		(0x021188)	/* R/W R/W 0x0000 0000 32 */
@@ -385,6 +436,7 @@
 #define	SH4A_PCIEDMCCR3		(0x0211E0)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMCC2R3	(0x0211E4)	/* R/W R/W 0x0000 0000 -  */
 #define	SH4A_PCIEDMCCCR3	(0x0211E8)	/* R/W R/W 0x0000 0000 32 */
+#define SH4A_PCIEDMCHSR3	(0x0211EC)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEPCICONF0	(0x040000)	/* R R - 8/16/32 */
 #define	SH4A_PCIEPCICONF1	(0x040004)	/* R/W R/W 0x0008 0000 8/16/32 */
 #define	SH4A_PCIEPCICONF2	(0x040008)	/* R/W R/W 0xFF00 0000 8/16/32 */
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 0eed47b..7beb423 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -5,5 +5,7 @@
 header-y += hw_breakpoint.h
 header-y += posix_types_32.h
 header-y += posix_types_64.h
+header-y += ptrace_32.h
+header-y += ptrace_64.h
 header-y += unistd_32.h
 header-y += unistd_64.h
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index ce830fa..f38112b 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -50,25 +50,14 @@
 #define	R_SH_GOTPC		167
 
 /* FDPIC relocs */
-#define R_SH_GOT20		70
-#define R_SH_GOTOFF20		71
-#define R_SH_GOTFUNCDESC	72
-#define R_SH_GOTFUNCDESC20	73
-#define R_SH_GOTOFFFUNCDESC	74
-#define R_SH_GOTOFFFUNCDESC20	75
-#define R_SH_FUNCDESC		76
-#define R_SH_FUNCDESC_VALUE	77
-
-#if 0 /* XXX - later .. */
-#define R_SH_GOT20		198
-#define R_SH_GOTOFF20		199
-#define R_SH_GOTFUNCDESC	200
-#define R_SH_GOTFUNCDESC20	201
-#define R_SH_GOTOFFFUNCDESC	202
-#define R_SH_GOTOFFFUNCDESC20	203
-#define R_SH_FUNCDESC		204
-#define R_SH_FUNCDESC_VALUE	205
-#endif
+#define R_SH_GOT20		201
+#define R_SH_GOTOFF20		202
+#define R_SH_GOTFUNCDESC	203
+#define R_SH_GOTFUNCDESC20	204
+#define R_SH_GOTOFFFUNCDESC	205
+#define R_SH_GOTOFFFUNCDESC20	206
+#define R_SH_FUNCDESC		207
+#define R_SH_FUNCDESC_VALUE	208
 
 /* SHmedia relocs */
 #define R_SH_IMM_LOW16		246
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 6e7cea4..bd7e79a 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -58,7 +58,7 @@
 
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
 #endif
 
 #ifdef CONFIG_IOREMAP_FIXED
@@ -69,7 +69,7 @@
 	 */
 #define FIX_N_IOREMAPS	32
 	FIX_IOREMAP_BEGIN,
-	FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS,
+	FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
 #endif
 
 	__end_of_fixed_addresses
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index f8d9a73..04f53d3 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -41,14 +41,12 @@
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-	WARN_ON(1);
-	return -ENOSYS;
+	return __gpio_to_irq(gpio);
 }
 
 static inline int irq_to_gpio(unsigned int irq)
 {
-	WARN_ON(1);
-	return -EINVAL;
+	return -ENOSYS;
 }
 
 #endif /* CONFIG_GPIOLIB */
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index 02c2f01..45d08b6 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -9,7 +9,7 @@
  * advised to cap this at the hard limit that they're interested in
  * through the machvec.
  */
-#define NR_IRQS			256
+#define NR_IRQS			512
 #define NR_IRQS_LEGACY		8	/* Legacy external IRQ0-7 */
 
 /*
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 036c331..134f398 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -16,7 +16,6 @@
 	? (MAX_STACK_SIZE) \
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
-#define regs_return_value(_regs)		((_regs)->regs[0])
 #define flush_insn_slot(p)		do { } while (0)
 #define kretprobe_blacklist_size	0
 
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 8bd952f..f0efe97 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -37,6 +37,8 @@
 };
 
 /* arch/sh/drivers/pci/pci.c */
+extern raw_spinlock_t pci_config_lock;
+
 extern int register_pci_controller(struct pci_channel *hose);
 extern void pcibios_report_status(unsigned int status_mask, int warn);
 
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 61a445d..46d5179 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -13,7 +13,6 @@
 #include <linux/linkage.h>
 #include <asm/page.h>
 #include <asm/types.h>
-#include <asm/ptrace.h>
 #include <asm/hw_breakpoint.h>
 
 /*
@@ -194,8 +193,6 @@
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->pc)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->regs[15])
 
-#define user_stack_pointer(_regs)	((_regs)->regs[15])
-
 #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
 #define PREFETCH_STRIDE		L1_CACHE_BYTES
 #define ARCH_HAS_PREFETCH
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 621bc46..2a541dd 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -17,7 +17,6 @@
 #include <linux/compiler.h>
 #include <asm/page.h>
 #include <asm/types.h>
-#include <asm/ptrace.h>
 #include <cpu/registers.h>
 
 /*
@@ -231,7 +230,5 @@
 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
 #define KSTK_ESP(tsk)  ((tsk)->thread.sp)
 
-#define user_stack_pointer(_regs)	((_regs)->regs[15])
-
 #endif	/* __ASSEMBLY__ */
 #endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 2168fde..f6edc10 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -3,90 +3,7 @@
 
 /*
  * Copyright (C) 1999, 2000  Niibe Yutaka
- *
  */
-#if defined(__SH5__)
-struct pt_regs {
-	unsigned long long pc;
-	unsigned long long sr;
-	long long syscall_nr;
-	unsigned long long regs[63];
-	unsigned long long tregs[8];
-	unsigned long long pad[2];
-};
-#else
-/*
- * GCC defines register number like this:
- * -----------------------------
- *	 0 - 15 are integer registers
- *	17 - 22 are control/special registers
- *	24 - 39 fp registers
- *	40 - 47 xd registers
- *	48 -    fpscr register
- * -----------------------------
- *
- * We follows above, except:
- *	16 --- program counter (PC)
- *	22 --- syscall #
- *	23 --- floating point communication register
- */
-#define REG_REG0	 0
-#define REG_REG15	15
-
-#define REG_PC		16
-
-#define REG_PR		17
-#define REG_SR		18
-#define REG_GBR		19
-#define REG_MACH	20
-#define REG_MACL	21
-
-#define REG_SYSCALL	22
-
-#define REG_FPREG0	23
-#define REG_FPREG15	38
-#define REG_XFREG0	39
-#define REG_XFREG15	54
-
-#define REG_FPSCR	55
-#define REG_FPUL	56
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_regs {
-	unsigned long regs[16];
-	unsigned long pc;
-	unsigned long pr;
-	unsigned long sr;
-	unsigned long gbr;
-	unsigned long mach;
-	unsigned long macl;
-	long tra;
-};
-
-/*
- * This struct defines the way the DSP registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_dspregs {
-	unsigned long	a1;
-	unsigned long	a0g;
-	unsigned long	a1g;
-	unsigned long	m0;
-	unsigned long	m1;
-	unsigned long	a0;
-	unsigned long	x0;
-	unsigned long	x1;
-	unsigned long	y0;
-	unsigned long	y1;
-	unsigned long	dsr;
-	unsigned long	rs;
-	unsigned long	re;
-	unsigned long	mod;
-};
-#endif
 
 #define PTRACE_GETREGS		12	/* General registers */
 #define PTRACE_SETREGS		13
@@ -107,23 +24,103 @@
 #define PT_DATA_ADDR		248	/* &(struct user)->start_data */
 #define PT_TEXT_LEN		252
 
+#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
+#include "ptrace_64.h"
+#else
+#include "ptrace_32.h"
+#endif
+
 #ifdef __KERNEL__
+
+#include <linux/stringify.h>
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
 #include <asm/system.h>
 
 #define user_mode(regs)			(((regs)->sr & 0x40000000)==0)
+#define user_stack_pointer(regs)	((unsigned long)(regs)->regs[15])
+#define kernel_stack_pointer(regs)	((unsigned long)(regs)->regs[15])
 #define instruction_pointer(regs)	((unsigned long)(regs)->pc)
 
 extern void show_regs(struct pt_regs *);
 
-/*
- * These are defined as per linux/ptrace.h.
- */
-struct task_struct;
-
 #define arch_has_single_step()	(1)
 
+/*
+ * kprobe-based event tracer support
+ */
+struct pt_regs_offset {
+	const char *name;
+	int offset;
+};
+
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REGS_OFFSET_NAME(num)	\
+	{.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
+#define TREGS_OFFSET_NAME(num)	\
+	{.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+extern const struct pt_regs_offset regoffset_table[];
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:	pt_regs from which register value is gotten.
+ * @offset:	offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @addr:	address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+					   unsigned long addr)
+{
+	return ((addr & ~(THREAD_SIZE - 1))  ==
+		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @n:		stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+						      unsigned int n)
+{
+	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+	addr += n;
+	if (regs_within_kernel_stack(regs, (unsigned long)addr))
+		return *addr;
+	else
+		return 0;
+}
+
 struct perf_event;
 struct perf_sample_data;
 
diff --git a/arch/sh/include/asm/ptrace_32.h b/arch/sh/include/asm/ptrace_32.h
new file mode 100644
index 0000000..35d9e25
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_32.h
@@ -0,0 +1,83 @@
+#ifndef __ASM_SH_PTRACE_32_H
+#define __ASM_SH_PTRACE_32_H
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ *	 0 - 15 are integer registers
+ *	17 - 22 are control/special registers
+ *	24 - 39 fp registers
+ *	40 - 47 xd registers
+ *	48 -    fpscr register
+ * -----------------------------
+ *
+ * We follows above, except:
+ *	16 --- program counter (PC)
+ *	22 --- syscall #
+ *	23 --- floating point communication register
+ */
+#define REG_REG0	 0
+#define REG_REG15	15
+
+#define REG_PC		16
+
+#define REG_PR		17
+#define REG_SR		18
+#define REG_GBR		19
+#define REG_MACH	20
+#define REG_MACL	21
+
+#define REG_SYSCALL	22
+
+#define REG_FPREG0	23
+#define REG_FPREG15	38
+#define REG_XFREG0	39
+#define REG_XFREG15	54
+
+#define REG_FPSCR	55
+#define REG_FPUL	56
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+	unsigned long regs[16];
+	unsigned long pc;
+	unsigned long pr;
+	unsigned long sr;
+	unsigned long gbr;
+	unsigned long mach;
+	unsigned long macl;
+	long tra;
+};
+
+/*
+ * This struct defines the way the DSP registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_dspregs {
+	unsigned long	a1;
+	unsigned long	a0g;
+	unsigned long	a1g;
+	unsigned long	m0;
+	unsigned long	m1;
+	unsigned long	a0;
+	unsigned long	x0;
+	unsigned long	x1;
+	unsigned long	y0;
+	unsigned long	y1;
+	unsigned long	dsr;
+	unsigned long	rs;
+	unsigned long	re;
+	unsigned long	mod;
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET		offsetof(struct pt_regs, tra)
+#define regs_return_value(regs)	((regs)->regs[0])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_32_H */
diff --git a/arch/sh/include/asm/ptrace_64.h b/arch/sh/include/asm/ptrace_64.h
new file mode 100644
index 0000000..d43c1cb
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_64.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SH_PTRACE_64_H
+#define __ASM_SH_PTRACE_64_H
+
+struct pt_regs {
+	unsigned long long pc;
+	unsigned long long sr;
+	long long syscall_nr;
+	unsigned long long regs[63];
+	unsigned long long tregs[8];
+	unsigned long long pad[2];
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET		offsetof(struct pt_regs, tregs[7])
+#define regs_return_value(regs)	((regs)->regs[3])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_64_H */
diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h
index 3a1fb97..0b9fe2d 100644
--- a/arch/sh/include/asm/sizes.h
+++ b/arch/sh/include/asm/sizes.h
@@ -32,6 +32,7 @@
 #define SZ_512				0x00000200
 
 #define SZ_1K                           0x00000400
+#define SZ_2K                           0x00000800
 #define SZ_4K                           0x00001000
 #define SZ_8K                           0x00002000
 #define SZ_16K                          0x00004000
diff --git a/arch/sh/include/asm/sram.h b/arch/sh/include/asm/sram.h
new file mode 100644
index 0000000..a2808ce
--- /dev/null
+++ b/arch/sh/include/asm/sram.h
@@ -0,0 +1,38 @@
+#ifndef __ASM_SRAM_H
+#define __ASM_SRAM_H
+
+#ifdef CONFIG_HAVE_SRAM_POOL
+
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+/* arch/sh/mm/sram.c */
+extern struct gen_pool *sram_pool;
+
+static inline unsigned long sram_alloc(size_t len)
+{
+	if (!sram_pool)
+		return 0UL;
+
+	return gen_pool_alloc(sram_pool, len);
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+	return gen_pool_free(sram_pool, addr, len);
+}
+
+#else
+
+static inline unsigned long sram_alloc(size_t len)
+{
+	return 0;
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+}
+
+#endif /* CONFIG_HAVE_SRAM_POOL */
+
+#endif /* __ASM_SRAM_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 0bd7a17..1f1af5a 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -140,8 +140,6 @@
 extern unsigned long cached_to_uncached;
 extern unsigned long uncached_size;
 
-extern struct dentry *sh_debugfs_root;
-
 void per_cpu_trap_init(void);
 void default_idle(void);
 void cpu_idle_wait(void);
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 51296b3..c941b27 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -212,17 +212,16 @@
 }
 
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma, int);
+			    struct mem_access *ma, int, unsigned long address);
 
 static inline void trigger_address_error(void)
 {
-	if (__in_29bit_mode())
-		__asm__ __volatile__ (
-			"ldc %0, sr\n\t"
-			"mov.l @%1, %0"
-			:
-			: "r" (0x10000000), "r" (0x80000001)
-		);
+	__asm__ __volatile__ (
+		"ldc %0, sr\n\t"
+		"mov.l @%1, %0"
+		:
+		: "r" (0x10000000), "r" (0x80000001)
+	);
 }
 
 asmlinkage void do_address_error(struct pt_regs *regs,
diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h
index e0ac972..0df66f0 100644
--- a/arch/sh/include/asm/tlbflush.h
+++ b/arch/sh/include/asm/tlbflush.h
@@ -21,6 +21,8 @@
 					 unsigned long end);
 extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
 
+extern void __flush_tlb_global(void);
+
 #ifdef CONFIG_SMP
 
 extern void flush_tlb_all(void);
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 0e7f0fc..903cd61 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -345,13 +345,34 @@
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
 #define __NR_perf_event_open	336
+#define __NR_fanotify_init	337
+#define __NR_fanotify_mark	338
+#define __NR_prlimit64		339
 
-#define NR_syscalls 337
+/* Non-multiplexed socket family */
+#define __NR_socket		340
+#define __NR_bind		341
+#define __NR_connect		342
+#define __NR_listen		343
+#define __NR_accept		344
+#define __NR_getsockname	345
+#define __NR_getpeername	346
+#define __NR_socketpair		347
+#define __NR_send		348
+#define __NR_sendto		349
+#define __NR_recv		350
+#define __NR_recvfrom		351
+#define __NR_shutdown		352
+#define __NR_setsockopt		353
+#define __NR_getsockopt		354
+#define __NR_sendmsg		355
+#define __NR_recvmsg		356
+#define __NR_recvmmsg		357
+
+#define NR_syscalls 358
 
 #ifdef __KERNEL__
 
-#define __IGNORE_recvmmsg
-
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index 0580c33..09aa93f 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -387,10 +387,13 @@
 #define __NR_perf_event_open	364
 #define __NR_recvmmsg		365
 #define __NR_accept4		366
+#define __NR_fanotify_init	367
+#define __NR_fanotify_mark	368
+#define __NR_prlimit64		369
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 367
+#define NR_syscalls 370
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff --git a/arch/sh/include/cpu-sh3/cpu/mmu_context.h b/arch/sh/include/cpu-sh3/cpu/mmu_context.h
index ab09da7..0c7c735 100644
--- a/arch/sh/include/cpu-sh3/cpu/mmu_context.h
+++ b/arch/sh/include/cpu-sh3/cpu/mmu_context.h
@@ -16,6 +16,7 @@
 #define MMU_TEA		0xFFFFFFFC	/* TLB Exception Address */
 
 #define MMUCR		0xFFFFFFE0	/* MMU Control Register */
+#define MMUCR_TI	(1 << 2)	/* TLB flush bit */
 
 #define MMU_TLB_ADDRESS_ARRAY	0xF2000000
 #define MMU_PAGE_ASSOC_BIT	0x80
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index e1e9096..cffd25e 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -56,7 +56,9 @@
 #define FRQCR1			0xffc40004
 #define FRQMR1			0xffc40014
 #elif defined(CONFIG_CPU_SUBTYPE_SHX3)
-#define FRQCR			0xffc00014
+#define FRQCR0			0xffc00000
+#define FRQCR1			0xffc00004
+#define FRQMR1			0xffc00014
 #else
 #define FRQCR			0xffc00000
 #define FRQCR_PSTBY		0x0200
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h
index f4d267e..15f3de1 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7757.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h
@@ -3,241 +3,252 @@
 
 enum {
 	/* PTA */
-	GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
-	GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+	GPIO_PTA0, GPIO_PTA1, GPIO_PTA2, GPIO_PTA3,
+	GPIO_PTA4, GPIO_PTA5, GPIO_PTA6, GPIO_PTA7,
 
 	/* PTB */
-	GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
-	GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+	GPIO_PTB0, GPIO_PTB1, GPIO_PTB2, GPIO_PTB3,
+	GPIO_PTB4, GPIO_PTB5, GPIO_PTB6, GPIO_PTB7,
 
 	/* PTC */
-	GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
-	GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+	GPIO_PTC0, GPIO_PTC1, GPIO_PTC2, GPIO_PTC3,
+	GPIO_PTC4, GPIO_PTC5, GPIO_PTC6, GPIO_PTC7,
 
 	/* PTD */
-	GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
-	GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+	GPIO_PTD0, GPIO_PTD1, GPIO_PTD2, GPIO_PTD3,
+	GPIO_PTD4, GPIO_PTD5, GPIO_PTD6, GPIO_PTD7,
 
 	/* PTE */
-	GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
-	GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+	GPIO_PTE0, GPIO_PTE1, GPIO_PTE2, GPIO_PTE3,
+	GPIO_PTE4, GPIO_PTE5, GPIO_PTE6, GPIO_PTE7,
 
 	/* PTF */
-	GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
-	GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+	GPIO_PTF0, GPIO_PTF1, GPIO_PTF2, GPIO_PTF3,
+	GPIO_PTF4, GPIO_PTF5, GPIO_PTF6, GPIO_PTF7,
 
 	/* PTG */
-	GPIO_PTG7, GPIO_PTG6, GPIO_PTG5, GPIO_PTG4,
-	GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+	GPIO_PTG0, GPIO_PTG1, GPIO_PTG2, GPIO_PTG3,
+	GPIO_PTG4, GPIO_PTG5, GPIO_PTG6, GPIO_PTG7,
 
 	/* PTH */
-	GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
-	GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+	GPIO_PTH0, GPIO_PTH1, GPIO_PTH2, GPIO_PTH3,
+	GPIO_PTH4, GPIO_PTH5, GPIO_PTH6, GPIO_PTH7,
 
 	/* PTI */
-	GPIO_PTI7, GPIO_PTI6, GPIO_PTI5, GPIO_PTI4,
-	GPIO_PTI3, GPIO_PTI2, GPIO_PTI1, GPIO_PTI0,
+	GPIO_PTI0, GPIO_PTI1, GPIO_PTI2, GPIO_PTI3,
+	GPIO_PTI4, GPIO_PTI5, GPIO_PTI6, GPIO_PTI7,
 
 	/* PTJ */
-	GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4,
-	GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+	GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
+	GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV,
 
 	/* PTK */
-	GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
-	GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+	GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
+	GPIO_PTK4, GPIO_PTK5, GPIO_PTK6, GPIO_PTK7,
 
 	/* PTL */
-	GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
-	GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+	GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
+	GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV,
 
 	/* PTM */
-		   GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
-	GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+	GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
+	GPIO_PTM4, GPIO_PTM5, GPIO_PTM6, GPIO_PTM7,
 
 	/* PTN */
-	GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
-	GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+	GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
+	GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV,
 
 	/* PTO */
-	GPIO_PTO7, GPIO_PTO6, GPIO_PTO5, GPIO_PTO4,
-	GPIO_PTO3, GPIO_PTO2, GPIO_PTO1, GPIO_PTO0,
+	GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
+	GPIO_PTO4, GPIO_PTO5, GPIO_PTO6, GPIO_PTO7,
 
 	/* PTP */
-		   GPIO_PTP6, GPIO_PTP5, GPIO_PTP4,
-	GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+	GPIO_PTP0, GPIO_PTP1, GPIO_PTP2, GPIO_PTP3,
+	GPIO_PTP4, GPIO_PTP5, GPIO_PTP6, GPIO_PTP7,
 
 	/* PTQ */
-		   GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
-	GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+	GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
+	GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV,
 
 	/* PTR */
-	GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
-	GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+	GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
+	GPIO_PTR4, GPIO_PTR5, GPIO_PTR6, GPIO_PTR7,
 
 	/* PTS */
-	GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
-	GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+	GPIO_PTS0, GPIO_PTS1, GPIO_PTS2, GPIO_PTS3,
+	GPIO_PTS4, GPIO_PTS5, GPIO_PTS6, GPIO_PTS7,
 
 	/* PTT */
-			      GPIO_PTT5, GPIO_PTT4,
-	GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+	GPIO_PTT0, GPIO_PTT1, GPIO_PTT2, GPIO_PTT3,
+	GPIO_PTT4, GPIO_PTT5, GPIO_PTT6, GPIO_PTT7,
 
 	/* PTU */
-	GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
-	GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+	GPIO_PTU0, GPIO_PTU1, GPIO_PTU2, GPIO_PTU3,
+	GPIO_PTU4, GPIO_PTU5, GPIO_PTU6, GPIO_PTU7,
 
 	/* PTV */
-	GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
-	GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+	GPIO_PTV0, GPIO_PTV1, GPIO_PTV2, GPIO_PTV3,
+	GPIO_PTV4, GPIO_PTV5, GPIO_PTV6, GPIO_PTV7,
 
 	/* PTW */
-	GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
-	GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+	GPIO_PTW0, GPIO_PTW1, GPIO_PTW2, GPIO_PTW3,
+	GPIO_PTW4, GPIO_PTW5, GPIO_PTW6, GPIO_PTW7,
 
 	/* PTX */
-	GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
-	GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+	GPIO_PTX0, GPIO_PTX1, GPIO_PTX2, GPIO_PTX3,
+	GPIO_PTX4, GPIO_PTX5, GPIO_PTX6, GPIO_PTX7,
 
 	/* PTY */
-	GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
-	GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+	GPIO_PTY0, GPIO_PTY1, GPIO_PTY2, GPIO_PTY3,
+	GPIO_PTY4, GPIO_PTY5, GPIO_PTY6, GPIO_PTY7,
 
 	/* PTZ */
-	GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
-	GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+	GPIO_PTZ0, GPIO_PTZ1, GPIO_PTZ2, GPIO_PTZ3,
+	GPIO_PTZ4, GPIO_PTZ5, GPIO_PTZ6, GPIO_PTZ7,
 
 
-	/* PTA (mobule: LBSC, CPG, LPC) */
+	/* PTA (mobule: LBSC, RGMII) */
 	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,
+	GPIO_FN_ET0_MDC,	GPIO_FN_ET0_MDIO,
+	GPIO_FN_ET1_MDC,	GPIO_FN_ET1_MDIO,
 
-	/* 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,
+	/* PTB (mobule: INTC, ONFI, TMU) */
+	GPIO_FN_IRQ15,	GPIO_FN_IRQ14,	GPIO_FN_IRQ13,	GPIO_FN_IRQ12,
+	GPIO_FN_IRQ11,	GPIO_FN_IRQ10,	GPIO_FN_IRQ9,	GPIO_FN_IRQ8,
+	GPIO_FN_ON_NRE,	GPIO_FN_ON_NWE,	GPIO_FN_ON_NWP,	GPIO_FN_ON_NCE0,
+	GPIO_FN_ON_R_B0,	GPIO_FN_ON_ALE,	GPIO_FN_ON_CLE,
+	GPIO_FN_TCLK,
 
-	/* 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) */
+	/* PTC (mobule: IRQ, PWMU) */
 	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,
+	GPIO_FN_PWMU0,	GPIO_FN_PWMU1,	GPIO_FN_PWMU2,	GPIO_FN_PWMU3,
+	GPIO_FN_PWMU4,	GPIO_FN_PWMU5,
 
-	/* 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,
+	/* PTD (mobule: SPI0, DMAC) */
+	GPIO_FN_SP0_MOSI,	GPIO_FN_SP0_MISO,	GPIO_FN_SP0_SCK,
+	GPIO_FN_SP0_SCK_FB,	GPIO_FN_SP0_SS0,	GPIO_FN_SP0_SS1,
+	GPIO_FN_SP0_SS2,	GPIO_FN_SP0_SS3,	GPIO_FN_DREQ0,
+	GPIO_FN_DACK0,		GPIO_FN_TEND0,
 
-	/* 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,
+	/* PTE (mobule: RMII) */
+	GPIO_FN_RMII0_CRS_DV,	GPIO_FN_RMII0_TXD1,	GPIO_FN_RMII0_TXD0,
+	GPIO_FN_RMII0_TXEN,	GPIO_FN_RMII0_REFCLK,	GPIO_FN_RMII0_RXD1,
+	GPIO_FN_RMII0_RXD0,	GPIO_FN_RMII0_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,
+	/* PTF (mobule: RMII, SerMux) */
+	GPIO_FN_RMII1_CRS_DV,	GPIO_FN_RMII1_TXD1,	GPIO_FN_RMII1_TXD0,
+	GPIO_FN_RMII1_TXEN,	GPIO_FN_RMII1_REFCLK,	GPIO_FN_RMII1_RXD1,
+	GPIO_FN_RMII1_RXD0,	GPIO_FN_RMII1_RX_ER,	GPIO_FN_RAC_RI,
 
-	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
-	GPIO_FN_TCLK,	GPIO_FN_RXD4,	GPIO_FN_TXD4,
+	/* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+	GPIO_FN_BOOTFMS,		GPIO_FN_BOOTWP,
+	GPIO_FN_A25,	GPIO_FN_A24,	GPIO_FN_SERIRQ,	GPIO_FN_WDTOVF,
+	GPIO_FN_LPCPD,	GPIO_FN_LDRQ,	GPIO_FN_MMCCLK,	GPIO_FN_MMCCMD,
+
+	/* PTH (mobule: SPI1, LPC, DMAC, ADC) */
 	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,
+	GPIO_FN_WP,	GPIO_FN_FMS0,	GPIO_FN_TEND1,	GPIO_FN_DREQ1,
+	GPIO_FN_DACK1,	GPIO_FN_ADTRG1,	GPIO_FN_ADTRG0,
 
-	/* 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,
+	/* PTI (mobule: LBSC, SDHI) */
+	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_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,
 
-	/* 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,
+	/* PTJ (mobule: SCIF234) */
+	GPIO_FN_RTS3,	GPIO_FN_CTS3,	GPIO_FN_TXD3,	GPIO_FN_RXD3,
+	GPIO_FN_RTS4,	GPIO_FN_RXD4,	GPIO_FN_TXD4,
 
-	/* 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,
+	/* PTK (mobule: SERMUX, LBSC, SCIF) */
+	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_CLKOUT,
+	GPIO_FN_SCK2,		GPIO_FN_SCK4,	GPIO_FN_SCK3,
 
-	/* 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,
+	/* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+	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_TXD,	GPIO_FN_RXD2,		GPIO_FN_CS5,
+	GPIO_FN_CS6,		GPIO_FN_AUDSYNC,	GPIO_FN_AUDCK,
+	GPIO_FN_TXD2,
 
-	/* PTM (mobule: IIC, LPC) */
+	/* PTM (mobule: LBSC, IIC) */
+	GPIO_FN_CS4,	GPIO_FN_RD,	GPIO_FN_WE0,	GPIO_FN_CS0,
 	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,
+	/* PTN (mobule: USB, JMC, SGPIO, WDT) */
+	GPIO_FN_VBUS_EN,	GPIO_FN_VBUS_OC,	GPIO_FN_JMCTCK,
+	GPIO_FN_JMCTMS,		GPIO_FN_JMCTDO,		GPIO_FN_JMCTDI,
+	GPIO_FN_JMCTRST,
+	GPIO_FN_SGPIO1_CLK,	GPIO_FN_SGPIO1_LOAD,	GPIO_FN_SGPIO1_DI,
+	GPIO_FN_SGPIO1_DO,	GPIO_FN_SUB_CLKIN,
 
-	/* 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,
+	/* PTO (mobule: SGPIO, SerMux) */
+	GPIO_FN_SGPIO0_CLK,	GPIO_FN_SGPIO0_LOAD,	GPIO_FN_SGPIO0_DI,
+	GPIO_FN_SGPIO0_DO,	GPIO_FN_SGPIO2_CLK,	GPIO_FN_SGPIO2_LOAD,
+	GPIO_FN_SGPIO2_DI,	GPIO_FN_SGPIO2_DO,	GPIO_FN_COM1_TXD,
+	GPIO_FN_COM1_RXD,	GPIO_FN_COM1_RTS,	GPIO_FN_COM1_CTS,
 
 	/* 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_DDC3,	GPIO_FN_DDC2,	GPIO_FN_SDA2,	GPIO_FN_SCL2,
 	GPIO_FN_SDA1,	GPIO_FN_SCL1,	GPIO_FN_SDA0,	GPIO_FN_SCL0,
+	GPIO_FN_SDA8,	GPIO_FN_SCL8,
 
 	/* PTS (mobule: GRA, IIC) */
-	GPIO_FN_DDC1,	GPIO_FN_DDC0,
-	GPIO_FN_SDA9,	GPIO_FN_SCL9,	GPIO_FN_SDA5,	GPIO_FN_SCL5,
+	GPIO_FN_DDC1,	GPIO_FN_DDC0,	GPIO_FN_SDA5,	GPIO_FN_SCL5,
 	GPIO_FN_SDA4,	GPIO_FN_SCL4,	GPIO_FN_SDA3,	GPIO_FN_SCL3,
+	GPIO_FN_SDA9,	GPIO_FN_SCL9,
 
-	/* 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,
+	/* PTT (mobule: PWMX, AUD) */
+	GPIO_FN_PWMX7,	GPIO_FN_PWMX6,	GPIO_FN_PWMX5,	GPIO_FN_PWMX4,
+	GPIO_FN_PWMX3,	GPIO_FN_PWMX2,	GPIO_FN_PWMX1,	GPIO_FN_PWMX0,
+	GPIO_FN_AUDATA3,	GPIO_FN_AUDATA2,	GPIO_FN_AUDATA1,
+	GPIO_FN_AUDATA0,	GPIO_FN_STATUS1,	GPIO_FN_STATUS0,
 
-	/* 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,
+	/* PTU (mobule: LPC, APM) */
+	GPIO_FN_LGPIO7,	GPIO_FN_LGPIO6,	GPIO_FN_LGPIO5,	GPIO_FN_LGPIO4,
+	GPIO_FN_LGPIO3,	GPIO_FN_LGPIO2,	GPIO_FN_LGPIO1,	GPIO_FN_LGPIO0,
+	GPIO_FN_APMONCTL_O,	GPIO_FN_APMPWBTOUT_O,	GPIO_FN_APMSCI_O,
+	GPIO_FN_APMVDDON,	GPIO_FN_APMSLPBTN,	GPIO_FN_APMPWRBTN,
+	GPIO_FN_APMS5N,		GPIO_FN_APMS3N,
 
-	/* PTV (mobule: LBSC, DMAC) */
+	/* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
 	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,
+	GPIO_FN_COM2_RI,	GPIO_FN_R_SPI_MOSI,	GPIO_FN_R_SPI_MISO,
+	GPIO_FN_R_SPI_RSPCK,	GPIO_FN_R_SPI_SSL0,	GPIO_FN_R_SPI_SSL1,
+	GPIO_FN_EVENT7,		GPIO_FN_EVENT6,		GPIO_FN_VBIOS_DI,
+	GPIO_FN_VBIOS_DO,	GPIO_FN_VBIOS_CLK,	GPIO_FN_VBIOS_CS,
 
-	/* PTW (mobule: LBSC) */
+	/* PTW (mobule: LBSC, EVC, SCIF) */
 	GPIO_FN_A15,	GPIO_FN_A14,	GPIO_FN_A13,	GPIO_FN_A12,
 	GPIO_FN_A11,	GPIO_FN_A10,	GPIO_FN_A9,	GPIO_FN_A8,
+	GPIO_FN_EVENT5,	GPIO_FN_EVENT4,	GPIO_FN_EVENT3,	GPIO_FN_EVENT2,
+	GPIO_FN_EVENT1,	GPIO_FN_EVENT0,	GPIO_FN_CTS4,	GPIO_FN_CTS2,
 
-	/* PTX (mobule: LBSC) */
+	/* PTX (mobule: LBSC, SCIF, SIM) */
 	GPIO_FN_A7,	GPIO_FN_A6,	GPIO_FN_A5,	GPIO_FN_A4,
 	GPIO_FN_A3,	GPIO_FN_A2,	GPIO_FN_A1,	GPIO_FN_A0,
+	GPIO_FN_RTS2,	GPIO_FN_SIM_D,	GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
 
 	/* 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,
+
+	/* PTZ (mobule: eMMC, ONFI) */
+	GPIO_FN_MMCDAT7,	GPIO_FN_MMCDAT6,	GPIO_FN_MMCDAT5,
+	GPIO_FN_MMCDAT4,	GPIO_FN_MMCDAT3,	GPIO_FN_MMCDAT2,
+	GPIO_FN_MMCDAT1,	GPIO_FN_MMCDAT0,
+	GPIO_FN_ON_DQ7,	GPIO_FN_ON_DQ6,	GPIO_FN_ON_DQ5,	GPIO_FN_ON_DQ4,
+	GPIO_FN_ON_DQ3,	GPIO_FN_ON_DQ2,	GPIO_FN_ON_DQ1,	GPIO_FN_ON_DQ0,
 };
 
 #endif /* __ASM_SH7757_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/shx3.h b/arch/sh/include/cpu-sh4/cpu/shx3.h
new file mode 100644
index 0000000..68d9080
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/shx3.h
@@ -0,0 +1,64 @@
+#ifndef __CPU_SHX3_H
+#define __CPU_SHX3_H
+
+enum {
+	/* PA */
+	GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+	GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+	/* PB */
+	GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+	GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+	/* PC */
+	GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+	GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+	/* PD */
+	GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+	GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+	/* PE */
+	GPIO_PE7, GPIO_PE6, GPIO_PE5, GPIO_PE4,
+	GPIO_PE3, GPIO_PE2, GPIO_PE1, GPIO_PE0,
+
+	/* PF */
+	GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+	GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+	/* PG */
+	GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
+	GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
+
+	/* PH */
+	GPIO_PH5, GPIO_PH4,
+	GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+
+	/* SCIF */
+	GPIO_FN_SCK3, GPIO_FN_TXD3, GPIO_FN_RXD3,
+	GPIO_FN_SCK2, GPIO_FN_TXD2, GPIO_FN_RXD2,
+	GPIO_FN_SCK1, GPIO_FN_TXD1, GPIO_FN_RXD1,
+	GPIO_FN_SCK0, GPIO_FN_TXD0, GPIO_FN_RXD0,
+
+	/* LBSC */
+	GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+	GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+	GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+	GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+	GPIO_FN_WE3, GPIO_FN_WE2, GPIO_FN_CS6, GPIO_FN_CS5,
+	GPIO_FN_CS4, GPIO_FN_CLKOUTENB, GPIO_FN_BREQ,
+	GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+	/* DMAC */
+	GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+	GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+	GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+	GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+	/* INTC */
+	GPIO_FN_IRQ3, GPIO_FN_IRQ2, GPIO_FN_IRQ1, GPIO_FN_IRQ0,
+	GPIO_FN_IRL3, GPIO_FN_IRL2, GPIO_FN_IRL1, GPIO_FN_IRL0,
+	GPIO_FN_IRQOUT, GPIO_FN_STATUS1, GPIO_FN_STATUS0,
+};
+
+#endif /* __CPU_SHX3_H */
diff --git a/arch/sh/include/mach-common/mach/sh2007.h b/arch/sh/include/mach-common/mach/sh2007.h
new file mode 100644
index 0000000..48180b9
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/sh2007.h
@@ -0,0 +1,117 @@
+#ifndef __MACH_SH2007_H
+#define __MACH_SH2007_H
+
+#define CS5BCR		0xff802050
+#define CS5WCR		0xff802058
+#define CS5PCR		0xff802070
+
+#define BUS_SZ8		1
+#define BUS_SZ16	2
+#define BUS_SZ32	3
+
+#define PCMCIA_IODYN	1
+#define PCMCIA_ATA	0
+#define PCMCIA_IO8	2
+#define PCMCIA_IO16	3
+#define PCMCIA_COMM8	4
+#define PCMCIA_COMM16	5
+#define PCMCIA_ATTR8	6
+#define PCMCIA_ATTR16	7
+
+#define TYPE_SRAM	0
+#define TYPE_PCMCIA	4
+
+/* write-read/write-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWW5		0
+#define IWW6		3
+/* different area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWD5		2
+#define IWRWD6		2
+/* same area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWS5		2
+#define IWRWS6		2
+/* different area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRD5		2
+#define IWRRD6		2
+/* same area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRS5		0
+#define IWRRS6		2
+/* burst count (0-3:4,8,16,32) */
+#define BST5		0
+#define BST6		0
+/* bus size */
+#define SZ5		BUS_SZ16
+#define SZ6		BUS_SZ16
+/* RD hold for SRAM (0-1:0,1) */
+#define RDSPL5		0
+#define RDSPL6		0
+/* Burst pitch (0-7:0,1,2,3,4,5,6,7) */
+#define BW5		0
+#define BW6		0
+/* Multiplex (0-1:0,1) */
+#define MPX5		0
+#define MPX6		0
+/* device type */
+#define TYPE5		TYPE_PCMCIA
+#define TYPE6		TYPE_PCMCIA
+/* address setup before assert CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADS5		0
+#define ADS6		0
+/* address hold after negate CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADH5		0
+#define ADH6		0
+/* CSn assert to RD assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDS5		0
+#define RDS6		0
+/* RD negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDH5		0
+#define RDH6		0
+/* CSn assert to WE assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTS5		0
+#define WTS6		0
+/* WE negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTH5		0
+#define WTH6		0
+/* BS hold (0-1:1,2) */
+#define BSH5		0
+#define BSH6		0
+/* wait cycle (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define IW5		6	/* 60ns PIO mode 4 */
+#define IW6		15	/* 250ns */
+
+#define SAA5		PCMCIA_IODYN	/* IDE area b4000000-b5ffffff */
+#define SAB5		PCMCIA_IODYN	/* CF  area b6000000-b7ffffff */
+#define PCWA5		0	/* additional wait A (0-3:0,15,30,50) */
+#define PCWB5		0	/* additional wait B (0-3:0,15,30,50) */
+/* wait B (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define PCIW5		12
+/* Address->OE/WE assert delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEDA5		2
+/* Address->OE/WE assert delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEDB5		4
+/* OE/WE negate->Address delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEHA5		2
+/* OE/WE negate->Address delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEHB5		3
+
+#define CS5BCR_D	((IWW5<<28)|(IWRWD5<<24)|(IWRWS5<<20)|		\
+			(IWRRD5<<16)|(IWRRS5<<12)|(BST5<<10)|		\
+			(SZ5<<8)|(RDSPL5<<7)|(BW5<<4)|(MPX5<<3)|TYPE5)
+#define CS5WCR_D	((ADS5<<28)|(ADH5<<24)|(RDS5<<20)|	\
+			(RDH5<<16)|(WTS5<<12)|(WTH5<<8)|(BSH5<<4)|IW5)
+#define CS5PCR_D	((SAA5<<28)|(SAB5<<24)|(PCWA5<<22)|		\
+			(PCWB5<<20)|(PCIW5<<16)|(TEDA5<<12)|		\
+			(TEDB5<<8)|(TEHA5<<4)|TEHB5)
+
+#define SMC0_BASE       0xb0800000      /* eth0 */
+#define SMC1_BASE       0xb0900000      /* eth1 */
+#define CF_BASE         0xb6100000      /* Compact Flash (I/O area) */
+#define IDE_BASE        0xb4000000      /* IDE */
+#define PC104_IO_BASE   0xb8000000
+#define PC104_MEM_BASE  0xba000000
+#define SMC_IO_SIZE     0x100
+
+#define CF_OFFSET       0x1f0
+#define IDE_OFFSET      0x170
+
+#endif /* __MACH_SH2007_H */
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
index 416b621..40f0c2d 100644
--- a/arch/sh/include/mach-sdk7786/mach/fpga.h
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -31,11 +31,35 @@
 #define EXTASR		0x110
 #define SPCAR		0x120
 #define INTMSR		0x130
+
 #define PCIECR		0x140
+#define  PCIECR_PCIEMUX1	BIT(15)
+#define  PCIECR_PCIEMUX0	BIT(14)
+#define  PCIECR_PRST4		BIT(12) /* slot 4 card present */
+#define  PCIECR_PRST3		BIT(11) /* slot 3 card present */
+#define  PCIECR_PRST2		BIT(10) /* slot 2 card present */
+#define  PCIECR_PRST1		BIT(9)  /* slot 1 card present */
+#define  PCIECR_CLKEN		BIT(4)	/* oscillator enable */
+
 #define FAER		0x150
 #define USRGPIR		0x160
+
 /* 0x170 reserved */
-#define LCLASR		0x180
+
+#define LCLASR			0x180
+#define  LCLASR_FRAMEN		BIT(15)
+
+#define  LCLASR_FPGA_SEL_SHIFT	12
+#define  LCLASR_NAND_SEL_SHIFT	8
+#define  LCLASR_NORB_SEL_SHIFT	4
+#define  LCLASR_NORA_SEL_SHIFT	0
+
+#define  LCLASR_AREA_MASK	0x7
+
+#define  LCLASR_FPGA_SEL_MASK	(LCLASR_AREA_MASK << LCLASR_FPGA_SEL_SHIFT)
+#define  LCLASR_NAND_SEL_MASK	(LCLASR_AREA_MASK << LCLASR_NAND_SEL_SHIFT)
+#define  LCLASR_NORB_SEL_MASK	(LCLASR_AREA_MASK << LCLASR_NORB_SEL_SHIFT)
+#define  LCLASR_NORA_SEL_MASK	(LCLASR_AREA_MASK << LCLASR_NORA_SEL_SHIFT)
 
 #define SBCR		0x190
 #define  SCBR_I2CMEN	BIT(0)	/* FPGA I2C master enable */
diff --git a/arch/sh/include/mach-x3proto/mach/hardware.h b/arch/sh/include/mach-x3proto/mach/hardware.h
new file mode 100644
index 0000000..52bca57
--- /dev/null
+++ b/arch/sh/include/mach-x3proto/mach/hardware.h
@@ -0,0 +1,12 @@
+#ifndef __MACH_X3PROTO_HARDWARE_H
+#define __MACH_X3PROTO_HARDWARE_H
+
+struct gpio_chip;
+
+/* arch/sh/boards/mach-x3proto/gpio.c */
+int x3proto_gpio_setup(void);
+extern struct gpio_chip x3proto_gpio_chip;
+
+#define NR_BASEBOARD_GPIOS	16
+
+#endif /* __MACH_X3PROTO_HARDWARE_H */
diff --git a/arch/sh/include/asm/ilsel.h b/arch/sh/include/mach-x3proto/mach/ilsel.h
similarity index 100%
rename from arch/sh/include/asm/ilsel.h
rename to arch/sh/include/mach-x3proto/mach/ilsel.h
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index e25f3c6..8eed6a4 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -12,9 +12,9 @@
 CFLAGS_REMOVE_return_address.o = -pg
 
 obj-y	:= clkdev.o debugtraps.o dma-nommu.o dumpstack.o 		\
-	   idle.o io.o irq.o						\
-	   irq_$(BITS).o machvec.o nmi_debug.o process.o		\
-	   process_$(BITS).o ptrace_$(BITS).o				\
+	   idle.o io.o irq.o irq_$(BITS).o kdebugfs.o			\
+	   machvec.o nmi_debug.o process.o				\
+	   process_$(BITS).o ptrace.o ptrace_$(BITS).o			\
 	   reboot.o return_address.o					\
 	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
 	   syscalls_$(BITS).o time.o topology.o traps.o			\
@@ -44,4 +44,4 @@
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)		+= hw_breakpoint.o
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
 
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
index befc255..1f800ef 100644
--- a/arch/sh/kernel/clkdev.c
+++ b/arch/sh/kernel/clkdev.c
@@ -161,9 +161,11 @@
  */
 void clkdev_drop(struct clk_lookup *cl)
 {
+	struct clk_lookup_alloc *cla = container_of(cl, struct clk_lookup_alloc, cl);
+
 	mutex_lock(&clocks_mutex);
 	list_del(&cl->node);
 	mutex_unlock(&clocks_mutex);
-	kfree(cl);
+	kfree(cla);
 }
 EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index d180f16..b93458f 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -150,7 +150,7 @@
 			boot_cpu_data.type = CPU_SH7724;
 			boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
 			break;
-		case 0x50:
+		case 0x10:
 			boot_cpu_data.type = CPU_SH7757;
 			break;
 		}
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index b144e8a..cc122b1 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -8,13 +8,13 @@
 obj-$(CONFIG_CPU_SUBTYPE_SH7770)	+= setup-sh7770.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= setup-sh7780.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7785)	+= setup-sh7785.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7786)	+= setup-sh7786.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786)	+= setup-sh7786.o intc-shx3.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7343)	+= setup-sh7343.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7722)	+= setup-sh7722.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7723)	+= setup-sh7723.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7724)	+= setup-sh7724.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7366)	+= setup-sh7366.o
-obj-$(CONFIG_CPU_SUBTYPE_SHX3)		+= setup-shx3.o
+obj-$(CONFIG_CPU_SUBTYPE_SHX3)		+= setup-shx3.o intc-shx3.o
 
 # SMP setup
 smp-$(CONFIG_CPU_SHX3)			:= smp-shx3.o
@@ -40,6 +40,7 @@
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7757)	:= pinmux-sh7757.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SHX3)	:= pinmux-shx3.o
 
 obj-y					+= $(clock-y)
 obj-$(CONFIG_SMP)			+= $(smp-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index 0a752bd..ce39a2a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -3,7 +3,7 @@
  *
  * SH7757 support for the clock framework
  *
- *  Copyright (C) 2009  Renesas Solutions Corp.
+ *  Copyright (C) 2009-2010  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
@@ -16,124 +16,147 @@
 #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 = __raw_readl(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 = (__raw_readl(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 = (__raw_readl(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 = (__raw_readl(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 = {
-	.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
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
  */
-static struct clk *sh7757_onchip_clocks[] = {
-	&sh7757_shyway_clk,
+static struct clk extal_clk = {
+	.rate		= 48000000,
+};
+
+static unsigned long pll_recalc(struct clk *clk)
+{
+	int multiplier;
+
+	multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;
+
+	return clk->parent->rate * multiplier;
+}
+
+static struct clk_ops pll_clk_ops = {
+	.recalc		= pll_recalc,
+};
+
+static struct clk pll_clk = {
+	.ops		= &pll_clk_ops,
+	.parent		= &extal_clk,
+	.flags		= CLK_ENABLE_ON_INIT,
+};
+
+static struct clk *clks[] = {
+	&extal_clk,
+	&pll_clk,
+};
+
+static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,
+			       1, 1, 1, 16, 1, 24, 1, 1 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = div2,
+	.nr_divisors = ARRAY_SIZE(div2),
+};
+
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };
+
+#define DIV4(_bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)
+
+struct clk div4_clks[DIV4_NR] = {
+	/*
+	 * P clock is always enable, because some P clock modules is used
+	 * by Host PC.
+	 */
+	[DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),
+	[DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),
+	[DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),
+};
+
+#define MSTPCR0		0xffc80030
+#define MSTPCR1		0xffc80034
+
+enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,
+       MSTP111, MSTP110, MSTP103, MSTP102,
+       MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+	/* MSTPCR0 */
+	[MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
+	[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
+
+	/* MSTPCR1 */
+	[MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
+	[MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),
+	[MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),
+	[MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
+	[MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
+	[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
+	[MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
 };
 
 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 
 static struct clk_lookup lookups[] = {
 	/* main clocks */
-	CLKDEV_CON_ID("shyway_clk", &sh7757_shyway_clk),
+	CLKDEV_CON_ID("extal", &extal_clk),
+	CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+	/* DIV4 clocks */
+	CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+	CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+	/* MSTP32 clocks */
+	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),
+	CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]),
+	{
+		/* TMU0 */
+		.dev_id		= "sh_tmu.0",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP113],
+	}, {
+		/* TMU1 */
+		.dev_id		= "sh_tmu.1",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP114],
+	},
+	{
+		/* SCIF4 (But, ID is 2) */
+		.dev_id		= "sh-sci.2",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP112],
+	}, {
+		/* SCIF3 */
+		.dev_id		= "sh-sci.1",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP111],
+	}, {
+		/* SCIF2 */
+		.dev_id		= "sh-sci.0",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP110],
+	},
+	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
 };
 
-static int __init sh7757_clk_init(void)
+int __init arch_clk_init(void)
 {
-	struct clk *clk = clk_get(NULL, "master_clk");
-	int i;
+	int i, ret = 0;
 
-	for (i = 0; i < ARRAY_SIZE(sh7757_onchip_clocks); i++) {
-		struct clk *clkp = sh7757_onchip_clocks[i];
+	for (i = 0; i < ARRAY_SIZE(clks); i++)
+		ret |= clk_register(clks[i]);
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
 
-		clkp->parent = clk;
-		clk_register(clkp);
-		clk_enable(clkp);
-	}
+	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+					   &div4_table);
+	if (!ret)
+		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
-	/*
-	 * 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);
-
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	return 0;
+	return ret;
 }
 
-arch_initcall(sh7757_clk_init);
-
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 236a628..4f70df6 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -5,7 +5,7 @@
  *
  *  Copyright (C) 2006-2007  Renesas Technology Corp.
  *  Copyright (C) 2006-2007  Renesas Solutions Corp.
- *  Copyright (C) 2006-2007  Paul Mundt
+ *  Copyright (C) 2006-2010  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
@@ -18,120 +18,179 @@
 #include <asm/clock.h>
 #include <asm/freq.h>
 
-static int ifc_divisors[] = { 1, 2, 4 ,6 };
-static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 };
-static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 };
-static int cfc_divisors[] = { 1, 1, 4, 6 };
-
-#define IFC_POS		28
-#define IFC_MSK		0x0003
-#define BFC_MSK		0x000f
-#define PFC_MSK		0x000f
-#define CFC_MSK		0x0003
-#define BFC_POS		16
-#define PFC_POS		0
-#define CFC_POS		20
-
-static void master_clk_init(struct clk *clk)
-{
-	clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK];
-}
-
-static struct clk_ops shx3_master_clk_ops = {
-	.init		= master_clk_init,
-};
-
-static unsigned long module_clk_recalc(struct clk *clk)
-{
-	int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK);
-	return clk->parent->rate / pfc_divisors[idx];
-}
-
-static struct clk_ops shx3_module_clk_ops = {
-	.recalc		= module_clk_recalc,
-};
-
-static unsigned long bus_clk_recalc(struct clk *clk)
-{
-	int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK);
-	return clk->parent->rate / bfc_divisors[idx];
-}
-
-static struct clk_ops shx3_bus_clk_ops = {
-	.recalc		= bus_clk_recalc,
-};
-
-static unsigned long cpu_clk_recalc(struct clk *clk)
-{
-	int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK);
-	return clk->parent->rate / ifc_divisors[idx];
-}
-
-static struct clk_ops shx3_cpu_clk_ops = {
-	.recalc		= cpu_clk_recalc,
-};
-
-static struct clk_ops *shx3_clk_ops[] = {
-	&shx3_master_clk_ops,
-	&shx3_module_clk_ops,
-	&shx3_bus_clk_ops,
-	&shx3_cpu_clk_ops,
-};
-
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
-	if (idx < ARRAY_SIZE(shx3_clk_ops))
-		*ops = shx3_clk_ops[idx];
-}
-
-static unsigned long shyway_clk_recalc(struct clk *clk)
-{
-	int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK);
-	return clk->parent->rate / cfc_divisors[idx];
-}
-
-static struct clk_ops shx3_shyway_clk_ops = {
-	.recalc		= shyway_clk_recalc,
-};
-
-static struct clk shx3_shyway_clk = {
-	.flags		= CLK_ENABLE_ON_INIT,
-	.ops		= &shx3_shyway_clk_ops,
-};
-
 /*
- * Additional SHx3-specific on-chip clocks that aren't already part of the
- * clock framework
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
  */
-static struct clk *shx3_onchip_clocks[] = {
-	&shx3_shyway_clk,
+static struct clk extal_clk = {
+	.rate		= 16666666,
+};
+
+static unsigned long pll_recalc(struct clk *clk)
+{
+	/* PLL1 has a fixed x72 multiplier.  */
+	return clk->parent->rate * 72;
+}
+
+static struct clk_ops pll_clk_ops = {
+	.recalc		= pll_recalc,
+};
+
+static struct clk pll_clk = {
+	.ops		= &pll_clk_ops,
+	.parent		= &extal_clk,
+	.flags		= CLK_ENABLE_ON_INIT,
+};
+
+static struct clk *clks[] = {
+	&extal_clk,
+	&pll_clk,
+};
+
+static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
+			       24, 32, 36, 48 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = div2,
+	.nr_divisors = ARRAY_SIZE(div2),
+};
+
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_SHA, DIV4_P, DIV4_NR };
+
+#define DIV4(_bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
+
+struct clk div4_clks[DIV4_NR] = {
+	[DIV4_P] = DIV4(0, 0x0f80, 0),
+	[DIV4_SHA] = DIV4(4, 0x0ff0, 0),
+	[DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
+	[DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
+	[DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
+	[DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
+};
+
+#define MSTPCR0		0xffc00030
+#define MSTPCR1		0xffc00034
+
+enum { MSTP027, MSTP026, MSTP025, MSTP024,
+       MSTP009, MSTP008, MSTP003, MSTP002,
+       MSTP001, MSTP000, MSTP119, MSTP105,
+       MSTP104, MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+	/* MSTPCR0 */
+	[MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
+	[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
+	[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
+	[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
+	[MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+	[MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+	[MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
+	[MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
+	[MSTP001] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
+	[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
+
+	/* MSTPCR1 */
+	[MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
+	[MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
+	[MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
 };
 
 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 
 static struct clk_lookup lookups[] = {
 	/* main clocks */
-	CLKDEV_CON_ID("shyway_clk", &shx3_shyway_clk),
+	CLKDEV_CON_ID("extal", &extal_clk),
+	CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+	/* DIV4 clocks */
+	CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+	CLKDEV_CON_ID("shywaya_clk", &div4_clks[DIV4_SHA]),
+	CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
+	CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+	CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+	/* MSTP32 clocks */
+	{
+		/* SCIF3 */
+		.dev_id		= "sh-sci.3",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP027],
+	}, {
+		/* SCIF2 */
+		.dev_id		= "sh-sci.2",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP026],
+	}, {
+		/* SCIF1 */
+		.dev_id		= "sh-sci.1",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP025],
+	}, {
+		/* SCIF0 */
+		.dev_id		= "sh-sci.0",
+		.con_id		= "sci_fck",
+		.clk		= &mstp_clks[MSTP024],
+	},
+	CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]),
+	CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]),
+	CLKDEV_CON_ID("fe1_fck", &mstp_clks[MSTP001]),
+	CLKDEV_CON_ID("fe0_fck", &mstp_clks[MSTP000]),
+	{
+		/* TMU0 */
+		.dev_id		= "sh_tmu.0",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP008],
+	}, {
+		/* TMU1 */
+		.dev_id		= "sh_tmu.1",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP008],
+	}, {
+		/* TMU2 */
+		.dev_id		= "sh_tmu.2",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP008],
+	}, {
+		/* TMU3 */
+		.dev_id		= "sh_tmu.3",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP009],
+	}, {
+		/* TMU4 */
+		.dev_id		= "sh_tmu.4",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP009],
+	}, {
+		/* TMU5 */
+		.dev_id		= "sh_tmu.5",
+		.con_id		= "tmu_fck",
+		.clk		= &mstp_clks[MSTP009],
+	},
+	CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
+	CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
+	CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
 };
 
 int __init arch_clk_init(void)
 {
-	struct clk *clk;
 	int i, ret = 0;
 
-	cpg_clk_init();
+	for (i = 0; i < ARRAY_SIZE(clks); i++)
+		ret |= clk_register(clks[i]);
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
 
-	clk = clk_get(NULL, "master_clk");
-	for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
-		struct clk *clkp = shx3_onchip_clocks[i];
-
-		clkp->parent = clk;
-		ret |= clk_register(clkp);
-	}
-
-	clk_put(clk);
-
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+					   &div4_table);
+	if (!ret)
+		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/intc-shx3.c b/arch/sh/kernel/cpu/sh4a/intc-shx3.c
new file mode 100644
index 0000000..78c9714
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/intc-shx3.c
@@ -0,0 +1,34 @@
+/*
+ * Shared support for SH-X3 interrupt controllers.
+ *
+ *  Copyright (C) 2009 - 2010  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/irq.h>
+#include <linux/io.h>
+#include <linux/init.h>
+
+#define INTACK		0xfe4100b8
+#define INTACKCLR	0xfe4100bc
+#define INTC_USERIMASK	0xfe411000
+
+#ifdef CONFIG_INTC_BALANCING
+unsigned int irq_lookup(unsigned int irq)
+{
+	return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
+}
+
+void irq_finish(unsigned int irq)
+{
+	__raw_writel(irq2evt(irq), INTACKCLR);
+}
+#endif
+
+static int __init shx3_irq_setup(void)
+{
+	return register_intc_userimask(INTC_USERIMASK);
+}
+arch_initcall(shx3_irq_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/perf_event.c b/arch/sh/kernel/cpu/sh4a/perf_event.c
index eddc219..b8b873d 100644
--- a/arch/sh/kernel/cpu/sh4a/perf_event.c
+++ b/arch/sh/kernel/cpu/sh4a/perf_event.c
@@ -1,7 +1,7 @@
 /*
  * Performance events support for SH-4A performance counters
  *
- *  Copyright (C) 2009  Paul Mundt
+ *  Copyright (C) 2009, 2010  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
@@ -22,7 +22,25 @@
 #define CCBR_CMDS	(1 << 1)
 #define CCBR_PPCE	(1 << 0)
 
+#ifdef CONFIG_CPU_SHX3
+/*
+ * The PMCAT location for SH-X3 CPUs was quietly moved, while the CCBR
+ * and PMCTR locations remains tentatively constant. This change remains
+ * wholly undocumented, and was simply found through trial and error.
+ *
+ * Early cuts of SH-X3 still appear to use the SH-X/SH-X2 locations, and
+ * it's unclear when this ceased to be the case. For now we always use
+ * the new location (if future parts keep up with this trend then
+ * scanning for them at runtime also remains a viable option.)
+ *
+ * The gap in the register space also suggests that there are other
+ * undocumented counters, so this will need to be revisited at a later
+ * point in time.
+ */
+#define PPC_PMCAT	0xfc100240
+#else
 #define PPC_PMCAT	0xfc100080
+#endif
 
 #define PMCAT_OVF3	(1 << 27)
 #define PMCAT_CNN3	(1 << 26)
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
index ed23b15..4c74bd0 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
@@ -1,11 +1,11 @@
 /*
- * SH7757 (A0 step) Pinmux
+ * SH7757 (B0 step) Pinmux
  *
- *  Copyright (C) 2009  Renesas Solutions Corp.
+ *  Copyright (C) 2009-2010  Renesas Solutions Corp.
  *
  *  Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
  *
- * Based on SH7757 Pinmux
+ * Based on SH7723 Pinmux
  *  Copyright (C) 2008  Magnus Damm
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -40,27 +40,27 @@
 	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,
+		   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,
+		   PTL6_DATA, PTL5_DATA, PTL4_DATA,
 	PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
-	PTM6_DATA, PTM5_DATA, PTM4_DATA,
+	PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
 	PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
-	PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_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,
+	PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
 	PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
-	PTQ6_DATA, PTQ5_DATA, PTQ4_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,
+	PTT7_DATA, PTT6_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,
@@ -95,27 +95,27 @@
 	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,
+		 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,
+		 PTL6_IN, PTL5_IN, PTL4_IN,
 	PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
-	PTM6_IN, PTM5_IN, PTM4_IN,
+	PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
 	PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
-	PTN7_IN, PTN6_IN, PTN5_IN, PTN4_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,
+	PTP7_IN, PTP6_IN, PTP5_IN, PTP4_IN,
 	PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
-	PTQ6_IN, PTQ5_IN, PTQ4_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,
+	PTT7_IN, PTT6_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,
@@ -132,16 +132,43 @@
 	PINMUX_INPUT_END,
 
 	PINMUX_INPUT_PULLUP_BEGIN,
+	PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU,
+	PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+	PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+	PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU,
+	PTE7_IN_PU, PTE6_IN_PU, PTE5_IN_PU, PTE4_IN_PU,
+	PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU,
+	PTF7_IN_PU, PTF6_IN_PU, PTF5_IN_PU, PTF4_IN_PU,
+	PTF3_IN_PU, PTF2_IN_PU, PTF1_IN_PU, PTF0_IN_PU,
+	PTG7_IN_PU, PTG6_IN_PU,		    PTG4_IN_PU,
+	PTH7_IN_PU, PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU,
+	PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU,
+	PTI7_IN_PU, PTI6_IN_PU,		    PTI4_IN_PU,
+	PTI3_IN_PU, PTI2_IN_PU, PTI1_IN_PU, PTI0_IN_PU,
+		    PTJ6_IN_PU, PTJ5_IN_PU, PTJ4_IN_PU,
+	PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU,
+	PTK7_IN_PU, PTK6_IN_PU, PTK5_IN_PU, PTK4_IN_PU,
+	PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU,
+		    PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU,
+	PTL3_IN_PU, PTL2_IN_PU, PTL1_IN_PU, PTL0_IN_PU,
+	PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU,
+					    PTN4_IN_PU,
+	PTN3_IN_PU, PTN2_IN_PU, PTN1_IN_PU, PTN0_IN_PU,
+	PTO7_IN_PU, PTO6_IN_PU, PTO5_IN_PU, PTO4_IN_PU,
+	PTO3_IN_PU, PTO2_IN_PU, PTO1_IN_PU, PTO0_IN_PU,
+	PTT7_IN_PU, PTT6_IN_PU, PTT5_IN_PU, PTT4_IN_PU,
+	PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU,
 	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,
+	PTV3_IN_PU, PTV2_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,
+	PTZ7_IN_PU, PTZ6_IN_PU, PTZ5_IN_PU, PTZ4_IN_PU,
+	PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU, PTZ0_IN_PU,
 	PINMUX_INPUT_PULLUP_END,
 
 	PINMUX_OUTPUT_BEGIN,
@@ -163,27 +190,27 @@
 	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,
+		  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,
+		  PTL6_OUT, PTL5_OUT, PTL4_OUT,
 	PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
-	PTM6_OUT, PTM5_OUT, PTM4_OUT,
+	PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
 	PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
-	PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_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,
+	PTP7_OUT, PTP6_OUT, PTP5_OUT, PTP4_OUT,
 	PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
-	PTQ6_OUT, PTQ5_OUT, PTQ4_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,
+	PTT7_OUT, PTT6_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,
@@ -218,27 +245,27 @@
 	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,
+		 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,
+		 PTL6_FN, PTL5_FN, PTL4_FN,
 	PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
-	PTM6_FN, PTM5_FN, PTM4_FN,
+	PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
 	PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
-	PTN7_FN, PTN6_FN, PTN5_FN, PTN4_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,
+	PTP7_FN, PTP6_FN, PTP5_FN, PTP4_FN,
 	PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
-	PTQ6_FN, PTQ5_FN, PTQ4_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,
+	PTT7_FN, PTT6_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,
@@ -253,181 +280,248 @@
 	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_15_FN1, PS0_15_FN2,
+	PS0_14_FN1, PS0_14_FN2,
+	PS0_13_FN1, PS0_13_FN2,
+	PS0_12_FN1, PS0_12_FN2,
+	PS0_11_FN1, PS0_11_FN2,
+	PS0_10_FN1, PS0_10_FN2,
+	PS0_9_FN1, PS0_9_FN2,
+	PS0_8_FN1, PS0_8_FN2,
 	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,
+	PS1_10_FN1, PS1_10_FN2,
+	PS1_9_FN1, PS1_9_FN2,
+	PS1_8_FN1, PS1_8_FN2,
+	PS1_2_FN1, PS1_2_FN2,
 
-	PS2_13_FN1, PS2_13_FN3,
-	PS2_12_FN1, PS2_12_FN3,
-	PS2_1_FN1, PS2_1_FN2,
-	PS2_0_FN1, PS2_0_FN2,
+	PS2_13_FN1, PS2_13_FN2,
+	PS2_12_FN1, PS2_12_FN2,
+	PS2_7_FN1, PS2_7_FN2,
+	PS2_6_FN1, PS2_6_FN2,
+	PS2_5_FN1, PS2_5_FN2,
+	PS2_4_FN1, PS2_4_FN2,
+	PS2_2_FN1, PS2_2_FN2,
 
-	PS4_15_FN1, PS4_15_FN2,
+	PS3_15_FN1, PS3_15_FN2,
+	PS3_14_FN1, PS3_14_FN2,
+	PS3_13_FN1, PS3_13_FN2,
+	PS3_12_FN1, PS3_12_FN2,
+	PS3_11_FN1, PS3_11_FN2,
+	PS3_10_FN1, PS3_10_FN2,
+	PS3_9_FN1, PS3_9_FN2,
+	PS3_8_FN1, PS3_8_FN2,
+	PS3_7_FN1, PS3_7_FN2,
+	PS3_2_FN1, PS3_2_FN2,
+	PS3_1_FN1, PS3_1_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_8_FN1, PS4_8_FN2,
+	PS4_4_FN1, PS4_4_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_11_FN1, PS5_11_FN2,
+	PS5_10_FN1, PS5_10_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,
+	PS5_3_FN1, PS5_3_FN2,
+	PS5_2_FN1, PS5_2_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,
+	PS6_15_FN1, PS6_15_FN2,
+	PS6_14_FN1, PS6_14_FN2,
+	PS6_13_FN1, PS6_13_FN2,
+	PS6_12_FN1, PS6_12_FN2,
+	PS6_11_FN1, PS6_11_FN2,
+	PS6_10_FN1, PS6_10_FN2,
+	PS6_9_FN1, PS6_9_FN2,
+	PS6_8_FN1, PS6_8_FN2,
+	PS6_7_FN1, PS6_7_FN2,
+	PS6_6_FN1, PS6_6_FN2,
+	PS6_5_FN1, PS6_5_FN2,
+	PS6_4_FN1, PS6_4_FN2,
+	PS6_3_FN1, PS6_3_FN2,
+	PS6_2_FN1, PS6_2_FN2,
+	PS6_1_FN1, PS6_1_FN2,
+	PS6_0_FN1, PS6_0_FN2,
 
+	PS7_15_FN1, PS7_15_FN2,
+	PS7_14_FN1, PS7_14_FN2,
+	PS7_13_FN1, PS7_13_FN2,
+	PS7_12_FN1, PS7_12_FN2,
+	PS7_11_FN1, PS7_11_FN2,
+	PS7_10_FN1, PS7_10_FN2,
+	PS7_9_FN1, PS7_9_FN2,
+	PS7_8_FN1, PS7_8_FN2,
+	PS7_7_FN1, PS7_7_FN2,
+	PS7_6_FN1, PS7_6_FN2,
+	PS7_5_FN1, PS7_5_FN2,
+	PS7_4_FN1, PS7_4_FN2,
+
+	PS8_15_FN1, PS8_15_FN2,
+	PS8_14_FN1, PS8_14_FN2,
+	PS8_13_FN1, PS8_13_FN2,
+	PS8_12_FN1, PS8_12_FN2,
+	PS8_11_FN1, PS8_11_FN2,
+	PS8_10_FN1, PS8_10_FN2,
+	PS8_9_FN1, PS8_9_FN2,
+	PS8_8_FN1, PS8_8_FN2,
 	PINMUX_FUNCTION_END,
 
 	PINMUX_MARK_BEGIN,
-	/* PTA (mobule: LBSC, CPG, LPC) */
+	/* PTA (mobule: LBSC, RGMII) */
 	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,
+	ET0_MDC_MARK,	ET0_MDIO_MARK,	ET1_MDC_MARK,	ET1_MDIO_MARK,
 
-	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	/* PTB (mobule: INTC, ONFI, TMU) */
+	IRQ15_MARK,	IRQ14_MARK,	IRQ13_MARK,	IRQ12_MARK,
+	IRQ11_MARK,	IRQ10_MARK,	IRQ9_MARK,	IRQ8_MARK,
+	ON_NRE_MARK,	ON_NWE_MARK,	ON_NWP_MARK,	ON_NCE0_MARK,
+	ON_R_B0_MARK,	ON_ALE_MARK,	ON_CLE_MARK,	TCLK_MARK,
+
+	/* PTC (mobule: IRQ, PWMU) */
+	IRQ7_MARK,	IRQ6_MARK,	IRQ5_MARK,	IRQ4_MARK,
+	IRQ3_MARK,	IRQ2_MARK,	IRQ1_MARK,	IRQ0_MARK,
+	PWMU0_MARK,	PWMU1_MARK,	PWMU2_MARK,	PWMU3_MARK,
+	PWMU4_MARK,	PWMU5_MARK,
+
+	/* PTD (mobule: SPI0, DMAC) */
+	SP0_MOSI_MARK,	SP0_MISO_MARK,	SP0_SCK_MARK,	SP0_SCK_FB_MARK,
+	SP0_SS0_MARK,	SP0_SS1_MARK,	SP0_SS2_MARK,	SP0_SS3_MARK,
+	DREQ0_MARK,	DACK0_MARK,	TEND0_MARK,
+
+	/* PTE (mobule: RMII) */
+	RMII0_CRS_DV_MARK,	RMII0_TXD1_MARK,
+	RMII0_TXD0_MARK,	RMII0_TXEN_MARK,
+	RMII0_REFCLK_MARK,	RMII0_RXD1_MARK,
+	RMII0_RXD0_MARK,	RMII0_RX_ER_MARK,
+
+	/* PTF (mobule: RMII, SerMux) */
+	RMII1_CRS_DV_MARK,	RMII1_TXD1_MARK,
+	RMII1_TXD0_MARK,	RMII1_TXEN_MARK,
+	RMII1_REFCLK_MARK,	RMII1_RXD1_MARK,
+	RMII1_RXD0_MARK,	RMII1_RX_ER_MARK,
+	RAC_RI_MARK,
+
+	/* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+	BOOTFMS_MARK,	BOOTWP_MARK,	A25_MARK,	A24_MARK,
+	SERIRQ_MARK,	WDTOVF_MARK,	LPCPD_MARK,	LDRQ_MARK,
+	MMCCLK_MARK,	MMCCMD_MARK,
+
+	/* PTH (mobule: SPI1, LPC, DMAC, ADC) */
+	SP1_MOSI_MARK,	SP1_MISO_MARK,	SP1_SCK_MARK,	SP1_SCK_FB_MARK,
+	SP1_SS0_MARK,	SP1_SS1_MARK,	WP_MARK,	FMS0_MARK,
+	TEND1_MARK,	DREQ1_MARK,	DACK1_MARK,	ADTRG1_MARK,
+	ADTRG0_MARK,
+
+	/* PTI (mobule: LBSC, SDHI) */
 	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,
+	/* PTJ (mobule: SCIF234) */
+	RTS3_MARK,	CTS3_MARK,	TXD3_MARK,	RXD3_MARK,
+	RTS4_MARK,	RXD4_MARK,	TXD4_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) */
+	/* PTK (mobule: SERMUX, LBSC, SCIF) */
 	COM2_TXD_MARK,	COM2_RXD_MARK,	COM2_RTS_MARK,	COM2_CTS_MARK,
-	COM2_DTR_MARK,	COM2_DSR_MARK,	COM2_DCD_MARK,	COM2_RI_MARK,
+	COM2_DTR_MARK,	COM2_DSR_MARK,	COM2_DCD_MARK,	CLKOUT_MARK,
+	SCK2_MARK,	SCK4_MARK,	SCK3_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,
+	/* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+	RAC_RXD_MARK,	RAC_RTS_MARK,	RAC_CTS_MARK,	RAC_DTR_MARK,
+	RAC_DSR_MARK,	RAC_DCD_MARK,	RAC_TXD_MARK,	RXD2_MARK,
+	CS5_MARK,	CS6_MARK,	AUDSYNC_MARK,	AUDCK_MARK,
+	TXD2_MARK,
 
-	/* PTM (mobule: IIC, LPC) */
+	/* PTM (mobule: LBSC, IIC) */
+	CS4_MARK,	RD_MARK,	WE0_MARK,	CS0_MARK,
 	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,
+	/* PTN (mobule: USB, JMC, SGPIO, WDT) */
+	VBUS_EN_MARK,	VBUS_OC_MARK,	JMCTCK_MARK,	JMCTMS_MARK,
+	JMCTDO_MARK,	JMCTDI_MARK,	JMCTRST_MARK,
+	SGPIO1_CLK_MARK,	SGPIO1_LOAD_MARK,	SGPIO1_DI_MARK,
+	SGPIO1_DO_MARK,		SUB_CLKIN_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,
+	/* PTO (mobule: SGPIO, SerMux) */
+	SGPIO0_CLK_MARK,	SGPIO0_LOAD_MARK,	SGPIO0_DI_MARK,
+	SGPIO0_DO_MARK,		SGPIO2_CLK_MARK,	SGPIO2_LOAD_MARK,
+	SGPIO2_DI_MARK,		SGPIO2_DO_MARK,
+	COM1_TXD_MARK,	COM1_RXD_MARK,	COM1_RTS_MARK,	COM1_CTS_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,
+	DDC3_MARK,	DDC2_MARK,	SDA2_MARK,	SCL2_MARK,
 	SDA1_MARK,	SCL1_MARK,	SDA0_MARK,	SCL0_MARK,
+	SDA8_MARK,	SCL8_MARK,
 
 	/* PTS (mobule: GRA, IIC) */
-	DDC1_MARK,	DDC0_MARK,
-	SDA9_MARK,	SCL9_MARK,	SDA5_MARK,	SCL5_MARK,
+	DDC1_MARK,	DDC0_MARK,	SDA5_MARK,	SCL5_MARK,
 	SDA4_MARK,	SCL4_MARK,	SDA3_MARK,	SCL3_MARK,
+	SDA9_MARK,	SCL9_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,
+	/* PTT (mobule: PWMX, AUD) */
+	PWMX7_MARK,	PWMX6_MARK,	PWMX5_MARK,	PWMX4_MARK,
+	PWMX3_MARK,	PWMX2_MARK,	PWMX1_MARK,	PWMX0_MARK,
+	AUDATA3_MARK,	AUDATA2_MARK,	AUDATA1_MARK,	AUDATA0_MARK,
+	STATUS1_MARK,	STATUS0_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,
+	/* PTU (mobule: LPC, APM) */
+	LGPIO7_MARK,	LGPIO6_MARK,	LGPIO5_MARK,	LGPIO4_MARK,
+	LGPIO3_MARK,	LGPIO2_MARK,	LGPIO1_MARK,	LGPIO0_MARK,
+	APMONCTL_O_MARK,	APMPWBTOUT_O_MARK,	APMSCI_O_MARK,
+	APMVDDON_MARK,	APMSLPBTN_MARK,	APMPWRBTN_MARK,	APMS5N_MARK,
+	APMS3N_MARK,
 
-	/* PTV (mobule: LBSC, DMAC) */
+	/* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
 	A23_MARK,	A22_MARK,	A21_MARK,	A20_MARK,
 	A19_MARK,	A18_MARK,	A17_MARK,	A16_MARK,
-	TEND0_MARK,	DREQ1_MARK,	DACK1_MARK,	TEND1_MARK,
+	COM2_RI_MARK,		R_SPI_MOSI_MARK,	R_SPI_MISO_MARK,
+	R_SPI_RSPCK_MARK,	R_SPI_SSL0_MARK,	R_SPI_SSL1_MARK,
+	EVENT7_MARK,	EVENT6_MARK,	VBIOS_DI_MARK,	VBIOS_DO_MARK,
+	VBIOS_CLK_MARK,	VBIOS_CS_MARK,
 
-	/* PTW (mobule: LBSC) */
+	/* PTW (mobule: LBSC, EVC, SCIF) */
 	A15_MARK,	A14_MARK,	A13_MARK,	A12_MARK,
 	A11_MARK,	A10_MARK,	A9_MARK,	A8_MARK,
+	EVENT5_MARK,	EVENT4_MARK,	EVENT3_MARK,	EVENT2_MARK,
+	EVENT1_MARK,	EVENT0_MARK,	CTS4_MARK,	CTS2_MARK,
 
-	/* PTX (mobule: LBSC) */
+	/* PTX (mobule: LBSC, SCIF, SIM) */
 	A7_MARK,	A6_MARK,	A5_MARK,	A4_MARK,
 	A3_MARK,	A2_MARK,	A1_MARK,	A0_MARK,
+	RTS2_MARK,	SIM_D_MARK,	SIM_CLK_MARK,	SIM_RST_MARK,
 
 	/* PTY (mobule: LBSC) */
 	D7_MARK,	D6_MARK,	D5_MARK,	D4_MARK,
 	D3_MARK,	D2_MARK,	D1_MARK,	D0_MARK,
+
+	/* PTZ (mobule: eMMC, ONFI) */
+	MMCDAT7_MARK,	MMCDAT6_MARK,	MMCDAT5_MARK,	MMCDAT4_MARK,
+	MMCDAT3_MARK,	MMCDAT2_MARK,	MMCDAT1_MARK,	MMCDAT0_MARK,
+	ON_DQ7_MARK,	ON_DQ6_MARK,	ON_DQ5_MARK,	ON_DQ4_MARK,
+	ON_DQ3_MARK,	ON_DQ2_MARK,	ON_DQ1_MARK,	ON_DQ0_MARK,
+
 	PINMUX_MARK_END,
 };
 
@@ -473,6 +567,8 @@
 	PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
 
 	/* PTE GPIO */
+	PINMUX_DATA(PTE7_DATA, PTE7_IN, PTE7_OUT),
+	PINMUX_DATA(PTE6_DATA, PTE6_IN, PTE6_OUT),
 	PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
 	PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
 	PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
@@ -521,7 +617,6 @@
 	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),
@@ -541,7 +636,6 @@
 	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),
@@ -560,7 +654,6 @@
 	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),
@@ -609,6 +702,8 @@
 	PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
 
 	/* PTT GPIO */
+	PINMUX_DATA(PTT7_DATA, PTT7_IN, PTT7_OUT),
+	PINMUX_DATA(PTT6_DATA, PTT6_IN, PTT6_OUT),
 	PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
 	PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
 	PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
@@ -677,186 +772,204 @@
 	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),
+	PINMUX_DATA(BS_MARK, PTA7_FN),
+	PINMUX_DATA(RDWR_MARK, PTA6_FN),
+	PINMUX_DATA(WE1_MARK, PTA5_FN),
+	PINMUX_DATA(RDY_MARK, PTA4_FN),
+	PINMUX_DATA(ET0_MDC_MARK, PTA3_FN),
+	PINMUX_DATA(ET0_MDIO_MARK, PTA2_FN),
+	PINMUX_DATA(ET1_MDC_MARK, PTA1_FN),
+	PINMUX_DATA(ET1_MDIO_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),
+	PINMUX_DATA(IRQ15_MARK, PS0_15_FN1, PTB7_FN),
+	PINMUX_DATA(ON_NRE_MARK, PS0_15_FN2, PTB7_FN),
+	PINMUX_DATA(IRQ14_MARK, PS0_14_FN1, PTB6_FN),
+	PINMUX_DATA(ON_NWE_MARK, PS0_14_FN2, PTB6_FN),
+	PINMUX_DATA(IRQ13_MARK, PS0_13_FN1, PTB5_FN),
+	PINMUX_DATA(ON_NWP_MARK, PS0_13_FN2, PTB5_FN),
+	PINMUX_DATA(IRQ12_MARK, PS0_12_FN1, PTB4_FN),
+	PINMUX_DATA(ON_NCE0_MARK, PS0_12_FN2, PTB4_FN),
+	PINMUX_DATA(IRQ11_MARK, PS0_11_FN1, PTB3_FN),
+	PINMUX_DATA(ON_R_B0_MARK, PS0_11_FN2, PTB3_FN),
+	PINMUX_DATA(IRQ10_MARK, PS0_10_FN1, PTB2_FN),
+	PINMUX_DATA(ON_ALE_MARK, PS0_10_FN2, PTB2_FN),
+	PINMUX_DATA(IRQ9_MARK, PS0_9_FN1, PTB1_FN),
+	PINMUX_DATA(ON_CLE_MARK, PS0_9_FN2, PTB1_FN),
+	PINMUX_DATA(IRQ8_MARK, PS0_8_FN1, PTB0_FN),
+	PINMUX_DATA(TCLK_MARK, PS0_8_FN2, 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),
+	PINMUX_DATA(IRQ7_MARK, PS0_7_FN1, PTC7_FN),
+	PINMUX_DATA(PWMU0_MARK, PS0_7_FN2, PTC7_FN),
+	PINMUX_DATA(IRQ6_MARK, PS0_6_FN1, PTC6_FN),
+	PINMUX_DATA(PWMU1_MARK, PS0_6_FN2, PTC6_FN),
+	PINMUX_DATA(IRQ5_MARK, PS0_5_FN1, PTC5_FN),
+	PINMUX_DATA(PWMU2_MARK, PS0_5_FN2, PTC5_FN),
+	PINMUX_DATA(IRQ4_MARK, PS0_4_FN1, PTC5_FN),
+	PINMUX_DATA(PWMU3_MARK, PS0_4_FN2, PTC4_FN),
+	PINMUX_DATA(IRQ3_MARK, PS0_3_FN1, PTC3_FN),
+	PINMUX_DATA(PWMU4_MARK, PS0_3_FN2, PTC3_FN),
+	PINMUX_DATA(IRQ2_MARK, PS0_2_FN1, PTC2_FN),
+	PINMUX_DATA(PWMU5_MARK, PS0_2_FN2, PTC2_FN),
+	PINMUX_DATA(IRQ1_MARK, PTC1_FN),
+	PINMUX_DATA(IRQ0_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),
+	PINMUX_DATA(SP0_MOSI_MARK, PTD7_FN),
+	PINMUX_DATA(SP0_MISO_MARK, PTD6_FN),
+	PINMUX_DATA(SP0_SCK_MARK, PTD5_FN),
+	PINMUX_DATA(SP0_SCK_FB_MARK, PTD4_FN),
+	PINMUX_DATA(SP0_SS0_MARK, PTD3_FN),
+	PINMUX_DATA(SP0_SS1_MARK, PS1_10_FN1, PTD2_FN),
+	PINMUX_DATA(DREQ0_MARK, PS1_10_FN2, PTD2_FN),
+	PINMUX_DATA(SP0_SS2_MARK, PS1_9_FN1, PTD1_FN),
+	PINMUX_DATA(DACK0_MARK, PS1_9_FN2, PTD1_FN),
+	PINMUX_DATA(SP0_SS3_MARK, PS1_8_FN1, PTD0_FN),
+	PINMUX_DATA(TEND0_MARK, PS1_8_FN2, 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),
+	PINMUX_DATA(RMII0_CRS_DV_MARK, PTE7_FN),
+	PINMUX_DATA(RMII0_TXD1_MARK, PTE6_FN),
+	PINMUX_DATA(RMII0_TXD0_MARK, PTE5_FN),
+	PINMUX_DATA(RMII0_TXEN_MARK, PTE4_FN),
+	PINMUX_DATA(RMII0_REFCLK_MARK, PTE3_FN),
+	PINMUX_DATA(RMII0_RXD1_MARK, PTE2_FN),
+	PINMUX_DATA(RMII0_RXD0_MARK, PTE1_FN),
+	PINMUX_DATA(RMII0_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),
+	PINMUX_DATA(RMII1_CRS_DV_MARK, PTF7_FN),
+	PINMUX_DATA(RMII1_TXD1_MARK, PTF6_FN),
+	PINMUX_DATA(RMII1_TXD0_MARK, PTF5_FN),
+	PINMUX_DATA(RMII1_TXEN_MARK, PTF4_FN),
+	PINMUX_DATA(RMII1_REFCLK_MARK, PTF3_FN),
+	PINMUX_DATA(RMII1_RXD1_MARK, PS1_2_FN1, PTF2_FN),
+	PINMUX_DATA(RAC_RI_MARK, PS1_2_FN2, PTF2_FN),
+	PINMUX_DATA(RMII1_RXD0_MARK, PTF1_FN),
+	PINMUX_DATA(RMII1_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(BOOTFMS_MARK, PTG7_FN),
+	PINMUX_DATA(BOOTWP_MARK, PTG6_FN),
+	PINMUX_DATA(A25_MARK, PS2_13_FN1, PTG5_FN),
+	PINMUX_DATA(MMCCLK_MARK, PS2_13_FN2, PTG5_FN),
+	PINMUX_DATA(A24_MARK, PS2_12_FN1, PTG4_FN),
+	PINMUX_DATA(MMCCMD_MARK, PS2_12_FN2, PTG4_FN),
 	PINMUX_DATA(SERIRQ_MARK, PTG3_FN),
-	PINMUX_DATA(CLKRUN_MARK, PTG2_FN),
+	PINMUX_DATA(WDTOVF_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_MOSI_MARK, PS2_7_FN1, PTH7_FN),
+	PINMUX_DATA(TEND1_MARK, PS2_7_FN2, PTH7_FN),
+	PINMUX_DATA(SP1_MISO_MARK, PS2_6_FN1, PTH6_FN),
+	PINMUX_DATA(DREQ1_MARK, PS2_6_FN2, PTH6_FN),
+	PINMUX_DATA(SP1_SCK_MARK, PS2_5_FN1, PTH5_FN),
+	PINMUX_DATA(DACK1_MARK, PS2_5_FN2, PTH5_FN),
+	PINMUX_DATA(SP1_SCK_FB_MARK, PS2_4_FN1, PTH4_FN),
+	PINMUX_DATA(ADTRG1_MARK, PS2_4_FN2, 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),
+	PINMUX_DATA(SP1_SS1_MARK, PS2_2_FN1, PTH2_FN),
+	PINMUX_DATA(ADTRG0_MARK, PS2_2_FN2, PTH2_FN),
+	PINMUX_DATA(WP_MARK, PTH1_FN),
+	PINMUX_DATA(FMS0_MARK, 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),
+	PINMUX_DATA(D15_MARK, PS3_15_FN1, PTI7_FN),
+	PINMUX_DATA(SD_WP_MARK, PS3_15_FN2, PTI7_FN),
+	PINMUX_DATA(D14_MARK, PS3_14_FN1, PTI6_FN),
+	PINMUX_DATA(SD_CD_MARK, PS3_14_FN2, PTI6_FN),
+	PINMUX_DATA(D13_MARK, PS3_13_FN1, PTI5_FN),
+	PINMUX_DATA(SD_CLK_MARK, PS3_13_FN2, PTI5_FN),
+	PINMUX_DATA(D12_MARK, PS3_12_FN1, PTI4_FN),
+	PINMUX_DATA(SD_CMD_MARK, PS3_12_FN2, PTI4_FN),
+	PINMUX_DATA(D11_MARK, PS3_11_FN1, PTI3_FN),
+	PINMUX_DATA(SD_D3_MARK, PS3_11_FN2, PTI3_FN),
+	PINMUX_DATA(D10_MARK, PS3_10_FN1, PTI2_FN),
+	PINMUX_DATA(SD_D2_MARK, PS3_10_FN2, PTI2_FN),
+	PINMUX_DATA(D9_MARK, PS3_9_FN1, PTI1_FN),
+	PINMUX_DATA(SD_D1_MARK, PS3_9_FN2, PTI1_FN),
+	PINMUX_DATA(D8_MARK, PS3_8_FN1, PTI0_FN),
+	PINMUX_DATA(SD_D0_MARK, PS3_8_FN2, 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),
+	PINMUX_DATA(RTS3_MARK, PTJ6_FN),
+	PINMUX_DATA(CTS3_MARK, PTJ5_FN),
+	PINMUX_DATA(TXD3_MARK, PTJ4_FN),
+	PINMUX_DATA(RXD3_MARK, PTJ3_FN),
+	PINMUX_DATA(RTS4_MARK, PTJ2_FN),
+	PINMUX_DATA(RXD4_MARK, PTJ1_FN),
+	PINMUX_DATA(TXD4_MARK, PTJ0_FN),
 
 	/* PTK FN */
-	PINMUX_DATA(COM2_TXD_MARK, PTK7_FN),
+	PINMUX_DATA(COM2_TXD_MARK, PS3_7_FN1, PTK7_FN),
+	PINMUX_DATA(SCK2_MARK, PS3_7_FN2, 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),
+	PINMUX_DATA(COM2_DSR_MARK, PS3_2_FN1, PTK2_FN),
+	PINMUX_DATA(SCK4_MARK, PS3_2_FN2, PTK2_FN),
+	PINMUX_DATA(COM2_DCD_MARK, PS3_1_FN1, PTK1_FN),
+	PINMUX_DATA(SCK3_MARK, PS3_1_FN2, PTK1_FN),
+	PINMUX_DATA(CLKOUT_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_RXD_MARK, PS4_14_FN1, PTL6_FN),
+	PINMUX_DATA(RXD2_MARK, PS4_14_FN2, PTL6_FN),
+	PINMUX_DATA(RAC_RTS_MARK, PS4_13_FN1, PTL5_FN),
+	PINMUX_DATA(CS5_MARK, PS4_13_FN2, PTL5_FN),
+	PINMUX_DATA(RAC_CTS_MARK, PS4_12_FN1, PTL4_FN),
+	PINMUX_DATA(CS6_MARK, PS4_12_FN2, 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),
+	PINMUX_DATA(RAC_DSR_MARK, PS4_10_FN1, PTL2_FN),
+	PINMUX_DATA(AUDSYNC_MARK, PS4_10_FN2, PTL2_FN),
+	PINMUX_DATA(RAC_DCD_MARK, PS4_9_FN1, PTL1_FN),
+	PINMUX_DATA(AUDCK_MARK, PS4_9_FN2, PTL1_FN),
+	PINMUX_DATA(RAC_TXD_MARK, PS4_8_FN1, PTL0_FN),
+	PINMUX_DATA(TXD2_MARK, PS4_8_FN1, PTL0_FN),
 
 	/* PTM FN */
-	PINMUX_DATA(WP_MARK, PTM6_FN),
-	PINMUX_DATA(FMS0_MARK, PTM5_FN),
-	PINMUX_DATA(FMS1_MARK, PTM4_FN),
+	PINMUX_DATA(CS4_MARK, PTM7_FN),
+	PINMUX_DATA(RD_MARK, PTM6_FN),
+	PINMUX_DATA(WE0_MARK, PTM7_FN),
+	PINMUX_DATA(CS0_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),
+	PINMUX_DATA(VBUS_EN_MARK, PTN6_FN),
+	PINMUX_DATA(VBUS_OC_MARK, PTN5_FN),
+	PINMUX_DATA(JMCTCK_MARK, PS4_4_FN1, PTN4_FN),
+	PINMUX_DATA(SGPIO1_CLK_MARK, PS4_4_FN2, PTN4_FN),
+	PINMUX_DATA(JMCTMS_MARK, PS4_3_FN1, PTN5_FN),
+	PINMUX_DATA(SGPIO1_LOAD_MARK, PS4_3_FN2, PTN5_FN),
+	PINMUX_DATA(JMCTDO_MARK, PS4_2_FN1, PTN2_FN),
+	PINMUX_DATA(SGPIO1_DO_MARK, PS4_2_FN2, PTN2_FN),
+	PINMUX_DATA(JMCTDI_MARK, PS4_1_FN1, PTN1_FN),
+	PINMUX_DATA(SGPIO1_DI_MARK, PS4_1_FN2, PTN1_FN),
+	PINMUX_DATA(JMCTRST_MARK, PS4_0_FN1, PTN0_FN),
+	PINMUX_DATA(SUB_CLKIN_MARK, PS4_0_FN2, 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),
+	PINMUX_DATA(SGPIO2_CLK_MARK, PS5_11_FN1, PTO3_FN),
+	PINMUX_DATA(COM1_TXD_MARK, PS5_11_FN2, PTO3_FN),
+	PINMUX_DATA(SGPIO2_LOAD_MARK, PS5_10_FN1, PTO2_FN),
+	PINMUX_DATA(COM1_RXD_MARK, PS5_10_FN2, PTO2_FN),
+	PINMUX_DATA(SGPIO2_DI_MARK, PS5_9_FN1, PTO1_FN),
+	PINMUX_DATA(COM1_RTS_MARK, PS5_9_FN2, PTO1_FN),
+	PINMUX_DATA(SGPIO2_DO_MARK, PS5_8_FN1, PTO0_FN),
+	PINMUX_DATA(COM1_CTS_MARK, PS5_8_FN2, 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),
@@ -864,8 +977,8 @@
 	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),
+	PINMUX_DATA(LRESET_MARK, PTQ1_FN),
+	PINMUX_DATA(LCLK_MARK, PTQ0_FN),
 
 	/* PTR FN */
 	PINMUX_DATA(SDA8_MARK, PTR7_FN),	/* DDC3? */
@@ -888,58 +1001,84 @@
 	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),
+	PINMUX_DATA(PWMX7_MARK, PS5_7_FN1, PTT7_FN),
+	PINMUX_DATA(AUDATA3_MARK, PS5_7_FN2, PTT7_FN),
+	PINMUX_DATA(PWMX6_MARK, PS5_6_FN1, PTT6_FN),
+	PINMUX_DATA(AUDATA2_MARK, PS5_6_FN2, PTT6_FN),
+	PINMUX_DATA(PWMX5_MARK, PS5_5_FN1, PTT5_FN),
+	PINMUX_DATA(AUDATA1_MARK, PS5_5_FN2, PTT5_FN),
+	PINMUX_DATA(PWMX4_MARK, PS5_4_FN1, PTT4_FN),
+	PINMUX_DATA(AUDATA0_MARK, PS5_4_FN2, PTT4_FN),
+	PINMUX_DATA(PWMX3_MARK, PS5_3_FN1, PTT3_FN),
+	PINMUX_DATA(STATUS1_MARK, PS5_3_FN2, PTT3_FN),
+	PINMUX_DATA(PWMX2_MARK, PS5_2_FN1, PTT2_FN),
+	PINMUX_DATA(STATUS0_MARK, PS5_2_FN2, PTT2_FN),
+	PINMUX_DATA(PWMX1_MARK, PTT1_FN),
+	PINMUX_DATA(PWMX0_MARK, PTT0_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),
+	PINMUX_DATA(LGPIO7_MARK, PS6_15_FN1, PTU7_FN),
+	PINMUX_DATA(APMONCTL_O_MARK, PS6_15_FN2, PTU7_FN),
+	PINMUX_DATA(LGPIO6_MARK, PS6_14_FN1, PTU6_FN),
+	PINMUX_DATA(APMPWBTOUT_O_MARK, PS6_14_FN2, PTU6_FN),
+	PINMUX_DATA(LGPIO5_MARK, PS6_13_FN1, PTU5_FN),
+	PINMUX_DATA(APMSCI_O_MARK, PS6_13_FN2, PTU5_FN),
+	PINMUX_DATA(LGPIO4_MARK, PS6_12_FN1, PTU4_FN),
+	PINMUX_DATA(APMVDDON_MARK, PS6_12_FN2, PTU4_FN),
+	PINMUX_DATA(LGPIO3_MARK, PS6_11_FN1, PTU3_FN),
+	PINMUX_DATA(APMSLPBTN_MARK, PS6_11_FN2, PTU3_FN),
+	PINMUX_DATA(LGPIO2_MARK, PS6_10_FN1, PTU2_FN),
+	PINMUX_DATA(APMPWRBTN_MARK, PS6_10_FN2, PTU2_FN),
+	PINMUX_DATA(LGPIO1_MARK, PS6_9_FN1, PTU1_FN),
+	PINMUX_DATA(APMS5N_MARK, PS6_9_FN2, PTU1_FN),
+	PINMUX_DATA(LGPIO0_MARK, PS6_8_FN1, PTU0_FN),
+	PINMUX_DATA(APMS3N_MARK, PS6_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),
+	PINMUX_DATA(A23_MARK, PS6_7_FN1, PTV7_FN),
+	PINMUX_DATA(COM2_RI_MARK, PS6_7_FN2, PTV7_FN),
+	PINMUX_DATA(A22_MARK, PS6_6_FN1, PTV6_FN),
+	PINMUX_DATA(R_SPI_MOSI_MARK, PS6_6_FN2, PTV6_FN),
+	PINMUX_DATA(A21_MARK, PS6_5_FN1, PTV5_FN),
+	PINMUX_DATA(R_SPI_MISO_MARK, PS6_5_FN2, PTV5_FN),
+	PINMUX_DATA(A20_MARK, PS6_4_FN1, PTV4_FN),
+	PINMUX_DATA(R_SPI_RSPCK_MARK, PS6_4_FN2, PTV4_FN),
+	PINMUX_DATA(A19_MARK, PS6_3_FN1, PTV3_FN),
+	PINMUX_DATA(R_SPI_SSL0_MARK, PS6_3_FN2, PTV3_FN),
+	PINMUX_DATA(A18_MARK, PS6_2_FN1, PTV2_FN),
+	PINMUX_DATA(R_SPI_SSL1_MARK, PS6_2_FN2, PTV2_FN),
+	PINMUX_DATA(A17_MARK, PS6_1_FN1, PTV1_FN),
+	PINMUX_DATA(EVENT7_MARK, PS6_1_FN2, PTV1_FN),
+	PINMUX_DATA(A16_MARK, PS6_0_FN1, PTV0_FN),
+	PINMUX_DATA(EVENT6_MARK, PS6_0_FN1, 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),
+	PINMUX_DATA(A15_MARK, PS7_15_FN1, PTW7_FN),
+	PINMUX_DATA(EVENT5_MARK, PS7_15_FN2, PTW7_FN),
+	PINMUX_DATA(A14_MARK, PS7_14_FN1, PTW6_FN),
+	PINMUX_DATA(EVENT4_MARK, PS7_14_FN2, PTW6_FN),
+	PINMUX_DATA(A13_MARK, PS7_13_FN1, PTW5_FN),
+	PINMUX_DATA(EVENT3_MARK, PS7_13_FN2, PTW5_FN),
+	PINMUX_DATA(A12_MARK, PS7_12_FN1, PTW4_FN),
+	PINMUX_DATA(EVENT2_MARK, PS7_12_FN2, PTW4_FN),
+	PINMUX_DATA(A11_MARK, PS7_11_FN1, PTW3_FN),
+	PINMUX_DATA(EVENT1_MARK, PS7_11_FN2, PTW3_FN),
+	PINMUX_DATA(A10_MARK, PS7_10_FN1, PTW2_FN),
+	PINMUX_DATA(EVENT0_MARK, PS7_10_FN2, PTW2_FN),
+	PINMUX_DATA(A9_MARK, PS7_9_FN1, PTW1_FN),
+	PINMUX_DATA(CTS4_MARK, PS7_9_FN2, PTW1_FN),
+	PINMUX_DATA(A8_MARK, PS7_8_FN1, PTW0_FN),
+	PINMUX_DATA(CTS2_MARK, PS7_8_FN2, 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(A7_MARK, PS7_7_FN1, PTX7_FN),
+	PINMUX_DATA(RTS2_MARK, PS7_7_FN2, PTX7_FN),
+	PINMUX_DATA(A6_MARK, PS7_6_FN1, PTX6_FN),
+	PINMUX_DATA(SIM_D_MARK, PS7_6_FN2, PTX6_FN),
+	PINMUX_DATA(A5_MARK, PS7_5_FN1, PTX5_FN),
+	PINMUX_DATA(SIM_CLK_MARK, PS7_5_FN2, PTX5_FN),
+	PINMUX_DATA(A4_MARK, PS7_4_FN1, PTX4_FN),
+	PINMUX_DATA(SIM_RST_MARK, PS7_4_FN2, PTX4_FN),
 	PINMUX_DATA(A3_MARK, PTX3_FN),
 	PINMUX_DATA(A2_MARK, PTX2_FN),
 	PINMUX_DATA(A1_MARK, PTX1_FN),
@@ -954,6 +1093,24 @@
 	PINMUX_DATA(D2_MARK, PTY2_FN),
 	PINMUX_DATA(D1_MARK, PTY1_FN),
 	PINMUX_DATA(D0_MARK, PTY0_FN),
+
+	/* PTZ FN */
+	PINMUX_DATA(MMCDAT7_MARK, PS8_15_FN1, PTZ7_FN),
+	PINMUX_DATA(ON_DQ7_MARK, PS8_15_FN2, PTZ7_FN),
+	PINMUX_DATA(MMCDAT6_MARK, PS8_14_FN1, PTZ6_FN),
+	PINMUX_DATA(ON_DQ6_MARK, PS8_14_FN2, PTZ6_FN),
+	PINMUX_DATA(MMCDAT5_MARK, PS8_13_FN1, PTZ5_FN),
+	PINMUX_DATA(ON_DQ5_MARK, PS8_13_FN2, PTZ5_FN),
+	PINMUX_DATA(MMCDAT4_MARK, PS8_12_FN1, PTZ4_FN),
+	PINMUX_DATA(ON_DQ4_MARK, PS8_12_FN2, PTZ4_FN),
+	PINMUX_DATA(MMCDAT3_MARK, PS8_11_FN1, PTZ3_FN),
+	PINMUX_DATA(ON_DQ3_MARK, PS8_11_FN2, PTZ3_FN),
+	PINMUX_DATA(MMCDAT2_MARK, PS8_10_FN1, PTZ2_FN),
+	PINMUX_DATA(ON_DQ2_MARK, PS8_10_FN2, PTZ2_FN),
+	PINMUX_DATA(MMCDAT1_MARK, PS8_9_FN1, PTZ1_FN),
+	PINMUX_DATA(ON_DQ1_MARK, PS8_9_FN2, PTZ1_FN),
+	PINMUX_DATA(MMCDAT0_MARK, PS8_8_FN1, PTZ0_FN),
+	PINMUX_DATA(ON_DQ0_MARK, PS8_8_FN2, PTZ0_FN),
 };
 
 static struct pinmux_gpio pinmux_gpios[] = {
@@ -1048,7 +1205,6 @@
 	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),
@@ -1068,7 +1224,6 @@
 	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),
@@ -1078,6 +1233,7 @@
 	PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
 
 	/* PTM */
+	PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
 	PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
 	PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
 	PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
@@ -1087,7 +1243,6 @@
 	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),
@@ -1107,6 +1262,7 @@
 	PINMUX_GPIO(GPIO_PTO0, PTO0_DATA),
 
 	/* PTP */
+	PINMUX_GPIO(GPIO_PTP7, PTP7_DATA),
 	PINMUX_GPIO(GPIO_PTP6, PTP6_DATA),
 	PINMUX_GPIO(GPIO_PTP5, PTP5_DATA),
 	PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
@@ -1145,6 +1301,8 @@
 	PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
 
 	/* PTT */
+	PINMUX_GPIO(GPIO_PTT7, PTT7_DATA),
+	PINMUX_GPIO(GPIO_PTT6, PTT6_DATA),
 	PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
 	PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
 	PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
@@ -1212,24 +1370,112 @@
 	PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
 	PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
 
-	/* PTA (mobule: LBSC, CPG, LPC) */
+	/* PTA (mobule: LBSC, RGMII) */
 	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),
+	PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDC_MARK),
 
-	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	/* PTB (mobule: INTC, ONFI, TMU) */
+	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),
+	PINMUX_GPIO(GPIO_FN_ON_NRE, ON_NRE_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_NWE, ON_NWE_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_NWP, ON_NWP_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_NCE0, ON_NCE0_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_R_B0, ON_R_B0_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_ALE, ON_ALE_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_CLE, ON_CLE_MARK),
+	PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+
+	/* PTC (mobule: IRQ, PWMU) */
+	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_PWMU0, PWMU0_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMU1, PWMU1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMU2, PWMU2_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMU3, PWMU3_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMU4, PWMU4_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMU5, PWMU5_MARK),
+
+	/* PTD (mobule: SPI0, DMAC) */
+	PINMUX_GPIO(GPIO_FN_SP0_MOSI, SP0_MOSI_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_MISO, SP0_MISO_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SCK, SP0_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SCK_FB, SP0_SCK_FB_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS0, SP0_SS0_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS2, SP0_SS2_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS3, SP0_SS3_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
+
+	/* PTE (mobule: RMII) */
+	PINMUX_GPIO(GPIO_FN_RMII0_CRS_DV, RMII0_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_TXD1, RMII0_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_TXD0, RMII0_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_TXEN, RMII0_TXEN_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_REFCLK, RMII0_REFCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_RXD1, RMII0_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_RXD0, RMII0_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII0_RX_ER, RMII0_RX_ER_MARK),
+
+	/* PTF (mobule: RMII, SerMux) */
+	PINMUX_GPIO(GPIO_FN_RMII1_CRS_DV, RMII1_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_TXD1, RMII1_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_TXD0, RMII1_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_TXEN, RMII1_TXEN_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_REFCLK, RMII1_REFCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_RXD1, RMII1_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_RXD0, RMII1_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_RMII1_RX_ER, RMII1_RX_ER_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+
+	/* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+	PINMUX_GPIO(GPIO_FN_BOOTFMS, BOOTFMS_MARK),
+	PINMUX_GPIO(GPIO_FN_BOOTWP, BOOTWP_MARK),
+	PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+	PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+	PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK),
+	PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK),
+	PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK),
+	PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK),
+
+	/* PTH (mobule: SPI1, LPC, DMAC, ADC) */
+	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_WP, WP_MARK),
+	PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
+
+	/* PTI (mobule: LBSC, SDHI) */
 	PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
 	PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
 	PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
@@ -1238,18 +1484,6 @@
 	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),
@@ -1259,89 +1493,16 @@
 	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),
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS4, RTS4_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) */
+	/* PTK (mobule: SERMUX, LBSC, SCIF) */
 	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),
@@ -1349,62 +1510,65 @@
 	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),
+	PINMUX_GPIO(GPIO_FN_CLKOUT, CLKOUT_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
 
-	/* PTL (mobule: SERMUX) */
-	PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+	/* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
 	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),
+	PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+	PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
 
-	/* PTM (mobule: IIC, LPC) */
+	/* PTM (mobule: LBSC, IIC) */
+	PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+	PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
+	PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
+	PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
 	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) */
+	/* PTN (mobule: USB, JMC, SGPIO, WDT) */
+	PINMUX_GPIO(GPIO_FN_VBUS_EN, VBUS_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_VBUS_OC, VBUS_OC_MARK),
 	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),
+	PINMUX_GPIO(GPIO_FN_JMCTRST, JMCTRST_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),
+	PINMUX_GPIO(GPIO_FN_SUB_CLKIN, SUB_CLKIN_MARK),
+
+	/* PTO (mobule: SGPIO, SerMux) */
+	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_SGPIO2_CLK, SGPIO2_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO2_LOAD, SGPIO2_LOAD_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO2_DI, SGPIO2_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO2_DO, SGPIO2_DO_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),
+
+	/* PTP (mobule: EVC, ADC) */
 
 	/* PTQ (mobule: LPC) */
 	PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK),
@@ -1439,31 +1603,41 @@
 	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),
+	/* PTT (mobule: PWMX, AUD) */
+	PINMUX_GPIO(GPIO_FN_PWMX7, PWMX7_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX6, PWMX6_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX5, PWMX5_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX4, PWMX4_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX3, PWMX3_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX2, PWMX2_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX1, PWMX1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWMX0, PWMX0_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),
+	PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+	PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_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),
+	/* PTU (mobule: LPC, APM) */
+	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),
+	PINMUX_GPIO(GPIO_FN_APMONCTL_O, APMONCTL_O_MARK),
+	PINMUX_GPIO(GPIO_FN_APMPWBTOUT_O, APMPWBTOUT_O_MARK),
+	PINMUX_GPIO(GPIO_FN_APMSCI_O, APMSCI_O_MARK),
+	PINMUX_GPIO(GPIO_FN_APMVDDON, APMVDDON_MARK),
+	PINMUX_GPIO(GPIO_FN_APMSLPBTN, APMSLPBTN_MARK),
+	PINMUX_GPIO(GPIO_FN_APMPWRBTN, APMPWRBTN_MARK),
+	PINMUX_GPIO(GPIO_FN_APMS5N, APMS5N_MARK),
+	PINMUX_GPIO(GPIO_FN_APMS3N, APMS3N_MARK),
 
-	/* PTV (mobule: LBSC, DMAC) */
+	/* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
 	PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
 	PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
 	PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
@@ -1472,12 +1646,20 @@
 	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),
+	PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+	PINMUX_GPIO(GPIO_FN_R_SPI_MOSI, R_SPI_MOSI_MARK),
+	PINMUX_GPIO(GPIO_FN_R_SPI_MISO, R_SPI_MISO_MARK),
+	PINMUX_GPIO(GPIO_FN_R_SPI_RSPCK, R_SPI_RSPCK_MARK),
+	PINMUX_GPIO(GPIO_FN_R_SPI_SSL0, R_SPI_SSL0_MARK),
+	PINMUX_GPIO(GPIO_FN_R_SPI_SSL1, R_SPI_SSL1_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
+	PINMUX_GPIO(GPIO_FN_VBIOS_DI, VBIOS_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_VBIOS_DO, VBIOS_DO_MARK),
+	PINMUX_GPIO(GPIO_FN_VBIOS_CLK, VBIOS_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_VBIOS_CS, VBIOS_CS_MARK),
 
-	/* PTW (mobule: LBSC) */
+	/* PTW (mobule: LBSC, EVC, SCIF) */
 	PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
 	PINMUX_GPIO(GPIO_FN_A15, A15_MARK),
 	PINMUX_GPIO(GPIO_FN_A14, A14_MARK),
@@ -1487,6 +1669,14 @@
 	PINMUX_GPIO(GPIO_FN_A10, A10_MARK),
 	PINMUX_GPIO(GPIO_FN_A9, A9_MARK),
 	PINMUX_GPIO(GPIO_FN_A8, A8_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),
+	PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
 
 	/* PTX (mobule: LBSC) */
 	PINMUX_GPIO(GPIO_FN_A7, A7_MARK),
@@ -1497,6 +1687,10 @@
 	PINMUX_GPIO(GPIO_FN_A2, A2_MARK),
 	PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
 	PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
+	PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK),
+	PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK),
 
 	/* PTY (mobule: LBSC) */
 	PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
@@ -1507,18 +1701,36 @@
 	PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
 	PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
 	PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+
+	/* PTZ (mobule: eMMC, ONFI) */
+	PINMUX_GPIO(GPIO_FN_MMCDAT7, MMCDAT7_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT6, MMCDAT6_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT5, MMCDAT5_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT4, MMCDAT4_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT3, MMCDAT3_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT2, MMCDAT2_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT1, MMCDAT1_MARK),
+	PINMUX_GPIO(GPIO_FN_MMCDAT0, MMCDAT0_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ7, ON_DQ7_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ6, ON_DQ6_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ5, ON_DQ5_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ4, ON_DQ4_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ3, ON_DQ3_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ2, ON_DQ2_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ1, ON_DQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_ON_DQ0, ON_DQ0_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 }
+		PTA7_FN, PTA7_OUT, PTA7_IN, PTA7_IN_PU,
+		PTA6_FN, PTA6_OUT, PTA6_IN, PTA6_IN_PU,
+		PTA5_FN, PTA5_OUT, PTA5_IN, PTA5_IN_PU,
+		PTA4_FN, PTA4_OUT, PTA4_IN, PTA4_IN_PU,
+		PTA3_FN, PTA3_OUT, PTA3_IN, PTA3_IN_PU,
+		PTA2_FN, PTA2_OUT, PTA2_IN, PTA2_IN_PU,
+		PTA1_FN, PTA1_OUT, PTA1_IN, PTA1_IN_PU,
+		PTA0_FN, PTA0_OUT, PTA0_IN, PTA0_IN_PU }
 	},
 	{ PINMUX_CFG_REG("PBCR", 0xffec0002, 16, 2) {
 		PTB7_FN, PTB7_OUT, PTB7_IN, 0,
@@ -1541,125 +1753,126 @@
 		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 }
+		PTD7_FN, PTD7_OUT, PTD7_IN, PTD7_IN_PU,
+		PTD6_FN, PTD6_OUT, PTD6_IN, PTD6_IN_PU,
+		PTD5_FN, PTD5_OUT, PTD5_IN, PTD5_IN_PU,
+		PTD4_FN, PTD4_OUT, PTD4_IN, PTD4_IN_PU,
+		PTD3_FN, PTD3_OUT, PTD3_IN, PTD3_IN_PU,
+		PTD2_FN, PTD2_OUT, PTD2_IN, PTD2_IN_PU,
+		PTD1_FN, PTD1_OUT, PTD1_IN, PTD1_IN_PU,
+		PTD0_FN, PTD0_OUT, PTD0_IN, PTD0_IN_PU }
 	},
 	{ 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 }
+		PTE7_FN, PTE7_OUT, PTE7_IN, PTE7_IN_PU,
+		PTE6_FN, PTE6_OUT, PTE6_IN, PTE6_IN_PU,
+		PTE5_FN, PTE5_OUT, PTE5_IN, PTE5_IN_PU,
+		PTE4_FN, PTE4_OUT, PTE4_IN, PTE4_IN_PU,
+		PTE3_FN, PTE3_OUT, PTE3_IN, PTE3_IN_PU,
+		PTE2_FN, PTE2_OUT, PTE2_IN, PTE2_IN_PU,
+		PTE1_FN, PTE1_OUT, PTE1_IN, PTE1_IN_PU,
+		PTE0_FN, PTE0_OUT, PTE0_IN, PTE0_IN_PU }
 	},
 	{ 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 }
+		PTF7_FN, PTF7_OUT, PTF7_IN, PTF7_IN_PU,
+		PTF6_FN, PTF6_OUT, PTF6_IN, PTF6_IN_PU,
+		PTF5_FN, PTF5_OUT, PTF5_IN, PTF5_IN_PU,
+		PTF4_FN, PTF4_OUT, PTF4_IN, PTF4_IN_PU,
+		PTF3_FN, PTF3_OUT, PTF3_IN, PTF3_IN_PU,
+		PTF2_FN, PTF2_OUT, PTF2_IN, PTF2_IN_PU,
+		PTF1_FN, PTF1_OUT, PTF1_IN, PTF1_IN_PU,
+		PTF0_FN, PTF0_OUT, PTF0_IN, PTF0_IN_PU }
 	},
 	{ PINMUX_CFG_REG("PGCR", 0xffec000c, 16, 2) {
-		PTG7_FN, PTG7_OUT, PTG7_IN, 0,
-		PTG6_FN, PTG6_OUT, PTG6_IN, 0,
+		PTG7_FN, PTG7_OUT, PTG7_IN, PTG7_IN_PU ,
+		PTG6_FN, PTG6_OUT, PTG6_IN, PTG6_IN_PU ,
 		PTG5_FN, PTG5_OUT, PTG5_IN, 0,
-		PTG4_FN, PTG4_OUT, PTG4_IN, 0,
+		PTG4_FN, PTG4_OUT, PTG4_IN, PTG4_IN_PU ,
 		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 }
+		PTH7_FN, PTH7_OUT, PTH7_IN, PTH7_IN_PU,
+		PTH6_FN, PTH6_OUT, PTH6_IN, PTH6_IN_PU,
+		PTH5_FN, PTH5_OUT, PTH5_IN, PTH5_IN_PU,
+		PTH4_FN, PTH4_OUT, PTH4_IN, PTH4_IN_PU,
+		PTH3_FN, PTH3_OUT, PTH3_IN, PTH3_IN_PU,
+		PTH2_FN, PTH2_OUT, PTH2_IN, PTH2_IN_PU,
+		PTH1_FN, PTH1_OUT, PTH1_IN, PTH1_IN_PU,
+		PTH0_FN, PTH0_OUT, PTH0_IN, PTH0_IN_PU }
 	},
 	{ PINMUX_CFG_REG("PICR", 0xffec0010, 16, 2) {
-		PTI7_FN, PTI7_OUT, PTI7_IN, 0,
-		PTI6_FN, PTI6_OUT, PTI6_IN, 0,
+		PTI7_FN, PTI7_OUT, PTI7_IN, PTI7_IN_PU,
+		PTI6_FN, PTI6_OUT, PTI6_IN, PTI6_IN_PU,
 		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 }
+		PTI4_FN, PTI4_OUT, PTI4_IN, PTI4_IN_PU,
+		PTI3_FN, PTI3_OUT, PTI3_IN, PTI3_IN_PU,
+		PTI2_FN, PTI2_OUT, PTI2_IN, PTI2_IN_PU,
+		PTI1_FN, PTI1_OUT, PTI1_IN, PTI1_IN_PU,
+		PTI0_FN, PTI0_OUT, PTI0_IN, PTI0_IN_PU }
 	},
 	{ 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 }
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTJ6_FN, PTJ6_OUT, PTJ6_IN, PTJ6_IN_PU,
+		PTJ5_FN, PTJ5_OUT, PTJ5_IN, PTJ5_IN_PU,
+		PTJ4_FN, PTJ4_OUT, PTJ4_IN, PTJ4_IN_PU,
+		PTJ3_FN, PTJ3_OUT, PTJ3_IN, PTJ3_IN_PU,
+		PTJ2_FN, PTJ2_OUT, PTJ2_IN, PTJ2_IN_PU,
+		PTJ1_FN, PTJ1_OUT, PTJ1_IN, PTJ1_IN_PU,
+		PTJ0_FN, PTJ0_OUT, PTJ0_IN, PTJ0_IN_PU }
 	},
 	{ 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 }
+		PTK7_FN, PTK7_OUT, PTK7_IN, PTK7_IN_PU,
+		PTK6_FN, PTK6_OUT, PTK6_IN, PTK6_IN_PU,
+		PTK5_FN, PTK5_OUT, PTK5_IN, PTK5_IN_PU,
+		PTK4_FN, PTK4_OUT, PTK4_IN, PTK4_IN_PU,
+		PTK3_FN, PTK3_OUT, PTK3_IN, PTK3_IN_PU,
+		PTK2_FN, PTK2_OUT, PTK2_IN, PTK2_IN_PU,
+		PTK1_FN, PTK1_OUT, PTK1_IN, PTK1_IN_PU,
+		PTK0_FN, PTK0_OUT, PTK0_IN, PTK0_IN_PU }
 	},
 	{ 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 }
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTL6_FN, PTL6_OUT, PTL6_IN, PTL6_IN_PU,
+		PTL5_FN, PTL5_OUT, PTL5_IN, PTL5_IN_PU,
+		PTL4_FN, PTL4_OUT, PTL4_IN, PTL4_IN_PU,
+		PTL3_FN, PTL3_OUT, PTL3_IN, PTL3_IN_PU,
+		PTL2_FN, PTL2_OUT, PTL2_IN, PTL2_IN_PU,
+		PTL1_FN, PTL1_OUT, PTL1_IN, PTL1_IN_PU,
+		PTL0_FN, PTL0_OUT, PTL0_IN, PTL0_IN_PU }
 	},
 	{ 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,
+		PTM7_FN, PTM7_OUT, PTM7_IN, PTM7_IN_PU,
+		PTM6_FN, PTM6_OUT, PTM6_IN, PTM6_IN_PU,
+		PTM5_FN, PTM5_OUT, PTM5_IN, PTM5_IN_PU,
+		PTM4_FN, PTM4_OUT, PTM4_IN, PTM4_IN_PU,
 		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,
+		0, 0, 0, 0,	/* reserved: always set 1 */
 		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 }
+		PTN4_FN, PTN4_OUT, PTN4_IN, PTN4_IN_PU,
+		PTN3_FN, PTN3_OUT, PTN3_IN, PTN3_IN_PU,
+		PTN2_FN, PTN2_OUT, PTN2_IN, PTN2_IN_PU,
+		PTN1_FN, PTN1_OUT, PTN1_IN, PTN1_IN_PU,
+		PTN0_FN, PTN0_OUT, PTN0_IN, PTN0_IN_PU }
 	},
 	{ 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 }
+		PTO7_FN, PTO7_OUT, PTO7_IN, PTO7_IN_PU,
+		PTO6_FN, PTO6_OUT, PTO6_IN, PTO6_IN_PU,
+		PTO5_FN, PTO5_OUT, PTO5_IN, PTO5_IN_PU,
+		PTO4_FN, PTO4_OUT, PTO4_IN, PTO4_IN_PU,
+		PTO3_FN, PTO3_OUT, PTO3_IN, PTO3_IN_PU,
+		PTO2_FN, PTO2_OUT, PTO2_IN, PTO2_IN_PU,
+		PTO1_FN, PTO1_OUT, PTO1_IN, PTO1_IN_PU,
+		PTO0_FN, PTO0_OUT, PTO0_IN, PTO0_IN_PU }
 	},
+#if 0	/* FIXME: Remove it? */
 	{ PINMUX_CFG_REG("PPCR", 0xffec001e, 16, 2) {
 		0, 0, 0, 0,	/* reserved: always set 1 */
 		PTP6_FN, PTP6_OUT, PTP6_IN, 0,
@@ -1670,6 +1883,7 @@
 		PTP1_FN, PTP1_OUT, PTP1_IN, 0,
 		PTP0_FN, PTP0_OUT, PTP0_IN, 0 }
 	},
+#endif
 	{ PINMUX_CFG_REG("PQCR", 0xffec0020, 16, 2) {
 		0, 0, 0, 0,	/* reserved: always set 1 */
 		PTQ6_FN, PTQ6_OUT, PTQ6_IN, 0,
@@ -1701,14 +1915,14 @@
 		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 }
+		PTT7_FN, PTT7_OUT, PTT7_IN, PTO7_IN_PU,
+		PTT6_FN, PTT6_OUT, PTT6_IN, PTO6_IN_PU,
+		PTT5_FN, PTT5_OUT, PTT5_IN, PTO5_IN_PU,
+		PTT4_FN, PTT4_OUT, PTT4_IN, PTO4_IN_PU,
+		PTT3_FN, PTT3_OUT, PTT3_IN, PTO3_IN_PU,
+		PTT2_FN, PTT2_OUT, PTT2_IN, PTO2_IN_PU,
+		PTT1_FN, PTT1_OUT, PTT1_IN, PTO1_IN_PU,
+		PTT0_FN, PTT0_OUT, PTT0_IN, PTO0_IN_PU }
 	},
 	{ PINMUX_CFG_REG("PUCR", 0xffec0028, 16, 2) {
 		PTU7_FN, PTU7_OUT, PTU7_IN, PTU7_IN_PU,
@@ -1727,16 +1941,16 @@
 		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 }
+		PTV1_FN, PTV1_OUT, PTV1_IN, 0,
+		PTV0_FN, PTV0_OUT, PTV0_IN, 0 }
 	},
 	{ 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,
+		PTW7_FN, PTW7_OUT, PTW7_IN, 0,
+		PTW6_FN, PTW6_OUT, PTW6_IN, 0,
+		PTW5_FN, PTW5_OUT, PTW5_IN, 0,
+		PTW4_FN, PTW4_OUT, PTW4_IN, 0,
+		PTW3_FN, PTW3_OUT, PTW3_IN, 0,
+		PTW2_FN, PTW2_OUT, PTW2_IN, 0,
 		PTW1_FN, PTW1_OUT, PTW1_IN, PTW1_IN_PU,
 		PTW0_FN, PTW0_OUT, PTW0_IN, PTW0_IN_PU }
 	},
@@ -1761,32 +1975,32 @@
 		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 }
+		PTZ7_FN, PTZ7_OUT, PTZ7_IN, 0,
+		PTZ6_FN, PTZ6_OUT, PTZ6_IN, 0,
+		PTZ5_FN, PTZ5_OUT, PTZ5_IN, 0,
+		PTZ4_FN, PTZ4_OUT, PTZ4_IN, 0,
+		PTZ3_FN, PTZ3_OUT, PTZ3_IN, 0,
+		PTZ2_FN, PTZ2_OUT, PTZ2_IN, 0,
+		PTZ1_FN, PTZ1_OUT, PTZ1_IN, 0,
+		PTZ0_FN, 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,
+		PS0_15_FN1, PS0_15_FN2,
+		PS0_14_FN1, PS0_14_FN2,
+		PS0_13_FN1, PS0_13_FN2,
+		PS0_12_FN1, PS0_12_FN2,
+		PS0_11_FN1, PS0_11_FN2,
+		PS0_10_FN1, PS0_10_FN2,
+		PS0_9_FN1, PS0_9_FN2,
+		PS0_8_FN1, PS0_8_FN2,
+		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,
 		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) {
@@ -1795,73 +2009,136 @@
 		0, 0,
 		0, 0,
 		0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		PS1_7_FN1, PS1_7_FN3,
-		PS1_6_FN1, PS1_6_FN3,
+		PS1_10_FN1, PS1_10_FN2,
+		PS1_9_FN1, PS1_9_FN2,
+		PS1_8_FN1, PS1_8_FN2,
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0,
+		PS1_2_FN1, PS1_2_FN2,
+		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,
+		PS2_13_FN1, PS2_13_FN2,
+		PS2_12_FN1, PS2_12_FN2,
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0,
+		PS2_7_FN1, PS2_7_FN2,
+		PS2_6_FN1, PS2_6_FN2,
+		PS2_5_FN1, PS2_5_FN2,
+		PS2_4_FN1, PS2_4_FN2,
 		0, 0,
+		PS2_2_FN1, PS2_2_FN2,
 		0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		PS2_1_FN1, PS2_1_FN2,
-		PS2_0_FN1, PS2_0_FN2, }
+		0, 0, }
 	},
+	{ PINMUX_CFG_REG("PSEL3", 0xffec0076, 16, 1) {
+		PS3_15_FN1, PS3_15_FN2,
+		PS3_14_FN1, PS3_14_FN2,
+		PS3_13_FN1, PS3_13_FN2,
+		PS3_12_FN1, PS3_12_FN2,
+		PS3_11_FN1, PS3_11_FN2,
+		PS3_10_FN1, PS3_10_FN2,
+		PS3_9_FN1, PS3_9_FN2,
+		PS3_8_FN1, PS3_8_FN2,
+		PS3_7_FN1, PS3_7_FN2,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS3_2_FN1, PS3_2_FN2,
+		PS3_1_FN1, PS3_1_FN2,
+		0, 0, }
+	},
+
 	{ 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,
+		PS4_14_FN1, PS4_14_FN2,
+		PS4_13_FN1, PS4_13_FN2,
+		PS4_12_FN1, PS4_12_FN2,
+		0, 0,
+		PS4_10_FN1, PS4_10_FN2,
+		PS4_9_FN1, PS4_9_FN2,
+		PS4_8_FN1, PS4_8_FN2,
 		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, }
+		PS4_4_FN1, PS4_4_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, }
 	},
 	{ PINMUX_CFG_REG("PSEL5", 0xffec007a, 16, 1) {
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0,
-		0, 0,
-		0, 0,
+		PS5_11_FN1, PS5_11_FN2,
+		PS5_10_FN1, PS5_10_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,
+		PS5_3_FN1, PS5_3_FN2,
+		PS5_2_FN1, PS5_2_FN2,
+		0, 0,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+		PS6_15_FN1, PS6_15_FN2,
+		PS6_14_FN1, PS6_14_FN2,
+		PS6_13_FN1, PS6_13_FN2,
+		PS6_12_FN1, PS6_12_FN2,
+		PS6_11_FN1, PS6_11_FN2,
+		PS6_10_FN1, PS6_10_FN2,
+		PS6_9_FN1, PS6_9_FN2,
+		PS6_8_FN1, PS6_8_FN2,
+		PS6_7_FN1, PS6_7_FN2,
+		PS6_6_FN1, PS6_6_FN2,
+		PS6_5_FN1, PS6_5_FN2,
+		PS6_4_FN1, PS6_4_FN2,
+		PS6_3_FN1, PS6_3_FN2,
+		PS6_2_FN1, PS6_2_FN2,
+		PS6_1_FN1, PS6_1_FN2,
+		PS6_0_FN1, PS6_0_FN2, }
+	},
+	{ PINMUX_CFG_REG("PSEL7", 0xffec0082, 16, 1) {
+		PS7_15_FN1, PS7_15_FN2,
+		PS7_14_FN1, PS7_14_FN2,
+		PS7_13_FN1, PS7_13_FN2,
+		PS7_12_FN1, PS7_12_FN2,
+		PS7_11_FN1, PS7_11_FN2,
+		PS7_10_FN1, PS7_10_FN2,
+		PS7_9_FN1, PS7_9_FN2,
+		PS7_8_FN1, PS7_8_FN2,
+		PS7_7_FN1, PS7_7_FN2,
+		PS7_6_FN1, PS7_6_FN2,
+		PS7_5_FN1, PS7_5_FN2,
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0,
 		0, 0, }
 	},
-	{ PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+	{ PINMUX_CFG_REG("PSEL8", 0xffec0084, 16, 1) {
+		PS8_15_FN1, PS8_15_FN2,
+		PS8_14_FN1, PS8_14_FN2,
+		PS8_13_FN1, PS8_13_FN2,
+		PS8_12_FN1, PS8_12_FN2,
+		PS8_11_FN1, PS8_11_FN2,
+		PS8_10_FN1, PS8_10_FN2,
+		PS8_9_FN1, PS8_9_FN2,
+		PS8_8_FN1, PS8_8_FN2,
 		0, 0,
 		0, 0,
 		0, 0,
@@ -1869,15 +2146,7 @@
 		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, }
+		0, 0, }
 	},
 	{}
 };
@@ -1920,7 +2189,7 @@
 		PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA }
 	},
 	{ PINMUX_DATA_REG("PJDR", 0xffec0046, 8) {
-		PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+		0, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
 		PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
 	},
 	{ PINMUX_DATA_REG("PKDR", 0xffec0048, 8) {
@@ -1928,15 +2197,15 @@
 		PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
 	},
 	{ PINMUX_DATA_REG("PLDR", 0xffec004a, 8) {
-		PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+		0, 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,
+		PTM7_DATA, 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,
+		0, PTN6_DATA, PTN5_DATA, PTN4_DATA,
 		PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
 	},
 	{ PINMUX_DATA_REG("PODR", 0xffec0050, 8) {
@@ -1944,7 +2213,7 @@
 		PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA }
 	},
 	{ PINMUX_DATA_REG("PPDR", 0xffec0052, 8) {
-		0, PTP6_DATA, PTP5_DATA, PTP4_DATA,
+		PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
 		PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
 	},
 	{ PINMUX_DATA_REG("PQDR", 0xffec0054, 8) {
@@ -1960,7 +2229,7 @@
 		PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
 	},
 	{ PINMUX_DATA_REG("PTDR", 0xffec005a, 8) {
-		0, 0, PTT5_DATA, PTT4_DATA,
+		PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
 		PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
 	},
 	{ PINMUX_DATA_REG("PUDR", 0xffec005c, 8) {
@@ -2000,8 +2269,8 @@
 	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
 	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
 
-	.first_gpio = GPIO_PTA7,
-	.last_gpio = GPIO_FN_D0,
+	.first_gpio = GPIO_PTA0,
+	.last_gpio = GPIO_FN_ON_DQ0,
 
 	.gpios = pinmux_gpios,
 	.cfg_regs = pinmux_config_regs,
@@ -2015,5 +2284,4 @@
 {
 	return register_pinmux(&sh7757_pinmux_info);
 }
-
 arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c b/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c
new file mode 100644
index 0000000..aaa5338
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-shx3.c
@@ -0,0 +1,587 @@
+/*
+ * SH-X3 prototype CPU pinmux
+ *
+ * Copyright (C) 2010  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/gpio.h>
+#include <cpu/shx3.h>
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+	PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+	PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+	PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+	PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+	PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+	PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+	PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+	PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+	PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+	PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+	PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+	PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+	PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
+
+	PH5_DATA, PH4_DATA,
+	PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+	PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+	PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+	PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+	PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+	PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+	PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+	PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+	PE7_IN, PE6_IN, PE5_IN, PE4_IN,
+	PE3_IN, PE2_IN, PE1_IN, PE0_IN,
+	PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+	PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+	PG7_IN, PG6_IN, PG5_IN, PG4_IN,
+	PG3_IN, PG2_IN, PG1_IN, PG0_IN,
+
+	PH5_IN, PH4_IN,
+	PH3_IN, PH2_IN, PH1_IN, PH0_IN,
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PA7_IN_PU, PA6_IN_PU, PA5_IN_PU, PA4_IN_PU,
+	PA3_IN_PU, PA2_IN_PU, PA1_IN_PU, PA0_IN_PU,
+	PB7_IN_PU, PB6_IN_PU, PB5_IN_PU, PB4_IN_PU,
+	PB3_IN_PU, PB2_IN_PU, PB1_IN_PU, PB0_IN_PU,
+	PC7_IN_PU, PC6_IN_PU, PC5_IN_PU, PC4_IN_PU,
+	PC3_IN_PU, PC2_IN_PU, PC1_IN_PU, PC0_IN_PU,
+	PD7_IN_PU, PD6_IN_PU, PD5_IN_PU, PD4_IN_PU,
+	PD3_IN_PU, PD2_IN_PU, PD1_IN_PU, PD0_IN_PU,
+	PE7_IN_PU, PE6_IN_PU, PE5_IN_PU, PE4_IN_PU,
+	PE3_IN_PU, PE2_IN_PU, PE1_IN_PU, PE0_IN_PU,
+	PF7_IN_PU, PF6_IN_PU, PF5_IN_PU, PF4_IN_PU,
+	PF3_IN_PU, PF2_IN_PU, PF1_IN_PU, PF0_IN_PU,
+	PG7_IN_PU, PG6_IN_PU, PG5_IN_PU, PG4_IN_PU,
+	PG3_IN_PU, PG2_IN_PU, PG1_IN_PU, PG0_IN_PU,
+
+	PH5_IN_PU, PH4_IN_PU,
+	PH3_IN_PU, PH2_IN_PU, PH1_IN_PU, PH0_IN_PU,
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
+	PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
+	PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
+	PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
+	PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+	PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+	PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+	PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+	PE7_OUT, PE6_OUT, PE5_OUT, PE4_OUT,
+	PE3_OUT, PE2_OUT, PE1_OUT, PE0_OUT,
+	PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+	PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+	PG7_OUT, PG6_OUT, PG5_OUT, PG4_OUT,
+	PG3_OUT, PG2_OUT, PG1_OUT, PG0_OUT,
+
+	PH5_OUT, PH4_OUT,
+	PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PA7_FN, PA6_FN, PA5_FN, PA4_FN,
+	PA3_FN, PA2_FN, PA1_FN, PA0_FN,
+	PB7_FN, PB6_FN, PB5_FN, PB4_FN,
+	PB3_FN, PB2_FN, PB1_FN, PB0_FN,
+	PC7_FN, PC6_FN, PC5_FN, PC4_FN,
+	PC3_FN, PC2_FN, PC1_FN, PC0_FN,
+	PD7_FN, PD6_FN, PD5_FN, PD4_FN,
+	PD3_FN, PD2_FN, PD1_FN, PD0_FN,
+	PE7_FN, PE6_FN, PE5_FN, PE4_FN,
+	PE3_FN, PE2_FN, PE1_FN, PE0_FN,
+	PF7_FN, PF6_FN, PF5_FN, PF4_FN,
+	PF3_FN, PF2_FN, PF1_FN, PF0_FN,
+	PG7_FN, PG6_FN, PG5_FN, PG4_FN,
+	PG3_FN, PG2_FN, PG1_FN, PG0_FN,
+
+	PH5_FN, PH4_FN,
+	PH3_FN, PH2_FN, PH1_FN, PH0_FN,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+
+	D31_MARK, D30_MARK, D29_MARK, D28_MARK, D27_MARK, D26_MARK,
+	D25_MARK, D24_MARK, D23_MARK, D22_MARK, D21_MARK, D20_MARK,
+	D19_MARK, D18_MARK, D17_MARK, D16_MARK,
+
+	BACK_MARK, BREQ_MARK,
+	WE3_MARK, WE2_MARK,
+	CS6_MARK, CS5_MARK, CS4_MARK,
+	CLKOUTENB_MARK,
+
+	DACK3_MARK, DACK2_MARK, DACK1_MARK, DACK0_MARK,
+	DREQ3_MARK, DREQ2_MARK, DREQ1_MARK, DREQ0_MARK,
+
+	IRQ3_MARK, IRQ2_MARK, IRQ1_MARK, IRQ0_MARK,
+
+	DRAK3_MARK, DRAK2_MARK, DRAK1_MARK, DRAK0_MARK,
+
+	SCK3_MARK, SCK2_MARK, SCK1_MARK, SCK0_MARK,
+	IRL3_MARK, IRL2_MARK, IRL1_MARK, IRL0_MARK,
+	TXD3_MARK, TXD2_MARK, TXD1_MARK, TXD0_MARK,
+	RXD3_MARK, RXD2_MARK, RXD1_MARK, RXD0_MARK,
+
+	CE2B_MARK, CE2A_MARK, IOIS16_MARK,
+	STATUS1_MARK, STATUS0_MARK,
+
+	IRQOUT_MARK,
+
+	PINMUX_MARK_END,
+};
+
+static pinmux_enum_t shx3_pinmux_data[] = {
+
+	/* PA GPIO */
+	PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU),
+	PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT, PA6_IN_PU),
+	PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT, PA5_IN_PU),
+	PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT, PA4_IN_PU),
+	PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT, PA3_IN_PU),
+	PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT, PA2_IN_PU),
+	PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT, PA1_IN_PU),
+	PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT, PA0_IN_PU),
+
+	/* PB GPIO */
+	PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT, PB7_IN_PU),
+	PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT, PB6_IN_PU),
+	PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT, PB5_IN_PU),
+	PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT, PB4_IN_PU),
+	PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT, PB3_IN_PU),
+	PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT, PB2_IN_PU),
+	PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT, PB1_IN_PU),
+	PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT, PB0_IN_PU),
+
+	/* PC GPIO */
+	PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT, PC7_IN_PU),
+	PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT, PC6_IN_PU),
+	PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT, PC5_IN_PU),
+	PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT, PC4_IN_PU),
+	PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT, PC3_IN_PU),
+	PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT, PC2_IN_PU),
+	PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT, PC1_IN_PU),
+	PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT, PC0_IN_PU),
+
+	/* PD GPIO */
+	PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT, PD7_IN_PU),
+	PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT, PD6_IN_PU),
+	PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT, PD5_IN_PU),
+	PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT, PD4_IN_PU),
+	PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT, PD3_IN_PU),
+	PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT, PD2_IN_PU),
+	PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT, PD1_IN_PU),
+	PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT, PD0_IN_PU),
+
+	/* PE GPIO */
+	PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT, PE7_IN_PU),
+	PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT, PE6_IN_PU),
+	PINMUX_DATA(PE5_DATA, PE5_IN, PE5_OUT, PE5_IN_PU),
+	PINMUX_DATA(PE4_DATA, PE4_IN, PE4_OUT, PE4_IN_PU),
+	PINMUX_DATA(PE3_DATA, PE3_IN, PE3_OUT, PE3_IN_PU),
+	PINMUX_DATA(PE2_DATA, PE2_IN, PE2_OUT, PE2_IN_PU),
+	PINMUX_DATA(PE1_DATA, PE1_IN, PE1_OUT, PE1_IN_PU),
+	PINMUX_DATA(PE0_DATA, PE0_IN, PE0_OUT, PE0_IN_PU),
+
+	/* PF GPIO */
+	PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT, PF7_IN_PU),
+	PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT, PF6_IN_PU),
+	PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT, PF5_IN_PU),
+	PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT, PF4_IN_PU),
+	PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT, PF3_IN_PU),
+	PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT, PF2_IN_PU),
+	PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT, PF1_IN_PU),
+	PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT, PF0_IN_PU),
+
+	/* PG GPIO */
+	PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT, PG7_IN_PU),
+	PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT, PG6_IN_PU),
+	PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT, PG5_IN_PU),
+	PINMUX_DATA(PG4_DATA, PG4_IN, PG4_OUT, PG4_IN_PU),
+	PINMUX_DATA(PG3_DATA, PG3_IN, PG3_OUT, PG3_IN_PU),
+	PINMUX_DATA(PG2_DATA, PG2_IN, PG2_OUT, PG2_IN_PU),
+	PINMUX_DATA(PG1_DATA, PG1_IN, PG1_OUT, PG1_IN_PU),
+	PINMUX_DATA(PG0_DATA, PG0_IN, PG0_OUT, PG0_IN_PU),
+
+	/* PH GPIO */
+	PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT, PH5_IN_PU),
+	PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT, PH4_IN_PU),
+	PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT, PH3_IN_PU),
+	PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT, PH2_IN_PU),
+	PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT, PH1_IN_PU),
+	PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT, PH0_IN_PU),
+
+	/* PA FN */
+	PINMUX_DATA(D31_MARK, PA7_FN),
+	PINMUX_DATA(D30_MARK, PA6_FN),
+	PINMUX_DATA(D29_MARK, PA5_FN),
+	PINMUX_DATA(D28_MARK, PA4_FN),
+	PINMUX_DATA(D27_MARK, PA3_FN),
+	PINMUX_DATA(D26_MARK, PA2_FN),
+	PINMUX_DATA(D25_MARK, PA1_FN),
+	PINMUX_DATA(D24_MARK, PA0_FN),
+
+	/* PB FN */
+	PINMUX_DATA(D23_MARK, PB7_FN),
+	PINMUX_DATA(D22_MARK, PB6_FN),
+	PINMUX_DATA(D21_MARK, PB5_FN),
+	PINMUX_DATA(D20_MARK, PB4_FN),
+	PINMUX_DATA(D19_MARK, PB3_FN),
+	PINMUX_DATA(D18_MARK, PB2_FN),
+	PINMUX_DATA(D17_MARK, PB1_FN),
+	PINMUX_DATA(D16_MARK, PB0_FN),
+
+	/* PC FN */
+	PINMUX_DATA(BACK_MARK,		PC7_FN),
+	PINMUX_DATA(BREQ_MARK,		PC6_FN),
+	PINMUX_DATA(WE3_MARK,		PC5_FN),
+	PINMUX_DATA(WE2_MARK,		PC4_FN),
+	PINMUX_DATA(CS6_MARK,		PC3_FN),
+	PINMUX_DATA(CS5_MARK,		PC2_FN),
+	PINMUX_DATA(CS4_MARK,		PC1_FN),
+	PINMUX_DATA(CLKOUTENB_MARK,	PC0_FN),
+
+	/* PD FN */
+	PINMUX_DATA(DACK3_MARK,	PD7_FN),
+	PINMUX_DATA(DACK2_MARK, PD6_FN),
+	PINMUX_DATA(DACK1_MARK, PD5_FN),
+	PINMUX_DATA(DACK0_MARK, PD4_FN),
+	PINMUX_DATA(DREQ3_MARK, PD3_FN),
+	PINMUX_DATA(DREQ2_MARK, PD2_FN),
+	PINMUX_DATA(DREQ1_MARK, PD1_FN),
+	PINMUX_DATA(DREQ0_MARK, PD0_FN),
+
+	/* PE FN */
+	PINMUX_DATA(IRQ3_MARK,	PE7_FN),
+	PINMUX_DATA(IRQ2_MARK,	PE6_FN),
+	PINMUX_DATA(IRQ1_MARK,	PE5_FN),
+	PINMUX_DATA(IRQ0_MARK,	PE4_FN),
+	PINMUX_DATA(DRAK3_MARK, PE3_FN),
+	PINMUX_DATA(DRAK2_MARK, PE2_FN),
+	PINMUX_DATA(DRAK1_MARK, PE1_FN),
+	PINMUX_DATA(DRAK0_MARK, PE0_FN),
+
+	/* PF FN */
+	PINMUX_DATA(SCK3_MARK, PF7_FN),
+	PINMUX_DATA(SCK2_MARK, PF6_FN),
+	PINMUX_DATA(SCK1_MARK, PF5_FN),
+	PINMUX_DATA(SCK0_MARK, PF4_FN),
+	PINMUX_DATA(IRL3_MARK, PF3_FN),
+	PINMUX_DATA(IRL2_MARK, PF2_FN),
+	PINMUX_DATA(IRL1_MARK, PF1_FN),
+	PINMUX_DATA(IRL0_MARK, PF0_FN),
+
+	/* PG FN */
+	PINMUX_DATA(TXD3_MARK, PG7_FN),
+	PINMUX_DATA(TXD2_MARK, PG6_FN),
+	PINMUX_DATA(TXD1_MARK, PG5_FN),
+	PINMUX_DATA(TXD0_MARK, PG4_FN),
+	PINMUX_DATA(RXD3_MARK, PG3_FN),
+	PINMUX_DATA(RXD2_MARK, PG2_FN),
+	PINMUX_DATA(RXD1_MARK, PG1_FN),
+	PINMUX_DATA(RXD0_MARK, PG0_FN),
+
+	/* PH FN */
+	PINMUX_DATA(CE2B_MARK,		PH5_FN),
+	PINMUX_DATA(CE2A_MARK,		PH4_FN),
+	PINMUX_DATA(IOIS16_MARK,	PH3_FN),
+	PINMUX_DATA(STATUS1_MARK,	PH2_FN),
+	PINMUX_DATA(STATUS0_MARK,	PH1_FN),
+	PINMUX_DATA(IRQOUT_MARK,	PH0_FN),
+};
+
+static struct pinmux_gpio shx3_pinmux_gpios[] = {
+	/* PA */
+	PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+	PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+	PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+	PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+	PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+	PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+	PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+	PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+	/* PB */
+	PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+	PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+	PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+	PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+	PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+	PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+	PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+	PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+	/* PC */
+	PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+	PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+	PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+	PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+	PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+	PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+	PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+	PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+	/* PD */
+	PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+	PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+	PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+	PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+	PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+	PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+	PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+	PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+	/* PE */
+	PINMUX_GPIO(GPIO_PE7, PE7_DATA),
+	PINMUX_GPIO(GPIO_PE6, PE6_DATA),
+	PINMUX_GPIO(GPIO_PE5, PE5_DATA),
+	PINMUX_GPIO(GPIO_PE4, PE4_DATA),
+	PINMUX_GPIO(GPIO_PE3, PE3_DATA),
+	PINMUX_GPIO(GPIO_PE2, PE2_DATA),
+	PINMUX_GPIO(GPIO_PE1, PE1_DATA),
+	PINMUX_GPIO(GPIO_PE0, PE0_DATA),
+
+	/* PF */
+	PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+	PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+	PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+	PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+	PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+	PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+	PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+	PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+	/* PG */
+	PINMUX_GPIO(GPIO_PG7, PG7_DATA),
+	PINMUX_GPIO(GPIO_PG6, PG6_DATA),
+	PINMUX_GPIO(GPIO_PG5, PG5_DATA),
+	PINMUX_GPIO(GPIO_PG4, PG4_DATA),
+	PINMUX_GPIO(GPIO_PG3, PG3_DATA),
+	PINMUX_GPIO(GPIO_PG2, PG2_DATA),
+	PINMUX_GPIO(GPIO_PG1, PG1_DATA),
+	PINMUX_GPIO(GPIO_PG0, PG0_DATA),
+
+	/* PH */
+	PINMUX_GPIO(GPIO_PH5, PH5_DATA),
+	PINMUX_GPIO(GPIO_PH4, PH4_DATA),
+	PINMUX_GPIO(GPIO_PH3, PH3_DATA),
+	PINMUX_GPIO(GPIO_PH2, PH2_DATA),
+	PINMUX_GPIO(GPIO_PH1, PH1_DATA),
+	PINMUX_GPIO(GPIO_PH0, PH0_DATA),
+
+	/* FN */
+	PINMUX_GPIO(GPIO_FN_D31,	D31_MARK),
+	PINMUX_GPIO(GPIO_FN_D30,	D30_MARK),
+	PINMUX_GPIO(GPIO_FN_D29,	D29_MARK),
+	PINMUX_GPIO(GPIO_FN_D28,	D28_MARK),
+	PINMUX_GPIO(GPIO_FN_D27,	D27_MARK),
+	PINMUX_GPIO(GPIO_FN_D26,	D26_MARK),
+	PINMUX_GPIO(GPIO_FN_D25,	D25_MARK),
+	PINMUX_GPIO(GPIO_FN_D24,	D24_MARK),
+	PINMUX_GPIO(GPIO_FN_D23,	D23_MARK),
+	PINMUX_GPIO(GPIO_FN_D22,	D22_MARK),
+	PINMUX_GPIO(GPIO_FN_D21,	D21_MARK),
+	PINMUX_GPIO(GPIO_FN_D20,	D20_MARK),
+	PINMUX_GPIO(GPIO_FN_D19,	D19_MARK),
+	PINMUX_GPIO(GPIO_FN_D18,	D18_MARK),
+	PINMUX_GPIO(GPIO_FN_D17,	D17_MARK),
+	PINMUX_GPIO(GPIO_FN_D16,	D16_MARK),
+	PINMUX_GPIO(GPIO_FN_BACK,	BACK_MARK),
+	PINMUX_GPIO(GPIO_FN_BREQ,	BREQ_MARK),
+	PINMUX_GPIO(GPIO_FN_WE3,	WE3_MARK),
+	PINMUX_GPIO(GPIO_FN_WE2,	WE2_MARK),
+	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_CLKOUTENB,	CLKOUTENB_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK3,	DACK3_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK2,	DACK2_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK1,	DACK1_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK0,	DACK0_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ3,	DREQ3_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ2,	DREQ2_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ1,	DREQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ0,	DREQ0_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_DRAK3,	DRAK3_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK2,	DRAK2_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK1,	DRAK1_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK0,	DRAK0_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK3,	SCK3_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK2,	SCK2_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK1,	SCK1_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK0,	SCK0_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL3,	IRL3_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL2,	IRL2_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL1,	IRL1_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL0,	IRL0_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD3,	TXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD2,	TXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD1,	TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD0,	TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD3,	RXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD2,	RXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD1,	RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD0,	RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_CE2B,	CE2B_MARK),
+	PINMUX_GPIO(GPIO_FN_CE2A,	CE2A_MARK),
+	PINMUX_GPIO(GPIO_FN_IOIS16,	IOIS16_MARK),
+	PINMUX_GPIO(GPIO_FN_STATUS1,	STATUS1_MARK),
+	PINMUX_GPIO(GPIO_FN_STATUS0,	STATUS0_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQOUT,	IRQOUT_MARK),
+};
+
+static struct pinmux_cfg_reg shx3_pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("PABCR", 0xffc70000, 32, 2) {
+		PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU,
+		PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU,
+		PA5_FN, PA5_OUT, PA5_IN, PA5_IN_PU,
+		PA4_FN, PA4_OUT, PA4_IN, PA4_IN_PU,
+		PA3_FN, PA3_OUT, PA3_IN, PA3_IN_PU,
+		PA2_FN, PA2_OUT, PA2_IN, PA2_IN_PU,
+		PA1_FN, PA1_OUT, PA1_IN, PA1_IN_PU,
+		PA0_FN, PA0_OUT, PA0_IN, PA0_IN_PU,
+		PB7_FN, PB7_OUT, PB7_IN, PB7_IN_PU,
+		PB6_FN, PB6_OUT, PB6_IN, PB6_IN_PU,
+		PB5_FN, PB5_OUT, PB5_IN, PB5_IN_PU,
+		PB4_FN, PB4_OUT, PB4_IN, PB4_IN_PU,
+		PB3_FN, PB3_OUT, PB3_IN, PB3_IN_PU,
+		PB2_FN, PB2_OUT, PB2_IN, PB2_IN_PU,
+		PB1_FN, PB1_OUT, PB1_IN, PB1_IN_PU,
+		PB0_FN, PB0_OUT, PB0_IN, PB0_IN_PU, },
+	},
+	{ PINMUX_CFG_REG("PCDCR", 0xffc70004, 32, 2) {
+		PC7_FN, PC7_OUT, PC7_IN, PC7_IN_PU,
+		PC6_FN, PC6_OUT, PC6_IN, PC6_IN_PU,
+		PC5_FN, PC5_OUT, PC5_IN, PC5_IN_PU,
+		PC4_FN, PC4_OUT, PC4_IN, PC4_IN_PU,
+		PC3_FN, PC3_OUT, PC3_IN, PC3_IN_PU,
+		PC2_FN, PC2_OUT, PC2_IN, PC2_IN_PU,
+		PC1_FN, PC1_OUT, PC1_IN, PC1_IN_PU,
+		PC0_FN, PC0_OUT, PC0_IN, PC0_IN_PU,
+		PD7_FN, PD7_OUT, PD7_IN, PD7_IN_PU,
+		PD6_FN, PD6_OUT, PD6_IN, PD6_IN_PU,
+		PD5_FN, PD5_OUT, PD5_IN, PD5_IN_PU,
+		PD4_FN, PD4_OUT, PD4_IN, PD4_IN_PU,
+		PD3_FN, PD3_OUT, PD3_IN, PD3_IN_PU,
+		PD2_FN, PD2_OUT, PD2_IN, PD2_IN_PU,
+		PD1_FN, PD1_OUT, PD1_IN, PD1_IN_PU,
+		PD0_FN, PD0_OUT, PD0_IN, PD0_IN_PU, },
+	},
+	{ PINMUX_CFG_REG("PEFCR", 0xffc70008, 32, 2) {
+		PE7_FN, PE7_OUT, PE7_IN, PE7_IN_PU,
+		PE6_FN, PE6_OUT, PE6_IN, PE6_IN_PU,
+		PE5_FN, PE5_OUT, PE5_IN, PE5_IN_PU,
+		PE4_FN, PE4_OUT, PE4_IN, PE4_IN_PU,
+		PE3_FN, PE3_OUT, PE3_IN, PE3_IN_PU,
+		PE2_FN, PE2_OUT, PE2_IN, PE2_IN_PU,
+		PE1_FN, PE1_OUT, PE1_IN, PE1_IN_PU,
+		PE0_FN, PE0_OUT, PE0_IN, PE0_IN_PU,
+		PF7_FN, PF7_OUT, PF7_IN, PF7_IN_PU,
+		PF6_FN, PF6_OUT, PF6_IN, PF6_IN_PU,
+		PF5_FN, PF5_OUT, PF5_IN, PF5_IN_PU,
+		PF4_FN, PF4_OUT, PF4_IN, PF4_IN_PU,
+		PF3_FN, PF3_OUT, PF3_IN, PF3_IN_PU,
+		PF2_FN, PF2_OUT, PF2_IN, PF2_IN_PU,
+		PF1_FN, PF1_OUT, PF1_IN, PF1_IN_PU,
+		PF0_FN, PF0_OUT, PF0_IN, PF0_IN_PU, },
+	},
+	{ PINMUX_CFG_REG("PGHCR", 0xffc7000c, 32, 2) {
+		PG7_FN, PG7_OUT, PG7_IN, PG7_IN_PU,
+		PG6_FN, PG6_OUT, PG6_IN, PG6_IN_PU,
+		PG5_FN, PG5_OUT, PG5_IN, PG5_IN_PU,
+		PG4_FN, PG4_OUT, PG4_IN, PG4_IN_PU,
+		PG3_FN, PG3_OUT, PG3_IN, PG3_IN_PU,
+		PG2_FN, PG2_OUT, PG2_IN, PG2_IN_PU,
+		PG1_FN, PG1_OUT, PG1_IN, PG1_IN_PU,
+		PG0_FN, PG0_OUT, PG0_IN, PG0_IN_PU,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		PH5_FN, PH5_OUT, PH5_IN, PH5_IN_PU,
+		PH4_FN, PH4_OUT, PH4_IN, PH4_IN_PU,
+		PH3_FN, PH3_OUT, PH3_IN, PH3_IN_PU,
+		PH2_FN, PH2_OUT, PH2_IN, PH2_IN_PU,
+		PH1_FN, PH1_OUT, PH1_IN, PH1_IN_PU,
+		PH0_FN, PH0_OUT, PH0_IN, PH0_IN_PU, },
+	},
+	{ },
+};
+
+static struct pinmux_data_reg shx3_pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PABDR", 0xffc70010, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+		PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+		PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA, },
+	},
+	{ PINMUX_DATA_REG("PCDDR", 0xffc70014, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+		PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+		PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA, },
+	},
+	{ PINMUX_DATA_REG("PEFDR", 0xffc70018, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+		PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+		PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA, },
+	},
+	{ PINMUX_DATA_REG("PGHDR", 0xffc7001c, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+		PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, PH5_DATA, PH4_DATA,
+		PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA, },
+	},
+	{ },
+};
+
+static struct pinmux_info shx3_pinmux_info = {
+	.name		= "shx3_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_PA7,
+	.last_gpio	= GPIO_FN_IRQOUT,
+	.gpios		= shx3_pinmux_gpios,
+	.gpio_data	= shx3_pinmux_data,
+	.gpio_data_size	= ARRAY_SIZE(shx3_pinmux_data),
+	.cfg_regs	= shx3_pinmux_config_regs,
+	.data_regs	= shx3_pinmux_data_regs,
+};
+
+static int __init shx3_pinmux_setup(void)
+{
+	return register_pinmux(&shx3_pinmux_info);
+}
+arch_initcall(shx3_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 79c556e..828c965 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -524,6 +524,70 @@
 	},
 };
 
+/* BEU0 */
+static struct uio_info beu0_platform_data = {
+	.name = "BEU0",
+	.version = "0",
+	.irq = evt2irq(0x8A0),
+};
+
+static struct resource beu0_resources[] = {
+	[0] = {
+		.name	= "BEU0",
+		.start	= 0xfe930000,
+		.end	= 0xfe933400,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device beu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 6,
+	.dev = {
+		.platform_data	= &beu0_platform_data,
+	},
+	.resource	= beu0_resources,
+	.num_resources	= ARRAY_SIZE(beu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_BEU0,
+	},
+};
+
+/* BEU1 */
+static struct uio_info beu1_platform_data = {
+	.name = "BEU1",
+	.version = "0",
+	.irq = evt2irq(0xA00),
+};
+
+static struct resource beu1_resources[] = {
+	[0] = {
+		.name	= "BEU1",
+		.start	= 0xfe940000,
+		.end	= 0xfe943400,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device beu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 7,
+	.dev = {
+		.platform_data	= &beu1_platform_data,
+	},
+	.resource	= beu1_resources,
+	.num_resources	= ARRAY_SIZE(beu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_BEU1,
+	},
+};
+
 static struct sh_timer_config cmt_platform_data = {
 	.channel_offset = 0x60,
 	.timer_bit = 5,
@@ -857,6 +921,8 @@
 	&vpu_device,
 	&veu0_device,
 	&veu1_device,
+	&beu0_device,
+	&beu1_device,
 	&jpu_device,
 	&spu0_device,
 	&spu1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 444aca9..749c638 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -26,7 +26,7 @@
 
 static struct platform_device scif2_device = {
 	.name		= "sh-sci",
-	.id		= 2,
+	.id		= 0,
 	.dev		= {
 		.platform_data	= &scif2_platform_data,
 	},
@@ -41,7 +41,7 @@
 
 static struct platform_device scif3_device = {
 	.name		= "sh-sci",
-	.id		= 3,
+	.id		= 1,
 	.dev		= {
 		.platform_data	= &scif3_platform_data,
 	},
@@ -56,7 +56,7 @@
 
 static struct platform_device scif4_device = {
 	.name		= "sh-sci",
-	.id		= 4,
+	.id		= 2,
 	.dev		= {
 		.platform_data	= &scif4_platform_data,
 	},
@@ -163,39 +163,23 @@
 	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,
+	SDHI, DVC,
+	IRQ8, IRQ9, IRQ11, IRQ10, IRQ12, IRQ13, IRQ14, IRQ15,
+	TMU0, TMU1, TMU2, TMU2_TICPI, TMU3, TMU4, TMU5,
 	HUDI,
-
 	ARC4,
-	DMAC0,
-	IRQ11,
-	SCIF2,
-	DMAC1_6,
-	USB0,
-	IRQ12,
+	DMAC0_5, DMAC6_7, DMAC8_11,
+	SCIF0, SCIF1, SCIF2, SCIF3, SCIF4,
+	USB0, USB1,
 	JMC,
-	SPI1,
-	IRQ13, IRQ14,
-	USB1,
+	SPI0, SPI1,
 	TMR01, TMR23, TMR45,
-	WDT1,
 	FRT,
-	LPC,
-	SCIF0, SCIF1, SCIF3,
-	PECI0I, PECI1I, PECI2I,
-	IRQ15,
+	LPC, LPC5, LPC6, LPC7, LPC8,
+	PECI0, PECI1, PECI2, PECI3, PECI4, PECI5,
 	ETHERC,
-	SPI0,
-	ADC1,
-	DMAC1_8,
+	ADC0, ADC1,
 	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,
@@ -206,9 +190,23 @@
 	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,
+	ONFICTL,
+	MMC1, MMC2,
+	ECCU,
+	PCIC,
+	G200,
+	RSPI,
 	SGPIO,
+	DMINT12, DMINT13, DMINT14, DMINT15, DMINT16, DMINT17, DMINT18, DMINT19,
+	DMINT20, DMINT21, DMINT22, DMINT23,
+	DDRECC,
+	TSIP,
+	PCIE_BRIDGE,
+	WDT0B, WDT1B, WDT2B, WDT3B, WDT4B, WDT5B, WDT6B, WDT7B, WDT8B,
+	GETHER0, GETHER1, GETHER2,
+	PBIA, PBIB, PBIC,
+	DMAE2, DMAE3,
+	SERMUX2, SERMUX3,
 
 	/* interrupt groups */
 
@@ -221,19 +219,18 @@
 	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(DMAC0_5, 0x640), INTC_VECT(DMAC0_5, 0x660),
+	INTC_VECT(DMAC0_5, 0x680), INTC_VECT(DMAC0_5, 0x6a0),
+	INTC_VECT(DMAC0_5, 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(DMAC0_5, 0x780), INTC_VECT(DMAC0_5, 0x7a0),
+	INTC_VECT(DMAC6_7, 0x7c0), INTC_VECT(DMAC6_7, 0x7e0),
 	INTC_VECT(USB0, 0x840),
 	INTC_VECT(IRQ12, 0x880),
 	INTC_VECT(JMC, 0x8a0),
@@ -242,7 +239,6 @@
 	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),
@@ -250,14 +246,14 @@
 	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(PECI0, 0xc00), INTC_VECT(PECI1, 0xc20),
+	INTC_VECT(PECI2, 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(DMAC8_11, 0xd00), INTC_VECT(DMAC8_11, 0xd20),
+	INTC_VECT(DMAC8_11, 0xd40), INTC_VECT(DMAC8_11, 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),
@@ -278,17 +274,47 @@
 	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(IIC6_2, 0x1920),
+	INTC_VECT(ONFICTL, 0x1960),
+	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),
+	INTC_VECT(MMC1, 0x1c60), INTC_VECT(MMC2, 0x1c80),
+	INTC_VECT(ECCU, 0x1cc0),
+	INTC_VECT(PCIC, 0x1ce0),
+	INTC_VECT(G200, 0x1d00),
+	INTC_VECT(RSPI, 0x1d80), INTC_VECT(RSPI, 0x1da0),
+	INTC_VECT(RSPI, 0x1dc0), INTC_VECT(RSPI, 0x1de0),
+	INTC_VECT(PECI3, 0x1ec0), INTC_VECT(PECI4, 0x1ee0),
+	INTC_VECT(PECI5, 0x1f00),
+	INTC_VECT(SGPIO, 0x1f80), INTC_VECT(SGPIO, 0x1fa0),
+	INTC_VECT(SGPIO, 0x1fc0),
+	INTC_VECT(DMINT12, 0x2400), INTC_VECT(DMINT13, 0x2420),
+	INTC_VECT(DMINT14, 0x2440), INTC_VECT(DMINT15, 0x2460),
+	INTC_VECT(DMINT16, 0x2480), INTC_VECT(DMINT17, 0x24e0),
+	INTC_VECT(DMINT18, 0x2500), INTC_VECT(DMINT19, 0x2520),
+	INTC_VECT(DMINT20, 0x2540), INTC_VECT(DMINT21, 0x2560),
+	INTC_VECT(DMINT22, 0x2580), INTC_VECT(DMINT23, 0x2600),
+	INTC_VECT(DDRECC, 0x2620),
+	INTC_VECT(TSIP, 0x2640),
+	INTC_VECT(PCIE_BRIDGE, 0x27c0),
+	INTC_VECT(WDT0B, 0x2800), INTC_VECT(WDT1B, 0x2820),
+	INTC_VECT(WDT2B, 0x2840), INTC_VECT(WDT3B, 0x2860),
+	INTC_VECT(WDT4B, 0x2880), INTC_VECT(WDT5B, 0x28a0),
+	INTC_VECT(WDT6B, 0x28c0), INTC_VECT(WDT7B, 0x28e0),
+	INTC_VECT(WDT8B, 0x2900),
+	INTC_VECT(GETHER0, 0x2960), INTC_VECT(GETHER1, 0x2980),
+	INTC_VECT(GETHER2, 0x29a0),
+	INTC_VECT(PBIA, 0x2a00), INTC_VECT(PBIB, 0x2a20),
+	INTC_VECT(PBIC, 0x2a40),
+	INTC_VECT(DMAE2, 0x2a60), INTC_VECT(DMAE3, 0x2a80),
+	INTC_VECT(SERMUX2, 0x2aa0), INTC_VECT(SERMUX3, 0x2b40),
+	INTC_VECT(LPC5, 0x2b60), INTC_VECT(LPC6, 0x2b80),
+	INTC_VECT(LPC7, 0x2c00), INTC_VECT(LPC8, 0x2c20),
 };
 
 static struct intc_group groups[] __initdata = {
@@ -312,31 +338,45 @@
 
 	{ 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
+	    0, DMAC8_11, 0, PECI0, LPC, FRT, 0, TMR45,
+	    TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0_5,
+	    HUDI, 0, 0, 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,
+	    ADC1, 0, DMAC6_7, ADC0, SPI0, SIM, PECI2, PECI1,
 	    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,
+	  { IIC4_1, IIC4_2, IIC5_0, ONFICTL, 0, 0, SGPIO, 0,
+	    0, G200, 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
+	    IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, 0, IIC2_2
 	     } },
 
-	{ 0xffd100d0, 0xff1400d4, 32, /* INT2MSKR3 / INT2MSKCR4 */
-	  { 0, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, 0, 0,
+	{ 0xffd100d0, 0xffd100d4, 32, /* INT2MSKR3 / INT2MSKCR3 */
+	  { MMC1, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, PECI5, MMC2,
 	    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,
+	    PCIC, 0, IIC4_0, 0, ECCU, RSPI, 0, IIC9_3,
 	    IIC3_0, 0, IIC5_3, IIC5_2, 0, 0, 0, IIC1_1
 	     } },
+
+	{ 0xffd20038, 0xffd2003c, 32, /* INT2MSKR4 / INT2MSKCR4 */
+	  { WDT0B, WDT1B, WDT3B, GETHER0, 0, 0, 0, 0,
+	    0, 0, 0, LPC7, SERMUX2, DMAE3, DMAE2, PBIC,
+	    PBIB, PBIA, GETHER1, DMINT12, DMINT13, DMINT14, DMINT15, TSIP,
+	    DMINT23, 0, DMINT21, LPC6, 0, DMINT16, 0, DMINT22
+	     } },
+
+	{ 0xffd200d0, 0xffd200d4, 32, /* INT2MSKR5 / INT2MSKCR5 */
+	  { 0, WDT8B, WDT7B, WDT4B, 0, DMINT20, 0, 0,
+	    DMINT19, DMINT18, LPC5, SERMUX3, WDT2B, GETHER2, 0, 0,
+	    0, 0, PCIE_BRIDGE, 0, 0, 0, 0, LPC8,
+	    DDRECC, 0, WDT6B, WDT5B, 0, 0, 0, DMINT17
+	     } },
 };
 
 #define INTPRI		0xffd00010
@@ -372,6 +412,22 @@
 #define INT2PRI29	0xffd100b4
 #define INT2PRI30	0xffd100b8
 #define INT2PRI31	0xffd100bc
+#define INT2PRI32	0xffd20000
+#define INT2PRI33	0xffd20004
+#define INT2PRI34	0xffd20008
+#define INT2PRI35	0xffd2000c
+#define INT2PRI36	0xffd20010
+#define INT2PRI37	0xffd20014
+#define INT2PRI38	0xffd20018
+#define INT2PRI39	0xffd2001c
+#define INT2PRI40	0xffd200a0
+#define INT2PRI41	0xffd200a4
+#define INT2PRI42	0xffd200a8
+#define INT2PRI43	0xffd200ac
+#define INT2PRI44	0xffd200b0
+#define INT2PRI45	0xffd200b4
+#define INT2PRI46	0xffd200b8
+#define INT2PRI47	0xffd200bc
 
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ INTPRI, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
@@ -379,39 +435,61 @@
 
 	{ 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 } },
+	{ INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, 0, IRQ8 } },
+	{ INT2PRI3, 0, 32, 8, { HUDI, DMAC0_5, 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 } },
+	{ INT2PRI5, 0, 32, 8, { TMR45, 0, FRT, LPC } },
+	{ INT2PRI6, 0, 32, 8, { PECI0, ETHERC, DMAC8_11, 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 } },
+	{ INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2, PECI1 } },
+	{ INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC6_7, 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 } },
+	{ INT2PRI17, 0, 32, 8, { 0, 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 } },
+	{ INT2PRI22, 0, 32, 8, { IIC9_2, MMC2, G200, 0 } },
+	{ INT2PRI23, 0, 32, 8, { PECI5, SGPIO, IIC3_2, IIC5_1 } },
+	{ INT2PRI24, 0, 32, 8, { PECI4, PECI3, 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 } },
+	{ INT2PRI26, 0, 32, 8, { ECCU, RSPI, 0, IIC9_3 } },
+	{ INT2PRI27, 0, 32, 8, { PCIC, IIC6_0, IIC4_0, IIC6_1 } },
+	{ INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, MMC1, IIC6_2 } },
 	{ INT2PRI29, 0, 32, 8, { 0, 0, IIC9_0, IIC8_3 } },
-	{ INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, 0 } },
+	{ INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, ONFICTL } },
 	{ INT2PRI31, 0, 32, 8, { IIC0_0, IIC0_1, IIC0_2, IIC0_3 } },
+	{ INT2PRI32, 0, 32, 8, { DMINT22, 0, 0, 0 } },
+	{ INT2PRI33, 0, 32, 8, { 0, 0, 0, DMINT16 } },
+	{ INT2PRI34, 0, 32, 8, { 0, LPC6, DMINT21, DMINT18 } },
+	{ INT2PRI35, 0, 32, 8, { DMINT23, TSIP, 0, DMINT19 } },
+	{ INT2PRI36, 0, 32, 8, { DMINT20, GETHER1, PBIA, PBIB } },
+	{ INT2PRI37, 0, 32, 8, { PBIC, DMAE2, DMAE3, SERMUX2 } },
+	{ INT2PRI38, 0, 32, 8, { LPC7, 0, 0, 0 } },
+	{ INT2PRI39, 0, 32, 8, { 0, 0, 0, WDT4B } },
+	{ INT2PRI40, 0, 32, 8, { 0, 0, 0, DMINT17 } },
+	{ INT2PRI41, 0, 32, 8, { DDRECC, 0, WDT6B, WDT5B } },
+	{ INT2PRI42, 0, 32, 8, { 0, 0, 0, LPC8 } },
+	{ INT2PRI43, 0, 32, 8, { 0, WDT7B, PCIE_BRIDGE, WDT8B } },
+	{ INT2PRI44, 0, 32, 8, { WDT2B, GETHER2, 0, 0 } },
+	{ INT2PRI45, 0, 32, 8, { 0, 0, LPC5, SERMUX3 } },
+	{ INT2PRI46, 0, 32, 8, { WDT0B, WDT1B, WDT3B, GETHER0 } },
+	{ INT2PRI47, 0, 32, 8, { DMINT12, DMINT13, DMINT14, DMINT15 } },
+};
+
+static struct intc_sense_reg sense_registers_irq8to15[] __initdata = {
+	{ 0xffd100f8, 32, 2, /* ICR2 */   { IRQ15, IRQ14, IRQ13, IRQ12,
+					    IRQ11, IRQ10, IRQ9, IRQ8 } },
 };
 
 static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups,
-			 mask_registers, prio_registers, NULL);
+			 mask_registers, prio_registers,
+			 sense_registers_irq8to15);
 
 /* Support for external interrupt pins in IRQ mode */
 static struct intc_vect vectors_irq0123[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 8797723..c016c00 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -629,33 +629,10 @@
 	}
 }
 
-static int __init sh7786_devices_setup(void)
-{
-	int ret;
-
-	sh7786_usb_setup();
-
-	ret = platform_add_devices(sh7786_early_devices,
-				   ARRAY_SIZE(sh7786_early_devices));
-	if (unlikely(ret != 0))
-		return ret;
-
-	return platform_add_devices(sh7786_devices,
-				    ARRAY_SIZE(sh7786_devices));
-}
-arch_initcall(sh7786_devices_setup);
-
-void __init plat_early_device_setup(void)
-{
-	early_platform_add_devices(sh7786_early_devices,
-				   ARRAY_SIZE(sh7786_early_devices));
-}
-
 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,
@@ -693,9 +670,12 @@
 	Thermal,
 	INTICI0, INTICI1, INTICI2, INTICI3,
 	INTICI4, INTICI5, INTICI6, INTICI7,
+
+	/* Muxed sub-events */
+	TXI1, BRI1, RXI1, ERI1,
 };
 
-static struct intc_vect vectors[] __initdata = {
+static struct intc_vect sh7786_vectors[] __initdata = {
 	INTC_VECT(WDT, 0x3e0),
 	INTC_VECT(TMU0_0, 0x400), INTC_VECT(TMU0_1, 0x420),
 	INTC_VECT(TMU0_2, 0x440), INTC_VECT(TMU0_3, 0x460),
@@ -756,14 +736,12 @@
 
 #define INTDISTCR0	0xfe4100b0
 #define INTDISTCR1	0xfe4100b4
-#define INTACK		0xfe4100b8
-#define INTACKCLR	0xfe4100bc
 #define INT2DISTCR0	0xfe410900
 #define INT2DISTCR1	0xfe410904
 #define INT2DISTCR2	0xfe410908
 #define INT2DISTCR3	0xfe41090c
 
-static struct intc_mask_reg mask_registers[] __initdata = {
+static struct intc_mask_reg sh7786_mask_registers[] __initdata = {
 	{ CnINTMSK0, CnINTMSKCLR0, 32,
 	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 },
 	    INTC_SMP_BALANCING(INTDISTCR0) },
@@ -807,7 +785,7 @@
 	    0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) },
 };
 
-static struct intc_prio_reg prio_registers[] __initdata = {
+static struct intc_prio_reg sh7786_prio_registers[] __initdata = {
 	{ 0xfe410010, 0, 32, 4, /* INTPRI */   { IRQ0, IRQ1, IRQ2, IRQ3,
 						 IRQ4, IRQ5, IRQ6, IRQ7 } },
 	{ 0xfe410800, 0, 32, 8, /* INT2PRI0 */ { 0, 0, 0, WDT } },
@@ -851,11 +829,27 @@
 	    INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 2) },
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,
-			 mask_registers, prio_registers, NULL);
+static struct intc_subgroup sh7786_subgroups[] __initdata = {
+	{ 0xfe410c20, 32, SCIF1,
+	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TXI1, BRI1, RXI1, ERI1 } },
+};
+
+static struct intc_desc sh7786_intc_desc __initdata = {
+	.name		= "sh7786",
+	.hw		= {
+		.vectors	= sh7786_vectors,
+		.nr_vectors	= ARRAY_SIZE(sh7786_vectors),
+		.mask_regs	= sh7786_mask_registers,
+		.nr_mask_regs	= ARRAY_SIZE(sh7786_mask_registers),
+		.subgroups	= sh7786_subgroups,
+		.nr_subgroups	= ARRAY_SIZE(sh7786_subgroups),
+		.prio_regs	= sh7786_prio_registers,
+		.nr_prio_regs	= ARRAY_SIZE(sh7786_prio_registers),
+	},
+};
 
 /* Support for external interrupt pins in IRQ mode */
-
 static struct intc_vect vectors_irq0123[] __initdata = {
 	INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
 	INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
@@ -866,23 +860,25 @@
 	INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
 };
 
-static struct intc_sense_reg sense_registers[] __initdata = {
+static struct intc_sense_reg sh7786_sense_registers[] __initdata = {
 	{ 0xfe41001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
 					    IRQ4, IRQ5, IRQ6, IRQ7 } },
 };
 
-static struct intc_mask_reg ack_registers[] __initdata = {
+static struct intc_mask_reg sh7786_ack_registers[] __initdata = {
 	{ 0xfe410024, 0, 32, /* INTREQ */
 	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 };
 
 static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7786-irq0123",
-			     vectors_irq0123, NULL, mask_registers,
-			     prio_registers, sense_registers, ack_registers);
+			     vectors_irq0123, NULL, sh7786_mask_registers,
+			     sh7786_prio_registers, sh7786_sense_registers,
+			     sh7786_ack_registers);
 
 static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7786-irq4567",
-			     vectors_irq4567, NULL, mask_registers,
-			     prio_registers, sense_registers, ack_registers);
+			     vectors_irq4567, NULL, sh7786_mask_registers,
+			     sh7786_prio_registers, sh7786_sense_registers,
+			     sh7786_ack_registers);
 
 /* External interrupt pins in IRL mode */
 
@@ -909,10 +905,10 @@
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7786-irl0123", vectors_irl0123,
-			 NULL, mask_registers, NULL, NULL);
+			 NULL, sh7786_mask_registers, NULL, NULL);
 
 static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
-			 NULL, mask_registers, NULL, NULL);
+			 NULL, sh7786_mask_registers, NULL, NULL);
 
 #define INTC_ICR0	0xfe410000
 #define INTC_INTMSK0	CnINTMSK0
@@ -920,19 +916,6 @@
 #define INTC_INTMSK2	INTMSK2
 #define INTC_INTMSKCLR1	CnINTMSKCLR1
 #define INTC_INTMSKCLR2	INTMSKCLR2
-#define INTC_USERIMASK	0xfe411000
-
-#ifdef CONFIG_INTC_BALANCING
-unsigned int irq_lookup(unsigned int irq)
-{
-	return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
-}
-
-void irq_finish(unsigned int irq)
-{
-	__raw_writel(irq2evt(irq), INTACKCLR);
-}
-#endif
 
 void __init plat_irq_setup(void)
 {
@@ -946,8 +929,7 @@
 	/* select IRL mode for IRL3-0 + IRL7-4 */
 	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
-	register_intc_controller(&intc_desc);
-	register_intc_userimask(INTC_USERIMASK);
+	register_intc_controller(&sh7786_intc_desc);
 }
 
 void __init plat_irq_setup_pins(int mode)
@@ -991,3 +973,39 @@
 void __init plat_mem_setup(void)
 {
 }
+
+static int __init sh7786_devices_setup(void)
+{
+	int ret, irq;
+
+	sh7786_usb_setup();
+
+	/*
+	 * De-mux SCIF1 IRQs if possible
+	 */
+	irq = intc_irq_lookup(sh7786_intc_desc.name, TXI1);
+	if (irq > 0) {
+		scif1_platform_data.irqs[SCIx_TXI_IRQ] = irq;
+		scif1_platform_data.irqs[SCIx_ERI_IRQ] =
+			intc_irq_lookup(sh7786_intc_desc.name, ERI1);
+		scif1_platform_data.irqs[SCIx_BRI_IRQ] =
+			intc_irq_lookup(sh7786_intc_desc.name, BRI1);
+		scif1_platform_data.irqs[SCIx_RXI_IRQ] =
+			intc_irq_lookup(sh7786_intc_desc.name, RXI1);
+	}
+
+	ret = platform_add_devices(sh7786_early_devices,
+				   ARRAY_SIZE(sh7786_early_devices));
+	if (unlikely(ret != 0))
+		return ret;
+
+	return platform_add_devices(sh7786_devices,
+				    ARRAY_SIZE(sh7786_devices));
+}
+arch_initcall(sh7786_devices_setup);
+
+void __init plat_early_device_setup(void)
+{
+	early_platform_add_devices(sh7786_early_devices,
+				   ARRAY_SIZE(sh7786_early_devices));
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 9158bc5..013f0b1 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -1,7 +1,7 @@
 /*
  * SH-X3 Prototype Setup
  *
- *  Copyright (C) 2007 - 2009  Paul Mundt
+ *  Copyright (C) 2007 - 2010  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
@@ -12,7 +12,9 @@
 #include <linux/serial.h>
 #include <linux/serial_sci.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/sh_timer.h>
+#include <cpu/shx3.h>
 #include <asm/mmzone.h>
 
 /*
@@ -354,6 +356,10 @@
 		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
 };
 
+#define INT2DISTCR0	0xfe4108a0
+#define INT2DISTCR1	0xfe4108a4
+#define INT2DISTCR2	0xfe4108a8
+
 static struct intc_mask_reg mask_registers[] __initdata = {
 	{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
 	  { IRQ0, IRQ1, IRQ2, IRQ3 } },
@@ -363,20 +369,23 @@
 	  { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
 	    DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
 	    0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
-	    0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } },
+	    0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
+	    INTC_SMP_BALANCING(INT2DISTCR0) },
 	{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
 	  { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
 	    PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
 	    PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
 	    DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
 	    DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
-	    DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } },
+	    DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
+	    INTC_SMP_BALANCING(INT2DISTCR1) },
 	{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
 	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	    SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
 	    SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
 	    SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
-	    SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } },
+	    SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
+	    INTC_SMP_BALANCING(INT2DISTCR2) },
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -433,11 +442,33 @@
 
 void __init plat_irq_setup_pins(int mode)
 {
+	int ret = 0;
+
 	switch (mode) {
 	case IRQ_MODE_IRQ:
+		ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
+		ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
+		ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
+		ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
+
+		if (unlikely(ret)) {
+			pr_err("Failed to set IRQ mode\n");
+			return;
+		}
+
 		register_intc_controller(&intc_desc_irq);
 		break;
 	case IRQ_MODE_IRL3210:
+		ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
+		ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
+		ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
+		ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
+
+		if (unlikely(ret)) {
+			pr_err("Failed to set IRL mode\n");
+			return;
+		}
+
 		register_intc_controller(&intc_desc_irl);
 		break;
 	default:
@@ -447,6 +478,9 @@
 
 void __init plat_irq_setup(void)
 {
+	reserve_intc_vectors(vectors_irq, ARRAY_SIZE(vectors_irq));
+	reserve_intc_vectors(vectors_irl, ARRAY_SIZE(vectors_irl));
+
 	register_intc_controller(&intc_desc);
 }
 
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 6e35f01..7db2489 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -330,7 +330,7 @@
 #if defined(CONFIG_CPU_SH2)
 1:	.long	0x000000F0		! IMASK=0xF
 #else
-1:	.long	0x400080F0		! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
+1:	.long	0x500080F0		! MD=1, RB=0, BL=1, FD=1, IMASK=0xF
 #endif
 ENTRY(stack_start)
 2:	.long	init_thread_union+THREAD_SIZE
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 2947d2b..32c385e 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -291,7 +291,7 @@
 	}
 
 	tmp = handle_unaligned_access(instruction, regs,
-				      &trapped_io_access, 1);
+				      &trapped_io_access, 1, address);
 	set_fs(oldfs);
 	return tmp == 0;
 }
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index ae5bac3..9dc447d 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -283,6 +283,8 @@
 	if (sh_mv.mv_init_irq)
 		sh_mv.mv_init_irq();
 
+	intc_finalize();
+
 	irq_ctx_init(smp_processor_id());
 }
 
diff --git a/arch/sh/kernel/kdebugfs.c b/arch/sh/kernel/kdebugfs.c
new file mode 100644
index 0000000..e11c30b
--- /dev/null
+++ b/arch/sh/kernel/kdebugfs.c
@@ -0,0 +1,16 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+
+struct dentry *arch_debugfs_dir;
+EXPORT_SYMBOL(arch_debugfs_dir);
+
+static int __init arch_kdebugfs_init(void)
+{
+	arch_debugfs_dir = debugfs_create_dir("sh", NULL);
+	if (!arch_debugfs_dir)
+		return -ENOMEM;
+
+	return 0;
+}
+arch_initcall(arch_kdebugfs_init);
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index 4049d99..1208b09 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -20,9 +20,9 @@
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
-static struct kprobe saved_current_opcode;
-static struct kprobe saved_next_opcode;
-static struct kprobe saved_next_opcode2;
+static DEFINE_PER_CPU(struct kprobe, saved_current_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
 
 #define OPCODE_JMP(x)	(((x) & 0xF0FF) == 0x402b)
 #define OPCODE_JSR(x)	(((x) & 0xF0FF) == 0x400b)
@@ -102,16 +102,21 @@
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
-	if (saved_next_opcode.addr != 0x0) {
-		arch_disarm_kprobe(p);
-		arch_disarm_kprobe(&saved_next_opcode);
-		saved_next_opcode.addr = 0x0;
-		saved_next_opcode.opcode = 0x0;
+	struct kprobe *saved = &__get_cpu_var(saved_next_opcode);
 
-		if (saved_next_opcode2.addr != 0x0) {
-			arch_disarm_kprobe(&saved_next_opcode2);
-			saved_next_opcode2.addr = 0x0;
-			saved_next_opcode2.opcode = 0x0;
+	if (saved->addr) {
+		arch_disarm_kprobe(p);
+		arch_disarm_kprobe(saved);
+
+		saved->addr = NULL;
+		saved->opcode = 0;
+
+		saved = &__get_cpu_var(saved_next_opcode2);
+		if (saved->addr) {
+			arch_disarm_kprobe(saved);
+
+			saved->addr = NULL;
+			saved->opcode = 0;
 		}
 	}
 }
@@ -141,57 +146,59 @@
  */
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
-	kprobe_opcode_t *addr = NULL;
-	saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
-	addr = saved_current_opcode.addr;
+	__get_cpu_var(saved_current_opcode).addr = (kprobe_opcode_t *)regs->pc;
 
 	if (p != NULL) {
+		struct kprobe *op1, *op2;
+
 		arch_disarm_kprobe(p);
 
+		op1 = &__get_cpu_var(saved_next_opcode);
+		op2 = &__get_cpu_var(saved_next_opcode2);
+
 		if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
 			unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
-			saved_next_opcode.addr =
-			    (kprobe_opcode_t *) regs->regs[reg_nr];
+			op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
 		} else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
 			unsigned long disp = (p->opcode & 0x0FFF);
-			saved_next_opcode.addr =
+			op1->addr =
 			    (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
 
 		} else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
 			unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
-			saved_next_opcode.addr =
+			op1->addr =
 			    (kprobe_opcode_t *) (regs->pc + 4 +
 						 regs->regs[reg_nr]);
 
 		} else if (OPCODE_RTS(p->opcode)) {
-			saved_next_opcode.addr = (kprobe_opcode_t *) regs->pr;
+			op1->addr = (kprobe_opcode_t *) regs->pr;
 
 		} else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
 			unsigned long disp = (p->opcode & 0x00FF);
 			/* case 1 */
-			saved_next_opcode.addr = p->addr + 1;
+			op1->addr = p->addr + 1;
 			/* case 2 */
-			saved_next_opcode2.addr =
+			op2->addr =
 			    (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
-			saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
-			arch_arm_kprobe(&saved_next_opcode2);
+			op2->opcode = *(op2->addr);
+			arch_arm_kprobe(op2);
 
 		} else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
 			unsigned long disp = (p->opcode & 0x00FF);
 			/* case 1 */
-			saved_next_opcode.addr = p->addr + 2;
+			op1->addr = p->addr + 2;
 			/* case 2 */
-			saved_next_opcode2.addr =
+			op2->addr =
 			    (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
-			saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
-			arch_arm_kprobe(&saved_next_opcode2);
+			op2->opcode = *(op2->addr);
+			arch_arm_kprobe(op2);
 
 		} else {
-			saved_next_opcode.addr = p->addr + 1;
+			op1->addr = p->addr + 1;
 		}
 
-		saved_next_opcode.opcode = *(saved_next_opcode.addr);
-		arch_arm_kprobe(&saved_next_opcode);
+		op1->opcode = *(op1->addr);
+		arch_arm_kprobe(op1);
 	}
 }
 
@@ -376,21 +383,23 @@
 		cur->post_handler(cur, regs, 0);
 	}
 
-	if (saved_next_opcode.addr != 0x0) {
-		arch_disarm_kprobe(&saved_next_opcode);
-		saved_next_opcode.addr = 0x0;
-		saved_next_opcode.opcode = 0x0;
+	p = &__get_cpu_var(saved_next_opcode);
+	if (p->addr) {
+		arch_disarm_kprobe(p);
+		p->addr = NULL;
+		p->opcode = 0;
 
-		addr = saved_current_opcode.addr;
-		saved_current_opcode.addr = 0x0;
+		addr = __get_cpu_var(saved_current_opcode).addr;
+		__get_cpu_var(saved_current_opcode).addr = NULL;
 
 		p = get_kprobe(addr);
 		arch_arm_kprobe(p);
 
-		if (saved_next_opcode2.addr != 0x0) {
-			arch_disarm_kprobe(&saved_next_opcode2);
-			saved_next_opcode2.addr = 0x0;
-			saved_next_opcode2.opcode = 0x0;
+		p = &__get_cpu_var(saved_next_opcode2);
+		if (p->addr) {
+			arch_disarm_kprobe(p);
+			p->addr = NULL;
+			p->opcode = 0;
 		}
 	}
 
@@ -572,14 +581,5 @@
 
 int __init arch_init_kprobes(void)
 {
-	saved_next_opcode.addr = 0x0;
-	saved_next_opcode.opcode = 0x0;
-
-	saved_current_opcode.addr = 0x0;
-	saved_current_opcode.opcode = 0x0;
-
-	saved_next_opcode2.addr = 0x0;
-	saved_next_opcode2.opcode = 0x0;
-
 	return register_kprobe(&trampoline_p);
 }
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
new file mode 100644
index 0000000..0a05983
--- /dev/null
+++ b/arch/sh/kernel/ptrace.c
@@ -0,0 +1,33 @@
+#include <linux/ptrace.h>
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:	the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->offset;
+	return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:	the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (roff->offset == offset)
+			return roff->name;
+	return NULL;
+}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 6c4bbba..2cd42b5 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -274,6 +274,33 @@
 }
 #endif
 
+const struct pt_regs_offset regoffset_table[] = {
+	REGS_OFFSET_NAME(0),
+	REGS_OFFSET_NAME(1),
+	REGS_OFFSET_NAME(2),
+	REGS_OFFSET_NAME(3),
+	REGS_OFFSET_NAME(4),
+	REGS_OFFSET_NAME(5),
+	REGS_OFFSET_NAME(6),
+	REGS_OFFSET_NAME(7),
+	REGS_OFFSET_NAME(8),
+	REGS_OFFSET_NAME(9),
+	REGS_OFFSET_NAME(10),
+	REGS_OFFSET_NAME(11),
+	REGS_OFFSET_NAME(12),
+	REGS_OFFSET_NAME(13),
+	REGS_OFFSET_NAME(14),
+	REGS_OFFSET_NAME(15),
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(pr),
+	REG_OFFSET_NAME(sr),
+	REG_OFFSET_NAME(gbr),
+	REG_OFFSET_NAME(mach),
+	REG_OFFSET_NAME(macl),
+	REG_OFFSET_NAME(tra),
+	REG_OFFSET_END,
+};
+
 /*
  * These are our native regset flavours.
  */
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5fd644d..e0fb065 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -20,7 +20,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
@@ -252,6 +252,85 @@
 }
 #endif
 
+const struct pt_regs_offset regoffset_table[] = {
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(sr),
+	REG_OFFSET_NAME(syscall_nr),
+	REGS_OFFSET_NAME(0),
+	REGS_OFFSET_NAME(1),
+	REGS_OFFSET_NAME(2),
+	REGS_OFFSET_NAME(3),
+	REGS_OFFSET_NAME(4),
+	REGS_OFFSET_NAME(5),
+	REGS_OFFSET_NAME(6),
+	REGS_OFFSET_NAME(7),
+	REGS_OFFSET_NAME(8),
+	REGS_OFFSET_NAME(9),
+	REGS_OFFSET_NAME(10),
+	REGS_OFFSET_NAME(11),
+	REGS_OFFSET_NAME(12),
+	REGS_OFFSET_NAME(13),
+	REGS_OFFSET_NAME(14),
+	REGS_OFFSET_NAME(15),
+	REGS_OFFSET_NAME(16),
+	REGS_OFFSET_NAME(17),
+	REGS_OFFSET_NAME(18),
+	REGS_OFFSET_NAME(19),
+	REGS_OFFSET_NAME(20),
+	REGS_OFFSET_NAME(21),
+	REGS_OFFSET_NAME(22),
+	REGS_OFFSET_NAME(23),
+	REGS_OFFSET_NAME(24),
+	REGS_OFFSET_NAME(25),
+	REGS_OFFSET_NAME(26),
+	REGS_OFFSET_NAME(27),
+	REGS_OFFSET_NAME(28),
+	REGS_OFFSET_NAME(29),
+	REGS_OFFSET_NAME(30),
+	REGS_OFFSET_NAME(31),
+	REGS_OFFSET_NAME(32),
+	REGS_OFFSET_NAME(33),
+	REGS_OFFSET_NAME(34),
+	REGS_OFFSET_NAME(35),
+	REGS_OFFSET_NAME(36),
+	REGS_OFFSET_NAME(37),
+	REGS_OFFSET_NAME(38),
+	REGS_OFFSET_NAME(39),
+	REGS_OFFSET_NAME(40),
+	REGS_OFFSET_NAME(41),
+	REGS_OFFSET_NAME(42),
+	REGS_OFFSET_NAME(43),
+	REGS_OFFSET_NAME(44),
+	REGS_OFFSET_NAME(45),
+	REGS_OFFSET_NAME(46),
+	REGS_OFFSET_NAME(47),
+	REGS_OFFSET_NAME(48),
+	REGS_OFFSET_NAME(49),
+	REGS_OFFSET_NAME(50),
+	REGS_OFFSET_NAME(51),
+	REGS_OFFSET_NAME(52),
+	REGS_OFFSET_NAME(53),
+	REGS_OFFSET_NAME(54),
+	REGS_OFFSET_NAME(55),
+	REGS_OFFSET_NAME(56),
+	REGS_OFFSET_NAME(57),
+	REGS_OFFSET_NAME(58),
+	REGS_OFFSET_NAME(59),
+	REGS_OFFSET_NAME(60),
+	REGS_OFFSET_NAME(61),
+	REGS_OFFSET_NAME(62),
+	REGS_OFFSET_NAME(63),
+	TREGS_OFFSET_NAME(0),
+	TREGS_OFFSET_NAME(1),
+	TREGS_OFFSET_NAME(2),
+	TREGS_OFFSET_NAME(3),
+	TREGS_OFFSET_NAME(4),
+	TREGS_OFFSET_NAME(5),
+	TREGS_OFFSET_NAME(6),
+	TREGS_OFFSET_NAME(7),
+	REG_OFFSET_END,
+};
+
 /*
  * These are our native regset flavours.
  */
@@ -395,10 +474,9 @@
 asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
 {
 #define WPC_DBRMODE 0x0d104008
-	static int first_call = 1;
+	static unsigned long first_call;
 
-	lock_kernel();
-	if (first_call) {
+	if (!test_and_set_bit(0, &first_call)) {
 		/* Set WPC.DBRMODE to 0.  This makes all debug events get
 		 * delivered through RESVEC, i.e. into the handlers in entry.S.
 		 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
@@ -408,9 +486,7 @@
 		 * the remote gdb.) */
 		printk("DBRMODE set to 0 to permit native debugging\n");
 		poke_real_address_q(WPC_DBRMODE, 0);
-		first_call = 0;
 	}
-	unlock_kernel();
 
 	return sys_ptrace(request, pid, addr, data);
 }
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index b1fca66..ca6a5ca 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -9,6 +9,7 @@
 #include <asm/addrspace.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <asm/tlbflush.h>
 
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
@@ -25,6 +26,9 @@
 {
 	local_irq_disable();
 
+	/* Destroy all of the TLBs in preparation for reset by MMU */
+	__flush_tlb_global();
+
 	/* Address error with SR.BL=1 first. */
 	trigger_address_error();
 
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e769401..4e27846 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/err.h>
-#include <linux/debugfs.h>
 #include <linux/crash_dump.h>
 #include <linux/mmzone.h>
 #include <linux/clk.h>
@@ -136,8 +135,9 @@
 		goto disable;
 	}
 
-	if (unlikely(start < PAGE_OFFSET)) {
-		pr_err("initrd start < PAGE_OFFSET\n");
+	if (unlikely(start < __MEMORY_START)) {
+		pr_err("initrd start (%08lx) < __MEMORY_START(%x)\n",
+			start, __MEMORY_START);
 		goto disable;
 	}
 
@@ -158,7 +158,7 @@
 	/*
 	 * Address sanitization
 	 */
-	initrd_start = (unsigned long)__va(__pa(start));
+	initrd_start = (unsigned long)__va(start);
 	initrd_end = initrd_start + INITRD_SIZE;
 
 	memblock_reserve(__pa(initrd_start), INITRD_SIZE);
@@ -458,17 +458,3 @@
 	.show	= show_cpuinfo,
 };
 #endif /* CONFIG_PROC_FS */
-
-struct dentry *sh_debugfs_root;
-
-static int __init sh_debugfs_init(void)
-{
-	sh_debugfs_root = debugfs_create_dir("sh", NULL);
-	if (!sh_debugfs_root)
-		return -ENOMEM;
-	if (IS_ERR(sh_debugfs_root))
-		return PTR_ERR(sh_debugfs_root);
-
-	return 0;
-}
-arch_initcall(sh_debugfs_init);
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index 19fd11d..e872e81 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -353,3 +353,25 @@
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
 	.long sys_perf_event_open
+	.long sys_fanotify_init
+	.long sys_fanotify_mark
+	.long sys_prlimit64
+	/* Broken-out socket family */
+	.long sys_socket		/* 340 */
+	.long sys_bind
+	.long sys_connect
+	.long sys_listen
+	.long sys_accept
+	.long sys_getsockname	/* 345 */
+	.long sys_getpeername
+	.long sys_socketpair
+	.long sys_send
+	.long sys_sendto
+	.long sys_recv			/* 350 */
+	.long sys_recvfrom
+	.long sys_shutdown
+	.long sys_setsockopt
+	.long sys_getsockopt
+	.long sys_sendmsg		/* 355 */
+	.long sys_recvmsg
+	.long sys_recvmmsg
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index 2048a20..6658570 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -393,3 +393,6 @@
 	.long sys_perf_event_open
 	.long sys_recvmmsg		/* 365 */
 	.long sys_accept4
+	.long sys_fanotify_init
+	.long sys_fanotify_mark
+	.long sys_prlimit64
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index c3d86fa..3484c2f 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -5,7 +5,7 @@
  *  SuperH version: Copyright (C) 1999 Niibe Yutaka
  *                  Copyright (C) 2000 Philipp Rumpf
  *                  Copyright (C) 2000 David Howells
- *                  Copyright (C) 2002 - 2007 Paul Mundt
+ *                  Copyright (C) 2002 - 2010 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
@@ -26,6 +26,7 @@
 #include <linux/limits.h>
 #include <linux/sysfs.h>
 #include <linux/uaccess.h>
+#include <linux/perf_event.h>
 #include <asm/system.h>
 #include <asm/alignment.h>
 #include <asm/fpu.h>
@@ -369,7 +370,8 @@
 #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
 
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma, int expected)
+			    struct mem_access *ma, int expected,
+			    unsigned long address)
 {
 	u_int rm;
 	int ret, index;
@@ -383,9 +385,18 @@
 	index = (instruction>>8)&15;	/* 0x0F00 */
 	rm = regs->regs[index];
 
-	/* shout about fixups */
-	if (!expected)
+	/*
+	 * Log the unexpected fixups, and then pass them on to perf.
+	 *
+	 * We intentionally don't report the expected cases to perf as
+	 * otherwise the trapped I/O case will skew the results too much
+	 * to be useful.
+	 */
+	if (!expected) {
 		unaligned_fixups_notify(current, instruction, regs);
+		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0,
+			      regs, address);
+	}
 
 	ret = -EFAULT;
 	switch (instruction&0xF000) {
@@ -574,7 +585,8 @@
 
 		set_fs(USER_DS);
 		tmp = handle_unaligned_access(instruction, regs,
-					      &user_mem_access, 0);
+					      &user_mem_access, 0,
+					      address);
 		set_fs(oldfs);
 
 		if (tmp == 0)
@@ -607,8 +619,8 @@
 
 		unaligned_fixups_notify(current, instruction, regs);
 
-		handle_unaligned_access(instruction, regs,
-					&user_mem_access, 0);
+		handle_unaligned_access(instruction, regs, &user_mem_access,
+					0, address);
 		set_fs(oldfs);
 	}
 }
@@ -802,6 +814,9 @@
 		     : /* no output */
 		     : "r" (&vbr_base)
 		     : "memory");
+
+	/* disable exception blocking now when the vbr has been setup */
+	clear_bl_bit();
 }
 
 void *set_exception_table_vec(unsigned int vec, void *handler)
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index e67e140..6713ca9 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
 #include <linux/module.h>
+#include <linux/perf_event.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -50,7 +51,7 @@
 	do_unhandled_exception(trapnr, signr, str, __stringify(name), error_code, regs, current); \
 }
 
-spinlock_t die_lock;
+static DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
@@ -433,6 +434,8 @@
 		return error;
 	}
 
+	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, address);
+
 	destreg = (opcode >> 4) & 0x3f;
 	if (user_mode(regs)) {
 		__u64 buffer;
@@ -509,6 +512,8 @@
 		return error;
 	}
 
+	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, address);
+
 	srcreg = (opcode >> 4) & 0x3f;
 	if (user_mode(regs)) {
 		__u64 buffer;
@@ -583,6 +588,8 @@
 		return error;
 	}
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, address);
+
 	destreg = (opcode >> 4) & 0x3f;
 	if (user_mode(regs)) {
 		__u64 buffer;
@@ -658,6 +665,8 @@
 		return error;
 	}
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, address);
+
 	srcreg = (opcode >> 4) & 0x3f;
 	if (user_mode(regs)) {
 		__u64 buffer;
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index dab4d21..7b95f29 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -30,4 +30,4 @@
 lib-$(CONFIG_MCOUNT)		+= mcount.o
 lib-y				+= $(memcpy-y) $(memset-y) $(udivsi3-y)
 
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index 1fcdb12..f76a509 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
+#include <linux/perf_event.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -619,6 +620,8 @@
 	struct task_struct *tsk = current;
 	struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
 	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
 		/* initialize once. */
 		fpu_init(fpu);
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 1445ca6..0937039 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -168,6 +168,10 @@
 config UNCACHED_MAPPING
 	bool
 
+config HAVE_SRAM_POOL
+	bool
+	select GENERIC_ALLOCATOR
+
 choice
 	prompt "Kernel page size"
 	default PAGE_SIZE_4KB
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 53f7c68..ab89ea4 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -40,6 +40,7 @@
 obj-$(CONFIG_NUMA)		+= numa.o
 obj-$(CONFIG_IOREMAP_FIXED)	+= ioremap_fixed.o
 obj-$(CONFIG_UNCACHED_MAPPING)	+= uncached.o
+obj-$(CONFIG_HAVE_SRAM_POOL)	+= sram.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.
@@ -66,4 +67,4 @@
 	-ffixed-r60 -ffixed-r61 -ffixed-r62 \
 	-fomit-frame-pointer
 
-EXTRA_CFLAGS += -Werror
+ccflags-y := -Werror
diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c
index cd8c3bf..74c03ec 100644
--- a/arch/sh/mm/asids-debugfs.c
+++ b/arch/sh/mm/asids-debugfs.c
@@ -63,7 +63,7 @@
 {
 	struct dentry *asids_dentry;
 
-	asids_dentry = debugfs_create_file("asids", S_IRUSR, sh_debugfs_root,
+	asids_dentry = debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir,
 					   NULL, &asids_debugfs_fops);
 	if (!asids_dentry)
 		return -ENOMEM;
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index 690ed01..5241146 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -126,25 +126,19 @@
 {
 	struct dentry *dcache_dentry, *icache_dentry;
 
-	dcache_dentry = debugfs_create_file("dcache", S_IRUSR, sh_debugfs_root,
+	dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir,
 					    (unsigned int *)CACHE_TYPE_DCACHE,
 					    &cache_debugfs_fops);
 	if (!dcache_dentry)
 		return -ENOMEM;
-	if (IS_ERR(dcache_dentry))
-		return PTR_ERR(dcache_dentry);
 
-	icache_dentry = debugfs_create_file("icache", S_IRUSR, sh_debugfs_root,
+	icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir,
 					    (unsigned int *)CACHE_TYPE_ICACHE,
 					    &cache_debugfs_fops);
 	if (!icache_dentry) {
 		debugfs_remove(dcache_dentry);
 		return -ENOMEM;
 	}
-	if (IS_ERR(icache_dentry)) {
-		debugfs_remove(dcache_dentry);
-		return PTR_ERR(icache_dentry);
-	}
 
 	return 0;
 }
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index c86a085..0387932 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -38,11 +38,12 @@
 	void *ret, *ret_nocache;
 	int order = get_order(size);
 
+	gfp |= __GFP_ZERO;
+
 	ret = (void *)__get_free_pages(gfp, order);
 	if (!ret)
 		return NULL;
 
-	memset(ret, 0, size);
 	/*
 	 * Pages from the page allocator may have data present in
 	 * cache. So flush the cache before using uncached memory.
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 552bea5..3385b28 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -47,7 +47,6 @@
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
-	pte_t *pte;
 
 	pgd = pgd_offset_k(addr);
 	if (pgd_none(*pgd)) {
@@ -67,8 +66,7 @@
 		return NULL;
 	}
 
-	pte = pte_offset_kernel(pmd, addr);
-	return pte;
+	return pte_offset_kernel(pmd, addr);
 }
 
 static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
@@ -125,13 +123,45 @@
 	clear_pte_phys(address, prot);
 }
 
+static pmd_t * __init one_md_table_init(pud_t *pud)
+{
+	if (pud_none(*pud)) {
+		pmd_t *pmd;
+
+		pmd = alloc_bootmem_pages(PAGE_SIZE);
+		pud_populate(&init_mm, pud, pmd);
+		BUG_ON(pmd != pmd_offset(pud, 0));
+	}
+
+	return pmd_offset(pud, 0);
+}
+
+static pte_t * __init one_page_table_init(pmd_t *pmd)
+{
+	if (pmd_none(*pmd)) {
+		pte_t *pte;
+
+		pte = alloc_bootmem_pages(PAGE_SIZE);
+		pmd_populate_kernel(&init_mm, pmd, pte);
+		BUG_ON(pte != pte_offset_kernel(pmd, 0));
+	}
+
+	return pte_offset_kernel(pmd, 0);
+}
+
+static pte_t * __init page_table_kmap_check(pte_t *pte, pmd_t *pmd,
+					    unsigned long vaddr, pte_t *lastpte)
+{
+	return pte;
+}
+
 void __init page_table_range_init(unsigned long start, unsigned long end,
 					 pgd_t *pgd_base)
 {
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
-	pte_t *pte;
+	pte_t *pte = NULL;
 	int i, j, k;
 	unsigned long vaddr;
 
@@ -144,19 +174,13 @@
 	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
 		pud = (pud_t *)pgd;
 		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
-#ifdef __PAGETABLE_PMD_FOLDED
-			pmd = (pmd_t *)pud;
-#else
-			pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
-			pud_populate(&init_mm, pud, pmd);
+			pmd = one_md_table_init(pud);
+#ifndef __PAGETABLE_PMD_FOLDED
 			pmd += k;
 #endif
 			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));
-				}
+				pte = page_table_kmap_check(one_page_table_init(pmd),
+							    pmd, vaddr, pte);
 				vaddr += PMD_SIZE;
 			}
 			k = 0;
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
index 7694f50..36312d2 100644
--- a/arch/sh/mm/nommu.c
+++ b/arch/sh/mm/nommu.c
@@ -67,6 +67,10 @@
 	BUG();
 }
 
+void __flush_tlb_global(void)
+{
+}
+
 void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
 }
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 6379091..b20b1b3 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -40,7 +40,7 @@
 	unsigned long flags;
 	unsigned long size;
 
-	spinlock_t lock;
+	raw_spinlock_t lock;
 
 	/*
 	 * 0 .. NR_PMB_ENTRIES for specific entry selection, or
@@ -265,7 +265,7 @@
 
 	memset(pmbe, 0, sizeof(struct pmb_entry));
 
-	spin_lock_init(&pmbe->lock);
+	raw_spin_lock_init(&pmbe->lock);
 
 	pmbe->vpn	= vpn;
 	pmbe->ppn	= ppn;
@@ -327,9 +327,9 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&pmbe->lock, flags);
+	raw_spin_lock_irqsave(&pmbe->lock, flags);
 	__set_pmb_entry(pmbe);
-	spin_unlock_irqrestore(&pmbe->lock, flags);
+	raw_spin_unlock_irqrestore(&pmbe->lock, flags);
 }
 #endif /* CONFIG_PM */
 
@@ -368,7 +368,7 @@
 				return PTR_ERR(pmbe);
 			}
 
-			spin_lock_irqsave(&pmbe->lock, flags);
+			raw_spin_lock_irqsave(&pmbe->lock, flags);
 
 			pmbe->size = pmb_sizes[i].size;
 
@@ -383,9 +383,10 @@
 			 * entries for easier tear-down.
 			 */
 			if (likely(pmbp)) {
-				spin_lock(&pmbp->lock);
+				raw_spin_lock_nested(&pmbp->lock,
+						     SINGLE_DEPTH_NESTING);
 				pmbp->link = pmbe;
-				spin_unlock(&pmbp->lock);
+				raw_spin_unlock(&pmbp->lock);
 			}
 
 			pmbp = pmbe;
@@ -398,7 +399,7 @@
 			i--;
 			mapped++;
 
-			spin_unlock_irqrestore(&pmbe->lock, flags);
+			raw_spin_unlock_irqrestore(&pmbe->lock, flags);
 		}
 	} while (size >= SZ_16M);
 
@@ -627,15 +628,14 @@
 			continue;
 		}
 
-		spin_lock_irqsave(&pmbe->lock, irqflags);
+		raw_spin_lock_irqsave(&pmbe->lock, irqflags);
 
 		for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++)
 			if (pmb_sizes[j].flag == size)
 				pmbe->size = pmb_sizes[j].size;
 
 		if (pmbp) {
-			spin_lock(&pmbp->lock);
-
+			raw_spin_lock_nested(&pmbp->lock, SINGLE_DEPTH_NESTING);
 			/*
 			 * Compare the previous entry against the current one to
 			 * see if the entries span a contiguous mapping. If so,
@@ -644,13 +644,12 @@
 			 */
 			if (pmb_can_merge(pmbp, pmbe))
 				pmbp->link = pmbe;
-
-			spin_unlock(&pmbp->lock);
+			raw_spin_unlock(&pmbp->lock);
 		}
 
 		pmbp = pmbe;
 
-		spin_unlock_irqrestore(&pmbe->lock, irqflags);
+		raw_spin_unlock_irqrestore(&pmbe->lock, irqflags);
 	}
 }
 
@@ -757,7 +756,7 @@
 		/*
 		 * Found it, now resize it.
 		 */
-		spin_lock_irqsave(&pmbe->lock, flags);
+		raw_spin_lock_irqsave(&pmbe->lock, flags);
 
 		pmbe->size = SZ_16M;
 		pmbe->flags &= ~PMB_SZ_MASK;
@@ -767,7 +766,7 @@
 
 		__set_pmb_entry(pmbe);
 
-		spin_unlock_irqrestore(&pmbe->lock, flags);
+		raw_spin_unlock_irqrestore(&pmbe->lock, flags);
 	}
 
 	read_unlock(&pmb_rwlock);
@@ -866,11 +865,9 @@
 	struct dentry *dentry;
 
 	dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO,
-				     sh_debugfs_root, NULL, &pmb_debugfs_fops);
+				     arch_debugfs_dir, NULL, &pmb_debugfs_fops);
 	if (!dentry)
 		return -ENOMEM;
-	if (IS_ERR(dentry))
-		return PTR_ERR(dentry);
 
 	return 0;
 }
diff --git a/arch/sh/mm/sram.c b/arch/sh/mm/sram.c
new file mode 100644
index 0000000..bc156ec
--- /dev/null
+++ b/arch/sh/mm/sram.c
@@ -0,0 +1,34 @@
+/*
+ * SRAM pool for tiny memories not otherwise managed.
+ *
+ * Copyright (C) 2010  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 <asm/sram.h>
+
+/*
+ * This provides a standard SRAM pool for tiny memories that can be
+ * added either by the CPU or the platform code. Typical SRAM sizes
+ * to be inserted in to the pool will generally be less than the page
+ * size, with anything more reasonably sized handled as a NUMA memory
+ * node.
+ */
+struct gen_pool *sram_pool;
+
+static int __init sram_pool_init(void)
+{
+	/*
+	 * This is a global pool, we don't care about node locality.
+	 */
+	sram_pool = gen_pool_create(1, -1);
+	if (unlikely(!sram_pool))
+		return -ENOMEM;
+
+	return 0;
+}
+core_initcall(sram_pool_init);
diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c
index 229bf75..dea637a 100644
--- a/arch/sh/mm/tlb-debugfs.c
+++ b/arch/sh/mm/tlb-debugfs.c
@@ -151,15 +151,13 @@
 {
 	struct dentry *itlb, *utlb;
 
-	itlb = debugfs_create_file("itlb", S_IRUSR, sh_debugfs_root,
+	itlb = debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir,
 				   (unsigned int *)TLB_TYPE_ITLB,
 				   &tlb_debugfs_fops);
 	if (unlikely(!itlb))
 		return -ENOMEM;
-	if (IS_ERR(itlb))
-		return PTR_ERR(itlb);
 
-	utlb = debugfs_create_file("utlb", S_IRUSR, sh_debugfs_root,
+	utlb = debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir,
 				   (unsigned int *)TLB_TYPE_UTLB,
 				   &tlb_debugfs_fops);
 	if (unlikely(!utlb)) {
@@ -167,11 +165,6 @@
 		return -ENOMEM;
 	}
 
-	if (IS_ERR(utlb)) {
-		debugfs_remove(itlb);
-		return PTR_ERR(utlb);
-	}
-
 	return 0;
 }
 module_init(tlb_debugfs_init);
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 3fbe03c..a6a20d6 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -119,3 +119,19 @@
 		local_irq_restore(flags);
 	}
 }
+
+void __flush_tlb_global(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	/*
+	 * This is the most destructive of the TLB flushing options,
+	 * and will tear down all of the UTLB/ITLB mappings, including
+	 * wired entries.
+	 */
+	__raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+
+	local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 03db41c..7f5810f 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -455,6 +455,11 @@
         flush_tlb_all();
 }
 
+void __flush_tlb_global(void)
+{
+	flush_tlb_all();
+}
+
 void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
 }
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index b25aa55..9f56eb9 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -52,6 +52,8 @@
 RSK7201			SH_RSK7201
 RSK7203			SH_RSK7203
 AP325RXA		SH_AP325RXA
+SH2007			SH_SH2007
+SH7757LCR		SH_SH7757LCR
 SH7763RDP		SH_SH7763RDP
 SH7785LCR		SH_SH7785LCR
 SH7785LCR_PT		SH_SH7785LCR_PT
diff --git a/drivers/Makefile b/drivers/Makefile
index a2aea53..167af31 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -92,6 +92,7 @@
 obj-y				+= lguest/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
+obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
 obj-$(CONFIG_NEW_LEDS)		+= leds/
@@ -104,7 +105,6 @@
 ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
 obj-y				+= clocksource/
 endif
-obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_DCA)		+= dca/
 obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 717305d..a446116 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -308,7 +308,7 @@
 	 * isr before we end up here.
 	 */
 	if (p->flags & FLAG_CLOCKSOURCE)
-		p->total_cycles += p->match_value;
+		p->total_cycles += p->match_value + 1;
 
 	if (!(p->flags & FLAG_REPROGRAM))
 		p->next_match_value = p->max_match_value;
@@ -403,7 +403,7 @@
 	raw = sh_cmt_get_counter(p, &has_wrapped);
 
 	if (unlikely(has_wrapped))
-		raw += p->match_value;
+		raw += p->match_value + 1;
 	spin_unlock_irqrestore(&p->lock, flags);
 
 	return value + raw;
@@ -445,7 +445,7 @@
 
 	/* clk_get_rate() needs an enabled clock */
 	clk_enable(p->clk);
-	p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8;
+	p->rate = clk_get_rate(p->clk) / ((p->width == 16) ? 512 : 8);
 	clk_disable(p->clk);
 
 	/* TODO: calculate good shift from rate and counter bit width */
@@ -478,7 +478,7 @@
 	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
 
 	if (periodic)
-		sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+		sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1);
 	else
 		sh_cmt_set_next(p, p->max_match_value);
 }
@@ -523,9 +523,9 @@
 
 	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
 	if (likely(p->flags & FLAG_IRQCONTEXT))
-		p->next_match_value = delta;
+		p->next_match_value = delta - 1;
 	else
-		sh_cmt_set_next(p, delta);
+		sh_cmt_set_next(p, delta - 1);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c
index 4f93da3..3cad8fe 100644
--- a/drivers/i2c/busses/i2c-sh7760.c
+++ b/drivers/i2c/busses/i2c-sh7760.c
@@ -101,12 +101,12 @@
 
 static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
 {
-	ctrl_outl(val, (unsigned long)cam->iobase + reg);
+	__raw_writel(val, (unsigned long)cam->iobase + reg);
 }
 
 static inline unsigned long IN32(struct cami2c *cam, int reg)
 {
-	return ctrl_inl((unsigned long)cam->iobase + reg);
+	return __raw_readl((unsigned long)cam->iobase + reg);
 }
 
 static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 598c49a..2707f5e 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -538,15 +538,17 @@
 {
 	struct resource *res;
 	int ret = -ENXIO;
-	int q, m;
-	int k = 0;
-	int n = 0;
+	int n, k = 0;
 
 	while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
 		for (n = res->start; hook && n <= res->end; n++) {
 			if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED,
-					dev_name(&dev->dev), dev))
+					dev_name(&dev->dev), dev)) {
+				for (n--; n >= res->start; n--)
+					free_irq(n, dev);
+
 				goto rollback;
+			}
 		}
 		k++;
 	}
@@ -554,16 +556,17 @@
 	if (hook)
 		return k > 0 ? 0 : -ENOENT;
 
-	k--;
 	ret = 0;
 
  rollback:
-	for (q = k; k >= 0; k--) {
-		for (m = n; m >= res->start; m--)
-			free_irq(m, dev);
+	k--;
 
-		res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1);
-		m = res->end;
+	while (k >= 0) {
+		res = platform_get_resource(dev, IORESOURCE_IRQ, k);
+		for (n = res->start; n <= res->end; n++)
+			free_irq(n, dev);
+
+		k--;
 	}
 
 	return ret;
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index cd16459..49b4d06 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -65,7 +65,7 @@
 		p->set_pwr(pdev, state);
 }
 
-static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
+static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 {
 	struct sh_mobile_sdhi *priv;
 	struct tmio_mmc_data *mmc_data;
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 9b52f77..d2352ac 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -140,7 +140,15 @@
 # define SCSPTR0	0xffe00024	/* 16 bit SCIF */
 # define SCSPTR1	0xffe10024	/* 16 bit SCIF */
 # define SCIF_ORER	0x0001		/* Overrun error bit */
-# define SCSCR_INIT(port)	0x3a	/* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+
+#if defined(CONFIG_SH_SH2007)
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=0 */
+# define SCSCR_INIT(port)	0x38
+#else
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=1 */
+# define SCSCR_INIT(port)	0x3a
+#endif
+
 #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
       defined(CONFIG_CPU_SUBTYPE_SH7786)
 # define SCSPTR0	0xffea0024	/* 16 bit SCIF */
@@ -616,9 +624,10 @@
  * -- Mitch Davis - 15 Jul 2000
  */
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7785) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7786)
+#if (defined(CONFIG_CPU_SUBTYPE_SH7780)  || \
+     defined(CONFIG_CPU_SUBTYPE_SH7785)  || \
+     defined(CONFIG_CPU_SUBTYPE_SH7786)) && \
+    !defined(CONFIG_SH_SH2007)
 #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
       defined(CONFIG_CPU_SUBTYPE_SH7720) || \
diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig
index a54de0b..f168a61 100644
--- a/drivers/sh/Kconfig
+++ b/drivers/sh/Kconfig
@@ -1,24 +1,5 @@
-config INTC_USERIMASK
-	bool "Userspace interrupt masking support"
-	depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A)
-	help
-	  This enables support for hardware-assisted userspace hardirq
-	  masking.
+menu "SuperH / SH-Mobile Driver Options"
 
-	  SH-4A and newer interrupt blocks all support a special shadowed
-	  page with all non-masking registers obscured when mapped in to
-	  userspace. This is primarily for use by userspace device
-	  drivers that are using special priority levels.
+source "drivers/sh/intc/Kconfig"
 
-	  If in doubt, say N.
-
-config INTC_BALANCING
-	bool "Hardware IRQ balancing support"
-	depends on SMP && SUPERH && CPU_SUBTYPE_SH7786
-	help
-	  This enables support for IRQ auto-distribution mode on SH-X3
-	  SMP parts. All of the balancing and CPU wakeup decisions are
-	  taken care of automatically by hardware for distributed
-	  vectors.
-
-	  If in doubt, say N.
+endmenu
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 08fc653..24e6cec 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -1,10 +1,9 @@
 #
 # Makefile for the SuperH specific drivers.
 #
-obj-y	:= clk.o intc.o
+obj-y	:= intc/
 
-obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
+obj-$(CONFIG_HAVE_CLK)		+= clk/
 obj-$(CONFIG_MAPLE)		+= maple/
-
+obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
 obj-$(CONFIG_GENERIC_GPIO)	+= pfc.o
-obj-$(CONFIG_SH_CLK_CPG)	+= clk-cpg.o
diff --git a/drivers/sh/clk/Makefile b/drivers/sh/clk/Makefile
new file mode 100644
index 0000000..5d15ebf
--- /dev/null
+++ b/drivers/sh/clk/Makefile
@@ -0,0 +1,3 @@
+obj-y	:= core.o
+
+obj-$(CONFIG_SH_CLK_CPG)	+= cpg.o
diff --git a/drivers/sh/clk.c b/drivers/sh/clk/core.c
similarity index 73%
rename from drivers/sh/clk.c
rename to drivers/sh/clk/core.c
index 5d84ada..fd0d1b9 100644
--- a/drivers/sh/clk.c
+++ b/drivers/sh/clk/core.c
@@ -1,7 +1,7 @@
 /*
- * drivers/sh/clk.c - SuperH clock framework
+ * SuperH clock framework
  *
- *  Copyright (C) 2005 - 2009  Paul Mundt
+ *  Copyright (C) 2005 - 2010  Paul Mundt
  *
  * This clock framework is derived from the OMAP version by:
  *
@@ -14,6 +14,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#define pr_fmt(fmt) "clock: " fmt
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -23,7 +25,7 @@
 #include <linux/sysdev.h>
 #include <linux/seq_file.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/io.h>
 #include <linux/debugfs.h>
 #include <linux/cpufreq.h>
 #include <linux/clk.h>
@@ -43,6 +45,8 @@
 	unsigned long freq;
 	int i;
 
+	clk->nr_freqs = nr_freqs;
+
 	for (i = 0; i < nr_freqs; i++) {
 		div = 1;
 		mult = 1;
@@ -67,29 +71,39 @@
 	freq_table[i].frequency = CPUFREQ_TABLE_END;
 }
 
-long clk_rate_table_round(struct clk *clk,
-			  struct cpufreq_frequency_table *freq_table,
-			  unsigned long rate)
+struct clk_rate_round_data;
+
+struct clk_rate_round_data {
+	unsigned long rate;
+	unsigned int min, max;
+	long (*func)(unsigned int, struct clk_rate_round_data *);
+	void *arg;
+};
+
+#define for_each_frequency(pos, r, freq)			\
+	for (pos = r->min, freq = r->func(pos, r);		\
+	     pos <= r->max; pos++, freq = r->func(pos, r))	\
+		if (unlikely(freq == 0))			\
+			;					\
+		else
+
+static long clk_rate_round_helper(struct clk_rate_round_data *rounder)
 {
 	unsigned long rate_error, rate_error_prev = ~0UL;
-	unsigned long rate_best_fit = rate;
-	unsigned long highest, lowest;
+	unsigned long rate_best_fit = rounder->rate;
+	unsigned long highest, lowest, freq;
 	int i;
 
-	highest = lowest = 0;
+	highest = 0;
+	lowest = ~0UL;
 
-	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		unsigned long freq = freq_table[i].frequency;
-
-		if (freq == CPUFREQ_ENTRY_INVALID)
-			continue;
-
+	for_each_frequency(i, rounder, freq) {
 		if (freq > highest)
 			highest = freq;
 		if (freq < lowest)
 			lowest = freq;
 
-		rate_error = abs(freq - rate);
+		rate_error = abs(freq - rounder->rate);
 		if (rate_error < rate_error_prev) {
 			rate_best_fit = freq;
 			rate_error_prev = rate_error;
@@ -99,14 +113,64 @@
 			break;
 	}
 
-	if (rate >= highest)
+	if (rounder->rate >= highest)
 		rate_best_fit = highest;
-	if (rate <= lowest)
+	if (rounder->rate <= lowest)
 		rate_best_fit = lowest;
 
 	return rate_best_fit;
 }
 
+static long clk_rate_table_iter(unsigned int pos,
+				struct clk_rate_round_data *rounder)
+{
+	struct cpufreq_frequency_table *freq_table = rounder->arg;
+	unsigned long freq = freq_table[pos].frequency;
+
+	if (freq == CPUFREQ_ENTRY_INVALID)
+		freq = 0;
+
+	return freq;
+}
+
+long clk_rate_table_round(struct clk *clk,
+			  struct cpufreq_frequency_table *freq_table,
+			  unsigned long rate)
+{
+	struct clk_rate_round_data table_round = {
+		.min	= 0,
+		.max	= clk->nr_freqs - 1,
+		.func	= clk_rate_table_iter,
+		.arg	= freq_table,
+		.rate	= rate,
+	};
+
+	if (clk->nr_freqs < 1)
+		return 0;
+
+	return clk_rate_round_helper(&table_round);
+}
+
+static long clk_rate_div_range_iter(unsigned int pos,
+				    struct clk_rate_round_data *rounder)
+{
+	return clk_get_rate(rounder->arg) / pos;
+}
+
+long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
+			      unsigned int div_max, unsigned long rate)
+{
+	struct clk_rate_round_data div_range_round = {
+		.min	= div_min,
+		.max	= div_max,
+		.func	= clk_rate_div_range_iter,
+		.arg	= clk_get_parent(clk),
+		.rate	= rate,
+	};
+
+	return clk_rate_round_helper(&div_range_round);
+}
+
 int clk_rate_table_find(struct clk *clk,
 			struct cpufreq_frequency_table *freq_table,
 			unsigned long rate)
@@ -160,8 +224,8 @@
 
 static void __clk_disable(struct clk *clk)
 {
-	if (WARN(!clk->usecount, "Trying to disable clock %s with 0 usecount\n",
-		 clk->name))
+	if (WARN(!clk->usecount, "Trying to disable clock %p with 0 usecount\n",
+		 clk))
 		return;
 
 	if (!(--clk->usecount)) {
@@ -248,8 +312,88 @@
 	}
 }
 
+static struct clk_mapping dummy_mapping;
+
+static struct clk *lookup_root_clock(struct clk *clk)
+{
+	while (clk->parent)
+		clk = clk->parent;
+
+	return clk;
+}
+
+static int clk_establish_mapping(struct clk *clk)
+{
+	struct clk_mapping *mapping = clk->mapping;
+
+	/*
+	 * Propagate mappings.
+	 */
+	if (!mapping) {
+		struct clk *clkp;
+
+		/*
+		 * dummy mapping for root clocks with no specified ranges
+		 */
+		if (!clk->parent) {
+			clk->mapping = &dummy_mapping;
+			return 0;
+		}
+
+		/*
+		 * If we're on a child clock and it provides no mapping of its
+		 * own, inherit the mapping from its root clock.
+		 */
+		clkp = lookup_root_clock(clk);
+		mapping = clkp->mapping;
+		BUG_ON(!mapping);
+	}
+
+	/*
+	 * Establish initial mapping.
+	 */
+	if (!mapping->base && mapping->phys) {
+		kref_init(&mapping->ref);
+
+		mapping->base = ioremap_nocache(mapping->phys, mapping->len);
+		if (unlikely(!mapping->base))
+			return -ENXIO;
+	} else if (mapping->base) {
+		/*
+		 * Bump the refcount for an existing mapping
+		 */
+		kref_get(&mapping->ref);
+	}
+
+	clk->mapping = mapping;
+	return 0;
+}
+
+static void clk_destroy_mapping(struct kref *kref)
+{
+	struct clk_mapping *mapping;
+
+	mapping = container_of(kref, struct clk_mapping, ref);
+
+	iounmap(mapping->base);
+}
+
+static void clk_teardown_mapping(struct clk *clk)
+{
+	struct clk_mapping *mapping = clk->mapping;
+
+	/* Nothing to do */
+	if (mapping == &dummy_mapping)
+		return;
+
+	kref_put(&mapping->ref, clk_destroy_mapping);
+	clk->mapping = NULL;
+}
+
 int clk_register(struct clk *clk)
 {
+	int ret;
+
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
@@ -264,6 +408,10 @@
 	INIT_LIST_HEAD(&clk->children);
 	clk->usecount = 0;
 
+	ret = clk_establish_mapping(clk);
+	if (unlikely(ret))
+		goto out_unlock;
+
 	if (clk->parent)
 		list_add(&clk->sibling, &clk->parent->children);
 	else
@@ -272,9 +420,11 @@
 	list_add(&clk->node, &clock_list);
 	if (clk->ops && clk->ops->init)
 		clk->ops->init(clk);
+
+out_unlock:
 	mutex_unlock(&clock_list_sem);
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_register);
 
@@ -283,6 +433,7 @@
 	mutex_lock(&clock_list_sem);
 	list_del(&clk->sibling);
 	list_del(&clk->node);
+	clk_teardown_mapping(clk);
 	mutex_unlock(&clock_list_sem);
 }
 EXPORT_SYMBOL_GPL(clk_unregister);
@@ -354,10 +505,10 @@
 			ret = clk_reparent(clk, parent);
 
 		if (ret == 0) {
-			pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
-				 clk->name, clk->parent->name, clk->rate);
 			if (clk->ops->recalc)
 				clk->rate = clk->ops->recalc(clk);
+			pr_debug("set parent of %p to %p (new rate %ld)\n",
+				 clk, clk->parent, clk->rate);
 			propagate_rate(clk);
 		}
 	} else
@@ -469,9 +620,7 @@
 	char s[255];
 	char *p = s;
 
-	p += sprintf(p, "%s", c->name);
-	if (c->id >= 0)
-		sprintf(p, ":%d", c->id);
+	p += sprintf(p, "%p", c);
 	d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
 	if (!d)
 		return -ENOMEM;
@@ -513,7 +662,7 @@
 			return err;
 	}
 
-	if (!c->dentry && c->name) {
+	if (!c->dentry) {
 		err = clk_debugfs_register_one(c);
 		if (err)
 			return err;
diff --git a/drivers/sh/clk-cpg.c b/drivers/sh/clk/cpg.c
similarity index 96%
rename from drivers/sh/clk-cpg.c
rename to drivers/sh/clk/cpg.c
index 8c024b9..3aea5f0 100644
--- a/drivers/sh/clk-cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -1,3 +1,12 @@
+/*
+ * Helper routines for SuperH Clock Pulse Generator blocks (CPG).
+ *
+ *  Copyright (C) 2010  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/clk.h>
 #include <linux/compiler.h>
 #include <linux/slab.h>
@@ -180,7 +189,6 @@
 		clkp = clks + k;
 
 		clkp->ops = ops;
-		clkp->id = -1;
 		clkp->freq_table = freq_table + (k * freq_table_size);
 		clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
 
@@ -319,7 +327,6 @@
 		clkp = clks + k;
 
 		clkp->ops = ops;
-		clkp->id = -1;
 		clkp->priv = table;
 
 		clkp->freq_table = freq_table + (k * freq_table_size);
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
deleted file mode 100644
index e91a23e..0000000
--- a/drivers/sh/intc.c
+++ /dev/null
@@ -1,1390 +0,0 @@
-/*
- * Shared interrupt handling code for IPR and INTC2 types of IRQs.
- *
- * Copyright (C) 2007, 2008 Magnus Damm
- * Copyright (C) 2009, 2010 Paul Mundt
- *
- * Based on intc2.c and ipr.c
- *
- * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
- * Copyright (C) 2000  Kazumoto Kojima
- * Copyright (C) 2001  David J. Mckay (david.mckay@st.com)
- * Copyright (C) 2003  Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
- * Copyright (C) 2005, 2006  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.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/sh_intc.h>
-#include <linux/sysdev.h>
-#include <linux/list.h>
-#include <linux/topology.h>
-#include <linux/bitmap.h>
-#include <linux/cpumask.h>
-#include <asm/sizes.h>
-
-#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
-	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
-	 ((addr_e) << 16) | ((addr_d << 24)))
-
-#define _INTC_SHIFT(h) (h & 0x1f)
-#define _INTC_WIDTH(h) ((h >> 5) & 0xf)
-#define _INTC_FN(h) ((h >> 9) & 0xf)
-#define _INTC_MODE(h) ((h >> 13) & 0x7)
-#define _INTC_ADDR_E(h) ((h >> 16) & 0xff)
-#define _INTC_ADDR_D(h) ((h >> 24) & 0xff)
-
-struct intc_handle_int {
-	unsigned int irq;
-	unsigned long handle;
-};
-
-struct intc_window {
-	phys_addr_t phys;
-	void __iomem *virt;
-	unsigned long size;
-};
-
-struct intc_desc_int {
-	struct list_head list;
-	struct sys_device sysdev;
-	pm_message_t state;
-	unsigned long *reg;
-#ifdef CONFIG_SMP
-	unsigned long *smp;
-#endif
-	unsigned int nr_reg;
-	struct intc_handle_int *prio;
-	unsigned int nr_prio;
-	struct intc_handle_int *sense;
-	unsigned int nr_sense;
-	struct intc_window *window;
-	unsigned int nr_windows;
-	struct irq_chip chip;
-};
-
-static LIST_HEAD(intc_list);
-
-/*
- * The intc_irq_map provides a global map of bound IRQ vectors for a
- * given platform. Allocation of IRQs are either static through the CPU
- * vector map, or dynamic in the case of board mux vectors or MSI.
- *
- * As this is a central point for all IRQ controllers on the system,
- * each of the available sources are mapped out here. This combined with
- * sparseirq makes it quite trivial to keep the vector map tightly packed
- * when dynamically creating IRQs, as well as tying in to otherwise
- * unused irq_desc positions in the sparse array.
- */
-static DECLARE_BITMAP(intc_irq_map, NR_IRQS);
-static DEFINE_SPINLOCK(vector_lock);
-
-#ifdef CONFIG_SMP
-#define IS_SMP(x) x.smp
-#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
-#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1)
-#else
-#define IS_SMP(x) 0
-#define INTC_REG(d, x, c) (d->reg[(x)])
-#define SMP_NR(d, x) 1
-#endif
-
-static unsigned int intc_prio_level[NR_IRQS];	/* for now */
-static unsigned int default_prio_level = 2;	/* 2 - 16 */
-static unsigned long ack_handle[NR_IRQS];
-#ifdef CONFIG_INTC_BALANCING
-static unsigned long dist_handle[NR_IRQS];
-#endif
-
-static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
-{
-	struct irq_chip *chip = get_irq_chip(irq);
-	return container_of(chip, struct intc_desc_int, chip);
-}
-
-static unsigned long intc_phys_to_virt(struct intc_desc_int *d,
-				       unsigned long address)
-{
-	struct intc_window *window;
-	int k;
-
-	/* scan through physical windows and convert address */
-	for (k = 0; k < d->nr_windows; k++) {
-		window = d->window + k;
-
-		if (address < window->phys)
-			continue;
-
-		if (address >= (window->phys + window->size))
-			continue;
-
-		address -= window->phys;
-		address += (unsigned long)window->virt;
-
-		return address;
-	}
-
-	/* no windows defined, register must be 1:1 mapped virt:phys */
-	return address;
-}
-
-static unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address)
-{
-	unsigned int k;
-
-	address = intc_phys_to_virt(d, address);
-
-	for (k = 0; k < d->nr_reg; k++) {
-		if (d->reg[k] == address)
-			return k;
-	}
-
-	BUG();
-	return 0;
-}
-
-static inline unsigned int set_field(unsigned int value,
-				     unsigned int field_value,
-				     unsigned int handle)
-{
-	unsigned int width = _INTC_WIDTH(handle);
-	unsigned int shift = _INTC_SHIFT(handle);
-
-	value &= ~(((1 << width) - 1) << shift);
-	value |= field_value << shift;
-	return value;
-}
-
-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)
-{
-	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);
-}
-
-static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
-{
-	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);
-}
-
-static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
-{
-	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);
-}
-
-enum {	REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
-
-static void (*intc_reg_fns[])(unsigned long addr,
-			      unsigned long h,
-			      unsigned long data) = {
-	[REG_FN_WRITE_BASE + 0] = write_8,
-	[REG_FN_WRITE_BASE + 1] = write_16,
-	[REG_FN_WRITE_BASE + 3] = write_32,
-	[REG_FN_MODIFY_BASE + 0] = modify_8,
-	[REG_FN_MODIFY_BASE + 1] = modify_16,
-	[REG_FN_MODIFY_BASE + 3] = modify_32,
-};
-
-enum {	MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
-	MODE_MASK_REG,       /* Bit(s) set -> interrupt disabled */
-	MODE_DUAL_REG,       /* Two registers, set bit to enable / disable */
-	MODE_PRIO_REG,       /* Priority value written to enable interrupt */
-	MODE_PCLR_REG,       /* Above plus all bits set to disable interrupt */
-};
-
-static void intc_mode_field(unsigned long addr,
-			    unsigned long handle,
-			    void (*fn)(unsigned long,
-				       unsigned long,
-				       unsigned long),
-			    unsigned int irq)
-{
-	fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1));
-}
-
-static void intc_mode_zero(unsigned long addr,
-			   unsigned long handle,
-			   void (*fn)(unsigned long,
-				       unsigned long,
-				       unsigned long),
-			   unsigned int irq)
-{
-	fn(addr, handle, 0);
-}
-
-static void intc_mode_prio(unsigned long addr,
-			   unsigned long handle,
-			   void (*fn)(unsigned long,
-				       unsigned long,
-				       unsigned long),
-			   unsigned int irq)
-{
-	fn(addr, handle, intc_prio_level[irq]);
-}
-
-static void (*intc_enable_fns[])(unsigned long addr,
-				 unsigned long handle,
-				 void (*fn)(unsigned long,
-					    unsigned long,
-					    unsigned long),
-				 unsigned int irq) = {
-	[MODE_ENABLE_REG] = intc_mode_field,
-	[MODE_MASK_REG] = intc_mode_zero,
-	[MODE_DUAL_REG] = intc_mode_field,
-	[MODE_PRIO_REG] = intc_mode_prio,
-	[MODE_PCLR_REG] = intc_mode_prio,
-};
-
-static void (*intc_disable_fns[])(unsigned long addr,
-				  unsigned long handle,
-				  void (*fn)(unsigned long,
-					     unsigned long,
-					     unsigned long),
-				  unsigned int irq) = {
-	[MODE_ENABLE_REG] = intc_mode_zero,
-	[MODE_MASK_REG] = intc_mode_field,
-	[MODE_DUAL_REG] = intc_mode_field,
-	[MODE_PRIO_REG] = intc_mode_zero,
-	[MODE_PCLR_REG] = intc_mode_field,
-};
-
-#ifdef CONFIG_INTC_BALANCING
-static inline void intc_balancing_enable(unsigned int irq)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = dist_handle[irq];
-	unsigned long addr;
-
-	if (irq_balancing_disabled(irq) || !handle)
-		return;
-
-	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
-	intc_reg_fns[_INTC_FN(handle)](addr, handle, 1);
-}
-
-static inline void intc_balancing_disable(unsigned int irq)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = dist_handle[irq];
-	unsigned long addr;
-
-	if (irq_balancing_disabled(irq) || !handle)
-		return;
-
-	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
-	intc_reg_fns[_INTC_FN(handle)](addr, handle, 0);
-}
-
-static unsigned int intc_dist_data(struct intc_desc *desc,
-				   struct intc_desc_int *d,
-				   intc_enum enum_id)
-{
-	struct intc_mask_reg *mr = desc->hw.mask_regs;
-	unsigned int i, j, fn, mode;
-	unsigned long reg_e, reg_d;
-
-	for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) {
-		mr = desc->hw.mask_regs + i;
-
-		/*
-		 * Skip this entry if there's no auto-distribution
-		 * register associated with it.
-		 */
-		if (!mr->dist_reg)
-			continue;
-
-		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
-			if (mr->enum_ids[j] != enum_id)
-				continue;
-
-			fn = REG_FN_MODIFY_BASE;
-			mode = MODE_ENABLE_REG;
-			reg_e = mr->dist_reg;
-			reg_d = mr->dist_reg;
-
-			fn += (mr->reg_width >> 3) - 1;
-			return _INTC_MK(fn, mode,
-					intc_get_reg(d, reg_e),
-					intc_get_reg(d, reg_d),
-					1,
-					(mr->reg_width - 1) - j);
-		}
-	}
-
-	/*
-	 * It's possible we've gotten here with no distribution options
-	 * available for the IRQ in question, so we just skip over those.
-	 */
-	return 0;
-}
-#else
-static inline void intc_balancing_enable(unsigned int irq)
-{
-}
-
-static inline void intc_balancing_disable(unsigned int irq)
-{
-}
-#endif
-
-static inline void _intc_enable(unsigned int irq, unsigned long handle)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long addr;
-	unsigned int cpu;
-
-	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
-#ifdef CONFIG_SMP
-		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
-			continue;
-#endif
-		addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
-		intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
-						    [_INTC_FN(handle)], irq);
-	}
-
-	intc_balancing_enable(irq);
-}
-
-static void intc_enable(unsigned int irq)
-{
-	_intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
-}
-
-static void intc_disable(unsigned int irq)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = (unsigned long)get_irq_chip_data(irq);
-	unsigned long addr;
-	unsigned int cpu;
-
-	intc_balancing_disable(irq);
-
-	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
-#ifdef CONFIG_SMP
-		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
-			continue;
-#endif
-		addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
-		intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
-						     [_INTC_FN(handle)], irq);
-	}
-}
-
-static void (*intc_enable_noprio_fns[])(unsigned long addr,
-					unsigned long handle,
-					void (*fn)(unsigned long,
-						   unsigned long,
-						   unsigned long),
-					unsigned int irq) = {
-	[MODE_ENABLE_REG] = intc_mode_field,
-	[MODE_MASK_REG] = intc_mode_zero,
-	[MODE_DUAL_REG] = intc_mode_field,
-	[MODE_PRIO_REG] = intc_mode_field,
-	[MODE_PCLR_REG] = intc_mode_field,
-};
-
-static void intc_enable_disable(struct intc_desc_int *d,
-				unsigned long handle, int do_enable)
-{
-	unsigned long addr;
-	unsigned int cpu;
-	void (*fn)(unsigned long, unsigned long,
-		   void (*)(unsigned long, unsigned long, unsigned long),
-		   unsigned int);
-
-	if (do_enable) {
-		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
-			addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
-			fn = intc_enable_noprio_fns[_INTC_MODE(handle)];
-			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
-		}
-	} else {
-		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
-			addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
-			fn = intc_disable_fns[_INTC_MODE(handle)];
-			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
-		}
-	}
-}
-
-static int intc_set_wake(unsigned int irq, unsigned int on)
-{
-	return 0; /* allow wakeup, but setup hardware in intc_suspend() */
-}
-
-#ifdef CONFIG_SMP
-/*
- * This is held with the irq desc lock held, so we don't require any
- * additional locking here at the intc desc level. The affinity mask is
- * later tested in the enable/disable paths.
- */
-static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask)
-{
-	if (!cpumask_intersects(cpumask, cpu_online_mask))
-		return -1;
-
-	cpumask_copy(irq_to_desc(irq)->affinity, cpumask);
-
-	return 0;
-}
-#endif
-
-static void intc_mask_ack(unsigned int irq)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned long handle = ack_handle[irq];
-	unsigned long addr;
-
-	intc_disable(irq);
-
-	/* read register and write zero only to the associated bit */
-	if (handle) {
-		addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
-		switch (_INTC_FN(handle)) {
-		case REG_FN_MODIFY_BASE + 0:	/* 8bit */
-			__raw_readb(addr);
-			__raw_writeb(0xff ^ set_field(0, 1, handle), addr);
-			break;
-		case REG_FN_MODIFY_BASE + 1:	/* 16bit */
-			__raw_readw(addr);
-			__raw_writew(0xffff ^ set_field(0, 1, handle), addr);
-			break;
-		case REG_FN_MODIFY_BASE + 3:	/* 32bit */
-			__raw_readl(addr);
-			__raw_writel(0xffffffff ^ set_field(0, 1, handle), addr);
-			break;
-		default:
-			BUG();
-			break;
-		}
-	}
-}
-
-static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
-					     unsigned int nr_hp,
-					     unsigned int irq)
-{
-	int i;
-
-	/*
-	 * this doesn't scale well, but...
-	 *
-	 * this function should only be used for cerain uncommon
-	 * operations such as intc_set_priority() and intc_set_sense()
-	 * and in those rare cases performance doesn't matter that much.
-	 * keeping the memory footprint low is more important.
-	 *
-	 * one rather simple way to speed this up and still keep the
-	 * memory footprint down is to make sure the array is sorted
-	 * and then perform a bisect to lookup the irq.
-	 */
-	for (i = 0; i < nr_hp; i++) {
-		if ((hp + i)->irq != irq)
-			continue;
-
-		return hp + i;
-	}
-
-	return NULL;
-}
-
-int intc_set_priority(unsigned int irq, unsigned int prio)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	struct intc_handle_int *ihp;
-
-	if (!intc_prio_level[irq] || prio <= 1)
-		return -EINVAL;
-
-	ihp = intc_find_irq(d->prio, d->nr_prio, irq);
-	if (ihp) {
-		if (prio >= (1 << _INTC_WIDTH(ihp->handle)))
-			return -EINVAL;
-
-		intc_prio_level[irq] = prio;
-
-		/*
-		 * only set secondary masking method directly
-		 * primary masking method is using intc_prio_level[irq]
-		 * priority level will be set during next enable()
-		 */
-		if (_INTC_FN(ihp->handle) != REG_FN_ERR)
-			_intc_enable(irq, ihp->handle);
-	}
-	return 0;
-}
-
-#define VALID(x) (x | 0x80)
-
-static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
-	[IRQ_TYPE_EDGE_FALLING] = VALID(0),
-	[IRQ_TYPE_EDGE_RISING] = VALID(1),
-	[IRQ_TYPE_LEVEL_LOW] = VALID(2),
-	/* SH7706, SH7707 and SH7709 do not support high level triggered */
-#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
-    !defined(CONFIG_CPU_SUBTYPE_SH7707) && \
-    !defined(CONFIG_CPU_SUBTYPE_SH7709)
-	[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
-#endif
-};
-
-static int intc_set_sense(unsigned int irq, unsigned int type)
-{
-	struct intc_desc_int *d = get_intc_desc(irq);
-	unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK];
-	struct intc_handle_int *ihp;
-	unsigned long addr;
-
-	if (!value)
-		return -EINVAL;
-
-	ihp = intc_find_irq(d->sense, d->nr_sense, irq);
-	if (ihp) {
-		addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
-		intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
-	}
-	return 0;
-}
-
-static intc_enum __init intc_grp_id(struct intc_desc *desc,
-				    intc_enum enum_id)
-{
-	struct intc_group *g = desc->hw.groups;
-	unsigned int i, j;
-
-	for (i = 0; g && enum_id && i < desc->hw.nr_groups; i++) {
-		g = desc->hw.groups + i;
-
-		for (j = 0; g->enum_ids[j]; j++) {
-			if (g->enum_ids[j] != enum_id)
-				continue;
-
-			return g->enum_id;
-		}
-	}
-
-	return 0;
-}
-
-static unsigned int __init _intc_mask_data(struct intc_desc *desc,
-					   struct intc_desc_int *d,
-					   intc_enum enum_id,
-					   unsigned int *reg_idx,
-					   unsigned int *fld_idx)
-{
-	struct intc_mask_reg *mr = desc->hw.mask_regs;
-	unsigned int fn, mode;
-	unsigned long reg_e, reg_d;
-
-	while (mr && enum_id && *reg_idx < desc->hw.nr_mask_regs) {
-		mr = desc->hw.mask_regs + *reg_idx;
-
-		for (; *fld_idx < ARRAY_SIZE(mr->enum_ids); (*fld_idx)++) {
-			if (mr->enum_ids[*fld_idx] != enum_id)
-				continue;
-
-			if (mr->set_reg && mr->clr_reg) {
-				fn = REG_FN_WRITE_BASE;
-				mode = MODE_DUAL_REG;
-				reg_e = mr->clr_reg;
-				reg_d = mr->set_reg;
-			} else {
-				fn = REG_FN_MODIFY_BASE;
-				if (mr->set_reg) {
-					mode = MODE_ENABLE_REG;
-					reg_e = mr->set_reg;
-					reg_d = mr->set_reg;
-				} else {
-					mode = MODE_MASK_REG;
-					reg_e = mr->clr_reg;
-					reg_d = mr->clr_reg;
-				}
-			}
-
-			fn += (mr->reg_width >> 3) - 1;
-			return _INTC_MK(fn, mode,
-					intc_get_reg(d, reg_e),
-					intc_get_reg(d, reg_d),
-					1,
-					(mr->reg_width - 1) - *fld_idx);
-		}
-
-		*fld_idx = 0;
-		(*reg_idx)++;
-	}
-
-	return 0;
-}
-
-static unsigned int __init intc_mask_data(struct intc_desc *desc,
-					  struct intc_desc_int *d,
-					  intc_enum enum_id, int do_grps)
-{
-	unsigned int i = 0;
-	unsigned int j = 0;
-	unsigned int ret;
-
-	ret = _intc_mask_data(desc, d, enum_id, &i, &j);
-	if (ret)
-		return ret;
-
-	if (do_grps)
-		return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0);
-
-	return 0;
-}
-
-static unsigned int __init _intc_prio_data(struct intc_desc *desc,
-					   struct intc_desc_int *d,
-					   intc_enum enum_id,
-					   unsigned int *reg_idx,
-					   unsigned int *fld_idx)
-{
-	struct intc_prio_reg *pr = desc->hw.prio_regs;
-	unsigned int fn, n, mode, bit;
-	unsigned long reg_e, reg_d;
-
-	while (pr && enum_id && *reg_idx < desc->hw.nr_prio_regs) {
-		pr = desc->hw.prio_regs + *reg_idx;
-
-		for (; *fld_idx < ARRAY_SIZE(pr->enum_ids); (*fld_idx)++) {
-			if (pr->enum_ids[*fld_idx] != enum_id)
-				continue;
-
-			if (pr->set_reg && pr->clr_reg) {
-				fn = REG_FN_WRITE_BASE;
-				mode = MODE_PCLR_REG;
-				reg_e = pr->set_reg;
-				reg_d = pr->clr_reg;
-			} else {
-				fn = REG_FN_MODIFY_BASE;
-				mode = MODE_PRIO_REG;
-				if (!pr->set_reg)
-					BUG();
-				reg_e = pr->set_reg;
-				reg_d = pr->set_reg;
-			}
-
-			fn += (pr->reg_width >> 3) - 1;
-			n = *fld_idx + 1;
-
-			BUG_ON(n * pr->field_width > pr->reg_width);
-
-			bit = pr->reg_width - (n * pr->field_width);
-
-			return _INTC_MK(fn, mode,
-					intc_get_reg(d, reg_e),
-					intc_get_reg(d, reg_d),
-					pr->field_width, bit);
-		}
-
-		*fld_idx = 0;
-		(*reg_idx)++;
-	}
-
-	return 0;
-}
-
-static unsigned int __init intc_prio_data(struct intc_desc *desc,
-					  struct intc_desc_int *d,
-					  intc_enum enum_id, int do_grps)
-{
-	unsigned int i = 0;
-	unsigned int j = 0;
-	unsigned int ret;
-
-	ret = _intc_prio_data(desc, d, enum_id, &i, &j);
-	if (ret)
-		return ret;
-
-	if (do_grps)
-		return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0);
-
-	return 0;
-}
-
-static void __init intc_enable_disable_enum(struct intc_desc *desc,
-					    struct intc_desc_int *d,
-					    intc_enum enum_id, int enable)
-{
-	unsigned int i, j, data;
-
-	/* go through and enable/disable all mask bits */
-	i = j = 0;
-	do {
-		data = _intc_mask_data(desc, d, enum_id, &i, &j);
-		if (data)
-			intc_enable_disable(d, data, enable);
-		j++;
-	} while (data);
-
-	/* go through and enable/disable all priority fields */
-	i = j = 0;
-	do {
-		data = _intc_prio_data(desc, d, enum_id, &i, &j);
-		if (data)
-			intc_enable_disable(d, data, enable);
-
-		j++;
-	} while (data);
-}
-
-static unsigned int __init intc_ack_data(struct intc_desc *desc,
-					  struct intc_desc_int *d,
-					  intc_enum enum_id)
-{
-	struct intc_mask_reg *mr = desc->hw.ack_regs;
-	unsigned int i, j, fn, mode;
-	unsigned long reg_e, reg_d;
-
-	for (i = 0; mr && enum_id && i < desc->hw.nr_ack_regs; i++) {
-		mr = desc->hw.ack_regs + i;
-
-		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
-			if (mr->enum_ids[j] != enum_id)
-				continue;
-
-			fn = REG_FN_MODIFY_BASE;
-			mode = MODE_ENABLE_REG;
-			reg_e = mr->set_reg;
-			reg_d = mr->set_reg;
-
-			fn += (mr->reg_width >> 3) - 1;
-			return _INTC_MK(fn, mode,
-					intc_get_reg(d, reg_e),
-					intc_get_reg(d, reg_d),
-					1,
-					(mr->reg_width - 1) - j);
-		}
-	}
-
-	return 0;
-}
-
-static unsigned int __init intc_sense_data(struct intc_desc *desc,
-					   struct intc_desc_int *d,
-					   intc_enum enum_id)
-{
-	struct intc_sense_reg *sr = desc->hw.sense_regs;
-	unsigned int i, j, fn, bit;
-
-	for (i = 0; sr && enum_id && i < desc->hw.nr_sense_regs; i++) {
-		sr = desc->hw.sense_regs + i;
-
-		for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
-			if (sr->enum_ids[j] != enum_id)
-				continue;
-
-			fn = REG_FN_MODIFY_BASE;
-			fn += (sr->reg_width >> 3) - 1;
-
-			BUG_ON((j + 1) * sr->field_width > sr->reg_width);
-
-			bit = sr->reg_width - ((j + 1) * sr->field_width);
-
-			return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg),
-					0, sr->field_width, bit);
-		}
-	}
-
-	return 0;
-}
-
-static void __init intc_register_irq(struct intc_desc *desc,
-				     struct intc_desc_int *d,
-				     intc_enum enum_id,
-				     unsigned int irq)
-{
-	struct intc_handle_int *hp;
-	unsigned int data[2], primary;
-
-	/*
-	 * Register the IRQ position with the global IRQ map
-	 */
-	set_bit(irq, intc_irq_map);
-
-	/*
-	 * Prefer single interrupt source bitmap over other combinations:
-	 *
-	 * 1. bitmap, single interrupt source
-	 * 2. priority, single interrupt source
-	 * 3. bitmap, multiple interrupt sources (groups)
-	 * 4. priority, multiple interrupt sources (groups)
-	 */
-	data[0] = intc_mask_data(desc, d, enum_id, 0);
-	data[1] = intc_prio_data(desc, d, enum_id, 0);
-
-	primary = 0;
-	if (!data[0] && data[1])
-		primary = 1;
-
-	if (!data[0] && !data[1])
-		pr_warning("missing unique irq mask for irq %d (vect 0x%04x)\n",
-			   irq, irq2evt(irq));
-
-	data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1);
-	data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1);
-
-	if (!data[primary])
-		primary ^= 1;
-
-	BUG_ON(!data[primary]); /* must have primary masking method */
-
-	disable_irq_nosync(irq);
-	set_irq_chip_and_handler_name(irq, &d->chip,
-				      handle_level_irq, "level");
-	set_irq_chip_data(irq, (void *)data[primary]);
-
-	/*
-	 * set priority level
-	 * - this needs to be at least 2 for 5-bit priorities on 7780
-	 */
-	intc_prio_level[irq] = default_prio_level;
-
-	/* enable secondary masking method if present */
-	if (data[!primary])
-		_intc_enable(irq, data[!primary]);
-
-	/* add irq to d->prio list if priority is available */
-	if (data[1]) {
-		hp = d->prio + d->nr_prio;
-		hp->irq = irq;
-		hp->handle = data[1];
-
-		if (primary) {
-			/*
-			 * only secondary priority should access registers, so
-			 * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority()
-			 */
-			hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0);
-			hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0);
-		}
-		d->nr_prio++;
-	}
-
-	/* add irq to d->sense list if sense is available */
-	data[0] = intc_sense_data(desc, d, enum_id);
-	if (data[0]) {
-		(d->sense + d->nr_sense)->irq = irq;
-		(d->sense + d->nr_sense)->handle = data[0];
-		d->nr_sense++;
-	}
-
-	/* irq should be disabled by default */
-	d->chip.mask(irq);
-
-	if (desc->hw.ack_regs)
-		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
-
-#ifdef CONFIG_INTC_BALANCING
-	if (desc->hw.mask_regs)
-		dist_handle[irq] = intc_dist_data(desc, d, enum_id);
-#endif
-
-#ifdef CONFIG_ARM
-	set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
-#endif
-}
-
-static unsigned int __init save_reg(struct intc_desc_int *d,
-				    unsigned int cnt,
-				    unsigned long value,
-				    unsigned int smp)
-{
-	if (value) {
-		value = intc_phys_to_virt(d, value);
-
-		d->reg[cnt] = value;
-#ifdef CONFIG_SMP
-		d->smp[cnt] = smp;
-#endif
-		return 1;
-	}
-
-	return 0;
-}
-
-static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
-{
-	generic_handle_irq((unsigned int)get_irq_data(irq));
-}
-
-int __init register_intc_controller(struct intc_desc *desc)
-{
-	unsigned int i, k, smp;
-	struct intc_hw_desc *hw = &desc->hw;
-	struct intc_desc_int *d;
-	struct resource *res;
-
-	pr_info("Registered controller '%s' with %u IRQs\n",
-		desc->name, hw->nr_vectors);
-
-	d = kzalloc(sizeof(*d), GFP_NOWAIT);
-	if (!d)
-		goto err0;
-
-	INIT_LIST_HEAD(&d->list);
-	list_add(&d->list, &intc_list);
-
-	if (desc->num_resources) {
-		d->nr_windows = desc->num_resources;
-		d->window = kzalloc(d->nr_windows * sizeof(*d->window),
-				    GFP_NOWAIT);
-		if (!d->window)
-			goto err1;
-
-		for (k = 0; k < d->nr_windows; k++) {
-			res = desc->resource + k;
-			WARN_ON(resource_type(res) != IORESOURCE_MEM);
-			d->window[k].phys = res->start;
-			d->window[k].size = resource_size(res);
-			d->window[k].virt = ioremap_nocache(res->start,
-							 resource_size(res));
-			if (!d->window[k].virt)
-				goto err2;
-		}
-	}
-
-	d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0;
-#ifdef CONFIG_INTC_BALANCING
-	if (d->nr_reg)
-		d->nr_reg += hw->nr_mask_regs;
-#endif
-	d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0;
-	d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0;
-	d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0;
-
-	d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
-	if (!d->reg)
-		goto err2;
-
-#ifdef CONFIG_SMP
-	d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);
-	if (!d->smp)
-		goto err3;
-#endif
-	k = 0;
-
-	if (hw->mask_regs) {
-		for (i = 0; i < hw->nr_mask_regs; i++) {
-			smp = IS_SMP(hw->mask_regs[i]);
-			k += save_reg(d, k, hw->mask_regs[i].set_reg, smp);
-			k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp);
-#ifdef CONFIG_INTC_BALANCING
-			k += save_reg(d, k, hw->mask_regs[i].dist_reg, 0);
-#endif
-		}
-	}
-
-	if (hw->prio_regs) {
-		d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio),
-				  GFP_NOWAIT);
-		if (!d->prio)
-			goto err4;
-
-		for (i = 0; i < hw->nr_prio_regs; i++) {
-			smp = IS_SMP(hw->prio_regs[i]);
-			k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
-			k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
-		}
-	}
-
-	if (hw->sense_regs) {
-		d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense),
-				   GFP_NOWAIT);
-		if (!d->sense)
-			goto err5;
-
-		for (i = 0; i < hw->nr_sense_regs; i++)
-			k += save_reg(d, k, hw->sense_regs[i].reg, 0);
-	}
-
-	d->chip.name = desc->name;
-	d->chip.mask = intc_disable;
-	d->chip.unmask = intc_enable;
-	d->chip.mask_ack = intc_disable;
-	d->chip.enable = intc_enable;
-	d->chip.disable = intc_disable;
-	d->chip.shutdown = intc_disable;
-	d->chip.set_type = intc_set_sense;
-	d->chip.set_wake = intc_set_wake;
-#ifdef CONFIG_SMP
-	d->chip.set_affinity = intc_set_affinity;
-#endif
-
-	if (hw->ack_regs) {
-		for (i = 0; i < hw->nr_ack_regs; i++)
-			k += save_reg(d, k, hw->ack_regs[i].set_reg, 0);
-
-		d->chip.mask_ack = intc_mask_ack;
-	}
-
-	/* disable bits matching force_disable before registering irqs */
-	if (desc->force_disable)
-		intc_enable_disable_enum(desc, d, desc->force_disable, 0);
-
-	/* disable bits matching force_enable before registering irqs */
-	if (desc->force_enable)
-		intc_enable_disable_enum(desc, d, desc->force_enable, 0);
-
-	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
-
-	/* register the vectors one by one */
-	for (i = 0; i < hw->nr_vectors; i++) {
-		struct intc_vect *vect = hw->vectors + i;
-		unsigned int irq = evt2irq(vect->vect);
-		struct irq_desc *irq_desc;
-
-		if (!vect->enum_id)
-			continue;
-
-		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
-		if (unlikely(!irq_desc)) {
-			pr_err("can't get irq_desc for %d\n", irq);
-			continue;
-		}
-
-		intc_register_irq(desc, d, vect->enum_id, irq);
-
-		for (k = i + 1; k < hw->nr_vectors; k++) {
-			struct intc_vect *vect2 = hw->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_err("can't get irq_desc for %d\n", irq2);
-				continue;
-			}
-
-			vect2->enum_id = 0;
-
-			/* redirect this interrupts to the first one */
-			set_irq_chip(irq2, &dummy_irq_chip);
-			set_irq_chained_handler(irq2, intc_redirect_irq);
-			set_irq_data(irq2, (void *)irq);
-		}
-	}
-
-	/* enable bits matching force_enable after registering irqs */
-	if (desc->force_enable)
-		intc_enable_disable_enum(desc, d, desc->force_enable, 1);
-
-	return 0;
-err5:
-	kfree(d->prio);
-err4:
-#ifdef CONFIG_SMP
-	kfree(d->smp);
-err3:
-#endif
-	kfree(d->reg);
-err2:
-	for (k = 0; k < d->nr_windows; k++)
-		if (d->window[k].virt)
-			iounmap(d->window[k].virt);
-
-	kfree(d->window);
-err1:
-	kfree(d);
-err0:
-	pr_err("unable to allocate INTC memory\n");
-
-	return -ENOMEM;
-}
-
-#ifdef CONFIG_INTC_USERIMASK
-static void __iomem *uimask;
-
-int register_intc_userimask(unsigned long addr)
-{
-	if (unlikely(uimask))
-		return -EBUSY;
-
-	uimask = ioremap_nocache(addr, SZ_4K);
-	if (unlikely(!uimask))
-		return -ENOMEM;
-
-	pr_info("userimask support registered for levels 0 -> %d\n",
-		default_prio_level - 1);
-
-	return 0;
-}
-
-static ssize_t
-show_intc_userimask(struct sysdev_class *cls,
-		    struct sysdev_class_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
-}
-
-static ssize_t
-store_intc_userimask(struct sysdev_class *cls,
-		     struct sysdev_class_attribute *attr,
-		     const char *buf, size_t count)
-{
-	unsigned long level;
-
-	level = simple_strtoul(buf, NULL, 10);
-
-	/*
-	 * Minimal acceptable IRQ levels are in the 2 - 16 range, but
-	 * these are chomped so as to not interfere with normal IRQs.
-	 *
-	 * Level 1 is a special case on some CPUs in that it's not
-	 * directly settable, but given that USERIMASK cuts off below a
-	 * certain level, we don't care about this limitation here.
-	 * Level 0 on the other hand equates to user masking disabled.
-	 *
-	 * We use default_prio_level as a cut off so that only special
-	 * case opt-in IRQs can be mangled.
-	 */
-	if (level >= default_prio_level)
-		return -EINVAL;
-
-	__raw_writel(0xa5 << 24 | level << 4, uimask);
-
-	return count;
-}
-
-static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR,
-			 show_intc_userimask, store_intc_userimask);
-#endif
-
-static ssize_t
-show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
-{
-	struct intc_desc_int *d;
-
-	d = container_of(dev, struct intc_desc_int, sysdev);
-
-	return sprintf(buf, "%s\n", d->chip.name);
-}
-
-static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
-
-static int intc_suspend(struct sys_device *dev, pm_message_t state)
-{
-	struct intc_desc_int *d;
-	struct irq_desc *desc;
-	int irq;
-
-	/* get intc controller associated with this sysdev */
-	d = container_of(dev, struct intc_desc_int, sysdev);
-
-	switch (state.event) {
-	case PM_EVENT_ON:
-		if (d->state.event != PM_EVENT_FREEZE)
-			break;
-		for_each_irq_desc(irq, desc) {
-			if (desc->handle_irq == intc_redirect_irq)
-				continue;
-			if (desc->chip != &d->chip)
-				continue;
-			if (desc->status & IRQ_DISABLED)
-				intc_disable(irq);
-			else
-				intc_enable(irq);
-		}
-		break;
-	case PM_EVENT_FREEZE:
-		/* nothing has to be done */
-		break;
-	case PM_EVENT_SUSPEND:
-		/* enable wakeup irqs belonging to this intc controller */
-		for_each_irq_desc(irq, desc) {
-			if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
-				intc_enable(irq);
-		}
-		break;
-	}
-	d->state = state;
-
-	return 0;
-}
-
-static int intc_resume(struct sys_device *dev)
-{
-	return intc_suspend(dev, PMSG_ON);
-}
-
-static struct sysdev_class intc_sysdev_class = {
-	.name = "intc",
-	.suspend = intc_suspend,
-	.resume = intc_resume,
-};
-
-/* register this intc as sysdev to allow suspend/resume */
-static int __init register_intc_sysdevs(void)
-{
-	struct intc_desc_int *d;
-	int error;
-	int id = 0;
-
-	error = sysdev_class_register(&intc_sysdev_class);
-#ifdef CONFIG_INTC_USERIMASK
-	if (!error && uimask)
-		error = sysdev_class_create_file(&intc_sysdev_class,
-						 &attr_userimask);
-#endif
-	if (!error) {
-		list_for_each_entry(d, &intc_list, list) {
-			d->sysdev.id = id;
-			d->sysdev.cls = &intc_sysdev_class;
-			error = sysdev_register(&d->sysdev);
-			if (error == 0)
-				error = sysdev_create_file(&d->sysdev,
-							   &attr_name);
-			if (error)
-				break;
-
-			id++;
-		}
-	}
-
-	if (error)
-		pr_err("sysdev registration error\n");
-
-	return error;
-}
-device_initcall(register_intc_sysdevs);
-
-/*
- * Dynamic IRQ allocation and deallocation
- */
-unsigned int create_irq_nr(unsigned int irq_want, int node)
-{
-	unsigned int irq = 0, new;
-	unsigned long flags;
-	struct irq_desc *desc;
-
-	spin_lock_irqsave(&vector_lock, flags);
-
-	/*
-	 * First try the wanted IRQ
-	 */
-	if (test_and_set_bit(irq_want, intc_irq_map) == 0) {
-		new = irq_want;
-	} else {
-		/* .. then fall back to scanning. */
-		new = find_first_zero_bit(intc_irq_map, nr_irqs);
-		if (unlikely(new == nr_irqs))
-			goto out_unlock;
-
-		__set_bit(new, intc_irq_map);
-	}
-
-	desc = irq_to_desc_alloc_node(new, node);
-	if (unlikely(!desc)) {
-		pr_err("can't get irq_desc for %d\n", new);
-		goto out_unlock;
-	}
-
-	desc = move_irq_desc(desc, node);
-	irq = new;
-
-out_unlock:
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	if (irq > 0) {
-		dynamic_irq_init(irq);
-#ifdef CONFIG_ARM
-		set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
-#endif
-	}
-
-	return irq;
-}
-
-int create_irq(void)
-{
-	int nid = cpu_to_node(smp_processor_id());
-	int irq;
-
-	irq = create_irq_nr(NR_IRQS_LEGACY, nid);
-	if (irq == 0)
-		irq = -1;
-
-	return irq;
-}
-
-void destroy_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	dynamic_irq_cleanup(irq);
-
-	spin_lock_irqsave(&vector_lock, flags);
-	__clear_bit(irq, intc_irq_map);
-	spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-int reserve_irq_vector(unsigned int irq)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	if (test_and_set_bit(irq, intc_irq_map))
-		ret = -EBUSY;
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	return ret;
-}
-
-void reserve_irq_legacy(void)
-{
-	unsigned long flags;
-	int i, j;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	j = find_first_bit(intc_irq_map, nr_irqs);
-	for (i = 0; i < j; i++)
-		__set_bit(i, intc_irq_map);
-	spin_unlock_irqrestore(&vector_lock, flags);
-}
diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig
new file mode 100644
index 0000000..c88cbcc
--- /dev/null
+++ b/drivers/sh/intc/Kconfig
@@ -0,0 +1,35 @@
+comment "Interrupt controller options"
+
+config INTC_USERIMASK
+	bool "Userspace interrupt masking support"
+	depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A)
+	help
+	  This enables support for hardware-assisted userspace hardirq
+	  masking.
+
+	  SH-4A and newer interrupt blocks all support a special shadowed
+	  page with all non-masking registers obscured when mapped in to
+	  userspace. This is primarily for use by userspace device
+	  drivers that are using special priority levels.
+
+	  If in doubt, say N.
+
+config INTC_BALANCING
+	bool "Hardware IRQ balancing support"
+	depends on SMP && SUPERH && CPU_SHX3
+	help
+	  This enables support for IRQ auto-distribution mode on SH-X3
+	  SMP parts. All of the balancing and CPU wakeup decisions are
+	  taken care of automatically by hardware for distributed
+	  vectors.
+
+	  If in doubt, say N.
+
+config INTC_MAPPING_DEBUG
+	bool "Expose IRQ to per-controller id mapping via debugfs"
+	depends on DEBUG_FS
+	help
+	  This will create a debugfs entry for showing the relationship
+	  between system IRQs and the per-controller id tables.
+
+	  If in doubt, say N.
diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile
new file mode 100644
index 0000000..bb5df86
--- /dev/null
+++ b/drivers/sh/intc/Makefile
@@ -0,0 +1,5 @@
+obj-y 	:= access.o chip.o core.o dynamic.o handle.o virq.o
+
+obj-$(CONFIG_INTC_BALANCING)		+= balancing.o
+obj-$(CONFIG_INTC_USERIMASK)		+= userimask.o
+obj-$(CONFIG_INTC_MAPPING_DEBUG)	+= virq-debugfs.o
diff --git a/drivers/sh/intc/access.c b/drivers/sh/intc/access.c
new file mode 100644
index 0000000..f892ae1
--- /dev/null
+++ b/drivers/sh/intc/access.c
@@ -0,0 +1,237 @@
+/*
+ * Common INTC2 register accessors
+ *
+ * Copyright (C) 2007, 2008 Magnus Damm
+ * Copyright (C) 2009, 2010 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/io.h>
+#include "internals.h"
+
+unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address)
+{
+	struct intc_window *window;
+	int k;
+
+	/* scan through physical windows and convert address */
+	for (k = 0; k < d->nr_windows; k++) {
+		window = d->window + k;
+
+		if (address < window->phys)
+			continue;
+
+		if (address >= (window->phys + window->size))
+			continue;
+
+		address -= window->phys;
+		address += (unsigned long)window->virt;
+
+		return address;
+	}
+
+	/* no windows defined, register must be 1:1 mapped virt:phys */
+	return address;
+}
+
+unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address)
+{
+	unsigned int k;
+
+	address = intc_phys_to_virt(d, address);
+
+	for (k = 0; k < d->nr_reg; k++) {
+		if (d->reg[k] == address)
+			return k;
+	}
+
+	BUG();
+	return 0;
+}
+
+unsigned int intc_set_field_from_handle(unsigned int value,
+					unsigned int field_value,
+					unsigned int handle)
+{
+	unsigned int width = _INTC_WIDTH(handle);
+	unsigned int shift = _INTC_SHIFT(handle);
+
+	value &= ~(((1 << width) - 1) << shift);
+	value |= field_value << shift;
+	return value;
+}
+
+unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle)
+{
+	unsigned int width = _INTC_WIDTH(handle);
+	unsigned int shift = _INTC_SHIFT(handle);
+	unsigned int mask = ((1 << width) - 1) << shift;
+
+	return (value & mask) >> shift;
+}
+
+static unsigned long test_8(unsigned long addr, unsigned long h,
+			    unsigned long ignore)
+{
+	return intc_get_field_from_handle(__raw_readb(addr), h);
+}
+
+static unsigned long test_16(unsigned long addr, unsigned long h,
+			     unsigned long ignore)
+{
+	return intc_get_field_from_handle(__raw_readw(addr), h);
+}
+
+static unsigned long test_32(unsigned long addr, unsigned long h,
+			     unsigned long ignore)
+{
+	return intc_get_field_from_handle(__raw_readl(addr), h);
+}
+
+static unsigned long write_8(unsigned long addr, unsigned long h,
+			     unsigned long data)
+{
+	__raw_writeb(intc_set_field_from_handle(0, data, h), addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
+	return 0;
+}
+
+static unsigned long write_16(unsigned long addr, unsigned long h,
+			      unsigned long data)
+{
+	__raw_writew(intc_set_field_from_handle(0, data, h), addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
+	return 0;
+}
+
+static unsigned long write_32(unsigned long addr, unsigned long h,
+			      unsigned long data)
+{
+	__raw_writel(intc_set_field_from_handle(0, data, h), addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
+	return 0;
+}
+
+static unsigned long modify_8(unsigned long addr, unsigned long h,
+			      unsigned long data)
+{
+	unsigned long flags;
+	unsigned int value;
+	local_irq_save(flags);
+	value = intc_set_field_from_handle(__raw_readb(addr), data, h);
+	__raw_writeb(value, addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
+	local_irq_restore(flags);
+	return 0;
+}
+
+static unsigned long modify_16(unsigned long addr, unsigned long h,
+			       unsigned long data)
+{
+	unsigned long flags;
+	unsigned int value;
+	local_irq_save(flags);
+	value = intc_set_field_from_handle(__raw_readw(addr), data, h);
+	__raw_writew(value, addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
+	local_irq_restore(flags);
+	return 0;
+}
+
+static unsigned long modify_32(unsigned long addr, unsigned long h,
+			       unsigned long data)
+{
+	unsigned long flags;
+	unsigned int value;
+	local_irq_save(flags);
+	value = intc_set_field_from_handle(__raw_readl(addr), data, h);
+	__raw_writel(value, addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
+	local_irq_restore(flags);
+	return 0;
+}
+
+static unsigned long intc_mode_field(unsigned long addr,
+				     unsigned long handle,
+				     unsigned long (*fn)(unsigned long,
+						unsigned long,
+						unsigned long),
+				     unsigned int irq)
+{
+	return fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1));
+}
+
+static unsigned long intc_mode_zero(unsigned long addr,
+				    unsigned long handle,
+				    unsigned long (*fn)(unsigned long,
+					       unsigned long,
+					       unsigned long),
+				    unsigned int irq)
+{
+	return fn(addr, handle, 0);
+}
+
+static unsigned long intc_mode_prio(unsigned long addr,
+				    unsigned long handle,
+				    unsigned long (*fn)(unsigned long,
+					       unsigned long,
+					       unsigned long),
+				    unsigned int irq)
+{
+	return fn(addr, handle, intc_get_prio_level(irq));
+}
+
+unsigned long (*intc_reg_fns[])(unsigned long addr,
+				unsigned long h,
+				unsigned long data) = {
+	[REG_FN_TEST_BASE + 0] = test_8,
+	[REG_FN_TEST_BASE + 1] = test_16,
+	[REG_FN_TEST_BASE + 3] = test_32,
+	[REG_FN_WRITE_BASE + 0] = write_8,
+	[REG_FN_WRITE_BASE + 1] = write_16,
+	[REG_FN_WRITE_BASE + 3] = write_32,
+	[REG_FN_MODIFY_BASE + 0] = modify_8,
+	[REG_FN_MODIFY_BASE + 1] = modify_16,
+	[REG_FN_MODIFY_BASE + 3] = modify_32,
+};
+
+unsigned long (*intc_enable_fns[])(unsigned long addr,
+				   unsigned long handle,
+				   unsigned long (*fn)(unsigned long,
+					    unsigned long,
+					    unsigned long),
+				   unsigned int irq) = {
+	[MODE_ENABLE_REG] = intc_mode_field,
+	[MODE_MASK_REG] = intc_mode_zero,
+	[MODE_DUAL_REG] = intc_mode_field,
+	[MODE_PRIO_REG] = intc_mode_prio,
+	[MODE_PCLR_REG] = intc_mode_prio,
+};
+
+unsigned long (*intc_disable_fns[])(unsigned long addr,
+				    unsigned long handle,
+				    unsigned long (*fn)(unsigned long,
+					     unsigned long,
+					     unsigned long),
+				    unsigned int irq) = {
+	[MODE_ENABLE_REG] = intc_mode_zero,
+	[MODE_MASK_REG] = intc_mode_field,
+	[MODE_DUAL_REG] = intc_mode_field,
+	[MODE_PRIO_REG] = intc_mode_zero,
+	[MODE_PCLR_REG] = intc_mode_field,
+};
+
+unsigned long (*intc_enable_noprio_fns[])(unsigned long addr,
+					  unsigned long handle,
+					  unsigned long (*fn)(unsigned long,
+						unsigned long,
+						unsigned long),
+					  unsigned int irq) = {
+	[MODE_ENABLE_REG] = intc_mode_field,
+	[MODE_MASK_REG] = intc_mode_zero,
+	[MODE_DUAL_REG] = intc_mode_field,
+	[MODE_PRIO_REG] = intc_mode_field,
+	[MODE_PCLR_REG] = intc_mode_field,
+};
diff --git a/drivers/sh/intc/balancing.c b/drivers/sh/intc/balancing.c
new file mode 100644
index 0000000..cec7a96
--- /dev/null
+++ b/drivers/sh/intc/balancing.c
@@ -0,0 +1,97 @@
+/*
+ * Support for hardware-managed IRQ auto-distribution.
+ *
+ * Copyright (C) 2010  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 "internals.h"
+
+static unsigned long dist_handle[NR_IRQS];
+
+void intc_balancing_enable(unsigned int irq)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long handle = dist_handle[irq];
+	unsigned long addr;
+
+	if (irq_balancing_disabled(irq) || !handle)
+		return;
+
+	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+	intc_reg_fns[_INTC_FN(handle)](addr, handle, 1);
+}
+
+void intc_balancing_disable(unsigned int irq)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long handle = dist_handle[irq];
+	unsigned long addr;
+
+	if (irq_balancing_disabled(irq) || !handle)
+		return;
+
+	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+	intc_reg_fns[_INTC_FN(handle)](addr, handle, 0);
+}
+
+static unsigned int intc_dist_data(struct intc_desc *desc,
+				   struct intc_desc_int *d,
+				   intc_enum enum_id)
+{
+	struct intc_mask_reg *mr = desc->hw.mask_regs;
+	unsigned int i, j, fn, mode;
+	unsigned long reg_e, reg_d;
+
+	for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) {
+		mr = desc->hw.mask_regs + i;
+
+		/*
+		 * Skip this entry if there's no auto-distribution
+		 * register associated with it.
+		 */
+		if (!mr->dist_reg)
+			continue;
+
+		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+			if (mr->enum_ids[j] != enum_id)
+				continue;
+
+			fn = REG_FN_MODIFY_BASE;
+			mode = MODE_ENABLE_REG;
+			reg_e = mr->dist_reg;
+			reg_d = mr->dist_reg;
+
+			fn += (mr->reg_width >> 3) - 1;
+			return _INTC_MK(fn, mode,
+					intc_get_reg(d, reg_e),
+					intc_get_reg(d, reg_d),
+					1,
+					(mr->reg_width - 1) - j);
+		}
+	}
+
+	/*
+	 * It's possible we've gotten here with no distribution options
+	 * available for the IRQ in question, so we just skip over those.
+	 */
+	return 0;
+}
+
+void intc_set_dist_handle(unsigned int irq, struct intc_desc *desc,
+			  struct intc_desc_int *d, intc_enum id)
+{
+	unsigned long flags;
+
+	/*
+	 * Nothing to do for this IRQ.
+	 */
+	if (!desc->hw.mask_regs)
+		return;
+
+	raw_spin_lock_irqsave(&intc_big_lock, flags);
+	dist_handle[irq] = intc_dist_data(desc, d, id);
+	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
+}
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c
new file mode 100644
index 0000000..35c0370
--- /dev/null
+++ b/drivers/sh/intc/chip.c
@@ -0,0 +1,215 @@
+/*
+ * IRQ chip definitions for INTC IRQs.
+ *
+ * Copyright (C) 2007, 2008 Magnus Damm
+ * Copyright (C) 2009, 2010 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/cpumask.h>
+#include <linux/io.h>
+#include "internals.h"
+
+void _intc_enable(unsigned int irq, unsigned long handle)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long addr;
+	unsigned int cpu;
+
+	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+#ifdef CONFIG_SMP
+		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+			continue;
+#endif
+		addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
+		intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
+						    [_INTC_FN(handle)], irq);
+	}
+
+	intc_balancing_enable(irq);
+}
+
+static void intc_enable(unsigned int irq)
+{
+	_intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
+}
+
+static void intc_disable(unsigned int irq)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long handle = (unsigned long)get_irq_chip_data(irq);
+	unsigned long addr;
+	unsigned int cpu;
+
+	intc_balancing_disable(irq);
+
+	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+#ifdef CONFIG_SMP
+		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+			continue;
+#endif
+		addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
+		intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
+						     [_INTC_FN(handle)], irq);
+	}
+}
+
+static int intc_set_wake(unsigned int irq, unsigned int on)
+{
+	return 0; /* allow wakeup, but setup hardware in intc_suspend() */
+}
+
+#ifdef CONFIG_SMP
+/*
+ * This is held with the irq desc lock held, so we don't require any
+ * additional locking here at the intc desc level. The affinity mask is
+ * later tested in the enable/disable paths.
+ */
+static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+	if (!cpumask_intersects(cpumask, cpu_online_mask))
+		return -1;
+
+	cpumask_copy(irq_to_desc(irq)->affinity, cpumask);
+
+	return 0;
+}
+#endif
+
+static void intc_mask_ack(unsigned int irq)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long handle = intc_get_ack_handle(irq);
+	unsigned long addr;
+
+	intc_disable(irq);
+
+	/* read register and write zero only to the associated bit */
+	if (handle) {
+		unsigned int value;
+
+		addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+		value = intc_set_field_from_handle(0, 1, handle);
+
+		switch (_INTC_FN(handle)) {
+		case REG_FN_MODIFY_BASE + 0:	/* 8bit */
+			__raw_readb(addr);
+			__raw_writeb(0xff ^ value, addr);
+			break;
+		case REG_FN_MODIFY_BASE + 1:	/* 16bit */
+			__raw_readw(addr);
+			__raw_writew(0xffff ^ value, addr);
+			break;
+		case REG_FN_MODIFY_BASE + 3:	/* 32bit */
+			__raw_readl(addr);
+			__raw_writel(0xffffffff ^ value, addr);
+			break;
+		default:
+			BUG();
+			break;
+		}
+	}
+}
+
+static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
+					     unsigned int nr_hp,
+					     unsigned int irq)
+{
+	int i;
+
+	/*
+	 * this doesn't scale well, but...
+	 *
+	 * this function should only be used for cerain uncommon
+	 * operations such as intc_set_priority() and intc_set_type()
+	 * and in those rare cases performance doesn't matter that much.
+	 * keeping the memory footprint low is more important.
+	 *
+	 * one rather simple way to speed this up and still keep the
+	 * memory footprint down is to make sure the array is sorted
+	 * and then perform a bisect to lookup the irq.
+	 */
+	for (i = 0; i < nr_hp; i++) {
+		if ((hp + i)->irq != irq)
+			continue;
+
+		return hp + i;
+	}
+
+	return NULL;
+}
+
+int intc_set_priority(unsigned int irq, unsigned int prio)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	struct intc_handle_int *ihp;
+
+	if (!intc_get_prio_level(irq) || prio <= 1)
+		return -EINVAL;
+
+	ihp = intc_find_irq(d->prio, d->nr_prio, irq);
+	if (ihp) {
+		if (prio >= (1 << _INTC_WIDTH(ihp->handle)))
+			return -EINVAL;
+
+		intc_set_prio_level(irq, prio);
+
+		/*
+		 * only set secondary masking method directly
+		 * primary masking method is using intc_prio_level[irq]
+		 * priority level will be set during next enable()
+		 */
+		if (_INTC_FN(ihp->handle) != REG_FN_ERR)
+			_intc_enable(irq, ihp->handle);
+	}
+	return 0;
+}
+
+#define VALID(x) (x | 0x80)
+
+static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
+	[IRQ_TYPE_EDGE_FALLING] = VALID(0),
+	[IRQ_TYPE_EDGE_RISING] = VALID(1),
+	[IRQ_TYPE_LEVEL_LOW] = VALID(2),
+	/* SH7706, SH7707 and SH7709 do not support high level triggered */
+#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7707) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7709)
+	[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
+#endif
+};
+
+static int intc_set_type(unsigned int irq, unsigned int type)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK];
+	struct intc_handle_int *ihp;
+	unsigned long addr;
+
+	if (!value)
+		return -EINVAL;
+
+	ihp = intc_find_irq(d->sense, d->nr_sense, irq);
+	if (ihp) {
+		addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
+		intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
+	}
+
+	return 0;
+}
+
+struct irq_chip intc_irq_chip	= {
+	.mask		= intc_disable,
+	.unmask		= intc_enable,
+	.mask_ack	= intc_mask_ack,
+	.enable		= intc_enable,
+	.disable	= intc_disable,
+	.shutdown	= intc_disable,
+	.set_type	= intc_set_type,
+	.set_wake	= intc_set_wake,
+#ifdef CONFIG_SMP
+	.set_affinity	= intc_set_affinity,
+#endif
+};
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
new file mode 100644
index 0000000..306ed28
--- /dev/null
+++ b/drivers/sh/intc/core.c
@@ -0,0 +1,469 @@
+/*
+ * Shared interrupt handling code for IPR and INTC2 types of IRQs.
+ *
+ * Copyright (C) 2007, 2008 Magnus Damm
+ * Copyright (C) 2009, 2010 Paul Mundt
+ *
+ * Based on intc2.c and ipr.c
+ *
+ * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
+ * Copyright (C) 2000  Kazumoto Kojima
+ * Copyright (C) 2001  David J. Mckay (david.mckay@st.com)
+ * Copyright (C) 2003  Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ * Copyright (C) 2005, 2006  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.
+ */
+#define pr_fmt(fmt) "intc: " fmt
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/sh_intc.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/radix-tree.h>
+#include "internals.h"
+
+LIST_HEAD(intc_list);
+DEFINE_RAW_SPINLOCK(intc_big_lock);
+unsigned int nr_intc_controllers;
+
+/*
+ * Default priority level
+ * - this needs to be at least 2 for 5-bit priorities on 7780
+ */
+static unsigned int default_prio_level = 2;	/* 2 - 16 */
+static unsigned int intc_prio_level[NR_IRQS];	/* for now */
+
+unsigned int intc_get_dfl_prio_level(void)
+{
+	return default_prio_level;
+}
+
+unsigned int intc_get_prio_level(unsigned int irq)
+{
+	return intc_prio_level[irq];
+}
+
+void intc_set_prio_level(unsigned int irq, unsigned int level)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&intc_big_lock, flags);
+	intc_prio_level[irq] = level;
+	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
+}
+
+static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
+{
+	generic_handle_irq((unsigned int)get_irq_data(irq));
+}
+
+static void __init intc_register_irq(struct intc_desc *desc,
+				     struct intc_desc_int *d,
+				     intc_enum enum_id,
+				     unsigned int irq)
+{
+	struct intc_handle_int *hp;
+	unsigned int data[2], primary;
+	unsigned long flags;
+
+	/*
+	 * Register the IRQ position with the global IRQ map, then insert
+	 * it in to the radix tree.
+	 */
+	reserve_irq_vector(irq);
+
+	raw_spin_lock_irqsave(&intc_big_lock, flags);
+	radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq));
+	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
+
+	/*
+	 * Prefer single interrupt source bitmap over other combinations:
+	 *
+	 * 1. bitmap, single interrupt source
+	 * 2. priority, single interrupt source
+	 * 3. bitmap, multiple interrupt sources (groups)
+	 * 4. priority, multiple interrupt sources (groups)
+	 */
+	data[0] = intc_get_mask_handle(desc, d, enum_id, 0);
+	data[1] = intc_get_prio_handle(desc, d, enum_id, 0);
+
+	primary = 0;
+	if (!data[0] && data[1])
+		primary = 1;
+
+	if (!data[0] && !data[1])
+		pr_warning("missing unique irq mask for irq %d (vect 0x%04x)\n",
+			   irq, irq2evt(irq));
+
+	data[0] = data[0] ? data[0] : intc_get_mask_handle(desc, d, enum_id, 1);
+	data[1] = data[1] ? data[1] : intc_get_prio_handle(desc, d, enum_id, 1);
+
+	if (!data[primary])
+		primary ^= 1;
+
+	BUG_ON(!data[primary]); /* must have primary masking method */
+
+	disable_irq_nosync(irq);
+	set_irq_chip_and_handler_name(irq, &d->chip,
+				      handle_level_irq, "level");
+	set_irq_chip_data(irq, (void *)data[primary]);
+
+	/*
+	 * set priority level
+	 */
+	intc_set_prio_level(irq, intc_get_dfl_prio_level());
+
+	/* enable secondary masking method if present */
+	if (data[!primary])
+		_intc_enable(irq, data[!primary]);
+
+	/* add irq to d->prio list if priority is available */
+	if (data[1]) {
+		hp = d->prio + d->nr_prio;
+		hp->irq = irq;
+		hp->handle = data[1];
+
+		if (primary) {
+			/*
+			 * only secondary priority should access registers, so
+			 * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority()
+			 */
+			hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0);
+			hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0);
+		}
+		d->nr_prio++;
+	}
+
+	/* add irq to d->sense list if sense is available */
+	data[0] = intc_get_sense_handle(desc, d, enum_id);
+	if (data[0]) {
+		(d->sense + d->nr_sense)->irq = irq;
+		(d->sense + d->nr_sense)->handle = data[0];
+		d->nr_sense++;
+	}
+
+	/* irq should be disabled by default */
+	d->chip.mask(irq);
+
+	intc_set_ack_handle(irq, desc, d, enum_id);
+	intc_set_dist_handle(irq, desc, d, enum_id);
+
+	activate_irq(irq);
+}
+
+static unsigned int __init save_reg(struct intc_desc_int *d,
+				    unsigned int cnt,
+				    unsigned long value,
+				    unsigned int smp)
+{
+	if (value) {
+		value = intc_phys_to_virt(d, value);
+
+		d->reg[cnt] = value;
+#ifdef CONFIG_SMP
+		d->smp[cnt] = smp;
+#endif
+		return 1;
+	}
+
+	return 0;
+}
+
+int __init register_intc_controller(struct intc_desc *desc)
+{
+	unsigned int i, k, smp;
+	struct intc_hw_desc *hw = &desc->hw;
+	struct intc_desc_int *d;
+	struct resource *res;
+
+	pr_info("Registered controller '%s' with %u IRQs\n",
+		desc->name, hw->nr_vectors);
+
+	d = kzalloc(sizeof(*d), GFP_NOWAIT);
+	if (!d)
+		goto err0;
+
+	INIT_LIST_HEAD(&d->list);
+	list_add_tail(&d->list, &intc_list);
+
+	raw_spin_lock_init(&d->lock);
+
+	d->index = nr_intc_controllers;
+
+	if (desc->num_resources) {
+		d->nr_windows = desc->num_resources;
+		d->window = kzalloc(d->nr_windows * sizeof(*d->window),
+				    GFP_NOWAIT);
+		if (!d->window)
+			goto err1;
+
+		for (k = 0; k < d->nr_windows; k++) {
+			res = desc->resource + k;
+			WARN_ON(resource_type(res) != IORESOURCE_MEM);
+			d->window[k].phys = res->start;
+			d->window[k].size = resource_size(res);
+			d->window[k].virt = ioremap_nocache(res->start,
+							 resource_size(res));
+			if (!d->window[k].virt)
+				goto err2;
+		}
+	}
+
+	d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0;
+#ifdef CONFIG_INTC_BALANCING
+	if (d->nr_reg)
+		d->nr_reg += hw->nr_mask_regs;
+#endif
+	d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0;
+	d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0;
+	d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0;
+	d->nr_reg += hw->subgroups ? hw->nr_subgroups : 0;
+
+	d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
+	if (!d->reg)
+		goto err2;
+
+#ifdef CONFIG_SMP
+	d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);
+	if (!d->smp)
+		goto err3;
+#endif
+	k = 0;
+
+	if (hw->mask_regs) {
+		for (i = 0; i < hw->nr_mask_regs; i++) {
+			smp = IS_SMP(hw->mask_regs[i]);
+			k += save_reg(d, k, hw->mask_regs[i].set_reg, smp);
+			k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp);
+#ifdef CONFIG_INTC_BALANCING
+			k += save_reg(d, k, hw->mask_regs[i].dist_reg, 0);
+#endif
+		}
+	}
+
+	if (hw->prio_regs) {
+		d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio),
+				  GFP_NOWAIT);
+		if (!d->prio)
+			goto err4;
+
+		for (i = 0; i < hw->nr_prio_regs; i++) {
+			smp = IS_SMP(hw->prio_regs[i]);
+			k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
+			k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
+		}
+	}
+
+	if (hw->sense_regs) {
+		d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense),
+				   GFP_NOWAIT);
+		if (!d->sense)
+			goto err5;
+
+		for (i = 0; i < hw->nr_sense_regs; i++)
+			k += save_reg(d, k, hw->sense_regs[i].reg, 0);
+	}
+
+	if (hw->subgroups)
+		for (i = 0; i < hw->nr_subgroups; i++)
+			if (hw->subgroups[i].reg)
+				k+= save_reg(d, k, hw->subgroups[i].reg, 0);
+
+	memcpy(&d->chip, &intc_irq_chip, sizeof(struct irq_chip));
+	d->chip.name = desc->name;
+
+	if (hw->ack_regs)
+		for (i = 0; i < hw->nr_ack_regs; i++)
+			k += save_reg(d, k, hw->ack_regs[i].set_reg, 0);
+	else
+		d->chip.mask_ack = d->chip.disable;
+
+	/* disable bits matching force_disable before registering irqs */
+	if (desc->force_disable)
+		intc_enable_disable_enum(desc, d, desc->force_disable, 0);
+
+	/* disable bits matching force_enable before registering irqs */
+	if (desc->force_enable)
+		intc_enable_disable_enum(desc, d, desc->force_enable, 0);
+
+	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+
+	/* register the vectors one by one */
+	for (i = 0; i < hw->nr_vectors; i++) {
+		struct intc_vect *vect = hw->vectors + i;
+		unsigned int irq = evt2irq(vect->vect);
+		struct irq_desc *irq_desc;
+
+		if (!vect->enum_id)
+			continue;
+
+		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
+		if (unlikely(!irq_desc)) {
+			pr_err("can't get irq_desc for %d\n", irq);
+			continue;
+		}
+
+		intc_irq_xlate_set(irq, vect->enum_id, d);
+		intc_register_irq(desc, d, vect->enum_id, irq);
+
+		for (k = i + 1; k < hw->nr_vectors; k++) {
+			struct intc_vect *vect2 = hw->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_err("can't get irq_desc for %d\n", irq2);
+				continue;
+			}
+
+			vect2->enum_id = 0;
+
+			/* redirect this interrupts to the first one */
+			set_irq_chip(irq2, &dummy_irq_chip);
+			set_irq_chained_handler(irq2, intc_redirect_irq);
+			set_irq_data(irq2, (void *)irq);
+		}
+	}
+
+	intc_subgroup_init(desc, d);
+
+	/* enable bits matching force_enable after registering irqs */
+	if (desc->force_enable)
+		intc_enable_disable_enum(desc, d, desc->force_enable, 1);
+
+	nr_intc_controllers++;
+
+	return 0;
+err5:
+	kfree(d->prio);
+err4:
+#ifdef CONFIG_SMP
+	kfree(d->smp);
+err3:
+#endif
+	kfree(d->reg);
+err2:
+	for (k = 0; k < d->nr_windows; k++)
+		if (d->window[k].virt)
+			iounmap(d->window[k].virt);
+
+	kfree(d->window);
+err1:
+	kfree(d);
+err0:
+	pr_err("unable to allocate INTC memory\n");
+
+	return -ENOMEM;
+}
+
+static ssize_t
+show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
+{
+	struct intc_desc_int *d;
+
+	d = container_of(dev, struct intc_desc_int, sysdev);
+
+	return sprintf(buf, "%s\n", d->chip.name);
+}
+
+static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+
+static int intc_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct intc_desc_int *d;
+	struct irq_desc *desc;
+	int irq;
+
+	/* get intc controller associated with this sysdev */
+	d = container_of(dev, struct intc_desc_int, sysdev);
+
+	switch (state.event) {
+	case PM_EVENT_ON:
+		if (d->state.event != PM_EVENT_FREEZE)
+			break;
+
+		for_each_irq_desc(irq, desc) {
+			/*
+			 * This will catch the redirect and VIRQ cases
+			 * due to the dummy_irq_chip being inserted.
+			 */
+			if (desc->chip != &d->chip)
+				continue;
+			if (desc->status & IRQ_DISABLED)
+				desc->chip->disable(irq);
+			else
+				desc->chip->enable(irq);
+		}
+		break;
+	case PM_EVENT_FREEZE:
+		/* nothing has to be done */
+		break;
+	case PM_EVENT_SUSPEND:
+		/* enable wakeup irqs belonging to this intc controller */
+		for_each_irq_desc(irq, desc) {
+			if (desc->chip != &d->chip)
+				continue;
+			if ((desc->status & IRQ_WAKEUP))
+				desc->chip->enable(irq);
+		}
+		break;
+	}
+
+	d->state = state;
+
+	return 0;
+}
+
+static int intc_resume(struct sys_device *dev)
+{
+	return intc_suspend(dev, PMSG_ON);
+}
+
+struct sysdev_class intc_sysdev_class = {
+	.name		= "intc",
+	.suspend	= intc_suspend,
+	.resume		= intc_resume,
+};
+
+/* register this intc as sysdev to allow suspend/resume */
+static int __init register_intc_sysdevs(void)
+{
+	struct intc_desc_int *d;
+	int error;
+
+	error = sysdev_class_register(&intc_sysdev_class);
+	if (!error) {
+		list_for_each_entry(d, &intc_list, list) {
+			d->sysdev.id = d->index;
+			d->sysdev.cls = &intc_sysdev_class;
+			error = sysdev_register(&d->sysdev);
+			if (error == 0)
+				error = sysdev_create_file(&d->sysdev,
+							   &attr_name);
+			if (error)
+				break;
+		}
+	}
+
+	if (error)
+		pr_err("sysdev registration error\n");
+
+	return error;
+}
+device_initcall(register_intc_sysdevs);
diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c
new file mode 100644
index 0000000..6caecdf
--- /dev/null
+++ b/drivers/sh/intc/dynamic.c
@@ -0,0 +1,135 @@
+/*
+ * Dynamic IRQ management
+ *
+ * Copyright (C) 2010  Paul Mundt
+ *
+ * Modelled after arch/x86/kernel/apic/io_apic.c
+ *
+ * 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.
+ */
+#define pr_fmt(fmt) "intc: " fmt
+
+#include <linux/irq.h>
+#include <linux/bitmap.h>
+#include <linux/spinlock.h>
+#include "internals.h" /* only for activate_irq() damage.. */
+
+/*
+ * The intc_irq_map provides a global map of bound IRQ vectors for a
+ * given platform. Allocation of IRQs are either static through the CPU
+ * vector map, or dynamic in the case of board mux vectors or MSI.
+ *
+ * As this is a central point for all IRQ controllers on the system,
+ * each of the available sources are mapped out here. This combined with
+ * sparseirq makes it quite trivial to keep the vector map tightly packed
+ * when dynamically creating IRQs, as well as tying in to otherwise
+ * unused irq_desc positions in the sparse array.
+ */
+static DECLARE_BITMAP(intc_irq_map, NR_IRQS);
+static DEFINE_RAW_SPINLOCK(vector_lock);
+
+/*
+ * Dynamic IRQ allocation and deallocation
+ */
+unsigned int create_irq_nr(unsigned int irq_want, int node)
+{
+	unsigned int irq = 0, new;
+	unsigned long flags;
+	struct irq_desc *desc;
+
+	raw_spin_lock_irqsave(&vector_lock, flags);
+
+	/*
+	 * First try the wanted IRQ
+	 */
+	if (test_and_set_bit(irq_want, intc_irq_map) == 0) {
+		new = irq_want;
+	} else {
+		/* .. then fall back to scanning. */
+		new = find_first_zero_bit(intc_irq_map, nr_irqs);
+		if (unlikely(new == nr_irqs))
+			goto out_unlock;
+
+		__set_bit(new, intc_irq_map);
+	}
+
+	desc = irq_to_desc_alloc_node(new, node);
+	if (unlikely(!desc)) {
+		pr_err("can't get irq_desc for %d\n", new);
+		goto out_unlock;
+	}
+
+	desc = move_irq_desc(desc, node);
+	irq = new;
+
+out_unlock:
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq > 0) {
+		dynamic_irq_init(irq);
+		activate_irq(irq);
+	}
+
+	return irq;
+}
+
+int create_irq(void)
+{
+	int nid = cpu_to_node(smp_processor_id());
+	int irq;
+
+	irq = create_irq_nr(NR_IRQS_LEGACY, nid);
+	if (irq == 0)
+		irq = -1;
+
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	dynamic_irq_cleanup(irq);
+
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	__clear_bit(irq, intc_irq_map);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+int reserve_irq_vector(unsigned int irq)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	if (test_and_set_bit(irq, intc_irq_map))
+		ret = -EBUSY;
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+
+	return ret;
+}
+
+void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs)
+{
+	unsigned long flags;
+	int i;
+
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	for (i = 0; i < nr_vecs; i++)
+		__set_bit(evt2irq(vectors[i].vect), intc_irq_map);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+void reserve_irq_legacy(void)
+{
+	unsigned long flags;
+	int i, j;
+
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	j = find_first_bit(intc_irq_map, nr_irqs);
+	for (i = 0; i < j; i++)
+		__set_bit(i, intc_irq_map);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+}
diff --git a/drivers/sh/intc/handle.c b/drivers/sh/intc/handle.c
new file mode 100644
index 0000000..057ce56
--- /dev/null
+++ b/drivers/sh/intc/handle.c
@@ -0,0 +1,307 @@
+/*
+ * Shared interrupt handling code for IPR and INTC2 types of IRQs.
+ *
+ * Copyright (C) 2007, 2008 Magnus Damm
+ * Copyright (C) 2009, 2010 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/irq.h>
+#include <linux/spinlock.h>
+#include "internals.h"
+
+static unsigned long ack_handle[NR_IRQS];
+
+static intc_enum __init intc_grp_id(struct intc_desc *desc,
+				    intc_enum enum_id)
+{
+	struct intc_group *g = desc->hw.groups;
+	unsigned int i, j;
+
+	for (i = 0; g && enum_id && i < desc->hw.nr_groups; i++) {
+		g = desc->hw.groups + i;
+
+		for (j = 0; g->enum_ids[j]; j++) {
+			if (g->enum_ids[j] != enum_id)
+				continue;
+
+			return g->enum_id;
+		}
+	}
+
+	return 0;
+}
+
+static unsigned int __init _intc_mask_data(struct intc_desc *desc,
+					   struct intc_desc_int *d,
+					   intc_enum enum_id,
+					   unsigned int *reg_idx,
+					   unsigned int *fld_idx)
+{
+	struct intc_mask_reg *mr = desc->hw.mask_regs;
+	unsigned int fn, mode;
+	unsigned long reg_e, reg_d;
+
+	while (mr && enum_id && *reg_idx < desc->hw.nr_mask_regs) {
+		mr = desc->hw.mask_regs + *reg_idx;
+
+		for (; *fld_idx < ARRAY_SIZE(mr->enum_ids); (*fld_idx)++) {
+			if (mr->enum_ids[*fld_idx] != enum_id)
+				continue;
+
+			if (mr->set_reg && mr->clr_reg) {
+				fn = REG_FN_WRITE_BASE;
+				mode = MODE_DUAL_REG;
+				reg_e = mr->clr_reg;
+				reg_d = mr->set_reg;
+			} else {
+				fn = REG_FN_MODIFY_BASE;
+				if (mr->set_reg) {
+					mode = MODE_ENABLE_REG;
+					reg_e = mr->set_reg;
+					reg_d = mr->set_reg;
+				} else {
+					mode = MODE_MASK_REG;
+					reg_e = mr->clr_reg;
+					reg_d = mr->clr_reg;
+				}
+			}
+
+			fn += (mr->reg_width >> 3) - 1;
+			return _INTC_MK(fn, mode,
+					intc_get_reg(d, reg_e),
+					intc_get_reg(d, reg_d),
+					1,
+					(mr->reg_width - 1) - *fld_idx);
+		}
+
+		*fld_idx = 0;
+		(*reg_idx)++;
+	}
+
+	return 0;
+}
+
+unsigned int __init
+intc_get_mask_handle(struct intc_desc *desc, struct intc_desc_int *d,
+		     intc_enum enum_id, int do_grps)
+{
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int ret;
+
+	ret = _intc_mask_data(desc, d, enum_id, &i, &j);
+	if (ret)
+		return ret;
+
+	if (do_grps)
+		return intc_get_mask_handle(desc, d, intc_grp_id(desc, enum_id), 0);
+
+	return 0;
+}
+
+static unsigned int __init _intc_prio_data(struct intc_desc *desc,
+					   struct intc_desc_int *d,
+					   intc_enum enum_id,
+					   unsigned int *reg_idx,
+					   unsigned int *fld_idx)
+{
+	struct intc_prio_reg *pr = desc->hw.prio_regs;
+	unsigned int fn, n, mode, bit;
+	unsigned long reg_e, reg_d;
+
+	while (pr && enum_id && *reg_idx < desc->hw.nr_prio_regs) {
+		pr = desc->hw.prio_regs + *reg_idx;
+
+		for (; *fld_idx < ARRAY_SIZE(pr->enum_ids); (*fld_idx)++) {
+			if (pr->enum_ids[*fld_idx] != enum_id)
+				continue;
+
+			if (pr->set_reg && pr->clr_reg) {
+				fn = REG_FN_WRITE_BASE;
+				mode = MODE_PCLR_REG;
+				reg_e = pr->set_reg;
+				reg_d = pr->clr_reg;
+			} else {
+				fn = REG_FN_MODIFY_BASE;
+				mode = MODE_PRIO_REG;
+				if (!pr->set_reg)
+					BUG();
+				reg_e = pr->set_reg;
+				reg_d = pr->set_reg;
+			}
+
+			fn += (pr->reg_width >> 3) - 1;
+			n = *fld_idx + 1;
+
+			BUG_ON(n * pr->field_width > pr->reg_width);
+
+			bit = pr->reg_width - (n * pr->field_width);
+
+			return _INTC_MK(fn, mode,
+					intc_get_reg(d, reg_e),
+					intc_get_reg(d, reg_d),
+					pr->field_width, bit);
+		}
+
+		*fld_idx = 0;
+		(*reg_idx)++;
+	}
+
+	return 0;
+}
+
+unsigned int __init
+intc_get_prio_handle(struct intc_desc *desc, struct intc_desc_int *d,
+		     intc_enum enum_id, int do_grps)
+{
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int ret;
+
+	ret = _intc_prio_data(desc, d, enum_id, &i, &j);
+	if (ret)
+		return ret;
+
+	if (do_grps)
+		return intc_get_prio_handle(desc, d, intc_grp_id(desc, enum_id), 0);
+
+	return 0;
+}
+
+static unsigned int __init intc_ack_data(struct intc_desc *desc,
+					  struct intc_desc_int *d,
+					  intc_enum enum_id)
+{
+	struct intc_mask_reg *mr = desc->hw.ack_regs;
+	unsigned int i, j, fn, mode;
+	unsigned long reg_e, reg_d;
+
+	for (i = 0; mr && enum_id && i < desc->hw.nr_ack_regs; i++) {
+		mr = desc->hw.ack_regs + i;
+
+		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+			if (mr->enum_ids[j] != enum_id)
+				continue;
+
+			fn = REG_FN_MODIFY_BASE;
+			mode = MODE_ENABLE_REG;
+			reg_e = mr->set_reg;
+			reg_d = mr->set_reg;
+
+			fn += (mr->reg_width >> 3) - 1;
+			return _INTC_MK(fn, mode,
+					intc_get_reg(d, reg_e),
+					intc_get_reg(d, reg_d),
+					1,
+					(mr->reg_width - 1) - j);
+		}
+	}
+
+	return 0;
+}
+
+static void intc_enable_disable(struct intc_desc_int *d,
+				unsigned long handle, int do_enable)
+{
+	unsigned long addr;
+	unsigned int cpu;
+	unsigned long (*fn)(unsigned long, unsigned long,
+		   unsigned long (*)(unsigned long, unsigned long,
+				     unsigned long),
+		   unsigned int);
+
+	if (do_enable) {
+		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+			addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
+			fn = intc_enable_noprio_fns[_INTC_MODE(handle)];
+			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+		}
+	} else {
+		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+			addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
+			fn = intc_disable_fns[_INTC_MODE(handle)];
+			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+		}
+	}
+}
+
+void __init intc_enable_disable_enum(struct intc_desc *desc,
+				     struct intc_desc_int *d,
+				     intc_enum enum_id, int enable)
+{
+	unsigned int i, j, data;
+
+	/* go through and enable/disable all mask bits */
+	i = j = 0;
+	do {
+		data = _intc_mask_data(desc, d, enum_id, &i, &j);
+		if (data)
+			intc_enable_disable(d, data, enable);
+		j++;
+	} while (data);
+
+	/* go through and enable/disable all priority fields */
+	i = j = 0;
+	do {
+		data = _intc_prio_data(desc, d, enum_id, &i, &j);
+		if (data)
+			intc_enable_disable(d, data, enable);
+
+		j++;
+	} while (data);
+}
+
+unsigned int __init
+intc_get_sense_handle(struct intc_desc *desc, struct intc_desc_int *d,
+		      intc_enum enum_id)
+{
+	struct intc_sense_reg *sr = desc->hw.sense_regs;
+	unsigned int i, j, fn, bit;
+
+	for (i = 0; sr && enum_id && i < desc->hw.nr_sense_regs; i++) {
+		sr = desc->hw.sense_regs + i;
+
+		for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
+			if (sr->enum_ids[j] != enum_id)
+				continue;
+
+			fn = REG_FN_MODIFY_BASE;
+			fn += (sr->reg_width >> 3) - 1;
+
+			BUG_ON((j + 1) * sr->field_width > sr->reg_width);
+
+			bit = sr->reg_width - ((j + 1) * sr->field_width);
+
+			return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg),
+					0, sr->field_width, bit);
+		}
+	}
+
+	return 0;
+}
+
+
+void intc_set_ack_handle(unsigned int irq, struct intc_desc *desc,
+			 struct intc_desc_int *d, intc_enum id)
+{
+	unsigned long flags;
+
+	/*
+	 * Nothing to do for this IRQ.
+	 */
+	if (!desc->hw.ack_regs)
+		return;
+
+	raw_spin_lock_irqsave(&intc_big_lock, flags);
+	ack_handle[irq] = intc_ack_data(desc, d, id);
+	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
+}
+
+unsigned long intc_get_ack_handle(unsigned int irq)
+{
+	return ack_handle[irq];
+}
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
new file mode 100644
index 0000000..d49482c
--- /dev/null
+++ b/drivers/sh/intc/internals.h
@@ -0,0 +1,186 @@
+#include <linux/sh_intc.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/radix-tree.h>
+#include <linux/sysdev.h>
+
+#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
+	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
+	 ((addr_e) << 16) | ((addr_d << 24)))
+
+#define _INTC_SHIFT(h)		(h & 0x1f)
+#define _INTC_WIDTH(h)		((h >> 5) & 0xf)
+#define _INTC_FN(h)		((h >> 9) & 0xf)
+#define _INTC_MODE(h)		((h >> 13) & 0x7)
+#define _INTC_ADDR_E(h)		((h >> 16) & 0xff)
+#define _INTC_ADDR_D(h)		((h >> 24) & 0xff)
+
+#ifdef CONFIG_SMP
+#define IS_SMP(x)		(x.smp)
+#define INTC_REG(d, x, c)	(d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
+#define SMP_NR(d, x)		((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1)
+#else
+#define IS_SMP(x)		0
+#define INTC_REG(d, x, c)	(d->reg[(x)])
+#define SMP_NR(d, x)		1
+#endif
+
+struct intc_handle_int {
+	unsigned int irq;
+	unsigned long handle;
+};
+
+struct intc_window {
+	phys_addr_t phys;
+	void __iomem *virt;
+	unsigned long size;
+};
+
+struct intc_map_entry {
+	intc_enum enum_id;
+	struct intc_desc_int *desc;
+};
+
+struct intc_subgroup_entry {
+	unsigned int pirq;
+	intc_enum enum_id;
+	unsigned long handle;
+};
+
+struct intc_desc_int {
+	struct list_head list;
+	struct sys_device sysdev;
+	struct radix_tree_root tree;
+	pm_message_t state;
+	raw_spinlock_t lock;
+	unsigned int index;
+	unsigned long *reg;
+#ifdef CONFIG_SMP
+	unsigned long *smp;
+#endif
+	unsigned int nr_reg;
+	struct intc_handle_int *prio;
+	unsigned int nr_prio;
+	struct intc_handle_int *sense;
+	unsigned int nr_sense;
+	struct intc_window *window;
+	unsigned int nr_windows;
+	struct irq_chip chip;
+};
+
+
+enum {
+	REG_FN_ERR = 0,
+	REG_FN_TEST_BASE = 1,
+	REG_FN_WRITE_BASE = 5,
+	REG_FN_MODIFY_BASE = 9
+};
+
+enum {	MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
+	MODE_MASK_REG,       /* Bit(s) set -> interrupt disabled */
+	MODE_DUAL_REG,       /* Two registers, set bit to enable / disable */
+	MODE_PRIO_REG,       /* Priority value written to enable interrupt */
+	MODE_PCLR_REG,       /* Above plus all bits set to disable interrupt */
+};
+
+static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
+{
+	struct irq_chip *chip = get_irq_chip(irq);
+
+	return container_of(chip, struct intc_desc_int, chip);
+}
+
+/*
+ * Grumble.
+ */
+static inline void activate_irq(int irq)
+{
+#ifdef CONFIG_ARM
+	/* ARM requires an extra step to clear IRQ_NOREQUEST, which it
+	 * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
+	 */
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	/* same effect on other architectures */
+	set_irq_noprobe(irq);
+#endif
+}
+
+/* access.c */
+extern unsigned long
+(*intc_reg_fns[])(unsigned long addr, unsigned long h, unsigned long data);
+
+extern unsigned long
+(*intc_enable_fns[])(unsigned long addr, unsigned long handle,
+		     unsigned long (*fn)(unsigned long,
+				unsigned long, unsigned long),
+		     unsigned int irq);
+extern unsigned long
+(*intc_disable_fns[])(unsigned long addr, unsigned long handle,
+		      unsigned long (*fn)(unsigned long,
+				unsigned long, unsigned long),
+		      unsigned int irq);
+extern unsigned long
+(*intc_enable_noprio_fns[])(unsigned long addr, unsigned long handle,
+		            unsigned long (*fn)(unsigned long,
+				unsigned long, unsigned long),
+			    unsigned int irq);
+
+unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address);
+unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address);
+unsigned int intc_set_field_from_handle(unsigned int value,
+			    unsigned int field_value,
+			    unsigned int handle);
+unsigned long intc_get_field_from_handle(unsigned int value,
+					 unsigned int handle);
+
+/* balancing.c */
+#ifdef CONFIG_INTC_BALANCING
+void intc_balancing_enable(unsigned int irq);
+void intc_balancing_disable(unsigned int irq);
+void intc_set_dist_handle(unsigned int irq, struct intc_desc *desc,
+			  struct intc_desc_int *d, intc_enum id);
+#else
+static inline void intc_balancing_enable(unsigned int irq) { }
+static inline void intc_balancing_disable(unsigned int irq) { }
+static inline void
+intc_set_dist_handle(unsigned int irq, struct intc_desc *desc,
+		     struct intc_desc_int *d, intc_enum id) { }
+#endif
+
+/* chip.c */
+extern struct irq_chip intc_irq_chip;
+void _intc_enable(unsigned int irq, unsigned long handle);
+
+/* core.c */
+extern struct list_head intc_list;
+extern raw_spinlock_t intc_big_lock;
+extern unsigned int nr_intc_controllers;
+extern struct sysdev_class intc_sysdev_class;
+
+unsigned int intc_get_dfl_prio_level(void);
+unsigned int intc_get_prio_level(unsigned int irq);
+void intc_set_prio_level(unsigned int irq, unsigned int level);
+
+/* handle.c */
+unsigned int intc_get_mask_handle(struct intc_desc *desc,
+				  struct intc_desc_int *d,
+				  intc_enum enum_id, int do_grps);
+unsigned int intc_get_prio_handle(struct intc_desc *desc,
+				  struct intc_desc_int *d,
+				  intc_enum enum_id, int do_grps);
+unsigned int intc_get_sense_handle(struct intc_desc *desc,
+				   struct intc_desc_int *d,
+				   intc_enum enum_id);
+void intc_set_ack_handle(unsigned int irq, struct intc_desc *desc,
+			 struct intc_desc_int *d, intc_enum id);
+unsigned long intc_get_ack_handle(unsigned int irq);
+void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d,
+			      intc_enum enum_id, int enable);
+
+/* virq.c */
+void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d);
+void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d);
+struct intc_map_entry *intc_irq_xlate_get(unsigned int irq);
diff --git a/drivers/sh/intc/userimask.c b/drivers/sh/intc/userimask.c
new file mode 100644
index 0000000..e32304b
--- /dev/null
+++ b/drivers/sh/intc/userimask.c
@@ -0,0 +1,83 @@
+/*
+ * Support for hardware-assisted userspace interrupt masking.
+ *
+ * Copyright (C) 2010  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.
+ */
+#define pr_fmt(fmt) "intc: " fmt
+
+#include <linux/errno.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/sizes.h>
+#include "internals.h"
+
+static void __iomem *uimask;
+
+static ssize_t
+show_intc_userimask(struct sysdev_class *cls,
+		    struct sysdev_class_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
+}
+
+static ssize_t
+store_intc_userimask(struct sysdev_class *cls,
+		     struct sysdev_class_attribute *attr,
+		     const char *buf, size_t count)
+{
+	unsigned long level;
+
+	level = simple_strtoul(buf, NULL, 10);
+
+	/*
+	 * Minimal acceptable IRQ levels are in the 2 - 16 range, but
+	 * these are chomped so as to not interfere with normal IRQs.
+	 *
+	 * Level 1 is a special case on some CPUs in that it's not
+	 * directly settable, but given that USERIMASK cuts off below a
+	 * certain level, we don't care about this limitation here.
+	 * Level 0 on the other hand equates to user masking disabled.
+	 *
+	 * We use the default priority level as a cut off so that only
+	 * special case opt-in IRQs can be mangled.
+	 */
+	if (level >= intc_get_dfl_prio_level())
+		return -EINVAL;
+
+	__raw_writel(0xa5 << 24 | level << 4, uimask);
+
+	return count;
+}
+
+static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR,
+			 show_intc_userimask, store_intc_userimask);
+
+
+static int __init userimask_sysdev_init(void)
+{
+	if (unlikely(!uimask))
+		return -ENXIO;
+
+	return sysdev_class_create_file(&intc_sysdev_class, &attr_userimask);
+}
+late_initcall(userimask_sysdev_init);
+
+int register_intc_userimask(unsigned long addr)
+{
+	if (unlikely(uimask))
+		return -EBUSY;
+
+	uimask = ioremap_nocache(addr, SZ_4K);
+	if (unlikely(!uimask))
+		return -ENOMEM;
+
+	pr_info("userimask support registered for levels 0 -> %d\n",
+		intc_get_dfl_prio_level() - 1);
+
+	return 0;
+}
diff --git a/drivers/sh/intc/virq-debugfs.c b/drivers/sh/intc/virq-debugfs.c
new file mode 100644
index 0000000..9e62ba9
--- /dev/null
+++ b/drivers/sh/intc/virq-debugfs.c
@@ -0,0 +1,64 @@
+/*
+ * Support for virtual IRQ subgroups debugfs mapping.
+ *
+ * Copyright (C) 2010  Paul Mundt
+ *
+ * Modelled after arch/powerpc/kernel/irq.c.
+ *
+ * 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/seq_file.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/debugfs.h>
+#include "internals.h"
+
+static int intc_irq_xlate_debug(struct seq_file *m, void *priv)
+{
+	int i;
+
+	seq_printf(m, "%-5s  %-7s  %-15s\n", "irq", "enum", "chip name");
+
+	for (i = 1; i < nr_irqs; i++) {
+		struct intc_map_entry *entry = intc_irq_xlate_get(i);
+		struct intc_desc_int *desc = entry->desc;
+
+		if (!desc)
+			continue;
+
+		seq_printf(m, "%5d  ", i);
+		seq_printf(m, "0x%05x  ", entry->enum_id);
+		seq_printf(m, "%-15s\n", desc->chip.name);
+	}
+
+	return 0;
+}
+
+static int intc_irq_xlate_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, intc_irq_xlate_debug, inode->i_private);
+}
+
+static const struct file_operations intc_irq_xlate_fops = {
+	.open = intc_irq_xlate_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int __init intc_irq_xlate_init(void)
+{
+	/*
+	 * XXX.. use arch_debugfs_dir here when all of the intc users are
+	 * converted.
+	 */
+	if (debugfs_create_file("intc_irq_xlate", S_IRUGO, NULL, NULL,
+				&intc_irq_xlate_fops) == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+fs_initcall(intc_irq_xlate_init);
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
new file mode 100644
index 0000000..643dfd4
--- /dev/null
+++ b/drivers/sh/intc/virq.c
@@ -0,0 +1,255 @@
+/*
+ * Support for virtual IRQ subgroups.
+ *
+ * Copyright (C) 2010  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.
+ */
+#define pr_fmt(fmt) "intc: " fmt
+
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/radix-tree.h>
+#include <linux/spinlock.h>
+#include "internals.h"
+
+static struct intc_map_entry intc_irq_xlate[NR_IRQS];
+
+struct intc_virq_list {
+	unsigned int irq;
+	struct intc_virq_list *next;
+};
+
+#define for_each_virq(entry, head) \
+	for (entry = head; entry; entry = entry->next)
+
+/*
+ * Tags for the radix tree
+ */
+#define INTC_TAG_VIRQ_NEEDS_ALLOC	0
+
+void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&intc_big_lock, flags);
+	intc_irq_xlate[irq].enum_id = id;
+	intc_irq_xlate[irq].desc = d;
+	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
+}
+
+struct intc_map_entry *intc_irq_xlate_get(unsigned int irq)
+{
+	return intc_irq_xlate + irq;
+}
+
+int intc_irq_lookup(const char *chipname, intc_enum enum_id)
+{
+	struct intc_map_entry *ptr;
+	struct intc_desc_int *d;
+	int irq = -1;
+
+	list_for_each_entry(d, &intc_list, list) {
+		int tagged;
+
+		if (strcmp(d->chip.name, chipname) != 0)
+			continue;
+
+		/*
+		 * Catch early lookups for subgroup VIRQs that have not
+		 * yet been allocated an IRQ. This already includes a
+		 * fast-path out if the tree is untagged, so there is no
+		 * need to explicitly test the root tree.
+		 */
+		tagged = radix_tree_tag_get(&d->tree, enum_id,
+					    INTC_TAG_VIRQ_NEEDS_ALLOC);
+		if (unlikely(tagged))
+			break;
+
+		ptr = radix_tree_lookup(&d->tree, enum_id);
+		if (ptr) {
+			irq = ptr - intc_irq_xlate;
+			break;
+		}
+	}
+
+	return irq;
+}
+EXPORT_SYMBOL_GPL(intc_irq_lookup);
+
+static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
+{
+	struct intc_virq_list **last, *entry;
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	/* scan for duplicates */
+	last = (struct intc_virq_list **)&desc->handler_data;
+	for_each_virq(entry, desc->handler_data) {
+		if (entry->irq == virq)
+			return 0;
+		last = &entry->next;
+	}
+
+	entry = kzalloc(sizeof(struct intc_virq_list), GFP_ATOMIC);
+	if (!entry) {
+		pr_err("can't allocate VIRQ mapping for %d\n", virq);
+		return -ENOMEM;
+	}
+
+	entry->irq = virq;
+
+	*last = entry;
+
+	return 0;
+}
+
+static void intc_virq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct intc_virq_list *entry, *vlist = get_irq_data(irq);
+	struct intc_desc_int *d = get_intc_desc(irq);
+
+	desc->chip->mask_ack(irq);
+
+	for_each_virq(entry, vlist) {
+		unsigned long addr, handle;
+
+		handle = (unsigned long)get_irq_data(entry->irq);
+		addr = INTC_REG(d, _INTC_ADDR_E(handle), 0);
+
+		if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0))
+			generic_handle_irq(entry->irq);
+	}
+
+	desc->chip->unmask(irq);
+}
+
+static unsigned long __init intc_subgroup_data(struct intc_subgroup *subgroup,
+					       struct intc_desc_int *d,
+					       unsigned int index)
+{
+	unsigned int fn = REG_FN_TEST_BASE + (subgroup->reg_width >> 3) - 1;
+
+	return _INTC_MK(fn, MODE_ENABLE_REG, intc_get_reg(d, subgroup->reg),
+			0, 1, (subgroup->reg_width - 1) - index);
+}
+
+static void __init intc_subgroup_init_one(struct intc_desc *desc,
+					  struct intc_desc_int *d,
+					  struct intc_subgroup *subgroup)
+{
+	struct intc_map_entry *mapped;
+	unsigned int pirq;
+	unsigned long flags;
+	int i;
+
+	mapped = radix_tree_lookup(&d->tree, subgroup->parent_id);
+	if (!mapped) {
+		WARN_ON(1);
+		return;
+	}
+
+	pirq = mapped - intc_irq_xlate;
+
+	raw_spin_lock_irqsave(&d->lock, flags);
+
+	for (i = 0; i < ARRAY_SIZE(subgroup->enum_ids); i++) {
+		struct intc_subgroup_entry *entry;
+		int err;
+
+		if (!subgroup->enum_ids[i])
+			continue;
+
+		entry = kmalloc(sizeof(*entry), GFP_NOWAIT);
+		if (!entry)
+			break;
+
+		entry->pirq = pirq;
+		entry->enum_id = subgroup->enum_ids[i];
+		entry->handle = intc_subgroup_data(subgroup, d, i);
+
+		err = radix_tree_insert(&d->tree, entry->enum_id, entry);
+		if (unlikely(err < 0))
+			break;
+
+		radix_tree_tag_set(&d->tree, entry->enum_id,
+				   INTC_TAG_VIRQ_NEEDS_ALLOC);
+	}
+
+	raw_spin_unlock_irqrestore(&d->lock, flags);
+}
+
+void __init intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d)
+{
+	int i;
+
+	if (!desc->hw.subgroups)
+		return;
+
+	for (i = 0; i < desc->hw.nr_subgroups; i++)
+		intc_subgroup_init_one(desc, d, desc->hw.subgroups + i);
+}
+
+static void __init intc_subgroup_map(struct intc_desc_int *d)
+{
+	struct intc_subgroup_entry *entries[32];
+	unsigned long flags;
+	unsigned int nr_found;
+	int i;
+
+	raw_spin_lock_irqsave(&d->lock, flags);
+
+restart:
+	nr_found = radix_tree_gang_lookup_tag_slot(&d->tree,
+			(void ***)entries, 0, ARRAY_SIZE(entries),
+			INTC_TAG_VIRQ_NEEDS_ALLOC);
+
+	for (i = 0; i < nr_found; i++) {
+		struct intc_subgroup_entry *entry;
+		int irq;
+
+		entry = radix_tree_deref_slot((void **)entries[i]);
+		if (unlikely(!entry))
+			continue;
+		if (unlikely(entry == RADIX_TREE_RETRY))
+			goto restart;
+
+		irq = create_irq();
+		if (unlikely(irq < 0)) {
+			pr_err("no more free IRQs, bailing..\n");
+			break;
+		}
+
+		pr_info("Setting up a chained VIRQ from %d -> %d\n",
+			irq, entry->pirq);
+
+		intc_irq_xlate_set(irq, entry->enum_id, d);
+
+		set_irq_chip_and_handler_name(irq, get_irq_chip(entry->pirq),
+					      handle_simple_irq, "virq");
+		set_irq_chip_data(irq, get_irq_chip_data(entry->pirq));
+
+		set_irq_data(irq, (void *)entry->handle);
+
+		set_irq_chained_handler(entry->pirq, intc_virq_handler);
+		add_virq_to_pirq(entry->pirq, irq);
+
+		radix_tree_tag_clear(&d->tree, entry->enum_id,
+				     INTC_TAG_VIRQ_NEEDS_ALLOC);
+		radix_tree_replace_slot((void **)entries[i],
+					&intc_irq_xlate[irq]);
+	}
+
+	raw_spin_unlock_irqrestore(&d->lock, flags);
+}
+
+void __init intc_finalize(void)
+{
+	struct intc_desc_int *d;
+
+	list_for_each_entry(d, &intc_list, list)
+		if (radix_tree_tagged(&d->tree, INTC_TAG_VIRQ_NEEDS_ALLOC))
+			intc_subgroup_map(d);
+}
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index cf0303ac..75934e3 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -7,6 +7,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -559,10 +561,8 @@
 	struct pinmux_data_reg *dr = NULL;
 	int bit = 0;
 
-	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
-		BUG();
-		return 0;
-	}
+	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
+		return -EINVAL;
 
 	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
 }
@@ -581,7 +581,7 @@
 {
 	struct gpio_chip *chip = &pip->chip;
 
-	pr_info("sh pinmux: %s handling gpio %d -> %d\n",
+	pr_info("%s handling gpio %d -> %d\n",
 		pip->name, pip->first_gpio, pip->last_gpio);
 
 	setup_data_regs(pip);
@@ -602,3 +602,10 @@
 
 	return gpiochip_add(chip);
 }
+
+int unregister_pinmux(struct pinmux_info *pip)
+{
+	pr_info("%s deregistering\n", pip->name);
+
+	return gpiochip_remove(&pip->chip);
+}
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 77be3c2..3076b1c 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2397,7 +2397,7 @@
 #define R8A66597_DEV_PM_OPS	NULL
 #endif
 
-static int __init_or_module r8a66597_remove(struct platform_device *pdev)
+static int __devexit r8a66597_remove(struct platform_device *pdev)
 {
 	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
 	struct usb_hcd		*hcd = r8a66597_to_hcd(r8a66597);
@@ -2542,7 +2542,7 @@
 
 static struct platform_driver r8a66597_driver = {
 	.probe =	r8a66597_probe,
-	.remove =	r8a66597_remove,
+	.remove =	__devexit_p(r8a66597_remove),
 	.driver		= {
 		.name = (char *) hcd_name,
 		.owner	= THIS_MODULE,
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index d72075a..7a14192 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1243,8 +1243,10 @@
 		if (priv->ch[i].sglist)
 			vfree(priv->ch[i].sglist);
 
-		dma_free_coherent(&pdev->dev, info->fix.smem_len,
-				  info->screen_base, priv->ch[i].dma_handle);
+		if (info->screen_base)
+			dma_free_coherent(&pdev->dev, info->fix.smem_len,
+					  info->screen_base,
+					  priv->ch[i].dma_handle);
 		fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
 	}
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index d278dd9..b4c3d1b 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2268,6 +2268,13 @@
 
 #define PCI_VENDOR_ID_SILAN		0x1904
 
+#define PCI_VENDOR_ID_RENESAS		0x1912
+#define PCI_DEVICE_ID_RENESAS_SH7781	0x0001
+#define PCI_DEVICE_ID_RENESAS_SH7780	0x0002
+#define PCI_DEVICE_ID_RENESAS_SH7763	0x0004
+#define PCI_DEVICE_ID_RENESAS_SH7785	0x0007
+#define PCI_DEVICE_ID_RENESAS_SH7786	0x0010
+
 #define PCI_VENDOR_ID_TDI               0x192E
 #define PCI_DEVICE_ID_TDI_EHCI          0x0101
 
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
index 875ce50..4dca992 100644
--- a/include/linux/sh_clk.h
+++ b/include/linux/sh_clk.h
@@ -4,11 +4,20 @@
 #include <linux/list.h>
 #include <linux/seq_file.h>
 #include <linux/cpufreq.h>
+#include <linux/types.h>
+#include <linux/kref.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 
 struct clk;
 
+struct clk_mapping {
+	phys_addr_t		phys;
+	void __iomem		*base;
+	unsigned long		len;
+	struct kref		ref;
+};
+
 struct clk_ops {
 	void (*init)(struct clk *clk);
 	int (*enable)(struct clk *clk);
@@ -21,9 +30,6 @@
 
 struct clk {
 	struct list_head	node;
-	const char		*name;
-	int			id;
-
 	struct clk		*parent;
 	struct clk		**parent_table;	/* list of parents to */
 	unsigned short		parent_num;	/* choose between */
@@ -45,7 +51,9 @@
 	unsigned long		arch_flags;
 	void			*priv;
 	struct dentry		*dentry;
+	struct clk_mapping	*mapping;
 	struct cpufreq_frequency_table *freq_table;
+	unsigned int		nr_freqs;
 };
 
 #define CLK_ENABLE_ON_INIT	(1 << 0)
@@ -111,6 +119,9 @@
 			struct cpufreq_frequency_table *freq_table,
 			unsigned long rate);
 
+long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
+			      unsigned int div_max, unsigned long rate);
+
 #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags)	\
 {									\
 	.parent		= _parent,					\
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index 0d6cd38..b4f183a 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -20,6 +20,12 @@
 
 #define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
 
+struct intc_subgroup {
+	unsigned long reg, reg_width;
+	intc_enum parent_id;
+	intc_enum enum_ids[32];
+};
+
 struct intc_mask_reg {
 	unsigned long set_reg, clr_reg, reg_width;
 	intc_enum enum_ids[32];
@@ -69,9 +75,12 @@
 	unsigned int nr_sense_regs;
 	struct intc_mask_reg *ack_regs;
 	unsigned int nr_ack_regs;
+	struct intc_subgroup *subgroups;
+	unsigned int nr_subgroups;
 };
 
-#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
+#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a)
+
 #define INTC_HW_DESC(vectors, groups, mask_regs,	\
 		     prio_regs,	sense_regs, ack_regs)	\
 {							\
@@ -105,8 +114,11 @@
 			   prio_regs, sense_regs, ack_regs),		\
 }
 
-int __init register_intc_controller(struct intc_desc *desc);
+int register_intc_controller(struct intc_desc *desc);
+void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs);
 int intc_set_priority(unsigned int irq, unsigned int prio);
+int intc_irq_lookup(const char *chipname, intc_enum enum_id);
+void intc_finalize(void);
 
 #ifdef CONFIG_INTC_USERIMASK
 int register_intc_userimask(unsigned long addr);
diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h
index 07c08af..30cae70 100644
--- a/include/linux/sh_pfc.h
+++ b/include/linux/sh_pfc.h
@@ -92,5 +92,6 @@
 };
 
 int register_pinmux(struct pinmux_info *pip);
+int unregister_pinmux(struct pinmux_info *pip);
 
 #endif /* __SH_PFC_H */
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index 36170be..b0ccd0b 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -127,6 +127,7 @@
 	sg_init_table(&sg, 1);
 	sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
 		    size, offset_in_page(buff));
+	sg_dma_len(&sg) = size;
 	sg_dma_address(&sg) = buff;
 
 	desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
@@ -176,6 +177,7 @@
 	sg_init_table(&sg, 1);
 	sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
 		    size, offset_in_page(buff));
+	sg_dma_len(&sg) = size;
 	sg_dma_address(&sg) = buff;
 
 	desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,