summary refs log tree commit diff
path: root/arch/sh
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2008-12-31 17:34:16 -0800
committerIngo Molnar <mingo@elte.hu>2009-01-03 18:53:31 +0100
commit7eb19553369c46cc1fa64caf120cbcab1b597f7c (patch)
treeef1a3beae706b9497c845d0a2557ceb4d2754998 /arch/sh
parent6092848a2a23b660150a38bc06f59d75838d70c8 (diff)
parent8c384cdee3e04d6194a2c2b192b624754f990835 (diff)
downloadlinux-7eb19553369c46cc1fa64caf120cbcab1b597f7c.tar.gz
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-cpumask into merge-rr-cpumask
Conflicts:
	arch/x86/kernel/io_apic.c
	kernel/rcuclassic.c
	kernel/sched.c
	kernel/time/tick-sched.c

Signed-off-by: Mike Travis <travis@sgi.com>
[ mingo@elte.hu: backmerged typo fix for io_apic.c ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig83
-rw-r--r--arch/sh/Kconfig.debug104
-rw-r--r--arch/sh/Makefile33
-rw-r--r--arch/sh/boards/Kconfig11
-rw-r--r--arch/sh/boards/Makefile1
-rw-r--r--arch/sh/boards/board-ap325rxa.c7
-rw-r--r--arch/sh/boards/board-shmin.c14
-rw-r--r--arch/sh/boards/mach-cayman/Makefile1
-rw-r--r--arch/sh/boards/mach-cayman/irq.c35
-rw-r--r--arch/sh/boards/mach-cayman/led.c51
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c192
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c5
-rw-r--r--arch/sh/boards/mach-edosk7705/Makefile1
-rw-r--r--arch/sh/boards/mach-edosk7705/io.c61
-rw-r--r--arch/sh/boards/mach-edosk7705/setup.c9
-rw-r--r--arch/sh/boards/mach-hp6xx/pm.c78
-rw-r--r--arch/sh/boards/mach-microdev/Makefile5
-rw-r--r--arch/sh/boards/mach-microdev/fdc37c93xapm.c160
-rw-r--r--arch/sh/boards/mach-microdev/irq.c36
-rw-r--r--arch/sh/boards/mach-microdev/led.c101
-rw-r--r--arch/sh/boards/mach-microdev/setup.c196
-rw-r--r--arch/sh/boards/mach-migor/setup.c21
-rw-r--r--arch/sh/boards/mach-rsk/Kconfig18
-rw-r--r--arch/sh/boards/mach-rsk/Makefile2
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c (renamed from arch/sh/boards/board-rsk7203.c)76
-rw-r--r--arch/sh/boards/mach-rsk/setup.c106
-rw-r--r--arch/sh/boards/mach-se/7343/Makefile2
-rw-r--r--arch/sh/boards/mach-se/7343/io.c273
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c126
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c4
-rw-r--r--arch/sh/boards/mach-se/7721/setup.c7
-rw-r--r--arch/sh/boards/mach-se/7722/setup.c10
-rw-r--r--arch/sh/boards/mach-sh03/setup.c59
-rw-r--r--arch/sh/boards/mach-systemh/irq.c37
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c115
-rw-r--r--arch/sh/configs/edosk7705_defconfig438
-rw-r--r--arch/sh/configs/rsk7201_defconfig703
-rw-r--r--arch/sh/configs/rsk7203_defconfig65
-rw-r--r--arch/sh/configs/rts7751r2dplus_qemu_defconfig949
-rw-r--r--arch/sh/configs/se7343_defconfig303
-rw-r--r--arch/sh/drivers/dma/Makefile1
-rw-r--r--arch/sh/drivers/dma/dma-isa.c106
-rw-r--r--arch/sh/drivers/dma/dma-sh.c3
-rw-r--r--arch/sh/drivers/dma/dma-sh.h1
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c3
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c12
-rw-r--r--arch/sh/include/asm/addrspace.h11
-rw-r--r--arch/sh/include/asm/bitops-grb.h3
-rw-r--r--arch/sh/include/asm/bitops-irq.h91
-rw-r--r--arch/sh/include/asm/bitops-llsc.h2
-rw-r--r--arch/sh/include/asm/bitops-op32.h142
-rw-r--r--arch/sh/include/asm/bitops.h9
-rw-r--r--arch/sh/include/asm/bugs.h2
-rw-r--r--arch/sh/include/asm/elf.h4
-rw-r--r--arch/sh/include/asm/ftrace.h28
-rw-r--r--arch/sh/include/asm/io.h4
-rw-r--r--arch/sh/include/asm/kgdb.h66
-rw-r--r--arch/sh/include/asm/machvec.h5
-rw-r--r--arch/sh/include/asm/mmu_context.h4
-rw-r--r--arch/sh/include/asm/mutex-llsc.h112
-rw-r--r--arch/sh/include/asm/mutex.h5
-rw-r--r--arch/sh/include/asm/pm.h17
-rw-r--r--arch/sh/include/asm/processor.h5
-rw-r--r--arch/sh/include/asm/processor_32.h12
-rw-r--r--arch/sh/include/asm/processor_64.h4
-rw-r--r--arch/sh/include/asm/ptrace.h2
-rw-r--r--arch/sh/include/asm/sh_bios.h1
-rw-r--r--arch/sh/include/asm/string_64.h21
-rw-r--r--arch/sh/include/asm/syscall_32.h2
-rw-r--r--arch/sh/include/asm/syscall_64.h76
-rw-r--r--arch/sh/include/asm/system.h2
-rw-r--r--arch/sh/include/asm/topology.h1
-rw-r--r--arch/sh/include/asm/unaligned-sh4a.h258
-rw-r--r--arch/sh/include/asm/unaligned.h7
-rw-r--r--arch/sh/include/cpu-sh3/cpu/gpio.h14
-rw-r--r--arch/sh/include/mach-common/mach/edosk7705.h31
-rw-r--r--arch/sh/include/mach-se/mach/mrshpc.h52
-rw-r--r--arch/sh/include/mach-se/mach/se.h18
-rw-r--r--arch/sh/include/mach-se/mach/se7343.h9
-rw-r--r--arch/sh/kernel/Makefile_3218
-rw-r--r--arch/sh/kernel/Makefile_645
-rw-r--r--arch/sh/kernel/cf-enabler.c168
-rw-r--r--arch/sh/kernel/cpu/clock.c10
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c85
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c7
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c331
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S14
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/softfloat.c73
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c310
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c37
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c50
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c19
-rw-r--r--arch/sh/kernel/debugtraps.S13
-rw-r--r--arch/sh/kernel/disassemble.c573
-rw-r--r--arch/sh/kernel/entry-common.S54
-rw-r--r--arch/sh/kernel/ftrace.c133
-rw-r--r--arch/sh/kernel/head_32.S12
-rw-r--r--arch/sh/kernel/idle.c81
-rw-r--r--arch/sh/kernel/kgdb.c285
-rw-r--r--arch/sh/kernel/kgdb_jmp.S33
-rw-r--r--arch/sh/kernel/kgdb_stub.c1052
-rw-r--r--arch/sh/kernel/pm.c88
-rw-r--r--arch/sh/kernel/process_32.c81
-rw-r--r--arch/sh/kernel/process_64.c111
-rw-r--r--arch/sh/kernel/ptrace_64.c186
-rw-r--r--arch/sh/kernel/setup.c1
-rw-r--r--arch/sh/kernel/sh_bios.c65
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c37
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c5
-rw-r--r--arch/sh/kernel/signal_32.c1
-rw-r--r--arch/sh/kernel/signal_64.c154
-rw-r--r--arch/sh/kernel/sys_sh.c92
-rw-r--r--arch/sh/kernel/time_32.c12
-rw-r--r--arch/sh/kernel/time_64.c5
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c5
-rw-r--r--arch/sh/kernel/traps_32.c36
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.c3
-rw-r--r--arch/sh/lib/Makefile16
-rw-r--r--arch/sh/lib/ashiftrt.S149
-rw-r--r--arch/sh/lib/ashldi3.c29
-rw-r--r--arch/sh/lib/ashlsi3.S193
-rw-r--r--arch/sh/lib/ashrdi3.c31
-rw-r--r--arch/sh/lib/ashrsi3.S185
-rw-r--r--arch/sh/lib/libgcc.h26
-rw-r--r--arch/sh/lib/lshrdi3.c29
-rw-r--r--arch/sh/lib/lshrsi3.S193
-rw-r--r--arch/sh/lib/mcount.S90
-rw-r--r--arch/sh/lib/movmem.S238
-rw-r--r--arch/sh/lib/udiv_qrnnd.S81
-rw-r--r--arch/sh/lib/udivsi3.S87
-rw-r--r--arch/sh/lib/udivsi3_i4i-Os.S149
-rw-r--r--arch/sh/lib/udivsi3_i4i.S666
-rw-r--r--arch/sh/lib64/Makefile8
-rw-r--r--arch/sh/lib64/c-checksum.c4
-rw-r--r--arch/sh/lib64/memcpy.S201
-rw-r--r--arch/sh/lib64/memcpy.c81
-rw-r--r--arch/sh/lib64/memset.S91
-rw-r--r--arch/sh/lib64/sdivsi3.S131
-rw-r--r--arch/sh/lib64/strcpy.S97
-rw-r--r--arch/sh/lib64/strlen.S33
-rw-r--r--arch/sh/lib64/udivdi3.S120
-rw-r--r--arch/sh/lib64/udivsi3.S59
-rw-r--r--arch/sh/mm/Makefile_321
-rw-r--r--arch/sh/mm/Makefile_641
-rw-r--r--arch/sh/mm/asids-debugfs.c79
-rw-r--r--arch/sh/mm/consistent.c7
-rw-r--r--arch/sh/mm/fault_32.c17
-rw-r--r--arch/sh/mm/ioremap_32.c3
-rw-r--r--arch/sh/mm/mmap.c94
-rw-r--r--arch/sh/oprofile/Makefile13
-rw-r--r--arch/sh/oprofile/backtrace.c114
-rw-r--r--arch/sh/oprofile/common.c150
-rw-r--r--arch/sh/oprofile/op_impl.h33
-rw-r--r--arch/sh/oprofile/op_model_null.c23
-rw-r--r--arch/sh/oprofile/op_model_sh7750.c172
-rw-r--r--arch/sh/tools/mach-types2
160 files changed, 8695 insertions, 4916 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5c9cbfc14c4d..f32a5197128d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -13,6 +13,7 @@ config SUPERH
 	select HAVE_OPROFILE
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IOREMAP_PROT if MMU
+	select HAVE_ARCH_TRACEHOOK
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
@@ -23,8 +24,10 @@ config SUPERH32
 	def_bool !SUPERH64
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
-	select HAVE_ARCH_TRACEHOOK
 	select HAVE_FUNCTION_TRACER
+	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_DYNAMIC_FTRACE
+	select HAVE_ARCH_KGDB
 
 config SUPERH64
 	def_bool y if CPU_SH5
@@ -55,8 +58,6 @@ config GENERIC_HARDIRQS
 
 config GENERIC_HARDIRQS_NO__DO_IRQ
 	def_bool y
-	depends on SUPERH32 && (!SH_DREAMCAST && !SH_SH4202_MICRODEV && \
-				!SH_7751_SYSTEMH && !HD64461)
 
 config GENERIC_IRQ_PROBE
 	def_bool y
@@ -85,10 +86,17 @@ config GENERIC_LOCKBREAK
 
 config SYS_SUPPORTS_PM
 	bool
+	depends on !SMP
+
+config ARCH_SUSPEND_POSSIBLE
+	def_bool n
+
+config ARCH_HIBERNATION_POSSIBLE
+	def_bool n
 
 config SYS_SUPPORTS_APM_EMULATION
 	bool
-	select SYS_SUPPORTS_PM
+	select ARCH_SUSPEND_POSSIBLE
 
 config SYS_SUPPORTS_SMP
 	bool
@@ -183,6 +191,11 @@ config CPU_SUBTYPE_SH7619
 
 # SH-2A Processor Support
 
+config CPU_SUBTYPE_SH7201
+	bool "Support SH7201 processor"
+	select CPU_SH2A
+	select CPU_HAS_FPU
+ 
 config CPU_SUBTYPE_SH7203
 	bool "Support SH7203 processor"
 	select CPU_SH2A
@@ -456,8 +469,12 @@ config SH_CPU_FREQ
 	depends on CPU_FREQ
 	select CPU_FREQ_TABLE
 	help
-	  This adds the cpufreq driver for SuperH. At present, only
-	  the SH-4 is supported.
+	  This adds the cpufreq driver for SuperH. Any CPU that supports
+	  clock rate rounding through the clock framework can use this
+	  driver. While it will make the kernel slightly larger, this is
+	  harmless for CPUs that don't support rate rounding. The driver
+	  will also generate a notice in the boot log before disabling
+	  itself if the CPU in question is not capable of rate rounding.
 
 	  For details, take a look at <file:Documentation/cpu-freq>.
 
@@ -469,9 +486,6 @@ source "arch/sh/drivers/Kconfig"
 
 endmenu
 
-config ISA_DMA_API
-	bool
-
 menu "Kernel features"
 
 source kernel/Kconfig.hz
@@ -688,49 +702,6 @@ config MAPLE
          Dreamcast with a serial line terminal or a remote network
          connection.
 
-config CF_ENABLER
-	bool "Compact Flash Enabler support"
-	depends on SOLUTION_ENGINE || SH_SH03
-	---help---
-	  Compact Flash is a small, removable mass storage device introduced
-	  in 1994 originally as a PCMCIA device.  If you say `Y' here, you
-	  compile in support for Compact Flash devices directly connected to
-	  a SuperH processor.  A Compact Flash FAQ is available at
-	  <http://www.compactflash.org/faqs/faq.htm>.
-
-	  If your board has "Directly Connected" CompactFlash at area 5 or 6,
-	  you may want to enable this option.  Then, you can use CF as
-	  primary IDE drive (only tested for SanDisk).
-
-	  If in doubt, select 'N'.
-
-choice
-	prompt "Compact Flash Connection Area"
-	depends on CF_ENABLER
-	default CF_AREA6
-
-config CF_AREA5
-	bool "Area5"
-	help
-	  If your board has "Directly Connected" CompactFlash, You should
-	  select the area where your CF is connected to.
-
-	  - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
-	  - "Area6" if it is connected to Area 6 (0x18000000)
-
-	  "Area6" will work for most boards.
-
-config CF_AREA6
-	bool "Area6"
-
-endchoice
-
-config CF_BASE_ADDR
-	hex
-	depends on CF_ENABLER
-	default "0xb8000000" if CF_AREA6
-	default "0xb4000000" if CF_AREA5
-
 source "arch/sh/drivers/pci/Kconfig"
 
 source "drivers/pci/Kconfig"
@@ -748,13 +719,11 @@ source "fs/Kconfig.binfmt"
 endmenu
 
 menu "Power management options (EXPERIMENTAL)"
-depends on EXPERIMENTAL && SYS_SUPPORTS_PM
+depends on EXPERIMENTAL
 
-config ARCH_SUSPEND_POSSIBLE
-	def_bool y
-	depends on !SMP
+source "kernel/power/Kconfig"
 
-source kernel/power/Kconfig
+source "drivers/cpuidle/Kconfig"
 
 endmenu
 
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index e6d2c8b11abd..0d62681f72a0 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -98,18 +98,29 @@ config IRQSTACKS
 	  for handling hard and soft interrupts.  This can help avoid
 	  overflowing the process kernel stacks.
 
-config SH_KGDB
-	bool "Include KGDB kernel debugger"
-	select FRAME_POINTER
-	select DEBUG_INFO
-	depends on CPU_SH3 || CPU_SH4
+config DUMP_CODE
+	bool "Show disassembly of nearby code in register dumps"
+	depends on DEBUG_KERNEL && SUPERH32
+	default y if DEBUG_BUGVERBOSE
+	default n
+	help
+	  This prints out a code trace of the instructions leading up to
+	  the faulting instruction as a debugging aid. As this does grow
+	  the kernel in size a bit, most users will want to say N here.
+
+	  Those looking for more verbose debugging output should say Y.
+
+config SH_NO_BSS_INIT
+	bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
+	depends on DEBUG_KERNEL
+	default n
 	help
-	  Include in-kernel hooks for kgdb, the Linux kernel source level
-	  debugger.  See <http://kgdb.sourceforge.net/> for more information.
-	  Unless you are intending to debug the kernel, say N here.
+	  If running in painfully slow environments, such as an RTL
+	  simulation or from remote memory via SHdebug, where the memory
+	  can already be gauranteed to ber zeroed on boot, say Y.
 
-menu "KGDB configuration options"
-	depends on SH_KGDB
+	  For all other cases, say N. If this option seems perplexing, or
+	  you aren't sure, say N.
 
 config MORE_COMPILE_OPTIONS
 	bool "Add any additional compile options"
@@ -122,85 +133,16 @@ config COMPILE_OPTIONS
 	string "Additional compile arguments"
 	depends on MORE_COMPILE_OPTIONS
 
-config KGDB_NMI
-	def_bool n
-	prompt "Enter KGDB on NMI"
-
-config SH_KGDB_CONSOLE
-	def_bool n
-	prompt "Console messages through GDB"
-	depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
-	select SERIAL_CORE_CONSOLE
-
-config KGDB_SYSRQ
-	def_bool y
-	prompt "Allow SysRq 'G' to enter KGDB"
-	depends on MAGIC_SYSRQ
-
-comment "Serial port setup"
-
-config KGDB_DEFPORT
-	int "Port number (ttySCn)"
-	default "1"
-
-config KGDB_DEFBAUD
-	int "Baud rate"
-	default "115200"
-
-choice
-	prompt "Parity"
-	depends on SH_KGDB
-	default KGDB_DEFPARITY_N
-
-config KGDB_DEFPARITY_N
-	bool "None"
-
-config KGDB_DEFPARITY_E
-	bool "Even"
-
-config KGDB_DEFPARITY_O
-	bool "Odd"
-
-endchoice
-
-choice
-	prompt "Data bits"
-	depends on SH_KGDB
-	default KGDB_DEFBITS_8
-
-config KGDB_DEFBITS_8
-	bool "8"
-
-config KGDB_DEFBITS_7
-	bool "7"
-
-endchoice
-
-endmenu
-
-if SUPERH64
-
-config SH64_PROC_ASIDS
-	bool "Debug: report ASIDs through /proc/asids"
-	depends on PROC_FS && MMU
-
 config SH64_SR_WATCH
 	bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
+	depends on SUPERH64
 
 config POOR_MANS_STRACE
 	bool "Debug: enable rudimentary strace facility"
+	depends on SUPERH64
 	help
 	  This option allows system calls to be traced to the console.  It also
 	  aids in detecting kernel stack underflow.  It is useful for debugging
 	  early-userland problems (e.g. init incurring fatal exceptions.)
 
-config SH_ALPHANUMERIC
-	bool "Enable debug outputs to on-board alphanumeric display"
-	depends on SH_CAYMAN
-
-config SH_NO_BSS_INIT
-	bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
-
-endif
-
 endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index c43eb0d7fa3b..4067b0d9287b 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -32,6 +32,7 @@ cflags-$(CONFIG_CPU_SH4)		:= $(call cc-option,-m4,) \
 	$(call cc-option,-mno-implicit-fp,-m4-nofpu)
 cflags-$(CONFIG_CPU_SH4A)		+= $(call cc-option,-m4a,) \
 					   $(call cc-option,-m4a-nofpu,)
+cflags-$(CONFIG_CPU_SH4AL_DSP)		+= $(call cc-option,-m4al,)
 cflags-$(CONFIG_CPU_SH5)		:= $(call cc-option,-m5-32media-nofpu,)
 
 ifeq ($(cflags-y),)
@@ -39,22 +40,16 @@ ifeq ($(cflags-y),)
 # In the case where we are stuck with a compiler that has been uselessly
 # restricted to a particular ISA, a favourite default of newer GCCs when
 # extensive multilib targets are not provided, ensure we get the best fit
-# regarding FP generation. This is necessary to avoid references to FP
-# variants in libgcc where integer variants exist, which otherwise result
-# in link errors. This is intentionally stupid (albeit many orders of
-# magnitude less than GCC's default behaviour), as anything with a large
-# number of multilib targets better have been built correctly for
-# the target in mind.
+# regarding FP generation. This is intentionally stupid (albeit many
+# orders of magnitude less than GCC's default behaviour), as anything
+# with a large number of multilib targets better have been built
+# correctly for the target in mind.
 #
 cflags-y	+= $(shell $(CC) $(KBUILD_CFLAGS) -print-multi-lib | \
 		     grep nofpu | sed q | sed -e 's/^/-/;s/;.*$$//')
-endif
-
-cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= -mb
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -ml
-
-cflags-y	+= $(call cc-option,-mno-fdpic)
-
+# At this point, anything goes.
+isaflags-y	:= $(call as-option,-Wa$(comma)-isa=any,)
+else
 #
 # -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that
 # support it, while -Wa,-dsp by itself limits the range of usable opcodes
@@ -67,7 +62,12 @@ isaflags-y	:= $(call as-option,-Wa$(comma)-isa=$(isa-y),)
 
 isaflags-$(CONFIG_SH_DSP)		:= \
 	$(call as-option,-Wa$(comma)-isa=$(isa-y),-Wa$(comma)-dsp)
+endif
 
+cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= -mb
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -ml
+
+cflags-y	+= $(call cc-option,-mno-fdpic)
 cflags-y	+= $(isaflags-y) -ffreestanding
 
 cflags-$(CONFIG_MORE_COMPILE_OPTIONS)	+= \
@@ -79,6 +79,9 @@ OBJCOPYFLAGS	:= -O binary -R .note -R .note.gnu.build-id -R .comment \
 # Give the various platforms the opportunity to set default image types
 defaultimage-$(CONFIG_SUPERH32)			:= zImage
 defaultimage-$(CONFIG_SH_SH7785LCR)		:= uImage
+defaultimage-$(CONFIG_SH_RSK)			:= uImage
+defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE)	:= vmlinux
+defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE)	:= vmlinux
 
 # Set some sensible Kbuild defaults
 KBUILD_DEFCONFIG	:= shx3_defconfig
@@ -132,6 +135,7 @@ machdir-$(CONFIG_SH_LANDISK)			+= mach-landisk
 machdir-$(CONFIG_SH_TITAN)			+= mach-titan
 machdir-$(CONFIG_SH_LBOX_RE2)			+= mach-lboxre2
 machdir-$(CONFIG_SH_CAYMAN)			+= mach-cayman
+machdir-$(CONFIG_SH_RSK)			+= mach-rsk
 
 ifneq ($(machdir-y),)
 core-y	+= $(addprefix arch/sh/boards/, \
@@ -173,11 +177,8 @@ KBUILD_CFLAGS		+= -pipe $(cflags-y)
 KBUILD_CPPFLAGS		+= $(cflags-y)
 KBUILD_AFLAGS		+= $(cflags-y)
 
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
 libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
 libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)
-libs-y				+= $(LIBGCC)
 
 PHONY += maketools FORCE
 
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 50467f9d0d0b..861914747e4e 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -126,10 +126,12 @@ config SH_RTS7751R2D
 	  Select RTS7751R2D if configuring for a Renesas Technology
 	  Sales SH-Graphics board.
 
-config SH_RSK7203
-	bool "RSK7203"
-	select GENERIC_GPIO
-	depends on CPU_SUBTYPE_SH7203
+config SH_RSK
+	bool "Renesas Starter Kit"
+	depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203
+	help
+	 Select this option if configuring for any of the RSK+ MCU
+	 evaluation platforms.
 
 config SH_SDK7780
 	bool "SDK7780R3"
@@ -253,6 +255,7 @@ source "arch/sh/boards/mach-r2d/Kconfig"
 source "arch/sh/boards/mach-highlander/Kconfig"
 source "arch/sh/boards/mach-sdk7780/Kconfig"
 source "arch/sh/boards/mach-migor/Kconfig"
+source "arch/sh/boards/mach-rsk/Kconfig"
 
 if SH_MAGIC_PANEL_R2
 
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index d9efa3923721..269ae2be49ef 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -3,7 +3,6 @@
 #
 obj-$(CONFIG_SH_AP325RXA)	+= board-ap325rxa.o
 obj-$(CONFIG_SH_MAGIC_PANEL_R2)	+= board-magicpanelr2.o
-obj-$(CONFIG_SH_RSK7203)	+= board-rsk7203.o
 obj-$(CONFIG_SH_SH7785LCR)	+= board-sh7785lcr.o
 obj-$(CONFIG_SH_SHMIN)		+= board-shmin.o
 obj-$(CONFIG_SH_EDOSK7760)	+= board-edosk7760.o
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 8881a643ac32..1c67cba6e34f 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -197,6 +197,10 @@ static struct resource lcdc_resources[] = {
 		.end	= 0xfe941fff,
 		.flags	= IORESOURCE_MEM,
 	},
+	[1] = {
+		.start	= 28,
+		.flags	= IORESOURCE_IRQ,
+	},
 };
 
 static struct platform_device lcdc_device = {
@@ -303,6 +307,7 @@ static struct resource ceu_resources[] = {
 
 static struct platform_device ceu_device = {
 	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
 	.num_resources	= ARRAY_SIZE(ceu_resources),
 	.resource	= ceu_resources,
 	.dev		= {
@@ -344,7 +349,6 @@ static int __init ap325rxa_devices_setup(void)
 	gpio_export(GPIO_PTF7, 0);
 
 	/* LCDC */
-	clk_always_enable("mstp200");
 	gpio_request(GPIO_FN_LCDD15, NULL);
 	gpio_request(GPIO_FN_LCDD14, NULL);
 	gpio_request(GPIO_FN_LCDD13, NULL);
@@ -375,7 +379,6 @@ static int __init ap325rxa_devices_setup(void)
 	gpio_direction_output(GPIO_PTS3, 1);
 
 	/* CEU */
-	clk_always_enable("mstp203");
 	gpio_request(GPIO_FN_VIO_CLK2, NULL);
 	gpio_request(GPIO_FN_VIO_VD2, NULL);
 	gpio_request(GPIO_FN_VIO_HD2, NULL);
diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c
index 5cc0867de5ab..b1dcbbc89188 100644
--- a/arch/sh/boards/board-shmin.c
+++ b/arch/sh/boards/board-shmin.c
@@ -22,21 +22,13 @@ static void __init init_shmin_irq(void)
 	plat_irq_setup_pins(IRQ_MODE_IRQ);
 }
 
-static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size)
+static void __init shmin_setup(char **cmdline_p)
 {
-	static int dummy;
-
-	if ((port & ~0x1f) == SHMIN_NE_BASE)
-		return (void __iomem *)(SHMIN_IO_BASE + port);
-
-	dummy = 0;
-
-	return &dummy;
-
+	__set_io_port_base(SHMIN_IO_BASE);
 }
 
 static struct sh_machine_vector mv_shmin __initmv = {
 	.mv_name	= "SHMIN",
+	.mv_setup	= shmin_setup,
 	.mv_init_irq	= init_shmin_irq,
-	.mv_ioport_map	= shmin_ioport_map,
 };
diff --git a/arch/sh/boards/mach-cayman/Makefile b/arch/sh/boards/mach-cayman/Makefile
index 489a8f867368..cafe1ac3b29c 100644
--- a/arch/sh/boards/mach-cayman/Makefile
+++ b/arch/sh/boards/mach-cayman/Makefile
@@ -2,4 +2,3 @@
 # Makefile for the Hitachi Cayman specific parts of the kernel
 #
 obj-y := setup.o irq.o
-obj-$(CONFIG_HEARTBEAT)	+= led.o
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index ceb37ae92c70..da62ad516994 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -94,31 +94,11 @@ static void ack_cayman_irq(unsigned int irq)
 	disable_cayman_irq(irq);
 }
 
-static void end_cayman_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_cayman_irq(irq);
-}
-
-static unsigned int startup_cayman_irq(unsigned int irq)
-{
-	enable_cayman_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static void shutdown_cayman_irq(unsigned int irq)
-{
-	disable_cayman_irq(irq);
-}
-
-struct hw_interrupt_type cayman_irq_type = {
-	.typename	= "Cayman-IRQ",
-	.startup	= startup_cayman_irq,
-	.shutdown	= shutdown_cayman_irq,
-	.enable		= enable_cayman_irq,
-	.disable	= disable_cayman_irq,
-	.ack		= ack_cayman_irq,
-	.end		= end_cayman_irq,
+struct irq_chip cayman_irq_type = {
+	.name		= "Cayman-IRQ",
+	.unmask 	= enable_cayman_irq,
+	.mask		= disable_cayman_irq,
+	.mask_ack	= ack_cayman_irq,
 };
 
 int cayman_irq_demux(int evt)
@@ -187,8 +167,9 @@ void init_cayman_irq(void)
 		return;
 	}
 
-	for (i=0; i<NR_EXT_IRQS; i++) {
-		irq_desc[START_EXT_IRQS + i].chip = &cayman_irq_type;
+	for (i = 0; i < NR_EXT_IRQS; i++) {
+		set_irq_chip_and_handler(START_EXT_IRQS + i, &cayman_irq_type,
+					 handle_level_irq);
 	}
 
 	/* Setup the SMSC interrupt */
diff --git a/arch/sh/boards/mach-cayman/led.c b/arch/sh/boards/mach-cayman/led.c
deleted file mode 100644
index a808eac4ecd6..000000000000
--- a/arch/sh/boards/mach-cayman/led.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * arch/sh/boards/cayman/led.c
- *
- * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Flash the LEDs
- */
-#include <asm/io.h>
-
-/*
-** It is supposed these functions to be used for a low level
-** debugging (via Cayman LEDs), hence to be available as soon
-** as possible.
-** Unfortunately Cayman LEDs relies on Cayman EPLD to be mapped
-** (this happen when IRQ are initialized... quite late).
-** These triky dependencies should be removed. Temporary, it
-** may be enough to NOP until EPLD is mapped.
-*/
-
-extern unsigned long epld_virt;
-
-#define LED_ADDR      (epld_virt + 0x008)
-#define HDSP2534_ADDR (epld_virt + 0x100)
-
-void mach_led(int position, int value)
-{
-	if (!epld_virt)
-		return;
-
-	if (value)
-		ctrl_outl(0, LED_ADDR);
-	else
-		ctrl_outl(1, LED_ADDR);
-
-}
-
-void mach_alphanum(int position, unsigned char value)
-{
-	if (!epld_virt)
-		return;
-
-	ctrl_outb(value, HDSP2534_ADDR + 0xe0 + (position << 2));
-}
-
-void mach_alphanum_brightness(int setting)
-{
-	ctrl_outb(setting & 7, HDSP2534_ADDR + 0xc0);
-}
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index 67bdc33dd411..f55fc8e795e9 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -10,106 +10,90 @@
  */
 
 #include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <mach/sysasic.h>
 
-/* Dreamcast System ASIC Hardware Events -
-
-   The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
-   hardware events from system peripherals and triggering an SH7750 IRQ.
-   Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
-   set in the Event Mask Registers (EMRs).  When a hardware event is
-   triggered, it's corresponding bit in the Event Status Registers (ESRs)
-   is set, and that bit should be rewritten to the ESR to acknowledge that
-   event.
-
-   There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908.  Event
-   types can be found in include/asm-sh/dreamcast/sysasic.h. There are three
-   groups of EMRs that parallel the ESRs.  Each EMR group corresponds to an
-   IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928
-   triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
-
-   In the kernel, these events are mapped to virtual IRQs so that drivers can
-   respond to them as they would a normal interrupt.  In order to keep this
-   mapping simple, the events are mapped as:
-
-   6900/6910 - Events  0-31, IRQ 13
-   6904/6924 - Events 32-63, IRQ 11
-   6908/6938 - Events 64-95, IRQ  9
-
-*/
+/*
+ * Dreamcast System ASIC Hardware Events -
+ *
+ * The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
+ * hardware events from system peripherals and triggering an SH7750 IRQ.
+ * Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
+ * set in the Event Mask Registers (EMRs).  When a hardware event is
+ * triggered, its corresponding bit in the Event Status Registers (ESRs)
+ * is set, and that bit should be rewritten to the ESR to acknowledge that
+ * event.
+ *
+ * There are three 32-bit ESRs located at 0xa05f6900 - 0xa05f6908.  Event
+ * types can be found in arch/sh/include/mach-dreamcast/mach/sysasic.h.
+ * There are three groups of EMRs that parallel the ESRs.  Each EMR group
+ * corresponds to an IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13,
+ * 0xa05f6920 - 0xa05f6928 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938
+ * triggers IRQ 9.
+ *
+ * In the kernel, these events are mapped to virtual IRQs so that drivers can
+ * respond to them as they would a normal interrupt.  In order to keep this
+ * mapping simple, the events are mapped as:
+ *
+ * 6900/6910 - Events  0-31, IRQ 13
+ * 6904/6924 - Events 32-63, IRQ 11
+ * 6908/6938 - Events 64-95, IRQ  9
+ *
+ */
 
 #define ESR_BASE 0x005f6900    /* Base event status register */
 #define EMR_BASE 0x005f6910    /* Base event mask register */
 
-/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
-   1 = 0x6920, 2 = 0x6930; also determine the event offset */
+/*
+ * Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
+ * 1 = 0x6920, 2 = 0x6930; also determine the event offset.
+ */
 #define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
 
 /* Return the hardware event's bit positon within the EMR/ESR */
 #define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
 
-/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ
-   (logically mapped to the corresponding bit for the hardware event). */
+/*
+ * For each of these *_irq routines, the IRQ passed in is the virtual IRQ
+ * (logically mapped to the corresponding bit for the hardware event).
+ */
 
 /* Disable the hardware event by masking its bit in its EMR */
 static inline void disable_systemasic_irq(unsigned int irq)
 {
-        __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
-        __u32 mask;
+	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+	__u32 mask;
 
-        mask = inl(emr);
-        mask &= ~(1 << EVENT_BIT(irq));
-        outl(mask, emr);
+	mask = inl(emr);
+	mask &= ~(1 << EVENT_BIT(irq));
+	outl(mask, emr);
 }
 
 /* Enable the hardware event by setting its bit in its EMR */
 static inline void enable_systemasic_irq(unsigned int irq)
 {
-        __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
-        __u32 mask;
+	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+	__u32 mask;
 
-        mask = inl(emr);
-        mask |= (1 << EVENT_BIT(irq));
-        outl(mask, emr);
+	mask = inl(emr);
+	mask |= (1 << EVENT_BIT(irq));
+	outl(mask, emr);
 }
 
 /* Acknowledge a hardware event by writing its bit back to its ESR */
-static void ack_systemasic_irq(unsigned int irq)
-{
-        __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
-        disable_systemasic_irq(irq);
-        outl((1 << EVENT_BIT(irq)), esr);
-}
-
-/* After a IRQ has been ack'd and responded to, it needs to be renabled */
-static void end_systemasic_irq(unsigned int irq)
-{
-        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-                enable_systemasic_irq(irq);
-}
-
-static unsigned int startup_systemasic_irq(unsigned int irq)
-{
-        enable_systemasic_irq(irq);
-
-        return 0;
-}
-
-static void shutdown_systemasic_irq(unsigned int irq)
+static void mask_ack_systemasic_irq(unsigned int irq)
 {
-        disable_systemasic_irq(irq);
+	__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
+	disable_systemasic_irq(irq);
+	outl((1 << EVENT_BIT(irq)), esr);
 }
 
-struct hw_interrupt_type systemasic_int = {
-        .typename       = "System ASIC",
-        .startup        = startup_systemasic_irq,
-        .shutdown       = shutdown_systemasic_irq,
-        .enable         = enable_systemasic_irq,
-        .disable        = disable_systemasic_irq,
-        .ack            = ack_systemasic_irq,
-        .end            = end_systemasic_irq,
+struct irq_chip systemasic_int = {
+	.name		= "System ASIC",
+	.mask		= disable_systemasic_irq,
+	.mask_ack	= mask_ack_systemasic_irq,
+	.unmask		= enable_systemasic_irq,
 };
 
 /*
@@ -117,37 +101,37 @@ struct hw_interrupt_type systemasic_int = {
  */
 int systemasic_irq_demux(int irq)
 {
-        __u32 emr, esr, status, level;
-        __u32 j, bit;
-
-        switch (irq) {
-                case 13:
-                        level = 0;
-                        break;
-                case 11:
-                        level = 1;
-                        break;
-                case  9:
-                        level = 2;
-                        break;
-                default:
-                        return irq;
-        }
-        emr = EMR_BASE + (level << 4) + (level << 2);
-        esr = ESR_BASE + (level << 2);
-
-        /* Mask the ESR to filter any spurious, unwanted interrupts */
-        status = inl(esr);
-        status &= inl(emr);
-
-        /* Now scan and find the first set bit as the event to map */
-        for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
-                if (status & bit) {
-                        irq = HW_EVENT_IRQ_BASE + j + (level << 5);
-                        return irq;
-                }
-        }
-
-        /* Not reached */
-        return irq;
+	__u32 emr, esr, status, level;
+	__u32 j, bit;
+
+	switch (irq) {
+	case 13:
+		level = 0;
+		break;
+	case 11:
+		level = 1;
+		break;
+	case  9:
+		level = 2;
+		break;
+	default:
+		return irq;
+	}
+	emr = EMR_BASE + (level << 4) + (level << 2);
+	esr = ESR_BASE + (level << 2);
+
+	/* Mask the ESR to filter any spurious, unwanted interrupts */
+	status = inl(esr);
+	status &= inl(emr);
+
+	/* Now scan and find the first set bit as the event to map */
+	for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
+		if (status & bit) {
+			irq = HW_EVENT_IRQ_BASE + j + (level << 5);
+			return irq;
+		}
+	}
+
+	/* Not reached */
+	return irq;
 }
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index 7d944fc75e93..d1bee4884cd6 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -28,7 +28,7 @@
 #include <asm/machvec.h>
 #include <mach/sysasic.h>
 
-extern struct hw_interrupt_type systemasic_int;
+extern struct irq_chip systemasic_int;
 extern void aica_time_init(void);
 extern int gapspci_init(void);
 extern int systemasic_irq_demux(int);
@@ -47,7 +47,8 @@ static void __init dreamcast_setup(char **cmdline_p)
 
 	/* Assign all virtual IRQs to the System ASIC int. handler */
 	for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
-		irq_desc[i].chip = &systemasic_int;
+		set_irq_chip_and_handler(i, &systemasic_int,
+					 handle_level_irq);
 
 	board_time_init = aica_time_init;
 
diff --git a/arch/sh/boards/mach-edosk7705/Makefile b/arch/sh/boards/mach-edosk7705/Makefile
index 14bdd531f116..cd54acb51499 100644
--- a/arch/sh/boards/mach-edosk7705/Makefile
+++ b/arch/sh/boards/mach-edosk7705/Makefile
@@ -3,4 +3,3 @@
 #
 
 obj-y	 := setup.o io.o
-
diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c
index 7d153e50a01b..5b9c57c43241 100644
--- a/arch/sh/boards/mach-edosk7705/io.c
+++ b/arch/sh/boards/mach-edosk7705/io.c
@@ -10,28 +10,24 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/edosk7705.h>
 #include <asm/addrspace.h>
 
 #define SMC_IOADDR	0xA2000000
 
-#define maybebadio(name,port) \
-  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
-	 #name, (port), (__u32) __builtin_return_address(0))
-
 /* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
-unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
+static unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
 {
-     if (port >= 0x300 && port < 0x320) {
-	  /* SMC91C96 registers are 4 byte aligned rather than the
-	   * usual 2 byte!
-	   */
-	  return SMC_IOADDR + ( (port - 0x300) * 2);
-     }
+	/*
+	 * SMC91C96 registers are 4 byte aligned rather than the
+	 * usual 2 byte!
+	 */
+	if (port >= 0x300 && port < 0x320)
+		return SMC_IOADDR + ((port - 0x300) * 2);
 
-     maybebadio(sh_edosk7705_isa_port2addr, port);
-     return port;
+	maybebadio(port);
+	return port;
 }
 
 /* Trying to read / write bytes on odd-byte boundaries to the Ethernet
@@ -42,53 +38,34 @@ unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
  */
 unsigned char sh_edosk7705_inb(unsigned long port)
 {
-	if (port >= 0x300 && port < 0x320 && port & 0x01) {
-		return (volatile unsigned char)(generic_inw(port -1) >> 8);
-	}
-	return *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port);
-}
+	if (port >= 0x300 && port < 0x320 && port & 0x01)
+		return __raw_readw(port - 1) >> 8;
 
-unsigned int sh_edosk7705_inl(unsigned long port)
-{
-	return *(volatile unsigned long *)port;
+	return __raw_readb(sh_edosk7705_isa_port2addr(port));
 }
 
 void sh_edosk7705_outb(unsigned char value, unsigned long port)
 {
 	if (port >= 0x300 && port < 0x320 && port & 0x01) {
-		generic_outw(((unsigned short)value << 8), port -1);
+		__raw_writew(((unsigned short)value << 8), port - 1);
 		return;
 	}
-	*(volatile unsigned char *)sh_edosk7705_isa_port2addr(port) = value;
-}
 
-void sh_edosk7705_outl(unsigned int value, unsigned long port)
-{
-	*(volatile unsigned long *)port = value;
+	__raw_writeb(value, sh_edosk7705_isa_port2addr(port));
 }
 
 void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
 {
 	unsigned char *p = addr;
-	while (count--) *p++ = sh_edosk7705_inb(port);
-}
 
-void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count)
-{
-	unsigned long *p = (unsigned long*)addr;
 	while (count--)
-		*p++ = *(volatile unsigned long *)port;
+		*p++ = sh_edosk7705_inb(port);
 }
 
 void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
 {
-	unsigned char *p = (unsigned char*)addr;
-	while (count--) sh_edosk7705_outb(*p++, port);
-}
+	unsigned char *p = (unsigned char *)addr;
 
-void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-	unsigned long *p = (unsigned long*)addr;
-	while (count--) sh_edosk7705_outl(*p++, port);
+	while (count--)
+		sh_edosk7705_outb(*p++, port);
 }
-
diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c
index ab3f47bffdf3..d59225e26fb9 100644
--- a/arch/sh/boards/mach-edosk7705/setup.c
+++ b/arch/sh/boards/mach-edosk7705/setup.c
@@ -9,6 +9,7 @@
  * board by S. Dunn, 2003.
  */
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <asm/machvec.h>
 #include <mach/edosk7705.h>
 
@@ -26,18 +27,10 @@ static struct sh_machine_vector mv_edosk7705 __initmv = {
 	.mv_nr_irqs		= 80,
 
 	.mv_inb			= sh_edosk7705_inb,
-	.mv_inl			= sh_edosk7705_inl,
 	.mv_outb		= sh_edosk7705_outb,
-	.mv_outl		= sh_edosk7705_outl,
-
-	.mv_inl_p		= sh_edosk7705_inl,
-	.mv_outl_p		= sh_edosk7705_outl,
 
 	.mv_insb		= sh_edosk7705_insb,
-	.mv_insl		= sh_edosk7705_insl,
 	.mv_outsb		= sh_edosk7705_outsb,
-	.mv_outsl		= sh_edosk7705_outsl,
 
-	.mv_isa_port2addr	= sh_edosk7705_isa_port2addr,
 	.mv_init_irq		= sh_edosk7705_init_irq,
 };
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c
index 64af1f2eef05..d936c1af7620 100644
--- a/arch/sh/boards/mach-hp6xx/pm.c
+++ b/arch/sh/boards/mach-hp6xx/pm.c
@@ -10,15 +10,91 @@
 #include <linux/suspend.h>
 #include <linux/errno.h>
 #include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/hd64461.h>
 #include <mach/hp6xx.h>
 #include <cpu/dac.h>
-#include <asm/pm.h>
+#include <asm/freq.h>
+#include <asm/watchdog.h>
+
+#define INTR_OFFSET	0x600
 
 #define STBCR		0xffffff82
 #define STBCR2		0xffffff88
 
+#define STBCR_STBY	0x80
+#define STBCR_MSTP2	0x04
+
+#define MCR		0xffffff68
+#define RTCNT		0xffffff70
+
+#define MCR_RMODE	2
+#define MCR_RFSH	4
+
+extern u8 wakeup_start;
+extern u8 wakeup_end;
+
+static void pm_enter(void)
+{
+	u8 stbcr, csr;
+	u16 frqcr, mcr;
+	u32 vbr_new, vbr_old;
+
+	set_bl_bit();
+
+	/* set wdt */
+	csr = sh_wdt_read_csr();
+	csr &= ~WTCSR_TME;
+	csr |= WTCSR_CKS_4096;
+	sh_wdt_write_csr(csr);
+	csr = sh_wdt_read_csr();
+	sh_wdt_write_cnt(0);
+
+	/* disable PLL1 */
+	frqcr = ctrl_inw(FRQCR);
+	frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
+	ctrl_outw(frqcr, FRQCR);
+
+	/* enable standby */
+	stbcr = ctrl_inb(STBCR);
+	ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
+
+	/* set self-refresh */
+	mcr = ctrl_inw(MCR);
+	ctrl_outw(mcr & ~MCR_RFSH, MCR);
+
+	/* set interrupt handler */
+	asm volatile("stc vbr, %0" : "=r" (vbr_old));
+	vbr_new = get_zeroed_page(GFP_ATOMIC);
+	udelay(50);
+	memcpy((void*)(vbr_new + INTR_OFFSET),
+	       &wakeup_start, &wakeup_end - &wakeup_start);
+	asm volatile("ldc %0, vbr" : : "r" (vbr_new));
+
+	ctrl_outw(0, RTCNT);
+	ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
+
+	cpu_sleep();
+
+	asm volatile("ldc %0, vbr" : : "r" (vbr_old));
+
+	free_page(vbr_new);
+
+	/* enable PLL1 */
+	frqcr = ctrl_inw(FRQCR);
+	frqcr |= FRQCR_PSTBY;
+	ctrl_outw(frqcr, FRQCR);
+	udelay(50);
+	frqcr |= FRQCR_PLLEN;
+	ctrl_outw(frqcr, FRQCR);
+
+	ctrl_outb(stbcr, STBCR);
+
+	clear_bl_bit();
+}
+
 static int hp6x0_pm_enter(suspend_state_t state)
 {
 	u8 stbcr, stbcr2;
diff --git a/arch/sh/boards/mach-microdev/Makefile b/arch/sh/boards/mach-microdev/Makefile
index 1387dd6c85eb..4e3588e8806b 100644
--- a/arch/sh/boards/mach-microdev/Makefile
+++ b/arch/sh/boards/mach-microdev/Makefile
@@ -2,7 +2,4 @@
 # Makefile for the SuperH MicroDev specific parts of the kernel
 #
 
-obj-y	 := setup.o irq.o io.o
-
-obj-$(CONFIG_HEARTBEAT)	+= led.o
-
+obj-y	 := setup.o irq.o io.o fdc37c93xapm.o
diff --git a/arch/sh/boards/mach-microdev/fdc37c93xapm.c b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
new file mode 100644
index 000000000000..458a7cf5fb46
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
@@ -0,0 +1,160 @@
+/*
+ *
+ * Setup for the SMSC FDC37C93xAPM
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ * Copyright (C) 2003, 2004 SuperH, Inc.
+ * Copyright (C) 2004, 2005 Paul Mundt
+ *
+ * SuperH SH4-202 MicroDev board support.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <mach/microdev.h>
+
+#define SMSC_CONFIG_PORT_ADDR	 (0x3F0)
+#define SMSC_INDEX_PORT_ADDR	 SMSC_CONFIG_PORT_ADDR
+#define SMSC_DATA_PORT_ADDR	 (SMSC_INDEX_PORT_ADDR + 1)
+
+#define SMSC_ENTER_CONFIG_KEY	 0x55
+#define SMSC_EXIT_CONFIG_KEY	 0xaa
+
+#define SMCS_LOGICAL_DEV_INDEX	 0x07	/* Logical Device Number */
+#define SMSC_DEVICE_ID_INDEX	 0x20	/* Device ID */
+#define SMSC_DEVICE_REV_INDEX	 0x21	/* Device Revision */
+#define SMSC_ACTIVATE_INDEX	 0x30	/* Activate */
+#define SMSC_PRIMARY_BASE_INDEX	 0x60	/* Primary Base Address */
+#define SMSC_SECONDARY_BASE_INDEX 0x62	/* Secondary Base Address */
+#define SMSC_PRIMARY_INT_INDEX	 0x70	/* Primary Interrupt Select */
+#define SMSC_SECONDARY_INT_INDEX 0x72	/* Secondary Interrupt Select */
+#define SMSC_HDCS0_INDEX	 0xf0	/* HDCS0 Address Decoder */
+#define SMSC_HDCS1_INDEX	 0xf1	/* HDCS1 Address Decoder */
+
+#define SMSC_IDE1_DEVICE	1	/* IDE #1 logical device */
+#define SMSC_IDE2_DEVICE	2	/* IDE #2 logical device */
+#define SMSC_PARALLEL_DEVICE	3	/* Parallel Port logical device */
+#define SMSC_SERIAL1_DEVICE	4	/* Serial #1 logical device */
+#define SMSC_SERIAL2_DEVICE	5	/* Serial #2 logical device */
+#define SMSC_KEYBOARD_DEVICE	7	/* Keyboard logical device */
+#define SMSC_CONFIG_REGISTERS	8	/* Configuration Registers (Aux I/O) */
+
+#define SMSC_READ_INDEXED(index) ({ \
+	outb((index), SMSC_INDEX_PORT_ADDR); \
+	inb(SMSC_DATA_PORT_ADDR); })
+#define SMSC_WRITE_INDEXED(val, index) ({ \
+	outb((index), SMSC_INDEX_PORT_ADDR); \
+	outb((val),   SMSC_DATA_PORT_ADDR); })
+
+#define	IDE1_PRIMARY_BASE	0x01f0	/* Task File Registe base for IDE #1 */
+#define	IDE1_SECONDARY_BASE	0x03f6	/* Miscellaneous AT registers for IDE #1 */
+#define	IDE2_PRIMARY_BASE	0x0170	/* Task File Registe base for IDE #2 */
+#define	IDE2_SECONDARY_BASE	0x0376	/* Miscellaneous AT registers for IDE #2 */
+
+#define SERIAL1_PRIMARY_BASE	0x03f8
+#define SERIAL2_PRIMARY_BASE	0x02f8
+
+#define	MSB(x)		( (x) >> 8 )
+#define	LSB(x)		( (x) & 0xff )
+
+	/* General-Purpose base address on CPU-board FPGA */
+#define	MICRODEV_FPGA_GP_BASE		0xa6100000ul
+
+static int __init smsc_superio_setup(void)
+{
+
+	unsigned char devid, devrev;
+
+		/* Initially the chip is in run state */
+		/* Put it into configuration state */
+	outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+		/* Read device ID info */
+	devid  = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
+	devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
+
+	if ((devid == 0x30) && (devrev == 0x01))
+		printk("SMSC FDC37C93xAPM SuperIO device detected\n");
+	else
+		return -ENODEV;
+
+		/* Select the keyboard device */
+	SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+		/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+		/* enable the interrupts */
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
+
+		/* Select the Serial #1 device */
+	SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+		/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+		/* program with port addresses */
+	SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
+		/* enable the interrupts */
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
+
+		/* Select the Serial #2 device */
+	SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+		/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+		/* program with port addresses */
+	SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
+		/* enable the interrupts */
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
+
+		/* Select the IDE#1 device */
+	SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+		/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+		/* program with port addresses */
+	SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+	SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
+	SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
+	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
+		/* select the interrupt */
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
+
+		/* Select the IDE#2 device */
+	SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+		/* enable it */
+	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+		/* program with port addresses */
+	SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+	SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
+	SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
+		/* select the interrupt */
+	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
+
+		/* Select the configuration registers */
+	SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
+		/* enable the appropriate GPIO pins for IDE functionality:
+		 * bit[0]   In/Out		1==input;  0==output
+		 * bit[1]   Polarity		1==invert; 0==no invert
+		 * bit[2]   Int Enb #1		1==Enable Combined IRQ #1; 0==disable
+		 * bit[3:4] Function Select	00==original; 01==Alternate Function #1
+		 */
+	SMSC_WRITE_INDEXED(0x00, 0xc2);	/* GP42 = nIDE1_OE */
+	SMSC_WRITE_INDEXED(0x01, 0xc5);	/* GP45 = IDE1_IRQ */
+	SMSC_WRITE_INDEXED(0x00, 0xc6);	/* GP46 = nIOROP */
+	SMSC_WRITE_INDEXED(0x00, 0xc7);	/* GP47 = nIOWOP */
+	SMSC_WRITE_INDEXED(0x08, 0xe8);	/* GP20 = nIDE2_OE */
+
+		/* Exit the configuration state */
+	outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+	return 0;
+}
+device_initcall(smsc_superio_setup);
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index 702753cbd28f..b551963579c1 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -67,27 +67,13 @@ static const struct {
 
 static void enable_microdev_irq(unsigned int irq);
 static void disable_microdev_irq(unsigned int irq);
-
-	/* shutdown is same as "disable" */
-#define shutdown_microdev_irq disable_microdev_irq
-
 static void mask_and_ack_microdev(unsigned int);
-static void end_microdev_irq(unsigned int irq);
-
-static unsigned int startup_microdev_irq(unsigned int irq)
-{
-	enable_microdev_irq(irq);
-	return 0;		/* never anything pending */
-}
 
-static struct hw_interrupt_type microdev_irq_type = {
-	.typename = "MicroDev-IRQ",
-	.startup = startup_microdev_irq,
-	.shutdown = shutdown_microdev_irq,
-	.enable = enable_microdev_irq,
-	.disable = disable_microdev_irq,
+static struct irq_chip microdev_irq_type = {
+	.name = "MicroDev-IRQ",
+	.unmask = enable_microdev_irq,
+	.mask = disable_microdev_irq,
 	.ack = mask_and_ack_microdev,
-	.end = end_microdev_irq
 };
 
 static void disable_microdev_irq(unsigned int irq)
@@ -130,11 +116,11 @@ static void enable_microdev_irq(unsigned int irq)
 	ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
 }
 
-	/* This functions sets the desired irq handler to be a MicroDev type */
+/* This function sets the desired irq handler to be a MicroDev type */
 static void __init make_microdev_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-	irq_desc[irq].chip = &microdev_irq_type;
+	set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
 	disable_microdev_irq(irq);
 }
 
@@ -143,17 +129,11 @@ static void mask_and_ack_microdev(unsigned int irq)
 	disable_microdev_irq(irq);
 }
 
-static void end_microdev_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_microdev_irq(irq);
-}
-
 extern void __init init_microdev_irq(void)
 {
 	int i;
 
-		/* disable interrupts on the FPGA INTC register */
+	/* disable interrupts on the FPGA INTC register */
 	ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
 
 	for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
@@ -179,5 +159,3 @@ extern void microdev_print_fpga_intc_status(void)
 	printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
 	printk("-------------------------------------------------------------------------------\n");
 }
-
-
diff --git a/arch/sh/boards/mach-microdev/led.c b/arch/sh/boards/mach-microdev/led.c
deleted file mode 100644
index 36e54b47a752..000000000000
--- a/arch/sh/boards/mach-microdev/led.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * linux/arch/sh/boards/superh/microdev/led.c
- *
- * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
- * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- */
-
-#include <asm/io.h>
-
-#define LED_REGISTER 0xa6104d20
-
-static void mach_led_d9(int value)
-{
-	unsigned long reg;
-	reg = ctrl_inl(LED_REGISTER);
-	reg &= ~1;
-	reg |= (value & 1);
-	ctrl_outl(reg, LED_REGISTER);
-	return;
-}
-
-static void mach_led_d10(int value)
-{
-	unsigned long reg;
-	reg = ctrl_inl(LED_REGISTER);
-	reg &= ~2;
-	reg |= ((value & 1) << 1);
-	ctrl_outl(reg, LED_REGISTER);
-	return;
-}
-
-
-#ifdef CONFIG_HEARTBEAT
-#include <linux/sched.h>
-
-static unsigned char banner_table[] = {
-	0x11, 0x01, 0x11, 0x01, 0x11, 0x03,
-	0x11, 0x01, 0x11, 0x01, 0x13, 0x03,
-	0x11, 0x01, 0x13, 0x01, 0x13, 0x01, 0x11, 0x03,
-	0x11, 0x03,
-	0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
-	0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x07,
-	0x13, 0x01, 0x13, 0x03,
-	0x11, 0x01, 0x11, 0x03,
-	0x13, 0x01, 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
-	0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
-	0x13, 0x01, 0x13, 0x01, 0x13, 0x03,
-	0x13, 0x01, 0x11, 0x01, 0x11, 0x03,
-	0x11, 0x03,
-	0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x13, 0x07,
-	0xff
-};
-
-static void banner(void)
-{
-	static int pos = 0;
-	static int count = 0;
-
-	if (count) {
-		count--;
-	} else {
-		int val = banner_table[pos];
-		if (val == 0xff) {
-			pos = 0;
-			val = banner_table[pos];
-		}
-		pos++;
-		mach_led_d10((val >> 4) & 1);
-		count = 10 * (val & 0xf);
-	}
-}
-
-/* From heartbeat_harp in the stboards directory */
-/* acts like an actual heart beat -- ie thump-thump-pause... */
-void microdev_heartbeat(void)
-{
-	static unsigned cnt = 0, period = 0, dist = 0;
-
-	if (cnt == 0 || cnt == dist)
-		mach_led_d9(1);
-	else if (cnt == 7 || cnt == dist+7)
-		mach_led_d9(0);
-
-	if (++cnt > period) {
-		cnt = 0;
-		/* The hyperbolic function below modifies the heartbeat period
-		 * length in dependency of the current (5min) load. It goes
-		 * through the points f(0)=126, f(1)=86, f(5)=51,
-		 * f(inf)->30. */
-		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
-		dist = period / 4;
-	}
-
-	banner();
-}
-
-#endif
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c
index a9202fe3cb59..d1df2a4fb9b8 100644
--- a/arch/sh/boards/mach-microdev/setup.c
+++ b/arch/sh/boards/mach-microdev/setup.c
@@ -17,70 +17,12 @@
 #include <mach/microdev.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
-
-extern void microdev_heartbeat(void);
-
-
-/****************************************************************************/
-
-
-	/*
-	 * Setup for the SMSC FDC37C93xAPM
-	 */
-#define SMSC_CONFIG_PORT_ADDR	 (0x3F0)
-#define SMSC_INDEX_PORT_ADDR	 SMSC_CONFIG_PORT_ADDR
-#define SMSC_DATA_PORT_ADDR	 (SMSC_INDEX_PORT_ADDR + 1)
-
-#define SMSC_ENTER_CONFIG_KEY	 0x55
-#define SMSC_EXIT_CONFIG_KEY	 0xaa
-
-#define SMCS_LOGICAL_DEV_INDEX 	 0x07	/* Logical Device Number */
-#define SMSC_DEVICE_ID_INDEX	 0x20	/* Device ID */
-#define SMSC_DEVICE_REV_INDEX	 0x21	/* Device Revision */
-#define SMSC_ACTIVATE_INDEX	 0x30	/* Activate */
-#define SMSC_PRIMARY_BASE_INDEX	 0x60	/* Primary Base Address */
-#define SMSC_SECONDARY_BASE_INDEX 0x62	/* Secondary Base Address */
-#define SMSC_PRIMARY_INT_INDEX	 0x70	/* Primary Interrupt Select */
-#define SMSC_SECONDARY_INT_INDEX 0x72	/* Secondary Interrupt Select */
-#define SMSC_HDCS0_INDEX	 0xf0	/* HDCS0 Address Decoder */
-#define SMSC_HDCS1_INDEX	 0xf1	/* HDCS1 Address Decoder */
-
-#define SMSC_IDE1_DEVICE	1	/* IDE #1 logical device */
-#define SMSC_IDE2_DEVICE	2	/* IDE #2 logical device */
-#define SMSC_PARALLEL_DEVICE	3	/* Parallel Port logical device */
-#define SMSC_SERIAL1_DEVICE	4	/* Serial #1 logical device */
-#define SMSC_SERIAL2_DEVICE	5	/* Serial #2 logical device */
-#define SMSC_KEYBOARD_DEVICE	7	/* Keyboard logical device */
-#define SMSC_CONFIG_REGISTERS	8	/* Configuration Registers (Aux I/O) */
-
-#define SMSC_READ_INDEXED(index) ({ \
-	outb((index), SMSC_INDEX_PORT_ADDR); \
-	inb(SMSC_DATA_PORT_ADDR); })
-#define SMSC_WRITE_INDEXED(val, index) ({ \
-	outb((index), SMSC_INDEX_PORT_ADDR); \
-	outb((val),   SMSC_DATA_PORT_ADDR); })
-
-#define	IDE1_PRIMARY_BASE	0x01f0	/* Task File Registe base for IDE #1 */
-#define	IDE1_SECONDARY_BASE	0x03f6	/* Miscellaneous AT registers for IDE #1 */
-#define	IDE2_PRIMARY_BASE	0x0170	/* Task File Registe base for IDE #2 */
-#define	IDE2_SECONDARY_BASE	0x0376	/* Miscellaneous AT registers for IDE #2 */
-
-#define SERIAL1_PRIMARY_BASE	0x03f8
-#define SERIAL2_PRIMARY_BASE	0x02f8
-
-#define	MSB(x)		( (x) >> 8 )
-#define	LSB(x)		( (x) & 0xff )
-
-	/* General-Purpose base address on CPU-board FPGA */
-#define	MICRODEV_FPGA_GP_BASE		0xa6100000ul
-
-	/* assume a Keyboard Controller is present */
-int microdev_kbd_controller_present = 1;
+#include <asm/sizes.h>
 
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start		= 0x300,
-		.end		= 0x300 + 0x0001000 - 1,
+		.end		= 0x300 + SZ_4K - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -97,7 +39,6 @@ static struct platform_device smc91x_device = {
 	.resource	= smc91x_resources,
 };
 
-#ifdef CONFIG_FB_S1D13XXX
 static struct s1d13xxxfb_regval s1d13806_initregs[] = {
 	{ S1DREG_MISC,			0x00 },
 	{ S1DREG_COM_DISP_MODE,		0x00 },
@@ -216,12 +157,12 @@ static struct s1d13xxxfb_pdata s1d13806_platform_data = {
 static struct resource s1d13806_resources[] = {
 	[0] = {
 		.start		= 0x07200000,
-		.end		= 0x07200000 + 0x00200000 - 1,
+		.end		= 0x07200000 + SZ_2M - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
 		.start		= 0x07000000,
-		.end		= 0x07000000 + 0x00200000 - 1,
+		.end		= 0x07000000 + SZ_2M - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 };
@@ -236,145 +177,24 @@ static struct platform_device s1d13806_device = {
 		.platform_data	= &s1d13806_platform_data,
 	},
 };
-#endif
 
 static struct platform_device *microdev_devices[] __initdata = {
 	&smc91x_device,
-#ifdef CONFIG_FB_S1D13XXX
 	&s1d13806_device,
-#endif
 };
 
 static int __init microdev_devices_setup(void)
 {
 	return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
 }
-
-/*
- * Setup for the SMSC FDC37C93xAPM
- */
-static int __init smsc_superio_setup(void)
-{
-
-	unsigned char devid, devrev;
-
-		/* Initially the chip is in run state */
-		/* Put it into configuration state */
-	outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
-
-		/* Read device ID info */
-	devid  = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
-	devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
-	if ( (devid==0x30) && (devrev==0x01) )
-	{
-  		printk("SMSC FDC37C93xAPM SuperIO device detected\n");
-	}
-	else
-	{		/* not the device identity we expected */
-		printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
-			devid, devrev);
-			/* inform the keyboard driver that we have no keyboard controller */
-		microdev_kbd_controller_present = 0;
-			/* little point in doing anything else in this functon */
-		return 0;
-	}
-
-		/* Select the keyboard device */
-	SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-		/* enable it */
-	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-		/* enable the interrupts */
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
-
-		/* Select the Serial #1 device */
-	SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-		/* enable it */
-	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-		/* program with port addresses */
-	SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
-	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
-		/* enable the interrupts */
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
-
-		/* Select the Serial #2 device */
-	SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-		/* enable it */
-	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-		/* program with port addresses */
-	SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
-	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
-		/* enable the interrupts */
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
-
-		/* Select the IDE#1 device */
-	SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-		/* enable it */
-	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-		/* program with port addresses */
-	SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
-	SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
-	SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
-	SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
-		/* select the interrupt */
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
-
-		/* Select the IDE#2 device */
-	SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-		/* enable it */
-	SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-		/* program with port addresses */
-	SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
-	SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
-	SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
-		/* select the interrupt */
-	SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
-
-		/* Select the configuration registers */
-	SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
-		/* enable the appropriate GPIO pins for IDE functionality:
-		 * bit[0]   In/Out		1==input;  0==output
-		 * bit[1]   Polarity		1==invert; 0==no invert
-		 * bit[2]   Int Enb #1		1==Enable Combined IRQ #1; 0==disable
-		 * bit[3:4] Function Select	00==original; 01==Alternate Function #1
-		 */
-	SMSC_WRITE_INDEXED(0x00, 0xc2);	/* GP42 = nIDE1_OE */
-	SMSC_WRITE_INDEXED(0x01, 0xc5);	/* GP45 = IDE1_IRQ */
-	SMSC_WRITE_INDEXED(0x00, 0xc6);	/* GP46 = nIOROP */
-	SMSC_WRITE_INDEXED(0x00, 0xc7);	/* GP47 = nIOWOP */
-	SMSC_WRITE_INDEXED(0x08, 0xe8);	/* GP20 = nIDE2_OE */
-
-		/* Exit the configuration state */
-	outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
-
-	return 0;
-}
-
-static void __init microdev_setup(char **cmdline_p)
-{
-	int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
-	const int fpgaRevision = *fpgaRevisionRegister;
-	int * const CacheControlRegister = (int*)CCR;
-
-	device_initcall(microdev_devices_setup);
-	device_initcall(smsc_superio_setup);
-
-	printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
-		get_system_type(), fpgaRevision, *CacheControlRegister);
-}
+device_initcall(microdev_devices_setup);
 
 /*
  * The Machine Vector
  */
 static struct sh_machine_vector mv_sh4202_microdev __initmv = {
 	.mv_name		= "SH4-202 MicroDev",
-	.mv_setup		= microdev_setup,
-	.mv_nr_irqs		= 72,		/* QQQ need to check this - use the MACRO */
+	.mv_nr_irqs		= 72,
 
 	.mv_inb			= microdev_inb,
 	.mv_inw			= microdev_inw,
@@ -398,8 +218,4 @@ static struct sh_machine_vector mv_sh4202_microdev __initmv = {
 	.mv_outsl		= microdev_outsl,
 
 	.mv_init_irq		= init_microdev_irq,
-
-#ifdef CONFIG_HEARTBEAT
-	.mv_heartbeat		= microdev_heartbeat,
-#endif
 };
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 975281980299..cc1408119c24 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -89,6 +89,7 @@ static struct resource sh_keysc_resources[] = {
 
 static struct platform_device sh_keysc_device = {
 	.name           = "sh_keysc",
+	.id             = 0, /* "keysc0" clock */
 	.num_resources  = ARRAY_SIZE(sh_keysc_resources),
 	.resource       = sh_keysc_resources,
 	.dev	= {
@@ -261,6 +262,8 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
 		.sys_bus_cfg = {
 			.ldmt2r = 0x06000a09,
 			.ldmt3r = 0x180e3418,
+			/* set 1s delay to encourage fsync() */
+			.deferred_io_msec = 1000,
 		},
 	}
 #endif
@@ -273,6 +276,10 @@ static struct resource migor_lcdc_resources[] = {
 		.end	= 0xfe941fff,
 		.flags	= IORESOURCE_MEM,
 	},
+	[1] = {
+		.start	= 28,
+		.flags	= IORESOURCE_IRQ,
+	},
 };
 
 static struct platform_device migor_lcdc_device = {
@@ -300,6 +307,7 @@ static void camera_power_on(void)
 	gpio_set_value(GPIO_PTT3, 0);
 	mdelay(10);
 	gpio_set_value(GPIO_PTT3, 1);
+	mdelay(10); /* wait to let chip come out of reset */
 }
 
 static void camera_power_off(void)
@@ -432,6 +440,7 @@ static struct resource migor_ceu_resources[] = {
 
 static struct platform_device migor_ceu_device = {
 	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
 	.num_resources	= ARRAY_SIZE(migor_ceu_resources),
 	.resource	= migor_ceu_resources,
 	.dev	= {
@@ -479,7 +488,6 @@ static int __init migor_devices_setup(void)
 	ctrl_outl(0x00110080, BSC_CS4WCR);
 
 	/* KEYSC */
-	clk_always_enable("mstp214"); /* KEYSC */
 	gpio_request(GPIO_FN_KEYOUT0, NULL);
 	gpio_request(GPIO_FN_KEYOUT1, NULL);
 	gpio_request(GPIO_FN_KEYOUT2, NULL);
@@ -501,7 +509,6 @@ static int __init migor_devices_setup(void)
 	gpio_request(GPIO_FN_IRQ6, NULL);
 
 	/* LCD Panel */
-	clk_always_enable("mstp200"); /* LCDC */
 #ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */
 	gpio_request(GPIO_FN_LCDD17, NULL);
 	gpio_request(GPIO_FN_LCDD16, NULL);
@@ -554,7 +561,6 @@ static int __init migor_devices_setup(void)
 #endif
 
 	/* CEU */
-	clk_always_enable("mstp203"); /* CEU */
 	gpio_request(GPIO_FN_VIO_CLK2, NULL);
 	gpio_request(GPIO_FN_VIO_VD2, NULL);
 	gpio_request(GPIO_FN_VIO_HD2, NULL);
@@ -589,12 +595,3 @@ static int __init migor_devices_setup(void)
 	return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
 }
 __initcall(migor_devices_setup);
-
-static void __init migor_setup(char **cmdline_p)
-{
-}
-
-static struct sh_machine_vector mv_migor __initmv = {
-	.mv_name		= "Migo-R",
-	.mv_setup		= migor_setup,
-};
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
new file mode 100644
index 000000000000..bff095dffc02
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -0,0 +1,18 @@
+if SH_RSK
+
+choice
+	prompt "RSK+ options"
+	default SH_RSK7203
+
+config SH_RSK7201
+	bool "RSK7201"
+	depends on CPU_SUBTYPE_SH7201
+
+config SH_RSK7203
+	bool "RSK7203"
+	select GENERIC_GPIO
+	depends on CPU_SUBTYPE_SH7203
+
+endchoice
+
+endif
diff --git a/arch/sh/boards/mach-rsk/Makefile b/arch/sh/boards/mach-rsk/Makefile
new file mode 100644
index 000000000000..498da75ce38b
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Makefile
@@ -0,0 +1,2 @@
+obj-y				:= setup.o
+obj-$(CONFIG_SH_RSK7203)	+= devices-rsk7203.o
diff --git a/arch/sh/boards/board-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
index 58266f06134a..73f743b9be8d 100644
--- a/arch/sh/boards/board-rsk7203.c
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -50,73 +50,6 @@ static struct platform_device smc911x_device = {
 	},
 };
 
-static const char *probes[] = { "cmdlinepart", NULL };
-
-static struct mtd_partition *parsed_partitions;
-
-static struct mtd_partition rsk7203_partitions[] = {
-	{
-		.name		= "Bootloader",
-		.offset		= 0x00000000,
-		.size		= 0x00040000,
-		.mask_flags	= MTD_WRITEABLE,
-	}, {
-		.name		= "Kernel",
-		.offset		= MTDPART_OFS_NXTBLK,
-		.size		= 0x001c0000,
-	}, {
-		.name		= "Flash_FS",
-		.offset		= MTDPART_OFS_NXTBLK,
-		.size		= MTDPART_SIZ_FULL,
-	}
-};
-
-static struct physmap_flash_data flash_data = {
-	.width		= 2,
-};
-
-static struct resource flash_resource = {
-	.start		= 0x20000000,
-	.end		= 0x20400000,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device flash_device = {
-	.name		= "physmap-flash",
-	.id		= -1,
-	.resource	= &flash_resource,
-	.num_resources	= 1,
-	.dev		= {
-		.platform_data = &flash_data,
-	},
-};
-
-static struct mtd_info *flash_mtd;
-
-static struct map_info rsk7203_flash_map = {
-	.name		= "RSK+ Flash",
-	.size		= 0x400000,
-	.bankwidth	= 2,
-};
-
-static void __init set_mtd_partitions(void)
-{
-	int nr_parts = 0;
-
-	simple_map_init(&rsk7203_flash_map);
-	flash_mtd = do_map_probe("cfi_probe", &rsk7203_flash_map);
-	nr_parts = parse_mtd_partitions(flash_mtd, probes,
-					&parsed_partitions, 0);
-	/* If there is no partition table, used the hard coded table */
-	if (nr_parts <= 0) {
-		flash_data.parts = rsk7203_partitions;
-		flash_data.nr_parts = ARRAY_SIZE(rsk7203_partitions);
-	} else {
-		flash_data.nr_parts = nr_parts;
-		flash_data.parts = parsed_partitions;
-	}
-}
-
 static struct gpio_led rsk7203_gpio_leds[] = {
 	{
 		.name			= "green",
@@ -155,7 +88,6 @@ static struct platform_device led_device = {
 
 static struct platform_device *rsk7203_devices[] __initdata = {
 	&smc911x_device,
-	&flash_device,
 	&led_device,
 };
 
@@ -165,15 +97,7 @@ static int __init rsk7203_devices_setup(void)
 	gpio_request(GPIO_FN_TXD0, NULL);
 	gpio_request(GPIO_FN_RXD0, NULL);
 
-	set_mtd_partitions();
 	return platform_add_devices(rsk7203_devices,
 				    ARRAY_SIZE(rsk7203_devices));
 }
 device_initcall(rsk7203_devices_setup);
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_rsk7203 __initmv = {
-	.mv_name        = "RSK+7203",
-};
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
new file mode 100644
index 000000000000..af64d030a5c7
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -0,0 +1,106 @@
+/*
+ * Renesas Technology Europe RSK+ Support.
+ *
+ * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/map.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+
+static const char *probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition *parsed_partitions;
+
+static struct mtd_partition rsk_partitions[] = {
+	{
+		.name		= "Bootloader",
+		.offset		= 0x00000000,
+		.size		= 0x00040000,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "Kernel",
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= 0x001c0000,
+	}, {
+		.name		= "Flash_FS",
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct physmap_flash_data flash_data = {
+	.width		= 2,
+};
+
+static struct resource flash_resource = {
+	.start		= 0x20000000,
+	.end		= 0x20400000,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name		= "physmap-flash",
+	.id		= -1,
+	.resource	= &flash_resource,
+	.num_resources	= 1,
+	.dev		= {
+		.platform_data = &flash_data,
+	},
+};
+
+static struct mtd_info *flash_mtd;
+
+static struct map_info rsk_flash_map = {
+	.name		= "RSK+ Flash",
+	.size		= 0x400000,
+	.bankwidth	= 2,
+};
+
+static void __init set_mtd_partitions(void)
+{
+	int nr_parts = 0;
+
+	simple_map_init(&rsk_flash_map);
+	flash_mtd = do_map_probe("cfi_probe", &rsk_flash_map);
+	nr_parts = parse_mtd_partitions(flash_mtd, probes,
+					&parsed_partitions, 0);
+	/* If there is no partition table, used the hard coded table */
+	if (nr_parts <= 0) {
+		flash_data.parts = rsk_partitions;
+		flash_data.nr_parts = ARRAY_SIZE(rsk_partitions);
+	} else {
+		flash_data.nr_parts = nr_parts;
+		flash_data.parts = parsed_partitions;
+	}
+}
+
+static struct platform_device *rsk_devices[] __initdata = {
+	&flash_device,
+};
+
+static int __init rsk_devices_setup(void)
+{
+	set_mtd_partitions();
+	return platform_add_devices(rsk_devices,
+				    ARRAY_SIZE(rsk_devices));
+}
+device_initcall(rsk_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_rsk __initmv = {
+	.mv_name        = "RSK+",
+};
diff --git a/arch/sh/boards/mach-se/7343/Makefile b/arch/sh/boards/mach-se/7343/Makefile
index 3024796c6203..4c3666a93790 100644
--- a/arch/sh/boards/mach-se/7343/Makefile
+++ b/arch/sh/boards/mach-se/7343/Makefile
@@ -2,4 +2,4 @@
 # Makefile for the 7343 SolutionEngine specific parts of the kernel
 #
 
-obj-y	 := setup.o io.o irq.o
+obj-y	 := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7343/io.c b/arch/sh/boards/mach-se/7343/io.c
deleted file mode 100644
index 8741abc1da7b..000000000000
--- a/arch/sh/boards/mach-se/7343/io.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * arch/sh/boards/se/7343/io.c
- *
- * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
- *
- */
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <mach-se/mach/se7343.h>
-
-#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
-
-struct iop {
-	unsigned long start, end;
-	unsigned long base;
-	struct iop *(*check) (struct iop * p, unsigned long port);
-	unsigned char (*inb) (struct iop * p, unsigned long port);
-	unsigned short (*inw) (struct iop * p, unsigned long port);
-	void (*outb) (struct iop * p, unsigned char value, unsigned long port);
-	void (*outw) (struct iop * p, unsigned short value, unsigned long port);
-};
-
-struct iop *
-simple_check(struct iop *p, unsigned long port)
-{
-	static int count;
-
-	if (count < 100)
-		count++;
-
-	port &= 0xFFFF;
-
-	if ((p->start <= port) && (port <= p->end))
-		return p;
-	else
-		badio(check, port);
-}
-
-struct iop *
-ide_check(struct iop *p, unsigned long port)
-{
-	if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
-		return p;
-	return NULL;
-}
-
-unsigned char
-simple_inb(struct iop *p, unsigned long port)
-{
-	return *(unsigned char *) (p->base + port);
-}
-
-unsigned short
-simple_inw(struct iop *p, unsigned long port)
-{
-	return *(unsigned short *) (p->base + port);
-}
-
-void
-simple_outb(struct iop *p, unsigned char value, unsigned long port)
-{
-	*(unsigned char *) (p->base + port) = value;
-}
-
-void
-simple_outw(struct iop *p, unsigned short value, unsigned long port)
-{
-	*(unsigned short *) (p->base + port) = value;
-}
-
-unsigned char
-pcc_inb(struct iop *p, unsigned long port)
-{
-	unsigned long addr = p->base + port + 0x40000;
-	unsigned long v;
-
-	if (port & 1)
-		addr += 0x00400000;
-	v = *(volatile unsigned char *) addr;
-	return v;
-}
-
-void
-pcc_outb(struct iop *p, unsigned char value, unsigned long port)
-{
-	unsigned long addr = p->base + port + 0x40000;
-
-	if (port & 1)
-		addr += 0x00400000;
-	*(volatile unsigned char *) addr = value;
-}
-
-unsigned char
-bad_inb(struct iop *p, unsigned long port)
-{
-	badio(inb, port);
-}
-
-void
-bad_outb(struct iop *p, unsigned char value, unsigned long port)
-{
-	badio(inw, port);
-}
-
-#ifdef CONFIG_SMC91X
-/* MSTLANEX01 LAN at 0xb400:0000 */
-static struct iop laniop = {
-	.start = 0x00,
-	.end = 0x0F,
-	.base = 0x04000000,
-	.check = simple_check,
-	.inb = simple_inb,
-	.inw = simple_inw,
-	.outb = simple_outb,
-	.outw = simple_outw,
-};
-#endif
-
-#ifdef CONFIG_NE2000
-/* NE2000 pc card NIC */
-static struct iop neiop = {
-	.start = 0x280,
-	.end = 0x29f,
-	.base = 0xb0600000 + 0x80,	/* soft 0x280 -> hard 0x300 */
-	.check = simple_check,
-	.inb = pcc_inb,
-	.inw = simple_inw,
-	.outb = pcc_outb,
-	.outw = simple_outw,
-};
-#endif
-
-#ifdef CONFIG_IDE
-/* CF in CF slot */
-static struct iop cfiop = {
-	.base = 0xb0600000,
-	.check = ide_check,
-	.inb = pcc_inb,
-	.inw = simple_inw,
-	.outb = pcc_outb,
-	.outw = simple_outw,
-};
-#endif
-
-static __inline__ struct iop *
-port2iop(unsigned long port)
-{
-	if (0) ;
-#if defined(CONFIG_SMC91X)
-	else if (laniop.check(&laniop, port))
-		return &laniop;
-#endif
-#if defined(CONFIG_NE2000)
-	else if (neiop.check(&neiop, port))
-		return &neiop;
-#endif
-#if defined(CONFIG_IDE)
-	else if (cfiop.check(&cfiop, port))
-		return &cfiop;
-#endif
-	else
-		return NULL;
-}
-
-static inline void
-delay(void)
-{
-	ctrl_inw(0xac000000);
-	ctrl_inw(0xac000000);
-}
-
-unsigned char
-sh7343se_inb(unsigned long port)
-{
-	struct iop *p = port2iop(port);
-	return (p->inb) (p, port);
-}
-
-unsigned char
-sh7343se_inb_p(unsigned long port)
-{
-	unsigned char v = sh7343se_inb(port);
-	delay();
-	return v;
-}
-
-unsigned short
-sh7343se_inw(unsigned long port)
-{
-	struct iop *p = port2iop(port);
-	return (p->inw) (p, port);
-}
-
-unsigned int
-sh7343se_inl(unsigned long port)
-{
-	badio(inl, port);
-}
-
-void
-sh7343se_outb(unsigned char value, unsigned long port)
-{
-	struct iop *p = port2iop(port);
-	(p->outb) (p, value, port);
-}
-
-void
-sh7343se_outb_p(unsigned char value, unsigned long port)
-{
-	sh7343se_outb(value, port);
-	delay();
-}
-
-void
-sh7343se_outw(unsigned short value, unsigned long port)
-{
-	struct iop *p = port2iop(port);
-	(p->outw) (p, value, port);
-}
-
-void
-sh7343se_outl(unsigned int value, unsigned long port)
-{
-	badio(outl, port);
-}
-
-void
-sh7343se_insb(unsigned long port, void *addr, unsigned long count)
-{
-	unsigned char *a = addr;
-	struct iop *p = port2iop(port);
-	while (count--)
-		*a++ = (p->inb) (p, port);
-}
-
-void
-sh7343se_insw(unsigned long port, void *addr, unsigned long count)
-{
-	unsigned short *a = addr;
-	struct iop *p = port2iop(port);
-	while (count--)
-		*a++ = (p->inw) (p, port);
-}
-
-void
-sh7343se_insl(unsigned long port, void *addr, unsigned long count)
-{
-	badio(insl, port);
-}
-
-void
-sh7343se_outsb(unsigned long port, const void *addr, unsigned long count)
-{
-	unsigned char *a = (unsigned char *) addr;
-	struct iop *p = port2iop(port);
-	while (count--)
-		(p->outb) (p, *a++, port);
-}
-
-void
-sh7343se_outsw(unsigned long port, const void *addr, unsigned long count)
-{
-	unsigned short *a = (unsigned short *) addr;
-	struct iop *p = port2iop(port);
-	while (count--)
-		(p->outw) (p, *a++, port);
-}
-
-void
-sh7343se_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-	badio(outsw, port);
-}
diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c
index 486f40bf9274..4de56f35f419 100644
--- a/arch/sh/boards/mach-se/7343/setup.c
+++ b/arch/sh/boards/mach-se/7343/setup.c
@@ -1,36 +1,16 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/usb/isp116x.h>
+#include <linux/delay.h>
 #include <asm/machvec.h>
 #include <mach-se/mach/se7343.h>
 #include <asm/heartbeat.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
-static struct resource smc91x_resources[] = {
-	[0] = {
-		.start	= 0x10000000,
-		.end	= 0x1000000F,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		/*
-		 * shared with other devices via externel
-		 * interrupt controller in FPGA...
-		 */
-		.start	= SMC_IRQ,
-		.end	= SMC_IRQ,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(smc91x_resources),
-	.resource	= smc91x_resources,
-};
-
 static struct resource heartbeat_resources[] = {
 	[0] = {
 		.start	= PA_LED,
@@ -94,10 +74,83 @@ static struct platform_device nor_flash_device = {
 	.resource	= nor_flash_resources,
 };
 
+#define ST16C2550C_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP)
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	[0] = {
+		.iotype		= UPIO_MEM,
+		.mapbase	= 0x16000000,
+		.regshift	= 1,
+		.flags		= ST16C2550C_FLAGS,
+		.irq		= UARTA_IRQ,
+		.uartclk	= 7372800,
+	},
+	[1] = {
+		.iotype		= UPIO_MEM,
+		.mapbase	= 0x17000000,
+		.regshift	= 1,
+		.flags		= ST16C2550C_FLAGS,
+		.irq		= UARTB_IRQ,
+		.uartclk	= 7372800,
+	},
+	{ },
+};
+
+static struct platform_device uart_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+};
+
+static void isp116x_delay(struct device *dev, int delay)
+{
+	ndelay(delay);
+}
+
+static struct resource usb_resources[] = {
+	[0] = {
+		.start  = 0x11800000,
+		.end    = 0x11800001,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0x11800002,
+		.end    = 0x11800003,
+		.flags  = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start  = USB_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct isp116x_platform_data usb_platform_data = {
+	.sel15Kres		= 1,
+	.oc_enable		= 1,
+	.int_act_high		= 0,
+	.int_edge_triggered	= 0,
+	.remote_wakeup_enable	= 0,
+	.delay			= isp116x_delay,
+};
+
+static struct platform_device usb_device = {
+	.name			= "isp116x-hcd",
+	.id			= -1,
+	.num_resources  	= ARRAY_SIZE(usb_resources),
+	.resource       	= usb_resources,
+	.dev			= {
+		.platform_data	= &usb_platform_data,
+	},
+
+};
+
 static struct platform_device *sh7343se_platform_devices[] __initdata = {
-	&smc91x_device,
 	&heartbeat_device,
 	&nor_flash_device,
+	&uart_device,
+	&usb_device,
 };
 
 static int __init sh7343se_devices_setup(void)
@@ -126,27 +179,6 @@ static void __init sh7343se_setup(char **cmdline_p)
 static struct sh_machine_vector mv_7343se __initmv = {
 	.mv_name = "SolutionEngine 7343",
 	.mv_setup = sh7343se_setup,
-	.mv_nr_irqs = 108,
-	.mv_inb = sh7343se_inb,
-	.mv_inw = sh7343se_inw,
-	.mv_inl = sh7343se_inl,
-	.mv_outb = sh7343se_outb,
-	.mv_outw = sh7343se_outw,
-	.mv_outl = sh7343se_outl,
-
-	.mv_inb_p = sh7343se_inb_p,
-	.mv_inw_p = sh7343se_inw,
-	.mv_inl_p = sh7343se_inl,
-	.mv_outb_p = sh7343se_outb_p,
-	.mv_outw_p = sh7343se_outw,
-	.mv_outl_p = sh7343se_outl,
-
-	.mv_insb = sh7343se_insb,
-	.mv_insw = sh7343se_insw,
-	.mv_insl = sh7343se_insl,
-	.mv_outsb = sh7343se_outsb,
-	.mv_outsw = sh7343se_outsw,
-	.mv_outsl = sh7343se_outsl,
-
+	.mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
 	.mv_init_irq = init_7343se_IRQ,
 };
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
index 9123d9687bf7..527eb6b12610 100644
--- a/arch/sh/boards/mach-se/770x/setup.c
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -8,8 +8,9 @@
  */
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <asm/machvec.h>
 #include <mach-se/mach/se.h>
+#include <mach-se/mach/mrshpc.h>
+#include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/smc37c93x.h>
 #include <asm/heartbeat.h>
@@ -175,6 +176,7 @@ static struct platform_device *se_devices[] __initdata = {
 
 static int __init se_devices_setup(void)
 {
+	mrshpc_setup_windows();
 	return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
 }
 device_initcall(se_devices_setup);
diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c
index d3fc80ff4d83..55af4c36b43a 100644
--- a/arch/sh/boards/mach-se/7721/setup.c
+++ b/arch/sh/boards/mach-se/7721/setup.c
@@ -12,8 +12,9 @@
  */
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <asm/machvec.h>
 #include <mach-se/mach/se7721.h>
+#include <mach-se/mach/mrshpc.h>
+#include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
 
@@ -74,8 +75,8 @@ static struct platform_device *se7721_devices[] __initdata = {
 
 static int __init se7721_devices_setup(void)
 {
-	return platform_add_devices(se7721_devices,
-		ARRAY_SIZE(se7721_devices));
+	mrshpc_setup_windows();
+	return platform_add_devices(se7721_devices, ARRAY_SIZE(se7721_devices));
 }
 device_initcall(se7721_devices_setup);
 
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index fe6f96517e12..af84904ed86f 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -15,9 +15,10 @@
 #include <linux/ata_platform.h>
 #include <linux/input.h>
 #include <linux/smc91x.h>
+#include <mach-se/mach/se7722.h>
+#include <mach-se/mach/mrshpc.h>
 #include <asm/machvec.h>
 #include <asm/clock.h>
-#include <mach-se/mach/se7722.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_keysc.h>
@@ -130,6 +131,7 @@ static struct resource sh_keysc_resources[] = {
 
 static struct platform_device sh_keysc_device = {
 	.name           = "sh_keysc",
+	.id             = 0, /* "keysc0" clock */
 	.num_resources  = ARRAY_SIZE(sh_keysc_resources),
 	.resource       = sh_keysc_resources,
 	.dev	= {
@@ -146,10 +148,8 @@ static struct platform_device *se7722_devices[] __initdata = {
 
 static int __init se7722_devices_setup(void)
 {
-	clk_always_enable("mstp214"); /* KEYSC */
-
-	return platform_add_devices(se7722_devices,
-		ARRAY_SIZE(se7722_devices));
+	mrshpc_setup_windows();
+	return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
 }
 device_initcall(se7722_devices_setup);
 
diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c
index 5771219be3fd..74cfb4b8b03d 100644
--- a/arch/sh/boards/mach-sh03/setup.c
+++ b/arch/sh/boards/mach-sh03/setup.c
@@ -9,6 +9,7 @@
 #include <linux/irq.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/ata_platform.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
 #include <mach-sh03/mach/io.h>
@@ -20,19 +21,6 @@ static void __init init_sh03_IRQ(void)
 	plat_irq_setup_pins(IRQ_MODE_IRQ);
 }
 
-extern void *cf_io_base;
-
-static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size)
-{
-	if (PXSEG(port))
-		return (void __iomem *)port;
-	/* CompactFlash (IDE) */
-	if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6))
-		return (void __iomem *)((unsigned long)cf_io_base + port);
-
-        return (void __iomem *)(port + PCI_IO_BASE);
-}
-
 /* arch/sh/boards/sh03/rtc.c */
 void sh03_time_init(void);
 
@@ -41,6 +29,30 @@ static void __init sh03_setup(char **cmdline_p)
 	board_time_init = sh03_time_init;
 }
 
+static struct resource cf_ide_resources[] = {
+	[0] = {
+		.start  = 0x1f0,
+		.end    = 0x1f0 + 8,
+		.flags  = IORESOURCE_IO,
+	},
+	[1] = {
+		.start  = 0x1f0 + 0x206,
+		.end    = 0x1f0 +8 + 0x206 + 8,
+		.flags  = IORESOURCE_IO,
+	},
+	[2] = {
+		.start  = IRL2_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cf_ide_device = {
+	.name		= "pata_platform",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(cf_ide_resources),
+	.resource	= cf_ide_resources,
+};
+
 static struct resource heartbeat_resources[] = {
 	[0] = {
 		.start	= 0xa0800000,
@@ -58,10 +70,30 @@ static struct platform_device heartbeat_device = {
 
 static struct platform_device *sh03_devices[] __initdata = {
 	&heartbeat_device,
+	&cf_ide_device,
 };
 
 static int __init sh03_devices_setup(void)
 {
+	pgprot_t prot;
+	unsigned long paddrbase;
+	void *cf_ide_base;
+
+	/* open I/O area window */
+	paddrbase = virt_to_phys((void *)PA_AREA5_IO);
+	prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+	cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+	if (!cf_ide_base) {
+		printk("allocate_cf_area : can't open CF I/O window!\n");
+		return -ENOMEM;
+	}
+
+	/* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+	cf_ide_resources[0].start += (unsigned long)cf_ide_base;
+	cf_ide_resources[0].end   += (unsigned long)cf_ide_base;
+	cf_ide_resources[1].start += (unsigned long)cf_ide_base;
+	cf_ide_resources[1].end   += (unsigned long)cf_ide_base;
+
 	return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices));
 }
 __initcall(sh03_devices_setup);
@@ -70,6 +102,5 @@ static struct sh_machine_vector mv_sh03 __initmv = {
 	.mv_name		= "Interface (CTP/PCI-SH03)",
 	.mv_setup		= sh03_setup,
 	.mv_nr_irqs		= 48,
-	.mv_ioport_map		= sh03_ioport_map,
 	.mv_init_irq		= init_sh03_IRQ,
 };
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 538406872a89..986a0e71d220 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -12,8 +12,8 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/systemh7751.h>
 #include <asm/smc37c93x.h>
 
@@ -24,35 +24,17 @@ static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
 static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
 
 /* forward declaration */
-static unsigned int startup_systemh_irq(unsigned int irq);
-static void shutdown_systemh_irq(unsigned int irq);
 static void enable_systemh_irq(unsigned int irq);
 static void disable_systemh_irq(unsigned int irq);
 static void mask_and_ack_systemh(unsigned int);
-static void end_systemh_irq(unsigned int irq);
 
-/* hw_interrupt_type */
-static struct hw_interrupt_type systemh_irq_type = {
-	.typename = " SystemH Register",
-	.startup = startup_systemh_irq,
-	.shutdown = shutdown_systemh_irq,
-	.enable = enable_systemh_irq,
-	.disable = disable_systemh_irq,
+static struct irq_chip systemh_irq_type = {
+	.name = " SystemH Register",
+	.unmask = enable_systemh_irq,
+	.mask = disable_systemh_irq,
 	.ack = mask_and_ack_systemh,
-	.end = end_systemh_irq
 };
 
-static unsigned int startup_systemh_irq(unsigned int irq)
-{
-	enable_systemh_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static void shutdown_systemh_irq(unsigned int irq)
-{
-	disable_systemh_irq(irq);
-}
-
 static void disable_systemh_irq(unsigned int irq)
 {
 	if (systemh_irq_mask_register) {
@@ -86,16 +68,9 @@ static void mask_and_ack_systemh(unsigned int irq)
 	disable_systemh_irq(irq);
 }
 
-static void end_systemh_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_systemh_irq(irq);
-}
-
 void make_systemh_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-	irq_desc[irq].chip = &systemh_irq_type;
+	set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq);
 	disable_systemh_irq(irq);
 }
-
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index f1a4a0763c59..27ceeb948bb1 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -10,99 +10,49 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/hd64461.h>
 
 /* This belongs in cpu specific */
 #define INTC_ICR1 0xA4140010UL
 
-static void disable_hd64461_irq(unsigned int irq)
+static void hd64461_mask_irq(unsigned int irq)
 {
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
-	nimr = inw(HD64461_NIMR);
+	nimr = __raw_readw(HD64461_NIMR);
 	nimr |= mask;
-	outw(nimr, HD64461_NIMR);
+	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void enable_hd64461_irq(unsigned int irq)
+static void hd64461_unmask_irq(unsigned int irq)
 {
 	unsigned short nimr;
 	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 
-	nimr = inw(HD64461_NIMR);
+	nimr = __raw_readw(HD64461_NIMR);
 	nimr &= ~mask;
-	outw(nimr, HD64461_NIMR);
+	__raw_writew(nimr, HD64461_NIMR);
 }
 
-static void mask_and_ack_hd64461(unsigned int irq)
+static void hd64461_mask_and_ack_irq(unsigned int irq)
 {
-	disable_hd64461_irq(irq);
+	hd64461_mask_irq(irq);
 #ifdef CONFIG_HD64461_ENABLER
 	if (irq == HD64461_IRQBASE + 13)
-		outb(0x00, HD64461_PCC1CSCR);
+		__raw_writeb(0x00, HD64461_PCC1CSCR);
 #endif
 }
 
-static void end_hd64461_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_hd64461_irq(irq);
-}
-
-static unsigned int startup_hd64461_irq(unsigned int irq)
-{
-	enable_hd64461_irq(irq);
-	return 0;
-}
-
-static void shutdown_hd64461_irq(unsigned int irq)
-{
-	disable_hd64461_irq(irq);
-}
-
-static struct hw_interrupt_type hd64461_irq_type = {
-	.typename	= "HD64461-IRQ",
-	.startup	= startup_hd64461_irq,
-	.shutdown	= shutdown_hd64461_irq,
-	.enable		= enable_hd64461_irq,
-	.disable	= disable_hd64461_irq,
-	.ack		= mask_and_ack_hd64461,
-	.end		= end_hd64461_irq,
+static struct irq_chip hd64461_irq_chip = {
+	.name		= "HD64461-IRQ",
+	.mask		= hd64461_mask_irq,
+	.mask_ack	= hd64461_mask_and_ack_irq,
+	.unmask		= hd64461_unmask_irq,
 };
 
-static irqreturn_t hd64461_interrupt(int irq, void *dev_id)
-{
-	printk(KERN_INFO
-	       "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
-	       inw(HD64461_NIRR), inw(HD64461_NIMR));
-
-	return IRQ_NONE;
-}
-
-static struct {
-	int (*func) (int, void *);
-	void *dev;
-} hd64461_demux[HD64461_IRQ_NUM];
-
-void hd64461_register_irq_demux(int irq,
-				int (*demux) (int irq, void *dev), void *dev)
-{
-	hd64461_demux[irq - HD64461_IRQBASE].func = demux;
-	hd64461_demux[irq - HD64461_IRQBASE].dev = dev;
-}
-
-EXPORT_SYMBOL(hd64461_register_irq_demux);
-
-void hd64461_unregister_irq_demux(int irq)
-{
-	hd64461_demux[irq - HD64461_IRQBASE].func = 0;
-}
-
-EXPORT_SYMBOL(hd64461_unregister_irq_demux);
-
 int hd64461_irq_demux(int irq)
 {
 	if (irq == CONFIG_HD64461_IRQ) {
@@ -115,25 +65,11 @@ int hd64461_irq_demux(int irq)
 		for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
 			if (nirr & bit)
 				break;
-		if (i == 16)
-			irq = CONFIG_HD64461_IRQ;
-		else {
-			irq = HD64461_IRQBASE + i;
-			if (hd64461_demux[i].func != 0) {
-				irq = hd64461_demux[i].func(irq, hd64461_demux[i].dev);
-			}
-		}
+		irq = HD64461_IRQBASE + i;
 	}
 	return irq;
 }
 
-static struct irqaction irq0 = {
-	.handler = hd64461_interrupt,
-	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
-	.name = "HD64461",
-};
-
 int __init setup_hd64461(void)
 {
 	int i;
@@ -146,22 +82,21 @@ int __init setup_hd64461(void)
 	       CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE,
 	       HD64461_IRQBASE + 15);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)	/* Should be at processor specific part.. */
-	outw(0x2240, INTC_ICR1);
+/* Should be at processor specific part.. */
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+	__raw_writew(0x2240, INTC_ICR1);
 #endif
-	outw(0xffff, HD64461_NIMR);
+	__raw_writew(0xffff, HD64461_NIMR);
 
 	/*  IRQ 80 -> 95 belongs to HD64461  */
-	for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
-		irq_desc[i].chip = &hd64461_irq_type;
-	}
-
-	setup_irq(CONFIG_HD64461_IRQ, &irq0);
+	for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++)
+		set_irq_chip_and_handler(i, &hd64461_irq_chip,
+					 handle_level_irq);
 
 #ifdef CONFIG_HD64461_ENABLER
 	printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
-	outb(0x4c, HD64461_PCC1CSCIER);
-	outb(0x00, HD64461_PCC1CSCR);
+	__raw_writeb(0x4c, HD64461_PCC1CSCIER);
+	__raw_writeb(0x00, HD64461_PCC1CSCR);
 #endif
 
 	return 0;
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
new file mode 100644
index 000000000000..8f4329fbbd39
--- /dev/null
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -0,0 +1,438 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc6
+# Wed Dec 17 13:53:02 2008
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PRINTK is not set
+# CONFIG_BUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_SHMEM=y
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_MODULES is not set
+# CONFIG_BLOCK is not set
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+CONFIG_CPU_SUBTYPE_SH7705=y
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+
+#
+# Cache configuration
+#
+CONFIG_SH7705_CACHE_32KB=y
+# CONFIG_SH_DIRECT_MAPPED is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Board support
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+CONFIG_SH_EDOSK7705=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=31250000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
+
+#
+# File systems
+#
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
new file mode 100644
index 000000000000..014c18cbf46a
--- /dev/null
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -0,0 +1,703 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc6
+# Mon Dec  8 14:48:02 2008
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_IKCONFIG=y
+# CONFIG_IKCONFIG_PROC is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+# CONFIG_AIO is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH2=y
+CONFIG_CPU_SH2A=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+CONFIG_CPU_SUBTYPE_SH7201=y
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_PAGE_OFFSET=0x00000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x01000000
+CONFIG_29BIT=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_SH_FPU=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_RSK=y
+CONFIG_SH_RSK7201=y
+# CONFIG_SH_RSK7203 is not set
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_CMT is not set
+CONFIG_SH_MTU2=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=40000000
+CONFIG_SH_CLK_MD=0
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ignore_loglevel"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 85b0ac4fc667..dcdef31cf19b 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Tue Oct 21 12:58:47 2008
+# Linux kernel version: 2.6.28-rc6
+# Mon Dec  8 14:35:03 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,6 +16,8 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -75,7 +77,6 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -126,6 +127,7 @@ CONFIG_CLASSIC_RCU=y
 CONFIG_CPU_SH2=y
 CONFIG_CPU_SH2A=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
 CONFIG_CPU_SUBTYPE_SH7203=y
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -211,6 +213,8 @@ CONFIG_CPU_HAS_FPU=y
 #
 # Board support
 #
+CONFIG_SH_RSK=y
+# CONFIG_SH_RSK7201 is not set
 CONFIG_SH_RSK7203=y
 
 #
@@ -296,6 +300,14 @@ CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_NET=y
 
 #
@@ -477,6 +489,7 @@ CONFIG_BLK_DEV=y
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -603,11 +616,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -617,7 +630,11 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
 
 #
 # Multimedia devices
@@ -702,19 +719,22 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
+# CONFIG_USB_HWA_HCD is not set
 
 #
 # USB Device Class drivers
@@ -725,11 +745,11 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -770,7 +790,22 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -812,6 +847,7 @@ CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -950,9 +986,14 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
diff --git a/arch/sh/configs/rts7751r2dplus_qemu_defconfig b/arch/sh/configs/rts7751r2dplus_qemu_defconfig
deleted file mode 100644
index ae8f63000fbf..000000000000
--- a/arch/sh/configs/rts7751r2dplus_qemu_defconfig
+++ /dev/null
@@ -1,949 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 18:51:20 2008
-#
-CONFIG_SUPERH=y
-CONFIG_SUPERH32=y
-CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
-# CONFIG_GENERIC_GPIO is not set
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_SYS_SUPPORTS_PCI=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_IO_TRAPPED=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
-CONFIG_OPROFILE=y
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-# CONFIG_MODULE_UNLOAD is not set
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_FREEZER is not set
-
-#
-# System type
-#
-CONFIG_CPU_SH4=y
-# CONFIG_CPU_SUBTYPE_SH7619 is not set
-# CONFIG_CPU_SUBTYPE_SH7203 is not set
-# CONFIG_CPU_SUBTYPE_SH7206 is not set
-# CONFIG_CPU_SUBTYPE_SH7263 is not set
-# CONFIG_CPU_SUBTYPE_MXG is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7706 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7710 is not set
-# CONFIG_CPU_SUBTYPE_SH7712 is not set
-# CONFIG_CPU_SUBTYPE_SH7720 is not set
-# CONFIG_CPU_SUBTYPE_SH7721 is not set
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7091 is not set
-# CONFIG_CPU_SUBTYPE_SH7750R is not set
-# CONFIG_CPU_SUBTYPE_SH7750S is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-CONFIG_CPU_SUBTYPE_SH7751R=y
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-# CONFIG_CPU_SUBTYPE_SH7723 is not set
-# CONFIG_CPU_SUBTYPE_SH7763 is not set
-# CONFIG_CPU_SUBTYPE_SH7770 is not set
-# CONFIG_CPU_SUBTYPE_SH7780 is not set
-# CONFIG_CPU_SUBTYPE_SH7785 is not set
-# CONFIG_CPU_SUBTYPE_SHX3 is not set
-# CONFIG_CPU_SUBTYPE_SH7343 is not set
-# CONFIG_CPU_SUBTYPE_SH7722 is not set
-# CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
-
-#
-# Memory management options
-#
-CONFIG_QUICKLIST=y
-CONFIG_MMU=y
-CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_29BIT=y
-CONFIG_VSYSCALL=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_DEFAULT=y
-CONFIG_MAX_ACTIVE_REGIONS=1
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_ENTRY_OFFSET=0x00001000
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_SPARSEMEM_STATIC=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
-CONFIG_UNEVICTABLE_LRU=y
-
-#
-# Cache configuration
-#
-# CONFIG_SH_DIRECT_MAPPED is not set
-CONFIG_CACHE_WRITEBACK=y
-# CONFIG_CACHE_WRITETHROUGH is not set
-# CONFIG_CACHE_OFF is not set
-
-#
-# Processor features
-#
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_SH_FPU=y
-# CONFIG_SH_STORE_QUEUES is not set
-CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_SR_RB=y
-CONFIG_CPU_HAS_PTEA=y
-CONFIG_CPU_HAS_FPU=y
-
-#
-# Board support
-#
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-CONFIG_SH_RTS7751R2D=y
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_LBOX_RE2 is not set
-
-#
-# RTS7751R2D Board Revision
-#
-CONFIG_RTS7751R2D_PLUS=y
-# CONFIG_RTS7751R2D_1 is not set
-
-#
-# Timer and clock configuration
-#
-CONFIG_SH_TMU=y
-CONFIG_SH_TIMER_IRQ=16
-CONFIG_SH_PCLK_FREQ=60000000
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-
-#
-# Additional SuperH Device Drivers
-#
-CONFIG_HEARTBEAT=y
-# CONFIG_PUSH_SWITCH is not set
-
-#
-# Kernel features
-#
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
-# CONFIG_CRASH_DUMP is not set
-CONFIG_SECCOMP=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_GUSA=y
-# CONFIG_GUSA_RB is not set
-
-#
-# Boot options
-#
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
-
-#
-# Bus options
-#
-# CONFIG_PCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_NET is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_ATA=y
-# CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
-CONFIG_ATA_SFF=y
-# CONFIG_SATA_MV is not set
-# CONFIG_PATA_PLATFORM is not set
-# CONFIG_MD is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_CONSOLE is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-CONFIG_SPI_BITBANG=y
-# CONFIG_SPI_SH_SCI is not set
-
-#
-# SPI Protocol Masters
-#
-# CONFIG_SPI_AT25 is not set
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_TLE62X0 is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-CONFIG_MFD_SM501=y
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_S1D13XXX is not set
-CONFIG_FB_SH_MOBILE_LCDC=m
-CONFIG_FB_SM501=y
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_LOGO_SUPERH_MONO is not set
-# CONFIG_LOGO_SUPERH_VGA16 is not set
-CONFIG_LOGO_SUPERH_CLUT224=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_SPI=y
-CONFIG_SND_SUPERH=y
-# CONFIG_SND_SOC is not set
-CONFIG_SOUND_PRIME=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-# CONFIG_HIDRAW is not set
-# CONFIG_HID_PID is not set
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-# CONFIG_RTC_DRV_TEST is not set
-
-#
-# SPI RTC drivers
-#
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-CONFIG_RTC_DRV_R9701=y
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_RTC_DRV_SH is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
-# CONFIG_XFS_FS is not set
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FTRACE=y
-# CONFIG_FTRACE is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
-CONFIG_EARLY_PRINTK=y
-# CONFIG_DEBUG_BOOTMEM is not set
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_4KSTACKS is not set
-# CONFIG_IRQSTACKS is not set
-# CONFIG_SH_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_HW=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=y
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 075f42ed5b09..be246f381507 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 19:00:21 2008
+# Linux kernel version: 2.6.28-rc6
+# Thu Dec  4 16:40:25 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -74,7 +74,6 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -127,6 +126,7 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -227,7 +227,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
 #
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
-CONFIG_SH_PCLK_FREQ=27000000
+CONFIG_SH_PCLK_FREQ=33333333
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -274,7 +274,8 @@ CONFIG_GUSA=y
 #
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200"
 
 #
 # Bus options
@@ -463,6 +464,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -519,23 +521,10 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_ETHERNET is not set
 CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_STNIC is not set
-CONFIG_SMC91X=y
-# CONFIG_SMC911X is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-CONFIG_NETDEV_1000=y
-CONFIG_NETDEV_10000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 
 #
 # Wireless LAN
@@ -543,6 +532,26 @@ CONFIG_NETDEV_10000=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=y
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -597,13 +606,17 @@ CONFIG_DEVKMEM=y
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_NR_UARTS=4
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -615,7 +628,51 @@ CONFIG_HW_RANDOM=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
@@ -623,11 +680,11 @@ CONFIG_HW_RANDOM=y
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -637,7 +694,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -657,6 +717,16 @@ CONFIG_VIDEO_MEDIA=y
 # Multimedia drivers
 #
 # CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEO_V4L1=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -665,8 +735,57 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
 CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
 # CONFIG_DAB is not set
 
 #
@@ -700,6 +819,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -737,27 +857,147 @@ CONFIG_SND_DRIVERS=y
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 CONFIG_SND_SUPERH=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
 # CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
 
 #
 # Special HID drivers
 #
 CONFIG_HID_COMPAT=y
-# CONFIG_USB_SUPPORT is not set
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_ISP116X_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
 # CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -889,8 +1129,13 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
index 1ac812d24488..ab956adacb47 100644
--- a/arch/sh/drivers/dma/Makefile
+++ b/arch/sh/drivers/dma/Makefile
@@ -3,7 +3,6 @@
 #
 
 obj-$(CONFIG_SH_DMA_API)	+= dma-api.o dma-sysfs.o
-obj-$(CONFIG_ISA_DMA_API)	+= dma-isa.o
 obj-$(CONFIG_SH_DMA)		+= dma-sh.o
 obj-$(CONFIG_SH_DREAMCAST)	+= dma-pvr2.o dma-g2.o
 obj-$(CONFIG_SH_DMABRG)		+= dmabrg.o
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c
deleted file mode 100644
index 5fb044b791c3..000000000000
--- a/arch/sh/drivers/dma/dma-isa.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * arch/sh/drivers/dma/dma-isa.c
- *
- * Generic ISA DMA wrapper for SH DMA API
- *
- * Copyright (C) 2003, 2004  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/kernel.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-
-/*
- * This implements a small wrapper set to make code using the old ISA DMA API
- * work with the SH DMA API. Since most of the work in the new API happens
- * at ops->xfer() time, we simply use the various set_dma_xxx() routines to
- * fill in per-channel info, and then hand hand this off to ops->xfer() at
- * enable_dma() time.
- *
- * For channels that are doing on-demand data transfer via cascading, the
- * channel itself will still need to be configured through the new API. As
- * such, this code is meant for only the simplest of tasks (and shouldn't be
- * used in any new drivers at all).
- *
- * NOTE: ops->xfer() is the preferred way of doing things. However, there
- * are some users of the ISA DMA API that exist in common code that we
- * don't necessarily want to go out of our way to break, so we still
- * allow for some compatibility at that level. Any new code is strongly
- * advised to run far away from the ISA DMA API and use the SH DMA API
- * directly.
- */
-unsigned long claim_dma_lock(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dma_spin_lock, flags);
-
-	return flags;
-}
-EXPORT_SYMBOL(claim_dma_lock);
-
-void release_dma_lock(unsigned long flags)
-{
-	spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-EXPORT_SYMBOL(release_dma_lock);
-
-void disable_dma(unsigned int chan)
-{
-	/* Nothing */
-}
-EXPORT_SYMBOL(disable_dma);
-
-void enable_dma(unsigned int chan)
-{
-	struct dma_info *info = get_dma_info(chan);
-	struct dma_channel *channel = &info->channels[chan];
-
-	info->ops->xfer(channel);
-}
-EXPORT_SYMBOL(enable_dma);
-
-void clear_dma_ff(unsigned int chan)
-{
-	/* Nothing */
-}
-EXPORT_SYMBOL(clear_dma_ff);
-
-void set_dma_mode(unsigned int chan, char mode)
-{
-	struct dma_info *info = get_dma_info(chan);
-	struct dma_channel *channel = &info->channels[chan];
-
-	channel->mode = mode;
-}
-EXPORT_SYMBOL(set_dma_mode);
-
-void set_dma_addr(unsigned int chan, unsigned int addr)
-{
-	struct dma_info *info = get_dma_info(chan);
-	struct dma_channel *channel = &info->channels[chan];
-
-	/*
-	 * Single address mode is the only thing supported through
-	 * this interface.
-	 */
-	if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) {
-		channel->sar = addr;
-	} else {
-		channel->dar = addr;
-	}
-}
-EXPORT_SYMBOL(set_dma_addr);
-
-void set_dma_count(unsigned int chan, unsigned int count)
-{
-	struct dma_info *info = get_dma_info(chan);
-	struct dma_channel *channel = &info->channels[chan];
-
-	channel->count = count;
-}
-EXPORT_SYMBOL(set_dma_count);
-
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index b2ffe649c7c0..50887a592dd0 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -205,7 +205,8 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7780)
+    defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 #define dmaor_read_reg()	ctrl_inw(DMAOR)
 #define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
 #else
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
index b05af34fc15d..05fecd5428e4 100644
--- a/arch/sh/drivers/dma/dma-sh.h
+++ b/arch/sh/drivers/dma/dma-sh.h
@@ -29,6 +29,7 @@
 #define RS_IN	0x00000200
 #define RS_OUT	0x00000300
 #define TS_BLK	0x00000040
+#define TM_BUR	0x00000020
 #define CHCR_DE 0x00000001
 #define CHCR_TE 0x00000002
 #define CHCR_IE 0x00000004
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
index ebb58e605d9d..e1703ff5a4d2 100644
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -18,7 +18,8 @@
  */
 int __init pcibios_init_platform(void)
 {
-   return 1;
+	__set_io_port_base(SH7751_PCI_IO_BASE);
+	return 1;
 }
 
 static struct resource sh7751_io_resource = {
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index b2a2bfa3c1bd..078dc44d6b08 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -123,16 +123,14 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
 	 * Window0 = map->window0.size @ non-cached area base = SDRAM
 	 * Window1 = map->window1.size @ cached area base = SDRAM
 	 */
-	word = ((map->window0.size - 1) & 0x1ff00001) | 0x01;
-	pci_write_reg(0x07f00001, SH4_PCILSR0);
-	word = ((map->window1.size - 1) & 0x1ff00001) | 0x01;
+	word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
+	pci_write_reg(word, SH4_PCILSR0);
 	pci_write_reg(0x00000001, SH4_PCILSR1);
 	/* Set the values on window 0 PCI config registers */
-	word = P2SEGADDR(map->window0.base);
-	pci_write_reg(0xa8000000, SH4_PCILAR0);
-	pci_write_reg(0x08000000, SH7780_PCIMBAR0);
+	word = (CONFIG_MEMORY_SIZE > 0x08000000) ? 0x10000000 : 0x08000000;
+	pci_write_reg(word | 0xa0000000, SH4_PCILAR0);
+	pci_write_reg(word, SH7780_PCIMBAR0);
 	/* Set the values on window 1 PCI config registers */
-	word = P2SEGADDR(map->window1.base);
 	pci_write_reg(0x00000000, SH4_PCILAR1);
 	pci_write_reg(0x00000000, SH7780_PCIMBAR1);
 
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 2702d81bfc0d..36736c7e93db 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -49,5 +49,16 @@
 /* Check if an address can be reached in 29 bits */
 #define IS_29BIT(a)	(((unsigned long)(a)) < 0x20000000)
 
+#ifdef CONFIG_SH_STORE_QUEUES
+/*
+ * This is a special case for the SH-4 store queues, as pages for this
+ * space still need to be faulted in before it's possible to flush the
+ * store queue cache for writeout to the remapped region.
+ */
+#define P3_ADDR_MAX		(P4SEG_STORE_QUE + 0x04000000)
+#else
+#define P3_ADDR_MAX		P4SEG
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_ADDRSPACE_H */
diff --git a/arch/sh/include/asm/bitops-grb.h b/arch/sh/include/asm/bitops-grb.h
index a5907b94395b..e73af33acbf4 100644
--- a/arch/sh/include/asm/bitops-grb.h
+++ b/arch/sh/include/asm/bitops-grb.h
@@ -166,4 +166,7 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
 
         return retval;
 }
+
+#include <asm-generic/bitops/non-atomic.h>
+
 #endif /* __ASM_SH_BITOPS_GRB_H */
diff --git a/arch/sh/include/asm/bitops-irq.h b/arch/sh/include/asm/bitops-irq.h
deleted file mode 100644
index 653a12750584..000000000000
--- a/arch/sh/include/asm/bitops-irq.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef __ASM_SH_BITOPS_IRQ_H
-#define __ASM_SH_BITOPS_IRQ_H
-
-static inline void set_bit(int nr, volatile void *addr)
-{
-	int	mask;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	*a |= mask;
-	local_irq_restore(flags);
-}
-
-static inline void clear_bit(int nr, volatile void *addr)
-{
-	int	mask;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	*a &= ~mask;
-	local_irq_restore(flags);
-}
-
-static inline void change_bit(int nr, volatile void *addr)
-{
-	int	mask;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	*a ^= mask;
-	local_irq_restore(flags);
-}
-
-static inline int test_and_set_bit(int nr, volatile void *addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a |= mask;
-	local_irq_restore(flags);
-
-	return retval;
-}
-
-static inline int test_and_clear_bit(int nr, volatile void *addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a &= ~mask;
-	local_irq_restore(flags);
-
-	return retval;
-}
-
-static inline int test_and_change_bit(int nr, volatile void *addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = addr;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a ^= mask;
-	local_irq_restore(flags);
-
-	return retval;
-}
-
-#endif /* __ASM_SH_BITOPS_IRQ_H */
diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h
index 43b8e1a8239e..1d2fc0b010ad 100644
--- a/arch/sh/include/asm/bitops-llsc.h
+++ b/arch/sh/include/asm/bitops-llsc.h
@@ -141,4 +141,6 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
 	return retval != 0;
 }
 
+#include <asm-generic/bitops/non-atomic.h>
+
 #endif /* __ASM_SH_BITOPS_LLSC_H */
diff --git a/arch/sh/include/asm/bitops-op32.h b/arch/sh/include/asm/bitops-op32.h
new file mode 100644
index 000000000000..f0ae7e9218e0
--- /dev/null
+++ b/arch/sh/include/asm/bitops-op32.h
@@ -0,0 +1,142 @@
+#ifndef __ASM_SH_BITOPS_OP32_H
+#define __ASM_SH_BITOPS_OP32_H
+
+/*
+ * The bit modifying instructions on SH-2A are only capable of working
+ * with a 3-bit immediate, which signifies the shift position for the bit
+ * being worked on.
+ */
+#if defined(__BIG_ENDIAN)
+#define BITOP_LE_SWIZZLE	((BITS_PER_LONG-1) & ~0x7)
+#define BYTE_NUMBER(nr)		((nr ^ BITOP_LE_SWIZZLE) / BITS_PER_BYTE)
+#define BYTE_OFFSET(nr)		((nr ^ BITOP_LE_SWIZZLE) % BITS_PER_BYTE)
+#else
+#define BYTE_NUMBER(nr)		((nr) / BITS_PER_BYTE)
+#define BYTE_OFFSET(nr)		((nr) % BITS_PER_BYTE)
+#endif
+
+#define IS_IMMEDIATE(nr)	(__builtin_constant_p(nr))
+
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+	if (IS_IMMEDIATE(nr)) {
+		__asm__ __volatile__ (
+			"bset.b %1, @(%O2,%0)		! __set_bit\n\t"
+			: "+r" (addr)
+			: "i" (BYTE_OFFSET(nr)), "i" (BYTE_NUMBER(nr))
+			: "t", "memory"
+		);
+	} else {
+		unsigned long mask = BIT_MASK(nr);
+		unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+		*p |= mask;
+	}
+}
+
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+	if (IS_IMMEDIATE(nr)) {
+		__asm__ __volatile__ (
+			"bclr.b %1, @(%O2,%0)		! __clear_bit\n\t"
+			: "+r" (addr)
+			: "i" (BYTE_OFFSET(nr)),
+			  "i" (BYTE_NUMBER(nr))
+			: "t", "memory"
+		);
+	} else {
+		unsigned long mask = BIT_MASK(nr);
+		unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+		*p &= ~mask;
+	}
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static inline void __change_bit(int nr, volatile unsigned long *addr)
+{
+	if (IS_IMMEDIATE(nr)) {
+		__asm__ __volatile__ (
+			"bxor.b %1, @(%O2,%0)		! __change_bit\n\t"
+			: "+r" (addr)
+			: "i" (BYTE_OFFSET(nr)),
+			  "i" (BYTE_NUMBER(nr))
+			: "t", "memory"
+		);
+	} else {
+		unsigned long mask = BIT_MASK(nr);
+		unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+		*p ^= mask;
+	}
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old | mask;
+	return (old & mask) != 0;
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old & ~mask;
+	return (old & mask) != 0;
+}
+
+/* WARNING: non atomic and it can be reordered! */
+static inline int __test_and_change_bit(int nr,
+					    volatile unsigned long *addr)
+{
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+	unsigned long old = *p;
+
+	*p = old ^ mask;
+	return (old & mask) != 0;
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit(int nr, const volatile unsigned long *addr)
+{
+	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+#endif /* __ASM_SH_BITOPS_OP32_H */
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index 367930d8e5ae..ebe595b7ab1f 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -13,21 +13,22 @@
 
 #ifdef CONFIG_GUSA_RB
 #include <asm/bitops-grb.h>
+#elif defined(CONFIG_CPU_SH2A)
+#include <asm-generic/bitops/atomic.h>
+#include <asm/bitops-op32.h>
 #elif defined(CONFIG_CPU_SH4A)
 #include <asm/bitops-llsc.h>
 #else
-#include <asm/bitops-irq.h>
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
 #endif
 
-
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
 #define smp_mb__before_clear_bit()	barrier()
 #define smp_mb__after_clear_bit()	barrier()
 
-#include <asm-generic/bitops/non-atomic.h>
-
 #ifdef CONFIG_SUPERH32
 static inline unsigned long ffz(unsigned long word)
 {
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 121b2ecddfc3..4924ff6f5439 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -25,7 +25,7 @@ static void __init check_bugs(void)
 	case CPU_SH7619:
 		*p++ = '2';
 		break;
-	case CPU_SH7203 ... CPU_MXG:
+	case CPU_SH7201 ... CPU_MXG:
 		*p++ = '2';
 		*p++ = 'a';
 		break;
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index 9eb9036a1bdc..ccb1d93bb043 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -108,13 +108,11 @@ typedef struct user_fpu_struct elf_fpregset_t;
 #define elf_check_fdpic(x)		((x)->e_flags & EF_SH_FDPIC)
 #define elf_check_const_displacement(x)	((x)->e_flags & EF_SH_PIC)
 
-#ifdef CONFIG_SUPERH32
 /*
  * Enable dump using regset.
  * This covers all of general/DSP/FPU regs.
  */
 #define CORE_DUMP_USE_REGSET
-#endif
 
 #define USE_ELF_CORE_DUMP
 #define ELF_FDPIC_CORE_EFLAGS	EF_SH_FDPIC
@@ -204,7 +202,7 @@ do {									\
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
-				       int executable_stack);
+				       int uses_interp);
 
 extern unsigned int vdso_enabled;
 extern void __kernel_vsyscall;
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 3aed362c9463..8fea7d8c8258 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -1,8 +1,34 @@
 #ifndef __ASM_SH_FTRACE_H
 #define __ASM_SH_FTRACE_H
 
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
+
 #ifndef __ASSEMBLY__
 extern void mcount(void);
-#endif
+
+#define MCOUNT_ADDR		((long)(mcount))
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+#define CALLER_ADDR		((long)(ftrace_caller))
+#define STUB_ADDR		((long)(ftrace_stub))
+
+#define MCOUNT_INSN_OFFSET	((STUB_ADDR - CALLER_ADDR) >> 1)
+
+struct dyn_arch_ftrace {
+	/* No extra data needed on sh */
+};
+
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+	/* 'addr' is the memory table address. */
+	return addr;
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_FUNCTION_TRACER */
 
 #endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 65eaae34e753..61f6dae40534 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -260,6 +260,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 
 		return (void __iomem *)P2SEGADDR(offset);
 	}
+
+	/* P4 above the store queues are always mapped. */
+	if (unlikely(offset >= P3_ADDR_MAX))
+		return (void __iomem *)P4SEGADDR(offset);
 #endif
 
 	return __ioremap(offset, size, flags);
diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h
index 24e42078f36f..72704ed725e5 100644
--- a/arch/sh/include/asm/kgdb.h
+++ b/arch/sh/include/asm/kgdb.h
@@ -1,21 +1,7 @@
-/*
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Based on original code by Glenn Engel, Jim Kingdon,
- * David Grothe <dave@gcom.com>, Tigran Aivazian, <tigran@sco.com> and
- * Amit S. Kale <akale@veritas.com>
- * 
- * Super-H port based on sh-stub.c (Ben Lee and Steve Chamberlain) by
- * Henry Bell <henry.bell@st.com>
- * 
- * Header file for low-level support for remote debug using GDB. 
- *
- */
-
-#ifndef __KGDB_H
-#define __KGDB_H
+#ifndef __ASM_SH_KGDB_H
+#define __ASM_SH_KGDB_H
 
+#include <asm/cacheflush.h>
 #include <asm/ptrace.h>
 
 /* Same as pt_regs but has vbr in place of syscall_nr */
@@ -30,40 +16,26 @@ struct kgdb_regs {
         unsigned long vbr;
 };
 
-/* State info */
-extern char kgdb_in_gdb_mode;
-extern int kgdb_nofault;	/* Ignore bus errors (in gdb mem access) */
-extern char in_nmi;		/* Debounce flag to prevent NMI reentry*/
+enum regnames {
+	GDB_R0, GDB_R1, GDB_R2, GDB_R3, GDB_R4, GDB_R5, GDB_R6, GDB_R7,
+	GDB_R8, GDB_R9, GDB_R10, GDB_R11, GDB_R12, GDB_R13, GDB_R14, GDB_R15,
 
-/* SCI */
-extern int kgdb_portnum;
-extern int kgdb_baud;
-extern char kgdb_parity;
-extern char kgdb_bits;
+	GDB_PC, GDB_PR, GDB_SR, GDB_GBR, GDB_MACH, GDB_MACL, GDB_VBR,
+};
 
-/* Init and interface stuff */
-extern int kgdb_init(void);
-extern int (*kgdb_getchar)(void);
-extern void (*kgdb_putchar)(int);
+#define NUMREGBYTES    ((GDB_VBR + 1) * 4)
 
-/* Trap functions */
-typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
-typedef void (kgdb_bus_error_hook_t)(void);
-extern kgdb_debug_hook_t  *kgdb_debug_hook;
-extern kgdb_bus_error_hook_t *kgdb_bus_err_hook;
+static inline void arch_kgdb_breakpoint(void)
+{
+	__asm__ __volatile__ ("trapa #0x3c\n");
+}
 
-/* Console */
-struct console;
-void kgdb_console_write(struct console *co, const char *s, unsigned count);
-extern int kgdb_console_setup(struct console *, char *);
+/* State info */
+extern char in_nmi;		/* Debounce flag to prevent NMI reentry*/
 
-/* Prototypes for jmp fns */
-#define _JBLEN 9
-typedef        int jmp_buf[_JBLEN];
-extern void    longjmp(jmp_buf __jmpb, int __retval);
-extern int     setjmp(jmp_buf __jmpb);
+#define BUFMAX                 2048
 
-/* Forced breakpoint */
-#define breakpoint()	__asm__ __volatile__("trapa   #0x3c")
+#define CACHE_FLUSH_IS_SAFE	1
+#define BREAK_INSTR_SIZE	2
 
-#endif
+#endif /* __ASM_SH_KGDB_H */
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index f1bae02ef7b6..64b1c16a0f03 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -14,8 +14,6 @@
 #include <linux/time.h>
 #include <asm/machtypes.h>
 
-struct device;
-
 struct sh_machine_vector {
 	void (*mv_setup)(char **cmdline_p);
 	const char *mv_name;
@@ -45,9 +43,6 @@ struct sh_machine_vector {
 	int (*mv_irq_demux)(int irq);
 
 	void (*mv_init_irq)(void);
-	void (*mv_init_pci)(void);
-
-	void (*mv_heartbeat)(void);
 
 	void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
 	void (*mv_ioport_unmap)(void __iomem *);
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 04c0c9733ad6..5d9157bd474d 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -22,7 +22,7 @@
 #define MMU_CONTEXT_ASID_MASK		0x000000ff
 #define MMU_CONTEXT_VERSION_MASK	0xffffff00
 #define MMU_CONTEXT_FIRST_VERSION	0x00000100
-#define NO_CONTEXT			0
+#define NO_CONTEXT			0UL
 
 /* ASID is 8-bit value, so it can't be 0x100 */
 #define MMU_NO_ASID			0x100
@@ -130,7 +130,7 @@ static inline void switch_mm(struct mm_struct *prev,
 #define destroy_context(mm)		do { } while (0)
 #define set_asid(asid)			do { } while (0)
 #define get_asid()			(0)
-#define cpu_asid(cpu, mm)		({ (void)cpu; 0; })
+#define cpu_asid(cpu, mm)		({ (void)cpu; NO_CONTEXT; })
 #define switch_and_save_asid(asid)	(0)
 #define set_TTB(pgd)			do { } while (0)
 #define get_TTB()			(0)
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
new file mode 100644
index 000000000000..ee839ee58ac8
--- /dev/null
+++ b/arch/sh/include/asm/mutex-llsc.h
@@ -0,0 +1,112 @@
+/*
+ * arch/sh/include/asm/mutex-llsc.h
+ *
+ * SH-4A optimized mutex locking primitives
+ *
+ * Please look into asm-generic/mutex-xchg.h for a formal definition.
+ */
+#ifndef __ASM_SH_MUTEX_LLSC_H
+#define __ASM_SH_MUTEX_LLSC_H
+
+/*
+ * Attempting to lock a mutex on SH4A is done like in ARMv6+ architecure.
+ * with a bastardized atomic decrement (it is not a reliable atomic decrement
+ * but it satisfies the defined semantics for our purpose, while being
+ * smaller and faster than a real atomic decrement or atomic swap.
+ * The idea is to attempt  decrementing the lock value only once. If once
+ * decremented it isn't zero, or if its store-back fails due to a dispute
+ * on the exclusive store, we simply bail out immediately through the slow
+ * path where the lock will be reattempted until it succeeds.
+ */
+static inline void
+__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res;
+
+	__asm__ __volatile__ (
+		"movli.l	@%2, %0	\n"
+		"add		#-1, %0	\n"
+		"movco.l	%0, @%2	\n"
+		"movt		%1	\n"
+		: "=&z" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "t");
+
+	__res |= !__ex_flag;
+	if (unlikely(__res != 0))
+		fail_fn(count);
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res;
+
+	__asm__ __volatile__ (
+		"movli.l	@%2, %0	\n"
+		"add		#-1, %0	\n"
+		"movco.l	%0, @%2	\n"
+		"movt		%1	\n"
+		: "=&z" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "t");
+
+	__res |= !__ex_flag;
+	if (unlikely(__res != 0))
+		__res = fail_fn(count);
+
+	return __res;
+}
+
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res;
+
+	__asm__ __volatile__ (
+		"movli.l	@%2, %0	\n\t"
+		"add		#1, %0	\n\t"
+		"movco.l	%0, @%2 \n\t"
+		"movt		%1	\n\t"
+		: "=&z" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "t");
+
+	__res |= !__ex_flag;
+	if (unlikely(__res <= 0))
+		fail_fn(count);
+}
+
+/*
+ * If the unlock was done on a contended lock, or if the unlock simply fails
+ * then the mutex remains locked.
+ */
+#define __mutex_slowpath_needs_to_unlock()	1
+
+/*
+ * For __mutex_fastpath_trylock we do an atomic decrement and check the
+ * result and put it in the __res variable.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	int __res, __orig;
+
+	__asm__ __volatile__ (
+		"1: movli.l	@%2, %0		\n\t"
+		"dt		%0		\n\t"
+		"movco.l	%0,@%2		\n\t"
+		"bf		1b		\n\t"
+		"cmp/eq		#0,%0		\n\t"
+		"bt		2f		\n\t"
+		"mov		#0, %1		\n\t"
+		"bf		3f		\n\t"
+		"2: mov		#1, %1		\n\t"
+		"3:				"
+		: "=&z" (__orig), "=&r" (__res)
+		: "r" (&count->counter)
+		: "t");
+
+	return __res;
+}
+#endif /* __ASM_SH_MUTEX_LLSC_H */
diff --git a/arch/sh/include/asm/mutex.h b/arch/sh/include/asm/mutex.h
index 458c1f7fbc18..d8e37716a4a0 100644
--- a/arch/sh/include/asm/mutex.h
+++ b/arch/sh/include/asm/mutex.h
@@ -5,5 +5,8 @@
  * implementation in place, or pick the atomic_xchg() based generic
  * implementation. (see asm-generic/mutex-xchg.h for details)
  */
-
+#if defined(CONFIG_CPU_SH4A)
+#include <asm/mutex-llsc.h>
+#else
 #include <asm-generic/mutex-dec.h>
+#endif
diff --git a/arch/sh/include/asm/pm.h b/arch/sh/include/asm/pm.h
deleted file mode 100644
index 56fdbd6b1c94..000000000000
--- a/arch/sh/include/asm/pm.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright 2006 (c) Andriy Skulysh <askulysh@gmail.com>
- *
- */
-#ifndef __ASM_SH_PM_H
-#define __ASM_SH_PM_H
-
-extern u8 wakeup_start;
-extern u8 wakeup_end;
-
-void pm_enter(void);
-
-#endif
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 693364a20ad7..1ef4b24d7619 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -18,7 +18,7 @@ enum cpu_type {
 	CPU_SH7619,
 
 	/* SH-2A types */
-	CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_MXG,
+	CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_MXG,
 
 	/* SH-3 types */
 	CPU_SH7705, CPU_SH7706, CPU_SH7707,
@@ -82,6 +82,9 @@ extern struct sh_cpuinfo cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
 #define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
 
+#define cpu_sleep()	__asm__ __volatile__ ("sleep" : : : "memory")
+#define cpu_relax()	barrier()
+
 /* Forward decl */
 struct seq_operations;
 
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index a46a0207e977..d79063c5eb9c 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -175,6 +175,15 @@ static __inline__ void enable_fpu(void)
 
 void show_trace(struct task_struct *tsk, unsigned long *sp,
 		struct pt_regs *regs);
+
+#ifdef CONFIG_DUMP_CODE
+void show_code(struct pt_regs *regs);
+#else
+static inline void show_code(struct pt_regs *regs)
+{
+}
+#endif
+
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->pc)
@@ -182,9 +191,6 @@ extern unsigned long get_wchan(struct task_struct *p);
 
 #define user_stack_pointer(regs)	((regs)->regs[15])
 
-#define cpu_sleep()	__asm__ __volatile__ ("sleep" : : : "memory")
-#define cpu_relax()	barrier()
-
 #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \
     defined(CONFIG_CPU_SH4)
 #define PREFETCH_STRIDE		L1_CACHE_BYTES
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index b0b4824dfc4c..803177fcf086 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -226,9 +226,7 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
 #define KSTK_ESP(tsk)  ((tsk)->thread.sp)
 
-#define user_stack_pointer(regs)	((regs)->sp)
-
-#define cpu_relax()	barrier()
+#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 3ad18e91bca6..12912ab80c15 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -86,6 +86,7 @@ struct pt_dspregs {
 	unsigned long	re;
 	unsigned long	mod;
 };
+#endif
 
 #define PTRACE_GETREGS		12	/* General registers */
 #define PTRACE_SETREGS		13
@@ -100,7 +101,6 @@ struct pt_dspregs {
 
 #define	PTRACE_GETDSPREGS	55	/* DSP registers */
 #define	PTRACE_SETDSPREGS	56
-#endif
 
 #ifdef __KERNEL__
 #include <asm/addrspace.h>
diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h
index 0ca261956e3d..d9c96d7cf6c7 100644
--- a/arch/sh/include/asm/sh_bios.h
+++ b/arch/sh/include/asm/sh_bios.h
@@ -10,7 +10,6 @@
 
 extern void sh_bios_console_write(const char *buf, unsigned int len);
 extern void sh_bios_char_out(char ch);
-extern int sh_bios_in_gdb_mode(void);
 extern void sh_bios_gdb_detach(void);
 
 extern void sh_bios_get_node_addr(unsigned char *node_addr);
diff --git a/arch/sh/include/asm/string_64.h b/arch/sh/include/asm/string_64.h
index aa1fef229c78..742007172624 100644
--- a/arch/sh/include/asm/string_64.h
+++ b/arch/sh/include/asm/string_64.h
@@ -1,17 +1,20 @@
 #ifndef __ASM_SH_STRING_64_H
 #define __ASM_SH_STRING_64_H
 
-/*
- * include/asm-sh/string_64.h
- *
- * Copyright (C) 2000, 2001  Paolo Alberelli
- *
- * 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.
- */
+#ifdef __KERNEL__
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
 
 #define __HAVE_ARCH_MEMCPY
 extern void *memcpy(void *dest, const void *src, size_t count);
 
+#define __HAVE_ARCH_STRLEN
+extern size_t strlen(const char *);
+
+#define __HAVE_ARCH_STRCPY
+extern char *strcpy(char *__dest, const char *__src);
+
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_SH_STRING_64_H */
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 54773f26cd44..05a868a71ef5 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -5,7 +5,7 @@
 #include <linux/sched.h>
 #include <asm/ptrace.h>
 
-/* The system call number is given by the user in %g1 */
+/* The system call number is given by the user in R3 */
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
 {
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index bcaaa8ca4d70..e1143b9784d6 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -1,6 +1,80 @@
 #ifndef __ASM_SH_SYSCALL_64_H
 #define __ASM_SH_SYSCALL_64_H
 
-#include <asm-generic/syscall.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/* The system call number is given by the user in R9 */
+static inline long syscall_get_nr(struct task_struct *task,
+				  struct pt_regs *regs)
+{
+	return (regs->syscall_nr >= 0) ? regs->regs[9] : -1L;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+				    struct pt_regs *regs)
+{
+	/*
+	 * XXX: This needs some thought. On SH we don't
+	 * save away the original R9 value anywhere.
+	 */
+}
+
+static inline bool syscall_has_error(struct pt_regs *regs)
+{
+	return (regs->sr & 0x1) ? true : false;
+}
+static inline void syscall_set_error(struct pt_regs *regs)
+{
+	regs->sr |= 0x1;
+}
+static inline void syscall_clear_error(struct pt_regs *regs)
+{
+	regs->sr &= ~0x1;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
+{
+	return syscall_has_error(regs) ? regs->regs[9] : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+					    struct pt_regs *regs)
+{
+	return regs->regs[9];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+					    struct pt_regs *regs,
+					    int error, long val)
+{
+	if (error) {
+		syscall_set_error(regs);
+		regs->regs[9] = -error;
+	} else {
+		syscall_clear_error(regs);
+		regs->regs[9] = val;
+	}
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(args, &regs->regs[2 + i], n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 const unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(&regs->regs[2 + i], args, n * sizeof(args[0]));
+}
 
 #endif /* __ASM_SH_SYSCALL_64_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 6160fe445161..c9ec6af8e745 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -175,6 +175,8 @@ asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
 BUILD_TRAP_HANDLER(address_error);
 BUILD_TRAP_HANDLER(debug);
 BUILD_TRAP_HANDLER(bug);
+BUILD_TRAP_HANDLER(breakpoint);
+BUILD_TRAP_HANDLER(singlestep);
 BUILD_TRAP_HANDLER(fpu_error);
 BUILD_TRAP_HANDLER(fpu_state_restore);
 
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index 279d9cc4a007..066f0fba590e 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -32,6 +32,7 @@
 #define parent_node(node)	((void)(node),0)
 
 #define node_to_cpumask(node)	((void)node, cpu_online_map)
+#define cpumask_of_node(node)	((void)node, cpu_online_mask)
 #define node_to_first_cpu(node)	((void)(node),0)
 
 #define pcibus_to_node(bus)	((void)(bus), -1)
diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h
new file mode 100644
index 000000000000..d8f89770275b
--- /dev/null
+++ b/arch/sh/include/asm/unaligned-sh4a.h
@@ -0,0 +1,258 @@
+#ifndef __ASM_SH_UNALIGNED_SH4A_H
+#define __ASM_SH_UNALIGNED_SH4A_H
+
+/*
+ * SH-4A has support for unaligned 32-bit loads, and 32-bit loads only.
+ * Support for 16 and 64-bit accesses are done through shifting and
+ * masking relative to the endianness. Unaligned stores are not supported
+ * by the instruction encoding, so these continue to use the packed
+ * struct.
+ *
+ * The same note as with the movli.l/movco.l pair applies here, as long
+ * as the load is gauranteed to be inlined, nothing else will hook in to
+ * r0 and we get the return value for free.
+ *
+ * NOTE: Due to the fact we require r0 encoding, care should be taken to
+ * avoid mixing these heavily with other r0 consumers, such as the atomic
+ * ops. Failure to adhere to this can result in the compiler running out
+ * of spill registers and blowing up when building at low optimization
+ * levels. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34777.
+ */
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
+{
+	unsigned long unaligned;
+
+	__asm__ __volatile__ (
+		"movua.l	@%1, %0\n\t"
+		 : "=z" (unaligned)
+		 : "r" (p)
+	);
+
+	return unaligned;
+}
+
+struct __una_u16 { u16 x __attribute__((packed)); };
+struct __una_u32 { u32 x __attribute__((packed)); };
+struct __una_u64 { u64 x __attribute__((packed)); };
+
+static inline u16 __get_unaligned_cpu16(const u8 *p)
+{
+#ifdef __LITTLE_ENDIAN
+	return __get_unaligned_cpu32(p) & 0xffff;
+#else
+	return __get_unaligned_cpu32(p) >> 16;
+#endif
+}
+
+/*
+ * Even though movua.l supports auto-increment on the read side, it can
+ * only store to r0 due to instruction encoding constraints, so just let
+ * the compiler sort it out on its own.
+ */
+static inline u64 __get_unaligned_cpu64(const u8 *p)
+{
+#ifdef __LITTLE_ENDIAN
+	return (u64)__get_unaligned_cpu32(p + 4) << 32 |
+		    __get_unaligned_cpu32(p);
+#else
+	return (u64)__get_unaligned_cpu32(p) << 32 |
+		    __get_unaligned_cpu32(p + 4);
+#endif
+}
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+	return le16_to_cpu(__get_unaligned_cpu16(p));
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+	return le32_to_cpu(__get_unaligned_cpu32(p));
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+	return le64_to_cpu(__get_unaligned_cpu64(p));
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+	return be16_to_cpu(__get_unaligned_cpu16(p));
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+	return be32_to_cpu(__get_unaligned_cpu32(p));
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+	return be64_to_cpu(__get_unaligned_cpu64(p));
+}
+
+static inline void __put_le16_noalign(u8 *p, u16 val)
+{
+	*p++ = val;
+	*p++ = val >> 8;
+}
+
+static inline void __put_le32_noalign(u8 *p, u32 val)
+{
+	__put_le16_noalign(p, val);
+	__put_le16_noalign(p + 2, val >> 16);
+}
+
+static inline void __put_le64_noalign(u8 *p, u64 val)
+{
+	__put_le32_noalign(p, val);
+	__put_le32_noalign(p + 4, val >> 32);
+}
+
+static inline void __put_be16_noalign(u8 *p, u16 val)
+{
+	*p++ = val >> 8;
+	*p++ = val;
+}
+
+static inline void __put_be32_noalign(u8 *p, u32 val)
+{
+	__put_be16_noalign(p, val >> 16);
+	__put_be16_noalign(p + 2, val);
+}
+
+static inline void __put_be64_noalign(u8 *p, u64 val)
+{
+	__put_be32_noalign(p, val >> 32);
+	__put_be32_noalign(p + 4, val);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+#ifdef __LITTLE_ENDIAN
+	((struct __una_u16 *)p)->x = val;
+#else
+	__put_le16_noalign(p, val);
+#endif
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+#ifdef __LITTLE_ENDIAN
+	((struct __una_u32 *)p)->x = val;
+#else
+	__put_le32_noalign(p, val);
+#endif
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+#ifdef __LITTLE_ENDIAN
+	((struct __una_u64 *)p)->x = val;
+#else
+	__put_le64_noalign(p, val);
+#endif
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+#ifdef __BIG_ENDIAN
+	((struct __una_u16 *)p)->x = val;
+#else
+	__put_be16_noalign(p, val);
+#endif
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+#ifdef __BIG_ENDIAN
+	((struct __una_u32 *)p)->x = val;
+#else
+	__put_be32_noalign(p, val);
+#endif
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+#ifdef __BIG_ENDIAN
+	((struct __una_u64 *)p)->x = val;
+#else
+	__put_be64_noalign(p, val);
+#endif
+}
+
+/*
+ * Cause a link-time error if we try an unaligned access other than
+ * 1,2,4 or 8 bytes long
+ */
+extern void __bad_unaligned_access_size(void);
+
+#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({			\
+	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
+	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),	\
+	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),	\
+	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),	\
+	__bad_unaligned_access_size()))));					\
+	}))
+
+#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({			\
+	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
+	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),	\
+	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),	\
+	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),	\
+	__bad_unaligned_access_size()))));					\
+	}))
+
+#define __put_unaligned_le(val, ptr) ({					\
+	void *__gu_p = (ptr);						\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		*(u8 *)__gu_p = (__force u8)(val);			\
+		break;							\
+	case 2:								\
+		put_unaligned_le16((__force u16)(val), __gu_p);		\
+		break;							\
+	case 4:								\
+		put_unaligned_le32((__force u32)(val), __gu_p);		\
+		break;							\
+	case 8:								\
+		put_unaligned_le64((__force u64)(val), __gu_p);		\
+		break;							\
+	default:							\
+		__bad_unaligned_access_size();				\
+		break;							\
+	}								\
+	(void)0; })
+
+#define __put_unaligned_be(val, ptr) ({					\
+	void *__gu_p = (ptr);						\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		*(u8 *)__gu_p = (__force u8)(val);			\
+		break;							\
+	case 2:								\
+		put_unaligned_be16((__force u16)(val), __gu_p);		\
+		break;							\
+	case 4:								\
+		put_unaligned_be32((__force u32)(val), __gu_p);		\
+		break;							\
+	case 8:								\
+		put_unaligned_be64((__force u64)(val), __gu_p);		\
+		break;							\
+	default:							\
+		__bad_unaligned_access_size();				\
+		break;							\
+	}								\
+	(void)0; })
+
+#ifdef __LITTLE_ENDIAN
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+#else
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+#endif
+
+#endif /* __ASM_SH_UNALIGNED_SH4A_H */
diff --git a/arch/sh/include/asm/unaligned.h b/arch/sh/include/asm/unaligned.h
index c1641a01d50f..8c0ad5e4487a 100644
--- a/arch/sh/include/asm/unaligned.h
+++ b/arch/sh/include/asm/unaligned.h
@@ -1,7 +1,11 @@
 #ifndef _ASM_SH_UNALIGNED_H
 #define _ASM_SH_UNALIGNED_H
 
-/* SH can't handle unaligned accesses. */
+#ifdef CONFIG_CPU_SH4A
+/* SH-4A can handle unaligned loads in a relatively neutered fashion. */
+#include <asm/unaligned-sh4a.h>
+#else
+/* Otherwise, SH can't handle unaligned accesses. */
 #ifdef __LITTLE_ENDIAN__
 # include <linux/unaligned/le_struct.h>
 # include <linux/unaligned/be_byteshift.h>
@@ -15,5 +19,6 @@
 # define get_unaligned	__get_unaligned_be
 # define put_unaligned	__put_unaligned_be
 #endif
+#endif
 
 #endif /* _ASM_SH_UNALIGNED_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/gpio.h b/arch/sh/include/cpu-sh3/cpu/gpio.h
index 4e53eb314b8f..9a22b882f3dc 100644
--- a/arch/sh/include/cpu-sh3/cpu/gpio.h
+++ b/arch/sh/include/cpu-sh3/cpu/gpio.h
@@ -62,6 +62,20 @@
 #define PORT_PSELC	0xA4050128UL
 #define PORT_PSELD	0xA405012AUL
 
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+
+/* Control registers */
+#define PORT_PACR       0xa4000100UL
+#define PORT_PBCR       0xa4000102UL
+#define PORT_PCCR       0xa4000104UL
+#define PORT_PFCR       0xa400010aUL
+
+/* Data registers */
+#define PORT_PADR       0xa4000120UL
+#define PORT_PBDR       0xa4000122UL
+#define PORT_PCDR       0xa4000124UL
+#define PORT_PFDR       0xa400012aUL
+
 #endif
 
 #endif
diff --git a/arch/sh/include/mach-common/mach/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h
index 5bdc9d9be3de..efc43b323466 100644
--- a/arch/sh/include/mach-common/mach/edosk7705.h
+++ b/arch/sh/include/mach-common/mach/edosk7705.h
@@ -1,30 +1,7 @@
-/*
- * include/asm-sh/edosk7705.h
- *
- * Modified version of io_se.h for the EDOSK7705 specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Hitachi EDOSK7705 development board
- */
-
-#ifndef __ASM_SH_EDOSK7705_IO_H
-#define __ASM_SH_EDOSK7705_IO_H
+#ifndef __ASM_SH_EDOSK7705_H
+#define __ASM_SH_EDOSK7705_H
 
+#define __IO_PREFIX sh_edosk7705
 #include <asm/io_generic.h>
 
-extern unsigned char sh_edosk7705_inb(unsigned long port);
-extern unsigned int sh_edosk7705_inl(unsigned long port);
-
-extern void sh_edosk7705_outb(unsigned char value, unsigned long port);
-extern void sh_edosk7705_outl(unsigned int value, unsigned long port);
-
-extern void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count);
-extern void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count);
-extern void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern unsigned long sh_edosk7705_isa_port2addr(unsigned long offset);
-
-#endif /* __ASM_SH_EDOSK7705_IO_H */
+#endif /* __ASM_SH_EDOSK7705_H */
diff --git a/arch/sh/include/mach-se/mach/mrshpc.h b/arch/sh/include/mach-se/mach/mrshpc.h
new file mode 100644
index 000000000000..56287ee8563a
--- /dev/null
+++ b/arch/sh/include/mach-se/mach/mrshpc.h
@@ -0,0 +1,52 @@
+#ifndef __MACH_SE_MRSHPC_H
+#define __MACH_SE_MRSHPC_H
+
+#include <linux/io.h>
+
+static inline void __init mrshpc_setup_windows(void)
+{
+	if ((__raw_readw(MRSHPC_CSR) & 0x000c) != 0)
+		return;	/* Not detected */
+
+	if ((__raw_readw(MRSHPC_CSR) & 0x0080) == 0) {
+		__raw_writew(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
+	} else {
+		__raw_writew(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
+	}
+
+	/*
+	 *  PC-Card window open
+	 *  flag == COMMON/ATTRIBUTE/IO
+	 */
+	/* common window open */
+	__raw_writew(0x8a84, MRSHPC_MW0CR1);
+	if((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
+		/* common mode & bus width 16bit SWAP = 1*/
+		__raw_writew(0x0b00, MRSHPC_MW0CR2);
+	else
+		/* common mode & bus width 16bit SWAP = 0*/
+		__raw_writew(0x0300, MRSHPC_MW0CR2);
+
+	/* attribute window open */
+	__raw_writew(0x8a85, MRSHPC_MW1CR1);
+	if ((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
+		/* attribute mode & bus width 16bit SWAP = 1*/
+		__raw_writew(0x0a00, MRSHPC_MW1CR2);
+	else
+		/* attribute mode & bus width 16bit SWAP = 0*/
+		__raw_writew(0x0200, MRSHPC_MW1CR2);
+
+	/* I/O window open */
+	__raw_writew(0x8a86, MRSHPC_IOWCR1);
+	__raw_writew(0x0008, MRSHPC_CDCR);	 /* I/O card mode */
+	if ((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
+		__raw_writew(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
+	else
+		__raw_writew(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
+
+	__raw_writew(0x2000, MRSHPC_ICR);
+	__raw_writeb(0x00, PA_MRSHPC_MW2 + 0x206);
+	__raw_writeb(0x42, PA_MRSHPC_MW2 + 0x200);
+}
+
+#endif /* __MACH_SE_MRSHPC_H */
diff --git a/arch/sh/include/mach-se/mach/se.h b/arch/sh/include/mach-se/mach/se.h
index eb23000e1bbe..14be91c5a2f0 100644
--- a/arch/sh/include/mach-se/mach/se.h
+++ b/arch/sh/include/mach-se/mach/se.h
@@ -68,6 +68,24 @@
 #define BCR_ILCRF	(PA_BCR + 10)
 #define BCR_ILCRG	(PA_BCR + 12)
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+#define INTC_IRR0       0xa4000004UL
+#define INTC_IRR1       0xa4000006UL
+#define INTC_IRR2       0xa4000008UL
+
+#define INTC_ICR0       0xfffffee0UL
+#define INTC_ICR1       0xa4000010UL
+#define INTC_ICR2       0xa4000012UL
+#define INTC_INTER      0xa4000014UL
+
+#define INTC_IPRC       0xa4000016UL
+#define INTC_IPRD       0xa4000018UL
+#define INTC_IPRE       0xa400001aUL
+
+#define IRQ0_IRQ        32
+#define IRQ1_IRQ        33
+#endif
+
 #if defined(CONFIG_CPU_SUBTYPE_SH7705)
 #define IRQ_STNIC	12
 #define IRQ_CFCARD	14
diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h
index 98458460e632..749914b400fb 100644
--- a/arch/sh/include/mach-se/mach/se7343.h
+++ b/arch/sh/include/mach-se/mach/se7343.h
@@ -118,9 +118,6 @@
 #define FPGA_IN		0xb1400000
 #define FPGA_OUT	0xb1400002
 
-#define __IO_PREFIX	sh7343se
-#include <asm/io_generic.h>
-
 #define IRQ0_IRQ        32
 #define IRQ1_IRQ        33
 #define IRQ4_IRQ        36
@@ -132,8 +129,10 @@
 #define SE7343_FPGA_IRQ_MRSHPC3	3
 #define SE7343_FPGA_IRQ_SMC	6	/* EXT_IRQ2 */
 #define SE7343_FPGA_IRQ_USB	8
+#define SE7343_FPGA_IRQ_UARTA	10
+#define SE7343_FPGA_IRQ_UARTB	11
 
-#define SE7343_FPGA_IRQ_NR	11
+#define SE7343_FPGA_IRQ_NR	12
 #define SE7343_FPGA_IRQ_BASE	120
 
 #define MRSHPC_IRQ3    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
@@ -142,6 +141,8 @@
 #define MRSHPC_IRQ0    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
 #define SMC_IRQ		(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
 #define USB_IRQ		(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
+#define UARTA_IRQ	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
+#define UARTB_IRQ	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
 
 /* arch/sh/boards/se/7343/irq.c */
 void init_7343se_IRQ(void);
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 48edfb145fb4..2e1b86e16ab5 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -4,25 +4,31 @@
 
 extra-y	:= head_32.o init_task.o vmlinux.lds
 
-obj-y	:= debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \
-	   ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \
-	   syscalls_32.o time_32.o topology.o traps.o traps_32.o
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
+obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o			\
+	   machvec.o process_32.o ptrace_32.o setup.o signal_32.o	\
+	   sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o	\
+	   traps.o traps_32.o
 
 obj-y				+= cpu/ timers/
 obj-$(CONFIG_VSYSCALL)		+= vsyscall/
 obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
-obj-$(CONFIG_SH_KGDB)		+= kgdb_stub.o kgdb_jmp.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= sh_ksyms_32.o module.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
+obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index c97660b2b48d..fe425d7f6871 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -1,21 +1,18 @@
 extra-y	:= head_64.o init_task.o vmlinux.lds
 
-obj-y	:= debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \
+obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
 	   ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
 	   syscalls_64.o time_64.o topology.o traps.o traps_64.o
 
 obj-y				+= cpu/ timers/
 obj-$(CONFIG_VSYSCALL)		+= vsyscall/
 obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
-obj-$(CONFIG_SH_KGDB)		+= kgdb_stub.o kgdb_jmp.o
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= sh_ksyms_64.o module.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
deleted file mode 100644
index bea40339919b..000000000000
--- a/arch/sh/kernel/cf-enabler.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* $Id: cf-enabler.c,v 1.4 2004/02/22 22:44:36 kkojima Exp $
- *
- *  linux/drivers/block/cf-enabler.c
- *
- *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2000  Toshiharu Nozawa
- *  Copyright (C) 2001  A&D Co., Ltd.
- *
- *  Enable the CF configuration.
- */
-
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-/*
- * You can connect Compact Flash directly to the bus of SuperH.
- * This is the enabler for that.
- *
- * SIM: How generic is this really? It looks pretty board, or at
- * least SH sub-type, specific to me.
- * I know it doesn't work on the Overdrive!
- */
-
-/*
- * 0xB8000000 : Attribute
- * 0xB8001000 : Common Memory
- * 0xBA000000 : I/O
- */
-#if defined(CONFIG_CPU_SH4)
-/* SH4 can't access PCMCIA interface through P2 area.
- * we must remap it with appropriate attribute bit of the page set.
- * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
-
-#if defined(CONFIG_CF_AREA6)
-#define slot_no 0
-#else
-#define slot_no 1
-#endif
-
-/* use this pointer to access to directly connected compact flash io area*/
-void *cf_io_base;
-
-static int __init allocate_cf_area(void)
-{
-	pgprot_t prot;
-	unsigned long paddrbase, psize;
-
-	/* open I/O area window */
-	paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
-	psize = PAGE_SIZE;
-	prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
-	cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
-	if (!cf_io_base) {
-		printk("allocate_cf_area : can't open CF I/O window!\n");
-		return -ENOMEM;
-	}
-/*	printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
-		paddrbase, psize, prot.pgprot, cf_io_base);*/
-
-	/* XXX : do we need attribute and common-memory area also? */
-
-	return 0;
-}
-#endif
-
-static int __init cf_init_default(void)
-{
-/* You must have enabled the card, and set the level interrupt
- * before reaching this point. Possibly in boot ROM or boot loader.
- */
-#if defined(CONFIG_CPU_SH4)
-	allocate_cf_area();
-#endif
-
-	return 0;
-}
-
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
-#include <mach-se/mach/se.h>
-#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
-#include <mach-se/mach/se7722.h>
-#elif defined(CONFIG_SH_7721_SOLUTION_ENGINE)
-#include <mach-se/mach/se7721.h>
-#endif
-
-/*
- * SolutionEngine Seriese
- *
- * about MS770xSE
- * 0xB8400000 : Common Memory
- * 0xB8500000 : Attribute
- * 0xB8600000 : I/O
- *
- * about MS7722SE
- * 0xB0400000 : Common Memory
- * 0xB0500000 : Attribute
- * 0xB0600000 : I/O
- */
-
-#if defined(CONFIG_SH_SOLUTION_ENGINE) || \
-    defined(CONFIG_SH_7722_SOLUTION_ENGINE) || \
-    defined(CONFIG_SH_7721_SOLUTION_ENGINE)
-static int __init cf_init_se(void)
-{
-	if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
-		return 0;	/* Not detected */
-
-	if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
-		ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
-	} else {
-		ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
-	}
-
-	/*
-	 *  PC-Card window open
-	 *  flag == COMMON/ATTRIBUTE/IO
-	 */
-	/* common window open */
-	ctrl_outw(0x8a84, MRSHPC_MW0CR1);
-	if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
-		/* common mode & bus width 16bit SWAP = 1*/
-		ctrl_outw(0x0b00, MRSHPC_MW0CR2);
-	else
-		/* common mode & bus width 16bit SWAP = 0*/
-		ctrl_outw(0x0300, MRSHPC_MW0CR2);
-
-	/* attribute window open */
-	ctrl_outw(0x8a85, MRSHPC_MW1CR1);
-	if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
-		/* attribute mode & bus width 16bit SWAP = 1*/
-		ctrl_outw(0x0a00, MRSHPC_MW1CR2);
-	else
-		/* attribute mode & bus width 16bit SWAP = 0*/
-		ctrl_outw(0x0200, MRSHPC_MW1CR2);
-
-	/* I/O window open */
-	ctrl_outw(0x8a86, MRSHPC_IOWCR1);
-	ctrl_outw(0x0008, MRSHPC_CDCR);	 /* I/O card mode */
-	if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
-		ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
-	else
-		ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
-
-	ctrl_outw(0x2000, MRSHPC_ICR);
-	ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
-	ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
-	return 0;
-}
-#else
-static int __init cf_init_se(void)
-{
-	return -1;
-}
-#endif
-
-static int __init cf_init(void)
-{
-	if (mach_is_se() || mach_is_7722se() || mach_is_7721se())
-		return cf_init_se();
-
-	return cf_init_default();
-}
-
-__initcall (cf_init);
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index b7e46d5bba43..7b17137536d6 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -117,6 +117,11 @@ int clk_enable(struct clk *clk)
 	unsigned long flags;
 	int ret;
 
+	if (!clk)
+		return -EINVAL;
+
+	clk_enable(clk->parent);
+
 	spin_lock_irqsave(&clock_lock, flags);
 	ret = __clk_enable(clk);
 	spin_unlock_irqrestore(&clock_lock, flags);
@@ -147,9 +152,14 @@ void clk_disable(struct clk *clk)
 {
 	unsigned long flags;
 
+	if (!clk)
+		return;
+
 	spin_lock_irqsave(&clock_lock, flags);
 	__clk_disable(clk);
 	spin_unlock_irqrestore(&clock_lock, flags);
+
+	clk_disable(clk->parent);
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 75fb03d35670..d29e69c156f0 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -261,9 +261,11 @@ asmlinkage void __init sh_cpu_init(void)
 	cache_init();
 
 	if (raw_smp_processor_id() == 0) {
+#ifdef CONFIG_MMU
 		shm_align_mask = max_t(unsigned long,
 				       current_cpu_data.dcache.way_size - 1,
 				       PAGE_SIZE - 1);
+#endif
 
 		/* Boot CPU sets the cache shape */
 		detect_cache_shape();
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 428450cc0809..45f85c77ef75 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -8,9 +8,10 @@ common-y	+= ex.o entry.o
 
 obj-$(CONFIG_SH_FPU)	+= fpu.o
 
-obj-$(CONFIG_CPU_SUBTYPE_SH7206)	+= setup-sh7206.o clock-sh7206.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7201)	+= setup-sh7201.o clock-sh7201.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7203)	+= setup-sh7203.o clock-sh7203.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7263)	+= setup-sh7203.o clock-sh7203.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7206)	+= setup-sh7206.o clock-sh7206.o
 obj-$(CONFIG_CPU_SUBTYPE_MXG)		+= setup-mxg.o clock-sh7206.o
 
 # Pinmux setup
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
new file mode 100644
index 000000000000..020a96fe961a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -0,0 +1,85 @@
+/*
+ * arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+ *
+ * SH7201 support for the clock framework
+ *
+ *  Copyright (C) 2008 Peter Griffin  <pgriffin@mpc-data.co.uk>
+ *
+ * Based on clock-sh4.c
+ *  Copyright (C) 2005  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/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+const static int pll1rate[]={1,2,3,4,6,8};
+const static int pfc_divisors[]={1,2,3,4,6,8,12};
+#define ifc_divisors pfc_divisors
+
+#if (CONFIG_SH_CLK_MD == 0)
+#define PLL2 (4)
+#elif (CONFIG_SH_CLK_MD == 2)
+#define PLL2 (2)
+#elif (CONFIG_SH_CLK_MD == 3)
+#define PLL2 (1)
+#else
+#error "Illegal Clock Mode!"
+#endif
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate = 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+}
+
+static struct clk_ops sh7201_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7201_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7201_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007);
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7201_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7201_clk_ops[] = {
+	&sh7201_master_clk_ops,
+	&sh7201_module_clk_ops,
+	&sh7201_bus_clk_ops,
+	&sh7201_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7201_clk_ops))
+		*ops = sh7201_clk_ops[idx];
+}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 6e79132f6f30..e098e2f6aa08 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -18,16 +18,17 @@ int __init detect_cpu_and_cache_system(void)
 	/* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
 	boot_cpu_data.flags			|= CPU_HAS_OP32;
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7203)
+#if defined(CONFIG_CPU_SUBTYPE_SH7201)
+	boot_cpu_data.type			= CPU_SH7201;
+	boot_cpu_data.flags			|= CPU_HAS_FPU;
+#elif defined(CONFIG_CPU_SUBTYPE_SH7203)
 	boot_cpu_data.type			= CPU_SH7203;
-	/* SH7203 has an FPU.. */
 	boot_cpu_data.flags			|= CPU_HAS_FPU;
 #elif defined(CONFIG_CPU_SUBTYPE_SH7263)
 	boot_cpu_data.type			= CPU_SH7263;
 	boot_cpu_data.flags			|= CPU_HAS_FPU;
 #elif defined(CONFIG_CPU_SUBTYPE_SH7206)
 	boot_cpu_data.type			= CPU_SH7206;
-	/* While SH7206 has a DSP.. */
 	boot_cpu_data.flags			|= CPU_HAS_DSP;
 #elif defined(CONFIG_CPU_SUBTYPE_MXG)
 	boot_cpu_data.type			= CPU_MXG;
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
new file mode 100644
index 000000000000..0631e421c022
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -0,0 +1,331 @@
+/*
+ *  SH7201 setup
+ *
+ *  Copyright (C) 2008  Peter Griffin pgriffin@mpc-data.co.uk
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+	PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
+	ADC_ADI,
+	MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
+	MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
+	MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
+	MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
+	MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
+	MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
+	MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
+	RTC_ARM, RTC_PRD, RTC_CUP,
+	WDT,
+	IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
+	IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
+	IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
+
+	DMAC0_DMINT0, DMAC1_DMINT1,
+	DMAC2_DMINT2, DMAC3_DMINT3,
+
+	SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
+	SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
+	SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
+	SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
+	SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI,
+	SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI,
+	SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI,
+	SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI,
+
+	DMAC0_DMINTA, DMAC4_DMINT4, DMAC5_DMINT5, DMAC6_DMINT6,
+	DMAC7_DMINT7,
+
+	RCAN0_ERS, RCAN0_OVR,
+	RCAN0_SLE,
+	RCAN0_RM0, RCAN0_RM1,
+
+	RCAN1_ERS, RCAN1_OVR,
+	RCAN1_SLE,
+	RCAN1_RM0, RCAN1_RM1,
+
+	SSI0_SSII, SSI1_SSII,
+
+	TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0,
+	TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1,
+
+	/* interrupt groups */
+
+	IRQ, PINT, ADC,
+	MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
+	MTU23_ABCD, MTU24_ABCD, MTU25_UVW,
+	RTC, IIC30, IIC31, IIC32,
+	SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
+	RCAN0, RCAN1, TMR0, TMR1
+
+};
+
+static struct intc_vect vectors[] __initdata = {
+	INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
+	INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
+	INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
+	INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
+	INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
+	INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
+	INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
+	INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
+
+	INTC_IRQ(ADC_ADI, 92),
+
+	INTC_IRQ(MTU2_TGI0A, 108), INTC_IRQ(MTU2_TGI0B, 109),
+	INTC_IRQ(MTU2_TGI0C, 110), INTC_IRQ(MTU2_TGI0D, 111),
+	INTC_IRQ(MTU2_TCI0V, 112),
+	INTC_IRQ(MTU2_TGI0E, 113), INTC_IRQ(MTU2_TGI0F, 114),
+
+	INTC_IRQ(MTU2_TGI1A, 116), INTC_IRQ(MTU2_TGI1B, 117),
+	INTC_IRQ(MTU2_TCI1V, 120), INTC_IRQ(MTU2_TCI1U, 121),
+
+	INTC_IRQ(MTU2_TGI2A, 124), INTC_IRQ(MTU2_TGI2B, 125),
+	INTC_IRQ(MTU2_TCI2V, 128), INTC_IRQ(MTU2_TCI2U, 129),
+
+	INTC_IRQ(MTU2_TGI3A, 132), INTC_IRQ(MTU2_TGI3B, 133),
+	INTC_IRQ(MTU2_TGI3C, 134), INTC_IRQ(MTU2_TGI3D, 135),
+	INTC_IRQ(MTU2_TCI3V, 136),
+
+	INTC_IRQ(MTU2_TGI4A, 140), INTC_IRQ(MTU2_TGI4B, 141),
+	INTC_IRQ(MTU2_TGI4C, 142), INTC_IRQ(MTU2_TGI4D, 143),
+	INTC_IRQ(MTU2_TCI4V, 144),
+
+	INTC_IRQ(MTU2_TGI5U, 148), INTC_IRQ(MTU2_TGI5V, 149),
+	INTC_IRQ(MTU2_TGI5W, 150),
+
+	INTC_IRQ(RTC_ARM, 152), INTC_IRQ(RTC_PRD, 153),
+	INTC_IRQ(RTC_CUP, 154), INTC_IRQ(WDT, 156),
+
+	INTC_IRQ(IIC30_STPI, 157), INTC_IRQ(IIC30_NAKI, 158),
+	INTC_IRQ(IIC30_RXI, 159), INTC_IRQ(IIC30_TXI, 160),
+	INTC_IRQ(IIC30_TEI, 161),
+
+	INTC_IRQ(IIC31_STPI, 164), INTC_IRQ(IIC31_NAKI, 165),
+	INTC_IRQ(IIC31_RXI, 166), INTC_IRQ(IIC31_TXI, 167),
+	INTC_IRQ(IIC31_TEI, 168),
+
+	INTC_IRQ(IIC32_STPI, 170), INTC_IRQ(IIC32_NAKI, 171),
+	INTC_IRQ(IIC32_RXI, 172), INTC_IRQ(IIC32_TXI, 173),
+	INTC_IRQ(IIC32_TEI, 174),
+
+	INTC_IRQ(DMAC0_DMINT0, 176), INTC_IRQ(DMAC1_DMINT1, 177),
+	INTC_IRQ(DMAC2_DMINT2, 178), INTC_IRQ(DMAC3_DMINT3, 179),
+
+	INTC_IRQ(SCIF0_BRI, 180), INTC_IRQ(SCIF0_ERI, 181),
+	INTC_IRQ(SCIF0_RXI, 182), INTC_IRQ(SCIF0_TXI, 183),
+	INTC_IRQ(SCIF1_BRI, 184), INTC_IRQ(SCIF1_ERI, 185),
+	INTC_IRQ(SCIF1_RXI, 186), INTC_IRQ(SCIF1_TXI, 187),
+	INTC_IRQ(SCIF2_BRI, 188), INTC_IRQ(SCIF2_ERI, 189),
+	INTC_IRQ(SCIF2_RXI, 190), INTC_IRQ(SCIF2_TXI, 191),
+	INTC_IRQ(SCIF3_BRI, 192), INTC_IRQ(SCIF3_ERI, 193),
+	INTC_IRQ(SCIF3_RXI, 194), INTC_IRQ(SCIF3_TXI, 195),
+	INTC_IRQ(SCIF4_BRI, 196), INTC_IRQ(SCIF4_ERI, 197),
+	INTC_IRQ(SCIF4_RXI, 198), INTC_IRQ(SCIF4_TXI, 199),
+	INTC_IRQ(SCIF5_BRI, 200), INTC_IRQ(SCIF5_ERI, 201),
+	INTC_IRQ(SCIF5_RXI, 202), INTC_IRQ(SCIF5_TXI, 203),
+	INTC_IRQ(SCIF6_BRI, 204), INTC_IRQ(SCIF6_ERI, 205),
+	INTC_IRQ(SCIF6_RXI, 206), INTC_IRQ(SCIF6_TXI, 207),
+	INTC_IRQ(SCIF7_BRI, 208), INTC_IRQ(SCIF7_ERI, 209),
+	INTC_IRQ(SCIF7_RXI, 210), INTC_IRQ(SCIF7_TXI, 211),
+
+	INTC_IRQ(DMAC0_DMINTA, 212), INTC_IRQ(DMAC4_DMINT4, 216),
+	INTC_IRQ(DMAC5_DMINT5, 217), INTC_IRQ(DMAC6_DMINT6, 218),
+	INTC_IRQ(DMAC7_DMINT7, 219),
+
+	INTC_IRQ(RCAN0_ERS, 228), INTC_IRQ(RCAN0_OVR, 229),
+	INTC_IRQ(RCAN0_SLE, 230),
+	INTC_IRQ(RCAN0_RM0, 231), INTC_IRQ(RCAN0_RM1, 232),
+
+	INTC_IRQ(RCAN1_ERS, 234), INTC_IRQ(RCAN1_OVR, 235),
+	INTC_IRQ(RCAN1_SLE, 236),
+	INTC_IRQ(RCAN1_RM0, 237), INTC_IRQ(RCAN1_RM1, 238),
+
+	INTC_IRQ(SSI0_SSII, 244), INTC_IRQ(SSI1_SSII, 245),
+
+	INTC_IRQ(TMR0_CMIA0, 246), INTC_IRQ(TMR0_CMIB0, 247),
+	INTC_IRQ(TMR0_OVI0, 248),
+
+	INTC_IRQ(TMR1_CMIA1, 252), INTC_IRQ(TMR1_CMIB1, 253),
+	INTC_IRQ(TMR1_OVI1, 254),
+
+};
+
+static struct intc_group groups[] __initdata = {
+	INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
+		   PINT4, PINT5, PINT6, PINT7),
+	INTC_GROUP(MTU20_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
+	INTC_GROUP(MTU20_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
+
+	INTC_GROUP(MTU21_AB, MTU2_TGI1A, MTU2_TGI1B),
+	INTC_GROUP(MTU21_VU, MTU2_TCI1V, MTU2_TCI1U),
+	INTC_GROUP(MTU22_AB, MTU2_TGI2A, MTU2_TGI2B),
+	INTC_GROUP(MTU22_VU, MTU2_TCI2V, MTU2_TCI2U),
+	INTC_GROUP(MTU23_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
+	INTC_GROUP(MTU24_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
+	INTC_GROUP(MTU25_UVW, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
+	INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP ),
+
+	INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
+		   IIC30_TEI),
+	INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
+		   IIC31_TEI),
+	INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
+		   IIC32_TEI),
+
+	INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
+	INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
+	INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
+	INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
+	INTC_GROUP(SCIF4, SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI),
+	INTC_GROUP(SCIF5, SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI),
+	INTC_GROUP(SCIF6, SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI),
+	INTC_GROUP(SCIF7, SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI),
+
+	INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
+		   RCAN0_SLE),
+	INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
+		   RCAN1_SLE),
+
+	INTC_GROUP(TMR0, TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0),
+	INTC_GROUP(TMR1, TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+	{ 0xfffe9418, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
+	{ 0xfffe941a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
+	{ 0xfffe9420, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI, 0 } },
+	{ 0xfffe9800, 0, 16, 4, /* IPR06 */ { 0, MTU20_ABCD, MTU20_VEF, MTU21_AB } },
+	{ 0xfffe9802, 0, 16, 4, /* IPR07 */ { MTU21_VU, MTU22_AB, MTU22_VU,  MTU23_ABCD } },
+	{ 0xfffe9804, 0, 16, 4, /* IPR08 */ { MTU2_TCI3V, MTU24_ABCD, MTU2_TCI4V, MTU25_UVW } },
+
+	{ 0xfffe9806, 0, 16, 4, /* IPR09 */ { RTC, WDT, IIC30, 0 } },
+	{ 0xfffe9808, 0, 16, 4, /* IPR10 */ { IIC31, IIC32, DMAC0_DMINT0, DMAC1_DMINT1 } },
+	{ 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0 , SCIF1 } },
+	{ 0xfffe980c, 0, 16, 4, /* IPR12 */ { SCIF2, SCIF3, SCIF4, SCIF5 } },
+	{ 0xfffe980e, 0, 16, 4, /* IPR13 */ { SCIF6, SCIF7, DMAC0_DMINTA, DMAC4_DMINT4  } },
+	{ 0xfffe9810, 0, 16, 4, /* IPR14 */ { DMAC5_DMINT5, DMAC6_DMINT6, DMAC7_DMINT7, 0 } },
+	{ 0xfffe9812, 0, 16, 4, /* IPR15 */ { 0, RCAN0, RCAN1, 0 } },
+	{ 0xfffe9814, 0, 16, 4, /* IPR16 */ { SSI0_SSII, SSI1_SSII, TMR0, TMR1 } },
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+	{ 0xfffe9408, 0, 16, /* PINTER */
+	  { 0, 0, 0, 0, 0, 0, 0, 0,
+	    PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
+			 mask_registers, prio_registers, NULL);
+
+static struct plat_sci_port sci_platform_data[] = {
+	{
+		.mapbase	= 0xfffe8000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 181, 182, 183, 180}
+	}, {
+		.mapbase	= 0xfffe8800,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 185, 186, 187, 184}
+	}, {
+		.mapbase	= 0xfffe9000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 189, 186, 187, 188}
+	}, {
+		.mapbase	= 0xfffe9800,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 193, 194, 195, 192}
+	}, {
+		.mapbase	= 0xfffea000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 196, 198, 199, 196}
+	}, {
+		.mapbase	= 0xfffea800,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 201, 202, 203, 200}
+	}, {
+		.mapbase	= 0xfffeb000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 205, 206, 207, 204}
+	}, {
+		.mapbase	= 0xfffeb800,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 209, 210, 211, 208}
+	}, {
+		.flags = 0,
+	}
+};
+
+static struct platform_device sci_device = {
+	.name		= "sh-sci",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= sci_platform_data,
+	},
+};
+
+static struct resource rtc_resources[] = {
+	[0] = {
+		.start	= 0xffff0800,
+		.end	= 0xffff2000 + 0x58 - 1,
+		.flags	= IORESOURCE_IO,
+	},
+	[1] = {
+		/* Period IRQ */
+		.start	= 153,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* Carry IRQ */
+		.start	= 154,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		/* Alarm IRQ */
+		.start	= 152,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device rtc_device = {
+	.name		= "sh-rtc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(rtc_resources),
+	.resource	= rtc_resources,
+};
+
+static struct platform_device *sh7201_devices[] __initdata = {
+	&sci_device,
+	&rtc_device,
+};
+
+static int __init sh7201_devices_setup(void)
+{
+	return platform_add_devices(sh7201_devices,
+				    ARRAY_SIZE(sh7201_devices));
+}
+__initcall(sh7201_devices_setup);
+
+void __init plat_irq_setup(void)
+{
+	register_intc_controller(&intc_desc);
+}
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 3fe482dd05c1..b4106d0c68ec 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -52,7 +52,7 @@
  *	syscall #
  *
  */
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
 NMI_VEC = 0x1c0			! Must catch early for debounce
 #endif
 
@@ -307,7 +307,7 @@ skip_restore:
 6:	or	k0, k2			! Set the IMASK-bits
 	ldc	k2, ssr
 	!
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
 	! Clear in_nmi
 	mov.l	6f, k0
 	mov	#0, k1
@@ -320,7 +320,7 @@ skip_restore:
 
 	.align	2
 5:	.long	0x00001000	! DSP
-#ifdef CONFIG_KGDB_NMI
+#ifdef CONFIG_KGDB
 6:	.long	in_nmi
 #endif
 7:	.long	0x30000000
@@ -376,9 +376,9 @@ tlb_miss:
 !
 	.balign 	512,0,512
 interrupt:
-	mov.l	2f, k2
 	mov.l	3f, k3
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
+	mov.l	2f, k2
 	! Debounce (filter nested NMI)
 	mov.l	@k2, k0
 	mov.l	5f, k1
@@ -390,16 +390,16 @@ interrupt:
 	rte
 	 nop
 	.align	2
+2:	.long	INTEVT
 5:	.long	NMI_VEC
 6:	.long	in_nmi
 0:
-#endif /* defined(CONFIG_KGDB_NMI) */
+#endif /* defined(CONFIG_KGDB) */
 	bra	handle_exception
 	 mov	#-1, k2		! interrupt exception marker
 
 	.align	2
 1:	.long	EXPEVT
-2:	.long	INTEVT
 3:	.long	ret_from_irq
 4:	.long	ret_from_exception
 
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index dac429726899..e5a0de39a2db 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -26,7 +26,7 @@
 #define	fpu_error_trap_handler		exception_error
 #endif
 
-#if !defined(CONFIG_KGDB_NMI)
+#if !defined(CONFIG_KGDB)
 #define kgdb_handle_exception		exception_error
 #endif
 
diff --git a/arch/sh/kernel/cpu/sh4/softfloat.c b/arch/sh/kernel/cpu/sh4/softfloat.c
index 2b747f3b02bd..42edf2e54e85 100644
--- a/arch/sh/kernel/cpu/sh4/softfloat.c
+++ b/arch/sh/kernel/cpu/sh4/softfloat.c
@@ -37,6 +37,7 @@
  */
 #include <linux/kernel.h>
 #include <cpu/fpu.h>
+#include <asm/div64.h>
 
 #define LIT64( a ) a##LL
 
@@ -67,16 +68,16 @@ typedef unsigned long long float64;
 extern void float_raise(unsigned int flags);	/* in fpu.c */
 extern int float_rounding_mode(void);	/* in fpu.c */
 
-inline bits64 extractFloat64Frac(float64 a);
-inline flag extractFloat64Sign(float64 a);
-inline int16 extractFloat64Exp(float64 a);
-inline int16 extractFloat32Exp(float32 a);
-inline flag extractFloat32Sign(float32 a);
-inline bits32 extractFloat32Frac(float32 a);
-inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig);
-inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr);
-inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig);
-inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr);
+bits64 extractFloat64Frac(float64 a);
+flag extractFloat64Sign(float64 a);
+int16 extractFloat64Exp(float64 a);
+int16 extractFloat32Exp(float32 a);
+flag extractFloat32Sign(float32 a);
+bits32 extractFloat32Frac(float32 a);
+float64 packFloat64(flag zSign, int16 zExp, bits64 zSig);
+void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr);
+float32 packFloat32(flag zSign, int16 zExp, bits32 zSig);
+void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr);
 float64 float64_sub(float64 a, float64 b);
 float32 float32_sub(float32 a, float32 b);
 float32 float32_add(float32 a, float32 b);
@@ -86,11 +87,11 @@ float32 float32_div(float32 a, float32 b);
 float32 float32_mul(float32 a, float32 b);
 float64 float64_mul(float64 a, float64 b);
 float32 float64_to_float32(float64 a);
-inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
+void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
 		   bits64 * z1Ptr);
-inline void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
+void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
 		   bits64 * z1Ptr);
-inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr);
+void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr);
 
 static int8 countLeadingZeros32(bits32 a);
 static int8 countLeadingZeros64(bits64 a);
@@ -110,42 +111,42 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b);
 static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr,
 				      bits32 * zSigPtr);
 
-inline bits64 extractFloat64Frac(float64 a)
+bits64 extractFloat64Frac(float64 a)
 {
 	return a & LIT64(0x000FFFFFFFFFFFFF);
 }
 
-inline flag extractFloat64Sign(float64 a)
+flag extractFloat64Sign(float64 a)
 {
 	return a >> 63;
 }
 
-inline int16 extractFloat64Exp(float64 a)
+int16 extractFloat64Exp(float64 a)
 {
 	return (a >> 52) & 0x7FF;
 }
 
-inline int16 extractFloat32Exp(float32 a)
+int16 extractFloat32Exp(float32 a)
 {
 	return (a >> 23) & 0xFF;
 }
 
-inline flag extractFloat32Sign(float32 a)
+flag extractFloat32Sign(float32 a)
 {
 	return a >> 31;
 }
 
-inline bits32 extractFloat32Frac(float32 a)
+bits32 extractFloat32Frac(float32 a)
 {
 	return a & 0x007FFFFF;
 }
 
-inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig)
+float64 packFloat64(flag zSign, int16 zExp, bits64 zSig)
 {
 	return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig;
 }
 
-inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr)
+void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr)
 {
 	bits64 z;
 
@@ -338,12 +339,12 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign)
 
 }
 
-inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig)
+float32 packFloat32(flag zSign, int16 zExp, bits32 zSig)
 {
 	return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig;
 }
 
-inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr)
+void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr)
 {
 	bits32 z;
 	if (count == 0) {
@@ -634,7 +635,7 @@ normalizeFloat64Subnormal(bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr)
 	*zExpPtr = 1 - shiftCount;
 }
 
-inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
+void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
 		   bits64 * z1Ptr)
 {
 	bits64 z1;
@@ -644,7 +645,7 @@ inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
 	*z0Ptr = a0 + b0 + (z1 < a1);
 }
 
-inline void
+void
 sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
        bits64 * z1Ptr)
 {
@@ -656,11 +657,14 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
 {
 	bits64 b0, b1;
 	bits64 rem0, rem1, term0, term1;
-	bits64 z;
+	bits64 z, tmp;
 	if (b <= a0)
 		return LIT64(0xFFFFFFFFFFFFFFFF);
 	b0 = b >> 32;
-	z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : (a0 / b0) << 32;
+	tmp = a0;
+	do_div(tmp, b0);
+
+	z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : tmp << 32;
 	mul64To128(b, z, &term0, &term1);
 	sub128(a0, a1, term0, term1, &rem0, &rem1);
 	while (((sbits64) rem0) < 0) {
@@ -669,11 +673,13 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
 		add128(rem0, rem1, b0, b1, &rem0, &rem1);
 	}
 	rem0 = (rem0 << 32) | (rem1 >> 32);
-	z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0;
+	tmp = rem0;
+	do_div(tmp, b0);
+	z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : tmp;
 	return z;
 }
 
-inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr)
+void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr)
 {
 	bits32 aHigh, aLow, bHigh, bLow;
 	bits64 z0, zMiddleA, zMiddleB, z1;
@@ -769,7 +775,8 @@ float32 float32_div(float32 a, float32 b)
 {
 	flag aSign, bSign, zSign;
 	int16 aExp, bExp, zExp;
-	bits32 aSig, bSig, zSig;
+	bits32 aSig, bSig;
+	uint64_t zSig;
 
 	aSig = extractFloat32Frac(a);
 	aExp = extractFloat32Exp(a);
@@ -804,11 +811,13 @@ float32 float32_div(float32 a, float32 b)
 		aSig >>= 1;
 		++zExp;
 	}
-	zSig = (((bits64) aSig) << 32) / bSig;
+	zSig = (((bits64) aSig) << 32);
+	do_div(zSig, bSig);
+
 	if ((zSig & 0x3F) == 0) {
 		zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32);
 	}
-	return roundAndPackFloat32(zSign, zExp, zSig);
+	return roundAndPackFloat32(zSign, zExp, (bits32)zSig);
 
 }
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index db913855c2fd..0e174af21874 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -229,7 +229,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
 }
 
 /**
- * sh7722_find_divisors - find divisor for setting rate
+ * sh7722_find_div_index - find divisor for setting rate
  *
  * All sh7722 clocks use the same set of multipliers/divisors. This function
  * chooses correct divisor to set the rate of clock with parent clock that
@@ -238,7 +238,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
  * @parent_rate: rate of parent clock
  * @rate: requested rate to be set
  */
-static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
+static int sh7722_find_div_index(unsigned long parent_rate, unsigned rate)
 {
 	unsigned div2 = parent_rate * 2 / rate;
 	int index;
@@ -247,12 +247,12 @@ static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
 		return -EINVAL;
 
 	for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
-		if (div2 > divisors2[index] && div2 <= divisors2[index])
+		if (div2 > divisors2[index - 1] && div2 <= divisors2[index])
 			break;
 	}
 	if (index >= ARRAY_SIZE(divisors2))
 		index = ARRAY_SIZE(divisors2) - 1;
-	return divisors2[index];
+	return index;
 }
 
 static void sh7722_frqcr_recalc(struct clk *clk)
@@ -279,12 +279,12 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
 		return -EINVAL;
 
 	/* look for multiplier/divisor pair */
-	div = sh7722_find_divisors(parent_rate, rate);
+	div = sh7722_find_div_index(parent_rate, rate);
 	if (div<0)
 		return div;
 
 	/* calculate new value of clock rate */
-	clk->rate = parent_rate * 2 / div;
+	clk->rate = parent_rate * 2 / divisors2[div];
 	frqcr = ctrl_inl(FRQCR);
 
 	/* FIXME: adjust as algo_id specifies */
@@ -353,7 +353,7 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
 			int part_div;
 
 			if (likely(!err)) {
-				part_div = sh7722_find_divisors(parent_rate,
+				part_div = sh7722_find_div_index(parent_rate,
 								rate);
 				if (part_div > 0) {
 					part_ctx = sh7722_get_clk_context(
@@ -394,12 +394,12 @@ static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate)
 	int div;
 
 	/* look for multiplier/divisor pair */
-	div = sh7722_find_divisors(parent_rate, rate);
+	div = sh7722_find_div_index(parent_rate, rate);
 	if (div < 0)
 		return clk->rate;
 
 	/* calculate new value of clock rate */
-	return parent_rate * 2 / div;
+	return parent_rate * 2 / divisors2[div];
 }
 
 static struct clk_ops sh7722_frqcr_clk_ops = {
@@ -421,7 +421,7 @@ static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
 	int div;
 
 	r = ctrl_inl(clk->arch_flags);
-	div = sh7722_find_divisors(clk->parent->rate, rate);
+	div = sh7722_find_div_index(clk->parent->rate, rate);
 	if (div < 0)
 		return div;
 	r = (r & ~0xF) | div;
@@ -516,16 +516,19 @@ static struct clk_ops sh7722_video_clk_ops = {
 static struct clk sh7722_umem_clock = {
 	.name = "umem_clk",
 	.ops = &sh7722_frqcr_clk_ops,
+	.flags = CLK_RATE_PROPAGATES,
 };
 
 static struct clk sh7722_sh_clock = {
 	.name = "sh_clk",
 	.ops = &sh7722_frqcr_clk_ops,
+	.flags = CLK_RATE_PROPAGATES,
 };
 
 static struct clk sh7722_peripheral_clock = {
 	.name = "peripheral_clk",
 	.ops = &sh7722_frqcr_clk_ops,
+	.flags = CLK_RATE_PROPAGATES,
 };
 
 static struct clk sh7722_sdram_clock = {
@@ -533,6 +536,11 @@ static struct clk sh7722_sdram_clock = {
 	.ops = &sh7722_frqcr_clk_ops,
 };
 
+static struct clk sh7722_r_clock = {
+	.name = "r_clk",
+	.rate = 32768,
+	.flags = CLK_RATE_PROPAGATES,
+};
 
 #ifndef CONFIG_CPU_SUBTYPE_SH7343
 
@@ -567,12 +575,30 @@ static struct clk sh7722_video_clock = {
 	.ops = &sh7722_video_clk_ops,
 };
 
-static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg,
-				    int enable)
+#define MSTPCR_ARCH_FLAGS(reg, bit) (((reg) << 8) | (bit))
+#define MSTPCR_ARCH_FLAGS_REG(value) ((value) >> 8)
+#define MSTPCR_ARCH_FLAGS_BIT(value) ((value) & 0xff)
+
+static int sh7722_mstpcr_start_stop(struct clk *clk, int enable)
 {
-	unsigned long bit = clk->arch_flags;
+	unsigned long bit = MSTPCR_ARCH_FLAGS_BIT(clk->arch_flags);
+	unsigned long reg;
 	unsigned long r;
 
+	switch(MSTPCR_ARCH_FLAGS_REG(clk->arch_flags)) {
+	case 0:
+		reg = MSTPCR0;
+		break;
+	case 1:
+		reg = MSTPCR1;
+		break;
+	case 2:
+		reg = MSTPCR2;
+		break;
+	default:
+		return -EINVAL;
+	}  
+
 	r = ctrl_inl(reg);
 
 	if (enable)
@@ -584,96 +610,175 @@ static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg,
 	return 0;
 }
 
-static void sh7722_mstpcr0_enable(struct clk *clk)
-{
-	sh7722_mstpcr_start_stop(clk, MSTPCR0, 1);
-}
-
-static void sh7722_mstpcr0_disable(struct clk *clk)
-{
-	sh7722_mstpcr_start_stop(clk, MSTPCR0, 0);
-}
-
-static void sh7722_mstpcr1_enable(struct clk *clk)
-{
-	sh7722_mstpcr_start_stop(clk, MSTPCR1, 1);
-}
-
-static void sh7722_mstpcr1_disable(struct clk *clk)
+static void sh7722_mstpcr_enable(struct clk *clk)
 {
-	sh7722_mstpcr_start_stop(clk, MSTPCR1, 0);
+	sh7722_mstpcr_start_stop(clk, 1);
 }
 
-static void sh7722_mstpcr2_enable(struct clk *clk)
+static void sh7722_mstpcr_disable(struct clk *clk)
 {
-	sh7722_mstpcr_start_stop(clk, MSTPCR2, 1);
+	sh7722_mstpcr_start_stop(clk, 0);
 }
 
-static void sh7722_mstpcr2_disable(struct clk *clk)
+static void sh7722_mstpcr_recalc(struct clk *clk)
 {
-	sh7722_mstpcr_start_stop(clk, MSTPCR2, 0);
+	if (clk->parent)
+		clk->rate = clk->parent->rate;
 }
 
-static struct clk_ops sh7722_mstpcr0_clk_ops = {
-	.enable = sh7722_mstpcr0_enable,
-	.disable = sh7722_mstpcr0_disable,
-};
-
-static struct clk_ops sh7722_mstpcr1_clk_ops = {
-	.enable = sh7722_mstpcr1_enable,
-	.disable = sh7722_mstpcr1_disable,
+static struct clk_ops sh7722_mstpcr_clk_ops = {
+	.enable = sh7722_mstpcr_enable,
+	.disable = sh7722_mstpcr_disable,
+	.recalc = sh7722_mstpcr_recalc,
 };
 
-static struct clk_ops sh7722_mstpcr2_clk_ops = {
-	.enable = sh7722_mstpcr2_enable,
-	.disable = sh7722_mstpcr2_disable,
-};
-
-#define DECLARE_MSTPCRN(regnr, bitnr, bitstr)		\
-{							\
-	.name = "mstp" __stringify(regnr) bitstr,	\
-	.arch_flags = bitnr,				\
-	.ops = &sh7722_mstpcr ## regnr ## _clk_ops,	\
+#define MSTPCR(_name, _parent, regnr, bitnr) \
+{						\
+	.name = _name,				\
+	.arch_flags = MSTPCR_ARCH_FLAGS(regnr, bitnr),	\
+	.ops = (void *)_parent,		\
 }
 
-#define DECLARE_MSTPCR(regnr) \
-	DECLARE_MSTPCRN(regnr, 31, "31"), \
-	DECLARE_MSTPCRN(regnr, 30, "30"), \
-	DECLARE_MSTPCRN(regnr, 29, "29"), \
-	DECLARE_MSTPCRN(regnr, 28, "28"), \
-	DECLARE_MSTPCRN(regnr, 27, "27"), \
-	DECLARE_MSTPCRN(regnr, 26, "26"), \
-	DECLARE_MSTPCRN(regnr, 25, "25"), \
-	DECLARE_MSTPCRN(regnr, 24, "24"), \
-	DECLARE_MSTPCRN(regnr, 23, "23"), \
-	DECLARE_MSTPCRN(regnr, 22, "22"), \
-	DECLARE_MSTPCRN(regnr, 21, "21"), \
-	DECLARE_MSTPCRN(regnr, 20, "20"), \
-	DECLARE_MSTPCRN(regnr, 19, "19"), \
-	DECLARE_MSTPCRN(regnr, 18, "18"), \
-	DECLARE_MSTPCRN(regnr, 17, "17"), \
-	DECLARE_MSTPCRN(regnr, 16, "16"), \
-	DECLARE_MSTPCRN(regnr, 15, "15"), \
-	DECLARE_MSTPCRN(regnr, 14, "14"), \
-	DECLARE_MSTPCRN(regnr, 13, "13"), \
-	DECLARE_MSTPCRN(regnr, 12, "12"), \
-	DECLARE_MSTPCRN(regnr, 11, "11"), \
-	DECLARE_MSTPCRN(regnr, 10, "10"), \
-	DECLARE_MSTPCRN(regnr, 9, "09"), \
-	DECLARE_MSTPCRN(regnr, 8, "08"), \
-	DECLARE_MSTPCRN(regnr, 7, "07"), \
-	DECLARE_MSTPCRN(regnr, 6, "06"), \
-	DECLARE_MSTPCRN(regnr, 5, "05"), \
-	DECLARE_MSTPCRN(regnr, 4, "04"), \
-	DECLARE_MSTPCRN(regnr, 3, "03"), \
-	DECLARE_MSTPCRN(regnr, 2, "02"), \
-	DECLARE_MSTPCRN(regnr, 1, "01"), \
-	DECLARE_MSTPCRN(regnr, 0, "00")
-
-static struct clk sh7722_mstpcr[] = {
-	DECLARE_MSTPCR(0),
-	DECLARE_MSTPCR(1),
-	DECLARE_MSTPCR(2),
+static struct clk sh7722_mstpcr_clocks[] = {
+#if defined(CONFIG_CPU_SUBTYPE_SH7722)
+	MSTPCR("uram0", "umem_clk", 0, 28),
+	MSTPCR("xymem0", "bus_clk", 0, 26),
+	MSTPCR("tmu0", "peripheral_clk", 0, 15),
+	MSTPCR("cmt0", "r_clk", 0, 14),
+	MSTPCR("rwdt0", "r_clk", 0, 13),
+	MSTPCR("flctl0", "peripheral_clk", 0, 10),
+	MSTPCR("scif0", "peripheral_clk", 0, 7),
+	MSTPCR("scif1", "peripheral_clk", 0, 6),
+	MSTPCR("scif2", "peripheral_clk", 0, 5),
+	MSTPCR("i2c0", "peripheral_clk", 1, 9),
+	MSTPCR("rtc0", "r_clk", 1, 8),
+	MSTPCR("sdhi0", "peripheral_clk", 2, 18),
+	MSTPCR("keysc0", "r_clk", 2, 14),
+	MSTPCR("usbf0", "peripheral_clk", 2, 11),
+	MSTPCR("2dg0", "bus_clk", 2, 9),
+	MSTPCR("siu0", "bus_clk", 2, 8),
+	MSTPCR("vou0", "bus_clk", 2, 5),
+	MSTPCR("jpu0", "bus_clk", 2, 6),
+	MSTPCR("beu0", "bus_clk", 2, 4),
+	MSTPCR("ceu0", "bus_clk", 2, 3),
+	MSTPCR("veu0", "bus_clk", 2, 2),
+	MSTPCR("vpu0", "bus_clk", 2, 1),
+	MSTPCR("lcdc0", "bus_clk", 2, 0),
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)
+	/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
+	MSTPCR("tlb0", "cpu_clk", 0, 31),
+	MSTPCR("ic0", "cpu_clk", 0, 30),
+	MSTPCR("oc0", "cpu_clk", 0, 29),
+	MSTPCR("l2c0", "sh_clk", 0, 28),
+	MSTPCR("ilmem0", "cpu_clk", 0, 27),
+	MSTPCR("fpu0", "cpu_clk", 0, 24),
+	MSTPCR("intc0", "cpu_clk", 0, 22),
+	MSTPCR("dmac0", "bus_clk", 0, 21),
+	MSTPCR("sh0", "sh_clk", 0, 20),
+	MSTPCR("hudi0", "peripheral_clk", 0, 19),
+	MSTPCR("ubc0", "cpu_clk", 0, 17),
+	MSTPCR("tmu0", "peripheral_clk", 0, 15),
+	MSTPCR("cmt0", "r_clk", 0, 14),
+	MSTPCR("rwdt0", "r_clk", 0, 13),
+	MSTPCR("dmac1", "bus_clk", 0, 12),
+	MSTPCR("tmu1", "peripheral_clk", 0, 11),
+	MSTPCR("flctl0", "peripheral_clk", 0, 10),
+	MSTPCR("scif0", "peripheral_clk", 0, 9),
+	MSTPCR("scif1", "peripheral_clk", 0, 8),
+	MSTPCR("scif2", "peripheral_clk", 0, 7),
+	MSTPCR("scif3", "bus_clk", 0, 6),
+	MSTPCR("scif4", "bus_clk", 0, 5),
+	MSTPCR("scif5", "bus_clk", 0, 4),
+	MSTPCR("msiof0", "bus_clk", 0, 2),
+	MSTPCR("msiof1", "bus_clk", 0, 1),
+	MSTPCR("meram0", "sh_clk", 0, 0),
+	MSTPCR("i2c0", "peripheral_clk", 1, 9),
+	MSTPCR("rtc0", "r_clk", 1, 8),
+	MSTPCR("atapi0", "sh_clk", 2, 28),
+	MSTPCR("adc0", "peripheral_clk", 2, 28),
+	MSTPCR("tpu0", "bus_clk", 2, 25),
+	MSTPCR("irda0", "peripheral_clk", 2, 24),
+	MSTPCR("tsif0", "bus_clk", 2, 22),
+	MSTPCR("icb0", "bus_clk", 2, 21),
+	MSTPCR("sdhi0", "bus_clk", 2, 18),
+	MSTPCR("sdhi1", "bus_clk", 2, 17),
+	MSTPCR("keysc0", "r_clk", 2, 14),
+	MSTPCR("usb0", "bus_clk", 2, 11),
+	MSTPCR("2dg0", "bus_clk", 2, 10),
+	MSTPCR("siu0", "bus_clk", 2, 8),
+	MSTPCR("veu1", "bus_clk", 2, 6),
+	MSTPCR("vou0", "bus_clk", 2, 5),
+	MSTPCR("beu0", "bus_clk", 2, 4),
+	MSTPCR("ceu0", "bus_clk", 2, 3),
+	MSTPCR("veu0", "bus_clk", 2, 2),
+	MSTPCR("vpu0", "bus_clk", 2, 1),
+	MSTPCR("lcdc0", "bus_clk", 2, 0),
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7343)
+	MSTPCR("uram0", "umem_clk", 0, 28),
+	MSTPCR("xymem0", "bus_clk", 0, 26),
+	MSTPCR("tmu0", "peripheral_clk", 0, 15),
+	MSTPCR("cmt0", "r_clk", 0, 14),
+	MSTPCR("rwdt0", "r_clk", 0, 13),
+	MSTPCR("scif0", "peripheral_clk", 0, 7),
+	MSTPCR("scif1", "peripheral_clk", 0, 6),
+	MSTPCR("scif2", "peripheral_clk", 0, 5),
+	MSTPCR("scif3", "peripheral_clk", 0, 4),
+	MSTPCR("i2c0", "peripheral_clk", 1, 9),
+	MSTPCR("i2c1", "peripheral_clk", 1, 8),
+	MSTPCR("sdhi0", "peripheral_clk", 2, 18),
+	MSTPCR("keysc0", "r_clk", 2, 14),
+	MSTPCR("usbf0", "peripheral_clk", 2, 11),
+	MSTPCR("siu0", "bus_clk", 2, 8),
+	MSTPCR("jpu0", "bus_clk", 2, 6),
+	MSTPCR("vou0", "bus_clk", 2, 5),
+	MSTPCR("beu0", "bus_clk", 2, 4),
+	MSTPCR("ceu0", "bus_clk", 2, 3),
+	MSTPCR("veu0", "bus_clk", 2, 2),
+	MSTPCR("vpu0", "bus_clk", 2, 1),
+	MSTPCR("lcdc0", "bus_clk", 2, 0),
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7366)
+	/* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
+	MSTPCR("tlb0", "cpu_clk", 0, 31),
+	MSTPCR("ic0", "cpu_clk", 0, 30),
+	MSTPCR("oc0", "cpu_clk", 0, 29),
+	MSTPCR("rsmem0", "sh_clk", 0, 28),
+	MSTPCR("xymem0", "cpu_clk", 0, 26),
+	MSTPCR("intc30", "peripheral_clk", 0, 23),
+	MSTPCR("intc0", "peripheral_clk", 0, 22),
+	MSTPCR("dmac0", "bus_clk", 0, 21),
+	MSTPCR("sh0", "sh_clk", 0, 20),
+	MSTPCR("hudi0", "peripheral_clk", 0, 19),
+	MSTPCR("ubc0", "cpu_clk", 0, 17),
+	MSTPCR("tmu0", "peripheral_clk", 0, 15),
+	MSTPCR("cmt0", "r_clk", 0, 14),
+	MSTPCR("rwdt0", "r_clk", 0, 13),
+	MSTPCR("flctl0", "peripheral_clk", 0, 10),
+	MSTPCR("scif0", "peripheral_clk", 0, 7),
+	MSTPCR("scif1", "bus_clk", 0, 6),
+	MSTPCR("scif2", "bus_clk", 0, 5),
+	MSTPCR("msiof0", "peripheral_clk", 0, 2),
+	MSTPCR("sbr0", "peripheral_clk", 0, 1),
+	MSTPCR("i2c0", "peripheral_clk", 1, 9),
+	MSTPCR("icb0", "bus_clk", 2, 27),
+	MSTPCR("meram0", "sh_clk", 2, 26),
+	MSTPCR("dacc0", "peripheral_clk", 2, 24),
+	MSTPCR("dacy0", "peripheral_clk", 2, 23),
+	MSTPCR("tsif0", "bus_clk", 2, 22),
+	MSTPCR("sdhi0", "bus_clk", 2, 18),
+	MSTPCR("mmcif0", "bus_clk", 2, 17),
+	MSTPCR("usb0", "bus_clk", 2, 11),
+	MSTPCR("siu0", "bus_clk", 2, 8),
+	MSTPCR("veu1", "bus_clk", 2, 7),
+	MSTPCR("vou0", "bus_clk", 2, 5),
+	MSTPCR("beu0", "bus_clk", 2, 4),
+	MSTPCR("ceu0", "bus_clk", 2, 3),
+	MSTPCR("veu0", "bus_clk", 2, 2),
+	MSTPCR("vpu0", "bus_clk", 2, 1),
+	MSTPCR("lcdc0", "bus_clk", 2, 0),
+#endif
 };
 
 static struct clk *sh7722_clocks[] = {
@@ -710,21 +815,30 @@ arch_init_clk_ops(struct clk_ops **ops, int type)
 
 int __init arch_clk_init(void)
 {
-	struct clk *master;
+	struct clk *clk;
 	int i;
 
-	master = clk_get(NULL, "master_clk");
+	clk = clk_get(NULL, "master_clk");
 	for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
 		pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
-		sh7722_clocks[i]->parent = master;
+		sh7722_clocks[i]->parent = clk;
 		clk_register(sh7722_clocks[i]);
 	}
-	clk_put(master);
-
-	for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr); i++) {
-		pr_debug( "Registering mstpcr '%s'\n", sh7722_mstpcr[i].name);
-		clk_register(&sh7722_mstpcr[i]);
+	clk_put(clk);
+
+	clk_register(&sh7722_r_clock);
+
+	for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr_clocks); i++) {
+		pr_debug( "Registering mstpcr clock '%s'\n",
+			  sh7722_mstpcr_clocks[i].name);
+		clk = clk_get(NULL, (void *) sh7722_mstpcr_clocks[i].ops);
+		sh7722_mstpcr_clocks[i].parent = clk;
+		sh7722_mstpcr_clocks[i].ops = &sh7722_mstpcr_clk_ops;
+		clk_register(&sh7722_mstpcr_clocks[i]);
+		clk_put(clk);
 	}
 
+	clk_recalc_rate(&sh7722_r_clock); /* make sure rate gets propagated */
+
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 78881b4214da..0623e377f488 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -30,6 +30,7 @@ static struct resource iic0_resources[] = {
 
 static struct platform_device iic0_device = {
 	.name           = "i2c-sh_mobile",
+	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic0_resources),
 	.resource       = iic0_resources,
 };
@@ -50,6 +51,7 @@ static struct resource iic1_resources[] = {
 
 static struct platform_device iic1_device = {
 	.name           = "i2c-sh_mobile",
+	.id             = 1, /* "i2c1" clock */
 	.num_resources  = ARRAY_SIZE(iic1_resources),
 	.resource       = iic1_resources,
 };
@@ -115,7 +117,22 @@ static struct plat_sci_port sci_platform_data[] = {
 		.mapbase	= 0xffe00000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 80, 81, 83, 82 },
+		.irqs		= { 80, 80, 80, 80 },
+	}, {
+		.mapbase	= 0xffe10000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 81, 81, 81, 81 },
+	}, {
+		.mapbase	= 0xffe20000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 82, 82, 82, 82 },
+	}, {
+		.mapbase	= 0xffe30000,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 83, 83, 83, 83 },
 	}, {
 		.flags = 0,
 	}
@@ -139,18 +156,10 @@ static struct platform_device *sh7343_devices[] __initdata = {
 
 static int __init sh7343_devices_setup(void)
 {
-	clk_always_enable("mstp031"); /* TLB */
-	clk_always_enable("mstp030"); /* IC */
-	clk_always_enable("mstp029"); /* OC */
-	clk_always_enable("mstp028"); /* URAM */
-	clk_always_enable("mstp026"); /* XYMEM */
-	clk_always_enable("mstp023"); /* INTC3 */
-	clk_always_enable("mstp022"); /* INTC */
-	clk_always_enable("mstp020"); /* SuperHyway */
-	clk_always_enable("mstp109"); /* I2C0 */
-	clk_always_enable("mstp108"); /* I2C1 */
-	clk_always_enable("mstp202"); /* VEU */
-	clk_always_enable("mstp201"); /* VPU */
+	clk_always_enable("uram0"); /* URAM */
+	clk_always_enable("xymem0"); /* XYMEM */
+	clk_always_enable("veu0"); /* VEU */
+	clk_always_enable("vpu0"); /* VPU */
 
 	platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
 	platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
@@ -171,7 +180,7 @@ enum {
 	MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY,
 	DMAC4, DMAC5, DMAC_DADERR,
 	KEYSC,
-	SCIF, SCIF1, SCIF2, SCIF3, SCIF4,
+	SCIF, SCIF1, SCIF2, SCIF3,
 	SIOF0, SIOF1, SIO,
 	FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
 	I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index e17db39b97aa..839ae97a7fd2 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -32,6 +32,7 @@ static struct resource iic_resources[] = {
 
 static struct platform_device iic_device = {
 	.name           = "i2c-sh_mobile",
+	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
 };
@@ -176,19 +177,11 @@ static struct platform_device *sh7366_devices[] __initdata = {
 
 static int __init sh7366_devices_setup(void)
 {
-	clk_always_enable("mstp031"); /* TLB */
-	clk_always_enable("mstp030"); /* IC */
-	clk_always_enable("mstp029"); /* OC */
-	clk_always_enable("mstp028"); /* RSMEM */
-	clk_always_enable("mstp026"); /* XYMEM */
-	clk_always_enable("mstp023"); /* INTC3 */
-	clk_always_enable("mstp022"); /* INTC */
-	clk_always_enable("mstp020"); /* SuperHyway */
-	clk_always_enable("mstp109"); /* I2C */
-	clk_always_enable("mstp211"); /* USB */
-	clk_always_enable("mstp207"); /* VEU-2 */
-	clk_always_enable("mstp202"); /* VEU-1 */
-	clk_always_enable("mstp201"); /* VPU */
+	clk_always_enable("rsmem0"); /* RSMEM */
+	clk_always_enable("xymem0"); /* XYMEM */
+	clk_always_enable("veu1"); /* VEU-2 */
+	clk_always_enable("veu0"); /* VEU-1 */
+	clk_always_enable("vpu0"); /* VPU */
 
 	platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
 	platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ef77ee1d9f53..50cf6838ec41 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -62,7 +62,7 @@ static struct resource usbf_resources[] = {
 
 static struct platform_device usbf_device = {
 	.name		= "m66592_udc",
-	.id		= -1,
+	.id             = 0, /* "usbf0" clock */
 	.dev = {
 		.dma_mask		= NULL,
 		.coherent_dma_mask	= 0xffffffff,
@@ -87,6 +87,7 @@ static struct resource iic_resources[] = {
 
 static struct platform_device iic_device = {
 	.name           = "i2c-sh_mobile",
+	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
 };
@@ -147,6 +148,34 @@ static struct platform_device veu_device = {
 	.num_resources	= ARRAY_SIZE(veu_resources),
 };
 
+static struct uio_info jpu_platform_data = {
+	.name = "JPU",
+	.version = "0",
+	.irq = 27,
+};
+
+static struct resource jpu_resources[] = {
+	[0] = {
+		.name	= "JPU",
+		.start	= 0xfea00000,
+		.end	= 0xfea102d0,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device jpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 2,
+	.dev = {
+		.platform_data	= &jpu_platform_data,
+	},
+	.resource	= jpu_resources,
+	.num_resources	= ARRAY_SIZE(jpu_resources),
+};
+
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xffe00000,
@@ -186,24 +215,21 @@ static struct platform_device *sh7722_devices[] __initdata = {
 	&sci_device,
 	&vpu_device,
 	&veu_device,
+	&jpu_device,
 };
 
 static int __init sh7722_devices_setup(void)
 {
-	clk_always_enable("mstp031"); /* TLB */
-	clk_always_enable("mstp030"); /* IC */
-	clk_always_enable("mstp029"); /* OC */
-	clk_always_enable("mstp028"); /* URAM */
-	clk_always_enable("mstp026"); /* XYMEM */
-	clk_always_enable("mstp022"); /* INTC */
-	clk_always_enable("mstp020"); /* SuperHyway */
-	clk_always_enable("mstp109"); /* I2C */
-	clk_always_enable("mstp211"); /* USB */
-	clk_always_enable("mstp202"); /* VEU */
-	clk_always_enable("mstp201"); /* VPU */
+	clk_always_enable("uram0"); /* URAM */
+	clk_always_enable("xymem0"); /* XYMEM */
+	clk_always_enable("rtc0"); /* RTC */
+	clk_always_enable("veu0"); /* VEU */
+	clk_always_enable("vpu0"); /* VPU */
+	clk_always_enable("jpu0"); /* JPU */
 
 	platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
 	platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
+	platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
 
 	return platform_add_devices(sh7722_devices,
 				    ARRAY_SIZE(sh7722_devices));
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 6d9e6972cfc9..849770d780ae 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -215,6 +215,7 @@ static struct resource iic_resources[] = {
 
 static struct platform_device iic_device = {
 	.name           = "i2c-sh_mobile",
+	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
 };
@@ -231,19 +232,11 @@ static struct platform_device *sh7723_devices[] __initdata = {
 
 static int __init sh7723_devices_setup(void)
 {
-	clk_always_enable("mstp031"); /* TLB */
-	clk_always_enable("mstp030"); /* IC */
-	clk_always_enable("mstp029"); /* OC */
-	clk_always_enable("mstp024"); /* FPU */
-	clk_always_enable("mstp022"); /* INTC */
-	clk_always_enable("mstp020"); /* SuperHyway */
-	clk_always_enable("mstp000"); /* MERAM */
-	clk_always_enable("mstp109"); /* I2C */
-	clk_always_enable("mstp108"); /* RTC */
-	clk_always_enable("mstp211"); /* USB */
-	clk_always_enable("mstp206"); /* VEU2H1 */
-	clk_always_enable("mstp202"); /* VEU2H0 */
-	clk_always_enable("mstp201"); /* VPU */
+	clk_always_enable("meram0"); /* MERAM */
+	clk_always_enable("rtc0"); /* RTC */
+	clk_always_enable("veu1"); /* VEU2H1 */
+	clk_always_enable("veu0"); /* VEU2H0 */
+	clk_always_enable("vpu0"); /* VPU */
 
 	platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
 	platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 13b66746410a..591741383ee6 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -3,7 +3,7 @@
  *
  * Debug trap jump tables for SuperH
  *
- *  Copyright (C) 2006  Paul Mundt
+ *  Copyright (C) 2006 - 2008  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,12 +12,13 @@
 #include <linux/sys.h>
 #include <linux/linkage.h>
 
-#if !defined(CONFIG_SH_KGDB)
-#define kgdb_handle_exception	debug_trap_handler
+#if !defined(CONFIG_KGDB)
+#define breakpoint_trap_handler		debug_trap_handler
+#define singlestep_trap_handler		debug_trap_handler
 #endif
 
 #if !defined(CONFIG_SH_STANDARD_BIOS)
-#define sh_bios_handler		debug_trap_handler
+#define sh_bios_handler			debug_trap_handler
 #endif
 
 	.data
@@ -35,7 +36,7 @@ ENTRY(debug_trap_table)
 	.long debug_trap_handler	/* 0x39 */
 	.long debug_trap_handler	/* 0x3a */
 	.long debug_trap_handler	/* 0x3b */
-	.long kgdb_handle_exception	/* 0x3c */
-	.long debug_trap_handler	/* 0x3d */
+	.long breakpoint_trap_handler	/* 0x3c */
+	.long singlestep_trap_handler	/* 0x3d */
 	.long bug_trap_handler		/* 0x3e */
 	.long sh_bios_handler		/* 0x3f */
diff --git a/arch/sh/kernel/disassemble.c b/arch/sh/kernel/disassemble.c
new file mode 100644
index 000000000000..64d5d8dded7c
--- /dev/null
+++ b/arch/sh/kernel/disassemble.c
@@ -0,0 +1,573 @@
+/*
+ * Disassemble SuperH instructions.
+ *
+ * Copyright (C) 1999 kaz Kojima
+ * Copyright (C) 2008 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/kernel.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+
+/*
+ * Format of an instruction in memory.
+ */
+typedef enum {
+	HEX_0, HEX_1, HEX_2, HEX_3, HEX_4, HEX_5, HEX_6, HEX_7,
+	HEX_8, HEX_9, HEX_A, HEX_B, HEX_C, HEX_D, HEX_E, HEX_F,
+	REG_N, REG_M, REG_NM, REG_B,
+	BRANCH_12, BRANCH_8,
+	DISP_8, DISP_4,
+	IMM_4, IMM_4BY2, IMM_4BY4, PCRELIMM_8BY2, PCRELIMM_8BY4,
+	IMM_8, IMM_8BY2, IMM_8BY4,
+} sh_nibble_type;
+
+typedef enum {
+	A_END, A_BDISP12, A_BDISP8,
+	A_DEC_M, A_DEC_N,
+	A_DISP_GBR, A_DISP_PC, A_DISP_REG_M, A_DISP_REG_N,
+	A_GBR,
+	A_IMM,
+	A_INC_M, A_INC_N,
+	A_IND_M, A_IND_N, A_IND_R0_REG_M, A_IND_R0_REG_N,
+	A_MACH, A_MACL,
+	A_PR, A_R0, A_R0_GBR, A_REG_M, A_REG_N, A_REG_B,
+	A_SR, A_VBR, A_SSR, A_SPC, A_SGR, A_DBR,
+	F_REG_N, F_REG_M, D_REG_N, D_REG_M,
+	X_REG_N, /* Only used for argument parsing */
+	X_REG_M, /* Only used for argument parsing */
+	DX_REG_N, DX_REG_M, V_REG_N, V_REG_M,
+	FD_REG_N,
+	XMTRX_M4,
+	F_FR0,
+	FPUL_N, FPUL_M, FPSCR_N, FPSCR_M,
+} sh_arg_type;
+
+static struct sh_opcode_info {
+	char *name;
+	sh_arg_type arg[7];
+	sh_nibble_type nibbles[4];
+} sh_table[] = {
+	{"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
+	{"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
+	{"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
+	{"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
+	{"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
+	{"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
+	{"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
+	{"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
+	{"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
+	{"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
+	{"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
+	{"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+	{"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+	{"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+	{"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+	{"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
+	{"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
+	{"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
+	{"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
+	{"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
+	{"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
+	{"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
+	{"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
+	{"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
+	{"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
+	{"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
+	{"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
+	{"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
+	{"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
+	{"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
+	{"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
+	{"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
+	{"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}},
+	{"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}},
+	{"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
+	{"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
+	{"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
+	{"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
+	{"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
+	{"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
+	{"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
+	{"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}},
+	{"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
+	{"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
+	{"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
+	{"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
+	{"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
+	{"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
+	{"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}},
+	{"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
+	{"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
+	{"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
+	{"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
+	{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
+	{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
+	{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
+	{"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
+	{"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
+	{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
+	{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
+	{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
+	{"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
+	{"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
+	{"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
+	{"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}},
+	{"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
+	{"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
+	{"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}},
+	{"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
+	{"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}},
+	{"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
+	{"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
+	{"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
+	{"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
+	{"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
+	{"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}},
+	{"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}},
+	{"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
+	{"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}},
+	{"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
+	{"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
+	{"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}},
+	{"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}},
+	{"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}},
+	{"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
+	{"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}},
+	{"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
+	{"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
+	{"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
+	{"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
+	{"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
+	{"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}},
+	{"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}},
+	{"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}},
+	{"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}},
+	{"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
+	{"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
+	{"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
+	{"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
+	{"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
+	{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
+	{"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
+	{"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
+	{"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
+	{"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
+	{"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
+	{"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
+	{"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
+	{"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
+	{"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
+	{"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
+	{"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
+	{"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
+	{"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
+	{"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
+	{"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
+	{"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
+	{"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
+	{"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
+	{"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
+	{"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
+	{"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
+	{"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
+	{"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
+	{"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
+	{"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
+	{"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
+	{"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
+	{"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
+	{"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
+	{"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
+	{"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
+	{"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
+	{"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
+	{"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
+	{"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
+	{"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
+	{"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
+	{"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
+	{"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}},
+	{"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}},
+	{"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
+	{"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
+	{"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
+	{"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
+	{"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
+	{"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
+	{"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}},
+	{"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}},
+	{"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
+	{"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
+	{"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
+	{"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
+	{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
+	{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
+	{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
+	{"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
+	{"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
+	{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
+	{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
+	{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
+	{"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
+	{"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
+	{"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
+	{"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
+	{"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
+	{"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
+	{"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
+	{"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
+	{"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
+	{"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
+	{"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
+	{"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
+	{"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
+	{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
+	{"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
+	{"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
+	{"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
+	{"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
+	{"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
+	{"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
+	{"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
+	{"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
+	{"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
+	{"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
+	{"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
+	{"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
+	{"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
+	{"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
+	{"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
+	{"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
+	{"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
+	{"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
+	{"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}},
+	{"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
+	{"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
+	{"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
+	{"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}},
+	{"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
+	{"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
+	{"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+	{"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+	{"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+	{"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+	{"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+	{"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+	{"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+	{"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+	{"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+	{"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+	{"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+	{"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+	{"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+	{"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+	{"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+	{"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+	{"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+	{"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+	{"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+	{"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+	{"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+	{"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+	{"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+	{"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+	{"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
+	{"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
+	{"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
+	{"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
+	{"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
+	{"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
+	{"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}},
+	{"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
+	{"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
+	{"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
+	{"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
+	{ 0 },
+};
+
+static void print_sh_insn(u32 memaddr, u16 insn)
+{
+	int relmask = ~0;
+	int nibs[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, (insn >> 4) & 0xf, insn & 0xf};
+	int lastsp;
+	struct sh_opcode_info *op = sh_table;
+
+	for (; op->name; op++) {
+		int n;
+		int imm = 0;
+		int rn = 0;
+		int rm = 0;
+		int rb = 0;
+		int disp_pc;
+		int disp_pc_addr = 0;
+
+		for (n = 0; n < 4; n++) {
+			int i = op->nibbles[n];
+
+			if (i < 16) {
+				if (nibs[n] == i)
+					continue;
+				goto fail;
+			}
+			switch (i) {
+			case BRANCH_8:
+				imm = (nibs[2] << 4) | (nibs[3]);
+				if (imm & 0x80)
+					imm |= ~0xff;
+				imm = ((char)imm) * 2 + 4 ;
+				goto ok;
+			case BRANCH_12:
+				imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
+				if (imm & 0x800)
+					imm |= ~0xfff;
+				imm = imm * 2 + 4;
+				goto ok;
+			case IMM_4:
+				imm = nibs[3];
+				goto ok;
+			case IMM_4BY2:
+				imm = nibs[3] <<1;
+				goto ok;
+			case IMM_4BY4:
+				imm = nibs[3] <<2;
+				goto ok;
+			case IMM_8:
+				imm = (nibs[2] << 4) | nibs[3];
+				goto ok;
+			case PCRELIMM_8BY2:
+				imm = ((nibs[2] << 4) | nibs[3]) <<1;
+				relmask = ~1;
+				goto ok;
+			case PCRELIMM_8BY4:
+				imm = ((nibs[2] << 4) | nibs[3]) <<2;
+				relmask = ~3;
+				goto ok;
+			case IMM_8BY2:
+				imm = ((nibs[2] << 4) | nibs[3]) <<1;
+				goto ok;
+			case IMM_8BY4:
+				imm = ((nibs[2] << 4) | nibs[3]) <<2;
+				goto ok;
+			case DISP_8:
+				imm = (nibs[2] << 4) | (nibs[3]);
+				goto ok;
+			case DISP_4:
+				imm = nibs[3];
+				goto ok;
+			case REG_N:
+				rn = nibs[n];
+				break;
+			case REG_M:
+				rm = nibs[n];
+				break;
+			case REG_NM:
+				rn = (nibs[n] & 0xc) >> 2;
+				rm = (nibs[n] & 0x3);
+				break;
+			case REG_B:
+				rb = nibs[n] & 0x07;
+				break;
+			default:
+				return;
+			}
+		}
+
+	ok:
+		printk("%-8s  ", op->name);
+		lastsp = (op->arg[0] == A_END);
+		disp_pc = 0;
+		for (n = 0; n < 6 && op->arg[n] != A_END; n++) {
+			if (n && op->arg[1] != A_END)
+				printk(", ");
+			switch (op->arg[n]) {
+			case A_IMM:
+				printk("#%d", (char)(imm));
+				break;
+			case A_R0:
+				printk("r0");
+				break;
+			case A_REG_N:
+				printk("r%d", rn);
+				break;
+			case A_INC_N:
+				printk("@r%d+", rn);
+				break;
+			case A_DEC_N:
+				printk("@-r%d", rn);
+				break;
+			case A_IND_N:
+				printk("@r%d", rn);
+				break;
+			case A_DISP_REG_N:
+				printk("@(%d,r%d)", imm, rn);
+				break;
+			case A_REG_M:
+				printk("r%d", rm);
+				break;
+			case A_INC_M:
+				printk("@r%d+", rm);
+				break;
+			case A_DEC_M:
+				printk("@-r%d", rm);
+				break;
+			case A_IND_M:
+				printk("@r%d", rm);
+				break;
+			case A_DISP_REG_M:
+				printk("@(%d,r%d)", imm, rm);
+				break;
+			case A_REG_B:
+				printk("r%d_bank", rb);
+				break;
+			case A_DISP_PC:
+				disp_pc = 1;
+				disp_pc_addr = imm + 4 + (memaddr & relmask);
+				printk("%08x <%pS>", disp_pc_addr,
+				       (void *)disp_pc_addr);
+				break;
+			case A_IND_R0_REG_N:
+				printk("@(r0,r%d)", rn);
+				break;
+			case A_IND_R0_REG_M:
+				printk("@(r0,r%d)", rm);
+				break;
+			case A_DISP_GBR:
+				printk("@(%d,gbr)",imm);
+				break;
+			case A_R0_GBR:
+				printk("@(r0,gbr)");
+				break;
+			case A_BDISP12:
+			case A_BDISP8:
+				printk("%08x", imm + memaddr);
+				break;
+			case A_SR:
+				printk("sr");
+				break;
+			case A_GBR:
+				printk("gbr");
+				break;
+			case A_VBR:
+				printk("vbr");
+				break;
+			case A_SSR:
+				printk("ssr");
+				break;
+			case A_SPC:
+				printk("spc");
+				break;
+			case A_MACH:
+				printk("mach");
+				break;
+			case A_MACL:
+				printk("macl");
+				break;
+			case A_PR:
+				printk("pr");
+				break;
+			case A_SGR:
+				printk("sgr");
+				break;
+			case A_DBR:
+				printk("dbr");
+				break;
+			case FD_REG_N:
+				if (0)
+					goto d_reg_n;
+			case F_REG_N:
+				printk("fr%d", rn);
+				break;
+			case F_REG_M:
+				printk("fr%d", rm);
+				break;
+			case DX_REG_N:
+				if (rn & 1) {
+					printk("xd%d", rn & ~1);
+					break;
+				}
+			d_reg_n:
+			case D_REG_N:
+				printk("dr%d", rn);
+				break;
+			case DX_REG_M:
+				if (rm & 1) {
+					printk("xd%d", rm & ~1);
+					break;
+				}
+			case D_REG_M:
+				printk("dr%d", rm);
+				break;
+			case FPSCR_M:
+			case FPSCR_N:
+				printk("fpscr");
+				break;
+			case FPUL_M:
+			case FPUL_N:
+				printk("fpul");
+				break;
+			case F_FR0:
+				printk("fr0");
+				break;
+			case V_REG_N:
+				printk("fv%d", rn*4);
+				break;
+			case V_REG_M:
+				printk("fv%d", rm*4);
+				break;
+			case XMTRX_M4:
+				printk("xmtrx");
+				break;
+			default:
+				return;
+			}
+		}
+
+		if (disp_pc && strcmp(op->name, "mova") != 0) {
+			u32 val;
+
+			if (relmask == ~1)
+				__get_user(val, (u16 *)disp_pc_addr);
+			else
+				__get_user(val, (u32 *)disp_pc_addr);
+
+			printk("  ! %08x <%pS>", val, (void *)val);
+		}
+
+		return;
+	fail:
+		;
+
+	}
+
+	printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
+}
+
+void show_code(struct pt_regs *regs)
+{
+	unsigned short *pc = (unsigned short *)regs->pc;
+	long i;
+
+	if (regs->pc & 0x1)
+		return;
+
+	printk("Code:\n");
+
+	for (i = -3 ; i < 6 ; i++) {
+		unsigned short insn;
+
+		if (__get_user(insn, pc + i)) {
+			printk(" (Bad address in pc)\n");
+			break;
+		}
+
+		printk("%s%08lx:  ", (i ? "  ": "->"), (unsigned long)(pc + i));
+		print_sh_insn((unsigned long)(pc + i), insn);
+		printk("\n");
+	}
+
+	printk("\n");
+}
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 5b7efc4016fa..d62359cfbbe2 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -308,15 +308,19 @@ ENTRY(system_call)
 	mov.l	1f, r9
 	mov.l	@r9, r8		! Read from TRA (Trap Address) Register
 #endif
+
+	mov	#OFF_TRA, r10
+	add	r15, r10
+	mov.l	r8, @r10		! set TRA value to tra
+
 	/*
 	 * Check the trap type
 	 */
 	mov	#((0x20 << 2) - 1), r9
 	cmp/hi	r9, r8
 	bt/s	debug_trap		! it's a debug trap..
-	 mov	#OFF_TRA, r9
-	add	r15, r9
-	mov.l	r8, @r9			! set TRA value to tra
+	 nop
+
 #ifdef CONFIG_TRACE_IRQFLAGS
 	mov.l	5f, r10
 	jsr	@r10
@@ -371,47 +375,3 @@ syscall_exit:
 #endif
 7:	.long	do_syscall_trace_enter
 8:	.long	do_syscall_trace_leave
-
-#ifdef CONFIG_FUNCTION_TRACER
-	.align 2
-	.globl	_mcount
-	.type	_mcount,@function
-	.globl	mcount
-	.type	mcount,@function
-_mcount:
-mcount:
-	mov.l	r4, @-r15
-	mov.l	r5, @-r15
-	mov.l	r6, @-r15
-	mov.l	r7, @-r15
-	sts.l	pr, @-r15
-
-	mov.l	@(20,r15),r4
-	sts	pr, r5
-
-	mov.l	1f, r6
-	mov.l	ftrace_stub, r7	
-	cmp/eq	r6, r7
-	bt	skip_trace
-
-	mov.l	@r6, r6
-	jsr	@r6
-	 nop
-
-skip_trace:
-
-	lds.l	@r15+, pr
-	mov.l	@r15+, r7
-	mov.l	@r15+, r6
-	mov.l	@r15+, r5
-	rts
-	 mov.l	@r15+, r4
-
-	.align 2
-1:	.long	ftrace_trace_function
-
-	.globl	ftrace_stub
-ftrace_stub:
-	rts
-	 nop
-#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
new file mode 100644
index 000000000000..4c3247477aa3
--- /dev/null
+++ b/arch/sh/kernel/ftrace.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 Matt Fleming <mjf@gentoo.org>
+ * Copyright (C) 2008 Paul Mundt <lethal@linux-sh.org>
+ *
+ * Code for replacing ftrace calls with jumps.
+ *
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * Thanks goes to Ingo Molnar, for suggesting the idea.
+ * Mathieu Desnoyers, for suggesting postponing the modifications.
+ * Arjan van de Ven, for keeping me straight, and explaining to me
+ * the dangers of modifying code on the run.
+ */
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/ftrace.h>
+#include <asm/cacheflush.h>
+
+static unsigned char ftrace_nop[] = {
+	0x09, 0x00,		/* nop */
+	0x09, 0x00,		/* nop */
+};
+
+static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
+
+unsigned char *ftrace_nop_replace(void)
+{
+	return ftrace_nop;
+}
+
+static int is_sh_nop(unsigned char *ip)
+{
+	return strncmp(ip, ftrace_nop, sizeof(ftrace_nop));
+}
+
+unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+{
+	/* Place the address in the memory table. */
+	if (addr == CALLER_ADDR)
+		__raw_writel(addr + MCOUNT_INSN_OFFSET, ftrace_replaced_code);
+	else
+		__raw_writel(addr, ftrace_replaced_code);
+
+	/*
+	 * No locking needed, this must be called via kstop_machine
+	 * which in essence is like running on a uniprocessor machine.
+	 */
+	return ftrace_replaced_code;
+}
+
+int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
+		       unsigned char *new_code)
+{
+	unsigned char replaced[MCOUNT_INSN_SIZE];
+
+	/*
+	 * Note: Due to modules and __init, code can
+	 *  disappear and change, we need to protect against faulting
+	 *  as well as code changing. We do this by using the
+	 *  probe_kernel_* functions.
+	 *
+	 * No real locking needed, this code is run through
+	 * kstop_machine, or before SMP starts.
+	 */
+
+	/*
+	 * If we're trying to nop out a call to a function, we instead
+	 * place a call to the address after the memory table.
+	 */
+	if (is_sh_nop(new_code) == 0)
+		__raw_writel(ip + MCOUNT_INSN_SIZE, (unsigned long)new_code);
+
+	/* read the text we want to modify */
+	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+
+	/* Make sure it is what we expect it to be */
+	if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+		return -EINVAL;
+
+	/* replace the text with the new text */
+	if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
+		return -EPERM;
+
+	flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
+
+	return 0;
+}
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+	unsigned long ip = (unsigned long)(&ftrace_call);
+	unsigned char old[MCOUNT_INSN_SIZE], *new;
+
+	memcpy(old, (unsigned char *)(ip + MCOUNT_INSN_OFFSET), MCOUNT_INSN_SIZE);
+	new = ftrace_call_replace(ip, (unsigned long)func);
+
+	return ftrace_modify_code(ip + MCOUNT_INSN_OFFSET, old, new);
+}
+
+int ftrace_make_nop(struct module *mod,
+		    struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned char *new, *old;
+	unsigned long ip = rec->ip;
+
+	old = ftrace_call_replace(ip, addr);
+	new = ftrace_nop_replace();
+
+	return ftrace_modify_code(rec->ip, old, new);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned char *new, *old;
+	unsigned long ip = rec->ip;
+
+	old = ftrace_nop_replace();
+	new = ftrace_call_replace(ip, addr);
+
+	return ftrace_modify_code(rec->ip, old, new);
+}
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+	/* The return code is retured via data */
+	__raw_writel(0, (unsigned long)data);
+
+	return 0;
+}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index ae0a382a82eb..788605ff7088 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -80,8 +80,14 @@ ENTRY(_stext)
 	mov.l	7f, r0
 	ldc	r0, r7_bank	! ... and initial thread_info
 #endif
-	
-	!			Clear BSS area
+
+#ifndef CONFIG_SH_NO_BSS_INIT
+	/*
+	 * Don't clear BSS if running on slow platforms such as an RTL simulation,
+	 * remote memory via SHdebug link, etc.  For these the memory can be guaranteed
+	 * to be all zero on boot anyway.
+	 */
+				! Clear BSS area
 #ifdef CONFIG_SMP	
 	mov.l	3f, r0
 	cmp/eq	#0, r0		! skip clear if set to zero
@@ -97,6 +103,8 @@ ENTRY(_stext)
 	 mov.l	r0,@-r2
 
 10:		
+#endif
+
 	!			Additional CPU initialization
 	mov.l	6f, r0
 	jsr	@r0
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
new file mode 100644
index 000000000000..fe59ccfc1152
--- /dev/null
+++ b/arch/sh/kernel/idle.c
@@ -0,0 +1,81 @@
+/*
+ * The idle loop for all SuperH platforms.
+ *
+ *  Copyright (C) 2002 - 2008  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/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/pm.h>
+#include <linux/tick.h>
+#include <linux/preempt.h>
+#include <linux/thread_info.h>
+#include <linux/irqflags.h>
+#include <asm/pgalloc.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+static int hlt_counter;
+void (*pm_idle)(void);
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 1;
+}
+__setup("hlt", hlt_setup);
+
+static void default_idle(void)
+{
+	if (!hlt_counter) {
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+		smp_mb__after_clear_bit();
+		set_bl_bit();
+		stop_critical_timings();
+
+		while (!need_resched())
+			cpu_sleep();
+
+		start_critical_timings();
+		clear_bl_bit();
+		set_thread_flag(TIF_POLLING_NRFLAG);
+	} else
+		while (!need_resched())
+			cpu_relax();
+}
+
+void cpu_idle(void)
+{
+	set_thread_flag(TIF_POLLING_NRFLAG);
+
+	/* endless idle loop with no priority at all */
+	while (1) {
+		void (*idle)(void) = pm_idle;
+
+		if (!idle)
+			idle = default_idle;
+
+		tick_nohz_stop_sched_tick(1);
+		while (!need_resched())
+			idle();
+		tick_nohz_restart_sched_tick();
+
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+		check_pgt_cache();
+	}
+}
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
new file mode 100644
index 000000000000..7c747e7d71b8
--- /dev/null
+++ b/arch/sh/kernel/kgdb.c
@@ -0,0 +1,285 @@
+/*
+ * SuperH KGDB support
+ *
+ * Copyright (C) 2008  Paul Mundt
+ *
+ * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
+ *
+ * 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/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+char in_nmi = 0;	/* Set during NMI to prevent re-entry */
+
+/* Macros for single step instruction identification */
+#define OPCODE_BT(op)		(((op) & 0xff00) == 0x8900)
+#define OPCODE_BF(op)		(((op) & 0xff00) == 0x8b00)
+#define OPCODE_BTF_DISP(op)	(((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
+				 (((op) & 0x7f ) << 1))
+#define OPCODE_BFS(op)		(((op) & 0xff00) == 0x8f00)
+#define OPCODE_BTS(op)		(((op) & 0xff00) == 0x8d00)
+#define OPCODE_BRA(op)		(((op) & 0xf000) == 0xa000)
+#define OPCODE_BRA_DISP(op)	(((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+				 (((op) & 0x7ff) << 1))
+#define OPCODE_BRAF(op)		(((op) & 0xf0ff) == 0x0023)
+#define OPCODE_BRAF_REG(op)	(((op) & 0x0f00) >> 8)
+#define OPCODE_BSR(op)		(((op) & 0xf000) == 0xb000)
+#define OPCODE_BSR_DISP(op)	(((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+				 (((op) & 0x7ff) << 1))
+#define OPCODE_BSRF(op)		(((op) & 0xf0ff) == 0x0003)
+#define OPCODE_BSRF_REG(op)	(((op) >> 8) & 0xf)
+#define OPCODE_JMP(op)		(((op) & 0xf0ff) == 0x402b)
+#define OPCODE_JMP_REG(op)	(((op) >> 8) & 0xf)
+#define OPCODE_JSR(op)		(((op) & 0xf0ff) == 0x400b)
+#define OPCODE_JSR_REG(op)	(((op) >> 8) & 0xf)
+#define OPCODE_RTS(op)		((op) == 0xb)
+#define OPCODE_RTE(op)		((op) == 0x2b)
+
+#define SR_T_BIT_MASK           0x1
+#define STEP_OPCODE             0xc33d
+
+/* Calculate the new address for after a step */
+static short *get_step_address(struct pt_regs *linux_regs)
+{
+	opcode_t op = __raw_readw(linux_regs->pc);
+	long addr;
+
+	/* BT */
+	if (OPCODE_BT(op)) {
+		if (linux_regs->sr & SR_T_BIT_MASK)
+			addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = linux_regs->pc + 2;
+	}
+
+	/* BTS */
+	else if (OPCODE_BTS(op)) {
+		if (linux_regs->sr & SR_T_BIT_MASK)
+			addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = linux_regs->pc + 4;	/* Not in delay slot */
+	}
+
+	/* BF */
+	else if (OPCODE_BF(op)) {
+		if (!(linux_regs->sr & SR_T_BIT_MASK))
+			addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = linux_regs->pc + 2;
+	}
+
+	/* BFS */
+	else if (OPCODE_BFS(op)) {
+		if (!(linux_regs->sr & SR_T_BIT_MASK))
+			addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = linux_regs->pc + 4;	/* Not in delay slot */
+	}
+
+	/* BRA */
+	else if (OPCODE_BRA(op))
+		addr = linux_regs->pc + 4 + OPCODE_BRA_DISP(op);
+
+	/* BRAF */
+	else if (OPCODE_BRAF(op))
+		addr = linux_regs->pc + 4
+		    + linux_regs->regs[OPCODE_BRAF_REG(op)];
+
+	/* BSR */
+	else if (OPCODE_BSR(op))
+		addr = linux_regs->pc + 4 + OPCODE_BSR_DISP(op);
+
+	/* BSRF */
+	else if (OPCODE_BSRF(op))
+		addr = linux_regs->pc + 4
+		    + linux_regs->regs[OPCODE_BSRF_REG(op)];
+
+	/* JMP */
+	else if (OPCODE_JMP(op))
+		addr = linux_regs->regs[OPCODE_JMP_REG(op)];
+
+	/* JSR */
+	else if (OPCODE_JSR(op))
+		addr = linux_regs->regs[OPCODE_JSR_REG(op)];
+
+	/* RTS */
+	else if (OPCODE_RTS(op))
+		addr = linux_regs->pr;
+
+	/* RTE */
+	else if (OPCODE_RTE(op))
+		addr = linux_regs->regs[15];
+
+	/* Other */
+	else
+		addr = linux_regs->pc + instruction_size(op);
+
+	flush_icache_range(addr, addr + instruction_size(op));
+	return (short *)addr;
+}
+
+/*
+ * Replace the instruction immediately after the current instruction
+ * (i.e. next in the expected flow of control) with a trap instruction,
+ * so that returning will cause only a single instruction to be executed.
+ * Note that this model is slightly broken for instructions with delay
+ * slots (e.g. B[TF]S, BSR, BRA etc), where both the branch and the
+ * instruction in the delay slot will be executed.
+ */
+
+static unsigned long stepped_address;
+static opcode_t stepped_opcode;
+
+static void do_single_step(struct pt_regs *linux_regs)
+{
+	/* Determine where the target instruction will send us to */
+	unsigned short *addr = get_step_address(linux_regs);
+
+	stepped_address = (int)addr;
+
+	/* Replace it */
+	stepped_opcode = __raw_readw((long)addr);
+	*addr = STEP_OPCODE;
+
+	/* Flush and return */
+	flush_icache_range((long)addr, (long)addr +
+			   instruction_size(stepped_opcode));
+}
+
+/* Undo a single step */
+static void undo_single_step(struct pt_regs *linux_regs)
+{
+	/* If we have stepped, put back the old instruction */
+	/* Use stepped_address in case we stopped elsewhere */
+	if (stepped_opcode != 0) {
+		__raw_writew(stepped_opcode, stepped_address);
+		flush_icache_range(stepped_address, stepped_address + 2);
+	}
+
+	stepped_opcode = 0;
+}
+
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		gdb_regs[GDB_R0 + i] = regs->regs[i];
+
+	gdb_regs[GDB_PC] = regs->pc;
+	gdb_regs[GDB_PR] = regs->pr;
+	gdb_regs[GDB_SR] = regs->sr;
+	gdb_regs[GDB_GBR] = regs->gbr;
+	gdb_regs[GDB_MACH] = regs->mach;
+	gdb_regs[GDB_MACL] = regs->macl;
+
+	__asm__ __volatile__ ("stc vbr, %0" : "=r" (gdb_regs[GDB_VBR]));
+}
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		regs->regs[GDB_R0 + i] = gdb_regs[GDB_R0 + i];
+
+	regs->pc = gdb_regs[GDB_PC];
+	regs->pr = gdb_regs[GDB_PR];
+	regs->sr = gdb_regs[GDB_SR];
+	regs->gbr = gdb_regs[GDB_GBR];
+	regs->mach = gdb_regs[GDB_MACH];
+	regs->macl = gdb_regs[GDB_MACL];
+
+	__asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+	gdb_regs[GDB_R15] = p->thread.sp;
+	gdb_regs[GDB_PC] = p->thread.pc;
+}
+
+int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
+			       char *remcomInBuffer, char *remcomOutBuffer,
+			       struct pt_regs *linux_regs)
+{
+	unsigned long addr;
+	char *ptr;
+
+	/* Undo any stepping we may have done */
+	undo_single_step(linux_regs);
+
+	switch (remcomInBuffer[0]) {
+	case 'c':
+	case 's':
+		/* try to read optional parameter, pc unchanged if no parm */
+		ptr = &remcomInBuffer[1];
+		if (kgdb_hex2long(&ptr, &addr))
+			linux_regs->pc = addr;
+	case 'D':
+	case 'k':
+		atomic_set(&kgdb_cpu_doing_single_step, -1);
+
+		if (remcomInBuffer[0] == 's') {
+			do_single_step(linux_regs);
+			kgdb_single_step = 1;
+
+			atomic_set(&kgdb_cpu_doing_single_step,
+				   raw_smp_processor_id());
+		}
+
+		return 0;
+	}
+
+	/* this means that we do not want to exit from the handler: */
+	return -1;
+}
+
+/*
+ * The primary entry points for the kgdb debug trap table entries.
+ */
+BUILD_TRAP_HANDLER(singlestep)
+{
+	unsigned long flags;
+	TRAP_HANDLER_DECL;
+
+	local_irq_save(flags);
+	regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
+	kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+	local_irq_restore(flags);
+}
+
+
+BUILD_TRAP_HANDLER(breakpoint)
+{
+	unsigned long flags;
+	TRAP_HANDLER_DECL;
+
+	local_irq_save(flags);
+	kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+	local_irq_restore(flags);
+}
+
+int kgdb_arch_init(void)
+{
+	return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+	/* Breakpoint instruction: trapa #0x3c */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	.gdb_bpt_instr		= { 0x3c, 0xc3 },
+#else
+	.gdb_bpt_instr		= { 0xc3, 0x3c },
+#endif
+};
diff --git a/arch/sh/kernel/kgdb_jmp.S b/arch/sh/kernel/kgdb_jmp.S
deleted file mode 100644
index 339bb1d7ff0b..000000000000
--- a/arch/sh/kernel/kgdb_jmp.S
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <linux/linkage.h>
-
-ENTRY(setjmp)
-	add	#(9*4), r4
-	sts.l	pr, @-r4
-	mov.l	r15, @-r4
-	mov.l	r14, @-r4
-	mov.l	r13, @-r4
-	mov.l	r12, @-r4
-	mov.l	r11, @-r4
-	mov.l	r10, @-r4
-	mov.l	r9, @-r4
-	mov.l	r8, @-r4
-	rts
-	 mov	#0, r0
-
-ENTRY(longjmp)
-	mov.l	@r4+, r8
-	mov.l	@r4+, r9
-	mov.l	@r4+, r10
-	mov.l	@r4+, r11
-	mov.l	@r4+, r12
-	mov.l	@r4+, r13
-	mov.l	@r4+, r14
-	mov.l	@r4+, r15
-	lds.l	@r4+, pr
-	mov	r5, r0
-	tst	r0, r0
-	bf	1f
-	mov	#1, r0	! in case val==0
-1:	rts
-	 nop
-
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
deleted file mode 100644
index bf8ac4c71640..000000000000
--- a/arch/sh/kernel/kgdb_stub.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Contains extracts from code by Glenn Engel, Jim Kingdon,
- * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
- * Amit S. Kale <akale@veritas.com>,  William Gatliff <bgat@open-widgets.com>,
- * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
- *
- * This version by Henry Bell <henry.bell@st.com>
- * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
- *
- * Contains low-level support for remote debug using GDB.
- *
- * To enable debugger support, two things need to happen. A call to
- * set_debug_traps() is necessary in order to allow any breakpoints
- * or error conditions to be properly intercepted and reported to gdb.
- * A breakpoint also needs to be generated to begin communication.  This
- * is most easily accomplished by a call to breakpoint() which does
- * a trapa if the initialisation phase has been successfully completed.
- *
- * In this case, set_debug_traps() is not used to "take over" exceptions;
- * other kernel code is modified instead to enter the kgdb functions here
- * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
- * see traps.c for kernel error exceptions).
- *
- * The following gdb commands are supported:
- *
- *    Command       Function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *    XAA..AA,LLLL: Same, but data is binary (not hex)     OK or ENN
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *    CNN;          Resume at current address with signal  SNN
- *    CNN;AA..AA    Resume at address AA..AA with signal   SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *    SNN;          Step one instruction with signal       SNN
- *    SNNAA..AA     Step one instruction from AA..AA w/NN  SNN
- *
- *    k             kill (Detach GDB)
- *
- *    d             Toggle debug flag
- *    D             Detach GDB
- *
- *    Hct           Set thread t for operations,           OK or ENN
- *                  c = 'c' (step, cont), c = 'g' (other
- *                  operations)
- *
- *    qC            Query current thread ID                QCpid
- *    qfThreadInfo  Get list of current threads (first)    m<id>
- *    qsThreadInfo   "    "  "     "      "   (subsequent)
- *    qOffsets      Get section offsets                  Text=x;Data=y;Bss=z
- *
- *    TXX           Find if thread XX is alive             OK or ENN
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *    O             Output to GDB console
- *
- * Remote communication protocol.
- *
- *    A debug packet whose contents are <data> is encapsulated for
- *    transmission in the form:
- *
- *       $ <data> # CSUM1 CSUM2
- *
- *       <data> must be ASCII alphanumeric and cannot include characters
- *       '$' or '#'.  If <data> starts with two characters followed by
- *       ':', then the existing stubs interpret this as a sequence number.
- *
- *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
- *       checksum of <data>, the most significant nibble is sent first.
- *       the hex digits 0-9,a-f are used.
- *
- *    Receiver responds with:
- *
- *       +       - if CSUM is correct and ready for next packet
- *       -       - if CSUM is incorrect
- *
- * Responses can be run-length encoded to save space.  A '*' means that
- * the next character is an ASCII encoding giving a repeat count which
- * stands for that many repetitions of the character preceding the '*'.
- * The encoding is n+29, yielding a printable character where n >=3
- * (which is where RLE starts to win).  Don't use an n > 126.
- *
- * So "0* " means the same as "0000".
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/module.h>
-#include <asm/system.h>
-#include <asm/cacheflush.h>
-#include <asm/current.h>
-#include <asm/signal.h>
-#include <asm/pgtable.h>
-#include <asm/ptrace.h>
-#include <asm/kgdb.h>
-#include <asm/io.h>
-
-/* Function pointers for linkage */
-kgdb_debug_hook_t *kgdb_debug_hook;
-kgdb_bus_error_hook_t *kgdb_bus_err_hook;
-
-int (*kgdb_getchar)(void);
-EXPORT_SYMBOL_GPL(kgdb_getchar);
-void (*kgdb_putchar)(int);
-EXPORT_SYMBOL_GPL(kgdb_putchar);
-
-static void put_debug_char(int c)
-{
-	if (!kgdb_putchar)
-		return;
-	(*kgdb_putchar)(c);
-}
-static int get_debug_char(void)
-{
-	if (!kgdb_getchar)
-		return -1;
-	return (*kgdb_getchar)();
-}
-
-/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
-#define BUFMAX 1024
-#define NUMREGBYTES (MAXREG*4)
-#define OUTBUFMAX (NUMREGBYTES*2+512)
-
-enum {
-	R0 = 0, R1,  R2,  R3,   R4,   R5,  R6, R7,
-	R8, R9, R10, R11, R12,  R13,  R14, R15,
-	PC, PR, GBR, VBR, MACH, MACL, SR,
-	/*  */
-	MAXREG
-};
-
-static unsigned int registers[MAXREG];
-struct kgdb_regs trap_registers;
-
-char kgdb_in_gdb_mode;
-char in_nmi;			/* Set during NMI to prevent reentry */
-int kgdb_nofault;		/* Boolean to ignore bus errs (i.e. in GDB) */
-
-/* Default values for SCI (can override via kernel args in setup.c) */
-#ifndef CONFIG_KGDB_DEFPORT
-#define CONFIG_KGDB_DEFPORT 1
-#endif
-
-#ifndef CONFIG_KGDB_DEFBAUD
-#define CONFIG_KGDB_DEFBAUD 115200
-#endif
-
-#if defined(CONFIG_KGDB_DEFPARITY_E)
-#define CONFIG_KGDB_DEFPARITY 'E'
-#elif defined(CONFIG_KGDB_DEFPARITY_O)
-#define CONFIG_KGDB_DEFPARITY 'O'
-#else /* CONFIG_KGDB_DEFPARITY_N */
-#define CONFIG_KGDB_DEFPARITY 'N'
-#endif
-
-#ifdef CONFIG_KGDB_DEFBITS_7
-#define CONFIG_KGDB_DEFBITS '7'
-#else /* CONFIG_KGDB_DEFBITS_8 */
-#define CONFIG_KGDB_DEFBITS '8'
-#endif
-
-/* SCI/UART settings, used in kgdb_console_setup() */
-int  kgdb_portnum = CONFIG_KGDB_DEFPORT;
-EXPORT_SYMBOL_GPL(kgdb_portnum);
-int  kgdb_baud = CONFIG_KGDB_DEFBAUD;
-EXPORT_SYMBOL_GPL(kgdb_baud);
-char kgdb_parity = CONFIG_KGDB_DEFPARITY;
-EXPORT_SYMBOL_GPL(kgdb_parity);
-char kgdb_bits = CONFIG_KGDB_DEFBITS;
-EXPORT_SYMBOL_GPL(kgdb_bits);
-
-/* Jump buffer for setjmp/longjmp */
-static jmp_buf rem_com_env;
-
-/* TRA differs sh3/4 */
-#if defined(CONFIG_CPU_SH3)
-#define TRA 0xffffffd0
-#elif defined(CONFIG_CPU_SH4)
-#define TRA 0xff000020
-#endif
-
-/* Macros for single step instruction identification */
-#define OPCODE_BT(op)         (((op) & 0xff00) == 0x8900)
-#define OPCODE_BF(op)         (((op) & 0xff00) == 0x8b00)
-#define OPCODE_BTF_DISP(op)   (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
-			      (((op) & 0x7f ) << 1))
-#define OPCODE_BFS(op)        (((op) & 0xff00) == 0x8f00)
-#define OPCODE_BTS(op)        (((op) & 0xff00) == 0x8d00)
-#define OPCODE_BRA(op)        (((op) & 0xf000) == 0xa000)
-#define OPCODE_BRA_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
-			      (((op) & 0x7ff) << 1))
-#define OPCODE_BRAF(op)       (((op) & 0xf0ff) == 0x0023)
-#define OPCODE_BRAF_REG(op)   (((op) & 0x0f00) >> 8)
-#define OPCODE_BSR(op)        (((op) & 0xf000) == 0xb000)
-#define OPCODE_BSR_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
-			      (((op) & 0x7ff) << 1))
-#define OPCODE_BSRF(op)       (((op) & 0xf0ff) == 0x0003)
-#define OPCODE_BSRF_REG(op)   (((op) >> 8) & 0xf)
-#define OPCODE_JMP(op)        (((op) & 0xf0ff) == 0x402b)
-#define OPCODE_JMP_REG(op)    (((op) >> 8) & 0xf)
-#define OPCODE_JSR(op)        (((op) & 0xf0ff) == 0x400b)
-#define OPCODE_JSR_REG(op)    (((op) >> 8) & 0xf)
-#define OPCODE_RTS(op)        ((op) == 0xb)
-#define OPCODE_RTE(op)        ((op) == 0x2b)
-
-#define SR_T_BIT_MASK           0x1
-#define STEP_OPCODE             0xc320
-#define BIOS_CALL_TRAP          0x3f
-
-/* Exception codes as per SH-4 core manual */
-#define ADDRESS_ERROR_LOAD_VEC   7
-#define ADDRESS_ERROR_STORE_VEC  8
-#define TRAP_VEC                 11
-#define INVALID_INSN_VEC         12
-#define INVALID_SLOT_VEC         13
-#define NMI_VEC                  14
-#define USER_BREAK_VEC           15
-#define SERIAL_BREAK_VEC         58
-
-/* Misc static */
-static int stepped_address;
-static short stepped_opcode;
-static char in_buffer[BUFMAX];
-static char out_buffer[OUTBUFMAX];
-
-static void kgdb_to_gdb(const char *s);
-
-/* Convert ch to hex */
-static int hex(const char ch)
-{
-	if ((ch >= 'a') && (ch <= 'f'))
-		return (ch - 'a' + 10);
-	if ((ch >= '0') && (ch <= '9'))
-		return (ch - '0');
-	if ((ch >= 'A') && (ch <= 'F'))
-		return (ch - 'A' + 10);
-	return (-1);
-}
-
-/* Convert the memory pointed to by mem into hex, placing result in buf.
-   Returns a pointer to the last char put in buf (null) */
-static char *mem_to_hex(const char *mem, char *buf, const int count)
-{
-	int i;
-	int ch;
-	unsigned short s_val;
-	unsigned long l_val;
-
-	/* Check for 16 or 32 */
-	if (count == 2 && ((long) mem & 1) == 0) {
-		s_val = *(unsigned short *) mem;
-		mem = (char *) &s_val;
-	} else if (count == 4 && ((long) mem & 3) == 0) {
-		l_val = *(unsigned long *) mem;
-		mem = (char *) &l_val;
-	}
-	for (i = 0; i < count; i++) {
-		ch = *mem++;
-		buf = pack_hex_byte(buf, ch);
-	}
-	*buf = 0;
-	return (buf);
-}
-
-/* Convert the hex array pointed to by buf into binary, to be placed in mem.
-   Return a pointer to the character after the last byte written */
-static char *hex_to_mem(const char *buf, char *mem, const int count)
-{
-	int i;
-	unsigned char ch;
-
-	for (i = 0; i < count; i++) {
-		ch = hex(*buf++) << 4;
-		ch = ch + hex(*buf++);
-		*mem++ = ch;
-	}
-	return (mem);
-}
-
-/* While finding valid hex chars, convert to an integer, then return it */
-static int hex_to_int(char **ptr, int *int_value)
-{
-	int num_chars = 0;
-	int hex_value;
-
-	*int_value = 0;
-
-	while (**ptr) {
-		hex_value = hex(**ptr);
-		if (hex_value >= 0) {
-			*int_value = (*int_value << 4) | hex_value;
-			num_chars++;
-		} else
-			break;
-		(*ptr)++;
-	}
-	return num_chars;
-}
-
-/*  Copy the binary array pointed to by buf into mem.  Fix $, #,
-    and 0x7d escaped with 0x7d.  Return a pointer to the character
-    after the last byte written. */
-static char *ebin_to_mem(const char *buf, char *mem, int count)
-{
-	for (; count > 0; count--, buf++) {
-		if (*buf == 0x7d)
-			*mem++ = *(++buf) ^ 0x20;
-		else
-			*mem++ = *buf;
-	}
-	return mem;
-}
-
-/* Scan for the start char '$', read the packet and check the checksum */
-static void get_packet(char *buffer, int buflen)
-{
-	unsigned char checksum;
-	unsigned char xmitcsum;
-	int i;
-	int count;
-	char ch;
-
-	do {
-		/* Ignore everything until the start character */
-		while ((ch = get_debug_char()) != '$');
-
-		checksum = 0;
-		xmitcsum = -1;
-		count = 0;
-
-		/* Now, read until a # or end of buffer is found */
-		while (count < (buflen - 1)) {
-			ch = get_debug_char();
-
-			if (ch == '#')
-				break;
-
-			checksum = checksum + ch;
-			buffer[count] = ch;
-			count = count + 1;
-		}
-
-		buffer[count] = 0;
-
-		/* Continue to read checksum following # */
-		if (ch == '#') {
-			xmitcsum = hex(get_debug_char()) << 4;
-			xmitcsum += hex(get_debug_char());
-
-			/* Checksum */
-			if (checksum != xmitcsum)
-				put_debug_char('-');	/* Failed checksum */
-			else {
-				/* Ack successful transfer */
-				put_debug_char('+');
-
-				/* If a sequence char is present, reply
-				   the sequence ID */
-				if (buffer[2] == ':') {
-					put_debug_char(buffer[0]);
-					put_debug_char(buffer[1]);
-
-					/* Remove sequence chars from buffer */
-					count = strlen(buffer);
-					for (i = 3; i <= count; i++)
-						buffer[i - 3] = buffer[i];
-				}
-			}
-		}
-	}
-	while (checksum != xmitcsum);	/* Keep trying while we fail */
-}
-
-/* Send the packet in the buffer with run-length encoding */
-static void put_packet(char *buffer)
-{
-	int checksum;
-	char *src;
-	int runlen;
-	int encode;
-
-	do {
-		src = buffer;
-		put_debug_char('$');
-		checksum = 0;
-
-		/* Continue while we still have chars left */
-		while (*src) {
-			/* Check for runs up to 99 chars long */
-			for (runlen = 1; runlen < 99; runlen++) {
-				if (src[0] != src[runlen])
-					break;
-			}
-
-			if (runlen > 3) {
-				/* Got a useful amount, send encoding */
-				encode = runlen + ' ' - 4;
-				put_debug_char(*src);   checksum += *src;
-				put_debug_char('*');    checksum += '*';
-				put_debug_char(encode); checksum += encode;
-				src += runlen;
-			} else {
-				/* Otherwise just send the current char */
-				put_debug_char(*src);   checksum += *src;
-				src += 1;
-			}
-		}
-
-		/* '#' Separator, put high and low components of checksum */
-		put_debug_char('#');
-		put_debug_char(hex_asc_hi(checksum));
-		put_debug_char(hex_asc_lo(checksum));
-	}
-	while ((get_debug_char()) != '+');	/* While no ack */
-}
-
-/* A bus error has occurred - perform a longjmp to return execution and
-   allow handling of the error */
-static void kgdb_handle_bus_error(void)
-{
-	longjmp(rem_com_env, 1);
-}
-
-/* Translate SH-3/4 exception numbers to unix-like signal values */
-static int compute_signal(const int excep_code)
-{
-	int sigval;
-
-	switch (excep_code) {
-
-	case INVALID_INSN_VEC:
-	case INVALID_SLOT_VEC:
-		sigval = SIGILL;
-		break;
-	case ADDRESS_ERROR_LOAD_VEC:
-	case ADDRESS_ERROR_STORE_VEC:
-		sigval = SIGSEGV;
-		break;
-
-	case SERIAL_BREAK_VEC:
-	case NMI_VEC:
-		sigval = SIGINT;
-		break;
-
-	case USER_BREAK_VEC:
-	case TRAP_VEC:
-		sigval = SIGTRAP;
-		break;
-
-	default:
-		sigval = SIGBUS;	/* "software generated" */
-		break;
-	}
-
-	return (sigval);
-}
-
-/* Make a local copy of the registers passed into the handler (bletch) */
-static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
-				  int *gdb_regs)
-{
-	gdb_regs[R0] = regs->regs[R0];
-	gdb_regs[R1] = regs->regs[R1];
-	gdb_regs[R2] = regs->regs[R2];
-	gdb_regs[R3] = regs->regs[R3];
-	gdb_regs[R4] = regs->regs[R4];
-	gdb_regs[R5] = regs->regs[R5];
-	gdb_regs[R6] = regs->regs[R6];
-	gdb_regs[R7] = regs->regs[R7];
-	gdb_regs[R8] = regs->regs[R8];
-	gdb_regs[R9] = regs->regs[R9];
-	gdb_regs[R10] = regs->regs[R10];
-	gdb_regs[R11] = regs->regs[R11];
-	gdb_regs[R12] = regs->regs[R12];
-	gdb_regs[R13] = regs->regs[R13];
-	gdb_regs[R14] = regs->regs[R14];
-	gdb_regs[R15] = regs->regs[R15];
-	gdb_regs[PC] = regs->pc;
-	gdb_regs[PR] = regs->pr;
-	gdb_regs[GBR] = regs->gbr;
-	gdb_regs[MACH] = regs->mach;
-	gdb_regs[MACL] = regs->macl;
-	gdb_regs[SR] = regs->sr;
-	gdb_regs[VBR] = regs->vbr;
-}
-
-/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
-static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
-				  struct kgdb_regs *regs)
-{
-	regs->regs[R0] = gdb_regs[R0];
-	regs->regs[R1] = gdb_regs[R1];
-	regs->regs[R2] = gdb_regs[R2];
-	regs->regs[R3] = gdb_regs[R3];
-	regs->regs[R4] = gdb_regs[R4];
-	regs->regs[R5] = gdb_regs[R5];
-	regs->regs[R6] = gdb_regs[R6];
-	regs->regs[R7] = gdb_regs[R7];
-	regs->regs[R8] = gdb_regs[R8];
-	regs->regs[R9] = gdb_regs[R9];
-	regs->regs[R10] = gdb_regs[R10];
-	regs->regs[R11] = gdb_regs[R11];
-	regs->regs[R12] = gdb_regs[R12];
-	regs->regs[R13] = gdb_regs[R13];
-	regs->regs[R14] = gdb_regs[R14];
-	regs->regs[R15] = gdb_regs[R15];
-	regs->pc = gdb_regs[PC];
-	regs->pr = gdb_regs[PR];
-	regs->gbr = gdb_regs[GBR];
-	regs->mach = gdb_regs[MACH];
-	regs->macl = gdb_regs[MACL];
-	regs->sr = gdb_regs[SR];
-	regs->vbr = gdb_regs[VBR];
-}
-
-/* Calculate the new address for after a step */
-static short *get_step_address(void)
-{
-	short op = *(short *) trap_registers.pc;
-	long addr;
-
-	/* BT */
-	if (OPCODE_BT(op)) {
-		if (trap_registers.sr & SR_T_BIT_MASK)
-			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-		else
-			addr = trap_registers.pc + 2;
-	}
-
-	/* BTS */
-	else if (OPCODE_BTS(op)) {
-		if (trap_registers.sr & SR_T_BIT_MASK)
-			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-		else
-			addr = trap_registers.pc + 4;	/* Not in delay slot */
-	}
-
-	/* BF */
-	else if (OPCODE_BF(op)) {
-		if (!(trap_registers.sr & SR_T_BIT_MASK))
-			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-		else
-			addr = trap_registers.pc + 2;
-	}
-
-	/* BFS */
-	else if (OPCODE_BFS(op)) {
-		if (!(trap_registers.sr & SR_T_BIT_MASK))
-			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-		else
-			addr = trap_registers.pc + 4;	/* Not in delay slot */
-	}
-
-	/* BRA */
-	else if (OPCODE_BRA(op))
-		addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
-
-	/* BRAF */
-	else if (OPCODE_BRAF(op))
-		addr = trap_registers.pc + 4
-		    + trap_registers.regs[OPCODE_BRAF_REG(op)];
-
-	/* BSR */
-	else if (OPCODE_BSR(op))
-		addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
-
-	/* BSRF */
-	else if (OPCODE_BSRF(op))
-		addr = trap_registers.pc + 4
-		    + trap_registers.regs[OPCODE_BSRF_REG(op)];
-
-	/* JMP */
-	else if (OPCODE_JMP(op))
-		addr = trap_registers.regs[OPCODE_JMP_REG(op)];
-
-	/* JSR */
-	else if (OPCODE_JSR(op))
-		addr = trap_registers.regs[OPCODE_JSR_REG(op)];
-
-	/* RTS */
-	else if (OPCODE_RTS(op))
-		addr = trap_registers.pr;
-
-	/* RTE */
-	else if (OPCODE_RTE(op))
-		addr = trap_registers.regs[15];
-
-	/* Other */
-	else
-		addr = trap_registers.pc + 2;
-
-	flush_icache_range(addr, addr + 2);
-	return (short *) addr;
-}
-
-/* Set up a single-step.  Replace the instruction immediately after the
-   current instruction (i.e. next in the expected flow of control) with a
-   trap instruction, so that returning will cause only a single instruction
-   to be executed. Note that this model is slightly broken for instructions
-   with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
-   and the instruction in the delay slot will be executed. */
-static void do_single_step(void)
-{
-	unsigned short *addr = 0;
-
-	/* Determine where the target instruction will send us to */
-	addr = get_step_address();
-	stepped_address = (int)addr;
-
-	/* Replace it */
-	stepped_opcode = *(short *)addr;
-	*addr = STEP_OPCODE;
-
-	/* Flush and return */
-	flush_icache_range((long) addr, (long) addr + 2);
-}
-
-/* Undo a single step */
-static void undo_single_step(void)
-{
-	/* If we have stepped, put back the old instruction */
-	/* Use stepped_address in case we stopped elsewhere */
-	if (stepped_opcode != 0) {
-		*(short*)stepped_address = stepped_opcode;
-		flush_icache_range(stepped_address, stepped_address + 2);
-	}
-	stepped_opcode = 0;
-}
-
-/* Send a signal message */
-static void send_signal_msg(const int signum)
-{
-	out_buffer[0] = 'S';
-	out_buffer[1] = hex_asc_hi(signum);
-	out_buffer[2] = hex_asc_lo(signum);
-	out_buffer[3] = 0;
-	put_packet(out_buffer);
-}
-
-/* Reply that all was well */
-static void send_ok_msg(void)
-{
-	strcpy(out_buffer, "OK");
-	put_packet(out_buffer);
-}
-
-/* Reply that an error occurred */
-static void send_err_msg(void)
-{
-	strcpy(out_buffer, "E01");
-	put_packet(out_buffer);
-}
-
-/* Empty message indicates unrecognised command */
-static void send_empty_msg(void)
-{
-	put_packet("");
-}
-
-/* Read memory due to 'm' message */
-static void read_mem_msg(void)
-{
-	char *ptr;
-	int addr;
-	int length;
-
-	/* Jmp, disable bus error handler */
-	if (setjmp(rem_com_env) == 0) {
-
-		kgdb_nofault = 1;
-
-		/* Walk through, have m<addr>,<length> */
-		ptr = &in_buffer[1];
-		if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
-			if (hex_to_int(&ptr, &length)) {
-				ptr = 0;
-				if (length * 2 > OUTBUFMAX)
-					length = OUTBUFMAX / 2;
-				mem_to_hex((char *) addr, out_buffer, length);
-			}
-		if (ptr)
-			send_err_msg();
-		else
-			put_packet(out_buffer);
-	} else
-		send_err_msg();
-
-	/* Restore bus error handler */
-	kgdb_nofault = 0;
-}
-
-/* Write memory due to 'M' or 'X' message */
-static void write_mem_msg(int binary)
-{
-	char *ptr;
-	int addr;
-	int length;
-
-	if (setjmp(rem_com_env) == 0) {
-
-		kgdb_nofault = 1;
-
-		/* Walk through, have M<addr>,<length>:<data> */
-		ptr = &in_buffer[1];
-		if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
-			if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
-				if (binary)
-					ebin_to_mem(ptr, (char*)addr, length);
-				else
-					hex_to_mem(ptr, (char*)addr, length);
-				flush_icache_range(addr, addr + length);
-				ptr = 0;
-				send_ok_msg();
-			}
-		if (ptr)
-			send_err_msg();
-	} else
-		send_err_msg();
-
-	/* Restore bus error handler */
-	kgdb_nofault = 0;
-}
-
-/* Continue message  */
-static void continue_msg(void)
-{
-	/* Try to read optional parameter, PC unchanged if none */
-	char *ptr = &in_buffer[1];
-	int addr;
-
-	if (hex_to_int(&ptr, &addr))
-		trap_registers.pc = addr;
-}
-
-/* Continue message with signal */
-static void continue_with_sig_msg(void)
-{
-	int signal;
-	char *ptr = &in_buffer[1];
-	int addr;
-
-	/* Report limitation */
-	kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
-
-	/* Signal */
-	hex_to_int(&ptr, &signal);
-	if (*ptr == ';')
-		ptr++;
-
-	/* Optional address */
-	if (hex_to_int(&ptr, &addr))
-		trap_registers.pc = addr;
-}
-
-/* Step message */
-static void step_msg(void)
-{
-	continue_msg();
-	do_single_step();
-}
-
-/* Step message with signal */
-static void step_with_sig_msg(void)
-{
-	continue_with_sig_msg();
-	do_single_step();
-}
-
-/* Send register contents */
-static void send_regs_msg(void)
-{
-	kgdb_regs_to_gdb_regs(&trap_registers, registers);
-	mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
-	put_packet(out_buffer);
-}
-
-/* Set register contents - currently can't set other thread's registers */
-static void set_regs_msg(void)
-{
-	kgdb_regs_to_gdb_regs(&trap_registers, registers);
-	hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
-	gdb_regs_to_kgdb_regs(registers, &trap_registers);
-	send_ok_msg();
-}
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
-/*
- * Bring up the ports..
- */
-static int __init kgdb_serial_setup(void)
-{
-	struct console dummy;
-	return kgdb_console_setup(&dummy, 0);
-}
-#else
-#define kgdb_serial_setup()	0
-#endif
-
-/* The command loop, read and act on requests */
-static void kgdb_command_loop(const int excep_code, const int trapa_value)
-{
-	int sigval;
-
-	/* Enter GDB mode (e.g. after detach) */
-	if (!kgdb_in_gdb_mode) {
-		/* Do serial setup, notify user, issue preemptive ack */
-		printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
-		kgdb_in_gdb_mode = 1;
-		put_debug_char('+');
-	}
-
-	/* Reply to host that an exception has occurred */
-	sigval = compute_signal(excep_code);
-	send_signal_msg(sigval);
-
-	/* TRAP_VEC exception indicates a software trap inserted in place of
-	   code by GDB so back up PC by one instruction, as this instruction
-	   will later be replaced by its original one.  Do NOT do this for
-	   trap 0xff, since that indicates a compiled-in breakpoint which
-	   will not be replaced (and we would retake the trap forever) */
-	if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
-		trap_registers.pc -= 2;
-
-	/* Undo any stepping we may have done */
-	undo_single_step();
-
-	while (1) {
-		out_buffer[0] = 0;
-		get_packet(in_buffer, BUFMAX);
-
-		/* Examine first char of buffer to see what we need to do */
-		switch (in_buffer[0]) {
-		case '?':	/* Send which signal we've received */
-			send_signal_msg(sigval);
-			break;
-
-		case 'g':	/* Return the values of the CPU registers */
-			send_regs_msg();
-			break;
-
-		case 'G':	/* Set the value of the CPU registers */
-			set_regs_msg();
-			break;
-
-		case 'm':	/* Read LLLL bytes address AA..AA */
-			read_mem_msg();
-			break;
-
-		case 'M':	/* Write LLLL bytes address AA..AA, ret OK */
-			write_mem_msg(0);	/* 0 = data in hex */
-			break;
-
-		case 'X':	/* Write LLLL bytes esc bin address AA..AA */
-			if (kgdb_bits == '8')
-				write_mem_msg(1); /* 1 = data in binary */
-			else
-				send_empty_msg();
-			break;
-
-		case 'C':	/* Continue, signum included, we ignore it */
-			continue_with_sig_msg();
-			return;
-
-		case 'c':	/* Continue at address AA..AA (optional) */
-			continue_msg();
-			return;
-
-		case 'S':	/* Step, signum included, we ignore it */
-			step_with_sig_msg();
-			return;
-
-		case 's':	/* Step one instruction from AA..AA */
-			step_msg();
-			return;
-
-		case 'k':	/* 'Kill the program' with a kernel ? */
-			break;
-
-		case 'D':	/* Detach from program, send reply OK */
-			kgdb_in_gdb_mode = 0;
-			send_ok_msg();
-			get_debug_char();
-			return;
-
-		default:
-			send_empty_msg();
-			break;
-		}
-	}
-}
-
-/* There has been an exception, most likely a breakpoint. */
-static void handle_exception(struct pt_regs *regs)
-{
-	int excep_code, vbr_val;
-	int count;
-	int trapa_value = ctrl_inl(TRA);
-
-	/* Copy kernel regs (from stack) */
-	for (count = 0; count < 16; count++)
-		trap_registers.regs[count] = regs->regs[count];
-	trap_registers.pc = regs->pc;
-	trap_registers.pr = regs->pr;
-	trap_registers.sr = regs->sr;
-	trap_registers.gbr = regs->gbr;
-	trap_registers.mach = regs->mach;
-	trap_registers.macl = regs->macl;
-
-	asm("stc vbr, %0":"=r"(vbr_val));
-	trap_registers.vbr = vbr_val;
-
-	/* Get excode for command loop call, user access */
-	asm("stc r2_bank, %0":"=r"(excep_code));
-
-	/* Act on the exception */
-	kgdb_command_loop(excep_code, trapa_value);
-
-	/* Copy back the (maybe modified) registers */
-	for (count = 0; count < 16; count++)
-		regs->regs[count] = trap_registers.regs[count];
-	regs->pc = trap_registers.pc;
-	regs->pr = trap_registers.pr;
-	regs->sr = trap_registers.sr;
-	regs->gbr = trap_registers.gbr;
-	regs->mach = trap_registers.mach;
-	regs->macl = trap_registers.macl;
-
-	vbr_val = trap_registers.vbr;
-	asm("ldc %0, vbr": :"r"(vbr_val));
-}
-
-asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
-				      unsigned long r6, unsigned long r7,
-				      struct pt_regs __regs)
-{
-	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
-	handle_exception(regs);
-}
-
-/* Initialise the KGDB data structures and serial configuration */
-int __init kgdb_init(void)
-{
-	in_nmi = 0;
-	kgdb_nofault = 0;
-	stepped_opcode = 0;
-	kgdb_in_gdb_mode = 0;
-
-	if (kgdb_serial_setup() != 0) {
-		printk(KERN_NOTICE "KGDB: serial setup error\n");
-		return -1;
-	}
-
-	/* Init ptr to exception handler */
-	kgdb_debug_hook = handle_exception;
-	kgdb_bus_err_hook = kgdb_handle_bus_error;
-
-	/* Enter kgdb now if requested, or just report init done */
-	printk(KERN_NOTICE "KGDB: stub is initialized.\n");
-
-	return 0;
-}
-
-/* Make function available for "user messages"; console will use it too. */
-
-char gdbmsgbuf[BUFMAX];
-#define MAXOUT ((BUFMAX-2)/2)
-
-static void kgdb_msg_write(const char *s, unsigned count)
-{
-	int i;
-	int wcount;
-	char *bufptr;
-
-	/* 'O'utput */
-	gdbmsgbuf[0] = 'O';
-
-	/* Fill and send buffers... */
-	while (count > 0) {
-		bufptr = gdbmsgbuf + 1;
-
-		/* Calculate how many this time */
-		wcount = (count > MAXOUT) ? MAXOUT : count;
-
-		/* Pack in hex chars */
-		for (i = 0; i < wcount; i++)
-			bufptr = pack_hex_byte(bufptr, s[i]);
-		*bufptr = '\0';
-
-		/* Move up */
-		s += wcount;
-		count -= wcount;
-
-		/* Write packet */
-		put_packet(gdbmsgbuf);
-	}
-}
-
-static void kgdb_to_gdb(const char *s)
-{
-	kgdb_msg_write(s, strlen(s));
-}
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
-void kgdb_console_write(struct console *co, const char *s, unsigned count)
-{
-	/* Bail if we're not talking to GDB */
-	if (!kgdb_in_gdb_mode)
-		return;
-
-	kgdb_msg_write(s, count);
-}
-#endif
-
-#ifdef CONFIG_KGDB_SYSRQ
-static void sysrq_handle_gdb(int key, struct tty_struct *tty)
-{
-	printk("Entering GDB stub\n");
-	breakpoint();
-}
-
-static struct sysrq_key_op sysrq_gdb_op = {
-        .handler        = sysrq_handle_gdb,
-        .help_msg       = "Gdb",
-        .action_msg     = "GDB",
-};
-
-static int gdb_register_sysrq(void)
-{
-	printk("Registering GDB sysrq handler\n");
-	register_sysrq_key('g', &sysrq_gdb_op);
-	return 0;
-}
-module_init(gdb_register_sysrq);
-#endif
diff --git a/arch/sh/kernel/pm.c b/arch/sh/kernel/pm.c
deleted file mode 100644
index 10ab62c9aede..000000000000
--- a/arch/sh/kernel/pm.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Generic Power Management Routine
- *
- * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License.
- */
-#include <linux/suspend.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <asm/freq.h>
-#include <asm/io.h>
-#include <asm/watchdog.h>
-#include <asm/pm.h>
-
-#define INTR_OFFSET	0x600
-
-#define STBCR		0xffffff82
-#define STBCR2		0xffffff88
-
-#define STBCR_STBY	0x80
-#define STBCR_MSTP2	0x04
-
-#define MCR		0xffffff68
-#define RTCNT		0xffffff70
-
-#define MCR_RMODE	2
-#define MCR_RFSH	4
-
-void pm_enter(void)
-{
-	u8 stbcr, csr;
-	u16 frqcr, mcr;
-	u32 vbr_new, vbr_old;
-
-	set_bl_bit();
-
-	/* set wdt */
-	csr = sh_wdt_read_csr();
-	csr &= ~WTCSR_TME;
-	csr |= WTCSR_CKS_4096;
-	sh_wdt_write_csr(csr);
-	csr = sh_wdt_read_csr();
-	sh_wdt_write_cnt(0);
-
-	/* disable PLL1 */
-	frqcr = ctrl_inw(FRQCR);
-	frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
-	ctrl_outw(frqcr, FRQCR);
-
-	/* enable standby */
-	stbcr = ctrl_inb(STBCR);
-	ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
-
-	/* set self-refresh */
-	mcr = ctrl_inw(MCR);
-	ctrl_outw(mcr & ~MCR_RFSH, MCR);
-
-	/* set interrupt handler */
-	asm volatile("stc vbr, %0" : "=r" (vbr_old));
-	vbr_new = get_zeroed_page(GFP_ATOMIC);
-	udelay(50);
-	memcpy((void*)(vbr_new + INTR_OFFSET),
-	       &wakeup_start, &wakeup_end - &wakeup_start);
-	asm volatile("ldc %0, vbr" : : "r" (vbr_new));
-
-	ctrl_outw(0, RTCNT);
-	ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
-
-	cpu_sleep();
-
-	asm volatile("ldc %0, vbr" : : "r" (vbr_old));
-
-	free_page(vbr_new);
-
-	/* enable PLL1 */
-	frqcr = ctrl_inw(FRQCR);
-	frqcr |= FRQCR_PSTBY;
-	ctrl_outw(frqcr, FRQCR);
-	udelay(50);
-	frqcr |= FRQCR_PLLEN;
-	ctrl_outw(frqcr, FRQCR);
-
-	ctrl_outb(stbcr, STBCR);
-
-	clear_bl_bit();
-}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index b965f0282c7d..ddafbbbab2ab 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -32,65 +32,8 @@
 #include <asm/fpu.h>
 #include <asm/syscalls.h>
 
-static int hlt_counter;
 int ubc_usercnt = 0;
 
-void (*pm_idle)(void);
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-static int __init nohlt_setup(char *__unused)
-{
-	hlt_counter = 1;
-	return 1;
-}
-__setup("nohlt", nohlt_setup);
-
-static int __init hlt_setup(char *__unused)
-{
-	hlt_counter = 0;
-	return 1;
-}
-__setup("hlt", hlt_setup);
-
-static void default_idle(void)
-{
-	if (!hlt_counter) {
-		clear_thread_flag(TIF_POLLING_NRFLAG);
-		smp_mb__after_clear_bit();
-		set_bl_bit();
-		while (!need_resched())
-			cpu_sleep();
-		clear_bl_bit();
-		set_thread_flag(TIF_POLLING_NRFLAG);
-	} else
-		while (!need_resched())
-			cpu_relax();
-}
-
-void cpu_idle(void)
-{
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	/* endless idle loop with no priority at all */
-	while (1) {
-		void (*idle)(void) = pm_idle;
-
-		if (!idle)
-			idle = default_idle;
-
-		tick_nohz_stop_sched_tick(1);
-		while (!need_resched())
-			idle();
-		tick_nohz_restart_sched_tick();
-
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-		check_pgt_cache();
-	}
-}
-
 void machine_restart(char * __unused)
 {
 	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
@@ -115,8 +58,8 @@ void machine_power_off(void)
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
-	printk("CPU : %d    %s  (%s %.*s)\n",
+	printk("Pid : %d, Comm: \t\t%s\n", task_pid_nr(current), current->comm);
+	printk("CPU : %d        \t\t%s  (%s %.*s)\n\n",
 	       smp_processor_id(), print_tainted(), init_utsname()->release,
 	       (int)strcspn(init_utsname()->version, " "),
 	       init_utsname()->version);
@@ -148,26 +91,16 @@ void show_regs(struct pt_regs * regs)
 	       regs->mach, regs->macl, regs->gbr, regs->pr);
 
 	show_trace(NULL, (unsigned long *)regs->regs[15], regs);
+	show_code(regs);
 }
 
 /*
  * Create a kernel thread
  */
-
-/*
- * This is the mechanism for creating a new kernel thread.
- *
- */
-extern void kernel_thread_helper(void);
-__asm__(".align 5\n"
-	"kernel_thread_helper:\n\t"
-	"jsr	@r5\n\t"
-	" nop\n\t"
-	"mov.l	1f, r1\n\t"
-	"jsr	@r1\n\t"
-	" mov	r0, r4\n\t"
-	".align 2\n\t"
-	"1:.long do_exit");
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+	do_exit(fn(arg));
+}
 
 /* Don't use this in BL=1(cli).  Or else, CPU resets! */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index b7aa09235b51..a7e5f2e74bac 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -23,7 +23,6 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/proc_fs.h>
 #include <linux/io.h>
 #include <asm/syscalls.h>
 #include <asm/uaccess.h>
@@ -33,56 +32,6 @@
 
 struct task_struct *last_task_used_math = NULL;
 
-static int hlt_counter = 1;
-
-#define HARD_IDLE_TIMEOUT (HZ / 3)
-
-static int __init nohlt_setup(char *__unused)
-{
-	hlt_counter = 1;
-	return 1;
-}
-
-static int __init hlt_setup(char *__unused)
-{
-	hlt_counter = 0;
-	return 1;
-}
-
-__setup("nohlt", nohlt_setup);
-__setup("hlt", hlt_setup);
-
-static inline void hlt(void)
-{
-	__asm__ __volatile__ ("sleep" : : : "memory");
-}
-
-/*
- * The idle loop on a uniprocessor SH..
- */
-void cpu_idle(void)
-{
-	/* endless idle loop with no priority at all */
-	while (1) {
-		if (hlt_counter) {
-			while (!need_resched())
-				cpu_relax();
-		} else {
-			local_irq_disable();
-			while (!need_resched()) {
-				local_irq_enable();
-				hlt();
-				local_irq_disable();
-			}
-			local_irq_enable();
-		}
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
-
-}
-
 void machine_restart(char * __unused)
 {
 	extern void phys_stext(void);
@@ -97,13 +46,6 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-#if 0
-	/* Disable watchdog timer */
-	ctrl_outl(0xa5000000, WTCSR);
-	/* Configure deep standby on sleep */
-	ctrl_outl(0x03, STBCR);
-#endif
-
 	__asm__ __volatile__ (
 		"sleep\n\t"
 		"synci\n\t"
@@ -113,9 +55,6 @@ void machine_power_off(void)
 	panic("Unexpected wakeup!\n");
 }
 
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	unsigned long long ah, al, bh, bl, ch, cl;
@@ -365,18 +304,6 @@ void show_regs(struct pt_regs * regs)
 	}
 }
 
-struct task_struct * alloc_task_struct(void)
-{
-	/* Get task descriptor pages */
-	return (struct task_struct *)
-		__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE));
-}
-
-void free_task_struct(struct task_struct *p)
-{
-	free_pages((unsigned long) p, get_order(THREAD_SIZE));
-}
-
 /*
  * Create a kernel thread
  */
@@ -662,41 +589,3 @@ unsigned long get_wchan(struct task_struct *p)
 #endif
 	return pc;
 }
-
-/* Provide a /proc/asids file that lists out the
-   ASIDs currently associated with the processes.  (If the DM.PC register is
-   examined through the debug link, this shows ASID + PC.  To make use of this,
-   the PID->ASID relationship needs to be known.  This is primarily for
-   debugging.)
-   */
-
-#if defined(CONFIG_SH64_PROC_ASIDS)
-static int
-asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
-{
-	int len=0;
-	struct task_struct *p;
-	read_lock(&tasklist_lock);
-	for_each_process(p) {
-		int pid = p->pid;
-
-		if (!pid)
-			continue;
-		if (p->mm)
-			len += sprintf(buf+len, "%5d : %02lx\n", pid,
-				       asid_cache(smp_processor_id()));
-		else
-			len += sprintf(buf+len, "%5d : (none)\n", pid);
-	}
-	read_unlock(&tasklist_lock);
-	*eof = 1;
-	return len;
-}
-
-static int __init register_proc_asids(void)
-{
-	create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
-	return 0;
-}
-__initcall(register_proc_asids);
-#endif
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index e15b099c1f06..695097438f02 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -2,7 +2,7 @@
  * arch/sh/kernel/ptrace_64.c
  *
  * Copyright (C) 2000, 2001  Paolo Alberelli
- * Copyright (C) 2003 - 2007  Paul Mundt
+ * Copyright (C) 2003 - 2008  Paul Mundt
  *
  * Started from SH3/4 version:
  *   SuperH version:   Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
@@ -29,6 +29,8 @@
 #include <linux/audit.h>
 #include <linux/seccomp.h>
 #include <linux/tracehook.h>
+#include <linux/elf.h>
+#include <linux/regset.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -137,6 +139,165 @@ void user_disable_single_step(struct task_struct *child)
 	regs->sr &= ~SR_SSTEP;
 }
 
+static int genregs_get(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
+{
+	const struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* PC, SR, SYSCALL */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  &regs->pc,
+				  0, 3 * sizeof(unsigned long long));
+
+	/* R1 -> R63 */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					  regs->regs,
+					  offsetof(struct pt_regs, regs[0]),
+					  63 * sizeof(unsigned long long));
+	/* TR0 -> TR7 */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					  regs->tregs,
+					  offsetof(struct pt_regs, tregs[0]),
+					  8 * sizeof(unsigned long long));
+
+	if (!ret)
+		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					       sizeof(struct pt_regs), -1);
+
+	return ret;
+}
+
+static int genregs_set(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* PC, SR, SYSCALL */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 &regs->pc,
+				 0, 3 * sizeof(unsigned long long));
+
+	/* R1 -> R63 */
+	if (!ret && count > 0)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					 regs->regs,
+					 offsetof(struct pt_regs, regs[0]),
+					 63 * sizeof(unsigned long long));
+
+	/* TR0 -> TR7 */
+	if (!ret && count > 0)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					 regs->tregs,
+					 offsetof(struct pt_regs, tregs[0]),
+					 8 * sizeof(unsigned long long));
+
+	if (!ret)
+		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+						sizeof(struct pt_regs), -1);
+
+	return ret;
+}
+
+#ifdef CONFIG_SH_FPU
+int fpregs_get(struct task_struct *target,
+	       const struct user_regset *regset,
+	       unsigned int pos, unsigned int count,
+	       void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	ret = init_fpu(target);
+	if (ret)
+		return ret;
+
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				   &target->thread.fpu.hard, 0, -1);
+}
+
+static int fpregs_set(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	ret = init_fpu(target);
+	if (ret)
+		return ret;
+
+	set_stopped_child_used_math(target);
+
+	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				  &target->thread.fpu.hard, 0, -1);
+}
+
+static int fpregs_active(struct task_struct *target,
+			 const struct user_regset *regset)
+{
+	return tsk_used_math(target) ? regset->n : 0;
+}
+#endif
+
+/*
+ * These are our native regset flavours.
+ */
+enum sh_regset {
+	REGSET_GENERAL,
+#ifdef CONFIG_SH_FPU
+	REGSET_FPU,
+#endif
+};
+
+static const struct user_regset sh_regsets[] = {
+	/*
+	 * Format is:
+	 *	PC, SR, SYSCALL,
+	 *	R1 --> R63,
+	 *	TR0 --> TR7,
+	 */
+	[REGSET_GENERAL] = {
+		.core_note_type	= NT_PRSTATUS,
+		.n		= ELF_NGREG,
+		.size		= sizeof(long long),
+		.align		= sizeof(long long),
+		.get		= genregs_get,
+		.set		= genregs_set,
+	},
+
+#ifdef CONFIG_SH_FPU
+	[REGSET_FPU] = {
+		.core_note_type	= NT_PRFPREG,
+		.n		= sizeof(struct user_fpu_struct) /
+				  sizeof(long long),
+		.size		= sizeof(long long),
+		.align		= sizeof(long long),
+		.get		= fpregs_get,
+		.set		= fpregs_set,
+		.active		= fpregs_active,
+	},
+#endif
+};
+
+static const struct user_regset_view user_sh64_native_view = {
+	.name		= "sh64",
+	.e_machine	= EM_SH,
+	.regsets	= sh_regsets,
+	.n		= ARRAY_SIZE(sh_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+	return &user_sh64_native_view;
+}
+
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	int ret;
@@ -195,10 +356,33 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		}
 		break;
 
+	case PTRACE_GETREGS:
+		return copy_regset_to_user(child, &user_sh64_native_view,
+					   REGSET_GENERAL,
+					   0, sizeof(struct pt_regs),
+					   (void __user *)data);
+	case PTRACE_SETREGS:
+		return copy_regset_from_user(child, &user_sh64_native_view,
+					     REGSET_GENERAL,
+					     0, sizeof(struct pt_regs),
+					     (const void __user *)data);
+#ifdef CONFIG_SH_FPU
+	case PTRACE_GETFPREGS:
+		return copy_regset_to_user(child, &user_sh64_native_view,
+					   REGSET_FPU,
+					   0, sizeof(struct user_fpu_struct),
+					   (void __user *)data);
+	case PTRACE_SETFPREGS:
+		return copy_regset_from_user(child, &user_sh64_native_view,
+					     REGSET_FPU,
+					     0, sizeof(struct user_fpu_struct),
+					     (const void __user *)data);
+#endif
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
+
 	return ret;
 }
 
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e7152cc6930e..534247508572 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -417,6 +417,7 @@ void __init setup_arch(char **cmdline_p)
 }
 
 static const char *cpu_name[] = {
+	[CPU_SH7201]	= "SH7201",
 	[CPU_SH7203]	= "SH7203",	[CPU_SH7263]	= "SH7263",
 	[CPU_SH7206]	= "SH7206",	[CPU_SH7619]	= "SH7619",
 	[CPU_SH7705]	= "SH7705",	[CPU_SH7706]	= "SH7706",
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index d1bcac4fa269..c852f7805728 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -8,69 +8,50 @@
 #include <linux/module.h>
 #include <asm/sh_bios.h>
 
-#define BIOS_CALL_CONSOLE_WRITE     	0
-#define BIOS_CALL_READ_BLOCK     	1
+#define BIOS_CALL_CONSOLE_WRITE		0
 #define BIOS_CALL_ETH_NODE_ADDR		10
 #define BIOS_CALL_SHUTDOWN		11
-#define BIOS_CALL_CHAR_OUT     	    	0x1f  	/* TODO: hack */
-#define BIOS_CALL_GDB_GET_MODE_PTR     	0xfe
-#define BIOS_CALL_GDB_DETACH     	0xff
+#define BIOS_CALL_CHAR_OUT		0x1f	/* TODO: hack */
+#define BIOS_CALL_GDB_DETACH		0xff
 
-static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3)
+static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
+				    long arg3)
 {
-    register long r0 __asm__("r0") = func;
-    register long r4 __asm__("r4") = arg0;
-    register long r5 __asm__("r5") = arg1;
-    register long r6 __asm__("r6") = arg2;
-    register long r7 __asm__("r7") = arg3;
-    __asm__ __volatile__("trapa	#0x3f"
-	 : "=z" (r0)
-	 : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7)
-	 : "memory");
-    return r0;
+	register long r0 __asm__("r0") = func;
+	register long r4 __asm__("r4") = arg0;
+	register long r5 __asm__("r5") = arg1;
+	register long r6 __asm__("r6") = arg2;
+	register long r7 __asm__("r7") = arg3;
+
+	__asm__ __volatile__("trapa	#0x3f":"=z"(r0)
+			     :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
+			     :"memory");
+	return r0;
 }
 
-
 void sh_bios_console_write(const char *buf, unsigned int len)
 {
-    sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
+	sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
 }
 
-
 void sh_bios_char_out(char ch)
 {
-    sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
-}
-
-
-int sh_bios_in_gdb_mode(void)
-{
-    static char queried = 0;
-    static char *gdb_mode_p = 0;
-
-    if (!queried)
-    {
-    	/* Query the gdb stub for address of its gdb mode variable */
-    	long r = sh_bios_call(BIOS_CALL_GDB_GET_MODE_PTR, 0, 0, 0, 0);
-	if (r != ~0)	/* BIOS returns -1 for unknown function */
-	    gdb_mode_p = (char *)r;
-	queried = 1;
-    }
-    return (gdb_mode_p != 0 ? *gdb_mode_p : 0);
+	sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
 }
 
 void sh_bios_gdb_detach(void)
 {
-    sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
+	sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
 }
-EXPORT_SYMBOL(sh_bios_gdb_detach);
+EXPORT_SYMBOL_GPL(sh_bios_gdb_detach);
 
-void sh_bios_get_node_addr (unsigned char *node_addr)
+void sh_bios_get_node_addr(unsigned char *node_addr)
 {
-    sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
+	sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
 }
+EXPORT_SYMBOL_GPL(sh_bios_get_node_addr);
 
 void sh_bios_shutdown(unsigned int how)
 {
-    sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
+	sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
 }
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 92ae5e6c099e..528de2955c81 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -52,16 +52,12 @@ EXPORT_SYMBOL(__const_udelay);
 
 #define DECLARE_EXPORT(name)		\
 	extern void name(void);EXPORT_SYMBOL(name)
-#define MAYBE_DECLARE_EXPORT(name)	\
-	extern void name(void) __weak;EXPORT_SYMBOL(name)
 
-/* These symbols are generated by the compiler itself */
 DECLARE_EXPORT(__udivsi3);
 DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__lshrsi3);
 DECLARE_EXPORT(__ashrsi3);
 DECLARE_EXPORT(__ashlsi3);
-DECLARE_EXPORT(__ashrdi3);
-DECLARE_EXPORT(__ashldi3);
 DECLARE_EXPORT(__ashiftrt_r4_6);
 DECLARE_EXPORT(__ashiftrt_r4_7);
 DECLARE_EXPORT(__ashiftrt_r4_8);
@@ -79,8 +75,7 @@ DECLARE_EXPORT(__ashiftrt_r4_23);
 DECLARE_EXPORT(__ashiftrt_r4_24);
 DECLARE_EXPORT(__ashiftrt_r4_27);
 DECLARE_EXPORT(__ashiftrt_r4_30);
-DECLARE_EXPORT(__lshrsi3);
-DECLARE_EXPORT(__lshrdi3);
+DECLARE_EXPORT(__movstr);
 DECLARE_EXPORT(__movstrSI8);
 DECLARE_EXPORT(__movstrSI12);
 DECLARE_EXPORT(__movstrSI16);
@@ -95,31 +90,17 @@ DECLARE_EXPORT(__movstrSI48);
 DECLARE_EXPORT(__movstrSI52);
 DECLARE_EXPORT(__movstrSI56);
 DECLARE_EXPORT(__movstrSI60);
-#if __GNUC__ == 4
-DECLARE_EXPORT(__movmem);
-#else
-DECLARE_EXPORT(__movstr);
-#endif
-
-#if __GNUC__ == 4
+DECLARE_EXPORT(__movstr_i4_even);
+DECLARE_EXPORT(__movstr_i4_odd);
+DECLARE_EXPORT(__movstrSI12_i4);
 DECLARE_EXPORT(__movmem_i4_even);
 DECLARE_EXPORT(__movmem_i4_odd);
 DECLARE_EXPORT(__movmemSI12_i4);
-
-#if (__GNUC_MINOR__ >= 2 || defined(__GNUC_STM_RELEASE__))
-/*
- * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST
- * compiler which include backported patches.
- */
 DECLARE_EXPORT(__udiv_qrnnd_16);
-MAYBE_DECLARE_EXPORT(__sdivsi3_i4i);
-MAYBE_DECLARE_EXPORT(__udivsi3_i4i);
-#endif
-#else /* GCC 3.x */
-DECLARE_EXPORT(__movstr_i4_even);
-DECLARE_EXPORT(__movstr_i4_odd);
-DECLARE_EXPORT(__movstrSI12_i4);
-#endif /* __GNUC__ == 4 */
+DECLARE_EXPORT(__sdivsi3_i4);
+DECLARE_EXPORT(__udivsi3_i4);
+DECLARE_EXPORT(__sdivsi3_i4i);
+DECLARE_EXPORT(__udivsi3_i4i);
 
 #if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
 	defined(CONFIG_SH7705_CACHE_32KB))
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 9324d32adacc..0d74d6b8774e 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -65,15 +65,16 @@ EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
 EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcpy);
 
 /* Ugh.  These come in from libgcc.a at link time. */
 #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
 
 DECLARE_EXPORT(__sdivsi3);
-DECLARE_EXPORT(__sdivsi3_2);
-DECLARE_EXPORT(__muldi3);
 DECLARE_EXPORT(__udivsi3);
 DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 69d09c0b3498..77c21bde376a 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -533,7 +533,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 {
 	int ret;
 
-
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
 		ret = setup_rt_frame(sig, ka, info, oldset, regs);
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index ce3e851dffcb..b22fdfaaa191 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -2,7 +2,7 @@
  * arch/sh/kernel/signal_64.c
  *
  * Copyright (C) 2000, 2001  Paolo Alberelli
- * Copyright (C) 2003  Paul Mundt
+ * Copyright (C) 2003 - 2008  Paul Mundt
  * Copyright (C) 2004  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -43,10 +43,38 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-static void
+static int
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 		sigset_t *oldset, struct pt_regs * regs);
 
+static inline void
+handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
+{
+	/* If we're not from a syscall, bail out */
+	if (regs->syscall_nr < 0)
+		return;
+
+	/* check for system call restart.. */
+	switch (regs->regs[REG_RET]) {
+		case -ERESTART_RESTARTBLOCK:
+		case -ERESTARTNOHAND:
+		no_system_call_restart:
+			regs->regs[REG_RET] = -EINTR;
+			regs->sr |= 1;
+			break;
+
+		case -ERESTARTSYS:
+			if (!(sa->sa_flags & SA_RESTART))
+				goto no_system_call_restart;
+		/* fallthrough */
+		case -ERESTARTNOINTR:
+			/* Decode syscall # */
+			regs->regs[REG_RET] = regs->syscall_nr;
+			regs->pc -= 4;
+			break;
+	}
+}
+
 /*
  * Note that 'init' is a special process: it doesn't get signals it doesn't
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -80,21 +108,23 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, 0);
-
 	if (signr > 0) {
-		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, &ka, oldset, regs);
+		if (regs->sr & 1)
+			handle_syscall_restart(regs, &ka.sa);
 
-		/*
-		 * If a signal was successfully delivered, the saved sigmask
-		 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK
-		 * flag.
-		 */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-
-		tracehook_signal_handler(signr, &info, &ka, regs, 0);
-		return 1;
+		/* Whee!  Actually deliver the signal.  */
+		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+			/*
+			 * If a signal was successfully delivered, the
+			 * saved sigmask is in its frame, and we can
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+			tracehook_signal_handler(signr, &info, &ka, regs, 0);
+			return 1;
+		}
 	}
 
 no_signal:
@@ -129,7 +159,6 @@ no_signal:
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-
 asmlinkage int
 sys_sigsuspend(old_sigset_t mask,
 	       unsigned long r3, unsigned long r4, unsigned long r5,
@@ -235,20 +264,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 	return do_sigaltstack(uss, uoss, REF_REG_SP);
 }
 
-
 /*
  * Do a signal return; undo the signal stack.
  */
-
-struct sigframe
-{
+struct sigframe {
 	struct sigcontext sc;
 	unsigned long extramask[_NSIG_WORDS-1];
 	long long retcode[2];
 };
 
-struct rt_sigframe
-{
+struct rt_sigframe {
 	struct siginfo __user *pinfo;
 	void *puc;
 	struct siginfo info;
@@ -450,7 +475,6 @@ badframe:
 /*
  * Set up a signal frame.
  */
-
 static int
 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 		 unsigned long mask)
@@ -504,8 +528,8 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 void sa_default_restorer(void);		/* See comments below */
 void sa_default_rt_restorer(void);	/* See comments below */
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs *regs)
+static int setup_frame(int sig, struct k_sigaction *ka,
+		       sigset_t *set, struct pt_regs *regs)
 {
 	struct sigframe __user *frame;
 	int err = 0;
@@ -596,23 +620,21 @@ static void setup_frame(int sig, struct k_sigaction *ka,
 
 	set_fs(USER_DS);
 
-#if DEBUG_SIG
 	/* Broken %016Lx */
-	printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
-		signal,
-		current->comm, current->pid, frame,
-		regs->pc >> 32, regs->pc & 0xffffffff,
-		DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
-#endif
+	pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
+		 signal, current->comm, current->pid, frame,
+		 regs->pc >> 32, regs->pc & 0xffffffff,
+		 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			  sigset_t *set, struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
 	int err = 0;
@@ -702,62 +724,46 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
 	set_fs(USER_DS);
 
-#if DEBUG_SIG
-	/* Broken %016Lx */
-	printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
-		signal,
-		current->comm, current->pid, frame,
-		regs->pc >> 32, regs->pc & 0xffffffff,
-		DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
-#endif
+	pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
+		 signal, current->comm, current->pid, frame,
+		 regs->pc >> 32, regs->pc & 0xffffffff,
+		 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */
-
-static void
+static int
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 		sigset_t *oldset, struct pt_regs * regs)
 {
-	/* Are we from a system call? */
-	if (regs->syscall_nr >= 0) {
-		/* If so, check system call restarting.. */
-		switch (regs->regs[REG_RET]) {
-			case -ERESTART_RESTARTBLOCK:
-			case -ERESTARTNOHAND:
-			no_system_call_restart:
-				regs->regs[REG_RET] = -EINTR;
-				break;
-
-			case -ERESTARTSYS:
-				if (!(ka->sa.sa_flags & SA_RESTART))
-					goto no_system_call_restart;
-			/* fallthrough */
-			case -ERESTARTNOINTR:
-				/* Decode syscall # */
-				regs->regs[REG_RET] = regs->syscall_nr;
-				regs->pc -= 4;
-		}
-	}
+	int ret;
 
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset, regs);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (ret == 0) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	return ret;
 }
 
 asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 38f098c9c72d..58dfc02c7af1 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -22,102 +22,10 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/ipc.h>
-#include <asm/cacheflush.h>
 #include <asm/syscalls.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
-unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
-EXPORT_SYMBOL(shm_align_mask);
-
-#ifdef CONFIG_MMU
-/*
- * To avoid cache aliases, we map the shared page with same color.
- */
-#define COLOUR_ALIGN(addr, pgoff)				\
-	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
-	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
-
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-	unsigned long len, unsigned long pgoff, unsigned long flags)
-{
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	unsigned long start_addr;
-	int do_colour_align;
-
-	if (flags & MAP_FIXED) {
-		/* We do not accept a shared mapping if it would violate
-		 * cache aliasing constraints.
-		 */
-		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
-			return -EINVAL;
-		return addr;
-	}
-
-	if (unlikely(len > TASK_SIZE))
-		return -ENOMEM;
-
-	do_colour_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_colour_align = 1;
-
-	if (addr) {
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vma->vm_start))
-			return addr;
-	}
-
-	if (len > mm->cached_hole_size) {
-		start_addr = addr = mm->free_area_cache;
-	} else {
-	        mm->cached_hole_size = 0;
-		start_addr = addr = TASK_UNMAPPED_BASE;
-	}
-
-full_search:
-	if (do_colour_align)
-		addr = COLOUR_ALIGN(addr, pgoff);
-	else
-		addr = PAGE_ALIGN(mm->free_area_cache);
-
-	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
-		/* At this point:  (!vma || addr < vma->vm_end). */
-		if (unlikely(TASK_SIZE - len < addr)) {
-			/*
-			 * Start a new search - just in case we missed
-			 * some holes.
-			 */
-			if (start_addr != TASK_UNMAPPED_BASE) {
-				start_addr = addr = TASK_UNMAPPED_BASE;
-				mm->cached_hole_size = 0;
-				goto full_search;
-			}
-			return -ENOMEM;
-		}
-		if (likely(!vma || addr + len <= vma->vm_start)) {
-			/*
-			 * Remember the place where we stopped the search:
-			 */
-			mm->free_area_cache = addr + len;
-			return addr;
-		}
-		if (addr + mm->cached_hole_size < vma->vm_start)
-		        mm->cached_hole_size = vma->vm_start - addr;
-
-		addr = vma->vm_end;
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-	}
-}
-#endif /* CONFIG_MMU */
-
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
 	 unsigned long flags, int fd, unsigned long pgoff)
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 23ca711c27d2..8457f83242c5 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -125,11 +125,6 @@ void handle_timer_tick(void)
 	if (current->pid)
 		profile_tick(CPU_PROFILING);
 
-#ifdef CONFIG_HEARTBEAT
-	if (sh_mv.mv_heartbeat != NULL)
-		sh_mv.mv_heartbeat();
-#endif
-
 	/*
 	 * Here we are in the timer irq handler. We just have irqs locally
 	 * disabled but we don't know if the timer_bh is running on the other
@@ -277,11 +272,4 @@ void __init time_init(void)
 		       ((sh_hpt_frequency + 500) / 1000) / 1000,
 		       ((sh_hpt_frequency + 500) / 1000) % 1000);
 
-#if defined(CONFIG_SH_KGDB)
-	/*
-	 * Set up kgdb as requested. We do it here because the serial
-	 * init uses the timer vars we just set up for figuring baud.
-	 */
-	kgdb_init();
-#endif
 }
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index bbb2af1004d9..59d2a03e8b3c 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -240,11 +240,6 @@ static inline void do_timer_interrupt(void)
 
 	do_timer(1);
 
-#ifdef CONFIG_HEARTBEAT
-	if (sh_mv.mv_heartbeat != NULL)
-		sh_mv.mv_heartbeat();
-#endif
-
 	/*
 	 * If we have an externally synchronized Linux clock, then update
 	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index fe453c01f9c9..c3d237e1d566 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -34,7 +34,12 @@
 #define MTU2_TIER_1	0xfffe4384
 #define MTU2_TSR_1	0xfffe4385
 #define MTU2_TCNT_1	0xfffe4386	/* 16-bit counter */
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7201)
+#define MTU2_TGRA_1	0xfffe4388
+#else
 #define MTU2_TGRA_1	0xfffe438a
+#endif
 
 #define STBCR3		0xfffe0408
 
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 1e5c74efbacc..88807a2aacc3 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -28,17 +28,6 @@
 #include <asm/fpu.h>
 #include <asm/kprobes.h>
 
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-#define CHK_REMOTE_DEBUG(regs)			\
-{						\
-	if (kgdb_debug_hook && !user_mode(regs))\
-		(*kgdb_debug_hook)(regs);       \
-}
-#else
-#define CHK_REMOTE_DEBUG(regs)
-#endif
-
 #ifdef CONFIG_CPU_SH2
 # define TRAP_RESERVED_INST	4
 # define TRAP_ILLEGAL_SLOT_INST	6
@@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
 
 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 
-	CHK_REMOTE_DEBUG(regs);
 	print_modules();
 	show_regs(regs);
 
@@ -683,13 +671,12 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
 	error_code = lookup_exception_vector();
 
 	local_irq_enable();
-	CHK_REMOTE_DEBUG(regs);
 	force_sig(SIGILL, tsk);
 	die_if_no_fixup("reserved instruction", regs, error_code);
 }
 
 #ifdef CONFIG_SH_FPU_EMU
-static int emulate_branch(unsigned short inst, struct pt_regs* regs)
+static int emulate_branch(unsigned short inst, struct pt_regs *regs)
 {
 	/*
 	 * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +689,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
 	 * jsr: 4x0b: PC=Rn      after PR=PC+4;
 	 * rts: 000b: PC=PR;
 	 */
-	if ((inst & 0xfd00) == 0x8d00) {
+	if (((inst & 0xf000) == 0xb000)  ||	/* bsr */
+	    ((inst & 0xf0ff) == 0x0003)  ||	/* bsrf */
+	    ((inst & 0xf0ff) == 0x400b))	/* jsr */
+		regs->pr = regs->pc + 4;
+
+	if ((inst & 0xfd00) == 0x8d00) {	/* bfs, bts */
 		regs->pc += SH_PC_8BIT_OFFSET(inst);
 		return 0;
 	}
 
-	if ((inst & 0xe000) == 0xa000) {
+	if ((inst & 0xe000) == 0xa000) {	/* bra, bsr */
 		regs->pc += SH_PC_12BIT_OFFSET(inst);
 		return 0;
 	}
 
-	if ((inst & 0xf0df) == 0x0003) {
+	if ((inst & 0xf0df) == 0x0003) {	/* braf, bsrf */
 		regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
 		return 0;
 	}
 
-	if ((inst & 0xf0df) == 0x400b) {
+	if ((inst & 0xf0df) == 0x400b) {	/* jmp, jsr */
 		regs->pc = regs->regs[(inst & 0x0f00) >> 8];
 		return 0;
 	}
 
-	if ((inst & 0xffff) == 0x000b) {
+	if ((inst & 0xffff) == 0x000b) {	/* rts */
 		regs->pc = regs->pr;
 		return 0;
 	}
@@ -756,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
 	inst = lookup_exception_vector();
 
 	local_irq_enable();
-	CHK_REMOTE_DEBUG(regs);
 	force_sig(SIGILL, tsk);
 	die_if_no_fixup("illegal slot instruction", regs, inst);
 }
@@ -868,10 +859,7 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
 	if (regs && user_mode(regs))
 		return;
 
-	printk("\nCall trace: ");
-#ifdef CONFIG_KALLSYMS
-	printk("\n");
-#endif
+	printk("\nCall trace:\n");
 
 	while (!kstack_end(sp)) {
 		addr = *sp++;
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index 95f4de0800ec..3f7e415be86a 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -59,8 +59,7 @@ int __init vsyscall_init(void)
 }
 
 /* Setup a VMA at program startup for the vsyscall page */
-int arch_setup_additional_pages(struct linux_binprm *bprm,
-				int executable_stack)
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long addr;
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 8596cc78e18d..aaea580b65bb 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -5,12 +5,26 @@
 lib-y  = delay.o memset.o memmove.o memchr.o \
 	 checksum.o strlen.o div64.o div64-generic.o
 
+# Extracted from libgcc
+lib-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \
+	 ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \
+	 udiv_qrnnd.o
+
+udivsi3-y			:= udivsi3_i4i-Os.o
+
+ifneq ($(CONFIG_CC_OPTIMIZE_FOR_SIZE),y)
+udivsi3-$(CONFIG_CPU_SH3)	:= udivsi3_i4i.o
+udivsi3-$(CONFIG_CPU_SH4)	:= udivsi3_i4i.o
+endif
+udivsi3-y			+= udivsi3.o
+
 obj-y				+= io.o
 
 memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
 lib-$(CONFIG_MMU)		+= copy_page.o clear_page.o
-lib-y				+= $(memcpy-y)
+lib-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
+lib-y				+= $(memcpy-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/ashiftrt.S b/arch/sh/lib/ashiftrt.S
new file mode 100644
index 000000000000..45ce86558f46
--- /dev/null
+++ b/arch/sh/lib/ashiftrt.S
@@ -0,0 +1,149 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+	.global	__ashiftrt_r4_0
+	.global	__ashiftrt_r4_1
+	.global	__ashiftrt_r4_2
+	.global	__ashiftrt_r4_3
+	.global	__ashiftrt_r4_4
+	.global	__ashiftrt_r4_5
+	.global	__ashiftrt_r4_6
+	.global	__ashiftrt_r4_7
+	.global	__ashiftrt_r4_8
+	.global	__ashiftrt_r4_9
+	.global	__ashiftrt_r4_10
+	.global	__ashiftrt_r4_11
+	.global	__ashiftrt_r4_12
+	.global	__ashiftrt_r4_13
+	.global	__ashiftrt_r4_14
+	.global	__ashiftrt_r4_15
+	.global	__ashiftrt_r4_16
+	.global	__ashiftrt_r4_17
+	.global	__ashiftrt_r4_18
+	.global	__ashiftrt_r4_19
+	.global	__ashiftrt_r4_20
+	.global	__ashiftrt_r4_21
+	.global	__ashiftrt_r4_22
+	.global	__ashiftrt_r4_23
+	.global	__ashiftrt_r4_24
+	.global	__ashiftrt_r4_25
+	.global	__ashiftrt_r4_26
+	.global	__ashiftrt_r4_27
+	.global	__ashiftrt_r4_28
+	.global	__ashiftrt_r4_29
+	.global	__ashiftrt_r4_30
+	.global	__ashiftrt_r4_31
+	.global	__ashiftrt_r4_32
+
+	.align	1
+__ashiftrt_r4_32:
+__ashiftrt_r4_31:
+	rotcl	r4
+	rts
+	subc	r4,r4
+__ashiftrt_r4_30:
+	shar	r4
+__ashiftrt_r4_29:
+	shar	r4
+__ashiftrt_r4_28:
+	shar	r4
+__ashiftrt_r4_27:
+	shar	r4
+__ashiftrt_r4_26:
+	shar	r4
+__ashiftrt_r4_25:
+	shar	r4
+__ashiftrt_r4_24:
+	shlr16	r4
+	shlr8	r4
+	rts
+	exts.b	r4,r4
+__ashiftrt_r4_23:
+	shar	r4
+__ashiftrt_r4_22:
+	shar	r4
+__ashiftrt_r4_21:
+	shar	r4
+__ashiftrt_r4_20:
+	shar	r4
+__ashiftrt_r4_19:
+	shar	r4
+__ashiftrt_r4_18:
+	shar	r4
+__ashiftrt_r4_17:
+	shar	r4
+__ashiftrt_r4_16:
+	shlr16	r4
+	rts
+	exts.w	r4,r4
+__ashiftrt_r4_15:
+	shar	r4
+__ashiftrt_r4_14:
+	shar	r4
+__ashiftrt_r4_13:
+	shar	r4
+__ashiftrt_r4_12:
+	shar	r4
+__ashiftrt_r4_11:
+	shar	r4
+__ashiftrt_r4_10:
+	shar	r4
+__ashiftrt_r4_9:
+	shar	r4
+__ashiftrt_r4_8:
+	shar	r4
+__ashiftrt_r4_7:
+	shar	r4
+__ashiftrt_r4_6:
+	shar	r4
+__ashiftrt_r4_5:
+	shar	r4
+__ashiftrt_r4_4:
+	shar	r4
+__ashiftrt_r4_3:
+	shar	r4
+__ashiftrt_r4_2:
+	shar	r4
+__ashiftrt_r4_1:
+	rts
+	shar	r4
+__ashiftrt_r4_0:
+	rts
+	nop
diff --git a/arch/sh/lib/ashldi3.c b/arch/sh/lib/ashldi3.c
new file mode 100644
index 000000000000..beb80f316095
--- /dev/null
+++ b/arch/sh/lib/ashldi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (unsigned int) uu.s.low << -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+		w.s.low = (unsigned int) uu.s.low << b;
+		w.s.high = ((unsigned int) uu.s.high << b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S
new file mode 100644
index 000000000000..bd47e9b403a5
--- /dev/null
+++ b/arch/sh/lib/ashlsi3.S
@@ -0,0 +1,193 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+!
+! __ashlsi3
+!
+! Entry:
+!
+! r4: Value to shift
+! r5: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
+!
+	.global	__ashlsi3
+	
+	.align	2
+__ashlsi3:
+	mov	#31,r0
+	and	r0,r5
+	mova	ashlsi3_table,r0
+	mov.b	@(r0,r5),r5
+#ifdef __sh1__
+	add	r5,r0
+	jmp	@r0
+#else
+	braf	r5
+#endif
+	mov	r4,r0
+
+	.align	2
+ashlsi3_table:
+	.byte		ashlsi3_0-ashlsi3_table
+	.byte		ashlsi3_1-ashlsi3_table
+	.byte		ashlsi3_2-ashlsi3_table
+	.byte		ashlsi3_3-ashlsi3_table
+	.byte		ashlsi3_4-ashlsi3_table
+	.byte		ashlsi3_5-ashlsi3_table
+	.byte		ashlsi3_6-ashlsi3_table
+	.byte		ashlsi3_7-ashlsi3_table
+	.byte		ashlsi3_8-ashlsi3_table
+	.byte		ashlsi3_9-ashlsi3_table
+	.byte		ashlsi3_10-ashlsi3_table
+	.byte		ashlsi3_11-ashlsi3_table
+	.byte		ashlsi3_12-ashlsi3_table
+	.byte		ashlsi3_13-ashlsi3_table
+	.byte		ashlsi3_14-ashlsi3_table
+	.byte		ashlsi3_15-ashlsi3_table
+	.byte		ashlsi3_16-ashlsi3_table
+	.byte		ashlsi3_17-ashlsi3_table
+	.byte		ashlsi3_18-ashlsi3_table
+	.byte		ashlsi3_19-ashlsi3_table
+	.byte		ashlsi3_20-ashlsi3_table
+	.byte		ashlsi3_21-ashlsi3_table
+	.byte		ashlsi3_22-ashlsi3_table
+	.byte		ashlsi3_23-ashlsi3_table
+	.byte		ashlsi3_24-ashlsi3_table
+	.byte		ashlsi3_25-ashlsi3_table
+	.byte		ashlsi3_26-ashlsi3_table
+	.byte		ashlsi3_27-ashlsi3_table
+	.byte		ashlsi3_28-ashlsi3_table
+	.byte		ashlsi3_29-ashlsi3_table
+	.byte		ashlsi3_30-ashlsi3_table
+	.byte		ashlsi3_31-ashlsi3_table
+
+ashlsi3_6:
+	shll2	r0
+ashlsi3_4:
+	shll2	r0
+ashlsi3_2:
+	rts
+	shll2	r0
+
+ashlsi3_7:
+	shll2	r0
+ashlsi3_5:
+	shll2	r0
+ashlsi3_3:
+	shll2	r0
+ashlsi3_1:
+	rts
+	shll	r0
+
+ashlsi3_14:
+	shll2	r0
+ashlsi3_12:
+	shll2	r0
+ashlsi3_10:
+	shll2	r0
+ashlsi3_8:
+	rts
+	shll8	r0
+
+ashlsi3_15:
+	shll2	r0
+ashlsi3_13:
+	shll2	r0
+ashlsi3_11:
+	shll2	r0
+ashlsi3_9:
+	shll8	r0
+	rts
+	shll	r0
+
+ashlsi3_22:
+	shll2	r0
+ashlsi3_20:
+	shll2	r0
+ashlsi3_18:
+	shll2	r0
+ashlsi3_16:
+	rts
+	shll16	r0
+
+ashlsi3_23:
+	shll2	r0
+ashlsi3_21:
+	shll2	r0
+ashlsi3_19:
+	shll2	r0
+ashlsi3_17:
+	shll16	r0
+	rts
+	shll	r0
+
+ashlsi3_30:
+	shll2	r0
+ashlsi3_28:
+	shll2	r0
+ashlsi3_26:
+	shll2	r0
+ashlsi3_24:
+	shll16	r0
+	rts
+	shll8	r0
+
+ashlsi3_31:
+	shll2	r0
+ashlsi3_29:
+	shll2	r0
+ashlsi3_27:
+	shll2	r0
+ashlsi3_25:
+	shll16	r0
+	shll8	r0
+	rts
+	shll	r0
+
+ashlsi3_0:
+	rts
+	nop
diff --git a/arch/sh/lib/ashrdi3.c b/arch/sh/lib/ashrdi3.c
new file mode 100644
index 000000000000..c884a912b660
--- /dev/null
+++ b/arch/sh/lib/ashrdi3.c
@@ -0,0 +1,31 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		/* w.s.high = 1..1 or 0..0 */
+		w.s.high =
+		    uu.s.high >> 31;
+		w.s.low = uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S
new file mode 100644
index 000000000000..6f3cf46b77c2
--- /dev/null
+++ b/arch/sh/lib/ashrsi3.S
@@ -0,0 +1,185 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+!
+! __ashrsi3
+!
+! Entry:
+!
+! r4: Value to shift
+! r5: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
+!
+
+	.global	__ashrsi3
+	
+	.align	2
+__ashrsi3:
+	mov	#31,r0
+	and	r0,r5
+	mova	ashrsi3_table,r0
+	mov.b	@(r0,r5),r5
+#ifdef __sh1__
+	add	r5,r0
+	jmp	@r0
+#else
+	braf	r5
+#endif
+	mov	r4,r0
+
+	.align	2
+ashrsi3_table:
+	.byte		ashrsi3_0-ashrsi3_table
+	.byte		ashrsi3_1-ashrsi3_table
+	.byte		ashrsi3_2-ashrsi3_table
+	.byte		ashrsi3_3-ashrsi3_table
+	.byte		ashrsi3_4-ashrsi3_table
+	.byte		ashrsi3_5-ashrsi3_table
+	.byte		ashrsi3_6-ashrsi3_table
+	.byte		ashrsi3_7-ashrsi3_table
+	.byte		ashrsi3_8-ashrsi3_table
+	.byte		ashrsi3_9-ashrsi3_table
+	.byte		ashrsi3_10-ashrsi3_table
+	.byte		ashrsi3_11-ashrsi3_table
+	.byte		ashrsi3_12-ashrsi3_table
+	.byte		ashrsi3_13-ashrsi3_table
+	.byte		ashrsi3_14-ashrsi3_table
+	.byte		ashrsi3_15-ashrsi3_table
+	.byte		ashrsi3_16-ashrsi3_table
+	.byte		ashrsi3_17-ashrsi3_table
+	.byte		ashrsi3_18-ashrsi3_table
+	.byte		ashrsi3_19-ashrsi3_table
+	.byte		ashrsi3_20-ashrsi3_table
+	.byte		ashrsi3_21-ashrsi3_table
+	.byte		ashrsi3_22-ashrsi3_table
+	.byte		ashrsi3_23-ashrsi3_table
+	.byte		ashrsi3_24-ashrsi3_table
+	.byte		ashrsi3_25-ashrsi3_table
+	.byte		ashrsi3_26-ashrsi3_table
+	.byte		ashrsi3_27-ashrsi3_table
+	.byte		ashrsi3_28-ashrsi3_table
+	.byte		ashrsi3_29-ashrsi3_table
+	.byte		ashrsi3_30-ashrsi3_table
+	.byte		ashrsi3_31-ashrsi3_table
+
+ashrsi3_31:
+	rotcl	r0
+	rts
+	subc	r0,r0
+
+ashrsi3_30:
+	shar	r0
+ashrsi3_29:
+	shar	r0
+ashrsi3_28:
+	shar	r0
+ashrsi3_27:
+	shar	r0
+ashrsi3_26:
+	shar	r0
+ashrsi3_25:
+	shar	r0
+ashrsi3_24:
+	shlr16	r0
+	shlr8	r0
+	rts
+	exts.b	r0,r0
+
+ashrsi3_23:
+	shar	r0
+ashrsi3_22:
+	shar	r0
+ashrsi3_21:
+	shar	r0
+ashrsi3_20:
+	shar	r0
+ashrsi3_19:
+	shar	r0
+ashrsi3_18:
+	shar	r0
+ashrsi3_17:
+	shar	r0
+ashrsi3_16:
+	shlr16	r0
+	rts
+	exts.w	r0,r0
+
+ashrsi3_15:
+	shar	r0
+ashrsi3_14:
+	shar	r0
+ashrsi3_13:
+	shar	r0
+ashrsi3_12:
+	shar	r0
+ashrsi3_11:
+	shar	r0
+ashrsi3_10:
+	shar	r0
+ashrsi3_9:
+	shar	r0
+ashrsi3_8:
+	shar	r0
+ashrsi3_7:
+	shar	r0
+ashrsi3_6:
+	shar	r0
+ashrsi3_5:
+	shar	r0
+ashrsi3_4:
+	shar	r0
+ashrsi3_3:
+	shar	r0
+ashrsi3_2:
+	shar	r0
+ashrsi3_1:
+	rts
+	shar	r0
+
+ashrsi3_0:
+	rts
+	nop
diff --git a/arch/sh/lib/libgcc.h b/arch/sh/lib/libgcc.h
new file mode 100644
index 000000000000..3f19d1c5d942
--- /dev/null
+++ b/arch/sh/lib/libgcc.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#ifdef __BIG_ENDIAN
+struct DWstruct {
+	int high, low;
+};
+#elif defined(__LITTLE_ENDIAN)
+struct DWstruct {
+	int low, high;
+};
+#else
+#error I feel sick.
+#endif
+
+typedef union
+{
+	struct DWstruct s;
+	long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */
diff --git a/arch/sh/lib/lshrdi3.c b/arch/sh/lib/lshrdi3.c
new file mode 100644
index 000000000000..dcf8d6810b7c
--- /dev/null
+++ b/arch/sh/lib/lshrdi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.high = 0;
+		w.s.low = (unsigned int) uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = (unsigned int) uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S
new file mode 100644
index 000000000000..1e7aaa557130
--- /dev/null
+++ b/arch/sh/lib/lshrsi3.S
@@ -0,0 +1,193 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+!
+! __lshrsi3
+!
+! Entry:
+!
+! r4: Value to shift
+! r5: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
+!
+	.global	__lshrsi3
+	
+	.align	2
+__lshrsi3:
+	mov	#31,r0
+	and	r0,r5
+	mova	lshrsi3_table,r0
+	mov.b	@(r0,r5),r5
+#ifdef __sh1__
+	add	r5,r0
+	jmp	@r0
+#else
+	braf	r5
+#endif
+	mov	r4,r0
+
+	.align	2
+lshrsi3_table:
+	.byte		lshrsi3_0-lshrsi3_table
+	.byte		lshrsi3_1-lshrsi3_table
+	.byte		lshrsi3_2-lshrsi3_table
+	.byte		lshrsi3_3-lshrsi3_table
+	.byte		lshrsi3_4-lshrsi3_table
+	.byte		lshrsi3_5-lshrsi3_table
+	.byte		lshrsi3_6-lshrsi3_table
+	.byte		lshrsi3_7-lshrsi3_table
+	.byte		lshrsi3_8-lshrsi3_table
+	.byte		lshrsi3_9-lshrsi3_table
+	.byte		lshrsi3_10-lshrsi3_table
+	.byte		lshrsi3_11-lshrsi3_table
+	.byte		lshrsi3_12-lshrsi3_table
+	.byte		lshrsi3_13-lshrsi3_table
+	.byte		lshrsi3_14-lshrsi3_table
+	.byte		lshrsi3_15-lshrsi3_table
+	.byte		lshrsi3_16-lshrsi3_table
+	.byte		lshrsi3_17-lshrsi3_table
+	.byte		lshrsi3_18-lshrsi3_table
+	.byte		lshrsi3_19-lshrsi3_table
+	.byte		lshrsi3_20-lshrsi3_table
+	.byte		lshrsi3_21-lshrsi3_table
+	.byte		lshrsi3_22-lshrsi3_table
+	.byte		lshrsi3_23-lshrsi3_table
+	.byte		lshrsi3_24-lshrsi3_table
+	.byte		lshrsi3_25-lshrsi3_table
+	.byte		lshrsi3_26-lshrsi3_table
+	.byte		lshrsi3_27-lshrsi3_table
+	.byte		lshrsi3_28-lshrsi3_table
+	.byte		lshrsi3_29-lshrsi3_table
+	.byte		lshrsi3_30-lshrsi3_table
+	.byte		lshrsi3_31-lshrsi3_table
+
+lshrsi3_6:
+	shlr2	r0
+lshrsi3_4:
+	shlr2	r0
+lshrsi3_2:
+	rts
+	shlr2	r0
+
+lshrsi3_7:
+	shlr2	r0
+lshrsi3_5:
+	shlr2	r0
+lshrsi3_3:
+	shlr2	r0
+lshrsi3_1:
+	rts
+	shlr	r0
+
+lshrsi3_14:
+	shlr2	r0
+lshrsi3_12:
+	shlr2	r0
+lshrsi3_10:
+	shlr2	r0
+lshrsi3_8:
+	rts
+	shlr8	r0
+
+lshrsi3_15:
+	shlr2	r0
+lshrsi3_13:
+	shlr2	r0
+lshrsi3_11:
+	shlr2	r0
+lshrsi3_9:
+	shlr8	r0
+	rts
+	shlr	r0
+
+lshrsi3_22:
+	shlr2	r0
+lshrsi3_20:
+	shlr2	r0
+lshrsi3_18:
+	shlr2	r0
+lshrsi3_16:
+	rts
+	shlr16	r0
+
+lshrsi3_23:
+	shlr2	r0
+lshrsi3_21:
+	shlr2	r0
+lshrsi3_19:
+	shlr2	r0
+lshrsi3_17:
+	shlr16	r0
+	rts
+	shlr	r0
+
+lshrsi3_30:
+	shlr2	r0
+lshrsi3_28:
+	shlr2	r0
+lshrsi3_26:
+	shlr2	r0
+lshrsi3_24:
+	shlr16	r0
+	rts
+	shlr8	r0
+
+lshrsi3_31:
+	shlr2	r0
+lshrsi3_29:
+	shlr2	r0
+lshrsi3_27:
+	shlr2	r0
+lshrsi3_25:
+	shlr16	r0
+	shlr8	r0
+	rts
+	shlr	r0
+
+lshrsi3_0:
+	rts
+	nop
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
new file mode 100644
index 000000000000..110fbfe1831f
--- /dev/null
+++ b/arch/sh/lib/mcount.S
@@ -0,0 +1,90 @@
+/*
+ * arch/sh/lib/mcount.S
+ *
+ *  Copyright (C) 2008  Paul Mundt
+ *  Copyright (C) 2008  Matt Fleming
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <asm/ftrace.h>
+
+#define MCOUNT_ENTER()		\
+	mov.l	r4, @-r15;	\
+	mov.l	r5, @-r15;	\
+	mov.l	r6, @-r15;	\
+	mov.l	r7, @-r15;	\
+	sts.l	pr, @-r15;	\
+				\
+	mov.l	@(20,r15),r4;	\
+	sts	pr, r5
+
+#define MCOUNT_LEAVE()		\
+	lds.l	@r15+, pr;	\
+	mov.l	@r15+, r7;	\
+	mov.l	@r15+, r6;	\
+	mov.l	@r15+, r5;	\
+	rts;			\
+	 mov.l	@r15+, r4
+
+	.align 2
+	.globl	_mcount
+	.type	_mcount,@function
+	.globl	mcount
+	.type	mcount,@function
+_mcount:
+mcount:
+	MCOUNT_ENTER()
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+	.globl	mcount_call
+mcount_call:
+	mov.l	.Lftrace_stub, r6
+#else
+	mov.l	.Lftrace_trace_function, r6
+	mov.l	ftrace_stub, r7
+	cmp/eq	r6, r7
+	bt	skip_trace
+	mov.l	@r6, r6
+#endif
+
+	jsr	@r6
+	 nop
+
+skip_trace:
+	MCOUNT_LEAVE()
+
+	.align 2
+.Lftrace_trace_function:
+	.long	ftrace_trace_function
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+	.globl ftrace_caller
+ftrace_caller:
+	MCOUNT_ENTER()
+
+	.globl ftrace_call
+ftrace_call:
+	mov.l	.Lftrace_stub, r6
+	jsr	@r6
+	 nop
+
+	MCOUNT_LEAVE()
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * NOTE: From here on the locations of the .Lftrace_stub label and
+ * ftrace_stub itself are fixed. Adding additional data here will skew
+ * the displacement for the memory table and break the block replacement.
+ * Place new labels either after the ftrace_stub body, or before
+ * ftrace_caller. You have been warned.
+ */
+	.align 2
+.Lftrace_stub:
+	.long	ftrace_stub
+
+	.globl	ftrace_stub
+ftrace_stub:
+	rts
+	 nop
diff --git a/arch/sh/lib/movmem.S b/arch/sh/lib/movmem.S
new file mode 100644
index 000000000000..62075f6bc67c
--- /dev/null
+++ b/arch/sh/lib/movmem.S
@@ -0,0 +1,238 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+	.text
+	.balign	4
+	.global	__movmem
+	.global __movstr
+	.set __movstr, __movmem	
+	/* This would be a lot simpler if r6 contained the byte count
+	   minus 64, and we wouldn't be called here for a byte count of 64.  */
+__movmem:
+	sts.l	pr,@-r15
+	shll2	r6
+	bsr	__movmemSI52+2
+	mov.l	@(48,r5),r0
+	.balign	4
+movmem_loop: /* Reached with rts */
+	mov.l	@(60,r5),r0
+	add	#-64,r6
+	mov.l	r0,@(60,r4)
+	tst	r6,r6
+	mov.l	@(56,r5),r0
+	bt	movmem_done
+	mov.l	r0,@(56,r4)
+	cmp/pl	r6
+	mov.l	@(52,r5),r0
+	add	#64,r5
+	mov.l	r0,@(52,r4)
+	add	#64,r4
+	bt	__movmemSI52
+! done all the large groups, do the remainder
+! jump to movmem+
+	mova	__movmemSI4+4,r0
+	add	r6,r0
+	jmp	@r0
+movmem_done: ! share slot insn, works out aligned.
+	lds.l	@r15+,pr
+	mov.l	r0,@(56,r4)
+	mov.l	@(52,r5),r0
+	rts
+	mov.l	r0,@(52,r4)
+	.balign	4
+
+	.global	__movmemSI64
+	.global __movstrSI64
+	.set	__movstrSI64, __movmemSI64
+__movmemSI64:
+	mov.l	@(60,r5),r0
+	mov.l	r0,@(60,r4)
+	.global	__movmemSI60
+	.global __movstrSI60
+	.set	__movstrSI60, __movmemSI60
+__movmemSI60:
+	mov.l	@(56,r5),r0
+	mov.l	r0,@(56,r4)
+	.global	__movmemSI56
+	.global __movstrSI56
+	.set	__movstrSI56, __movmemSI56
+__movmemSI56:
+	mov.l	@(52,r5),r0
+	mov.l	r0,@(52,r4)
+	.global	__movmemSI52
+	.global __movstrSI52
+	.set	__movstrSI52, __movmemSI52
+__movmemSI52:
+	mov.l	@(48,r5),r0
+	mov.l	r0,@(48,r4)
+	.global	__movmemSI48
+	.global	__movstrSI48
+	.set	__movstrSI48, __movmemSI48
+__movmemSI48:
+	mov.l	@(44,r5),r0
+	mov.l	r0,@(44,r4)
+	.global	__movmemSI44
+	.global	__movstrSI44
+	.set	__movstrSI44, __movmemSI44
+__movmemSI44:
+	mov.l	@(40,r5),r0
+	mov.l	r0,@(40,r4)
+	.global	__movmemSI40
+	.global __movstrSI40
+	.set	__movstrSI40, __movmemSI40
+__movmemSI40:
+	mov.l	@(36,r5),r0
+	mov.l	r0,@(36,r4)
+	.global	__movmemSI36
+	.global	__movstrSI36
+	.set	__movstrSI36, __movmemSI36
+__movmemSI36:
+	mov.l	@(32,r5),r0
+	mov.l	r0,@(32,r4)
+	.global	__movmemSI32
+	.global	__movstrSI32
+	.set	__movstrSI32, __movmemSI32
+__movmemSI32:
+	mov.l	@(28,r5),r0
+	mov.l	r0,@(28,r4)
+	.global	__movmemSI28
+	.global	__movstrSI28
+	.set	__movstrSI28, __movmemSI28
+__movmemSI28:
+	mov.l	@(24,r5),r0
+	mov.l	r0,@(24,r4)
+	.global	__movmemSI24
+	.global	__movstrSI24
+	.set	__movstrSI24, __movmemSI24
+__movmemSI24:
+	mov.l	@(20,r5),r0
+	mov.l	r0,@(20,r4)
+	.global	__movmemSI20
+	.global	__movstrSI20
+	.set	__movstrSI20, __movmemSI20
+__movmemSI20:
+	mov.l	@(16,r5),r0
+	mov.l	r0,@(16,r4)
+	.global	__movmemSI16
+	.global	__movstrSI16
+	.set	__movstrSI16, __movmemSI16
+__movmemSI16:
+	mov.l	@(12,r5),r0
+	mov.l	r0,@(12,r4)
+	.global	__movmemSI12
+	.global	__movstrSI12
+	.set	__movstrSI12, __movmemSI12
+__movmemSI12:
+	mov.l	@(8,r5),r0
+	mov.l	r0,@(8,r4)
+	.global	__movmemSI8
+	.global	__movstrSI8
+	.set	__movstrSI8, __movmemSI8
+__movmemSI8:
+	mov.l	@(4,r5),r0
+	mov.l	r0,@(4,r4)
+	.global	__movmemSI4
+	.global	__movstrSI4
+	.set	__movstrSI4, __movmemSI4
+__movmemSI4:
+	mov.l	@(0,r5),r0
+	rts
+	mov.l	r0,@(0,r4)
+
+	.global	__movmem_i4_even
+	.global	__movstr_i4_even
+	.set	__movstr_i4_even, __movmem_i4_even
+
+	.global	__movmem_i4_odd
+	.global	__movstr_i4_odd
+	.set	__movstr_i4_odd, __movmem_i4_odd
+
+	.global	__movmemSI12_i4
+	.global	__movstrSI12_i4
+	.set	__movstrSI12_i4, __movmemSI12_i4
+
+	.p2align	5
+L_movmem_2mod4_end:
+	mov.l	r0,@(16,r4)
+	rts
+	mov.l	r1,@(20,r4)
+
+	.p2align	2
+
+__movmem_i4_even:
+	mov.l	@r5+,r0
+	bra	L_movmem_start_even
+	mov.l	@r5+,r1
+
+__movmem_i4_odd:
+	mov.l	@r5+,r1
+	add	#-4,r4
+	mov.l	@r5+,r2
+	mov.l	@r5+,r3
+	mov.l	r1,@(4,r4)
+	mov.l	r2,@(8,r4)
+
+L_movmem_loop:
+	mov.l	r3,@(12,r4)
+	dt	r6
+	mov.l	@r5+,r0
+	bt/s	L_movmem_2mod4_end
+	mov.l	@r5+,r1
+	add	#16,r4
+L_movmem_start_even:
+	mov.l	@r5+,r2
+	mov.l	@r5+,r3
+	mov.l	r0,@r4
+	dt	r6
+	mov.l	r1,@(4,r4)
+	bf/s	L_movmem_loop
+	mov.l	r2,@(8,r4)
+	rts
+	mov.l	r3,@(12,r4)
+
+	.p2align	4
+__movmemSI12_i4:
+	mov.l	@r5,r0
+	mov.l	@(4,r5),r1
+	mov.l	@(8,r5),r2
+	mov.l	r0,@r4
+	mov.l	r1,@(4,r4)
+	rts
+	mov.l	r2,@(8,r4)
diff --git a/arch/sh/lib/udiv_qrnnd.S b/arch/sh/lib/udiv_qrnnd.S
new file mode 100644
index 000000000000..32b9a36de943
--- /dev/null
+++ b/arch/sh/lib/udiv_qrnnd.S
@@ -0,0 +1,81 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+	/* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */
+	/* n1 < d, but n1 might be larger than d1.  */
+	.global __udiv_qrnnd_16
+	.balign 8
+__udiv_qrnnd_16:
+	div0u
+	cmp/hi r6,r0
+	bt .Lots
+	.rept 16
+	div1 r6,r0 
+	.endr
+	extu.w r0,r1
+	bt 0f
+	add r6,r0
+0:	rotcl r1
+	mulu.w r1,r5
+	xtrct r4,r0
+	swap.w r0,r0
+	sts macl,r2
+	cmp/hs r2,r0
+	sub r2,r0
+	bt 0f
+	addc r5,r0
+	add #-1,r1
+	bt 0f
+1:	add #-1,r1
+	rts
+	add r5,r0
+	.balign 8
+.Lots:
+	sub r5,r0
+	swap.w r4,r1
+	xtrct r0,r1
+	clrt
+	mov r1,r0
+	addc r5,r0
+	mov #-1,r1
+	bf/s 1b
+	 shlr16 r1
+0:	rts
+	 nop
diff --git a/arch/sh/lib/udivsi3.S b/arch/sh/lib/udivsi3.S
new file mode 100644
index 000000000000..72157ab5c314
--- /dev/null
+++ b/arch/sh/lib/udivsi3.S
@@ -0,0 +1,87 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+	.balign 4
+	.global	__udivsi3
+	.type	__udivsi3, @function
+div8:
+	div1 r5,r4
+div7:
+	div1 r5,r4; div1 r5,r4; div1 r5,r4
+	div1 r5,r4; div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
+
+divx4:
+	div1 r5,r4; rotcl r0
+	div1 r5,r4; rotcl r0
+	div1 r5,r4; rotcl r0
+	rts; div1 r5,r4
+
+__udivsi3:
+	sts.l pr,@-r15
+	extu.w r5,r0
+	cmp/eq r5,r0
+	bf/s large_divisor
+	div0u
+	swap.w r4,r0
+	shlr16 r4
+	bsr div8
+	shll16 r5
+	bsr div7
+	div1 r5,r4
+	xtrct r4,r0
+	xtrct r0,r4
+	bsr div8
+	swap.w r4,r4
+	bsr div7
+	div1 r5,r4
+	lds.l @r15+,pr
+	xtrct r4,r0
+	swap.w r0,r0
+	rotcl r0
+	rts
+	shlr16 r5
+
+large_divisor:
+	mov #0,r0
+	xtrct r4,r0
+	xtrct r0,r4
+	bsr divx4
+	rotcl r0
+	bsr divx4
+	rotcl r0
+	bsr divx4
+	rotcl r0
+	bsr divx4
+	rotcl r0
+	lds.l @r15+,pr
+	rts
+	rotcl r0
diff --git a/arch/sh/lib/udivsi3_i4i-Os.S b/arch/sh/lib/udivsi3_i4i-Os.S
new file mode 100644
index 000000000000..4835553e1ea9
--- /dev/null
+++ b/arch/sh/lib/udivsi3_i4i-Os.S
@@ -0,0 +1,149 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* Moderately Space-optimized libgcc routines for the Renesas SH /
+   STMicroelectronics ST40 CPUs.
+   Contributed by J"orn Rennecke joern.rennecke@st.com.  */
+
+/* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i
+   sh4-200 run times:
+   udiv small divisor: 55 cycles
+   udiv large divisor: 52 cycles
+   sdiv small divisor, positive result: 59 cycles
+   sdiv large divisor, positive result: 56 cycles
+   sdiv small divisor, negative result: 65 cycles (*)
+   sdiv large divisor, negative result: 62 cycles (*)
+   (*): r2 is restored in the rts delay slot and has a lingering latency
+        of two more cycles.  */
+	.balign 4
+	.global	__udivsi3_i4i
+	.global	__udivsi3_i4
+	.set	__udivsi3_i4, __udivsi3_i4i
+	.type	__udivsi3_i4i, @function
+	.type	__sdivsi3_i4i, @function
+__udivsi3_i4i:
+	sts pr,r1
+	mov.l r4,@-r15
+	extu.w r5,r0
+	cmp/eq r5,r0
+	swap.w r4,r0
+	shlr16 r4
+	bf/s large_divisor
+	div0u
+	mov.l r5,@-r15
+	shll16 r5
+sdiv_small_divisor:
+	div1 r5,r4
+	bsr div6
+	div1 r5,r4
+	div1 r5,r4
+	bsr div6
+	div1 r5,r4
+	xtrct r4,r0
+	xtrct r0,r4
+	bsr div7
+	swap.w r4,r4
+	div1 r5,r4
+	bsr div7
+	div1 r5,r4
+	xtrct r4,r0
+	mov.l @r15+,r5
+	swap.w r0,r0
+	mov.l @r15+,r4
+	jmp @r1
+	rotcl r0
+div7:
+	div1 r5,r4
+div6:
+	            div1 r5,r4; div1 r5,r4; div1 r5,r4
+	div1 r5,r4; div1 r5,r4; rts;        div1 r5,r4
+
+divx3:
+	rotcl r0
+	div1 r5,r4
+	rotcl r0
+	div1 r5,r4
+	rotcl r0
+	rts
+	div1 r5,r4
+
+large_divisor:
+	mov.l r5,@-r15
+sdiv_large_divisor:
+	xor r4,r0
+	.rept 4
+	rotcl r0
+	bsr divx3
+	div1 r5,r4
+	.endr
+	mov.l @r15+,r5
+	mov.l @r15+,r4
+	jmp @r1
+	rotcl r0
+
+	.global	__sdivsi3_i4i
+	.global __sdivsi3_i4
+	.global __sdivsi3
+	.set	__sdivsi3_i4, __sdivsi3_i4i
+	.set	__sdivsi3, __sdivsi3_i4i
+__sdivsi3_i4i:
+	mov.l r4,@-r15
+	cmp/pz r5
+	mov.l r5,@-r15
+	bt/s pos_divisor
+	cmp/pz r4
+	neg r5,r5
+	extu.w r5,r0
+	bt/s neg_result
+	cmp/eq r5,r0
+	neg r4,r4
+pos_result:
+	swap.w r4,r0
+	bra sdiv_check_divisor
+	sts pr,r1
+pos_divisor:
+	extu.w r5,r0
+	bt/s pos_result
+	cmp/eq r5,r0
+	neg r4,r4
+neg_result:
+	mova negate_result,r0
+	;
+	mov r0,r1
+	swap.w r4,r0
+	lds r2,macl
+	sts pr,r2
+sdiv_check_divisor:
+	shlr16 r4
+	bf/s sdiv_large_divisor
+	div0u
+	bra sdiv_small_divisor
+	shll16 r5
+	.balign 4
+negate_result:
+	neg r0,r0
+	jmp @r2
+	sts macl,r2
diff --git a/arch/sh/lib/udivsi3_i4i.S b/arch/sh/lib/udivsi3_i4i.S
new file mode 100644
index 000000000000..f1a79d9c5015
--- /dev/null
+++ b/arch/sh/lib/udivsi3_i4i.S
@@ -0,0 +1,666 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+!! libgcc routines for the Renesas / SuperH SH CPUs.
+!! Contributed by Steve Chamberlain.
+!! sac@cygnus.com
+
+!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
+!! recoded in assembly by Toshiyasu Morita
+!! tm@netcom.com
+
+/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
+   ELF local label prefixes by J"orn Rennecke
+   amylaar@cygnus.com  */
+
+/* This code used shld, thus is not suitable for SH1 / SH2.  */
+
+/* Signed / unsigned division without use of FPU, optimized for SH4.
+   Uses a lookup table for divisors in the range -128 .. +128, and
+   div1 with case distinction for larger divisors in three more ranges.
+   The code is lumped together with the table to allow the use of mova.  */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define L_LSB 0
+#define L_LSWMSB 1
+#define L_MSWLSB 2
+#else
+#define L_LSB 3
+#define L_LSWMSB 2
+#define L_MSWLSB 1
+#endif
+
+	.balign 4
+	.global	__udivsi3_i4i
+	.global	__udivsi3_i4
+	.set	__udivsi3_i4, __udivsi3_i4i
+	.type	__udivsi3_i4i, @function
+__udivsi3_i4i:
+	mov.w c128_w, r1
+	div0u
+	mov r4,r0
+	shlr8 r0
+	cmp/hi r1,r5
+	extu.w r5,r1
+	bf udiv_le128
+	cmp/eq r5,r1
+	bf udiv_ge64k
+	shlr r0
+	mov r5,r1
+	shll16 r5
+	mov.l r4,@-r15
+	div1 r5,r0
+	mov.l r1,@-r15
+	div1 r5,r0
+	div1 r5,r0
+	bra udiv_25
+	div1 r5,r0
+
+div_le128:
+	mova div_table_ix,r0
+	bra div_le128_2
+	mov.b @(r0,r5),r1
+udiv_le128:
+	mov.l r4,@-r15
+	mova div_table_ix,r0
+	mov.b @(r0,r5),r1
+	mov.l r5,@-r15
+div_le128_2:
+	mova div_table_inv,r0
+	mov.l @(r0,r1),r1
+	mov r5,r0
+	tst #0xfe,r0
+	mova div_table_clz,r0
+	dmulu.l r1,r4
+	mov.b @(r0,r5),r1
+	bt/s div_by_1
+	mov r4,r0
+	mov.l @r15+,r5
+	sts mach,r0
+	/* clrt */
+	addc r4,r0
+	mov.l @r15+,r4
+	rotcr r0
+	rts
+	shld r1,r0
+
+div_by_1_neg:
+	neg r4,r0
+div_by_1:
+	mov.l @r15+,r5
+	rts
+	mov.l @r15+,r4
+
+div_ge64k:
+	bt/s div_r8
+	div0u
+	shll8 r5
+	bra div_ge64k_2
+	div1 r5,r0
+udiv_ge64k:
+	cmp/hi r0,r5
+	mov r5,r1
+	bt udiv_r8
+	shll8 r5
+	mov.l r4,@-r15
+	div1 r5,r0
+	mov.l r1,@-r15
+div_ge64k_2:
+	div1 r5,r0
+	mov.l zero_l,r1
+	.rept 4
+	div1 r5,r0
+	.endr
+	mov.l r1,@-r15
+	div1 r5,r0
+	mov.w m256_w,r1
+	div1 r5,r0
+	mov.b r0,@(L_LSWMSB,r15)
+	xor r4,r0
+	and r1,r0
+	bra div_ge64k_end
+	xor r4,r0
+	
+div_r8:
+	shll16 r4
+	bra div_r8_2
+	shll8 r4
+udiv_r8:
+	mov.l r4,@-r15
+	shll16 r4
+	clrt
+	shll8 r4
+	mov.l r5,@-r15
+div_r8_2:
+	rotcl r4
+	mov r0,r1
+	div1 r5,r1
+	mov r4,r0
+	rotcl r0
+	mov r5,r4
+	div1 r5,r1
+	.rept 5
+	rotcl r0; div1 r5,r1
+	.endr
+	rotcl r0
+	mov.l @r15+,r5
+	div1 r4,r1
+	mov.l @r15+,r4
+	rts
+	rotcl r0
+
+	.global	__sdivsi3_i4i
+	.global __sdivsi3_i4
+	.global	__sdivsi3
+	.set	__sdivsi3_i4, __sdivsi3_i4i
+	.set	__sdivsi3, __sdivsi3_i4i
+	.type	__sdivsi3_i4i, @function
+	/* This is link-compatible with a __sdivsi3 call,
+	   but we effectively clobber only r1.  */
+__sdivsi3_i4i:
+	mov.l r4,@-r15
+	cmp/pz r5
+	mov.w c128_w, r1
+	bt/s pos_divisor
+	cmp/pz r4
+	mov.l r5,@-r15
+	neg r5,r5
+	bt/s neg_result
+	cmp/hi r1,r5
+	neg r4,r4
+pos_result:
+	extu.w r5,r0
+	bf div_le128
+	cmp/eq r5,r0
+	mov r4,r0
+	shlr8 r0
+	bf/s div_ge64k
+	cmp/hi r0,r5
+	div0u
+	shll16 r5
+	div1 r5,r0
+	div1 r5,r0
+	div1 r5,r0
+udiv_25:
+	mov.l zero_l,r1
+	div1 r5,r0
+	div1 r5,r0
+	mov.l r1,@-r15
+	.rept 3
+	div1 r5,r0
+	.endr
+	mov.b r0,@(L_MSWLSB,r15)
+	xtrct r4,r0
+	swap.w r0,r0
+	.rept 8
+	div1 r5,r0
+	.endr
+	mov.b r0,@(L_LSWMSB,r15)
+div_ge64k_end:
+	.rept 8
+	div1 r5,r0
+	.endr
+	mov.l @r15+,r4 ! zero-extension and swap using LS unit.
+	extu.b r0,r0
+	mov.l @r15+,r5
+	or r4,r0
+	mov.l @r15+,r4
+	rts
+	rotcl r0
+
+div_le128_neg:
+	tst #0xfe,r0
+	mova div_table_ix,r0
+	mov.b @(r0,r5),r1
+	mova div_table_inv,r0
+	bt/s div_by_1_neg
+	mov.l @(r0,r1),r1
+	mova div_table_clz,r0
+	dmulu.l r1,r4
+	mov.b @(r0,r5),r1
+	mov.l @r15+,r5
+	sts mach,r0
+	/* clrt */
+	addc r4,r0
+	mov.l @r15+,r4
+	rotcr r0
+	shld r1,r0
+	rts
+	neg r0,r0
+
+pos_divisor:
+	mov.l r5,@-r15
+	bt/s pos_result
+	cmp/hi r1,r5
+	neg r4,r4
+neg_result:
+	extu.w r5,r0
+	bf div_le128_neg
+	cmp/eq r5,r0
+	mov r4,r0
+	shlr8 r0
+	bf/s div_ge64k_neg
+	cmp/hi r0,r5
+	div0u
+	mov.l zero_l,r1
+	shll16 r5
+	div1 r5,r0
+	mov.l r1,@-r15
+	.rept 7
+	div1 r5,r0
+	.endr
+	mov.b r0,@(L_MSWLSB,r15)
+	xtrct r4,r0
+	swap.w r0,r0
+	.rept 8
+	div1 r5,r0
+	.endr
+	mov.b r0,@(L_LSWMSB,r15)
+div_ge64k_neg_end:
+	.rept 8
+	div1 r5,r0
+	.endr
+	mov.l @r15+,r4 ! zero-extension and swap using LS unit.
+	extu.b r0,r1
+	mov.l @r15+,r5
+	or r4,r1
+div_r8_neg_end:
+	mov.l @r15+,r4
+	rotcl r1
+	rts
+	neg r1,r0
+
+div_ge64k_neg:
+	bt/s div_r8_neg
+	div0u
+	shll8 r5
+	mov.l zero_l,r1
+	.rept 6
+	div1 r5,r0
+	.endr
+	mov.l r1,@-r15
+	div1 r5,r0
+	mov.w m256_w,r1
+	div1 r5,r0
+	mov.b r0,@(L_LSWMSB,r15)
+	xor r4,r0
+	and r1,r0
+	bra div_ge64k_neg_end
+	xor r4,r0
+
+c128_w:
+	.word 128
+
+div_r8_neg:
+	clrt
+	shll16 r4
+	mov r4,r1
+	shll8 r1
+	mov r5,r4
+	.rept 7
+	rotcl r1; div1 r5,r0
+	.endr
+	mov.l @r15+,r5
+	rotcl r1
+	bra div_r8_neg_end
+	div1 r4,r0
+
+m256_w:
+	.word 0xff00
+/* This table has been generated by divtab-sh4.c.  */
+	.balign 4
+div_table_clz:
+	.byte	0
+	.byte	1
+	.byte	0
+	.byte	-1
+	.byte	-1
+	.byte	-2
+	.byte	-2
+	.byte	-2
+	.byte	-2
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-3
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-4
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-5
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+	.byte	-6
+/* Lookup table translating positive divisor to index into table of
+   normalized inverse.  N.B. the '0' entry is also the last entry of the
+ previous table, and causes an unaligned access for division by zero.  */
+div_table_ix:
+	.byte	-6
+	.byte	-128
+	.byte	-128
+	.byte	0
+	.byte	-128
+	.byte	-64
+	.byte	0
+	.byte	64
+	.byte	-128
+	.byte	-96
+	.byte	-64
+	.byte	-32
+	.byte	0
+	.byte	32
+	.byte	64
+	.byte	96
+	.byte	-128
+	.byte	-112
+	.byte	-96
+	.byte	-80
+	.byte	-64
+	.byte	-48
+	.byte	-32
+	.byte	-16
+	.byte	0
+	.byte	16
+	.byte	32
+	.byte	48
+	.byte	64
+	.byte	80
+	.byte	96
+	.byte	112
+	.byte	-128
+	.byte	-120
+	.byte	-112
+	.byte	-104
+	.byte	-96
+	.byte	-88
+	.byte	-80
+	.byte	-72
+	.byte	-64
+	.byte	-56
+	.byte	-48
+	.byte	-40
+	.byte	-32
+	.byte	-24
+	.byte	-16
+	.byte	-8
+	.byte	0
+	.byte	8
+	.byte	16
+	.byte	24
+	.byte	32
+	.byte	40
+	.byte	48
+	.byte	56
+	.byte	64
+	.byte	72
+	.byte	80
+	.byte	88
+	.byte	96
+	.byte	104
+	.byte	112
+	.byte	120
+	.byte	-128
+	.byte	-124
+	.byte	-120
+	.byte	-116
+	.byte	-112
+	.byte	-108
+	.byte	-104
+	.byte	-100
+	.byte	-96
+	.byte	-92
+	.byte	-88
+	.byte	-84
+	.byte	-80
+	.byte	-76
+	.byte	-72
+	.byte	-68
+	.byte	-64
+	.byte	-60
+	.byte	-56
+	.byte	-52
+	.byte	-48
+	.byte	-44
+	.byte	-40
+	.byte	-36
+	.byte	-32
+	.byte	-28
+	.byte	-24
+	.byte	-20
+	.byte	-16
+	.byte	-12
+	.byte	-8
+	.byte	-4
+	.byte	0
+	.byte	4
+	.byte	8
+	.byte	12
+	.byte	16
+	.byte	20
+	.byte	24
+	.byte	28
+	.byte	32
+	.byte	36
+	.byte	40
+	.byte	44
+	.byte	48
+	.byte	52
+	.byte	56
+	.byte	60
+	.byte	64
+	.byte	68
+	.byte	72
+	.byte	76
+	.byte	80
+	.byte	84
+	.byte	88
+	.byte	92
+	.byte	96
+	.byte	100
+	.byte	104
+	.byte	108
+	.byte	112
+	.byte	116
+	.byte	120
+	.byte	124
+	.byte	-128
+/* 1/64 .. 1/127, normalized.  There is an implicit leading 1 in bit 32.  */
+	.balign 4
+zero_l:
+	.long	0x0
+	.long	0xF81F81F9
+	.long	0xF07C1F08
+	.long	0xE9131AC0
+	.long	0xE1E1E1E2
+	.long	0xDAE6076C
+	.long	0xD41D41D5
+	.long	0xCD856891
+	.long	0xC71C71C8
+	.long	0xC0E07039
+	.long	0xBACF914D
+	.long	0xB4E81B4F
+	.long	0xAF286BCB
+	.long	0xA98EF607
+	.long	0xA41A41A5
+	.long	0x9EC8E952
+	.long	0x9999999A
+	.long	0x948B0FCE
+	.long	0x8F9C18FA
+	.long	0x8ACB90F7
+	.long	0x86186187
+	.long	0x81818182
+	.long	0x7D05F418
+	.long	0x78A4C818
+	.long	0x745D1746
+	.long	0x702E05C1
+	.long	0x6C16C16D
+	.long	0x68168169
+	.long	0x642C8591
+	.long	0x60581606
+	.long	0x5C9882BA
+	.long	0x58ED2309
+div_table_inv:
+	.long	0x55555556
+	.long	0x51D07EAF
+	.long	0x4E5E0A73
+	.long	0x4AFD6A06
+	.long	0x47AE147B
+	.long	0x446F8657
+	.long	0x41414142
+	.long	0x3E22CBCF
+	.long	0x3B13B13C
+	.long	0x38138139
+	.long	0x3521CFB3
+	.long	0x323E34A3
+	.long	0x2F684BDB
+	.long	0x2C9FB4D9
+	.long	0x29E4129F
+	.long	0x27350B89
+	.long	0x24924925
+	.long	0x21FB7813
+	.long	0x1F7047DD
+	.long	0x1CF06ADB
+	.long	0x1A7B9612
+	.long	0x18118119
+	.long	0x15B1E5F8
+	.long	0x135C8114
+	.long	0x11111112
+	.long	0xECF56BF
+	.long	0xC9714FC
+	.long	0xA6810A7
+	.long	0x8421085
+	.long	0x624DD30
+	.long	0x4104105
+	.long	0x2040811
+	/* maximum error: 0.987342 scaled: 0.921875*/
diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile
index 9950966923a0..4bacb9e83478 100644
--- a/arch/sh/lib64/Makefile
+++ b/arch/sh/lib64/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the SH-5 specific library files..
 #
 # Copyright (C) 2000, 2001  Paolo Alberelli
-# Copyright (C) 2003  Paul Mundt
+# Copyright (C) 2003 - 2008  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
@@ -10,6 +10,8 @@
 #
 
 # Panic should really be compiled as PIC
-lib-y  := udelay.o c-checksum.o dbg.o panic.o memcpy.o copy_user_memcpy.o \
-		copy_page.o clear_page.o
+lib-y  := udelay.o c-checksum.o dbg.o panic.o memcpy.o memset.o \
+	  copy_user_memcpy.o copy_page.o clear_page.o strcpy.o strlen.o
 
+# Extracted from libgcc
+lib-y	+= udivsi3.o udivdi3.o sdivsi3.o
diff --git a/arch/sh/lib64/c-checksum.c b/arch/sh/lib64/c-checksum.c
index 5c284e0cff9c..73c0877e3a29 100644
--- a/arch/sh/lib64/c-checksum.c
+++ b/arch/sh/lib64/c-checksum.c
@@ -35,7 +35,7 @@ static inline unsigned short foldto16(unsigned long x)
 
 static inline unsigned short myfoldto16(unsigned long long x)
 {
-	/* Fold down to 32-bits so we don't loose in the typedef-less
+	/* Fold down to 32-bits so we don't lose in the typedef-less
 	   network stack.  */
 	/* 64 to 33 */
 	x = (x & 0xffffffff) + (x >> 32);
@@ -199,7 +199,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 	result = (__force u64) saddr + (__force u64) daddr +
 		 (__force u64) sum + ((len + proto) << 8);
 
-	/* Fold down to 32-bits so we don't loose in the typedef-less
+	/* Fold down to 32-bits so we don't lose in the typedef-less
 	   network stack.  */
 	/* 64 to 33 */
 	result = (result & 0xffffffff) + (result >> 32);
diff --git a/arch/sh/lib64/memcpy.S b/arch/sh/lib64/memcpy.S
new file mode 100644
index 000000000000..dd300c372ce1
--- /dev/null
+++ b/arch/sh/lib64/memcpy.S
@@ -0,0 +1,201 @@
+/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
+/* Modified by SuperH, Inc. September 2003 */
+!
+! Fast SH memcpy
+!
+! by Toshiyasu Morita (tm@netcom.com)
+! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut)
+! SH5 code Copyright 2002 SuperH Ltd.
+!
+! Entry: ARG0: destination pointer
+!        ARG1: source pointer
+!        ARG2: byte count
+!
+! Exit:  RESULT: destination pointer
+!        any other registers in the range r0-r7: trashed
+!
+! Notes: Usually one wants to do small reads and write a longword, but
+!        unfortunately it is difficult in some cases to concatanate bytes
+!        into a longword on the SH, so this does a longword read and small
+!        writes.
+!
+! This implementation makes two assumptions about how it is called:
+!
+! 1.: If the byte count is nonzero, the address of the last byte to be
+!     copied is unsigned greater than the address of the first byte to
+!     be copied.  This could be easily swapped for a signed comparison,
+!     but the algorithm used needs some comparison.
+!
+! 2.: When there are two or three bytes in the last word of an 11-or-more
+!     bytes memory chunk to b copied, the rest of the word can be read
+!     without side effects.
+!     This could be easily changed by increasing the minumum size of
+!     a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2,
+!     however, this would cost a few extra cyles on average.
+!     For SHmedia, the assumption is that any quadword can be read in its
+!     enirety if at least one byte is included in the copy.
+!
+
+	.section .text..SHmedia32,"ax"
+	.globl	memcpy
+	.type	memcpy, @function
+	.align	5
+
+memcpy:
+
+#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1
+#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1
+#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1
+#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1
+
+	ld.b r3,0,r63
+	pta/l Large,tr0
+	movi 25,r0
+	bgeu/u r4,r0,tr0
+	nsb r4,r0
+	shlli r0,5,r0
+	movi (L1-L0+63*32 + 1) & 0xffff,r1
+	sub r1, r0, r0
+L0:	ptrel r0,tr0
+	add r2,r4,r5
+	ptabs r18,tr1
+	add r3,r4,r6
+	blink tr0,r63
+	
+/* Rearranged to make cut2 safe */
+	.balign 8
+L4_7:	/* 4..7 byte memcpy cntd. */
+	stlo.l r2, 0, r0
+	or r6, r7, r6
+	sthi.l r5, -1, r6
+	stlo.l r5, -4, r6
+	blink tr1,r63
+
+	.balign 8
+L1:	/* 0 byte memcpy */
+	nop
+	blink tr1,r63
+	nop
+	nop
+	nop
+	nop
+
+L2_3:	/* 2 or 3 byte memcpy cntd. */
+	st.b r5,-1,r6
+	blink tr1,r63
+
+	/* 1 byte memcpy */
+	ld.b r3,0,r0
+	st.b r2,0,r0
+	blink tr1,r63
+
+L8_15:	/* 8..15 byte memcpy cntd. */
+	stlo.q r2, 0, r0
+	or r6, r7, r6
+	sthi.q r5, -1, r6
+	stlo.q r5, -8, r6
+	blink tr1,r63
+	
+	/* 2 or 3 byte memcpy */
+	ld.b r3,0,r0
+	ld.b r2,0,r63
+	ld.b r3,1,r1
+	st.b r2,0,r0
+	pta/l L2_3,tr0
+	ld.b r6,-1,r6
+	st.b r2,1,r1
+	blink tr0, r63
+
+	/* 4 .. 7 byte memcpy */
+	LDUAL (r3, 0, r0, r1)
+	pta L4_7, tr0
+	ldlo.l r6, -4, r7
+	or r0, r1, r0
+	sthi.l r2, 3, r0
+	ldhi.l r6, -1, r6
+	blink tr0, r63
+
+	/* 8 .. 15 byte memcpy */
+	LDUAQ (r3, 0, r0, r1)
+	pta L8_15, tr0
+	ldlo.q r6, -8, r7
+	or r0, r1, r0
+	sthi.q r2, 7, r0
+	ldhi.q r6, -1, r6
+	blink tr0, r63
+
+	/* 16 .. 24 byte memcpy */
+	LDUAQ (r3, 0, r0, r1)
+	LDUAQ (r3, 8, r8, r9)
+	or r0, r1, r0
+	sthi.q r2, 7, r0
+	or r8, r9, r8
+	sthi.q r2, 15, r8
+	ldlo.q r6, -8, r7
+	ldhi.q r6, -1, r6
+	stlo.q r2, 8, r8
+	stlo.q r2, 0, r0
+	or r6, r7, r6
+	sthi.q r5, -1, r6
+	stlo.q r5, -8, r6
+	blink tr1,r63
+
+Large:
+	ld.b r2, 0, r63
+	pta/l  Loop_ua, tr1
+	ori r3, -8, r7
+	sub r2, r7, r22
+	sub r3, r2, r6
+	add r2, r4, r5
+	ldlo.q r3, 0, r0
+	addi r5, -16, r5
+	movi 64+8, r27 // could subtract r7 from that.
+	stlo.q r2, 0, r0
+	sthi.q r2, 7, r0
+	ldx.q r22, r6, r0
+	bgtu/l r27, r4, tr1
+
+	addi r5, -48, r27
+	pta/l Loop_line, tr0
+	addi r6, 64, r36
+	addi r6, -24, r19
+	addi r6, -16, r20
+	addi r6, -8, r21
+
+Loop_line:
+	ldx.q r22, r36, r63
+	alloco r22, 32
+	addi r22, 32, r22
+	ldx.q r22, r19, r23
+	sthi.q r22, -25, r0
+	ldx.q r22, r20, r24
+	ldx.q r22, r21, r25
+	stlo.q r22, -32, r0
+	ldx.q r22, r6,  r0
+	sthi.q r22, -17, r23
+	sthi.q r22,  -9, r24
+	sthi.q r22,  -1, r25
+	stlo.q r22, -24, r23
+	stlo.q r22, -16, r24
+	stlo.q r22,  -8, r25
+	bgeu r27, r22, tr0
+
+Loop_ua:
+	addi r22, 8, r22
+	sthi.q r22, -1, r0
+	stlo.q r22, -8, r0
+	ldx.q r22, r6, r0
+	bgtu/l r5, r22, tr1
+
+	add r3, r4, r7
+	ldlo.q r7, -8, r1
+	sthi.q r22, 7, r0
+	ldhi.q r7, -1, r7
+	ptabs r18,tr1
+	stlo.q r22, 0, r0
+	or r1, r7, r1
+	sthi.q r5, 15, r1
+	stlo.q r5, 8, r1
+	blink tr1, r63
+
+	.size memcpy,.-memcpy
diff --git a/arch/sh/lib64/memcpy.c b/arch/sh/lib64/memcpy.c
deleted file mode 100644
index fba436a92bfa..000000000000
--- a/arch/sh/lib64/memcpy.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2002 Mark Debbage (Mark.Debbage@superh.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- */
-
-#include <linux/types.h>
-#include <asm/string.h>
-
-// This is a simplistic optimization of memcpy to increase the
-// granularity of access beyond one byte using aligned
-// loads and stores. This is not an optimal implementation
-// for SH-5 (especially with regard to prefetching and the cache),
-// and a better version should be provided later ...
-
-void *memcpy(void *dest, const void *src, size_t count)
-{
-	char *d = (char *) dest, *s = (char *) src;
-
-	if (count >= 32) {
-		int i = 8 - (((unsigned long) d) & 0x7);
-
-		if (i != 8)
-			while (i-- && count--) {
-				*d++ = *s++;
-			}
-
-		if (((((unsigned long) d) & 0x7) == 0) &&
-		    ((((unsigned long) s) & 0x7) == 0)) {
-			while (count >= 32) {
-				unsigned long long t1, t2, t3, t4;
-				t1 = *(unsigned long long *) (s);
-				t2 = *(unsigned long long *) (s + 8);
-				t3 = *(unsigned long long *) (s + 16);
-				t4 = *(unsigned long long *) (s + 24);
-				*(unsigned long long *) (d) = t1;
-				*(unsigned long long *) (d + 8) = t2;
-				*(unsigned long long *) (d + 16) = t3;
-				*(unsigned long long *) (d + 24) = t4;
-				d += 32;
-				s += 32;
-				count -= 32;
-			}
-			while (count >= 8) {
-				*(unsigned long long *) d =
-				    *(unsigned long long *) s;
-				d += 8;
-				s += 8;
-				count -= 8;
-			}
-		}
-
-		if (((((unsigned long) d) & 0x3) == 0) &&
-		    ((((unsigned long) s) & 0x3) == 0)) {
-			while (count >= 4) {
-				*(unsigned long *) d = *(unsigned long *) s;
-				d += 4;
-				s += 4;
-				count -= 4;
-			}
-		}
-
-		if (((((unsigned long) d) & 0x1) == 0) &&
-		    ((((unsigned long) s) & 0x1) == 0)) {
-			while (count >= 2) {
-				*(unsigned short *) d = *(unsigned short *) s;
-				d += 2;
-				s += 2;
-				count -= 2;
-			}
-		}
-	}
-
-	while (count--) {
-		*d++ = *s++;
-	}
-
-	return d;
-}
diff --git a/arch/sh/lib64/memset.S b/arch/sh/lib64/memset.S
new file mode 100644
index 000000000000..2d37b0488552
--- /dev/null
+++ b/arch/sh/lib64/memset.S
@@ -0,0 +1,91 @@
+/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
+/* Modified by SuperH, Inc. September 2003 */
+!
+! Fast SH memset
+!
+! by Toshiyasu Morita (tm@netcom.com)
+!
+! SH5 code by J"orn Rennecke (joern.rennecke@superh.com)
+! Copyright 2002 SuperH Ltd.
+!
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define SHHI shlld
+#define SHLO shlrd
+#else
+#define SHHI shlrd
+#define SHLO shlld
+#endif
+
+	.section .text..SHmedia32,"ax"
+	.globl	memset
+	.type	memset, @function
+
+	.align 5
+
+memset:
+	pta/l multiquad, tr0
+	andi r2, 7, r22
+	ptabs r18, tr2
+	mshflo.b r3,r3,r3
+	add r4, r22, r23
+	mperm.w r3, r63, r3	// Fill pattern now in every byte of r3
+
+	movi 8, r9
+	bgtu/u r23, r9, tr0 // multiquad
+
+	beqi/u r4, 0, tr2       // Return with size 0 - ensures no mem accesses
+	ldlo.q r2, 0, r7
+	shlli r4, 2, r4
+	movi -1, r8
+	SHHI r8, r4, r8
+	SHHI r8, r4, r8
+	mcmv r7, r8, r3
+	stlo.q r2, 0, r3
+	blink tr2, r63
+
+multiquad:
+	pta/l lastquad, tr0
+	stlo.q r2, 0, r3
+	shlri r23, 3, r24
+	add r2, r4, r5
+	beqi/u r24, 1, tr0 // lastquad
+	pta/l loop, tr1
+	sub r2, r22, r25
+	andi r5, -8, r20   // calculate end address and
+	addi r20, -7*8, r8 // loop end address; This might overflow, so we need
+	                   // to use a different test before we start the loop
+	bge/u r24, r9, tr1 // loop
+	st.q r25, 8, r3
+	st.q r20, -8, r3
+	shlri r24, 1, r24
+	beqi/u r24, 1, tr0 // lastquad
+	st.q r25, 16, r3
+	st.q r20, -16, r3
+	beqi/u r24, 2, tr0 // lastquad
+	st.q r25, 24, r3
+	st.q r20, -24, r3
+lastquad:
+	sthi.q r5, -1, r3
+	blink tr2,r63
+
+loop:
+!!!	alloco r25, 32	// QQQ comment out for short-term fix to SHUK #3895.
+			// QQQ commenting out is locically correct, but sub-optimal
+			// QQQ Sean McGoogan - 4th April 2003.
+	st.q r25, 8, r3
+	st.q r25, 16, r3
+	st.q r25, 24, r3
+	st.q r25, 32, r3
+	addi r25, 32, r25
+	bgeu/l r8, r25, tr1 // loop
+
+	st.q r20, -40, r3
+	st.q r20, -32, r3
+	st.q r20, -24, r3
+	st.q r20, -16, r3
+	st.q r20, -8, r3
+	sthi.q r5, -1, r3
+	blink tr2,r63
+
+	.size	memset,.-memset
diff --git a/arch/sh/lib64/sdivsi3.S b/arch/sh/lib64/sdivsi3.S
new file mode 100644
index 000000000000..6a800c6a4904
--- /dev/null
+++ b/arch/sh/lib64/sdivsi3.S
@@ -0,0 +1,131 @@
+	.global	__sdivsi3
+	.section	.text..SHmedia32,"ax"
+	.align	2
+
+	/* inputs: r4,r5 */
+	/* clobbered: r1,r18,r19,r20,r21,r25,tr0 */
+	/* result in r0 */
+__sdivsi3:
+	ptb __div_table,tr0
+
+	nsb r5, r1
+	shlld r5, r1, r25    /* normalize; [-2 ..1, 1..2) in s2.62 */
+	shari r25, 58, r21   /* extract 5(6) bit index (s2.4 with hole -1..1) */
+	/* bubble */
+	gettr tr0,r20
+	ldx.ub r20, r21, r19 /* u0.8 */
+	shari r25, 32, r25   /* normalize to s2.30 */
+	shlli r21, 1, r21
+	muls.l r25, r19, r19 /* s2.38 */
+	ldx.w r20, r21, r21  /* s2.14 */
+	ptabs r18, tr0
+	shari r19, 24, r19   /* truncate to s2.14 */
+	sub r21, r19, r19    /* some 11 bit inverse in s1.14 */
+	muls.l r19, r19, r21 /* u0.28 */
+	sub r63, r1, r1
+	addi r1, 92, r1
+	muls.l r25, r21, r18 /* s2.58 */
+	shlli r19, 45, r19   /* multiply by two and convert to s2.58 */
+	/* bubble */
+	sub r19, r18, r18
+	shari r18, 28, r18   /* some 22 bit inverse in s1.30 */
+	muls.l r18, r25, r0  /* s2.60 */
+	muls.l r18, r4, r25 /* s32.30 */
+	/* bubble */
+	shari r0, 16, r19   /* s-16.44 */
+	muls.l r19, r18, r19 /* s-16.74 */
+	shari r25, 63, r0
+	shari r4, 14, r18   /* s19.-14 */
+	shari r19, 30, r19   /* s-16.44 */
+	muls.l r19, r18, r19 /* s15.30 */
+	xor r21, r0, r21    /* You could also use the constant 1 << 27. */
+	add r21, r25, r21
+	sub r21, r19, r21
+	shard r21, r1, r21
+	sub r21, r0, r0
+	blink tr0, r63
+	
+/* This table has been generated by divtab.c .
+Defects for bias -330:
+   Max defect: 6.081536e-07 at -1.000000e+00
+   Min defect: 2.849516e-08 at 1.030651e+00
+   Max 2nd step defect: 9.606539e-12 at -1.000000e+00
+   Min 2nd step defect: 0.000000e+00 at 0.000000e+00
+   Defect at 1: 1.238659e-07
+   Defect at -2: 1.061708e-07 */
+
+	.balign 2
+	.type	__div_table,@object
+	.size	__div_table,128
+/* negative division constants */
+	.word	-16638
+	.word	-17135
+	.word	-17737
+	.word	-18433
+	.word	-19103
+	.word	-19751
+	.word	-20583
+	.word	-21383
+	.word	-22343
+	.word	-23353
+	.word	-24407
+	.word	-25582
+	.word	-26863
+	.word	-28382
+	.word	-29965
+	.word	-31800
+/* negative division factors */
+	.byte	66
+	.byte	70
+	.byte	75
+	.byte	81
+	.byte	87
+	.byte	93
+	.byte	101
+	.byte	109
+	.byte	119
+	.byte	130
+	.byte	142
+	.byte	156
+	.byte	172
+	.byte	192
+	.byte	214
+	.byte	241
+	.skip 16
+	.global	__div_table
+__div_table:
+	.skip 16
+/* positive division factors */
+	.byte	241
+	.byte	214
+	.byte	192
+	.byte	172
+	.byte	156
+	.byte	142
+	.byte	130
+	.byte	119
+	.byte	109
+	.byte	101
+	.byte	93
+	.byte	87
+	.byte	81
+	.byte	75
+	.byte	70
+	.byte	66
+/* positive division constants */
+	.word	31801
+	.word	29966
+	.word	28383
+	.word	26864
+	.word	25583
+	.word	24408
+	.word	23354
+	.word	22344
+	.word	21384
+	.word	20584
+	.word	19752
+	.word	19104
+	.word	18434
+	.word	17738
+	.word	17136
+	.word	16639
diff --git a/arch/sh/lib64/strcpy.S b/arch/sh/lib64/strcpy.S
new file mode 100644
index 000000000000..ea7c9c533eea
--- /dev/null
+++ b/arch/sh/lib64/strcpy.S
@@ -0,0 +1,97 @@
+/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
+/* Modified by SuperH, Inc. September 2003 */
+! Entry: arg0: destination
+!        arg1: source
+! Exit:  result: destination
+!
+! SH5 code Copyright 2002 SuperH Ltd.
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define SHHI shlld
+#define SHLO shlrd
+#else
+#define SHHI shlrd
+#define SHLO shlld
+#endif
+
+	.section .text..SHmedia32,"ax"
+	.globl	strcpy
+	.type	strcpy, @function
+	.align 5
+
+strcpy:
+
+	pta/l shortstring,tr1
+	ldlo.q r3,0,r4
+	ptabs r18,tr4
+	shlli r3,3,r7
+	addi r2, 8, r0
+	mcmpeq.b r4,r63,r6
+	SHHI r6,r7,r6
+	bnei/u r6,0,tr1 // shortstring
+	pta/l no_lddst, tr2
+	ori r3,-8,r23
+	sub r2, r23, r0
+	sub r3, r2, r21
+	addi r21, 8, r20
+	ldx.q r0, r21, r5
+	pta/l loop, tr0
+	ori r2,-8,r22
+	mcmpeq.b r5, r63, r6
+	bgt/u r22, r23, tr2 // no_lddst
+
+	// r22 < r23 :  Need to do a load from the destination.
+	// r22 == r23 : Doesn't actually need to load from destination,
+	//              but still can be handled here.
+	ldlo.q r2, 0, r9
+	movi -1, r8
+	SHLO r8, r7, r8
+	mcmv r4, r8, r9
+	stlo.q r2, 0, r9
+	beqi/l r6, 0, tr0 // loop
+
+	add r5, r63, r4
+	addi r0, 8, r0
+	blink tr1, r63 // shortstring
+no_lddst:
+	// r22 > r23: note that for r22 == r23 the sthi.q would clobber
+	//            bytes before the destination region.
+	stlo.q r2, 0, r4
+	SHHI r4, r7, r4
+	sthi.q r0, -1, r4
+	beqi/l r6, 0, tr0 // loop
+
+	add r5, r63, r4
+	addi r0, 8, r0
+shortstring:
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+	pta/l shortstring2,tr1
+	byterev r4,r4
+#endif
+shortstring2:
+	st.b r0,-8,r4
+	andi r4,0xff,r5
+	shlri r4,8,r4
+	addi r0,1,r0
+	bnei/l r5,0,tr1
+	blink tr4,r63 // return
+	
+	.balign 8
+loop:
+	stlo.q r0, 0, r5
+	ldx.q r0, r20, r4
+	addi r0, 16, r0
+	sthi.q r0, -9, r5
+	mcmpeq.b r4, r63, r6
+	bnei/u r6, 0, tr1 // shortstring
+	ldx.q r0, r21, r5
+	stlo.q r0, -8, r4
+	sthi.q r0, -1, r4
+	mcmpeq.b r5, r63, r6
+	beqi/l r6, 0, tr0 // loop
+
+	add r5, r63, r4
+	addi r0, 8, r0
+	blink tr1, r63 // shortstring
+
+	.size	strcpy,.-strcpy
diff --git a/arch/sh/lib64/strlen.S b/arch/sh/lib64/strlen.S
new file mode 100644
index 000000000000..cbc0d912e5f3
--- /dev/null
+++ b/arch/sh/lib64/strlen.S
@@ -0,0 +1,33 @@
+/*
+ * Simplistic strlen() implementation for SHmedia.
+ *
+ * Copyright (C) 2003  Paul Mundt <lethal@linux-sh.org>
+ */
+
+	.section .text..SHmedia32,"ax"
+	.globl	strlen
+	.type	strlen,@function
+
+	.balign 16
+strlen:
+	ptabs	r18, tr4
+
+	/*
+	 * Note: We could easily deal with the NULL case here with a simple
+	 * sanity check, though it seems that the behavior we want is to fault
+	 * in the event that r2 == NULL, so we don't bother.
+	 */
+/*	beqi    r2, 0, tr4 */	! Sanity check
+
+	movi	-1, r0
+	pta/l	loop, tr0
+loop:
+	ld.b	r2, 0, r1
+	addi	r2, 1, r2
+	addi	r0, 1, r0
+	bnei/l	r1, 0, tr0
+
+	or	r0, r63, r2
+	blink	tr4, r63
+
+	.size	strlen,.-strlen
diff --git a/arch/sh/lib64/udivdi3.S b/arch/sh/lib64/udivdi3.S
new file mode 100644
index 000000000000..6895c0225b85
--- /dev/null
+++ b/arch/sh/lib64/udivdi3.S
@@ -0,0 +1,120 @@
+	.section	.text..SHmedia32,"ax"
+	.align	2
+	.global	__udivdi3
+__udivdi3:
+	shlri r3,1,r4
+	nsb r4,r22
+	shlld r3,r22,r6
+	shlri r6,49,r5
+	movi 0xffffffffffffbaf1,r21 /* .l shift count 17.  */
+	sub r21,r5,r1
+	mmulfx.w r1,r1,r4
+	mshflo.w r1,r63,r1
+	sub r63,r22,r20 // r63 == 64 % 64
+	mmulfx.w r5,r4,r4
+	pta large_divisor,tr0
+	addi r20,32,r9
+	msub.w r1,r4,r1
+	madd.w r1,r1,r1
+	mmulfx.w r1,r1,r4
+	shlri r6,32,r7
+	bgt/u r9,r63,tr0 // large_divisor
+	mmulfx.w r5,r4,r4
+	shlri r2,32+14,r19
+	addi r22,-31,r0
+	msub.w r1,r4,r1
+
+	mulu.l r1,r7,r4
+	addi r1,-3,r5
+	mulu.l r5,r19,r5
+	sub r63,r4,r4 // Negate to make sure r1 ends up <= 1/r2
+	shlri r4,2,r4 /* chop off leading %0000000000000000 001.00000000000 - or, as
+	                 the case may be, %0000000000000000 000.11111111111, still */
+	muls.l r1,r4,r4 /* leaving at least one sign bit.  */
+	mulu.l r5,r3,r8
+	mshalds.l r1,r21,r1
+	shari r4,26,r4
+	shlld r8,r0,r8
+	add r1,r4,r1 // 31 bit unsigned reciprocal now in r1 (msb equiv. 0.5)
+	sub r2,r8,r2
+	/* Can do second step of 64 : 32 div now, using r1 and the rest in r2.  */
+
+	shlri r2,22,r21
+	mulu.l r21,r1,r21
+	shlld r5,r0,r8
+	addi r20,30-22,r0
+	shlrd r21,r0,r21
+	mulu.l r21,r3,r5
+	add r8,r21,r8
+	mcmpgt.l r21,r63,r21 // See Note 1
+	addi r20,30,r0
+	mshfhi.l r63,r21,r21
+	sub r2,r5,r2
+	andc r2,r21,r2
+
+	/* small divisor: need a third divide step */
+	mulu.l r2,r1,r7
+	ptabs r18,tr0
+	addi r2,1,r2
+	shlrd r7,r0,r7
+	mulu.l r7,r3,r5
+	add r8,r7,r8
+	sub r2,r3,r2
+	cmpgt r2,r5,r5
+	add r8,r5,r2
+	/* could test r3 here to check for divide by zero.  */
+	blink tr0,r63
+
+large_divisor:
+	mmulfx.w r5,r4,r4
+	shlrd r2,r9,r25
+	shlri r25,32,r8
+	msub.w r1,r4,r1
+
+	mulu.l r1,r7,r4
+	addi r1,-3,r5
+	mulu.l r5,r8,r5
+	sub r63,r4,r4 // Negate to make sure r1 ends up <= 1/r2
+	shlri r4,2,r4 /* chop off leading %0000000000000000 001.00000000000 - or, as
+	                 the case may be, %0000000000000000 000.11111111111, still */
+	muls.l r1,r4,r4 /* leaving at least one sign bit.  */
+	shlri r5,14-1,r8
+	mulu.l r8,r7,r5
+	mshalds.l r1,r21,r1
+	shari r4,26,r4
+	add r1,r4,r1 // 31 bit unsigned reciprocal now in r1 (msb equiv. 0.5)
+	sub r25,r5,r25
+	/* Can do second step of 64 : 32 div now, using r1 and the rest in r25.  */
+
+	shlri r25,22,r21
+	mulu.l r21,r1,r21
+	pta no_lo_adj,tr0
+	addi r22,32,r0
+	shlri r21,40,r21
+	mulu.l r21,r7,r5
+	add r8,r21,r8
+	shlld r2,r0,r2
+	sub r25,r5,r25
+	bgtu/u r7,r25,tr0 // no_lo_adj
+	addi r8,1,r8
+	sub r25,r7,r25
+no_lo_adj:
+	mextr4 r2,r25,r2
+
+	/* large_divisor: only needs a few adjustments.  */
+	mulu.l r8,r6,r5
+	ptabs r18,tr0
+	/* bubble */
+	cmpgtu r5,r2,r5
+	sub r8,r5,r2
+	blink tr0,r63
+	
+/* Note 1: To shift the result of the second divide stage so that the result
+   always fits into 32 bits, yet we still reduce the rest sufficiently
+   would require a lot of instructions to do the shifts just right.  Using
+   the full 64 bit shift result to multiply with the divisor would require
+   four extra instructions for the upper 32 bits (shift / mulu / shift / sub).
+   Fortunately, if the upper 32 bits of the shift result are nonzero, we
+   know that the rest after taking this partial result into account will
+   fit into 32 bits.  So we just clear the upper 32 bits of the rest if the
+   upper 32 bits of the partial result are nonzero.  */
diff --git a/arch/sh/lib64/udivsi3.S b/arch/sh/lib64/udivsi3.S
new file mode 100644
index 000000000000..e68120e4b847
--- /dev/null
+++ b/arch/sh/lib64/udivsi3.S
@@ -0,0 +1,59 @@
+	.global	__udivsi3
+	.section	.text..SHmedia32,"ax"
+	.align	2
+
+/*
+   inputs: r4,r5
+   clobbered: r18,r19,r20,r21,r22,r25,tr0
+   result in r0.
+ */
+__udivsi3:
+	addz.l r5,r63,r22
+	nsb r22,r0
+	shlld r22,r0,r25
+	shlri r25,48,r25
+	movi 0xffffffffffffbb0c,r20 /* shift count eqiv 76 */
+	sub r20,r25,r21
+	mmulfx.w r21,r21,r19
+	mshflo.w r21,r63,r21
+	ptabs r18,tr0
+	mmulfx.w r25,r19,r19
+	sub r20,r0,r0
+	/* bubble */
+	msub.w r21,r19,r19
+
+	/*
+	 * It would be nice for scheduling to do this add to r21 before
+	 * the msub.w, but we need a different value for r19 to keep
+	 * errors under control.
+	 */
+	addi r19,-2,r21
+	mulu.l r4,r21,r18
+	mmulfx.w r19,r19,r19
+	shlli r21,15,r21
+	shlrd r18,r0,r18
+	mulu.l r18,r22,r20
+	mmacnfx.wl r25,r19,r21
+	/* bubble */
+	sub r4,r20,r25
+
+	mulu.l r25,r21,r19
+	addi r0,14,r0
+	/* bubble */
+	shlrd r19,r0,r19
+	mulu.l r19,r22,r20
+	add r18,r19,r18
+	/* bubble */
+	sub.l r25,r20,r25
+
+	mulu.l r25,r21,r19
+	addz.l r25,r63,r25
+	sub r25,r22,r25
+	shlrd r19,r0,r19
+	mulu.l r19,r22,r20
+	addi r25,1,r25
+	add r18,r19,r18
+
+	cmpgt r25,r20,r25
+	add.l r18,r25,r0
+	blink tr0,r63
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
index f066e76da204..cb2f3f299591 100644
--- a/arch/sh/mm/Makefile_32
+++ b/arch/sh/mm/Makefile_32
@@ -18,6 +18,7 @@ mmu-y			:= tlb-nommu.o pg-nommu.o
 mmu-$(CONFIG_MMU)	:= fault_32.o tlbflush_32.o ioremap_32.o
 
 obj-y			+= $(mmu-y)
+obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
 
 ifdef CONFIG_DEBUG_FS
 obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
index 9481d0f54efd..2863ffb7006d 100644
--- a/arch/sh/mm/Makefile_64
+++ b/arch/sh/mm/Makefile_64
@@ -13,6 +13,7 @@ obj-y			+= cache-sh5.o
 endif
 
 obj-y			+= $(mmu-y)
+obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_NUMA)		+= numa.o
diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c
new file mode 100644
index 000000000000..8e912a15e94f
--- /dev/null
+++ b/arch/sh/mm/asids-debugfs.c
@@ -0,0 +1,79 @@
+/*
+ * debugfs ops for process ASIDs
+ *
+ *  Copyright (C) 2000, 2001  Paolo Alberelli
+ *  Copyright (C) 2003 - 2008  Paul Mundt
+ *  Copyright (C) 2003, 2004  Richard Curnow
+ *
+ * Provides a debugfs file that lists out the ASIDs currently associated
+ * with the processes.
+ *
+ * In the SH-5 case, if the DM.PC register is examined through the debug
+ * link, this shows ASID + PC. To make use of this, the PID->ASID
+ * relationship needs to be known. This is primarily for debugging.
+ *
+ * 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/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+
+static int asids_seq_show(struct seq_file *file, void *iter)
+{
+	struct task_struct *p;
+
+	read_lock(&tasklist_lock);
+
+	for_each_process(p) {
+		int pid = p->pid;
+
+		if (unlikely(!pid))
+			continue;
+
+		if (p->mm)
+			seq_printf(file, "%5d : %02lx\n", pid,
+				   cpu_asid(smp_processor_id(), p->mm));
+		else
+			seq_printf(file, "%5d : (none)\n", pid);
+	}
+
+	read_unlock(&tasklist_lock);
+
+	return 0;
+}
+
+static int asids_debugfs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, asids_seq_show, inode->i_private);
+}
+
+static const struct file_operations asids_debugfs_fops = {
+	.owner		= THIS_MODULE,
+	.open		= asids_debugfs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init asids_debugfs_init(void)
+{
+	struct dentry *asids_dentry;
+
+	asids_dentry = debugfs_create_file("asids", S_IRUSR, sh_debugfs_root,
+					   NULL, &asids_debugfs_fops);
+	if (!asids_dentry)
+		return -ENOMEM;
+	if (IS_ERR(asids_dentry))
+		return PTR_ERR(asids_dentry);
+
+	return 0;
+}
+module_init(asids_debugfs_init);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 9f8ea3ada4db..edcd5fbf9651 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -42,6 +42,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 		return NULL;
 	}
 
+	split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
+
 	*dma_handle = virt_to_phys(ret);
 	return ret_nocache;
 }
@@ -51,10 +53,13 @@ void dma_free_coherent(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
 	int order = get_order(size);
+	unsigned long pfn = dma_handle >> PAGE_SHIFT;
+	int k;
 
 	if (!dma_release_from_coherent(dev, order, vaddr)) {
 		WARN_ON(irqs_disabled());	/* for portability */
-		free_pages((unsigned long)phys_to_virt(dma_handle), order);
+		for (k = 0; k < (1 << order); k++)
+			__free_pages(pfn_to_page(pfn + k), 0);
 		iounmap(vaddr);
 	}
 }
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 898d477e47c1..31a33ebdef6f 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
-#include <asm/kgdb.h>
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -265,17 +264,6 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
 	return ret;
 }
 
-#ifdef CONFIG_SH_STORE_QUEUES
-/*
- * This is a special case for the SH-4 store queues, as pages for this
- * space still need to be faulted in before it's possible to flush the
- * store queue cache for writeout to the remapped region.
- */
-#define P3_ADDR_MAX		(P4SEG_STORE_QUE + 0x04000000)
-#else
-#define P3_ADDR_MAX		P4SEG
-#endif
-
 /*
  * Called with interrupts disabled.
  */
@@ -293,11 +281,6 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
 	if (notify_page_fault(regs, lookup_exception_vector()))
 		goto out;
 
-#ifdef CONFIG_SH_KGDB
-	if (kgdb_nofault && kgdb_bus_err_hook)
-		kgdb_bus_err_hook();
-#endif
-
 	ret = 1;
 
 	/*
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index 882a32ebc6b7..32946fba123e 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -116,9 +116,10 @@ EXPORT_SYMBOL(__ioremap);
 void __iounmap(void __iomem *addr)
 {
 	unsigned long vaddr = (unsigned long __force)addr;
+	unsigned long seg = PXSEG(vaddr);
 	struct vm_struct *p;
 
-	if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr))
+	if (seg < P3SEG || seg >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
 		return;
 
 #ifdef CONFIG_32BIT
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 8837d511710a..931f4d003fa0 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -9,7 +9,101 @@
  */
 #include <linux/io.h>
 #include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/module.h>
 #include <asm/page.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
+EXPORT_SYMBOL(shm_align_mask);
+
+/*
+ * To avoid cache aliases, we map the shared page with same color.
+ */
+#define COLOUR_ALIGN(addr, pgoff)				\
+	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
+	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long start_addr;
+	int do_colour_align;
+
+	if (flags & MAP_FIXED) {
+		/* We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (unlikely(len > TASK_SIZE))
+		return -ENOMEM;
+
+	do_colour_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_colour_align = 1;
+
+	if (addr) {
+		if (do_colour_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			return addr;
+	}
+
+	if (len > mm->cached_hole_size) {
+		start_addr = addr = mm->free_area_cache;
+	} else {
+	        mm->cached_hole_size = 0;
+		start_addr = addr = TASK_UNMAPPED_BASE;
+	}
+
+full_search:
+	if (do_colour_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(mm->free_area_cache);
+
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (unlikely(TASK_SIZE - len < addr)) {
+			/*
+			 * Start a new search - just in case we missed
+			 * some holes.
+			 */
+			if (start_addr != TASK_UNMAPPED_BASE) {
+				start_addr = addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
+				goto full_search;
+			}
+			return -ENOMEM;
+		}
+		if (likely(!vma || addr + len <= vma->vm_start)) {
+			/*
+			 * Remember the place where we stopped the search:
+			 */
+			mm->free_area_cache = addr + len;
+			return addr;
+		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
+
+		addr = vma->vm_end;
+		if (do_colour_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+#endif /* CONFIG_MMU */
 
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 2efc2e79fd29..8e6eec91c14c 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -6,13 +6,8 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-profdrvr-y				:= op_model_null.o
+oprofile-y	:= $(DRIVER_OBJS) common.o backtrace.o
 
-# SH7750-style performance counters exist across 7750/7750S and 7091.
-profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750S)	:= op_model_sh7750.o
-profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750)	:= op_model_sh7750.o
-profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091)	:= op_model_sh7750.o
-
-oprofile-y				:= $(DRIVER_OBJS) $(profdrvr-y)
-
-EXTRA_CFLAGS += -Werror
+oprofile-$(CONFIG_CPU_SUBTYPE_SH7750S)	+= op_model_sh7750.o
+oprofile-$(CONFIG_CPU_SUBTYPE_SH7750)	+= op_model_sh7750.o
+oprofile-$(CONFIG_CPU_SUBTYPE_SH7091)	+= op_model_sh7750.o
diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c
new file mode 100644
index 000000000000..9499a2914f89
--- /dev/null
+++ b/arch/sh/oprofile/backtrace.c
@@ -0,0 +1,114 @@
+/*
+ * SH specific backtracing code for oprofile
+ *
+ * Copyright 2007 STMicroelectronics Ltd.
+ *
+ * Author: Dave Peverley <dpeverley@mpc-data.co.uk>
+ *
+ * Based on ARM oprofile backtrace code by Richard Purdie and in turn, i386
+ * oprofile backtrace code by John Levon, David Smith
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+#include <asm/sections.h>
+
+/* Limit to stop backtracing too far. */
+static int backtrace_limit = 20;
+
+static unsigned long *
+user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
+{
+	unsigned long buf_stack;
+
+	/* Also check accessibility of address */
+	if (!access_ok(VERIFY_READ, stackaddr, sizeof(unsigned long)))
+		return NULL;
+
+	if (__copy_from_user_inatomic(&buf_stack, stackaddr, sizeof(unsigned long)))
+		return NULL;
+
+	/* Quick paranoia check */
+	if (buf_stack & 3)
+		return NULL;
+
+	oprofile_add_trace(buf_stack);
+
+	stackaddr++;
+
+	return stackaddr;
+}
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->regs[15] value if valid
+ * .             .
+ * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * |             |
+ * .             .
+ * |             |
+ * --------------- ???
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
+ */
+static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
+{
+	unsigned long stack = (unsigned long)regs;
+	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+	return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
+}
+
+static unsigned long *
+kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	/*
+	 * If not a valid kernel address, keep going till we find one
+	 * or the SP stops being a valid address.
+	 */
+	do {
+		addr = *stackaddr++;
+		oprofile_add_trace(addr);
+	} while (valid_kernel_stack(stackaddr, regs));
+
+	return stackaddr;
+}
+
+void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	unsigned long *stackaddr;
+
+	/*
+	 * Paranoia - clip max depth as we could get lost in the weeds.
+	 */
+	if (depth > backtrace_limit)
+		depth = backtrace_limit;
+
+	stackaddr = (unsigned long *)regs->regs[15];
+	if (!user_mode(regs)) {
+		while (depth-- && valid_kernel_stack(stackaddr, regs))
+			stackaddr = kernel_backtrace(stackaddr, regs);
+
+		return;
+	}
+
+	while (depth-- && (stackaddr != NULL))
+		stackaddr = user_backtrace(stackaddr, regs);
+}
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
new file mode 100644
index 000000000000..1d97d64cb95f
--- /dev/null
+++ b/arch/sh/oprofile/common.c
@@ -0,0 +1,150 @@
+/*
+ * arch/sh/oprofile/init.c
+ *
+ * Copyright (C) 2003 - 2008  Paul Mundt
+ *
+ * Based on arch/mips/oprofile/common.c:
+ *
+ *	Copyright (C) 2004, 2005 Ralf Baechle
+ *	Copyright (C) 2005 MIPS Technologies, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <asm/processor.h>
+#include "op_impl.h"
+
+extern struct op_sh_model op_model_sh7750_ops __weak;
+extern struct op_sh_model op_model_sh4a_ops __weak;
+
+static struct op_sh_model *model;
+
+static struct op_counter_config ctr[20];
+
+extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
+
+static int op_sh_setup(void)
+{
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr);
+
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->cpu_setup, NULL, 1);
+
+        return 0;
+}
+
+static int op_sh_create_files(struct super_block *sb, struct dentry *root)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < model->num_counters; i++) {
+		struct dentry *dir;
+		char buf[4];
+
+		snprintf(buf, sizeof(buf), "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		ret |= oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		ret |= oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		ret |= oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		ret |= oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+
+		if (model->create_files)
+			ret |= model->create_files(sb, dir);
+		else
+			ret |= oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+
+		/* Dummy entries */
+		ret |= oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	return ret;
+}
+
+static int op_sh_start(void)
+{
+	/* Enable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_start, NULL, 1);
+
+	return 0;
+}
+
+static void op_sh_stop(void)
+{
+	/* Disable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_stop, NULL, 1);
+}
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	struct op_sh_model *lmodel = NULL;
+	int ret;
+
+	/*
+	 * Always assign the backtrace op. If the counter initialization
+	 * fails, we fall back to the timer which will still make use of
+	 * this.
+	 */
+	ops->backtrace = sh_backtrace;
+
+	switch (current_cpu_data.type) {
+	/* SH-4 types */
+	case CPU_SH7750:
+	case CPU_SH7750S:
+		lmodel = &op_model_sh7750_ops;
+		break;
+
+        /* SH-4A types */
+	case CPU_SH7763:
+	case CPU_SH7770:
+	case CPU_SH7780:
+	case CPU_SH7781:
+	case CPU_SH7785:
+	case CPU_SH7723:
+	case CPU_SHX3:
+		lmodel = &op_model_sh4a_ops;
+		break;
+
+	/* SH4AL-DSP types */
+	case CPU_SH7343:
+	case CPU_SH7722:
+	case CPU_SH7366:
+		lmodel = &op_model_sh4a_ops;
+		break;
+	}
+
+	if (!lmodel)
+		return -ENODEV;
+	if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER))
+		return -ENODEV;
+
+	ret = lmodel->init();
+	if (unlikely(ret != 0))
+		return ret;
+
+	model = lmodel;
+
+	ops->setup		= op_sh_setup;
+	ops->create_files	= op_sh_create_files;
+	ops->start		= op_sh_start;
+	ops->stop		= op_sh_stop;
+	ops->cpu_type		= lmodel->cpu_type;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       lmodel->cpu_type);
+
+	return 0;
+}
+
+void oprofile_arch_exit(void)
+{
+	if (model && model->exit)
+		model->exit();
+}
diff --git a/arch/sh/oprofile/op_impl.h b/arch/sh/oprofile/op_impl.h
new file mode 100644
index 000000000000..4d509975eba6
--- /dev/null
+++ b/arch/sh/oprofile/op_impl.h
@@ -0,0 +1,33 @@
+#ifndef __OP_IMPL_H
+#define __OP_IMPL_H
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+
+	unsigned long long count;
+
+	/* Dummy values for userspace tool compliance */
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks.  */
+struct op_sh_model {
+	void (*reg_setup)(struct op_counter_config *);
+	int (*create_files)(struct super_block *sb, struct dentry *dir);
+	void (*cpu_setup)(void *dummy);
+	int (*init)(void);
+	void (*exit)(void);
+	void (*cpu_start)(void *args);
+	void (*cpu_stop)(void *args);
+	char *cpu_type;
+	unsigned char num_counters;
+};
+
+/* arch/sh/oprofile/common.c */
+extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
+
+#endif /* __OP_IMPL_H */
diff --git a/arch/sh/oprofile/op_model_null.c b/arch/sh/oprofile/op_model_null.c
deleted file mode 100644
index a845b088edb4..000000000000
--- a/arch/sh/oprofile/op_model_null.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * arch/sh/oprofile/op_model_null.c
- *
- * Copyright (C) 2003  Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/kernel.h>
-#include <linux/oprofile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
-	return -ENODEV;
-}
-
-void oprofile_arch_exit(void)
-{
-}
-
diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c
index 008b3b03750a..c892c7c30c2f 100644
--- a/arch/sh/oprofile/op_model_sh7750.c
+++ b/arch/sh/oprofile/op_model_sh7750.c
@@ -3,7 +3,7 @@
  *
  * OProfile support for SH7750/SH7750S Performance Counters
  *
- * Copyright (C) 2003, 2004  Paul Mundt
+ * Copyright (C) 2003 - 2008  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
@@ -15,19 +15,16 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/fs.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include "op_impl.h"
 
 #define PM_CR_BASE	0xff000084	/* 16-bit */
 #define PM_CTR_BASE	0xff100004	/* 32-bit */
 
-#define PMCR1		(PM_CR_BASE  + 0x00)
-#define PMCR2		(PM_CR_BASE  + 0x04)
-#define PMCTR1H		(PM_CTR_BASE + 0x00)
-#define PMCTR1L		(PM_CTR_BASE + 0x04)
-#define PMCTR2H		(PM_CTR_BASE + 0x08)
-#define PMCTR2L		(PM_CTR_BASE + 0x0c)
+#define PMCR(n)		(PM_CR_BASE + ((n) * 0x04))
+#define PMCTRH(n)	(PM_CTR_BASE + 0x00 + ((n) * 0x08))
+#define PMCTRL(n)	(PM_CTR_BASE + 0x04 + ((n) * 0x08))
 
 #define PMCR_PMM_MASK	0x0000003f
 
@@ -36,25 +33,15 @@
 #define PMCR_PMST	0x00004000
 #define PMCR_PMEN	0x00008000
 
-#define PMCR_ENABLE	(PMCR_PMST | PMCR_PMEN)
+struct op_sh_model op_model_sh7750_ops;
 
-/*
- * SH7750/SH7750S have 2 perf counters
- */
 #define NR_CNTRS	2
 
-struct op_counter_config {
-	unsigned long enabled;
-	unsigned long event;
-	unsigned long count;
-
-	/* Dummy values for userspace tool compliance */
-	unsigned long kernel;
-	unsigned long user;
-	unsigned long unit_mask;
-};
-
-static struct op_counter_config ctr[NR_CNTRS];
+static struct sh7750_ppc_register_config {
+	unsigned int ctrl;
+	unsigned long cnt_hi;
+	unsigned long cnt_lo;
+} regcache[NR_CNTRS];
 
 /*
  * There are a number of events supported by each counter (33 in total).
@@ -116,12 +103,8 @@ static int sh7750_timer_notify(struct pt_regs *regs)
 
 static u64 sh7750_read_counter(int counter)
 {
-	u32 hi, lo;
-
-	hi = (counter == 0) ? ctrl_inl(PMCTR1H) : ctrl_inl(PMCTR2H);
-	lo = (counter == 0) ? ctrl_inl(PMCTR1L) : ctrl_inl(PMCTR2L);
-
-	return (u64)((u64)(hi & 0xffff) << 32) | lo;
+	return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) |
+			   __raw_readl(PMCTRL(counter));
 }
 
 /*
@@ -170,11 +153,7 @@ static ssize_t sh7750_write_count(struct file *file, const char __user *buf,
 	 */
 	WARN_ON(val != 0);
 
-	if (counter == 0) {
-		ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1);
-	} else {
-		ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2);
-	}
+	__raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter));
 
 	return count;
 }
@@ -184,88 +163,93 @@ static const struct file_operations count_fops = {
 	.write		= sh7750_write_count,
 };
 
-static int sh7750_perf_counter_create_files(struct super_block *sb, struct dentry *root)
+static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir)
 {
-	int i;
+	return oprofilefs_create_file(sb, dir, "count", &count_fops);
+}
 
-	for (i = 0; i < NR_CNTRS; i++) {
-		struct dentry *dir;
-		char buf[4];
+static void sh7750_ppc_reg_setup(struct op_counter_config *ctr)
+{
+	unsigned int counters = op_model_sh7750_ops.num_counters;
+	int i;
 
-		snprintf(buf, sizeof(buf), "%d", i);
-		dir = oprofilefs_mkdir(sb, root, buf);
+	for (i = 0; i < counters; i++) {
+		regcache[i].ctrl	= 0;
+		regcache[i].cnt_hi	= 0;
+		regcache[i].cnt_lo	= 0;
 
-		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
-		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
-		oprofilefs_create_file(sb, dir, "count", &count_fops);
+		if (!ctr[i].enabled)
+			continue;
 
-		/* Dummy entries */
-		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
-		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
-		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+		regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST;
+		regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff);
+		regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff);
 	}
-
-	return 0;
 }
 
-static int sh7750_perf_counter_start(void)
+static void sh7750_ppc_cpu_setup(void *args)
 {
-	u16 pmcr;
-
-	/* Enable counter 1 */
-	if (ctr[0].enabled) {
-		pmcr = ctrl_inw(PMCR1);
-		WARN_ON(pmcr & PMCR_PMEN);
-
-		pmcr &= ~PMCR_PMM_MASK;
-		pmcr |= ctr[0].event;
-		ctrl_outw(pmcr | PMCR_ENABLE, PMCR1);
-	}
-
-	/* Enable counter 2 */
-	if (ctr[1].enabled) {
-		pmcr = ctrl_inw(PMCR2);
-		WARN_ON(pmcr & PMCR_PMEN);
+	unsigned int counters = op_model_sh7750_ops.num_counters;
+	int i;
 
-		pmcr &= ~PMCR_PMM_MASK;
-		pmcr |= ctr[1].event;
-		ctrl_outw(pmcr | PMCR_ENABLE, PMCR2);
+	for (i = 0; i < counters; i++) {
+		__raw_writew(0, PMCR(i));
+		__raw_writel(regcache[i].cnt_hi, PMCTRH(i));
+		__raw_writel(regcache[i].cnt_lo, PMCTRL(i));
 	}
-
-	return register_timer_hook(sh7750_timer_notify);
 }
 
-static void sh7750_perf_counter_stop(void)
+static void sh7750_ppc_cpu_start(void *args)
 {
-	ctrl_outw(ctrl_inw(PMCR1) & ~PMCR_PMEN, PMCR1);
-	ctrl_outw(ctrl_inw(PMCR2) & ~PMCR_PMEN, PMCR2);
+	unsigned int counters = op_model_sh7750_ops.num_counters;
+	int i;
 
-	unregister_timer_hook(sh7750_timer_notify);
+	for (i = 0; i < counters; i++)
+		__raw_writew(regcache[i].ctrl, PMCR(i));
 }
 
-static struct oprofile_operations sh7750_perf_counter_ops = {
-	.create_files	= sh7750_perf_counter_create_files,
-	.start		= sh7750_perf_counter_start,
-	.stop		= sh7750_perf_counter_stop,
-};
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
+static void sh7750_ppc_cpu_stop(void *args)
 {
-	if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER))
-		return -ENODEV;
+	unsigned int counters = op_model_sh7750_ops.num_counters;
+	int i;
 
-	ops = &sh7750_perf_counter_ops;
-	ops->cpu_type = "sh/sh7750";
+	/* Disable the counters */
+	for (i = 0; i < counters; i++)
+		__raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
+}
 
-	printk(KERN_INFO "oprofile: using SH-4 performance monitoring.\n");
+static inline void sh7750_ppc_reset(void)
+{
+	unsigned int counters = op_model_sh7750_ops.num_counters;
+	int i;
 
 	/* Clear the counters */
-	ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1);
-	ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2);
+	for (i = 0; i < counters; i++)
+		__raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i));
+}
 
-	return 0;
+static int sh7750_ppc_init(void)
+{
+	sh7750_ppc_reset();
+
+	return register_timer_hook(sh7750_timer_notify);
 }
 
-void oprofile_arch_exit(void)
+static void sh7750_ppc_exit(void)
 {
+	unregister_timer_hook(sh7750_timer_notify);
+
+	sh7750_ppc_reset();
 }
+
+struct op_sh_model op_model_sh7750_ops = {
+	.cpu_type	= "sh/sh7750",
+	.num_counters	= NR_CNTRS,
+	.reg_setup	= sh7750_ppc_reg_setup,
+	.cpu_setup	= sh7750_ppc_cpu_setup,
+	.cpu_start	= sh7750_ppc_cpu_start,
+	.cpu_stop	= sh7750_ppc_cpu_stop,
+	.init		= sh7750_ppc_init,
+	.exit		= sh7750_ppc_exit,
+	.create_files	= sh7750_ppc_create_files,
+};
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index d0c2928d1066..284b7e867496 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -8,6 +8,7 @@
 SE			SH_SOLUTION_ENGINE
 HIGHLANDER		SH_HIGHLANDER
 RTS7751R2D		SH_RTS7751R2D
+RSK			SH_RSK
 
 #
 # List of companion chips / MFDs.
@@ -46,6 +47,7 @@ R2D_1			RTS7751R2D_1
 CAYMAN			SH_CAYMAN
 SDK7780			SH_SDK7780
 MIGOR			SH_MIGOR
+RSK7201			SH_RSK7201
 RSK7203			SH_RSK7203
 AP325RXA		SH_AP325RXA
 SH7763RDP		SH_SH7763RDP