linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] sh updates
@ 2006-01-14 22:50 Paul Mundt
  2006-01-14 22:51 ` [PATCH 1/8] sh: Consolidate hp620/hp680/hp690 targets into hp6xx Paul Mundt
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:50 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This includes some various updates for sh. Including a new clock and
timer API, DMA updates, overhauling some of the I/O routines to allow for
further board cleanup, as well as shuffling some code around for reuse on
some new CPU subtypes.

Pretty much all of the changes are isolated to arch/sh and include/asm-sh.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/8] sh: Consolidate hp620/hp680/hp690 targets into hp6xx.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
@ 2006-01-14 22:51 ` Paul Mundt
  2006-01-14 22:51 ` [PATCH 2/8] sh: DMA updates Paul Mundt
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:51 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

Most of the reasons for keeping these separate before was due to hp690
discontig, and since we have a workaround for that now (abusing some
shadow space so everything is magically contiguous), there's no reason to
keep the targets separate.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/boards/hp6xx/Makefile       |    6 
 arch/sh/boards/hp6xx/hp620/Makefile |    6 
 arch/sh/boards/hp6xx/hp620/mach.c   |   52 --
 arch/sh/boards/hp6xx/hp620/setup.c  |   45 --
 arch/sh/boards/hp6xx/hp680/Makefile |    6 
 arch/sh/boards/hp6xx/hp680/mach.c   |   53 --
 arch/sh/boards/hp6xx/hp680/setup.c  |   41 -
 arch/sh/boards/hp6xx/hp690/Makefile |    6 
 arch/sh/boards/hp6xx/hp690/mach.c   |   48 --
 arch/sh/boards/hp6xx/mach.c         |   46 ++
 arch/sh/boards/hp6xx/setup.c        |   55 ++
 arch/sh/configs/hp680_defconfig     |  626 ------------------------------
 arch/sh/configs/hp6xx_defconfig     |  743 ++++++++++++++++++++++++++++++++++++
 arch/sh/tools/mach-types            |    7 
 drivers/input/touchscreen/Kconfig   |    2 
 15 files changed, 853 insertions(+), 889 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/Makefile sh-2.6.15/arch/sh/boards/hp6xx/Makefile
--- linux-2.6.15/arch/sh/boards/hp6xx/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/boards/hp6xx/Makefile	2006-01-04 00:15:26.000000000 +0200
@@ -0,0 +1,6 @@
+#
+# Makefile for the HP6xx specific parts of the kernel
+#
+
+obj-y	 := mach.o setup.o
+
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp620/Makefile sh-2.6.15/arch/sh/boards/hp6xx/hp620/Makefile
--- linux-2.6.15/arch/sh/boards/hp6xx/hp620/Makefile	2005-06-20 22:45:19.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp620/Makefile	1970-01-01 02:00:00.000000000 +0200
@@ -1,6 +0,0 @@
-#
-# Makefile for the HP620 specific parts of the kernel
-#
-
-obj-y	 := mach.o setup.o
-
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp620/mach.c sh-2.6.15/arch/sh/boards/hp6xx/hp620/mach.c
--- linux-2.6.15/arch/sh/boards/hp6xx/hp620/mach.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp620/mach.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,52 +0,0 @@
-/*
- * linux/arch/sh/boards/hp6xx/hp620/mach.c
- * 
- * Copyright (C) 2000 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.
- *
- * Machine vector for the HP620
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/hd64461/hd64461.h>
-#include <asm/irq.h>
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_hp620 __initmv = {
-        .mv_nr_irqs             = HD64461_IRQBASE+HD64461_IRQ_NUM,
-
-        .mv_inb                 = hd64461_inb,
-        .mv_inw                 = hd64461_inw,
-        .mv_inl                 = hd64461_inl,
-        .mv_outb                = hd64461_outb,
-        .mv_outw                = hd64461_outw,
-        .mv_outl                = hd64461_outl,
-
-        .mv_inb_p               = hd64461_inb_p,
-        .mv_inw_p               = hd64461_inw,
-        .mv_inl_p               = hd64461_inl,
-        .mv_outb_p              = hd64461_outb_p,
-        .mv_outw_p              = hd64461_outw,
-        .mv_outl_p              = hd64461_outl,
-
-        .mv_insb                = hd64461_insb,
-        .mv_insw                = hd64461_insw,
-        .mv_insl                = hd64461_insl,
-        .mv_outsb               = hd64461_outsb,
-        .mv_outsw               = hd64461_outsw,
-        .mv_outsl               = hd64461_outsl,
-
-        .mv_irq_demux           = hd64461_irq_demux,
-};
-ALIAS_MV(hp620)
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp620/setup.c sh-2.6.15/arch/sh/boards/hp6xx/hp620/setup.c
--- linux-2.6.15/arch/sh/boards/hp6xx/hp620/setup.c	2005-06-20 22:45:19.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp620/setup.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,45 +0,0 @@
-/*
- * linux/arch/sh/boards/hp6xx/hp620/setup.c
- *
- * Copyright (C) 2002 Andriy Skulysh, 2005 Kristoffer Ericson
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See Linux/COPYING for more information.
- *
- * Setup code for an HP620.
- * Due to similiarity with hp680/hp690 same inits are done (for now)
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <asm/hd64461/hd64461.h>
-#include <asm/io.h>
-#include <asm/hp6xx/hp6xx.h>
-#include <asm/cpu/dac.h>
-
-const char *get_system_type(void)
-{
-	return "HP620";
-}
-
-int __init platform_setup(void)
-{
-	u16 v;
-
-	v  = inw(HD64461_STBCR);
-	v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST  |
-	     HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
-	     HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
-	     HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST |
-	     HD64461_STBCR_SAFECKE_IST;
-	outw(v, HD64461_STBCR);
-
-	v  = inw(HD64461_GPADR);
-	v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
-	outw(v, HD64461_GPADR);
-
-	sh_dac_disable(DAC_SPEAKER_VOLUME);
-
-	return 0;
-}
-
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp680/Makefile sh-2.6.15/arch/sh/boards/hp6xx/hp680/Makefile
--- linux-2.6.15/arch/sh/boards/hp6xx/hp680/Makefile	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp680/Makefile	1970-01-01 02:00:00.000000000 +0200
@@ -1,6 +0,0 @@
-#
-# Makefile for the HP680 specific parts of the kernel
-#
-
-obj-y	 := mach.o setup.o
-
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp680/mach.c sh-2.6.15/arch/sh/boards/hp6xx/hp680/mach.c
--- linux-2.6.15/arch/sh/boards/hp6xx/hp680/mach.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp680/mach.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,53 +0,0 @@
-/*
- * linux/arch/sh/boards/hp6xx/hp680/mach.c
- *
- * Copyright (C) 2000 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.
- *
- * Machine vector for the HP680
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/hd64461/hd64461.h>
-#include <asm/hp6xx/io.h>
-#include <asm/irq.h>
-
-struct sh_machine_vector mv_hp680 __initmv = {
-	.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
-
-	.mv_inb = hd64461_inb,
-	.mv_inw = hd64461_inw,
-	.mv_inl = hd64461_inl,
-	.mv_outb = hd64461_outb,
-	.mv_outw = hd64461_outw,
-	.mv_outl = hd64461_outl,
-
-	.mv_inb_p = hd64461_inb_p,
-	.mv_inw_p = hd64461_inw,
-	.mv_inl_p = hd64461_inl,
-	.mv_outb_p = hd64461_outb_p,
-	.mv_outw_p = hd64461_outw,
-	.mv_outl_p = hd64461_outl,
-
-	.mv_insb = hd64461_insb,
-	.mv_insw = hd64461_insw,
-	.mv_insl = hd64461_insl,
-	.mv_outsb = hd64461_outsb,
-	.mv_outsw = hd64461_outsw,
-	.mv_outsl = hd64461_outsl,
-
-	.mv_readw = hd64461_readw,
-	.mv_writew = hd64461_writew,
-
-	.mv_irq_demux = hd64461_irq_demux,
-};
-
-ALIAS_MV(hp680)
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp680/setup.c sh-2.6.15/arch/sh/boards/hp6xx/hp680/setup.c
--- linux-2.6.15/arch/sh/boards/hp6xx/hp680/setup.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp680/setup.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,41 +0,0 @@
-/*
- * linux/arch/sh/boards/hp6xx/hp680/setup.c
- *
- * Copyright (C) 2002 Andriy Skulysh
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Setup code for an HP680  (internal peripherials only)
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <asm/hd64461/hd64461.h>
-#include <asm/io.h>
-#include <asm/hp6xx/hp6xx.h>
-#include <asm/cpu/dac.h>
-
-const char *get_system_type(void)
-{
-	return "HP680";
-}
-
-int __init platform_setup(void)
-{
-	u16 v;
-	v = inw(HD64461_STBCR);
-	v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
-	    HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
-	    HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
-	    HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST |
-	    HD64461_STBCR_SAFECKE_IST;
-	outw(v, HD64461_STBCR);
-	v = inw(HD64461_GPADR);
-	v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
-	outw(v, HD64461_GPADR);
-
-	sh_dac_disable(DAC_SPEAKER_VOLUME);
-
-	return 0;
-}
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp690/Makefile sh-2.6.15/arch/sh/boards/hp6xx/hp690/Makefile
--- linux-2.6.15/arch/sh/boards/hp6xx/hp690/Makefile	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp690/Makefile	1970-01-01 02:00:00.000000000 +0200
@@ -1,6 +0,0 @@
-#
-# Makefile for the HP690 specific parts of the kernel
-#
-
-obj-y	 := mach.o
-
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/hp690/mach.c sh-2.6.15/arch/sh/boards/hp6xx/hp690/mach.c
--- linux-2.6.15/arch/sh/boards/hp6xx/hp690/mach.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/hp6xx/hp690/mach.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,48 +0,0 @@
-/*
- * linux/arch/sh/boards/hp6xx/hp690/mach.c
- *
- * Copyright (C) 2000 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.
- *
- * Machine vector for the HP690
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/hd64461/hd64461.h>
-#include <asm/irq.h>
-
-struct sh_machine_vector mv_hp690 __initmv = {
-        .mv_nr_irqs             = HD64461_IRQBASE+HD64461_IRQ_NUM,
-
-        .mv_inb                 = hd64461_inb,
-        .mv_inw                 = hd64461_inw,
-        .mv_inl                 = hd64461_inl,
-        .mv_outb                = hd64461_outb,
-        .mv_outw                = hd64461_outw,
-        .mv_outl                = hd64461_outl,
-
-        .mv_inb_p               = hd64461_inb_p,
-        .mv_inw_p               = hd64461_inw,
-        .mv_inl_p               = hd64461_inl,
-        .mv_outb_p              = hd64461_outb_p,
-        .mv_outw_p              = hd64461_outw,
-        .mv_outl_p              = hd64461_outl,
-
-        .mv_insb                = hd64461_insb,
-        .mv_insw                = hd64461_insw,
-        .mv_insl                = hd64461_insl,
-        .mv_outsb               = hd64461_outsb,
-        .mv_outsw               = hd64461_outsw,
-        .mv_outsl               = hd64461_outsl,
-
-        .mv_irq_demux           = hd64461_irq_demux,
-};
-ALIAS_MV(hp690)
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/mach.c sh-2.6.15/arch/sh/boards/hp6xx/mach.c
--- linux-2.6.15/arch/sh/boards/hp6xx/mach.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/boards/hp6xx/mach.c	2006-01-04 15:36:51.000000000 +0200
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/sh/boards/hp6xx/mach.c
+ *
+ * Copyright (C) 2000 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.
+ *
+ * Machine vector for the HP680
+ */
+#include <asm/machvec.h>
+#include <asm/hd64461.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+struct sh_machine_vector mv_hp6xx __initmv = {
+	.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
+
+	.mv_inb = hd64461_inb,
+	.mv_inw = hd64461_inw,
+	.mv_inl = hd64461_inl,
+	.mv_outb = hd64461_outb,
+	.mv_outw = hd64461_outw,
+	.mv_outl = hd64461_outl,
+
+	.mv_inb_p = hd64461_inb_p,
+	.mv_inw_p = hd64461_inw,
+	.mv_inl_p = hd64461_inl,
+	.mv_outb_p = hd64461_outb_p,
+	.mv_outw_p = hd64461_outw,
+	.mv_outl_p = hd64461_outl,
+
+	.mv_insb = hd64461_insb,
+	.mv_insw = hd64461_insw,
+	.mv_insl = hd64461_insl,
+	.mv_outsb = hd64461_outsb,
+	.mv_outsw = hd64461_outsw,
+	.mv_outsl = hd64461_outsl,
+
+	.mv_readw = hd64461_readw,
+	.mv_writew = hd64461_writew,
+
+	.mv_irq_demux = hd64461_irq_demux,
+};
+
+ALIAS_MV(hp6xx)
diff -urN -X exclude linux-2.6.15/arch/sh/boards/hp6xx/setup.c sh-2.6.15/arch/sh/boards/hp6xx/setup.c
--- linux-2.6.15/arch/sh/boards/hp6xx/setup.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/boards/hp6xx/setup.c	2006-01-04 15:38:50.000000000 +0200
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/sh/boards/hp6xx/hp680/setup.c
+ *
+ * Copyright (C) 2002 Andriy Skulysh
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Setup code for an HP680  (internal peripherials only)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
+#include <asm/hp6xx/hp6xx.h>
+#include <asm/cpu/dac.h>
+
+const char *get_system_type(void)
+{
+	return "HP6xx";
+}
+
+int __init platform_setup(void)
+{
+	u8 v8;
+	u16 v;
+	v = inw(HD64461_STBCR);
+	v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
+	    HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
+	    HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
+	    HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST |
+	    HD64461_STBCR_SAFECKE_IST;
+#ifndef CONFIG_HD64461_ENABLER
+	v |= HD64461_STBCR_SPC1ST;
+#endif
+	outw(v, HD64461_STBCR);
+	v = inw(HD64461_GPADR);
+	v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
+	outw(v, HD64461_GPADR);
+
+	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR);
+
+#ifndef CONFIG_HD64461_ENABLER
+	outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR);
+#endif
+
+	sh_dac_output(0, DAC_SPEAKER_VOLUME);
+	sh_dac_disable(DAC_SPEAKER_VOLUME);
+	v8 = ctrl_inb(DACR);
+	v8 &= ~DACR_DAE;
+	ctrl_outb(v8,DACR);
+
+	return 0;
+}
diff -urN -X exclude linux-2.6.15/arch/sh/configs/hp680_defconfig sh-2.6.15/arch/sh/configs/hp680_defconfig
--- linux-2.6.15/arch/sh/configs/hp680_defconfig	2005-10-06 00:20:18.000000000 +0300
+++ sh-2.6.15/arch/sh/configs/hp680_defconfig	1970-01-01 02:00:00.000000000 +0200
@@ -1,626 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-sh
-# Thu Oct  6 00:20:18 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-CONFIG_SH_UNKNOWN=y
-
-#
-# Processor selection
-#
-CONFIG_CPU_SH3=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-CONFIG_CPU_SUBTYPE_SH7709=y
-
-#
-# SH-4 Processor Support
-#
-# 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
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_SH7770 is not set
-# CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# Memory management options
-#
-CONFIG_MMU=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-
-#
-# Cache configuration
-#
-# CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_CF_ENABLER is not set
-
-#
-# Processor features
-#
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
-# CONFIG_SH_DSP is not set
-CONFIG_SH_ADC=y
-
-#
-# Timer support
-#
-CONFIG_SH_TMU=y
-# CONFIG_SH_PCLK_FREQ_BOOL is not set
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-CONFIG_HD6446X_SERIES=y
-CONFIG_HD64461=y
-# CONFIG_HD64465 is not set
-CONFIG_HD64461_IRQ=36
-# CONFIG_HD64461_ENABLER is not set
-
-#
-# Kernel features
-#
-# CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_SMP is not set
-
-#
-# Boot options
-#
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_CMDLINE_BOOL is not set
-
-#
-# Bus options
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
-# CONFIG_NET is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# 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_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV 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_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# 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=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_EPSON1355 is not set
-CONFIG_FB_HIT=y
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_7x14 is not set
-CONFIG_FONT_PEARL_8x8=y
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# SN Devices
-#
-
-#
-# 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_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_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_KCORE=y
-CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# 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_HPFS_FS is not set
-# CONFIG_QNX4FS_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
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
diff -urN -X exclude linux-2.6.15/arch/sh/configs/hp6xx_defconfig sh-2.6.15/arch/sh/configs/hp6xx_defconfig
--- linux-2.6.15/arch/sh/configs/hp6xx_defconfig	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/configs/hp6xx_defconfig	2006-01-04 21:02:29.000000000 +0200
@@ -0,0 +1,743 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15-sh
+# Wed Jan  4 15:32:56 2006
+#
+CONFIG_SUPERH=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD 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"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_STB1_HARP is not set
+# CONFIG_SH_STB1_OVERDRIVE is not set
+CONFIG_SH_HP6XX=y
+# CONFIG_SH_CQREEK is not set
+# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_EC3104 is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_CAT68701 is not set
+# CONFIG_SH_BIGSUR is not set
+# CONFIG_SH_SH2000 is not set
+# CONFIG_SH_ADX is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH3=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+CONFIG_CPU_SUBTYPE_SH7709=y
+
+#
+# SH-4 Processor Support
+#
+# 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
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x00400000
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_RTC=y
+# CONFIG_SH_DSP is not set
+CONFIG_SH_ADC=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ_BOOL=y
+CONFIG_SH_PCLK_FREQ=22110000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+CONFIG_SH_DMA=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+# CONFIG_DMA_PAGE_OPS is not set
+
+#
+# Companion Chips
+#
+CONFIG_HD6446X_SERIES=y
+CONFIG_HD64461=y
+# CONFIG_HD64465 is not set
+CONFIG_HD64461_IRQ=36
+CONFIG_HD64461_IOBASE=0xb0000000
+CONFIG_HD64461_ENABLER=y
+
+#
+# Kernel features
+#
+# CONFIG_KEXEC is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_SMP is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_HD64461_PCMCIA=y
+CONFIG_HD64461_PCMCIA_SOCKETS=1
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# 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_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_IDE_SH=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV 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_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# 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=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_HIT=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+CONFIG_FONT_PEARL_8x8=y
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_SH_DAC_AUDIO=y
+CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# 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_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# 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 is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_HPFS_FS is not set
+# CONFIG_QNX4FS_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
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff -urN -X exclude linux-2.6.15/arch/sh/tools/mach-types sh-2.6.15/arch/sh/tools/mach-types
--- linux-2.6.15/arch/sh/tools/mach-types	2004-12-26 05:37:11.000000000 +0200
+++ sh-2.6.15/arch/sh/tools/mach-types	2006-01-07 22:11:41.257993544 +0200
@@ -7,13 +7,10 @@
 #
 SE			SH_SOLUTION_ENGINE
 7751SE			SH_7751_SOLUTION_ENGINE		
-7300SE			SH_7300_SOLUTION_ENGINE
+7300SE			SH_7300_SOLUTION_ENGINE
 73180SE			SH_73180_SOLUTION_ENGINE
 7751SYSTEMH		SH_7751_SYSTEMH
-HP600			SH_HP600
-HP620			SH_HP620
-HP680			SH_HP680
-HP690			SH_HP690
+HP6XX			SH_HP6XX
 HD64461			HD64461
 HD64465			HD64465
 SH2000			SH_SH2000

diff -urN -X exclude linux-2.6.15/drivers/input/touchscreen/Kconfig sh-2.6.15/drivers/input/touchscreen/Kconfig
--- linux-2.6.15/drivers/input/touchscreen/Kconfig	2005-11-12 20:17:37.000000000 +0200
+++ sh-2.6.15/drivers/input/touchscreen/Kconfig	2006-01-04 00:15:28.000000000 +0200
@@ -85,7 +85,7 @@
 
 config TOUCHSCREEN_HP600
 	tristate "HP Jornada 680/690 touchscreen"
-	depends on SH_HP600 && SH_ADC
+	depends on SH_HP6XX && SH_ADC
 	help
 	  Say Y here if you have a HP Jornada 680 or 690 and want to
           support the built-in touchscreen.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/8] sh: DMA updates
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
  2006-01-14 22:51 ` [PATCH 1/8] sh: Consolidate hp620/hp680/hp690 targets into hp6xx Paul Mundt
@ 2006-01-14 22:51 ` Paul Mundt
  2006-01-14 22:52 ` [PATCH 3/8] sh: kexec() support Paul Mundt
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:51 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This extends the current SH DMA API somewhat to support a proper virtual
channel abstraction, and also works to represent this through the driver
model by giving each DMAC its own platform device.

There's also a few other minor changes to support a few new CPU subtypes,
and make TEI generation for the SH DMAC configurable.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/drivers/dma/dma-api.c   |   51 +++++++++++----
 arch/sh/drivers/dma/dma-g2.c    |    3 
 arch/sh/drivers/dma/dma-isa.c   |   20 ++---
 arch/sh/drivers/dma/dma-pvr2.c  |    3 
 arch/sh/drivers/dma/dma-sh.c    |  134 ++++++++++++++++++++++++----------------
 arch/sh/drivers/dma/dma-sh.h    |   44 +++++++++----
 arch/sh/drivers/dma/dma-sysfs.c |   31 +++++++--
 arch/sh/kernel/cpu/bus.c        |    2 
 include/asm-sh/bus-sh.h         |    1 
 include/asm-sh/cpu-sh3/dma.h    |   31 ++++++++-
 include/asm-sh/cpu-sh4/dma.h    |   52 ++++++++++++---
 include/asm-sh/dma-mapping.h    |   25 +++----
 include/asm-sh/dma.h            |   14 +++-
 13 files changed, 291 insertions(+), 120 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-api.c sh-2.6.15/arch/sh/drivers/dma/dma-api.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-api.c	2005-06-20 22:36:13.000000000 +0300
+++ sh-2.6.15/arch/sh/drivers/dma/dma-api.c	2006-01-04 16:58:04.000000000 +0200
@@ -3,7 +3,7 @@
  *
  * SuperH-specific DMA management API
  *
- * Copyright (C) 2003, 2004  Paul Mundt
+ * Copyright (C) 2003, 2004, 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
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
 #include <linux/list.h>
+#include <linux/platform_device.h>
 #include <asm/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
@@ -55,16 +56,14 @@
 
 struct dma_info *get_dma_info(unsigned int chan)
 {
-	struct list_head *pos, *tmp;
+	struct dma_info *info;
 	unsigned int total = 0;
 
 	/*
 	 * Look for each DMAC's range to determine who the owner of
 	 * the channel is.
 	 */
-	list_for_each_safe(pos, tmp, &registered_dmac_list) {
-		struct dma_info *info = list_entry(pos, struct dma_info, list);
-
+	list_for_each_entry(info, &registered_dmac_list, list) {
 		total += info->nr_channels;
 		if (chan > total)
 			continue;
@@ -75,6 +74,20 @@
 	return NULL;
 }
 
+static unsigned int get_nr_channels(void)
+{
+	struct dma_info *info;
+	unsigned int nr = 0;
+
+	if (unlikely(list_empty(&registered_dmac_list)))
+		return nr;
+
+	list_for_each_entry(info, &registered_dmac_list, list)
+		nr += info->nr_channels;
+
+	return nr;
+}
+
 struct dma_channel *get_dma_channel(unsigned int chan)
 {
 	struct dma_info *info = get_dma_info(chan);
@@ -173,7 +186,7 @@
 static int dma_read_proc(char *buf, char **start, off_t off,
 			 int len, int *eof, void *data)
 {
-	struct list_head *pos, *tmp;
+	struct dma_info *info;
 	char *p = buf;
 
 	if (list_empty(&registered_dmac_list))
@@ -182,8 +195,7 @@
 	/*
 	 * Iterate over each registered DMAC
 	 */
-	list_for_each_safe(pos, tmp, &registered_dmac_list) {
-		struct dma_info *info = list_entry(pos, struct dma_info, list);
+	list_for_each_entry(info, &registered_dmac_list, list) {
 		int i;
 
 		/*
@@ -205,9 +217,9 @@
 #endif
 
 
-int __init register_dmac(struct dma_info *info)
+int register_dmac(struct dma_info *info)
 {
-	int i;
+	unsigned int total_channels, i;
 
 	INIT_LIST_HEAD(&info->list);
 
@@ -217,6 +229,11 @@
 
 	BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
 
+	info->pdev = platform_device_register_simple((char *)info->name, -1,
+						     NULL, 0);
+	if (IS_ERR(info->pdev))
+		return PTR_ERR(info->pdev);
+
 	/*
 	 * Don't touch pre-configured channels
 	 */
@@ -232,10 +249,12 @@
 		memset(info->channels, 0, size);
 	}
 
+	total_channels = get_nr_channels();
 	for (i = 0; i < info->nr_channels; i++) {
 		struct dma_channel *chan = info->channels + i;
 
 		chan->chan = i;
+		chan->vchan = i + total_channels;
 
 		memcpy(chan->dev_id, "Unused", 7);
 
@@ -245,9 +264,7 @@
 		init_MUTEX(&chan->sem);
 		init_waitqueue_head(&chan->wait_queue);
 
-#ifdef CONFIG_SYSFS
-		dma_create_sysfs_files(chan);
-#endif
+		dma_create_sysfs_files(chan, info);
 	}
 
 	list_add(&info->list, &registered_dmac_list);
@@ -255,12 +272,18 @@
 	return 0;
 }
 
-void __exit unregister_dmac(struct dma_info *info)
+void unregister_dmac(struct dma_info *info)
 {
+	unsigned int i;
+
+	for (i = 0; i < info->nr_channels; i++)
+		dma_remove_sysfs_files(info->channels + i, info);
+
 	if (!(info->flags & DMAC_CHANNELS_CONFIGURED))
 		kfree(info->channels);
 
 	list_del(&info->list);
+	platform_device_unregister(info->pdev);
 }
 
 static int __init dma_api_init(void)
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-g2.c sh-2.6.15/arch/sh/drivers/dma/dma-g2.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-g2.c	2004-12-26 05:37:10.000000000 +0200
+++ sh-2.6.15/arch/sh/drivers/dma/dma-g2.c	2006-01-04 00:15:27.000000000 +0200
@@ -140,7 +140,7 @@
 };
 
 static struct dma_info g2_dma_info = {
-	.name		= "G2 DMA",
+	.name		= "g2_dmac",
 	.nr_channels	= 4,
 	.ops		= &g2_dma_ops,
 	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
@@ -160,6 +160,7 @@
 static void __exit g2_dma_exit(void)
 {
 	free_irq(HW_EVENT_G2_DMA, 0);
+	unregister_dmac(&g2_dma_info);
 }
 
 subsys_initcall(g2_dma_init);
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-isa.c sh-2.6.15/arch/sh/drivers/dma/dma-isa.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-isa.c	2004-08-14 20:27:37.000000000 +0300
+++ sh-2.6.15/arch/sh/drivers/dma/dma-isa.c	2006-01-04 00:15:27.000000000 +0200
@@ -25,14 +25,14 @@
  * such, this code is meant for only the simplest of tasks (and shouldn't be
  * used in any new drivers at all).
  *
- * It should also be noted that various functions here are labelled as
- * being deprecated. This is due to the fact that the ops->xfer() method is
- * the preferred way of doing things (as well as just grabbing the spinlock
- * directly). As such, any users of this interface will be warned rather
- * loudly.
+ * 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 compatability 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 __deprecated claim_dma_lock(void)
+unsigned long claim_dma_lock(void)
 {
 	unsigned long flags;
 
@@ -42,19 +42,19 @@
 }
 EXPORT_SYMBOL(claim_dma_lock);
 
-void __deprecated release_dma_lock(unsigned long flags)
+void release_dma_lock(unsigned long flags)
 {
 	spin_unlock_irqrestore(&dma_spin_lock, flags);
 }
 EXPORT_SYMBOL(release_dma_lock);
 
-void __deprecated disable_dma(unsigned int chan)
+void disable_dma(unsigned int chan)
 {
 	/* Nothing */
 }
 EXPORT_SYMBOL(disable_dma);
 
-void __deprecated enable_dma(unsigned int chan)
+void enable_dma(unsigned int chan)
 {
 	struct dma_info *info = get_dma_info(chan);
 	struct dma_channel *channel = &info->channels[chan];
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-pvr2.c sh-2.6.15/arch/sh/drivers/dma/dma-pvr2.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-pvr2.c	2004-12-26 05:37:10.000000000 +0200
+++ sh-2.6.15/arch/sh/drivers/dma/dma-pvr2.c	2006-01-04 00:15:27.000000000 +0200
@@ -80,7 +80,7 @@
 };
 
 static struct dma_info pvr2_dma_info = {
-	.name		= "PowerVR 2 DMA",
+	.name		= "pvr2_dmac",
 	.nr_channels	= 1,
 	.ops		= &pvr2_dma_ops,
 	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
@@ -98,6 +98,7 @@
 {
 	free_dma(PVR2_CASCADE_CHAN);
 	free_irq(HW_EVENT_PVR2_DMA, 0);
+	unregister_dmac(&pvr2_dma_info);
 }
 
 subsys_initcall(pvr2_dma_init);
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-sh.c sh-2.6.15/arch/sh/drivers/dma/dma-sh.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-sh.c	2004-08-14 20:27:37.000000000 +0300
+++ sh-2.6.15/arch/sh/drivers/dma/dma-sh.c	2006-01-07 21:46:31.691900491 +0200
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2000 Takashi YOSHII
  * Copyright (C) 2003, 2004 Paul Mundt
+ * Copyright (C) 2005 Andriy Skulysh
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -16,51 +17,28 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <asm/dreamcast/dma.h>
 #include <asm/signal.h>
 #include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include "dma-sh.h"
 
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-enum {
-	XMIT_SZ_64BIT,
-	XMIT_SZ_8BIT,
-	XMIT_SZ_16BIT,
-	XMIT_SZ_32BIT,
-	XMIT_SZ_256BIT,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-static unsigned int ts_shift[] = {
-	[XMIT_SZ_64BIT]		= 3,
-	[XMIT_SZ_8BIT]		= 0,
-	[XMIT_SZ_16BIT]		= 1,
-	[XMIT_SZ_32BIT]		= 2,
-	[XMIT_SZ_256BIT]	= 5,
-};
-
 static inline unsigned int get_dmte_irq(unsigned int chan)
 {
-	unsigned int irq;
+	unsigned int irq = 0;
 
 	/*
 	 * Normally we could just do DMTE0_IRQ + chan outright, though in the
 	 * case of the 7751R, the DMTE IRQs for channels > 4 start right above
 	 * the SCIF
 	 */
-
 	if (chan < 4) {
 		irq = DMTE0_IRQ + chan;
 	} else {
+#ifdef DMTE4_IRQ
 		irq = DMTE4_IRQ + chan - 4;
+#endif
 	}
 
 	return irq;
@@ -78,9 +56,7 @@
 {
 	u32 chcr = ctrl_inl(CHCR[chan->chan]);
 
-	chcr >>= 4;
-
-	return ts_shift[chcr & 0x0007];
+	return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
 }
 
 /*
@@ -109,8 +85,13 @@
 
 static int sh_dmac_request_dma(struct dma_channel *chan)
 {
+	char name[32];
+
+	snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)",
+		 chan->chan);
+
 	return request_irq(get_dmte_irq(chan->chan), dma_tei,
-			   SA_INTERRUPT, "DMAC Transfer End", chan);
+			   SA_INTERRUPT, name, chan);
 }
 
 static void sh_dmac_free_dma(struct dma_channel *chan)
@@ -118,10 +99,18 @@
 	free_irq(get_dmte_irq(chan->chan), chan);
 }
 
-static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
+static void
+sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
 {
 	if (!chcr)
-		chcr = RS_DUAL;
+		chcr = RS_DUAL | CHCR_IE;
+
+	if (chcr & CHCR_IE) {
+		chcr &= ~CHCR_IE;
+		chan->flags |= DMA_TEI_CAPABLE;
+	} else {
+		chan->flags &= ~DMA_TEI_CAPABLE;
+	}
 
 	ctrl_outl(chcr, CHCR[chan->chan]);
 
@@ -130,22 +119,32 @@
 
 static void sh_dmac_enable_dma(struct dma_channel *chan)
 {
-	int irq = get_dmte_irq(chan->chan);
+	int irq;
 	u32 chcr;
 
 	chcr = ctrl_inl(CHCR[chan->chan]);
-	chcr |= CHCR_DE | CHCR_IE;
+	chcr |= CHCR_DE;
+
+	if (chan->flags & DMA_TEI_CAPABLE)
+		chcr |= CHCR_IE;
+
 	ctrl_outl(chcr, CHCR[chan->chan]);
 
-	enable_irq(irq);
+	if (chan->flags & DMA_TEI_CAPABLE) {
+		irq = get_dmte_irq(chan->chan);
+		enable_irq(irq);
+	}
 }
 
 static void sh_dmac_disable_dma(struct dma_channel *chan)
 {
-	int irq = get_dmte_irq(chan->chan);
+	int irq;
 	u32 chcr;
 
-	disable_irq(irq);
+	if (chan->flags & DMA_TEI_CAPABLE) {
+		irq = get_dmte_irq(chan->chan);
+		disable_irq(irq);
+	}
 
 	chcr = ctrl_inl(CHCR[chan->chan]);
 	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
@@ -158,7 +157,7 @@
 	 * If we haven't pre-configured the channel with special flags, use
 	 * the defaults.
 	 */
-	if (!(chan->flags & DMA_CONFIGURED))
+	if (unlikely(!(chan->flags & DMA_CONFIGURED)))
 		sh_dmac_configure_channel(chan, 0);
 
 	sh_dmac_disable_dma(chan);
@@ -178,9 +177,11 @@
 	 * cascading to the PVR2 DMAC. In this case, we still need to write
 	 * SAR and DAR, regardless of value, in order for cascading to work.
 	 */
-	if (chan->sar || (mach_is_dreamcast() && chan->chan == 2))
+	if (chan->sar || (mach_is_dreamcast() &&
+			  chan->chan == PVR2_CASCADE_CHAN))
 		ctrl_outl(chan->sar, SAR[chan->chan]);
-	if (chan->dar || (mach_is_dreamcast() && chan->chan == 2))
+	if (chan->dar || (mach_is_dreamcast() &&
+			  chan->chan == PVR2_CASCADE_CHAN))
 		ctrl_outl(chan->dar, DAR[chan->chan]);
 
 	ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
@@ -198,17 +199,38 @@
 	return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
 }
 
-#if defined(CONFIG_CPU_SH4)
-static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
+#ifdef CONFIG_CPU_SUBTYPE_SH7780
+#define dmaor_read_reg()	ctrl_inw(DMAOR)
+#define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
+#else
+#define dmaor_read_reg()	ctrl_inl(DMAOR)
+#define dmaor_write_reg(data)	ctrl_outl(data, DMAOR)
+#endif
+
+static inline int dmaor_reset(void)
 {
-	unsigned long dmaor = ctrl_inl(DMAOR);
+	unsigned long dmaor = dmaor_read_reg();
+
+	/* Try to clear the error flags first, incase they are set */
+	dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
+	dmaor_write_reg(dmaor);
 
-	printk("DMAE: DMAOR=%lx\n", dmaor);
+	dmaor |= DMAOR_INIT;
+	dmaor_write_reg(dmaor);
 
-	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR);
-	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR);
-	ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR);
+	/* See if we got an error again */
+	if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) {
+		printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
+		return -EINVAL;
+	}
 
+	return 0;
+}
+
+#if defined(CONFIG_CPU_SH4)
+static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
+{
+	dmaor_reset();
 	disable_irq(irq);
 
 	return IRQ_HANDLED;
@@ -224,8 +246,8 @@
 };
 
 static struct dma_info sh_dmac_info = {
-	.name		= "SuperH DMAC",
-	.nr_channels	= 4,
+	.name		= "sh_dmac",
+	.nr_channels	= CONFIG_NR_ONCHIP_DMA_CHANNELS,
 	.ops		= &sh_dmac_ops,
 	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
 };
@@ -248,7 +270,13 @@
 		make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
 	}
 
-	ctrl_outl(0x8000 | DMAOR_DME, DMAOR);
+	/*
+	 * Initialize DMAOR, and clean up any error flags that may have
+	 * been set.
+	 */
+	i = dmaor_reset();
+	if (i < 0)
+		return i;
 
 	return register_dmac(info);
 }
@@ -258,10 +286,12 @@
 #ifdef CONFIG_CPU_SH4
 	free_irq(DMAE_IRQ, 0);
 #endif
+	unregister_dmac(&sh_dmac_info);
 }
 
 subsys_initcall(sh_dmac_init);
 module_exit(sh_dmac_exit);
 
+MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh");
+MODULE_DESCRIPTION("SuperH On-Chip DMAC Support");
 MODULE_LICENSE("GPL");
-
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-sh.h sh-2.6.15/arch/sh/drivers/dma/dma-sh.h
--- linux-2.6.15/arch/sh/drivers/dma/dma-sh.h	2004-07-15 22:21:14.000000000 +0300
+++ sh-2.6.15/arch/sh/drivers/dma/dma-sh.h	2006-01-04 00:15:27.000000000 +0200
@@ -11,6 +11,8 @@
 #ifndef __DMA_SH_H
 #define __DMA_SH_H
 
+#include <asm/cpu/dma.h>
+
 /* Definitions for the SuperH DMAC */
 #define REQ_L	0x00000000
 #define REQ_E	0x00080000
@@ -26,27 +28,47 @@
 #define SM_DEC	0x00002000
 #define RS_IN	0x00000200
 #define RS_OUT	0x00000300
-#define TM_BURST 0x0000080
-#define TS_8	0x00000010
-#define TS_16	0x00000020
-#define TS_32	0x00000030
-#define TS_64	0x00000000
 #define TS_BLK	0x00000040
 #define CHCR_DE 0x00000001
 #define CHCR_TE 0x00000002
 #define CHCR_IE 0x00000004
 
-/* Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- */
-#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
-
-#define DMAOR_COD	0x00000008
+/* DMAOR definitions */
 #define DMAOR_AE	0x00000004
 #define DMAOR_NMIF	0x00000002
 #define DMAOR_DME	0x00000001
 
+/*
+ * Define the default configuration for dual address memory-memory transfer.
+ * The 0x400 value represents auto-request, external->external.
+ */
+#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
+
 #define MAX_DMAC_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
 
+/*
+ * Subtypes that have fewer channels than this simply need to change
+ * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number
+ * of channels should expand on this.
+ *
+ * For most subtypes we can easily figure these values out with some
+ * basic calculation, unfortunately on other subtypes these are more
+ * scattered, so we just leave it unrolled for simplicity.
+ */
+#define SAR	((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
+				   SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \
+				   SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60})
+#define DAR	((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
+				   SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \
+				   SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64})
+#define DMATCR	((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
+				   SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \
+				   SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68})
+#define CHCR	((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
+				   SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \
+				   SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c})
+
+#define DMAOR	(SH_DMAC_BASE + 0x40)
+
 #endif /* __DMA_SH_H */
 
diff -urN -X exclude linux-2.6.15/arch/sh/drivers/dma/dma-sysfs.c sh-2.6.15/arch/sh/drivers/dma/dma-sysfs.c
--- linux-2.6.15/arch/sh/drivers/dma/dma-sysfs.c	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/drivers/dma/dma-sysfs.c	2006-01-04 16:58:04.000000000 +0200
@@ -3,7 +3,7 @@
  *
  * sysfs interface for SH DMA API
  *
- * Copyright (C) 2004  Paul Mundt
+ * Copyright (C) 2004, 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
@@ -12,7 +12,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/err.h>
 #include <linux/string.h>
 #include <asm/dma.h>
 
@@ -77,7 +79,7 @@
 	unsigned long config;
 
 	config = simple_strtoul(buf, NULL, 0);
-	dma_configure_channel(channel->chan, config);
+	dma_configure_channel(channel->vchan, config);
 
 	return count;
 }
@@ -111,12 +113,13 @@
 dma_ro_attr(count, "0x%08x\n");
 dma_ro_attr(flags, "0x%08lx\n");
 
-int __init dma_create_sysfs_files(struct dma_channel *chan)
+int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info)
 {
 	struct sys_device *dev = &chan->dev;
+	char name[16];
 	int ret;
 
-	dev->id  = chan->chan;
+	dev->id  = chan->vchan;
 	dev->cls = &dma_sysclass;
 
 	ret = sysdev_register(dev);
@@ -129,6 +132,24 @@
 	sysdev_create_file(dev, &attr_flags);
 	sysdev_create_file(dev, &attr_config);
 
-	return 0;
+	snprintf(name, sizeof(name), "dma%d", chan->chan);
+	return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name);
+}
+
+void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info)
+{
+	struct sys_device *dev = &chan->dev;
+	char name[16];
+
+	sysdev_remove_file(dev, &attr_dev_id);
+	sysdev_remove_file(dev, &attr_count);
+	sysdev_remove_file(dev, &attr_mode);
+	sysdev_remove_file(dev, &attr_flags);
+	sysdev_remove_file(dev, &attr_config);
+
+	snprintf(name, sizeof(name), "dma%d", chan->chan);
+	sysfs_remove_link(&info->pdev->dev.kobj, name);
+
+	sysdev_unregister(dev);
 }
 
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/bus.c sh-2.6.15/arch/sh/kernel/cpu/bus.c
--- linux-2.6.15/arch/sh/kernel/cpu/bus.c	2005-06-20 22:45:19.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/cpu/bus.c	2006-01-04 00:15:27.000000000 +0200
@@ -107,6 +107,8 @@
 	/* This is needed for USB OHCI to work */
 	if (dev->dma_mask)
 		dev->dev.dma_mask = dev->dma_mask;
+	if (dev->coherent_dma_mask)
+		dev->dev.coherent_dma_mask = dev->coherent_dma_mask;
 
 	snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u",
 		 dev->name, dev->dev_id);

diff -urN -X exclude linux-2.6.15/include/asm-sh/bus-sh.h sh-2.6.15/include/asm-sh/bus-sh.h
--- linux-2.6.15/include/asm-sh/bus-sh.h	2005-06-20 22:46:02.000000000 +0300
+++ sh-2.6.15/include/asm-sh/bus-sh.h	2006-01-04 00:15:29.000000000 +0200
@@ -21,6 +21,7 @@
 	void		*mapbase;
 	unsigned int	irq[6];
 	u64		*dma_mask;
+	u64		coherent_dma_mask;
 };
 
 #define to_sh_dev(d)	container_of((d), struct sh_dev, dev)

diff -urN -X exclude linux-2.6.15/include/asm-sh/cpu-sh3/dma.h sh-2.6.15/include/asm-sh/cpu-sh3/dma.h
--- linux-2.6.15/include/asm-sh/cpu-sh3/dma.h	2004-07-15 22:22:27.000000000 +0300
+++ sh-2.6.15/include/asm-sh/cpu-sh3/dma.h	2006-01-04 16:58:04.000000000 +0200
@@ -3,5 +3,34 @@
 
 #define SH_DMAC_BASE	0xa4000020
 
-#endif /* __ASM_CPU_SH3_DMA_H */
+/* Definitions for the SuperH DMAC */
+#define TM_BURST	0x00000020
+#define TS_8		0x00000000
+#define TS_16		0x00000008
+#define TS_32		0x00000010
+#define TS_128		0x00000018
+
+#define CHCR_TS_MASK	0x18
+#define CHCR_TS_SHIFT	3
+
+#define DMAOR_INIT	DMAOR_DME
 
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ */
+enum {
+	XMIT_SZ_8BIT,
+	XMIT_SZ_16BIT,
+	XMIT_SZ_32BIT,
+	XMIT_SZ_128BIT,
+};
+
+static unsigned int ts_shift[] __attribute__ ((used)) = {
+	[XMIT_SZ_8BIT]		= 0,
+	[XMIT_SZ_16BIT]		= 1,
+	[XMIT_SZ_32BIT]		= 2,
+	[XMIT_SZ_128BIT]	= 4,
+};
+
+#endif /* __ASM_CPU_SH3_DMA_H */


diff -urN -X exclude linux-2.6.15/include/asm-sh/cpu-sh4/dma.h sh-2.6.15/include/asm-sh/cpu-sh4/dma.h
--- linux-2.6.15/include/asm-sh/cpu-sh4/dma.h	2004-08-14 20:28:00.000000000 +0300
+++ sh-2.6.15/include/asm-sh/cpu-sh4/dma.h	2006-01-04 00:15:29.000000000 +0200
@@ -1,17 +1,49 @@
 #ifndef __ASM_CPU_SH4_DMA_H
 #define __ASM_CPU_SH4_DMA_H
 
+#ifdef CONFIG_CPU_SH4A
+#define SH_DMAC_BASE	0xfc808020
+#else
 #define SH_DMAC_BASE	0xffa00000
+#endif
 
-#define SAR	((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
-				   SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30})
-#define DAR	((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
-				   SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34})
-#define DMATCR	((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
-				   SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38})
-#define CHCR	((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
-				   SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c})
-#define DMAOR	(SH_DMAC_BASE + 0x40)
+/* Definitions for the SuperH DMAC */
+#define TM_BURST	0x0000080
+#define TS_8		0x00000010
+#define TS_16		0x00000020
+#define TS_32		0x00000030
+#define TS_64		0x00000000
 
-#endif /* __ASM_CPU_SH4_DMA_H */
+#define CHCR_TS_MASK	0x30
+#define CHCR_TS_SHIFT	4
+
+#define DMAOR_COD	0x00000008
+
+#define DMAOR_INIT	( 0x8000 | DMAOR_DME )
 
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ *
+ * Defaults to a 64-bit transfer size.
+ */
+enum {
+	XMIT_SZ_64BIT,
+	XMIT_SZ_8BIT,
+	XMIT_SZ_16BIT,
+	XMIT_SZ_32BIT,
+	XMIT_SZ_256BIT,
+};
+
+/*
+ * The DMA count is defined as the number of bytes to transfer.
+ */
+static unsigned int ts_shift[] __attribute__ ((used)) = {
+	[XMIT_SZ_64BIT]		= 3,
+	[XMIT_SZ_8BIT]		= 0,
+	[XMIT_SZ_16BIT]		= 1,
+	[XMIT_SZ_32BIT]		= 2,
+	[XMIT_SZ_256BIT]	= 5,
+};
+
+#endif /* __ASM_CPU_SH4_DMA_H */

diff -urN -X exclude linux-2.6.15/include/asm-sh/dma-mapping.h sh-2.6.15/include/asm-sh/dma-mapping.h
--- linux-2.6.15/include/asm-sh/dma-mapping.h	2006-01-04 14:20:02.000000000 +0200
+++ sh-2.6.15/include/asm-sh/dma-mapping.h	2006-01-04 14:29:32.000000000 +0200
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
+#include <asm/cacheflush.h>
 #include <asm/io.h>
 
 extern struct bus_type pci_bus_type;
@@ -141,24 +142,24 @@
 	}
 }
 
-static inline void dma_sync_single_for_cpu(struct device *dev,
-					   dma_addr_t dma_handle, size_t size,
-					   enum dma_data_direction dir)
+static void dma_sync_single_for_cpu(struct device *dev,
+				    dma_addr_t dma_handle, size_t size,
+				    enum dma_data_direction dir)
 	__attribute__ ((alias("dma_sync_single")));
 
-static inline void dma_sync_single_for_device(struct device *dev,
-					   dma_addr_t dma_handle, size_t size,
-					   enum dma_data_direction dir)
+static void dma_sync_single_for_device(struct device *dev,
+				       dma_addr_t dma_handle, size_t size,
+				       enum dma_data_direction dir)
 	__attribute__ ((alias("dma_sync_single")));
 
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-				       struct scatterlist *sg, int nelems,
-				       enum dma_data_direction dir)
+static void dma_sync_sg_for_cpu(struct device *dev,
+				struct scatterlist *sg, int nelems,
+				enum dma_data_direction dir)
 	__attribute__ ((alias("dma_sync_sg")));
 
-static inline void dma_sync_sg_for_device(struct device *dev,
-				       struct scatterlist *sg, int nelems,
-				       enum dma_data_direction dir)
+static void dma_sync_sg_for_device(struct device *dev,
+				   struct scatterlist *sg, int nelems,
+				   enum dma_data_direction dir)
 	__attribute__ ((alias("dma_sync_sg")));
 
 static inline int dma_get_cache_alignment(void)
diff -urN -X exclude linux-2.6.15/include/asm-sh/dma.h sh-2.6.15/include/asm-sh/dma.h
--- linux-2.6.15/include/asm-sh/dma.h	2004-12-26 05:37:56.000000000 +0200
+++ sh-2.6.15/include/asm-sh/dma.h	2006-01-04 00:15:30.000000000 +0200
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/sysdev.h>
+#include <linux/device.h>
 #include <asm/cpu/dma.h>
 #include <asm/semaphore.h>
 
@@ -54,8 +55,8 @@
  * DMA channel capabilities / flags
  */
 enum {
-	DMA_CONFIGURED			= 0x00,
 	DMA_TEI_CAPABLE			= 0x01,
+	DMA_CONFIGURED			= 0x02,
 };
 
 extern spinlock_t dma_spin_lock;
@@ -74,7 +75,8 @@
 struct dma_channel {
 	char dev_id[16];
 
-	unsigned int chan;
+	unsigned int chan;		/* Physical channel number */
+	unsigned int vchan;		/* Virtual channel number */
 	unsigned int mode;
 	unsigned int count;
 
@@ -91,6 +93,8 @@
 };
 
 struct dma_info {
+	struct platform_device *pdev;
+
 	const char *name;
 	unsigned int nr_channels;
 	unsigned long flags;
@@ -130,7 +134,11 @@
 
 #ifdef CONFIG_SYSFS
 /* arch/sh/drivers/dma/dma-sysfs.c */
-extern int dma_create_sysfs_files(struct dma_channel *);
+extern int dma_create_sysfs_files(struct dma_channel *, struct dma_info *);
+extern void dma_remove_sysfs_files(struct dma_channel *, struct dma_info *);
+#else
+#define dma_create_sysfs_file(channel, info)		do { } while (0)
+#define dma_remove_sysfs_file(channel, info)		do { } while (0)
 #endif
 
 #ifdef CONFIG_PCI

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/8] sh: kexec() support.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
  2006-01-14 22:51 ` [PATCH 1/8] sh: Consolidate hp620/hp680/hp690 targets into hp6xx Paul Mundt
  2006-01-14 22:51 ` [PATCH 2/8] sh: DMA updates Paul Mundt
@ 2006-01-14 22:52 ` Paul Mundt
  2006-01-14 22:53 ` [PATCH 4/8] sh: IRQ handler updates Paul Mundt
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:52 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

From: kogiidena <kogiidena@eggplant.ddo.jp>

This adds kexec() support for SH.

Signed-off-by: kogiidena <kogiidena@eggplant.ddo.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/kernel/Makefile          |    4 -
 arch/sh/kernel/machine_kexec.c   |  112 +++++++++++++++++++++++++++++++++++++++
 arch/sh/kernel/process.c         |   10 +++
 arch/sh/kernel/relocate_kernel.S |  102 +++++++++++++++++++++++++++++++++++
 include/asm-sh/kexec.h           |   33 +++++++++++
 include/linux/kexec.h            |    1 
 6 files changed, 259 insertions(+), 3 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/Makefile sh-2.6.15/arch/sh/kernel/Makefile
--- linux-2.6.15/arch/sh/kernel/Makefile	2004-10-25 13:03:28.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/Makefile	2006-01-04 00:15:27.000000000 +0200
@@ -17,6 +17,4 @@
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-
-USE_STANDARD_AS_RULE := true
-
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/machine_kexec.c sh-2.6.15/arch/sh/kernel/machine_kexec.c
--- linux-2.6.15/arch/sh/kernel/machine_kexec.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/machine_kexec.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,112 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ * LANDISK/sh4 supported by kogiidena
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+
+typedef NORET_TYPE void (*relocate_new_kernel_t)(
+				unsigned long indirection_page,
+				unsigned long reboot_code_buffer,
+				unsigned long start_address,
+				unsigned long vbr_reg) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned int relocate_new_kernel_size;
+extern void *gdb_vbr_vector;
+
+/*
+ * Provide a dummy crash_notes definition while crash dump arrives to ppc.
+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
+ */
+void *crash_notes = NULL;
+
+void machine_shutdown(void)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+/*
+ * Do what every setup is needed on image and the
+ * reboot code buffer to allow us to avoid allocations
+ * later.
+ */
+int machine_kexec_prepare(struct kimage *image)
+{
+	return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+static void kexec_info(struct kimage *image)
+{
+        int i;
+	printk("kexec information\n");
+	for (i = 0; i < image->nr_segments; i++) {
+	        printk("  segment[%d]: 0x%08x - 0x%08x (0x%08x)\n",
+		       i,
+		       (unsigned int)image->segment[i].mem,
+		       (unsigned int)image->segment[i].mem + image->segment[i].memsz,
+		       (unsigned int)image->segment[i].memsz);
+ 	}
+	printk("  start     : 0x%08x\n\n", (unsigned int)image->start);
+}
+
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+
+	unsigned long page_list;
+	unsigned long reboot_code_buffer;
+	unsigned long vbr_reg;
+	relocate_new_kernel_t rnk;
+
+#if defined(CONFIG_SH_STANDARD_BIOS)
+	vbr_reg = ((unsigned long )gdb_vbr_vector) - 0x100;
+#else
+	vbr_reg = 0x80000000;  // dummy
+#endif
+	/* Interrupts aren't acceptable while we reboot */
+	local_irq_disable();
+
+	page_list = image->head;
+
+	/* we need both effective and real address here */
+	reboot_code_buffer =
+			(unsigned long)page_address(image->control_code_page);
+
+	/* copy our kernel relocation code to the control code page */
+	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+						relocate_new_kernel_size);
+
+        kexec_info(image);
+	flush_cache_all();
+
+	/* now call it */
+	rnk = (relocate_new_kernel_t) reboot_code_buffer;
+       	(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
+}
+

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/relocate_kernel.S sh-2.6.15/arch/sh/kernel/relocate_kernel.S
--- linux-2.6.15/arch/sh/kernel/relocate_kernel.S	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/relocate_kernel.S	2006-01-04 00:15:28.000000000 +0200
@@ -0,0 +1,102 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * 2005.9.17 kogiidena@eggplant.ddo.jp
+ *
+ * LANDISK/sh4 is supported. Maybe, SH archtecture works well.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#define PAGE_SIZE      4096 /* must be same value as in <asm/page.h> */
+	
+	
+		.globl relocate_new_kernel
+relocate_new_kernel:
+	/* r4 = indirection_page   */
+	/* r5 = reboot_code_buffer */
+	/* r6 = start_address      */
+	/* r7 = vbr_reg            */
+
+	mov.l	10f,r8	  /* 4096 */
+	mov.l	11f,r9    /* 0xa0000000 */
+
+	/*  stack setting */
+	add	r8,r5
+	mov	r5,r15
+
+	bra	1f
+	mov	r4,r0	  /* cmd = indirection_page */
+0:	
+	mov.l	@r4+,r0	  /* cmd = *ind++ */
+
+1:	/* addr = (cmd | 0xa0000000) & 0xfffffff0 */
+	mov	r0,r2
+	or	r9,r2
+	mov	#-16,r1
+	and	r1,r2	
+
+	/* if(cmd & IND_DESTINATION) dst = addr  */
+	tst	#1,r0	
+	bt	2f
+	bra	0b	
+	mov	r2,r5	
+
+2:	/* else if(cmd & IND_INDIRECTION) ind = addr  */
+	tst	#2,r0
+	bt	3f
+	bra	0b	
+	mov	r2,r4
+
+3:	/* else if(cmd & IND_DONE) goto 6  */
+	tst	#4,r0
+	bt	4f
+	bra	6f
+	nop
+
+4:	/* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
+	tst	#8,r0
+	bt	0b
+
+	mov	r8,r3
+	shlr2	r3	
+	shlr2	r3	
+5:	
+	dt	r3
+	mov.l	@r2+,r1   /*  16n+0 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1	  /*  16n+4 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1   /*  16n+8 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1   /*  16n+12 */
+	mov.l	r1,@r5
+	add	#4,r5
+	bf	5b
+	
+	bra	0b
+	nop
+6:
+#ifdef CONFIG_SH_STANDARD_BIOS
+	ldc   r7, vbr
+#endif
+	jmp @r6
+	nop
+
+	.align 2
+10:
+	.long	PAGE_SIZE
+11:
+	.long	0xa0000000
+
+relocate_new_kernel_end:
+
+	.globl relocate_new_kernel_size
+relocate_new_kernel_size:
+	.long relocate_new_kernel_end - relocate_new_kernel

diff -urN -X exclude linux-2.6.15/include/asm-sh/kexec.h sh-2.6.15/include/asm-sh/kexec.h
--- linux-2.6.15/include/asm-sh/kexec.h	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/include/asm-sh/kexec.h	2006-01-04 00:15:29.000000000 +0200
@@ -0,0 +1,33 @@
+#ifndef _SH_KEXEC_H
+#define _SH_KEXEC_H
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
+ * calculation for the amount of memory directly mappable into the
+ * kernel memory space.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE	4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_SH
+
+#ifndef __ASSEMBLY__
+
+extern void machine_shutdown(void);
+extern void *crash_notes;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _SH_KEXEC_H */

diff -urN -X exclude linux-2.6.15/include/linux/kexec.h sh-2.6.15/include/linux/kexec.h
--- linux-2.6.15/include/linux/kexec.h	2005-09-01 00:20:33.000000000 +0300
+++ sh-2.6.15/include/linux/kexec.h	2006-01-04 00:15:30.000000000 +0200
@@ -119,6 +119,7 @@
 #define KEXEC_ARCH_PPC64   (21 << 16)
 #define KEXEC_ARCH_IA_64   (50 << 16)
 #define KEXEC_ARCH_S390    (22 << 16)
+#define KEXEC_ARCH_SH      (42 << 16)
 
 #define KEXEC_FLAGS    (KEXEC_ON_CRASH)  /* List of defined/legal kexec flags */

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/process.c sh-2.6.15/arch/sh/kernel/process.c
--- linux-2.6.15/arch/sh/kernel/process.c	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/process.c	2006-01-04 00:26:10.000000000 +0200
@@ -71,6 +81,16 @@
 
 void machine_restart(char * __unused)
 {
+
+#ifdef CONFIG_KEXEC
+	struct kimage *image;
+	image = xchg(&kexec_image, 0);
+	if (image) {
+		machine_shutdown();
+		machine_kexec(image);
+	}
+#endif
+
 	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
 	asm volatile("ldc %0, sr\n\t"
 		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/8] sh: IRQ handler updates.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
                   ` (2 preceding siblings ...)
  2006-01-14 22:52 ` [PATCH 3/8] sh: kexec() support Paul Mundt
@ 2006-01-14 22:53 ` Paul Mundt
  2006-01-14 22:54 ` [PATCH 5/8] sh: I/O routine cleanups and ioremap() overhaul Paul Mundt
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:53 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This moves the various IRQ controller drivers into a new subdirectory,
and also extends the INTC2 IRQ handler to also deal with SH7760 and
SH7780 interrupts, rather than just ST-40.

The old CONFIG_SH_GENERIC has also been removed from the IRQ definitions,
as new ports are expected to be based off of CONFIG_SH_UNKNOWN. Since
there are plenty of incompatible machvecs, CONFIG_SH_GENERIC doesn't make
sense anymore.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/kernel/cpu/Makefile        |    9 
 arch/sh/kernel/cpu/irq/Makefile    |    7 
 arch/sh/kernel/cpu/irq/imask.c     |  110 +++++++++++
 arch/sh/kernel/cpu/irq/intc2.c     |  284 ++++++++++++++++++++++++++++++
 arch/sh/kernel/cpu/irq/ipr.c       |  206 +++++++++++++++++++++
 arch/sh/kernel/cpu/irq/pint.c      |  169 +++++++++++++++++
 arch/sh/kernel/cpu/irq_imask.c     |  116 ------------
 arch/sh/kernel/cpu/irq_ipr.c       |  339 -----------------------------------
 arch/sh/kernel/cpu/sh4/irq_intc2.c |  222 -----------------------
 arch/sh/kernel/irq.c               |   64 ++----
 include/asm-sh/irq-sh73180.h       |   16 -
 include/asm-sh/irq-sh7780.h        |  349 +++++++++++++++++++++++++++++++++++++
 include/asm-sh/irq.h               |  143 ++++++++-------
 13 files changed, 1240 insertions(+), 794 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/Makefile sh-2.6.15/arch/sh/kernel/cpu/Makefile
--- linux-2.6.15/arch/sh/kernel/cpu/Makefile	2004-08-14 20:27:37.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/cpu/Makefile	2006-01-07 22:13:59.118151154 +0200
@@ -2,15 +2,12 @@
 # Makefile for the Linux/SuperH CPU-specifc backends.
 #
 
-obj-y	:= irq_ipr.o irq_imask.o init.o bus.o
+obj-y	+= irq/ init.o bus.o clock.o
 
 obj-$(CONFIG_CPU_SH2)		+= sh2/
 obj-$(CONFIG_CPU_SH3)		+= sh3/
 obj-$(CONFIG_CPU_SH4)		+= sh4/
 
-obj-$(CONFIG_SH_RTC)            += rtc.o
+obj-$(CONFIG_SH_RTC)		+= rtc.o
 obj-$(CONFIG_UBC_WAKEUP)	+= ubc.o
-obj-$(CONFIG_SH_ADC)            += adc.o
-
-USE_STANDARD_AS_RULE := true
-
+obj-$(CONFIG_SH_ADC)		+= adc.o

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq/Makefile sh-2.6.15/arch/sh/kernel/cpu/irq/Makefile
--- linux-2.6.15/arch/sh/kernel/cpu/irq/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq/Makefile	2006-01-07 22:13:59.123150761 +0200
@@ -0,0 +1,7 @@
+#
+# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
+#
+obj-y	+= ipr.o imask.o
+
+obj-$(CONFIG_CPU_HAS_PINT_IRQ)	+= pint.o
+obj-$(CONFIG_CPU_HAS_INTC2_IRQ)	+= intc2.o
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq/imask.c sh-2.6.15/arch/sh/kernel/cpu/irq/imask.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq/imask.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq/imask.c	2006-01-07 22:13:59.127150447 +0200
@@ -0,0 +1,110 @@
+/*
+ * arch/sh/kernel/cpu/irq/imask.c
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ *
+ * Simple interrupt handling using IMASK of SR register.
+ *
+ */
+/* NOTE: Will not work on level 15 */
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+/* Bitmap of IRQ masked */
+static unsigned long imask_mask = 0x7fff;
+static int interrupt_priority = 0;
+
+static void enable_imask_irq(unsigned int irq);
+static void disable_imask_irq(unsigned int irq);
+static void shutdown_imask_irq(unsigned int irq);
+static void mask_and_ack_imask(unsigned int);
+static void end_imask_irq(unsigned int irq);
+
+#define IMASK_PRIORITY	15
+
+static unsigned int startup_imask_irq(unsigned int irq)
+{
+	/* Nothing to do */
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type imask_irq_type = {
+	.typename = "SR.IMASK",
+	.startup = startup_imask_irq,
+	.shutdown = shutdown_imask_irq,
+	.enable = enable_imask_irq,
+	.disable = disable_imask_irq,
+	.ack = mask_and_ack_imask,
+	.end = end_imask_irq
+};
+
+void static inline set_interrupt_registers(int ip)
+{
+	unsigned long __dummy;
+
+	asm volatile("ldc	%2, r6_bank\n\t"
+		     "stc	sr, %0\n\t"
+		     "and	#0xf0, %0\n\t"
+		     "shlr2	%0\n\t"
+		     "cmp/eq	#0x3c, %0\n\t"
+		     "bt/s	1f	! CLI-ed\n\t"
+		     " stc	sr, %0\n\t"
+		     "and	%1, %0\n\t"
+		     "or	%2, %0\n\t"
+		     "ldc	%0, sr\n"
+		     "1:"
+		     : "=&z" (__dummy)
+		     : "r" (~0xf0), "r" (ip << 4)
+		     : "t");
+}
+
+static void disable_imask_irq(unsigned int irq)
+{
+	clear_bit(irq, &imask_mask);
+	if (interrupt_priority < IMASK_PRIORITY - irq)
+		interrupt_priority = IMASK_PRIORITY - irq;
+
+	set_interrupt_registers(interrupt_priority);
+}
+
+static void enable_imask_irq(unsigned int irq)
+{
+	set_bit(irq, &imask_mask);
+	interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
+
+	set_interrupt_registers(interrupt_priority);
+}
+
+static void mask_and_ack_imask(unsigned int irq)
+{
+	disable_imask_irq(irq);
+}
+
+static void end_imask_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_imask_irq(irq);
+}
+
+static void shutdown_imask_irq(unsigned int irq)
+{
+	/* Nothing to do */
+}
+
+void make_imask_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &imask_irq_type;
+	enable_irq(irq);
+}
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq/intc2.c sh-2.6.15/arch/sh/kernel/cpu/irq/intc2.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq/intc2.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq/intc2.c	2006-01-07 22:13:59.133149975 +0200
@@ -0,0 +1,284 @@
+/*
+ * Interrupt handling for INTC2-based IRQ.
+ *
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.org)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * These are the "new Hitachi style" interrupts, as present on the
+ * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+struct intc2_data {
+	unsigned char msk_offset;
+	unsigned char msk_shift;
+
+	int (*clear_irq) (int);
+};
+
+static struct intc2_data intc2_data[NR_INTC2_IRQS];
+
+static void enable_intc2_irq(unsigned int irq);
+static void disable_intc2_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_intc2_irq disable_intc2_irq
+
+static void mask_and_ack_intc2(unsigned int);
+static void end_intc2_irq(unsigned int irq);
+
+static unsigned int startup_intc2_irq(unsigned int irq)
+{
+	enable_intc2_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type intc2_irq_type = {
+	.typename	= "INTC2-IRQ",
+	.startup	= startup_intc2_irq,
+	.shutdown	= shutdown_intc2_irq,
+	.enable		= enable_intc2_irq,
+	.disable	= disable_intc2_irq,
+	.ack		= mask_and_ack_intc2,
+	.end		= end_intc2_irq
+};
+
+static void disable_intc2_irq(unsigned int irq)
+{
+	int irq_offset = irq - INTC2_FIRST_IRQ;
+	int msk_shift, msk_offset;
+
+	/* Sanity check */
+	if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
+		return;
+
+	msk_shift = intc2_data[irq_offset].msk_shift;
+	msk_offset = intc2_data[irq_offset].msk_offset;
+
+	ctrl_outl(1 << msk_shift,
+		  INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset);
+}
+
+static void enable_intc2_irq(unsigned int irq)
+{
+	int irq_offset = irq - INTC2_FIRST_IRQ;
+	int msk_shift, msk_offset;
+
+	/* Sanity check */
+	if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
+		return;
+
+	msk_shift = intc2_data[irq_offset].msk_shift;
+	msk_offset = intc2_data[irq_offset].msk_offset;
+
+	ctrl_outl(1 << msk_shift,
+		  INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset);
+}
+
+static void mask_and_ack_intc2(unsigned int irq)
+{
+	disable_intc2_irq(irq);
+}
+
+static void end_intc2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_intc2_irq(irq);
+
+	if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq))
+		intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq);
+}
+
+/*
+ * Setup an INTC2 style interrupt.
+ * NOTE: Unlike IPR interrupts, parameters are not shifted by this code,
+ * allowing the use of the numbers straight out of the datasheet.
+ * For example:
+ *    PIO1 which is INTPRI00[19,16] and INTMSK00[13]
+ * would be:               ^     ^             ^  ^
+ *                         |     |             |  |
+ *    make_intc2_irq(84,   0,   16,            0, 13);
+ */
+void make_intc2_irq(unsigned int irq,
+		    unsigned int ipr_offset, unsigned int ipr_shift,
+		    unsigned int msk_offset, unsigned int msk_shift,
+		    unsigned int priority)
+{
+	int irq_offset = irq - INTC2_FIRST_IRQ;
+	unsigned int flags;
+	unsigned long ipr;
+
+	if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
+		return;
+
+	disable_irq_nosync(irq);
+
+	/* Fill the data we need */
+	intc2_data[irq_offset].msk_offset = msk_offset;
+	intc2_data[irq_offset].msk_shift  = msk_shift;
+	intc2_data[irq_offset].clear_irq = NULL;
+
+	/* Set the priority level */
+	local_irq_save(flags);
+
+	ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset);
+	ipr &= ~(0xf << ipr_shift);
+	ipr |= priority << ipr_shift;
+	ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset);
+
+	local_irq_restore(flags);
+
+	irq_desc[irq].handler = &intc2_irq_type;
+
+	disable_intc2_irq(irq);
+}
+
+static struct intc2_init {
+	unsigned short irq;
+	unsigned char ipr_offset, ipr_shift;
+	unsigned char msk_offset, msk_shift;
+	unsigned char priority;
+} intc2_init_data[]  __initdata = {
+#if defined(CONFIG_CPU_SUBTYPE_ST40)
+	{64,  0,  0, 0,  0, 13},	/* PCI serr */
+	{65,  0,  4, 0,  1, 13},	/* PCI err */
+	{66,  0,  4, 0,  2, 13},	/* PCI ad */
+	{67,  0,  4, 0,  3, 13},	/* PCI pwd down */
+	{72,  0,  8, 0,  5, 13},	/* DMAC INT0 */
+	{73,  0,  8, 0,  6, 13},	/* DMAC INT1 */
+	{74,  0,  8, 0,  7, 13},	/* DMAC INT2 */
+	{75,  0,  8, 0,  8, 13},	/* DMAC INT3 */
+	{76,  0,  8, 0,  9, 13},	/* DMAC INT4 */
+	{78,  0,  8, 0, 11, 13},	/* DMAC ERR */
+	{80,  0, 12, 0, 12, 13},	/* PIO0 */
+	{84,  0, 16, 0, 13, 13},	/* PIO1 */
+	{88,  0, 20, 0, 14, 13},	/* PIO2 */
+	{112, 4,  0, 4,  0, 13},	/* Mailbox */
+ #ifdef CONFIG_CPU_SUBTYPE_ST40GX1
+	{116, 4,  4, 4,  4, 13},	/* SSC0 */
+	{120, 4,  8, 4,  8, 13},	/* IR Blaster */
+	{124, 4, 12, 4, 12, 13},	/* USB host */
+	{128, 4, 16, 4, 16, 13},	/* Video processor BLITTER */
+	{132, 4, 20, 4, 20, 13},	/* UART0 */
+	{134, 4, 20, 4, 22, 13},	/* UART2 */
+	{136, 4, 24, 4, 24, 13},	/* IO_PIO0 */
+	{140, 4, 28, 4, 28, 13},	/* EMPI */
+	{144, 8,  0, 8,  0, 13},	/* MAFE */
+	{148, 8,  4, 8,  4, 13},	/* PWM */
+	{152, 8,  8, 8,  8, 13},	/* SSC1 */
+	{156, 8, 12, 8, 12, 13},	/* IO_PIO1 */
+	{160, 8, 16, 8, 16, 13},	/* USB target */
+	{164, 8, 20, 8, 20, 13},	/* UART1 */
+	{168, 8, 24, 8, 24, 13},	/* Teletext */
+	{172, 8, 28, 8, 28, 13},	/* VideoSync VTG */
+	{173, 8, 28, 8, 29, 13},	/* VideoSync DVP0 */
+	{174, 8, 28, 8, 30, 13},	/* VideoSync DVP1 */
+#endif
+#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
+/*
+ * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
+ */
+	/* INTPRIO0 | INTMSK0 */
+	{48,  0, 28, 0, 31,  3},	/* IRQ 4 */
+	{49,  0, 24, 0, 30,  3},	/* IRQ 3 */
+	{50,  0, 20, 0, 29,  3},	/* IRQ 2 */
+	{51,  0, 16, 0, 28,  3},	/* IRQ 1 */
+	/* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
+	/* INTPRIO4 | INTMSK0 */
+	{56,  4, 28, 0, 25,  3},	/* HCAN2_CHAN0 */
+	{57,  4, 24, 0, 24,  3},	/* HCAN2_CHAN1 */
+	{58,  4, 20, 0, 23,  3},	/* I2S_CHAN0   */
+	{59,  4, 16, 0, 22,  3},	/* I2S_CHAN1   */
+	{60,  4, 12, 0, 21,  3},	/* AC97_CHAN0  */
+	{61,  4,  8, 0, 20,  3},	/* AC97_CHAN1  */
+	{62,  4,  4, 0, 19,  3},	/* I2C_CHAN0   */
+	{63,  4,  0, 0, 18,  3},	/* I2C_CHAN1   */
+	/* INTPRIO8 | INTMSK0 */
+	{52,  8, 16, 0, 11,  3},	/* SCIF0_ERI_IRQ */
+	{53,  8, 16, 0, 10,  3},	/* SCIF0_RXI_IRQ */
+	{54,  8, 16, 0,  9,  3},	/* SCIF0_BRI_IRQ */
+	{55,  8, 16, 0,  8,  3},	/* SCIF0_TXI_IRQ */
+	{64,  8, 28, 0, 17,  3},	/* USBHI_IRQ */
+	{65,  8, 24, 0, 16,  3},	/* LCDC      */
+	/* 66, 67 unused */
+	{68,  8, 20, 0, 14, 13},	/* DMABRGI0_IRQ */
+	{69,  8, 20, 0, 13, 13},	/* DMABRGI1_IRQ */
+	{70,  8, 20, 0, 12, 13},	/* DMABRGI2_IRQ */
+	/* 71 unused */
+	{72,  8, 12, 0,  7,  3},	/* SCIF1_ERI_IRQ */
+	{73,  8, 12, 0,  6,  3},	/* SCIF1_RXI_IRQ */
+	{74,  8, 12, 0,  5,  3},	/* SCIF1_BRI_IRQ */
+	{75,  8, 12, 0,  4,  3},	/* SCIF1_TXI_IRQ */
+	{76,  8,  8, 0,  3,  3},	/* SCIF2_ERI_IRQ */
+	{77,  8,  8, 0,  2,  3},	/* SCIF2_RXI_IRQ */
+	{78,  8,  8, 0,  1,  3},	/* SCIF2_BRI_IRQ */
+	{79,  8,  8, 0,  0,  3},	/* SCIF2_TXI_IRQ */
+	/*          | INTMSK4 */
+	{80,  8,  4, 4, 23,  3},	/* SIM_ERI */
+	{81,  8,  4, 4, 22,  3},	/* SIM_RXI */
+	{82,  8,  4, 4, 21,  3},	/* SIM_TXI */
+	{83,  8,  4, 4, 20,  3},	/* SIM_TEI */
+	{84,  8,  0, 4, 19,  3},	/* HSPII */
+	/* INTPRIOC | INTMSK4 */
+	/* 85-87 unused/reserved */
+	{88, 12, 20, 4, 18,  3},	/* MMCI0 */
+	{89, 12, 20, 4, 17,  3},	/* MMCI1 */
+	{90, 12, 20, 4, 16,  3},	/* MMCI2 */
+	{91, 12, 20, 4, 15,  3},	/* MMCI3 */
+	{92, 12, 12, 4,  6,  3},	/* MFI (unsure, bug? in my 7760 manual*/
+	/* 93-107 reserved/undocumented */
+	{108,12,  4, 4,  1,  3},	/* ADC  */
+	{109,12,  0, 4,  0,  3},	/* CMTI */
+	/* 110-111 reserved/unused */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+	{ TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
+#ifdef CONFIG_SH_RTC
+	{ RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+#endif
+	{ SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+
+	{ SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+
+	{ PCIC0_IRQ, 0x10,  8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
+	{ PCIC1_IRQ, 0x10,  0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
+	{ PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
+	{ PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
+	{ PCIC4_IRQ, 0x14,  8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
+#endif
+};
+
+void __init init_IRQ_intc2(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) {
+		struct intc2_init *p = intc2_init_data + i;
+		make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift,
+			       p-> msk_offset, p->msk_shift, p->priority);
+	}
+}
+
+/* Adds a termination callback to the interrupt */
+void intc2_add_clear_irq(int irq, int (*fn)(int))
+{
+	if (unlikely(irq < INTC2_FIRST_IRQ))
+		return;
+
+	intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn;
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq/ipr.c sh-2.6.15/arch/sh/kernel/cpu/irq/ipr.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq/ipr.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq/ipr.c	2006-01-07 22:13:59.139149503 +0200
@@ -0,0 +1,206 @@
+/*
+ * arch/sh/kernel/cpu/irq/ipr.c
+ *
+ * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
+ * Copyright (C) 2000  Kazumoto Kojima
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ *
+ * Interrupt handling for IPR-based IRQ.
+ *
+ * Supported system:
+ *	On-chip supporting modules (TMU, RTC, etc.).
+ *	On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300.
+ *	Hitachi SolutionEngine external I/O:
+ *		MS7709SE01, MS7709ASE01, and MS7750SE01
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+struct ipr_data {
+	unsigned int addr;	/* Address of Interrupt Priority Register */
+	int shift;		/* Shifts of the 16-bit data */
+	int priority;		/* The priority */
+};
+static struct ipr_data ipr_data[NR_IRQS];
+
+static void enable_ipr_irq(unsigned int irq);
+static void disable_ipr_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_ipr_irq disable_ipr_irq
+
+static void mask_and_ack_ipr(unsigned int);
+static void end_ipr_irq(unsigned int irq);
+
+static unsigned int startup_ipr_irq(unsigned int irq)
+{
+	enable_ipr_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type ipr_irq_type = {
+	.typename = "IPR-IRQ",
+	.startup = startup_ipr_irq,
+	.shutdown = shutdown_ipr_irq,
+	.enable = enable_ipr_irq,
+	.disable = disable_ipr_irq,
+	.ack = mask_and_ack_ipr,
+	.end = end_ipr_irq
+};
+
+static void disable_ipr_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+	unsigned int addr = ipr_data[irq].addr;
+	unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
+
+	/* Set the priority in IPR to 0 */
+	local_irq_save(flags);
+	val = ctrl_inw(addr);
+	val &= mask;
+	ctrl_outw(val, addr);
+	local_irq_restore(flags);
+}
+
+static void enable_ipr_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+	unsigned int addr = ipr_data[irq].addr;
+	int priority = ipr_data[irq].priority;
+	unsigned short value = (priority << ipr_data[irq].shift);
+
+	/* Set priority in IPR back to original value */
+	local_irq_save(flags);
+	val = ctrl_inw(addr);
+	val |= value;
+	ctrl_outw(val, addr);
+	local_irq_restore(flags);
+}
+
+static void mask_and_ack_ipr(unsigned int irq)
+{
+	disable_ipr_irq(irq);
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+	/* This is needed when we use edge triggered setting */
+	/* XXX: Is it really needed? */
+	if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
+		/* Clear external interrupt request */
+		int a = ctrl_inb(INTC_IRR0);
+		a &= ~(1 << (irq - IRQ0_IRQ));
+		ctrl_outb(a, INTC_IRR0);
+	}
+#endif
+}
+
+static void end_ipr_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_ipr_irq(irq);
+}
+
+void make_ipr_irq(unsigned int irq, unsigned int addr, int pos,
+		  int priority, int maskpos)
+{
+	disable_irq_nosync(irq);
+	ipr_data[irq].addr = addr;
+	ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
+	ipr_data[irq].priority = priority;
+
+	irq_desc[irq].handler = &ipr_irq_type;
+	disable_ipr_irq(irq);
+}
+
+void __init init_IRQ(void)
+{
+#ifndef CONFIG_CPU_SUBTYPE_SH7780
+	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY, 0);
+	make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY, 0);
+#if defined(CONFIG_SH_RTC)
+	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY, 0);
+#endif
+
+#ifdef SCI_ERI_IRQ
+	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
+	make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
+	make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
+#endif
+
+#ifdef SCIF1_ERI_IRQ
+	make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
+	make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
+	make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
+	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
+#endif
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY, 0);
+	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0);
+	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0);
+	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY, 0);
+#endif
+
+#ifdef SCIF_ERI_IRQ
+	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
+	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
+	make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
+	make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
+#endif
+
+#ifdef IRDA_ERI_IRQ
+	make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
+	make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
+	make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
+	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
+#endif
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+	/*
+	 * Initialize the Interrupt Controller (INTC)
+	 * registers to their power on values
+	 */
+
+	/*
+	 * Enable external irq (INTC IRQ mode).
+	 * You should set corresponding bits of PFC to "00"
+	 * to enable these interrupts.
+	 */
+	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY, 0);
+	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY, 0);
+	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY, 0);
+	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY, 0);
+	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY, 0);
+	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY, 0);
+#endif
+#endif
+
+#ifdef CONFIG_CPU_HAS_PINT_IRQ
+	init_IRQ_pint();
+#endif
+
+#ifdef CONFIG_CPU_HAS_INTC2_IRQ
+	init_IRQ_intc2();
+#endif
+	/* Perform the machine specific initialisation */
+	if (sh_mv.mv_init_irq != NULL)
+		sh_mv.mv_init_irq();
+}
+
+#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
+int ipr_irq_demux(int irq)
+{
+	return irq;
+}
+#endif
+
+EXPORT_SYMBOL(make_ipr_irq);
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq/pint.c sh-2.6.15/arch/sh/kernel/cpu/irq/pint.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq/pint.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq/pint.c	2006-01-07 22:13:59.144149110 +0200
@@ -0,0 +1,169 @@
+/*
+ * arch/sh/kernel/cpu/irq/pint.c - Interrupt handling for PINT-based IRQs.
+ *
+ * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
+ * Copyright (C) 2000  Kazumoto Kojima
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+static unsigned char pint_map[256];
+static unsigned long portcr_mask;
+
+static void enable_pint_irq(unsigned int irq);
+static void disable_pint_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_pint_irq disable_pint_irq
+
+static void mask_and_ack_pint(unsigned int);
+static void end_pint_irq(unsigned int irq);
+
+static unsigned int startup_pint_irq(unsigned int irq)
+{
+	enable_pint_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type pint_irq_type = {
+	.typename = "PINT-IRQ",
+	.startup = startup_pint_irq,
+	.shutdown = shutdown_pint_irq,
+	.enable = enable_pint_irq,
+	.disable = disable_pint_irq,
+	.ack = mask_and_ack_pint,
+	.end = end_pint_irq
+};
+
+static void disable_pint_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+
+	local_irq_save(flags);
+	val = ctrl_inw(INTC_INTER);
+	val &= ~(1 << (irq - PINT_IRQ_BASE));
+	ctrl_outw(val, INTC_INTER);	/* disable PINTn */
+	portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
+	local_irq_restore(flags);
+}
+
+static void enable_pint_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+
+	local_irq_save(flags);
+	val = ctrl_inw(INTC_INTER);
+	val |= 1 << (irq - PINT_IRQ_BASE);
+	ctrl_outw(val, INTC_INTER);	/* enable PINTn */
+	portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
+	local_irq_restore(flags);
+}
+
+static void mask_and_ack_pint(unsigned int irq)
+{
+	disable_pint_irq(irq);
+}
+
+static void end_pint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pint_irq(irq);
+}
+
+void make_pint_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &pint_irq_type;
+	disable_pint_irq(irq);
+}
+
+void __init init_IRQ_pint(void)
+{
+	int i;
+
+	make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
+	make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
+
+	enable_irq(PINT0_IRQ);
+	enable_irq(PINT8_IRQ);
+
+	for(i = 0; i < 16; i++)
+		make_pint_irq(PINT_IRQ_BASE + i);
+
+	for(i = 0; i < 256; i++) {
+		if (i & 1)
+			pint_map[i] = 0;
+		else if (i & 2)
+			pint_map[i] = 1;
+		else if (i & 4)
+			pint_map[i] = 2;
+		else if (i & 8)
+			pint_map[i] = 3;
+		else if (i & 0x10)
+			pint_map[i] = 4;
+		else if (i & 0x20)
+			pint_map[i] = 5;
+		else if (i & 0x40)
+			pint_map[i] = 6;
+		else if (i & 0x80)
+			pint_map[i] = 7;
+	}
+}
+
+int ipr_irq_demux(int irq)
+{
+	unsigned long creg, dreg, d, sav;
+
+	if (irq == PINT0_IRQ) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+		creg = PORT_PACR;
+		dreg = PORT_PADR;
+#else
+		creg = PORT_PCCR;
+		dreg = PORT_PCDR;
+#endif
+		sav = ctrl_inw(creg);
+		ctrl_outw(sav | portcr_mask, creg);
+		d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) &
+			ctrl_inw(INTC_INTER) & 0xff;
+		ctrl_outw(sav, creg);
+
+		if (d == 0)
+			return irq;
+
+		return PINT_IRQ_BASE + pint_map[d];
+	} else if (irq == PINT8_IRQ) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+		creg = PORT_PBCR;
+		dreg = PORT_PBDR;
+#else
+		creg = PORT_PFCR;
+		dreg = PORT_PFDR;
+#endif
+		sav = ctrl_inw(creg);
+		ctrl_outw(sav | (portcr_mask >> 16), creg);
+		d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) &
+			(ctrl_inw(INTC_INTER) >> 8) & 0xff;
+		ctrl_outw(sav, creg);
+
+		if (d == 0)
+			return irq;
+
+		return PINT_IRQ_BASE + 8 + pint_map[d];
+	}
+
+	return irq;
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq_imask.c sh-2.6.15/arch/sh/kernel/cpu/irq_imask.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq_imask.c	2005-11-12 20:17:23.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq_imask.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,116 +0,0 @@
-/* $Id: irq_imask.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $
- *
- * linux/arch/sh/kernel/irq_imask.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
- *
- * Simple interrupt handling using IMASK of SR register.
- *
- */
-
-/* NOTE: Will not work on level 15 */
-
-
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-
-#include <linux/spinlock.h>
-#include <linux/cache.h>
-#include <linux/irq.h>
-
-/* Bitmap of IRQ masked */
-static unsigned long imask_mask = 0x7fff;
-static int interrupt_priority = 0;
-
-static void enable_imask_irq(unsigned int irq);
-static void disable_imask_irq(unsigned int irq);
-static void shutdown_imask_irq(unsigned int irq);
-static void mask_and_ack_imask(unsigned int);
-static void end_imask_irq(unsigned int irq);
-
-#define IMASK_PRIORITY	15
-
-static unsigned int startup_imask_irq(unsigned int irq)
-{ 
-	/* Nothing to do */
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type imask_irq_type = {
-	.typename = "SR.IMASK",
-	.startup = startup_imask_irq,
-	.shutdown = shutdown_imask_irq,
-	.enable = enable_imask_irq,
-	.disable = disable_imask_irq,
-	.ack = mask_and_ack_imask,
-	.end = end_imask_irq
-};
-
-void static inline set_interrupt_registers(int ip)
-{
-	unsigned long __dummy;
-
-	asm volatile("ldc	%2, r6_bank\n\t"
-		     "stc	sr, %0\n\t"
-		     "and	#0xf0, %0\n\t"
-		     "shlr2	%0\n\t"
-		     "cmp/eq	#0x3c, %0\n\t"
-		     "bt/s	1f	! CLI-ed\n\t"
-		     " stc	sr, %0\n\t"
-		     "and	%1, %0\n\t"
-		     "or	%2, %0\n\t"
-		     "ldc	%0, sr\n"
-		     "1:"
-		     : "=&z" (__dummy)
-		     : "r" (~0xf0), "r" (ip << 4)
-		     : "t");
-}
-
-static void disable_imask_irq(unsigned int irq)
-{
-	clear_bit(irq, &imask_mask);
-	if (interrupt_priority < IMASK_PRIORITY - irq)
-		interrupt_priority = IMASK_PRIORITY - irq;
-
-	set_interrupt_registers(interrupt_priority);
-}
-
-static void enable_imask_irq(unsigned int irq)
-{
-	set_bit(irq, &imask_mask);
-	interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
-
-	set_interrupt_registers(interrupt_priority);
-}
-
-static void mask_and_ack_imask(unsigned int irq)
-{
-	disable_imask_irq(irq);
-}
-
-static void end_imask_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_imask_irq(irq);
-}
-
-static void shutdown_imask_irq(unsigned int irq)
-{
-	/* Nothing to do */
-}
-
-void make_imask_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	irq_desc[irq].handler = &imask_irq_type;
-	enable_irq(irq);
-}
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/irq_ipr.c sh-2.6.15/arch/sh/kernel/cpu/irq_ipr.c
--- linux-2.6.15/arch/sh/kernel/cpu/irq_ipr.c	2005-11-12 20:17:23.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/irq_ipr.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,339 +0,0 @@
-/* $Id: irq_ipr.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $
- *
- * linux/arch/sh/kernel/irq_ipr.c
- *
- * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
- * Copyright (C) 2000  Kazumoto Kojima
- * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
- *
- * Interrupt handling for IPR-based IRQ.
- *
- * Supported system:
- *	On-chip supporting modules (TMU, RTC, etc.).
- *	On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300.
- *	Hitachi SolutionEngine external I/O:
- *		MS7709SE01, MS7709ASE01, and MS7750SE01
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-
-struct ipr_data {
-	unsigned int addr;	/* Address of Interrupt Priority Register */
-	int shift;		/* Shifts of the 16-bit data */
-	int priority;		/* The priority */
-};
-static struct ipr_data ipr_data[NR_IRQS];
-
-static void enable_ipr_irq(unsigned int irq);
-static void disable_ipr_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_ipr_irq disable_ipr_irq
-
-static void mask_and_ack_ipr(unsigned int);
-static void end_ipr_irq(unsigned int irq);
-
-static unsigned int startup_ipr_irq(unsigned int irq)
-{
-	enable_ipr_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type ipr_irq_type = {
-	.typename = "IPR-IRQ",
-	.startup = startup_ipr_irq,
-	.shutdown = shutdown_ipr_irq,
-	.enable = enable_ipr_irq,
-	.disable = disable_ipr_irq,
-	.ack = mask_and_ack_ipr,
-	.end = end_ipr_irq
-};
-
-static void disable_ipr_irq(unsigned int irq)
-{
-	unsigned long val, flags;
-	unsigned int addr = ipr_data[irq].addr;
-	unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
-
-	/* Set the priority in IPR to 0 */
-	local_irq_save(flags);
-	val = ctrl_inw(addr);
-	val &= mask;
-	ctrl_outw(val, addr);
-	local_irq_restore(flags);
-}
-
-static void enable_ipr_irq(unsigned int irq)
-{
-	unsigned long val, flags;
-	unsigned int addr = ipr_data[irq].addr;
-	int priority = ipr_data[irq].priority;
-	unsigned short value = (priority << ipr_data[irq].shift);
-
-	/* Set priority in IPR back to original value */
-	local_irq_save(flags);
-	val = ctrl_inw(addr);
-	val |= value;
-	ctrl_outw(val, addr);
-	local_irq_restore(flags);
-}
-
-static void mask_and_ack_ipr(unsigned int irq)
-{
-	disable_ipr_irq(irq);
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
-	/* This is needed when we use edge triggered setting */
-	/* XXX: Is it really needed? */
-	if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
-		/* Clear external interrupt request */
-		int a = ctrl_inb(INTC_IRR0);
-		a &= ~(1 << (irq - IRQ0_IRQ));
-		ctrl_outb(a, INTC_IRR0);
-	}
-#endif
-}
-
-static void end_ipr_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_ipr_irq(irq);
-}
-
-void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
-{
-	disable_irq_nosync(irq);
-	ipr_data[irq].addr = addr;
-	ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
-	ipr_data[irq].priority = priority;
-
-	irq_desc[irq].handler = &ipr_irq_type;
-	disable_ipr_irq(irq);
-}
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-static unsigned char pint_map[256];
-static unsigned long portcr_mask = 0;
-
-static void enable_pint_irq(unsigned int irq);
-static void disable_pint_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_pint_irq disable_pint_irq
-
-static void mask_and_ack_pint(unsigned int);
-static void end_pint_irq(unsigned int irq);
-
-static unsigned int startup_pint_irq(unsigned int irq)
-{
-	enable_pint_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type pint_irq_type = {
-	.typename = "PINT-IRQ",
-	.startup = startup_pint_irq,
-	.shutdown = shutdown_pint_irq,
-	.enable = enable_pint_irq,
-	.disable = disable_pint_irq,
-	.ack = mask_and_ack_pint,
-	.end = end_pint_irq
-};
-
-static void disable_pint_irq(unsigned int irq)
-{
-	unsigned long val, flags;
-
-	local_irq_save(flags);
-	val = ctrl_inw(INTC_INTER);
-	val &= ~(1 << (irq - PINT_IRQ_BASE));
-	ctrl_outw(val, INTC_INTER);	/* disable PINTn */
-	portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
-	local_irq_restore(flags);
-}
-
-static void enable_pint_irq(unsigned int irq)
-{
-	unsigned long val, flags;
-
-	local_irq_save(flags);
-	val = ctrl_inw(INTC_INTER);
-	val |= 1 << (irq - PINT_IRQ_BASE);
-	ctrl_outw(val, INTC_INTER);	/* enable PINTn */
-	portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
-	local_irq_restore(flags);
-}
-
-static void mask_and_ack_pint(unsigned int irq)
-{
-	disable_pint_irq(irq);
-}
-
-static void end_pint_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pint_irq(irq);
-}
-
-void make_pint_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	irq_desc[irq].handler = &pint_irq_type;
-	disable_pint_irq(irq);
-}
-#endif
-
-void __init init_IRQ(void)
-{
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-	int i;
-#endif
-
-	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
-	make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
-#if defined(CONFIG_SH_RTC)
-	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
-#endif
-
-#ifdef SCI_ERI_IRQ
-	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-	make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-	make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-#endif
-
-#ifdef SCIF1_ERI_IRQ
-	make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-#endif
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-#endif
-
-#ifdef SCIF_ERI_IRQ
-	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-#endif
-
-#ifdef IRDA_ERI_IRQ
-	make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-#endif
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
-	/*
-	 * Initialize the Interrupt Controller (INTC)
-	 * registers to their power on values
-	 */
-
-	/*
-	 * Enable external irq (INTC IRQ mode).
-	 * You should set corresponding bits of PFC to "00"
-	 * to enable these interrupts.
-	 */
-	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
-	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
-	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
-	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
-	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
-	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
-	make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
-	make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
-	enable_ipr_irq(PINT0_IRQ);
-	enable_ipr_irq(PINT8_IRQ);
-
-	for(i = 0; i < 16; i++)
-		make_pint_irq(PINT_IRQ_BASE + i);
-	for(i = 0; i < 256; i++)
-	{
-		if(i & 1) pint_map[i] = 0;
-		else if(i & 2) pint_map[i] = 1;
-		else if(i & 4) pint_map[i] = 2;
-		else if(i & 8) pint_map[i] = 3;
-		else if(i & 0x10) pint_map[i] = 4;
-		else if(i & 0x20) pint_map[i] = 5;
-		else if(i & 0x40) pint_map[i] = 6;
-		else if(i & 0x80) pint_map[i] = 7;
-	}
-#endif /* !CONFIG_CPU_SUBTYPE_SH7300 */
-#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709  || CONFIG_CPU_SUBTYPE_SH7300*/
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-	init_IRQ_intc2();
-#endif
-
-	/* Perform the machine specific initialisation */
-	if (sh_mv.mv_init_irq != NULL) {
-		sh_mv.mv_init_irq();
-	}
-}
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
-int ipr_irq_demux(int irq)
-{
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
-	unsigned long creg, dreg, d, sav;
-
-	if(irq == PINT0_IRQ)
-	{
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
-		creg = PORT_PACR;
-		dreg = PORT_PADR;
-#else
-		creg = PORT_PCCR;
-		dreg = PORT_PCDR;
-#endif
-		sav = ctrl_inw(creg);
-		ctrl_outw(sav | portcr_mask, creg);
-		d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & ctrl_inw(INTC_INTER) & 0xff;
-		ctrl_outw(sav, creg);
-		if(d == 0) return irq;
-		return PINT_IRQ_BASE + pint_map[d];
-	}
-	else if(irq == PINT8_IRQ)
-	{
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
-		creg = PORT_PBCR;
-		dreg = PORT_PBDR;
-#else
-		creg = PORT_PFCR;
-		dreg = PORT_PFDR;
-#endif
-		sav = ctrl_inw(creg);
-		ctrl_outw(sav | (portcr_mask >> 16), creg);
-		d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & (ctrl_inw(INTC_INTER) >> 8) & 0xff;
-		ctrl_outw(sav, creg);
-		if(d == 0) return irq;
-		return PINT_IRQ_BASE + 8 + pint_map[d];
-	}
-#endif
-	return irq;
-}
-#endif
-
-EXPORT_SYMBOL(make_ipr_irq);
-

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/irq_intc2.c sh-2.6.15/arch/sh/kernel/cpu/sh4/irq_intc2.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/irq_intc2.c	2005-11-12 20:17:23.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/irq_intc2.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,222 +0,0 @@
-/*
- * linux/arch/sh/kernel/irq_intc2.c
- *
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.                            
- *
- * Interrupt handling for INTC2-based IRQ.
- *
- * These are the "new Hitachi style" interrupts, as present on the 
- * Hitachi 7751 and the STM ST40 STB1.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-
-
-struct intc2_data {
-	unsigned char msk_offset;
-	unsigned char msk_shift;
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-	int (*clear_irq) (int);
-#endif
-};
-
-
-static struct intc2_data intc2_data[NR_INTC2_IRQS];
-
-static void enable_intc2_irq(unsigned int irq);
-static void disable_intc2_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_intc2_irq disable_intc2_irq
-
-static void mask_and_ack_intc2(unsigned int);
-static void end_intc2_irq(unsigned int irq);
-
-static unsigned int startup_intc2_irq(unsigned int irq)
-{ 
-	enable_intc2_irq(irq);
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type intc2_irq_type = {
-	.typename = "INTC2-IRQ",
-	.startup = startup_intc2_irq,
-	.shutdown = shutdown_intc2_irq,
-	.enable = enable_intc2_irq,
-	.disable = disable_intc2_irq,
-	.ack = mask_and_ack_intc2,
-	.end = end_intc2_irq
-};
-
-static void disable_intc2_irq(unsigned int irq)
-{
-	int irq_offset = irq - INTC2_FIRST_IRQ;
-	int msk_shift, msk_offset;
-
-	// Sanity check
-	if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
-		return;
-
-	msk_shift = intc2_data[irq_offset].msk_shift;
-	msk_offset = intc2_data[irq_offset].msk_offset;
-
-	ctrl_outl(1<<msk_shift,
-		  INTC2_BASE+INTC2_INTMSK_OFFSET+msk_offset);
-}
-
-static void enable_intc2_irq(unsigned int irq)
-{
-	int irq_offset = irq - INTC2_FIRST_IRQ;
-	int msk_shift, msk_offset;
-
-	/* Sanity check */
-	if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
-		return;
-
-	msk_shift = intc2_data[irq_offset].msk_shift;
-	msk_offset = intc2_data[irq_offset].msk_offset;
-
-	ctrl_outl(1<<msk_shift,
-		  INTC2_BASE+INTC2_INTMSKCLR_OFFSET+msk_offset);
-}
-
-static void mask_and_ack_intc2(unsigned int irq)
-{
-	disable_intc2_irq(irq);
-}
-
-static void end_intc2_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_intc2_irq(irq);
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-	if (intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)
-		intc2_data[irq - INTC2_FIRST_IRQ].clear_irq (irq);
-#endif
-}
-
-/*
- * Setup an INTC2 style interrupt.
- * NOTE: Unlike IPR interrupts, parameters are not shifted by this code,
- * allowing the use of the numbers straight out of the datasheet.
- * For example:
- *    PIO1 which is INTPRI00[19,16] and INTMSK00[13]
- * would be:               ^     ^             ^  ^
- *                         |     |             |  |
- *    make_intc2_irq(84,   0,   16,            0, 13);
- */
-void make_intc2_irq(unsigned int irq,
-		    unsigned int ipr_offset, unsigned int ipr_shift,
-		    unsigned int msk_offset, unsigned int msk_shift,
-		    unsigned int priority)
-{
-	int irq_offset = irq - INTC2_FIRST_IRQ;
-	unsigned int flags;
-	unsigned long ipr;
-
-	if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
-		return;
-
-	disable_irq_nosync(irq);
-
-	/* Fill the data we need */
-	intc2_data[irq_offset].msk_offset = msk_offset;
-	intc2_data[irq_offset].msk_shift  = msk_shift;
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-	intc2_data[irq_offset].clear_irq = NULL;
-#endif
-		
-	/* Set the priority level */
-	local_irq_save(flags);
-
-	ipr=ctrl_inl(INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset);
-	ipr&=~(0xf<<ipr_shift);
-	ipr|=(priority)<<ipr_shift;
-	ctrl_outl(ipr, INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset);
-
-	local_irq_restore(flags);
-
-	irq_desc[irq].handler=&intc2_irq_type;
-
-	disable_intc2_irq(irq);
-}
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-
-struct intc2_init {
-	unsigned short irq;
-	unsigned char ipr_offset, ipr_shift;
-	unsigned char msk_offset, msk_shift;
-};
-
-static struct intc2_init intc2_init_data[]  __initdata = {
-	{64,  0,  0, 0,  0},	/* PCI serr */
-	{65,  0,  4, 0,  1},	/* PCI err */
-	{66,  0,  4, 0,  2},	/* PCI ad */
-	{67,  0,  4, 0,  3},	/* PCI pwd down */
-	{72,  0,  8, 0,  5},	/* DMAC INT0 */
-	{73,  0,  8, 0,  6},	/* DMAC INT1 */
-	{74,  0,  8, 0,  7},	/* DMAC INT2 */
-	{75,  0,  8, 0,  8},	/* DMAC INT3 */
-	{76,  0,  8, 0,  9},	/* DMAC INT4 */
-	{78,  0,  8, 0, 11},	/* DMAC ERR */
-	{80,  0, 12, 0, 12},	/* PIO0 */
-	{84,  0, 16, 0, 13},	/* PIO1 */
-	{88,  0, 20, 0, 14},	/* PIO2 */
-	{112, 4,  0, 4,  0},	/* Mailbox */
-#ifdef CONFIG_CPU_SUBTYPE_ST40GX1
-	{116, 4,  4, 4,  4},	/* SSC0 */
-	{120, 4,  8, 4,  8},	/* IR Blaster */
-	{124, 4, 12, 4, 12},	/* USB host */
-	{128, 4, 16, 4, 16},	/* Video processor BLITTER */
-	{132, 4, 20, 4, 20},	/* UART0 */
-	{134, 4, 20, 4, 22},	/* UART2 */
-	{136, 4, 24, 4, 24},	/* IO_PIO0 */
-	{140, 4, 28, 4, 28},	/* EMPI */
-	{144, 8,  0, 8,  0},	/* MAFE */
-	{148, 8,  4, 8,  4},	/* PWM */
-	{152, 8,  8, 8,  8},	/* SSC1 */
-	{156, 8, 12, 8, 12},	/* IO_PIO1 */
-	{160, 8, 16, 8, 16},	/* USB target */
-	{164, 8, 20, 8, 20},	/* UART1 */
-	{168, 8, 24, 8, 24},	/* Teletext */
-	{172, 8, 28, 8, 28},	/* VideoSync VTG */
-	{173, 8, 28, 8, 29},	/* VideoSync DVP0 */
-	{174, 8, 28, 8, 30},	/* VideoSync DVP1 */
-#endif
-};
-
-void __init init_IRQ_intc2(void)
-{
-	struct intc2_init *p;
-
-	printk(KERN_ALERT "init_IRQ_intc2\n");
-
-	for (p = intc2_init_data;
-	     p<intc2_init_data+ARRAY_SIZE(intc2_init_data);
-	     p++) {
-		make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift,
-			       p-> msk_offset, p->msk_shift, 13);
-	}
-}
-
-/* Adds a termination callback to the interrupt */
-void intc2_add_clear_irq(int irq, int (*fn)(int))
-{
-	if (irq < INTC2_FIRST_IRQ)
-		return;
-
-	intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn;
-}
-
-#endif /* CONFIG_CPU_SUBTYPE_ST40 */

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/irq.c sh-2.6.15/arch/sh/kernel/irq.c
--- linux-2.6.15/arch/sh/kernel/irq.c	2005-06-20 22:45:19.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/irq.c	2006-01-07 22:13:59.229142425 +0200
@@ -8,38 +8,13 @@
  * SuperH version:  Copyright (C) 1999  Niibe Yutaka
  */
 
-/*
- * IRQs are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
+#include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
+#include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
-#include <linux/kallsyms.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/delay.h>
 #include <asm/irq.h>
-#include <linux/irq.h>
-
+#include <asm/processor.h>
+#include <asm/cpu/mmu_context.h>
 
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
@@ -66,7 +41,7 @@
 		seq_putc(p, '\n');
 	}
 
-	if (i < ACTUAL_NR_IRQS) {
+	if (i < NR_IRQS) {
 		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
@@ -86,19 +61,32 @@
 }
 #endif
 
+
 asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 		      unsigned long r6, unsigned long r7,
 		      struct pt_regs regs)
-{	
-	int irq;
+{
+	int irq = r4;
 
 	irq_enter();
-	asm volatile("stc	r2_bank, %0\n\t"
-		     "shlr2	%0\n\t"
-		     "shlr2	%0\n\t"
-		     "shlr	%0\n\t"
-		     "add	#-16, %0\n\t"
-		     :"=z" (irq));
+
+#ifdef CONFIG_CPU_HAS_INTEVT
+	__asm__ __volatile__ (
+#ifdef CONFIG_CPU_HAS_SR_RB
+		"stc	r2_bank, %0\n\t"
+#else
+		"mov.l	@%1, %0\n\t"
+#endif
+		"shlr2	%0\n\t"
+		"shlr2	%0\n\t"
+		"shlr	%0\n\t"
+		"add	#-16, %0\n\t"
+		: "=z" (irq), "=r" (r4)
+		: "1" (INTEVT)
+		: "memory"
+	);
+#endif
+
 	irq = irq_demux(irq);
 	__do_IRQ(irq, &regs);
 	irq_exit();

diff -urN -X exclude linux-2.6.15/include/asm-sh/irq-sh73180.h sh-2.6.15/include/asm-sh/irq-sh73180.h
--- linux-2.6.15/include/asm-sh/irq-sh73180.h	2004-12-26 05:37:56.000000000 +0200
+++ sh-2.6.15/include/asm-sh/irq-sh73180.h	2006-01-04 00:15:30.000000000 +0200
@@ -12,14 +12,14 @@
 #undef INTC_IPRC
 #undef INTC_IPRD
 
-#undef DMTE0_IRQ
-#undef DMTE1_IRQ
-#undef DMTE2_IRQ
-#undef DMTE3_IRQ
-#undef DMTE4_IRQ
-#undef DMTE5_IRQ
-#undef DMTE6_IRQ
-#undef DMTE7_IRQ
+#undef DMTE0_IRQ	
+#undef DMTE1_IRQ	
+#undef DMTE2_IRQ	
+#undef DMTE3_IRQ	
+#undef DMTE4_IRQ	
+#undef DMTE5_IRQ	
+#undef DMTE6_IRQ	
+#undef DMTE7_IRQ	
 #undef DMAE_IRQ
 #undef DMA_IPR_ADDR
 #undef DMA_IPR_POS
diff -urN -X exclude linux-2.6.15/include/asm-sh/irq-sh7780.h sh-2.6.15/include/asm-sh/irq-sh7780.h
--- linux-2.6.15/include/asm-sh/irq-sh7780.h	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/include/asm-sh/irq-sh7780.h	2006-01-07 22:13:59.261139909 +0200
@@ -0,0 +1,349 @@
+#ifndef __ASM_SH_IRQ_SH7780_H
+#define __ASM_SH_IRQ_SH7780_H
+
+/*
+ * linux/include/asm-sh/irq-sh7780.h
+ *
+ * Copyright (C) 2004 Takashi SHUDO <shudo@hitachi-ul.co.jp>
+ */
+
+#ifdef CONFIG_IDE
+# ifndef IRQ_CFCARD
+#  define IRQ_CFCARD	14
+# endif
+# ifndef IRQ_PCMCIA
+#  define IRQ_PCMCIA	15
+# endif
+#endif
+
+#define INTC_BASE	0xffd00000
+#define INTC_ICR0	(INTC_BASE+0x0)
+#define INTC_ICR1	(INTC_BASE+0x1c)
+#define INTC_INTPRI	(INTC_BASE+0x10)
+#define INTC_INTREQ	(INTC_BASE+0x24)
+#define INTC_INTMSK0	(INTC_BASE+0x44)
+#define INTC_INTMSK1	(INTC_BASE+0x48)
+#define INTC_INTMSK2	(INTC_BASE+0x40080)
+#define INTC_INTMSKCLR0	(INTC_BASE+0x64)
+#define INTC_INTMSKCLR1	(INTC_BASE+0x68)
+#define INTC_INTMSKCLR2	(INTC_BASE+0x40084)
+#define INTC_NMIFCR	(INTC_BASE+0xc0)
+#define INTC_USERIMASK	(INTC_BASE+0x30000)
+
+#define	INTC_INT2PRI0	(INTC_BASE+0x40000)
+#define	INTC_INT2PRI1	(INTC_BASE+0x40004)
+#define	INTC_INT2PRI2	(INTC_BASE+0x40008)
+#define	INTC_INT2PRI3	(INTC_BASE+0x4000c)
+#define	INTC_INT2PRI4	(INTC_BASE+0x40010)
+#define	INTC_INT2PRI5	(INTC_BASE+0x40014)
+#define	INTC_INT2PRI6	(INTC_BASE+0x40018)
+#define	INTC_INT2PRI7	(INTC_BASE+0x4001c)
+#define	INTC_INT2A0	(INTC_BASE+0x40030)
+#define	INTC_INT2A1	(INTC_BASE+0x40034)
+#define	INTC_INT2MSKR	(INTC_BASE+0x40038)
+#define	INTC_INT2MSKCR	(INTC_BASE+0x4003c)
+#define	INTC_INT2B0	(INTC_BASE+0x40040)
+#define	INTC_INT2B1	(INTC_BASE+0x40044)
+#define	INTC_INT2B2	(INTC_BASE+0x40048)
+#define	INTC_INT2B3	(INTC_BASE+0x4004c)
+#define	INTC_INT2B4	(INTC_BASE+0x40050)
+#define	INTC_INT2B5	(INTC_BASE+0x40054)
+#define	INTC_INT2B6	(INTC_BASE+0x40058)
+#define	INTC_INT2B7	(INTC_BASE+0x4005c)
+#define	INTC_INT2GPIC	(INTC_BASE+0x40090)
+/*
+  NOTE:
+  *_IRQ = (INTEVT2 - 0x200)/0x20
+*/
+/* IRQ 0-7 line external int*/
+#define IRQ0_IRQ	2
+#define IRQ0_IPR_ADDR	INTC_INTPRI
+#define IRQ0_IPR_POS	7
+#define IRQ0_PRIORITY	2
+
+#define IRQ1_IRQ	4
+#define IRQ1_IPR_ADDR	INTC_INTPRI
+#define IRQ1_IPR_POS	6
+#define IRQ1_PRIORITY	2
+
+#define IRQ2_IRQ	6
+#define IRQ2_IPR_ADDR	INTC_INTPRI
+#define IRQ2_IPR_POS	5
+#define IRQ2_PRIORITY	2
+
+#define IRQ3_IRQ	8
+#define IRQ3_IPR_ADDR	INTC_INTPRI
+#define IRQ3_IPR_POS	4
+#define IRQ3_PRIORITY	2
+
+#define IRQ4_IRQ	10
+#define IRQ4_IPR_ADDR	INTC_INTPRI
+#define IRQ4_IPR_POS	3
+#define IRQ4_PRIORITY	2
+
+#define IRQ5_IRQ	12
+#define IRQ5_IPR_ADDR	INTC_INTPRI
+#define IRQ5_IPR_POS	2
+#define IRQ5_PRIORITY	2
+
+#define IRQ6_IRQ	14
+#define IRQ6_IPR_ADDR	INTC_INTPRI
+#define IRQ6_IPR_POS	1
+#define IRQ6_PRIORITY	2
+
+#define IRQ7_IRQ	0
+#define IRQ7_IPR_ADDR	INTC_INTPRI
+#define IRQ7_IPR_POS	0
+#define IRQ7_PRIORITY	2
+
+/* TMU */
+/* ch0 */
+#define TMU_IRQ		28
+#define	TMU_IPR_ADDR	INTC_INT2PRI0
+#define	TMU_IPR_POS	3
+#define TMU_PRIORITY	2
+
+#define TIMER_IRQ	28
+#define	TIMER_IPR_ADDR	INTC_INT2PRI0
+#define	TIMER_IPR_POS	3
+#define TIMER_PRIORITY	2
+
+/* ch 1*/
+#define TMU_CH1_IRQ		29
+#define	TMU_CH1_IPR_ADDR	INTC_INT2PRI0
+#define	TMU_CH1_IPR_POS		2
+#define TMU_CH1_PRIORITY	2
+
+#define TIMER1_IRQ	29
+#define	TIMER1_IPR_ADDR	INTC_INT2PRI0
+#define	TIMER1_IPR_POS	2
+#define TIMER1_PRIORITY	2
+
+/* ch 2*/
+#define TMU_CH2_IRQ		30
+#define	TMU_CH2_IPR_ADDR	INTC_INT2PRI0
+#define	TMU_CH2_IPR_POS		1
+#define TMU_CH2_PRIORITY	2
+/* ch 2 Input capture */
+#define TMU_CH2IC_IRQ		31
+#define	TMU_CH2IC_IPR_ADDR	INTC_INT2PRI0
+#define	TMU_CH2IC_IPR_POS	0
+#define TMU_CH2IC_PRIORITY	2
+/* ch 3 */
+#define TMU_CH3_IRQ		96
+#define	TMU_CH3_IPR_ADDR	INTC_INT2PRI1
+#define	TMU_CH3_IPR_POS		3
+#define TMU_CH3_PRIORITY	2
+/* ch 4 */
+#define TMU_CH4_IRQ		97
+#define	TMU_CH4_IPR_ADDR	INTC_INT2PRI1
+#define	TMU_CH4_IPR_POS		2
+#define TMU_CH4_PRIORITY	2
+/* ch 5*/
+#define TMU_CH5_IRQ		98
+#define	TMU_CH5_IPR_ADDR	INTC_INT2PRI1
+#define	TMU_CH5_IPR_POS		1
+#define TMU_CH5_PRIORITY	2
+
+#define	RTC_IRQ		22
+#define	RTC_IPR_ADDR	INTC_INT2PRI1
+#define	RTC_IPR_POS	0
+#define	RTC_PRIORITY	TIMER_PRIORITY
+
+/* SCIF0 */
+#define SCIF0_ERI_IRQ	40
+#define SCIF0_RXI_IRQ	41
+#define SCIF0_BRI_IRQ	42
+#define SCIF0_TXI_IRQ	43
+#define	SCIF0_IPR_ADDR	INTC_INT2PRI2
+#define	SCIF0_IPR_POS	3
+#define SCIF0_PRIORITY	3
+
+/* SCIF1 */
+#define SCIF1_ERI_IRQ	76
+#define SCIF1_RXI_IRQ	77
+#define SCIF1_BRI_IRQ	78
+#define SCIF1_TXI_IRQ	79
+#define	SCIF1_IPR_ADDR	INTC_INT2PRI2
+#define	SCIF1_IPR_POS	2
+#define SCIF1_PRIORITY	3
+
+#define	WDT_IRQ		27
+#define	WDT_IPR_ADDR	INTC_INT2PRI2
+#define	WDT_IPR_POS	1
+#define	WDT_PRIORITY	2
+
+/* DMAC(0) */
+#define	DMINT0_IRQ	34
+#define	DMINT1_IRQ	35
+#define	DMINT2_IRQ	36
+#define	DMINT3_IRQ	37
+#define	DMINT4_IRQ	44
+#define	DMINT5_IRQ	45
+#define	DMINT6_IRQ	46
+#define	DMINT7_IRQ	47
+#define	DMAE_IRQ	38
+#define	DMA0_IPR_ADDR	INTC_INT2PRI3
+#define	DMA0_IPR_POS	2
+#define	DMA0_PRIORITY	7
+
+/* DMAC(1) */
+#define	DMINT8_IRQ	92
+#define	DMINT9_IRQ	93
+#define	DMINT10_IRQ	94
+#define	DMINT11_IRQ	95
+#define	DMA1_IPR_ADDR	INTC_INT2PRI3
+#define	DMA1_IPR_POS	1
+#define	DMA1_PRIORITY	7
+
+#define	DMTE0_IRQ	DMINT0_IRQ
+#define	DMTE4_IRQ	DMINT4_IRQ
+#define	DMA_IPR_ADDR	DMA0_IPR_ADDR
+#define	DMA_IPR_POS	DMA0_IPR_POS
+#define	DMA_PRIORITY	DMA0_PRIORITY
+
+/* CMT */
+#define	CMT_IRQ		56
+#define	CMT_IPR_ADDR	INTC_INT2PRI4
+#define	CMT_IPR_POS	3
+#define	CMT_PRIORITY	0
+
+/* HAC */
+#define	HAC_IRQ		60
+#define	HAC_IPR_ADDR	INTC_INT2PRI4
+#define	HAC_IPR_POS	2
+#define	CMT_PRIORITY	0
+
+/* PCIC(0) */
+#define	PCIC0_IRQ	64
+#define	PCIC0_IPR_ADDR	INTC_INT2PRI4
+#define	PCIC0_IPR_POS	1
+#define	PCIC0_PRIORITY	2
+
+/* PCIC(1) */
+#define	PCIC1_IRQ	65
+#define	PCIC1_IPR_ADDR	INTC_INT2PRI4
+#define	PCIC1_IPR_POS	0
+#define	PCIC1_PRIORITY	2
+
+/* PCIC(2) */
+#define	PCIC2_IRQ	66
+#define	PCIC2_IPR_ADDR	INTC_INT2PRI5
+#define	PCIC2_IPR_POS	3
+#define	PCIC2_PRIORITY	2
+
+/* PCIC(3) */
+#define	PCIC3_IRQ	67
+#define	PCIC3_IPR_ADDR	INTC_INT2PRI5
+#define	PCIC3_IPR_POS	2
+#define	PCIC3_PRIORITY	2
+
+/* PCIC(4) */
+#define	PCIC4_IRQ	68
+#define	PCIC4_IPR_ADDR	INTC_INT2PRI5
+#define	PCIC4_IPR_POS	1
+#define	PCIC4_PRIORITY	2
+
+/* PCIC(5) */
+#define	PCICERR_IRQ	69
+#define	PCICPWD3_IRQ	70
+#define	PCICPWD2_IRQ	71
+#define	PCICPWD1_IRQ	72
+#define	PCICPWD0_IRQ	73
+#define	PCIC5_IPR_ADDR	INTC_INT2PRI5
+#define	PCIC5_IPR_POS	0
+#define	PCIC5_PRIORITY	2
+
+/* SIOF */
+#define	SIOF_IRQ	80
+#define	SIOF_IPR_ADDR	INTC_INT2PRI6
+#define	SIOF_IPR_POS	3
+#define	SIOF_PRIORITY	3
+
+/* HSPI */
+#define	HSPI_IRQ	84
+#define	HSPI_IPR_ADDR	INTC_INT2PRI6
+#define	HSPI_IPR_POS	2
+#define	HSPI_PRIORITY	3
+
+/* MMCIF */
+#define	MMCIF_FSTAT_IRQ	88
+#define	MMCIF_TRAN_IRQ	89
+#define	MMCIF_ERR_IRQ	90
+#define	MMCIF_FRDY_IRQ	91
+#define	MMCIF_IPR_ADDR	INTC_INT2PRI6
+#define	MMCIF_IPR_POS	1
+#define	HSPI_PRIORITY	3
+
+/* SSI */
+#define	SSI_IRQ		100
+#define	SSI_IPR_ADDR	INTC_INT2PRI6
+#define	SSI_IPR_POS	0
+#define	SSI_PRIORITY	3
+
+/* FLCTL */
+#define	FLCTL_FLSTE_IRQ		104
+#define	FLCTL_FLTEND_IRQ	105
+#define	FLCTL_FLTRQ0_IRQ	106
+#define	FLCTL_FLTRQ1_IRQ	107
+#define	FLCTL_IPR_ADDR		INTC_INT2PRI7
+#define	FLCTL_IPR_POS		3
+#define	FLCTL_PRIORITY		3
+
+/* GPIO */
+#define	GPIO0_IRQ	108
+#define	GPIO1_IRQ	109
+#define	GPIO2_IRQ	110
+#define	GPIO3_IRQ	111
+#define	GPIO_IPR_ADDR	INTC_INT2PRI7
+#define	GPIO_IPR_POS	2
+#define	GPIO_PRIORITY	3
+
+/* ONCHIP_NR_IRQS */
+#define NR_IRQS 150	/* 111 + 16 */
+
+/* In a generic kernel, NR_IRQS is an upper bound, and we should use
+ * ACTUAL_NR_IRQS (which uses the machine vector) to get the correct value.
+ */
+#define ACTUAL_NR_IRQS NR_IRQS
+
+extern void disable_irq(unsigned int);
+extern void disable_irq_nosync(unsigned int);
+extern void enable_irq(unsigned int);
+
+/*
+ * Simple Mask Register Support
+ */
+extern void make_maskreg_irq(unsigned int irq);
+extern unsigned short *irq_mask_register;
+
+/*
+ * Function for "on chip support modules".
+ */
+extern void make_imask_irq(unsigned int irq);
+
+#define	INTC_TMU0_MSK	0
+#define	INTC_TMU3_MSK	1
+#define	INTC_RTC_MSK	2
+#define	INTC_SCIF0_MSK	3
+#define	INTC_SCIF1_MSK	4
+#define	INTC_WDT_MSK	5
+#define	INTC_HUID_MSK	7
+#define	INTC_DMAC0_MSK	8
+#define	INTC_DMAC1_MSK	9
+#define	INTC_CMT_MSK	12
+#define	INTC_HAC_MSK	13
+#define	INTC_PCIC0_MSK	14
+#define	INTC_PCIC1_MSK	15
+#define	INTC_PCIC2_MSK	16
+#define	INTC_PCIC3_MSK	17
+#define	INTC_PCIC4_MSK	18
+#define	INTC_PCIC5_MSK	19
+#define	INTC_SIOF_MSK	20
+#define	INTC_HSPI_MSK	21
+#define	INTC_MMCIF_MSK	22
+#define	INTC_SSI_MSK	23
+#define	INTC_FLCTL_MSK	24
+#define	INTC_GPIO_MSK	25
+
+#endif /* __ASM_SH_IRQ_SH7780_H */
diff -urN -X exclude linux-2.6.15/include/asm-sh/irq.h sh-2.6.15/include/asm-sh/irq.h
--- linux-2.6.15/include/asm-sh/irq.h	2005-11-12 20:18:07.000000000 +0200
+++ sh-2.6.15/include/asm-sh/irq.h	2006-01-07 22:13:59.279138493 +0200
@@ -15,13 +15,20 @@
 #include <asm/machvec.h>
 #include <asm/ptrace.h>		/* for pt_regs */
 
-#if defined(CONFIG_SH_HP600) || \
+#if defined(CONFIG_SH_HP6XX) || \
     defined(CONFIG_SH_RTS7751R2D) || \
     defined(CONFIG_SH_HS7751RVOIP) || \
-    defined(CONFIG_SH_SH03)
+    defined(CONFIG_SH_HS7751RVOIP) || \
+    defined(CONFIG_SH_SH03) || \
+    defined(CONFIG_SH_R7780RP) || \
+    defined(CONFIG_SH_LANDISK)
 #include <asm/mach/ide.h>
 #endif
 
+#ifndef CONFIG_CPU_SUBTYPE_SH7780
+
+#define INTC_DMAC0_MSK	0
+
 #if defined(CONFIG_CPU_SH3)
 #define INTC_IPRA	0xfffffee2UL
 #define INTC_IPRB	0xfffffee4UL
@@ -235,8 +242,9 @@
 #define SCIF1_IPR_ADDR	INTC_IPRB
 #define SCIF1_IPR_POS	1
 #define SCIF1_PRIORITY	3
-#endif
-#endif
+#endif /* ST40STB1 */
+
+#endif /* 775x / SH4-202 / ST40STB1 */
 
 /* NR_IRQS is made from three components:
  *   1. ONCHIP_NR_IRQS - number of IRLS + on-chip peripherial modules
@@ -245,37 +253,35 @@
  */
 
 /* 1. ONCHIP_NR_IRQS */
-#ifdef CONFIG_SH_GENERIC
+#if defined(CONFIG_CPU_SUBTYPE_SH7604)
+# define ONCHIP_NR_IRQS 24	// Actually 21
+#elif defined(CONFIG_CPU_SUBTYPE_SH7707)
+# define ONCHIP_NR_IRQS 64
+# define PINT_NR_IRQS   16
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+# define ONCHIP_NR_IRQS 32
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7705)
+# define ONCHIP_NR_IRQS 64	// Actually 61
+# define PINT_NR_IRQS   16
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+# define ONCHIP_NR_IRQS 48	// Actually 44
+#elif defined(CONFIG_CPU_SUBTYPE_SH7751)
+# define ONCHIP_NR_IRQS 72
+#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
+# define ONCHIP_NR_IRQS 112	/* XXX */
+#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
+# define ONCHIP_NR_IRQS 72
+#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+# define ONCHIP_NR_IRQS 144
+#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
+# define ONCHIP_NR_IRQS 109
+#elif defined(CONFIG_SH_UNKNOWN)	/* Most be last */
 # define ONCHIP_NR_IRQS 144
-#else
-# if defined(CONFIG_CPU_SUBTYPE_SH7604)
-#  define ONCHIP_NR_IRQS 24	// Actually 21
-# elif defined(CONFIG_CPU_SUBTYPE_SH7707)
-#  define ONCHIP_NR_IRQS 64
-#  define PINT_NR_IRQS   16
-# elif defined(CONFIG_CPU_SUBTYPE_SH7708)
-#  define ONCHIP_NR_IRQS 32
-# elif defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-       defined(CONFIG_CPU_SUBTYPE_SH7705)
-#  define ONCHIP_NR_IRQS 64	// Actually 61
-#  define PINT_NR_IRQS   16
-# elif defined(CONFIG_CPU_SUBTYPE_SH7750)
-#  define ONCHIP_NR_IRQS 48	// Actually 44
-# elif defined(CONFIG_CPU_SUBTYPE_SH7751)
-#  define ONCHIP_NR_IRQS 72
-# elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-#  define ONCHIP_NR_IRQS 110
-# elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-#  define ONCHIP_NR_IRQS 72
-# elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-#  define ONCHIP_NR_IRQS 144
-# elif defined(CONFIG_CPU_SUBTYPE_SH7300)
-#  define ONCHIP_NR_IRQS 109
-# endif
 #endif
 
 /* 2. PINT_NR_IRQS */
-#ifdef CONFIG_SH_GENERIC
+#ifdef CONFIG_SH_UNKNOWN
 # define PINT_NR_IRQS 16
 #else
 # ifndef PINT_NR_IRQS
@@ -288,22 +294,22 @@
 #endif
 
 /* 3. OFFCHIP_NR_IRQS */
-#ifdef CONFIG_SH_GENERIC
+#if defined(CONFIG_HD64461)
+# define OFFCHIP_NR_IRQS 18
+#elif defined (CONFIG_SH_BIGSUR) /* must be before CONFIG_HD64465 */
+# define OFFCHIP_NR_IRQS 48
+#elif defined(CONFIG_HD64465)
 # define OFFCHIP_NR_IRQS 16
+#elif defined (CONFIG_SH_EC3104)
+# define OFFCHIP_NR_IRQS 16
+#elif defined (CONFIG_SH_DREAMCAST)
+# define OFFCHIP_NR_IRQS 96
+#elif defined (CONFIG_SH_TITAN)
+# define OFFCHIP_NR_IRQS 4
+#elif defined(CONFIG_SH_UNKNOWN)
+# define OFFCHIP_NR_IRQS 16	/* Must also be last */
 #else
-# if defined(CONFIG_HD64461)
-#  define OFFCHIP_NR_IRQS 18
-# elif defined (CONFIG_SH_BIGSUR) /* must be before CONFIG_HD64465 */
-#  define OFFCHIP_NR_IRQS 48
-# elif defined(CONFIG_HD64465)
-#  define OFFCHIP_NR_IRQS 16
-# elif defined (CONFIG_SH_EC3104)
-#  define OFFCHIP_NR_IRQS 16
-# elif defined (CONFIG_SH_DREAMCAST)
-#  define OFFCHIP_NR_IRQS 96
-# else
-#  define OFFCHIP_NR_IRQS 0
-# endif
+# define OFFCHIP_NR_IRQS 0
 #endif
 
 #if OFFCHIP_NR_IRQS > 0
@@ -313,16 +319,6 @@
 /* NR_IRQS. 1+2+3 */
 #define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS)
 
-/* In a generic kernel, NR_IRQS is an upper bound, and we should use
- * ACTUAL_NR_IRQS (which uses the machine vector) to get the correct value.
- */
-#ifdef CONFIG_SH_GENERIC
-# define ACTUAL_NR_IRQS (sh_mv.mv_nr_irqs)
-#else
-# define ACTUAL_NR_IRQS NR_IRQS
-#endif
-
-
 extern void disable_irq(unsigned int);
 extern void disable_irq_nosync(unsigned int);
 extern void enable_irq(unsigned int);
@@ -542,9 +538,6 @@
 
 extern int ipr_irq_demux(int irq);
 #define __irq_demux(irq) ipr_irq_demux(irq)
-
-#else
-#define __irq_demux(irq) irq
 #endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || \
@@ -557,18 +550,35 @@
 #define INTC_ICR_IRLM	(1<<7)
 #endif
 
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#else
+#include <asm/irq-sh7780.h>
+#endif
 
+/* SH with INTC2-style interrupts */
+#ifdef CONFIG_CPU_HAS_INTC2_IRQ
+#if defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+#define INTC2_BASE	0xfe080000
 #define INTC2_FIRST_IRQ 64
-#define NR_INTC2_IRQS 25
-
+#define INTC2_INTREQ_OFFSET	0x20
+#define INTC2_INTMSK_OFFSET	0x40
+#define INTC2_INTMSKCLR_OFFSET	0x60
+#define NR_INTC2_IRQS	25
+#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
 #define INTC2_BASE	0xfe080000
-#define INTC2_INTC2MODE	(INTC2_BASE+0x80)
-
-#define INTC2_INTPRI_OFFSET	0x00
+#define INTC2_FIRST_IRQ 48	/* INTEVT 0x800 */
 #define INTC2_INTREQ_OFFSET	0x20
 #define INTC2_INTMSK_OFFSET	0x40
 #define INTC2_INTMSKCLR_OFFSET	0x60
+#define NR_INTC2_IRQS	64
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define INTC2_BASE	0xffd40000
+#define INTC2_FIRST_IRQ	22
+#define INTC2_INTMSK_OFFSET	(0x38)
+#define INTC2_INTMSKCLR_OFFSET	(0x3c)
+#define NR_INTC2_IRQS	60
+#endif
+
+#define INTC2_INTPRI_OFFSET	0x00
 
 void make_intc2_irq(unsigned int irq,
 		    unsigned int ipr_offset, unsigned int ipr_shift,
@@ -577,13 +587,16 @@
 void init_IRQ_intc2(void);
 void intc2_add_clear_irq(int irq, int (*fn)(int));
 
-#endif	/* CONFIG_CPU_SUBTYPE_ST40STB1 */
+#endif
 
 static inline int generic_irq_demux(int irq)
 {
 	return irq;
 }
 
+#ifndef __irq_demux
+#define __irq_demux(irq)	(irq)
+#endif
 #define irq_canonicalize(irq)	(irq)
 #define irq_demux(irq)		__irq_demux(sh_mv.mv_irq_demux(irq))

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/8] sh: I/O routine cleanups and ioremap() overhaul.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
                   ` (3 preceding siblings ...)
  2006-01-14 22:53 ` [PATCH 4/8] sh: IRQ handler updates Paul Mundt
@ 2006-01-14 22:54 ` Paul Mundt
  2006-01-14 22:55 ` [PATCH 6/8] sh: Simplistic clock framework Paul Mundt
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:54 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This introduces a few changes in the way that the I/O routines are
defined on SH, specifically so that things like the iomap API properly
wrap through the machvec for board-specific quirks.

In addition to this, the old p3_ioremap() work is converted to a more
generic __ioremap() that will map through the PMB if it's available, or
fall back on page tables for everything else.

An alpha-like IO_CONCAT is also added so we can start to clean up the
board-specific io.h mess, which will be handled in board update patches..

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/kernel/io.c         |   41 ++++--
 arch/sh/kernel/io_generic.c |  192 +++++++++++++----------------
 arch/sh/mm/ioremap.c        |   99 ++++++++++++---
 include/asm-sh/io.h         |  287 +++++++++++++++++++++++++-------------------
 include/asm-sh/io_generic.h |   88 ++++++-------
 include/asm-sh/machvec.h    |   66 ++++------
 6 files changed, 438 insertions(+), 335 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/io.c sh-2.6.15/arch/sh/kernel/io.c
--- linux-2.6.15/arch/sh/kernel/io.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/io.c	2006-01-04 00:15:27.000000000 +0200
@@ -2,58 +2,73 @@
  * linux/arch/sh/kernel/io.c
  *
  * Copyright (C) 2000  Stuart Menefy
+ * Copyright (C) 2005  Paul Mundt
  *
  * Provide real functions which expand to whatever the header file defined.
  * Also definitions of machine independent IO functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
-
-#include <asm/io.h>
 #include <linux/module.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
 
 /*
  * Copy data from IO memory space to "real" memory space.
  * This needs to be optimized.
  */
-void  memcpy_fromio(void * to, unsigned long from, unsigned long count)
+void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count)
 {
 	char *p = to;
         while (count) {
                 count--;
-                *p = readb(from);
+                *p = readb((void __iomem *)from);
                 p++;
                 from++;
         }
 }
- 
+EXPORT_SYMBOL(memcpy_fromio);
+
 /*
  * Copy data from "real" memory space to IO memory space.
  * This needs to be optimized.
  */
-void  memcpy_toio(unsigned long to, const void * from, unsigned long count)
+void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count)
 {
 	const char *p = from;
         while (count) {
                 count--;
-                writeb(*p, to);
+                writeb(*p, (void __iomem *)to);
                 p++;
                 to++;
         }
 }
- 
+EXPORT_SYMBOL(memcpy_toio);
+
 /*
  * "memset" on IO memory space.
  * This needs to be optimized.
  */
-void  memset_io(unsigned long dst, int c, unsigned long count)
+void memset_io(volatile void __iomem *dst, int c, unsigned long count)
 {
         while (count) {
                 count--;
-                writeb(c, dst);
+                writeb(c, (void __iomem *)dst);
                 dst++;
         }
 }
-
-EXPORT_SYMBOL(memcpy_fromio);
-EXPORT_SYMBOL(memcpy_toio);
 EXPORT_SYMBOL(memset_io);
 
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return sh_mv.mv_ioport_map(port, nr);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+	sh_mv.mv_ioport_unmap(addr);
+}
+EXPORT_SYMBOL(ioport_unmap);
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/io_generic.c sh-2.6.15/arch/sh/kernel/io_generic.c
--- linux-2.6.15/arch/sh/kernel/io_generic.c	2004-08-14 20:27:37.000000000 +0300
+++ sh-2.6.15/arch/sh/kernel/io_generic.c	2006-01-04 00:46:18.000000000 +0200
@@ -3,6 +3,7 @@
  * linux/arch/sh/kernel/io_generic.c
  *
  * Copyright (C) 2000  Niibe Yutaka
+ * Copyright (C) 2005  Paul Mundt
  *
  * Generic I/O routine. These can be used where a machine specific version
  * is not required.
@@ -10,21 +11,20 @@
  * 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 <asm/io.h>
 #include <asm/machvec.h>
-#include <linux/module.h>
 
-#if defined(CONFIG_CPU_SH3)
+#ifdef CONFIG_CPU_SH3
+/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
+ * workaround. */
 /* I'm not sure SH7709 has this kind of bug */
-#define SH3_PCMCIA_BUG_WORKAROUND 1
-#define DUMMY_READ_AREA6	  0xba000000
+#define dummy_read()	ctrl_inb(0xba000000)
+#else
+#define dummy_read()
 #endif
 
-#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
-
 unsigned long generic_io_base;
 
 static inline void delay(void)
@@ -32,40 +32,40 @@
 	ctrl_inw(0xa0000000);
 }
 
-unsigned char generic_inb(unsigned long port)
+u8 generic_inb(unsigned long port)
 {
-	return *(volatile unsigned char*)PORT2ADDR(port);
+	return ctrl_inb((unsigned long __force)ioport_map(port, 1));
 }
 
-unsigned short generic_inw(unsigned long port)
+u16 generic_inw(unsigned long port)
 {
-	return *(volatile unsigned short*)PORT2ADDR(port);
+	return ctrl_inw((unsigned long __force)ioport_map(port, 2));
 }
 
-unsigned int generic_inl(unsigned long port)
+u32 generic_inl(unsigned long port)
 {
-	return *(volatile unsigned long*)PORT2ADDR(port);
+	return ctrl_inl((unsigned long __force)ioport_map(port, 4));
 }
 
-unsigned char generic_inb_p(unsigned long port)
+u8 generic_inb_p(unsigned long port)
 {
-	unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
+	unsigned long v = generic_inb(port);
 
 	delay();
 	return v;
 }
 
-unsigned short generic_inw_p(unsigned long port)
+u16 generic_inw_p(unsigned long port)
 {
-	unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
+	unsigned long v = generic_inw(port);
 
 	delay();
 	return v;
 }
 
-unsigned int generic_inl_p(unsigned long port)
+u32 generic_inl_p(unsigned long port)
 {
-	unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
+	unsigned long v = generic_inl(port);
 
 	delay();
 	return v;
@@ -77,75 +77,70 @@
  * convert the port address to real address once.
  */
 
-void generic_insb(unsigned long port, void *buffer, unsigned long count)
+void generic_insb(unsigned long port, void *dst, unsigned long count)
 {
-	volatile unsigned char *port_addr;
-	unsigned char *buf=buffer;
-
-	port_addr = (volatile unsigned char *)PORT2ADDR(port);
+	volatile u8 *port_addr;
+	u8 *buf = dst;
 
-	while(count--)
-	    *buf++ = *port_addr;
+	port_addr = (volatile u8 *)ioport_map(port, 1);
+	while (count--)
+		*buf++ = *port_addr;
 }
 
-void generic_insw(unsigned long port, void *buffer, unsigned long count)
+void generic_insw(unsigned long port, void *dst, unsigned long count)
 {
-	volatile unsigned short *port_addr;
-	unsigned short *buf=buffer;
+	volatile u16 *port_addr;
+	u16 *buf = dst;
 
-	port_addr = (volatile unsigned short *)PORT2ADDR(port);
+	port_addr = (volatile u16 *)ioport_map(port, 2);
+	while (count--)
+		*buf++ = *port_addr;
 
-	while(count--)
-	    *buf++ = *port_addr;
-#ifdef SH3_PCMCIA_BUG_WORKAROUND
-	ctrl_inb (DUMMY_READ_AREA6);
-#endif
+	dummy_read();
 }
 
-void generic_insl(unsigned long port, void *buffer, unsigned long count)
+void generic_insl(unsigned long port, void *dst, unsigned long count)
 {
-	volatile unsigned long *port_addr;
-	unsigned long *buf=buffer;
+	volatile u32 *port_addr;
+	u32 *buf = dst;
 
-	port_addr = (volatile unsigned long *)PORT2ADDR(port);
+	port_addr = (volatile u32 *)ioport_map(port, 4);
+	while (count--)
+		*buf++ = *port_addr;
 
-	while(count--)
-	    *buf++ = *port_addr;
-#ifdef SH3_PCMCIA_BUG_WORKAROUND
-	ctrl_inb (DUMMY_READ_AREA6);
-#endif
+	dummy_read();
 }
 
-void generic_outb(unsigned char b, unsigned long port)
+void generic_outb(u8 b, unsigned long port)
 {
-	*(volatile unsigned char*)PORT2ADDR(port) = b;
+	ctrl_outb(b, (unsigned long __force)ioport_map(port, 1));
 }
 
-void generic_outw(unsigned short b, unsigned long port)
+void generic_outw(u16 b, unsigned long port)
 {
-	*(volatile unsigned short*)PORT2ADDR(port) = b;
+	ctrl_outw(b, (unsigned long __force)ioport_map(port, 2));
 }
 
-void generic_outl(unsigned int b, unsigned long port)
+void generic_outl(u32 b, unsigned long port)
 {
-        *(volatile unsigned long*)PORT2ADDR(port) = b;
+	ctrl_outl(b, (unsigned long __force)ioport_map(port, 4));
 }
 
-void generic_outb_p(unsigned char b, unsigned long port)
+void generic_outb_p(u8 b, unsigned long port)
 {
-	*(volatile unsigned char*)PORT2ADDR(port) = b;
+	generic_outb(b, port);
 	delay();
 }
 
-void generic_outw_p(unsigned short b, unsigned long port)
+void generic_outw_p(u16 b, unsigned long port)
 {
-	*(volatile unsigned short*)PORT2ADDR(port) = b;
+	generic_outw(b, port);
 	delay();
 }
 
-void generic_outl_p(unsigned int b, unsigned long port)
+void generic_outl_p(u32 b, unsigned long port)
 {
-	*(volatile unsigned long*)PORT2ADDR(port) = b;
+	generic_outl(b, port);
 	delay();
 }
 
@@ -154,90 +149,77 @@
  * address. However as the port address doesn't change we only need to
  * convert the port address to real address once.
  */
-
-void generic_outsb(unsigned long port, const void *buffer, unsigned long count)
+void generic_outsb(unsigned long port, const void *src, unsigned long count)
 {
-	volatile unsigned char *port_addr;
-	const unsigned char *buf=buffer;
+	volatile u8 *port_addr;
+	const u8 *buf = src;
 
-	port_addr = (volatile unsigned char *)PORT2ADDR(port);
+	port_addr = (volatile u8 __force *)ioport_map(port, 1);
 
-	while(count--)
-	    *port_addr = *buf++;
+	while (count--)
+		*port_addr = *buf++;
 }
 
-void generic_outsw(unsigned long port, const void *buffer, unsigned long count)
+void generic_outsw(unsigned long port, const void *src, unsigned long count)
 {
-	volatile unsigned short *port_addr;
-	const unsigned short *buf=buffer;
+	volatile u16 *port_addr;
+	const u16 *buf = src;
 
-	port_addr = (volatile unsigned short *)PORT2ADDR(port);
+	port_addr = (volatile u16 __force *)ioport_map(port, 2);
 
-	while(count--)
-	    *port_addr = *buf++;
+	while (count--)
+		*port_addr = *buf++;
 
-#ifdef SH3_PCMCIA_BUG_WORKAROUND
-	ctrl_inb (DUMMY_READ_AREA6);
-#endif
+	dummy_read();
 }
 
-void generic_outsl(unsigned long port, const void *buffer, unsigned long count)
+void generic_outsl(unsigned long port, const void *src, unsigned long count)
 {
-	volatile unsigned long *port_addr;
-	const unsigned long *buf=buffer;
+	volatile u32 *port_addr;
+	const u32 *buf = src;
 
-	port_addr = (volatile unsigned long *)PORT2ADDR(port);
+	port_addr = (volatile u32 __force *)ioport_map(port, 4);
+	while (count--)
+		*port_addr = *buf++;
 
-	while(count--)
-	    *port_addr = *buf++;
-
-#ifdef SH3_PCMCIA_BUG_WORKAROUND
-	ctrl_inb (DUMMY_READ_AREA6);
-#endif
-}
-
-unsigned char generic_readb(unsigned long addr)
-{
-	return *(volatile unsigned char*)addr;
+	dummy_read();
 }
 
-unsigned short generic_readw(unsigned long addr)
+u8 generic_readb(void __iomem *addr)
 {
-	return *(volatile unsigned short*)addr;
+	return ctrl_inb((unsigned long __force)addr);
 }
 
-unsigned int generic_readl(unsigned long addr)
+u16 generic_readw(void __iomem *addr)
 {
-	return *(volatile unsigned long*)addr;
+	return ctrl_inw((unsigned long __force)addr);
 }
 
-void generic_writeb(unsigned char b, unsigned long addr)
+u32 generic_readl(void __iomem *addr)
 {
-	*(volatile unsigned char*)addr = b;
+	return ctrl_inl((unsigned long __force)addr);
 }
 
-void generic_writew(unsigned short b, unsigned long addr)
+void generic_writeb(u8 b, void __iomem *addr)
 {
-	*(volatile unsigned short*)addr = b;
+	ctrl_outb(b, (unsigned long __force)addr);
 }
 
-void generic_writel(unsigned int b, unsigned long addr)
+void generic_writew(u16 b, void __iomem *addr)
 {
-        *(volatile unsigned long*)addr = b;
+	ctrl_outw(b, (unsigned long __force)addr);
 }
 
-void * generic_ioremap(unsigned long offset, unsigned long size)
+void generic_writel(u32 b, void __iomem *addr)
 {
-	return (void *) P2SEGADDR(offset);
+	ctrl_outl(b, (unsigned long __force)addr);
 }
-EXPORT_SYMBOL(generic_ioremap);
 
-void generic_iounmap(void *addr)
+void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
 {
+	return (void __iomem *)(addr + generic_io_base);
 }
-EXPORT_SYMBOL(generic_iounmap);
 
-unsigned long generic_isa_port2addr(unsigned long offset)
+void generic_ioport_unmap(void __iomem *addr)
 {
-	return offset + generic_io_base;
 }

diff -urN -X exclude linux-2.6.15/arch/sh/mm/ioremap.c sh-2.6.15/arch/sh/mm/ioremap.c
--- linux-2.6.15/arch/sh/mm/ioremap.c	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/mm/ioremap.c	2006-01-11 03:12:36.000000000 +0200
@@ -6,13 +6,19 @@
  * 640k-1MB IO memory area on PC's
  *
  * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2005, 2006 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
  */
-
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
+#include <asm/addrspace.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
@@ -80,9 +86,15 @@
 	if (address >= end)
 		BUG();
 	do {
+		pud_t *pud;
 		pmd_t *pmd;
-		pmd = pmd_alloc(&init_mm, dir, address);
+
 		error = -ENOMEM;
+
+		pud = pud_alloc(&init_mm, dir, address);
+		if (!pud)
+			break;
+		pmd = pmd_alloc(&init_mm, pud, address);
 		if (!pmd)
 			break;
 		if (remap_area_pmd(pmd, address, end - address,
@@ -97,10 +109,6 @@
 }
 
 /*
- * Generic mapping function (not visible outside):
- */
-
-/*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. Needed when the kernel wants to access high addresses
  * directly.
@@ -109,11 +117,11 @@
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
+			unsigned long flags)
 {
-	void * addr;
 	struct vm_struct * area;
-	unsigned long offset, last_addr;
+	unsigned long offset, last_addr, addr, orig_addr;
 
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
@@ -124,7 +132,7 @@
 	 * Don't remap the low PCI/ISA area, it's always mapped..
 	 */
 	if (phys_addr >= 0xA0000 && last_addr < 0x100000)
-		return phys_to_virt(phys_addr);
+		return (void __iomem *)phys_to_virt(phys_addr);
 
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
@@ -146,16 +154,71 @@
 	if (!area)
 		return NULL;
 	area->phys_addr = phys_addr;
-	addr = area->addr;
-	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
-		vunmap(addr);
-		return NULL;
+	orig_addr = addr = (unsigned long)area->addr;
+
+#ifdef CONFIG_32BIT
+	/*
+	 * First try to remap through the PMB once a valid VMA has been
+	 * established. Smaller allocations (or the rest of the size
+	 * remaining after a PMB mapping due to the size not being
+	 * perfectly aligned on a PMB size boundary) are then mapped
+	 * through the UTLB using conventional page tables.
+	 *
+	 * PMB entries are all pre-faulted.
+	 */
+	if (unlikely(size >= 0x1000000)) {
+		unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
+
+		if (likely(mapped)) {
+			addr		+= mapped;
+			phys_addr	+= mapped;
+			size		-= mapped;
+		}
 	}
-	return (void *) (offset + (char *)addr);
+#endif
+
+	if (likely(size))
+		if (remap_area_pages(addr, phys_addr, size, flags)) {
+			vunmap((void *)orig_addr);
+			return NULL;
+		}
+
+	return (void __iomem *)(offset + (char *)orig_addr);
 }
+EXPORT_SYMBOL(__ioremap);
 
-void p3_iounmap(void *addr)
+void __iounmap(void __iomem *addr)
 {
-	if (addr > high_memory)
-		vfree((void *)(PAGE_MASK & (unsigned long)addr));
+	unsigned long vaddr = (unsigned long __force)addr;
+	struct vm_struct *p;
+
+	if (PXSEG(vaddr) < P3SEG)
+		return;
+
+#ifdef CONFIG_32BIT
+	/*
+	 * Purge any PMB entries that may have been established for this
+	 * mapping, then proceed with conventional VMA teardown.
+	 *
+	 * XXX: Note that due to the way that remove_vm_area() does
+	 * matching of the resultant VMA, we aren't able to fast-forward
+	 * the address past the PMB space until the end of the VMA where
+	 * the page tables reside. As such, unmap_vm_area() will be
+	 * forced to linearly scan over the area until it finds the page
+	 * tables where PTEs that need to be unmapped actually reside,
+	 * which is far from optimal. Perhaps we need to use a separate
+	 * VMA for the PMB mappings?
+	 *					-- PFM.
+	 */
+	pmb_unmap(vaddr);
+#endif
+
+	p = remove_vm_area((void *)(vaddr & PAGE_MASK));
+	if (!p) {
+		printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr);
+		return;
+	}
+
+	kfree(p);
 }
+EXPORT_SYMBOL(__iounmap);

diff -urN -X exclude linux-2.6.15/include/asm-sh/io.h sh-2.6.15/include/asm-sh/io.h
--- linux-2.6.15/include/asm-sh/io.h	2005-06-20 22:46:02.000000000 +0300
+++ sh-2.6.15/include/asm-sh/io.h	2006-01-11 03:14:10.000000000 +0200
@@ -11,7 +11,7 @@
  * For read{b,w,l} and write{b,w,l} there are also __raw versions, which
  * do not have a memory barrier after them.
  *
- * In addition, we have 
+ * In addition, we have
  *   ctrl_in{b,w,l}/ctrl_out{b,w,l} for SuperH specific I/O.
  *   which are processor specific.
  */
@@ -23,19 +23,27 @@
  *  inb   by default expands to _inb, but the machine specific code may
  *        define it to __inb if it chooses.
  */
-
+#include <linux/config.h>
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/addrspace.h>
 #include <asm/machvec.h>
-#include <linux/config.h>
+#include <asm/pgtable.h>
+#include <asm-generic/iomap.h>
+
+#ifdef __KERNEL__
 
 /*
  * Depending on which platform we are running on, we need different
  * I/O functions.
  */
+#define __IO_PREFIX	generic
+#include <asm/io_generic.h>
+
+#define maybebadio(port) \
+  printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
+	 __FUNCTION__, __LINE__, (port), (u32)__builtin_return_address(0))
 
-#ifdef __KERNEL__
 /*
  * Since boards are able to define their own set of I/O routines through
  * their respective machine vector, we always wrap through the mv.
@@ -44,113 +52,120 @@
  * a given routine, it will be wrapped to generic code at run-time.
  */
 
-# define __inb(p)	sh_mv.mv_inb((p))
-# define __inw(p)	sh_mv.mv_inw((p))
-# define __inl(p)	sh_mv.mv_inl((p))
-# define __outb(x,p)	sh_mv.mv_outb((x),(p))
-# define __outw(x,p)	sh_mv.mv_outw((x),(p))
-# define __outl(x,p)	sh_mv.mv_outl((x),(p))
-
-# define __inb_p(p)	sh_mv.mv_inb_p((p))
-# define __inw_p(p)	sh_mv.mv_inw_p((p))
-# define __inl_p(p)	sh_mv.mv_inl_p((p))
-# define __outb_p(x,p)	sh_mv.mv_outb_p((x),(p))
-# define __outw_p(x,p)	sh_mv.mv_outw_p((x),(p))
-# define __outl_p(x,p)	sh_mv.mv_outl_p((x),(p))
-
-# define __insb(p,b,c)	sh_mv.mv_insb((p), (b), (c))
-# define __insw(p,b,c)	sh_mv.mv_insw((p), (b), (c))
-# define __insl(p,b,c)	sh_mv.mv_insl((p), (b), (c))
-# define __outsb(p,b,c)	sh_mv.mv_outsb((p), (b), (c))
-# define __outsw(p,b,c)	sh_mv.mv_outsw((p), (b), (c))
-# define __outsl(p,b,c)	sh_mv.mv_outsl((p), (b), (c))
-
-# define __readb(a)	sh_mv.mv_readb((a))
-# define __readw(a)	sh_mv.mv_readw((a))
-# define __readl(a)	sh_mv.mv_readl((a))
-# define __writeb(v,a)	sh_mv.mv_writeb((v),(a))
-# define __writew(v,a)	sh_mv.mv_writew((v),(a))
-# define __writel(v,a)	sh_mv.mv_writel((v),(a))
-
-# define __ioremap(a,s)	sh_mv.mv_ioremap((a), (s))
-# define __iounmap(a)	sh_mv.mv_iounmap((a))
-
-# define __isa_port2addr(a)	sh_mv.mv_isa_port2addr(a)
-
-# define inb		__inb
-# define inw		__inw
-# define inl		__inl
-# define outb		__outb
-# define outw		__outw
-# define outl		__outl
-
-# define inb_p		__inb_p
-# define inw_p		__inw_p
-# define inl_p		__inl_p
-# define outb_p		__outb_p
-# define outw_p		__outw_p
-# define outl_p		__outl_p
-
-# define insb		__insb
-# define insw		__insw
-# define insl		__insl
-# define outsb		__outsb
-# define outsw		__outsw
-# define outsl		__outsl
-
-# define __raw_readb	__readb
-# define __raw_readw	__readw
-# define __raw_readl	__readl
-# define __raw_writeb	__writeb
-# define __raw_writew	__writew
-# define __raw_writel	__writel
+#define __inb(p)	sh_mv.mv_inb((p))
+#define __inw(p)	sh_mv.mv_inw((p))
+#define __inl(p)	sh_mv.mv_inl((p))
+#define __outb(x,p)	sh_mv.mv_outb((x),(p))
+#define __outw(x,p)	sh_mv.mv_outw((x),(p))
+#define __outl(x,p)	sh_mv.mv_outl((x),(p))
+
+#define __inb_p(p)	sh_mv.mv_inb_p((p))
+#define __inw_p(p)	sh_mv.mv_inw_p((p))
+#define __inl_p(p)	sh_mv.mv_inl_p((p))
+#define __outb_p(x,p)	sh_mv.mv_outb_p((x),(p))
+#define __outw_p(x,p)	sh_mv.mv_outw_p((x),(p))
+#define __outl_p(x,p)	sh_mv.mv_outl_p((x),(p))
+
+#define __insb(p,b,c)	sh_mv.mv_insb((p), (b), (c))
+#define __insw(p,b,c)	sh_mv.mv_insw((p), (b), (c))
+#define __insl(p,b,c)	sh_mv.mv_insl((p), (b), (c))
+#define __outsb(p,b,c)	sh_mv.mv_outsb((p), (b), (c))
+#define __outsw(p,b,c)	sh_mv.mv_outsw((p), (b), (c))
+#define __outsl(p,b,c)	sh_mv.mv_outsl((p), (b), (c))
+
+#define __readb(a)	sh_mv.mv_readb((a))
+#define __readw(a)	sh_mv.mv_readw((a))
+#define __readl(a)	sh_mv.mv_readl((a))
+#define __writeb(v,a)	sh_mv.mv_writeb((v),(a))
+#define __writew(v,a)	sh_mv.mv_writew((v),(a))
+#define __writel(v,a)	sh_mv.mv_writel((v),(a))
+
+#define inb		__inb
+#define inw		__inw
+#define inl		__inl
+#define outb		__outb
+#define outw		__outw
+#define outl		__outl
+
+#define inb_p		__inb_p
+#define inw_p		__inw_p
+#define inl_p		__inl_p
+#define outb_p		__outb_p
+#define outw_p		__outw_p
+#define outl_p		__outl_p
+
+#define insb		__insb
+#define insw		__insw
+#define insl		__insl
+#define outsb		__outsb
+#define outsw		__outsw
+#define outsl		__outsl
+
+#define __raw_readb(a)		__readb((void __iomem *)(a))
+#define __raw_readw(a)		__readw((void __iomem *)(a))
+#define __raw_readl(a)		__readl((void __iomem *)(a))
+#define __raw_writeb(v, a)	__writeb(v, (void __iomem *)(a))
+#define __raw_writew(v, a)	__writew(v, (void __iomem *)(a))
+#define __raw_writel(v, a)	__writel(v, (void __iomem *)(a))
 
 /*
  * The platform header files may define some of these macros to use
  * the inlined versions where appropriate.  These macros may also be
  * redefined by userlevel programs.
  */
-#ifdef __raw_readb
-# define readb(a)	({ unsigned long r_ = __raw_readb((unsigned long)a); mb(); r_; })
+#ifdef __readb
+# define readb(a)	({ unsigned long r_ = __raw_readb(a); mb(); r_; })
 #endif
 #ifdef __raw_readw
-# define readw(a)	({ unsigned long r_ = __raw_readw((unsigned long)a); mb(); r_; })
+# define readw(a)	({ unsigned long r_ = __raw_readw(a); mb(); r_; })
 #endif
 #ifdef __raw_readl
-# define readl(a)	({ unsigned long r_ = __raw_readl((unsigned long)a); mb(); r_; })
+# define readl(a)	({ unsigned long r_ = __raw_readl(a); mb(); r_; })
 #endif
 
 #ifdef __raw_writeb
-# define writeb(v,a)	({ __raw_writeb((v),(unsigned long)(a)); mb(); })
+# define writeb(v,a)	({ __raw_writeb((v),(a)); mb(); })
 #endif
 #ifdef __raw_writew
-# define writew(v,a)	({ __raw_writew((v),(unsigned long)(a)); mb(); })
+# define writew(v,a)	({ __raw_writew((v),(a)); mb(); })
 #endif
 #ifdef __raw_writel
-# define writel(v,a)	({ __raw_writel((v),(unsigned long)(a)); mb(); })
+# define writel(v,a)	({ __raw_writel((v),(a)); mb(); })
 #endif
 
 #define readb_relaxed(a) readb(a)
 #define readw_relaxed(a) readw(a)
 #define readl_relaxed(a) readl(a)
 
-#define mmiowb()
+/* Simple MMIO */
+#define ioread8(a)		readb(a)
+#define ioread16(a)		readw(a)
+#define ioread16be(a)		be16_to_cpu(__raw_readw((a)))
+#define ioread32(a)		readl(a)
+#define ioread32be(a)		be32_to_cpu(__raw_readl((a)))
+
+#define iowrite8(v,a)		writeb((v),(a))
+#define iowrite16(v,a)		writew((v),(a))
+#define iowrite16be(v,a)	__raw_writew(cpu_to_be16((v)),(a))
+#define iowrite32(v,a)		writel((v),(a))
+#define iowrite32be(v,a)	__raw_writel(cpu_to_be32((v)),(a))
+
+#define ioread8_rep(a,d,c)	insb((a),(d),(c))
+#define ioread16_rep(a,d,c)	insw((a),(d),(c))
+#define ioread32_rep(a,d,c)	insl((a),(d),(c))
+
+#define iowrite8_rep(a,s,c)	outsb((a),(s),(c))
+#define iowrite16_rep(a,s,c)	outsw((a),(s),(c))
+#define iowrite32_rep(a,s,c)	outsl((a),(s),(c))
 
-/*
- * If the platform has PC-like I/O, this function converts the offset into
- * an address.
- */
-static __inline__ unsigned long isa_port2addr(unsigned long offset)
-{
-	return __isa_port2addr(offset);
-}
+#define mmiowb()	wmb()	/* synco on SH-4A, otherwise a nop */
 
 /*
  * This function provides a method for the generic case where a board-specific
- * isa_port2addr simply needs to return the port + some arbitrary port base.
+ * ioport_map simply needs to return the port + some arbitrary port base.
  *
  * We use this at board setup time to implicitly set the port base, and
- * as a result, we can use the generic isa_port2addr.
+ * as a result, we can use the generic ioport_map.
  */
 static inline void __set_io_port_base(unsigned long pbase)
 {
@@ -159,51 +174,52 @@
 	generic_io_base = pbase;
 }
 
-#define isa_readb(a) readb(isa_port2addr(a))
-#define isa_readw(a) readw(isa_port2addr(a))
-#define isa_readl(a) readl(isa_port2addr(a))
-#define isa_writeb(b,a) writeb(b,isa_port2addr(a))
-#define isa_writew(w,a) writew(w,isa_port2addr(a))
-#define isa_writel(l,a) writel(l,isa_port2addr(a))
+#define isa_readb(a) readb(ioport_map(a, 1))
+#define isa_readw(a) readw(ioport_map(a, 2))
+#define isa_readl(a) readl(ioport_map(a, 4))
+#define isa_writeb(b,a) writeb(b,ioport_map(a, 1))
+#define isa_writew(w,a) writew(w,ioport_map(a, 2))
+#define isa_writel(l,a) writel(l,ioport_map(a, 4))
+
 #define isa_memset_io(a,b,c) \
-  memset((void *)(isa_port2addr((unsigned long)a)),(b),(c))
+  memset((void *)(ioport_map((unsigned long)(a), 1)),(b),(c))
 #define isa_memcpy_fromio(a,b,c) \
-  memcpy((a),(void *)(isa_port2addr((unsigned long)(b))),(c))
+  memcpy((a),(void *)(ioport_map((unsigned long)(b), 1)),(c))
 #define isa_memcpy_toio(a,b,c) \
-  memcpy((void *)(isa_port2addr((unsigned long)(a))),(b),(c))
+  memcpy((void *)(ioport_map((unsigned long)(a), 1)),(b),(c))
 
 /* We really want to try and get these to memcpy etc */
-extern void memcpy_fromio(void *, unsigned long, unsigned long);
-extern void memcpy_toio(unsigned long, const void *, unsigned long);
-extern void memset_io(unsigned long, int, unsigned long);
+extern void memcpy_fromio(void *, volatile void __iomem *, unsigned long);
+extern void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
+extern void memset_io(volatile void __iomem *, int, unsigned long);
 
 /* SuperH on-chip I/O functions */
-static __inline__ unsigned char ctrl_inb(unsigned long addr)
+static inline unsigned char ctrl_inb(unsigned long addr)
 {
 	return *(volatile unsigned char*)addr;
 }
 
-static __inline__ unsigned short ctrl_inw(unsigned long addr)
+static inline unsigned short ctrl_inw(unsigned long addr)
 {
 	return *(volatile unsigned short*)addr;
 }
 
-static __inline__ unsigned int ctrl_inl(unsigned long addr)
+static inline unsigned int ctrl_inl(unsigned long addr)
 {
 	return *(volatile unsigned long*)addr;
 }
 
-static __inline__ void ctrl_outb(unsigned char b, unsigned long addr)
+static inline void ctrl_outb(unsigned char b, unsigned long addr)
 {
 	*(volatile unsigned char*)addr = b;
 }
 
-static __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
+static inline void ctrl_outw(unsigned short b, unsigned long addr)
 {
 	*(volatile unsigned short*)addr = b;
 }
 
-static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
+static inline void ctrl_outl(unsigned int b, unsigned long addr)
 {
         *(volatile unsigned long*)addr = b;
 }
@@ -214,12 +230,12 @@
  * Change virtual addresses to physical addresses and vv.
  * These are trivial on the 1:1 Linux/SuperH mapping
  */
-static __inline__ unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void *address)
 {
 	return PHYSADDR(address);
 }
 
-static __inline__ void * phys_to_virt(unsigned long address)
+static inline void *phys_to_virt(unsigned long address)
 {
 	return (void *)P1SEGADDR(address);
 }
@@ -234,27 +250,60 @@
  * differently. On the x86 architecture, we just read/write the
  * memory location directly.
  *
- * On SH, we have the whole physical address space mapped at all times
- * (as MIPS does), so "ioremap()" and "iounmap()" do not need to do
- * anything.  (This isn't true for all machines but we still handle
- * these cases with wired TLB entries anyway ...)
+ * On SH, we traditionally have the whole physical address space mapped
+ * at all times (as MIPS does), so "ioremap()" and "iounmap()" do not
+ * need to do anything but place the address in the proper segment. This
+ * is true for P1 and P2 addresses, as well as some P3 ones. However,
+ * most of the P3 addresses and newer cores using extended addressing
+ * need to map through page tables, so the ioremap() implementation
+ * becomes a bit more complicated. See arch/sh/mm/ioremap.c for
+ * additional notes on this.
  *
  * We cheat a bit and always return uncachable areas until we've fixed
- * the drivers to handle caching properly.  
+ * the drivers to handle caching properly.
  */
-static __inline__ void * ioremap(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size);
-}
-
-static __inline__ void iounmap(void *addr)
-{
-	return __iounmap(addr);
-}
-
-#define ioremap_nocache(off,size) ioremap(off,size)
+#ifdef CONFIG_MMU
+void __iomem *__ioremap(unsigned long offset, unsigned long size,
+			unsigned long flags);
+void __iounmap(void __iomem *addr);
+#else
+#define __ioremap(offset, size, flags)	((void __iomem *)(offset))
+#define __iounmap(addr)			do { } while (0)
+#endif /* CONFIG_MMU */
+
+static inline void __iomem *
+__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
+{
+	unsigned long last_addr = offset + size - 1;
+
+	/*
+	 * For P1 and P2 space this is trivial, as everything is already
+	 * mapped. Uncached access for P1 addresses are done through P2.
+	 * In the P3 case or for addresses outside of the 29-bit space,
+	 * mapping must be done by the PMB or by using page tables.
+	 */
+	if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
+		if (unlikely(flags & _PAGE_CACHABLE))
+			return (void __iomem *)P1SEGADDR(offset);
+
+		return (void __iomem *)P2SEGADDR(offset);
+	}
+
+	return __ioremap(offset, size, flags);
+}
+
+#define ioremap(offset, size)				\
+	__ioremap_mode((offset), (size), 0)
+#define ioremap_nocache(offset, size)			\
+	__ioremap_mode((offset), (size), 0)
+#define ioremap_cache(offset, size)			\
+	__ioremap_mode((offset), (size), _PAGE_CACHABLE)
+#define p3_ioremap(offset, size, flags)			\
+	__ioremap((offset), (size), (flags))
+#define iounmap(addr)					\
+	__iounmap((addr))
 
-static __inline__ int check_signature(unsigned long io_addr,
+static inline int check_signature(char __iomem *io_addr,
 			const unsigned char *signature, int length)
 {
 	int retval = 0;
diff -urN -X exclude linux-2.6.15/include/asm-sh/io_generic.h sh-2.6.15/include/asm-sh/io_generic.h
--- linux-2.6.15/include/asm-sh/io_generic.h	2004-07-15 22:22:27.000000000 +0300
+++ sh-2.6.15/include/asm-sh/io_generic.h	2006-01-04 00:15:30.000000000 +0200
@@ -1,51 +1,49 @@
 /*
- * include/asm-sh/io_generic.h
- *
- * Copyright 2000 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.
- *
- * Generic IO functions
+ * Trivial I/O routine definitions, intentionally meant to be included
+ * multiple times. Ugly I/O routine concatenation helpers taken from
+ * alpha. Must be included _before_ io.h to avoid preprocessor-induced
+ * routine mismatch.
  */
+#define IO_CONCAT(a,b)	_IO_CONCAT(a,b)
+#define _IO_CONCAT(a,b)	a ## _ ## b
 
-#ifndef _ASM_SH_IO_GENERIC_H
-#define _ASM_SH_IO_GENERIC_H
+#ifndef __IO_PREFIX
+#error "Don't include this header without a valid system prefix"
+#endif
+
+u8 IO_CONCAT(__IO_PREFIX,inb)(unsigned long);
+u16 IO_CONCAT(__IO_PREFIX,inw)(unsigned long);
+u32 IO_CONCAT(__IO_PREFIX,inl)(unsigned long);
+
+void IO_CONCAT(__IO_PREFIX,outb)(u8, unsigned long);
+void IO_CONCAT(__IO_PREFIX,outw)(u16, unsigned long);
+void IO_CONCAT(__IO_PREFIX,outl)(u32, unsigned long);
+
+u8 IO_CONCAT(__IO_PREFIX,inb_p)(unsigned long);
+u16 IO_CONCAT(__IO_PREFIX,inw_p)(unsigned long);
+u32 IO_CONCAT(__IO_PREFIX,inl_p)(unsigned long);
+void IO_CONCAT(__IO_PREFIX,outb_p)(u8, unsigned long);
+void IO_CONCAT(__IO_PREFIX,outw_p)(u16, unsigned long);
+void IO_CONCAT(__IO_PREFIX,outl_p)(u32, unsigned long);
+
+void IO_CONCAT(__IO_PREFIX,insb)(unsigned long, void *dst, unsigned long count);
+void IO_CONCAT(__IO_PREFIX,insw)(unsigned long, void *dst, unsigned long count);
+void IO_CONCAT(__IO_PREFIX,insl)(unsigned long, void *dst, unsigned long count);
+void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long count);
+void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
+void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
+
+u8 IO_CONCAT(__IO_PREFIX,readb)(void __iomem *);
+u16 IO_CONCAT(__IO_PREFIX,readw)(void __iomem *);
+u32 IO_CONCAT(__IO_PREFIX,readl)(void __iomem *);
+void IO_CONCAT(__IO_PREFIX,writeb)(u8, void __iomem *);
+void IO_CONCAT(__IO_PREFIX,writew)(u16, void __iomem *);
+void IO_CONCAT(__IO_PREFIX,writel)(u32, void __iomem *);
 
-extern unsigned long generic_io_base;
+void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
+void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
 
-extern unsigned char generic_inb(unsigned long port);
-extern unsigned short generic_inw(unsigned long port);
-extern unsigned int generic_inl(unsigned long port);
-
-extern void generic_outb(unsigned char value, unsigned long port);
-extern void generic_outw(unsigned short value, unsigned long port);
-extern void generic_outl(unsigned int value, unsigned long port);
-
-extern unsigned char generic_inb_p(unsigned long port);
-extern unsigned short generic_inw_p(unsigned long port);
-extern unsigned int generic_inl_p(unsigned long port);
-extern void generic_outb_p(unsigned char value, unsigned long port);
-extern void generic_outw_p(unsigned short value, unsigned long port);
-extern void generic_outl_p(unsigned int value, unsigned long port);
-
-extern void generic_insb(unsigned long port, void *addr, unsigned long count);
-extern void generic_insw(unsigned long port, void *addr, unsigned long count);
-extern void generic_insl(unsigned long port, void *addr, unsigned long count);
-extern void generic_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void generic_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void generic_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern unsigned char generic_readb(unsigned long addr);
-extern unsigned short generic_readw(unsigned long addr);
-extern unsigned int generic_readl(unsigned long addr);
-extern void generic_writeb(unsigned char b, unsigned long addr);
-extern void generic_writew(unsigned short b, unsigned long addr);
-extern void generic_writel(unsigned int b, unsigned long addr);
+void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
+void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
 
-extern void *generic_ioremap(unsigned long offset, unsigned long size);
-extern void generic_iounmap(void *addr);
-
-extern unsigned long generic_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_GENERIC_H */
+#undef __IO_PREFIX

diff -urN -X exclude linux-2.6.15/include/asm-sh/machvec.h sh-2.6.15/include/asm-sh/machvec.h
--- linux-2.6.15/include/asm-sh/machvec.h	2006-01-04 14:20:02.000000000 +0200
+++ sh-2.6.15/include/asm-sh/machvec.h	2006-01-04 14:16:32.000000000 +0200
@@ -18,44 +18,37 @@
 #include <asm/machvec_init.h>
 
 struct device;
-struct timeval;
 
-struct sh_machine_vector
-{
+struct sh_machine_vector {
 	int mv_nr_irqs;
 
-	unsigned char (*mv_inb)(unsigned long);
-	unsigned short (*mv_inw)(unsigned long);
-	unsigned int (*mv_inl)(unsigned long);
-	void (*mv_outb)(unsigned char, unsigned long);
-	void (*mv_outw)(unsigned short, unsigned long);
-	void (*mv_outl)(unsigned int, unsigned long);
-
-	unsigned char (*mv_inb_p)(unsigned long);
-	unsigned short (*mv_inw_p)(unsigned long);
-	unsigned int (*mv_inl_p)(unsigned long);
-	void (*mv_outb_p)(unsigned char, unsigned long);
-	void (*mv_outw_p)(unsigned short, unsigned long);
-	void (*mv_outl_p)(unsigned int, unsigned long);
-
-	void (*mv_insb)(unsigned long port, void *addr, unsigned long count);
-	void (*mv_insw)(unsigned long port, void *addr, unsigned long count);
-	void (*mv_insl)(unsigned long port, void *addr, unsigned long count);
-	void (*mv_outsb)(unsigned long port, const void *addr, unsigned long count);
-	void (*mv_outsw)(unsigned long port, const void *addr, unsigned long count);
-	void (*mv_outsl)(unsigned long port, const void *addr, unsigned long count);
-
-	unsigned char (*mv_readb)(unsigned long);
-	unsigned short (*mv_readw)(unsigned long);
-	unsigned int (*mv_readl)(unsigned long);
-	void (*mv_writeb)(unsigned char, unsigned long);
-	void (*mv_writew)(unsigned short, unsigned long);
-	void (*mv_writel)(unsigned int, unsigned long);
-
-	void* (*mv_ioremap)(unsigned long offset, unsigned long size);
-	void (*mv_iounmap)(void *addr);
-
-	unsigned long (*mv_isa_port2addr)(unsigned long offset);
+	u8 (*mv_inb)(unsigned long);
+	u16 (*mv_inw)(unsigned long);
+	u32 (*mv_inl)(unsigned long);
+	void (*mv_outb)(u8, unsigned long);
+	void (*mv_outw)(u16, unsigned long);
+	void (*mv_outl)(u32, unsigned long);
+
+	u8 (*mv_inb_p)(unsigned long);
+	u16 (*mv_inw_p)(unsigned long);
+	u32 (*mv_inl_p)(unsigned long);
+	void (*mv_outb_p)(u8, unsigned long);
+	void (*mv_outw_p)(u16, unsigned long);
+	void (*mv_outl_p)(u32, unsigned long);
+
+	void (*mv_insb)(unsigned long, void *dst, unsigned long count);
+	void (*mv_insw)(unsigned long, void *dst, unsigned long count);
+	void (*mv_insl)(unsigned long, void *dst, unsigned long count);
+	void (*mv_outsb)(unsigned long, const void *src, unsigned long count);
+	void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
+	void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
+
+	u8 (*mv_readb)(void __iomem *);
+	u16 (*mv_readw)(void __iomem *);
+	u32 (*mv_readl)(void __iomem *);
+	void (*mv_writeb)(u8, void __iomem *);
+	void (*mv_writew)(u16, void __iomem *);
+	void (*mv_writel)(u32, void __iomem *);
 
 	int (*mv_irq_demux)(int irq);
 
@@ -66,6 +59,9 @@
 
 	void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, gfp_t);
 	int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
+
+	void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
+	void (*mv_ioport_unmap)(void __iomem *);
 };
 
 extern struct sh_machine_vector sh_mv;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/8] sh: Simplistic clock framework.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
                   ` (4 preceding siblings ...)
  2006-01-14 22:54 ` [PATCH 5/8] sh: I/O routine cleanups and ioremap() overhaul Paul Mundt
@ 2006-01-14 22:55 ` Paul Mundt
  2006-01-14 22:55 ` [PATCH 7/8] sh: Simple timer framework Paul Mundt
  2006-01-14 22:56 ` [PATCH 8/8] sh: Move CPU subtype configuration to its own Kconfig Paul Mundt
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:55 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This adds a relatively simplistic clock framework for sh. The initial
goal behind this is to clean up the arch/sh/kernel/time.c mess and to get
the CPU subtype-specific frequency setting and calculation code moved
somewhere more sensible.

This only deals with the core clocks at the moment, though it's trivial
for other drivers to define their own clocks as desired.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/boards/overdrive/Makefile      |    2 
 arch/sh/boards/overdrive/setup.c       |    6 
 arch/sh/boards/overdrive/time.c        |  119 -------
 arch/sh/kernel/cpu/clock.c             |  287 ++++++++++++++++++
 arch/sh/kernel/cpu/sh3/Makefile        |    7 
 arch/sh/kernel/cpu/sh3/clock-sh3.c     |   89 +++++
 arch/sh/kernel/cpu/sh3/clock-sh7300.c  |   78 ++++
 arch/sh/kernel/cpu/sh3/clock-sh7705.c  |   84 +++++
 arch/sh/kernel/cpu/sh3/clock-sh7709.c  |   96 ++++++
 arch/sh/kernel/cpu/sh4/Makefile        |   13 
 arch/sh/kernel/cpu/sh4/clock-sh4-202.c |  179 +++++++++++
 arch/sh/kernel/cpu/sh4/clock-sh4.c     |   80 +++++
 arch/sh/kernel/cpu/sh4/clock-sh73180.c |   81 +++++
 arch/sh/kernel/cpu/sh4/clock-sh7770.c  |   73 ++++
 arch/sh/kernel/cpu/sh4/clock-sh7780.c  |  126 ++++++++
 arch/sh/kernel/time.c                  |  518 ++-------------------------------
 include/asm-sh/clock.h                 |   61 +++
 include/asm-sh/cpu-sh4/freq.h          |    2 
 include/asm-sh/freq.h                  |   11 
 19 files changed, 1288 insertions(+), 624 deletions(-)

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/clock.c sh-2.6.15/arch/sh/kernel/cpu/clock.c
--- linux-2.6.15/arch/sh/kernel/cpu/clock.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/clock.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,287 @@
+/*
+ * arch/sh/kernel/cpu/clock.c - SuperH clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * This clock framework is derived from the OMAP version by:
+ *
+ *	Copyright (C) 2004 Nokia Corporation
+ *	Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/kref.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+#include <asm/clock.h>
+#include <asm/timer.h>
+
+static LIST_HEAD(clock_list);
+static DEFINE_SPINLOCK(clock_lock);
+static DECLARE_MUTEX(clock_list_sem);
+
+/*
+ * Each subtype is expected to define the init routines for these clocks,
+ * as each subtype (or processor family) will have these clocks at the
+ * very least. These are all provided through the CPG, which even some of
+ * the more quirky parts (such as ST40, SH4-202, etc.) still have.
+ *
+ * The processor-specific code is expected to register any additional
+ * clock sources that are of interest.
+ */
+static struct clk master_clk = {
+	.name		= "master_clk",
+	.flags		= CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
+#ifdef CONFIG_SH_PCLK_FREQ_BOOL
+	.rate		= CONFIG_SH_PCLK_FREQ,
+#endif
+};
+
+static struct clk module_clk = {
+	.name		= "module_clk",
+	.parent		= &master_clk,
+	.flags		= CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
+};
+
+static struct clk bus_clk = {
+	.name		= "bus_clk",
+	.parent		= &master_clk,
+	.flags		= CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
+};
+
+static struct clk cpu_clk = {
+	.name		= "cpu_clk",
+	.parent		= &master_clk,
+	.flags		= CLK_ALWAYS_ENABLED,
+};
+
+/*
+ * The ordering of these clocks matters, do not change it.
+ */
+static struct clk *onchip_clocks[] = {
+	&master_clk,
+	&module_clk,
+	&bus_clk,
+	&cpu_clk,
+};
+
+static void propagate_rate(struct clk *clk)
+{
+	struct clk *clkp;
+
+	list_for_each_entry(clkp, &clock_list, node) {
+		if (likely(clkp->parent != clk))
+			continue;
+		if (likely(clkp->ops && clkp->ops->recalc))
+			clkp->ops->recalc(clkp);
+	}
+}
+
+int __clk_enable(struct clk *clk)
+{
+	/*
+	 * See if this is the first time we're enabling the clock, some
+	 * clocks that are always enabled still require "special"
+	 * initialization. This is especially true if the clock mode
+	 * changes and the clock needs to hunt for the proper set of
+	 * divisors to use before it can effectively recalc.
+	 */
+	if (unlikely(atomic_read(&clk->kref.refcount) == 1))
+		if (clk->ops && clk->ops->init)
+			clk->ops->init(clk);
+
+	if (clk->flags & CLK_ALWAYS_ENABLED)
+		return 0;
+
+	if (likely(clk->ops && clk->ops->enable))
+		clk->ops->enable(clk);
+
+	kref_get(&clk->kref);
+	return 0;
+}
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&clock_lock, flags);
+	ret = __clk_enable(clk);
+	spin_unlock_irqrestore(&clock_lock, flags);
+
+	return ret;
+}
+
+static void clk_kref_release(struct kref *kref)
+{
+	/* Nothing to do */
+}
+
+void __clk_disable(struct clk *clk)
+{
+	if (clk->flags & CLK_ALWAYS_ENABLED)
+		return;
+
+	kref_put(&clk->kref, clk_kref_release);
+}
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clock_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clock_lock, flags);
+}
+
+int clk_register(struct clk *clk)
+{
+	down(&clock_list_sem);
+
+	list_add(&clk->node, &clock_list);
+	kref_init(&clk->kref);
+
+	up(&clock_list_sem);
+
+	return 0;
+}
+
+void clk_unregister(struct clk *clk)
+{
+	down(&clock_list_sem);
+	list_del(&clk->node);
+	up(&clock_list_sem);
+}
+
+inline unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EOPNOTSUPP;
+
+	if (likely(clk->ops && clk->ops->set_rate)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		ret = clk->ops->set_rate(clk, rate);
+		spin_unlock_irqrestore(&clock_lock, flags);
+	}
+
+	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+		propagate_rate(clk);
+
+	return ret;
+}
+
+void clk_recalc_rate(struct clk *clk)
+{
+	if (likely(clk->ops && clk->ops->recalc)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		clk->ops->recalc(clk);
+		spin_unlock_irqrestore(&clock_lock, flags);
+	}
+
+	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+		propagate_rate(clk);
+}
+
+struct clk *clk_get(const char *id)
+{
+	struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+	down(&clock_list_sem);
+	list_for_each_entry(p, &clock_list, node) {
+		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+	up(&clock_list_sem);
+
+	return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+	if (clk && !IS_ERR(clk))
+		module_put(clk->owner);
+}
+
+void __init __attribute__ ((weak))
+arch_init_clk_ops(struct clk_ops **ops, int type)
+{
+}
+
+int __init clk_init(void)
+{
+	int i, ret = 0;
+
+	if (unlikely(!master_clk.rate))
+		/*
+		 * NOTE: This will break if the default divisor has been
+		 * changed.
+		 *
+		 * No one should be changing the default on us however,
+		 * expect that a sane value for CONFIG_SH_PCLK_FREQ will
+		 * be defined in the event of a different divisor.
+		 */
+		master_clk.rate = get_timer_frequency() * 4;
+
+	for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
+		struct clk *clk = onchip_clocks[i];
+
+		arch_init_clk_ops(&clk->ops, i);
+		ret |= clk_register(clk);
+		clk_enable(clk);
+	}
+
+	/* Kick the child clocks.. */
+	propagate_rate(&master_clk);
+	propagate_rate(&bus_clk);
+
+	return ret;
+}
+
+int show_clocks(struct seq_file *m)
+{
+	struct clk *clk;
+
+	list_for_each_entry_reverse(clk, &clock_list, node) {
+		unsigned long rate = clk_get_rate(clk);
+
+		/*
+		 * Don't bother listing dummy clocks with no ancestry
+		 * that only support enable and disable ops.
+		 */
+		if (unlikely(!rate && !clk->parent))
+			continue;
+
+		seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name,
+			   rate / 1000000, (rate % 1000000) / 10000);
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(clk_register);
+EXPORT_SYMBOL_GPL(clk_unregister);
+EXPORT_SYMBOL_GPL(clk_get);
+EXPORT_SYMBOL_GPL(clk_put);
+EXPORT_SYMBOL_GPL(clk_enable);
+EXPORT_SYMBOL_GPL(clk_disable);
+EXPORT_SYMBOL_GPL(__clk_enable);
+EXPORT_SYMBOL_GPL(__clk_disable);
+EXPORT_SYMBOL_GPL(clk_get_rate);
+EXPORT_SYMBOL_GPL(clk_set_rate);
+EXPORT_SYMBOL_GPL(clk_recalc_rate);

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh3/Makefile sh-2.6.15/arch/sh/kernel/cpu/sh3/Makefile
--- linux-2.6.15/arch/sh/kernel/cpu/sh3/Makefile	2004-12-26 05:37:10.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh3/Makefile	2006-01-04 00:15:27.000000000 +0200
@@ -4,3 +4,10 @@
 
 obj-y	:= ex.o probe.o
 
+clock-$(CONFIG_CPU_SH3)			:= clock-sh3.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7300)	:= clock-sh7300.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7705)	:= clock-sh7705.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7709)	:= clock-sh7709.o
+
+obj-y	+= $(clock-y)
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh3.c sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh3.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh3.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh3.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,89 @@
+/*
+ * arch/sh/kernel/cpu/sh3/clock-sh3.c
+ *
+ * Generic SH-3 support for the clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * FRQCR parsing hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
+static int ifc_divisors[]    = { 1, 2, 3, 4, 1, 1, 1, 1 };
+static int pfc_divisors[]    = { 1, 2, 3, 4, 6, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
+
+	clk->rate *= pfc_divisors[idx];
+}
+
+static struct clk_ops sh3_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
+
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh3_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
+
+	clk->rate = clk->parent->rate / stc_multipliers[idx];
+}
+
+static struct clk_ops sh3_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
+
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh3_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh3_clk_ops[] = {
+	&sh3_master_clk_ops,
+	&sh3_module_clk_ops,
+	&sh3_bus_clk_ops,
+	&sh3_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh3_clk_ops))
+		*ops = sh3_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7300.c sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7300.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7300.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7300.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,78 @@
+/*
+ * arch/sh/kernel/cpu/sh3/clock-sh7300.c
+ *
+ * SH7300 support for the clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * FRQCR parsing hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007];
+}
+
+static struct clk_ops sh7300_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0007);
+	clk->rate = clk->parent->rate / md_table[idx];
+}
+
+static struct clk_ops sh7300_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8;
+	clk->rate = clk->parent->rate / md_table[idx];
+}
+
+static struct clk_ops sh7300_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4;
+	clk->rate = clk->parent->rate / md_table[idx];
+}
+
+static struct clk_ops sh7300_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7300_clk_ops[] = {
+	&sh7300_master_clk_ops,
+	&sh7300_module_clk_ops,
+	&sh7300_bus_clk_ops,
+	&sh7300_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7300_clk_ops))
+		*ops = sh7300_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7705.c sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7705.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7705.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7705.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,84 @@
+/*
+ * arch/sh/kernel/cpu/sh3/clock-sh7705.c
+ *
+ * SH7705 support for the clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * FRQCR parsing hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+/*
+ * SH7705 uses the same divisors as the generic SH-3 case, it's just the
+ * FRQCR layout that is a bit different..
+ */
+static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
+static int ifc_divisors[]    = { 1, 2, 3, 4, 1, 1, 1, 1 };
+static int pfc_divisors[]    = { 1, 2, 3, 4, 6, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003];
+}
+
+static struct clk_ops sh7705_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = ctrl_inw(FRQCR) & 0x0003;
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7705_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8;
+	clk->rate = clk->parent->rate / stc_multipliers[idx];
+}
+
+static struct clk_ops sh7705_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4;
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7705_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7705_clk_ops[] = {
+	&sh7705_master_clk_ops,
+	&sh7705_module_clk_ops,
+	&sh7705_bus_clk_ops,
+	&sh7705_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7705_clk_ops))
+		*ops = sh7705_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7709.c sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7709.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7709.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh3/clock-sh7709.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,96 @@
+/*
+ * arch/sh/kernel/cpu/sh3/clock-sh7709.c
+ *
+ * SH7709 support for the clock framework
+ *
+ *  Copyright (C) 2005  Andriy Skulysh
+ *
+ * Based on arch/sh/kernel/cpu/sh3/clock-sh7705.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>
+
+static int stc_multipliers[] = { 1, 2, 4, 8, 3, 6, 1, 1 };
+static int ifc_divisors[]    = { 1, 2, 4, 1, 3, 1, 1, 1 };
+static int pfc_divisors[]    = { 1, 2, 4, 1, 3, 6, 1, 1 };
+
+static void set_bus_parent(struct clk *clk)
+{
+	struct clk *bus_clk = clk_get("bus_clk");
+	clk->parent = bus_clk;
+	clk_put(bus_clk);
+}
+
+static void master_clk_init(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
+
+	clk->rate *= pfc_divisors[idx];
+}
+
+static struct clk_ops sh7709_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
+
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7709_module_clk_ops = {
+#ifdef CLOCK_MODE_0_1_2_7
+	.init		= set_bus_parent,
+#endif
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = (frqcr & 0x0080) ?
+		((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1;
+
+	clk->rate = clk->parent->rate * stc_multipliers[idx];
+}
+
+static struct clk_ops sh7709_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int frqcr = ctrl_inw(FRQCR);
+	int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
+
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7709_cpu_clk_ops = {
+	.init		= set_bus_parent,
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7709_clk_ops[] = {
+	&sh7709_master_clk_ops,
+	&sh7709_module_clk_ops,
+	&sh7709_bus_clk_ops,
+	&sh7709_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7709_clk_ops))
+		*ops = sh7709_clk_ops[idx];
+}
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/Makefile sh-2.6.15/arch/sh/kernel/cpu/sh4/Makefile
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/Makefile	2004-12-26 05:37:10.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/Makefile	2006-01-07 22:13:59.197144942 +0200
@@ -4,7 +4,16 @@
 
 obj-y	:= ex.o probe.o
 
-obj-$(CONFIG_SH_FPU)                    += fpu.o
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)	+= irq_intc2.o
+obj-$(CONFIG_SH_FPU)                    += fpu.o
 obj-$(CONFIG_SH_STORE_QUEUES)		+= sq.o
 
+# Primary on-chip clocks (common)
+clock-$(CONFIG_CPU_SH4)			:= clock-sh4.o
+clock-$(CONFIG_CPU_SUBTYPE_SH73180)	:= clock-sh73180.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7770)	:= clock-sh7770.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7780)	:= clock-sh7780.o
+
+# Additional clocks by subtype
+clock-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= clock-sh4-202.o
+
+obj-y	+= $(clock-y)
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4-202.c sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4-202.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4-202.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,179 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+ *
+ * Additional SH4-202 support for the clock framework
+ *
+ *  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 <linux/err.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+#define CPG2_FRQCR3	0xfe0a0018
+
+static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 };
+static int frqcr3_values[]   = { 0, 1, 2, 3, 4, 5, 6  };
+
+static void emi_clk_recalc(struct clk *clk)
+{
+	int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007;
+	clk->rate = clk->parent->rate / frqcr3_divisors[idx];
+}
+
+static inline int frqcr3_lookup(struct clk *clk, unsigned long rate)
+{
+	int divisor = clk->parent->rate / rate;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++)
+		if (frqcr3_divisors[i] == divisor)
+			return frqcr3_values[i];
+
+	/* Safe fallback */
+	return 5;
+}
+
+static struct clk_ops sh4202_emi_clk_ops = {
+	.recalc		= emi_clk_recalc,
+};
+
+static struct clk sh4202_emi_clk = {
+	.name		= "emi_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh4202_emi_clk_ops,
+};
+
+static void femi_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007;
+	clk->rate = clk->parent->rate / frqcr3_divisors[idx];
+}
+
+static struct clk_ops sh4202_femi_clk_ops = {
+	.recalc		= femi_clk_recalc,
+};
+
+static struct clk sh4202_femi_clk = {
+	.name		= "femi_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh4202_femi_clk_ops,
+};
+
+static void shoc_clk_init(struct clk *clk)
+{
+	int i;
+
+	/*
+	 * For some reason, the shoc_clk seems to be set to some really
+	 * insane value at boot (values outside of the allowable frequency
+	 * range for instance). We deal with this by scaling it back down
+	 * to something sensible just in case.
+	 *
+	 * Start scaling from the high end down until we find something
+	 * that passes rate verification..
+	 */
+	for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
+		int divisor = frqcr3_divisors[i];
+
+		if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
+			break;
+	}
+
+	WARN_ON(i == ARRAY_SIZE(frqcr3_divisors));	/* Undefined clock */
+}
+
+static void shoc_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007;
+	clk->rate = clk->parent->rate / frqcr3_divisors[idx];
+}
+
+static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *bclk = clk_get("bus_clk");
+	unsigned long bclk_rate = clk_get_rate(bclk);
+
+	clk_put(bclk);
+
+	if (rate > bclk_rate)
+		return 1;
+	if (rate > 66000000)
+		return 1;
+
+	return 0;
+}
+
+static int shoc_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long frqcr3;
+	unsigned int tmp;
+
+	/* Make sure we have something sensible to switch to */
+	if (shoc_clk_verify_rate(clk, rate) != 0)
+		return -EINVAL;
+
+	tmp = frqcr3_lookup(clk, rate);
+
+	frqcr3 = ctrl_inl(CPG2_FRQCR3);
+	frqcr3 &= ~(0x0007 << 6);
+	frqcr3 |= tmp << 6;
+	ctrl_outl(frqcr3, CPG2_FRQCR3);
+
+	clk->rate = clk->parent->rate / frqcr3_divisors[tmp];
+
+	return 0;
+}
+
+static struct clk_ops sh4202_shoc_clk_ops = {
+	.init		= shoc_clk_init,
+	.recalc		= shoc_clk_recalc,
+	.set_rate	= shoc_clk_set_rate,
+};
+
+static struct clk sh4202_shoc_clk = {
+	.name		= "shoc_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh4202_shoc_clk_ops,
+};
+
+static struct clk *sh4202_onchip_clocks[] = {
+	&sh4202_emi_clk,
+	&sh4202_femi_clk,
+	&sh4202_shoc_clk,
+};
+
+static int __init sh4202_clk_init(void)
+{
+	struct clk *clk = clk_get("master_clk");
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
+		struct clk *clkp = sh4202_onchip_clocks[i];
+
+		clkp->parent = clk;
+		clk_register(clkp);
+		clk_enable(clkp);
+	}
+
+	/*
+	 * Now that we have the rest of the clocks registered, we need to
+	 * force the parent clock to propagate so that these clocks will
+	 * automatically figure out their rate. We cheat by handing the
+	 * parent clock its current rate and forcing child propagation.
+	 */
+	clk_set_rate(clk, clk_get_rate(clk));
+
+	clk_put(clk);
+
+	return 0;
+}
+
+arch_initcall(sh4202_clk_init);
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4.c sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh4.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,80 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh4.c
+ *
+ * Generic SH-4 support for the clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * FRQCR parsing hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
+#define bfc_divisors ifc_divisors	/* Same */
+static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007];
+}
+
+static struct clk_ops sh4_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) & 0x0007);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh4_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007;
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh4_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007;
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh4_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh4_clk_ops[] = {
+	&sh4_master_clk_ops,
+	&sh4_module_clk_ops,
+	&sh4_bus_clk_ops,
+	&sh4_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh4_clk_ops))
+		*ops = sh4_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh73180.c sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh73180.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh73180.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh73180.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,81 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh73180.c
+ *
+ * SH73180 support for the clock framework
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * FRQCR parsing hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+/*
+ * SH73180 uses a common set of divisors, so this is quite simple..
+ */
+static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007];
+}
+
+static struct clk_ops sh73180_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) & 0x0007);
+	clk->rate = clk->parent->rate / divisors[idx];
+}
+
+static struct clk_ops sh73180_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007;
+	clk->rate = clk->parent->rate / divisors[idx];
+}
+
+static struct clk_ops sh73180_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007;
+	clk->rate = clk->parent->rate / divisors[idx];
+}
+
+static struct clk_ops sh73180_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh73180_clk_ops[] = {
+	&sh73180_master_clk_ops,
+	&sh73180_module_clk_ops,
+	&sh73180_bus_clk_ops,
+	&sh73180_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh73180_clk_ops))
+		*ops = sh73180_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7770.c sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7770.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7770.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7770.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,73 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh7770.c
+ *
+ * SH7770 support for the clock framework
+ *
+ *  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>
+
+static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
+static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 };
+static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f];
+}
+
+static struct clk_ops sh7770_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7770_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) & 0x000f);
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7770_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f);
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7770_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7770_clk_ops[] = {
+	&sh7770_master_clk_ops,
+	&sh7770_module_clk_ops,
+	&sh7770_bus_clk_ops,
+	&sh7770_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7770_clk_ops))
+		*ops = sh7770_clk_ops[idx];
+}
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7780.c sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7780.c
--- linux-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7780.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/cpu/sh4/clock-sh7780.c	2006-01-04 00:15:27.000000000 +0200
@@ -0,0 +1,126 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh7780.c
+ *
+ * SH7780 support for the clock framework
+ *
+ *  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>
+
+static int ifc_divisors[] = { 2, 4 };
+static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 };
+static int pfc_divisors[] = { 1, 24, 24, 1 };
+static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003];
+}
+
+static struct clk_ops sh7780_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) & 0x0003);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7780_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007);
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7780_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001);
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7780_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7780_clk_ops[] = {
+	&sh7780_master_clk_ops,
+	&sh7780_module_clk_ops,
+	&sh7780_bus_clk_ops,
+	&sh7780_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7780_clk_ops))
+		*ops = sh7780_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007);
+	clk->rate = clk->parent->rate / cfc_divisors[idx];
+}
+
+static struct clk_ops sh7780_shyway_clk_ops = {
+	.recalc		= shyway_clk_recalc,
+};
+
+static struct clk sh7780_shyway_clk = {
+	.name		= "shyway_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh7780_shyway_clk_ops,
+};
+
+/*
+ * Additional SH7780-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7780_onchip_clocks[] = {
+	&sh7780_shyway_clk,
+};
+
+static int __init sh7780_clk_init(void)
+{
+	struct clk *clk = clk_get("master_clk");
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
+		struct clk *clkp = sh7780_onchip_clocks[i];
+
+		clkp->parent = clk;
+		clk_register(clkp);
+		clk_enable(clkp);
+	}
+
+	/*
+	 * Now that we have the rest of the clocks registered, we need to
+	 * force the parent clock to propagate so that these clocks will
+	 * automatically figure out their rate. We cheat by handing the
+	 * parent clock its current rate and forcing child propagation.
+	 */
+	clk_set_rate(clk, clk_get_rate(clk));
+
+	clk_put(clk);
+
+	return 0;
+}
+
+arch_initcall(sh7780_clk_init);
+

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/time.c sh-2.6.15/arch/sh/kernel/time.c
--- linux-2.6.15/arch/sh/kernel/time.c	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/time.c	2006-01-04 00:15:28.000000000 +0200
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
  *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
- *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002, 2003, 2004, 2005  Paul Mundt
  *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
  *
  *  Some code taken from i386 version.
@@ -11,50 +11,21 @@
  */
 
 #include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/profile.h>
-
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/delay.h>
-#include <asm/machvec.h>
+#include <asm/clock.h>
 #include <asm/rtc.h>
-#include <asm/freq.h>
-#include <asm/cpu/timer.h>
-#ifdef CONFIG_SH_KGDB
+#include <asm/timer.h>
 #include <asm/kgdb.h>
-#endif
-
-#include <linux/timex.h>
-#include <linux/irq.h>
-
-#define TMU_TOCR_INIT	0x00
-#define TMU0_TCR_INIT	0x0020
-#define TMU_TSTR_INIT	1
-
-#define TMU0_TCR_CALIB	0x0000
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-#define CLOCKGEN_MEMCLKCR 0xbb040038
-#define MEMCLKCR_RATIO_MASK 0x7
-#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
 
 extern unsigned long wall_jiffies;
-#define TICK_SIZE (tick_nsec / 1000)
-DEFINE_SPINLOCK(tmu0_lock);
+struct sys_timer *sys_timer;
+
+/* Move this somewhere more sensible.. */
+DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
 
 /* XXX: Can we initialize this in a routine somewhere?  Dreamcast doesn't want
  * these routines anywhere... */
@@ -66,98 +37,14 @@
 int (*rtc_set_time)(const time_t);
 #endif
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 };
-#endif
-#if defined(CONFIG_CPU_SH3)
-static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
-static int stc_values[]      = { 0, 1, 4, 2, 5, 0, 0, 0 };
-#define bfc_divisors stc_multipliers
-#define bfc_values stc_values
-static int ifc_divisors[]    = { 1, 2, 3, 4, 1, 1, 1, 1 };
-static int ifc_values[]      = { 0, 1, 4, 2, 0, 0, 0, 0 };
-static int pfc_divisors[]    = { 1, 2, 3, 4, 6, 1, 1, 1 };
-static int pfc_values[]      = { 0, 1, 4, 2, 5, 0, 0, 0 };
-#elif defined(CONFIG_CPU_SH4)
-#if defined(CONFIG_CPU_SUBTYPE_SH73180)
-static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 };
-static int ifc_values[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
-#define bfc_divisors ifc_divisors	/* Same */
-#define bfc_values ifc_values
-#define pfc_divisors ifc_divisors	/* Same */
-#define pfc_values ifc_values
-#else
-static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
-static int ifc_values[]   = { 0, 1, 2, 3, 0, 4, 0, 5 };
-#define bfc_divisors ifc_divisors	/* Same */
-#define bfc_values ifc_values
-static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
-static int pfc_values[]   = { 0, 0, 1, 2, 0, 3, 0, 4 };
-#endif
-#else
-#error "Unknown ifc/bfc/pfc/stc values for this processor"
-#endif
-
 /*
  * Scheduler clock - returns current time in nanosec units.
  */
-unsigned long long sched_clock(void)
+unsigned long long __attribute__ ((weak)) sched_clock(void)
 {
 	return (unsigned long long)jiffies * (1000000000 / HZ);
 }
 
-static unsigned long do_gettimeoffset(void)
-{
-	int count;
-	unsigned long flags;
-
-	static int count_p = 0x7fffffff;    /* for the first call after boot */
-	static unsigned long jiffies_p = 0;
-
-	/*
-	 * cache volatile jiffies temporarily; we have IRQs turned off.
-	 */
-	unsigned long jiffies_t;
-
-	spin_lock_irqsave(&tmu0_lock, flags);
-	/* timer count may underflow right here */
-	count = ctrl_inl(TMU0_TCNT);	/* read the latched count */
-
-	jiffies_t = jiffies;
-
-	/*
-	 * avoiding timer inconsistencies (they are rare, but they happen)...
-	 * there is one kind of problem that must be avoided here:
-	 *  1. the timer counter underflows
-	 */
-
-	if( jiffies_t == jiffies_p ) {
-		if( count > count_p ) {
-			/* the nutcase */
-
-			if(ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */
-				/*
-				 * We cannot detect lost timer interrupts ...
-				 * well, that's why we call them lost, don't we? :)
-				 * [hmm, on the Pentium and Alpha we can ... sort of]
-				 */
-				count -= LATCH;
-			} else {
-				printk("do_slow_gettimeoffset(): hardware timer problem?\n");
-			}
-		}
-	} else
-		jiffies_p = jiffies_t;
-
-	count_p = count;
-	spin_unlock_irqrestore(&tmu0_lock, flags);
-
-	count = ((LATCH-1) - count) * TICK_SIZE;
-	count = (count + LATCH/2) / LATCH;
-
-	return count;
-}
-
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long seq;
@@ -166,7 +53,7 @@
 
 	do {
 		seq = read_seqbegin(&xtime_lock);
-		usec = do_gettimeoffset();
+		usec = get_timer_offset();
 
 		lost = jiffies - wall_jiffies;
 		if (lost)
@@ -202,7 +89,7 @@
 	 * wall time.  Discover what correction gettimeofday() would have
 	 * made, and then undo it!
 	 */
-	nsec -= 1000 * (do_gettimeoffset() +
+	nsec -= 1000 * (get_timer_offset() +
 				(jiffies - wall_jiffies) * (1000000 / HZ));
 
 	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
@@ -224,10 +111,10 @@
 static long last_rtc_update;
 
 /*
- * timer_interrupt() needs to keep up the real-time clock,
+ * handle_timer_tick() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void do_timer_interrupt(int irq, struct pt_regs *regs)
+void handle_timer_tick(struct pt_regs *regs)
 {
 	do_timer(regs);
 #ifndef CONFIG_SMP
@@ -252,337 +139,35 @@
 		if (rtc_set_time(xtime.tv_sec) == 0)
 			last_rtc_update = xtime.tv_sec;
 		else
-			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+			/* do it again in 60s */
+			last_rtc_update = xtime.tv_sec - 600;
 	}
 }
 
-/*
- * This is the same as the above, except we _also_ save the current
- * Time Stamp Counter value at the time of the timer interrupt, so that
- * we later on can estimate the time of day more exactly.
- */
-static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned long timer_status;
-
-	/* Clear UNF bit */
-	timer_status = ctrl_inw(TMU0_TCR);
-	timer_status &= ~0x100;
-	ctrl_outw(timer_status, TMU0_TCR);
-
-	/*
-	 * 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
-	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
-	 * the irq version of write_lock because as just said we have irq
-	 * locally disabled. -arca
-	 */
-	write_seqlock(&xtime_lock);
-	do_timer_interrupt(irq, regs);
-	write_sequnlock(&xtime_lock);
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Hah!  We'll see if this works (switching from usecs to nsecs).
- */
-static unsigned int __init get_timer_frequency(void)
-{
-	u32 freq;
-	struct timespec ts1, ts2;
-	unsigned long diff_nsec;
-	unsigned long factor;
-
-	/* Setup the timer:  We don't want to generate interrupts, just
-	 * have it count down at its natural rate.
-	 */
-	ctrl_outb(0, TMU_TSTR);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
-	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
-#endif
-	ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
-	ctrl_outl(0xffffffff, TMU0_TCOR);
-	ctrl_outl(0xffffffff, TMU0_TCNT);
-
-	rtc_get_time(&ts2);
-
-	do {
-		rtc_get_time(&ts1);
-	} while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
-
-	/* actually start the timer */
-	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
-
-	do {
-		rtc_get_time(&ts2);
-	} while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
-
-	freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
-	if (ts2.tv_nsec < ts1.tv_nsec) {
-		ts2.tv_nsec += 1000000000;
-		ts2.tv_sec--;
-	}
-
-	diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec);
-
-	/* this should work well if the RTC has a precision of n Hz, where
-	 * n is an integer.  I don't think we have to worry about the other
-	 * cases. */
-	factor = (1000000000 + diff_nsec/2) / diff_nsec;
-
-	if (factor * diff_nsec > 1100000000 ||
-	    factor * diff_nsec <  900000000)
-		panic("weird RTC (diff_nsec %ld)", diff_nsec);
-
-	return freq * factor;
-}
-
-void (*board_time_init)(void);
-void (*board_timer_setup)(struct irqaction *irq);
-
-static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ;
-
-static int __init sh_pclk_setup(char *str)
-{
-        unsigned int freq;
-
-	if (get_option(&str, &freq))
-		sh_pclk_freq = freq;
-
-	return 1;
-}
-__setup("sh_pclk=", sh_pclk_setup);
-
-static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL};
-
-void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc)
-{
-	unsigned int frqcr = ctrl_inw(FRQCR);
-
-#if defined(CONFIG_CPU_SH3)
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-	*ifc = md_table[((frqcr & 0x0070) >> 4)];
-	*bfc = md_table[((frqcr & 0x0700) >> 8)];
-	*pfc = md_table[frqcr & 0x0007];
-#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
-	*bfc = stc_multipliers[(frqcr & 0x0300) >> 8];
-	*ifc = ifc_divisors[(frqcr & 0x0030) >> 4];
-	*pfc = pfc_divisors[frqcr & 0x0003];
-#else
-	unsigned int tmp;
-
-	tmp  = (frqcr & 0x8000) >> 13;
-	tmp |= (frqcr & 0x0030) >>  4;
-	*bfc = stc_multipliers[tmp];
-	tmp  = (frqcr & 0x4000)  >> 12;
-	tmp |= (frqcr & 0x000c) >> 2;
-	*ifc = ifc_divisors[tmp];
-	tmp  = (frqcr & 0x2000) >> 11;
-	tmp |= frqcr & 0x0003;
-	*pfc = pfc_divisors[tmp];
-#endif
-#elif defined(CONFIG_CPU_SH4)
-#if defined(CONFIG_CPU_SUBTYPE_SH73180)
-	*ifc = ifc_divisors[(frqcr>> 20) & 0x0007];
-	*bfc = bfc_divisors[(frqcr>> 12) & 0x0007];
-	*pfc = pfc_divisors[frqcr & 0x0007];
-#else
-	*ifc = ifc_divisors[(frqcr >> 6) & 0x0007];
-	*bfc = bfc_divisors[(frqcr >> 3) & 0x0007];
-	*pfc = pfc_divisors[frqcr & 0x0007];
-#endif
-#endif
-}
-
-/*
- * This bit of ugliness builds up accessor routines to get at both
- * the divisors and the physical values.
- */
-#define _FREQ_TABLE(x) \
-	unsigned int get_##x##_divisor(unsigned int value)	\
-		{ return x##_divisors[value]; }			\
-								\
-	unsigned int get_##x##_value(unsigned int divisor)	\
-		{ return x##_values[(divisor - 1)]; }
-
-_FREQ_TABLE(ifc);
-_FREQ_TABLE(bfc);
-_FREQ_TABLE(pfc);
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-
-/*
- * The ST40 divisors are totally different so we set the cpu data
- * clocks using a different algorithm
- *
- * I've just plugged this from the 2.4 code
- *	- Alex Bennee <kernel-hacker@bennee.com>
- */
-#define CCN_PVR_CHIP_SHIFT 24
-#define CCN_PVR_CHIP_MASK  0xff
-#define CCN_PVR_CHIP_ST40STB1 0x4
-
-
-struct frqcr_data {
-	unsigned short frqcr;
-
-	struct {
-		unsigned char multiplier;
-		unsigned char divisor;
-	} factor[3];
+static struct sysdev_class timer_sysclass = {
+	set_kset_name("timer"),
 };
 
-static struct frqcr_data st40_frqcr_table[] = {
-	{ 0x000, {{1,1}, {1,1}, {1,2}}},
-	{ 0x002, {{1,1}, {1,1}, {1,4}}},
-	{ 0x004, {{1,1}, {1,1}, {1,8}}},
-	{ 0x008, {{1,1}, {1,2}, {1,2}}},
-	{ 0x00A, {{1,1}, {1,2}, {1,4}}},
-	{ 0x00C, {{1,1}, {1,2}, {1,8}}},
-	{ 0x011, {{1,1}, {2,3}, {1,6}}},
-	{ 0x013, {{1,1}, {2,3}, {1,3}}},
-	{ 0x01A, {{1,1}, {1,2}, {1,4}}},
-	{ 0x01C, {{1,1}, {1,2}, {1,8}}},
-	{ 0x023, {{1,1}, {2,3}, {1,3}}},
-	{ 0x02C, {{1,1}, {1,2}, {1,8}}},
-	{ 0x048, {{1,2}, {1,2}, {1,4}}},
-	{ 0x04A, {{1,2}, {1,2}, {1,6}}},
-	{ 0x04C, {{1,2}, {1,2}, {1,8}}},
-	{ 0x05A, {{1,2}, {1,3}, {1,6}}},
-	{ 0x05C, {{1,2}, {1,3}, {1,6}}},
-	{ 0x063, {{1,2}, {1,4}, {1,4}}},
-	{ 0x06C, {{1,2}, {1,4}, {1,8}}},
-	{ 0x091, {{1,3}, {1,3}, {1,6}}},
-	{ 0x093, {{1,3}, {1,3}, {1,6}}},
-	{ 0x0A3, {{1,3}, {1,6}, {1,6}}},
-	{ 0x0DA, {{1,4}, {1,4}, {1,8}}},
-	{ 0x0DC, {{1,4}, {1,4}, {1,8}}},
-	{ 0x0EC, {{1,4}, {1,8}, {1,8}}},
-	{ 0x123, {{1,4}, {1,4}, {1,8}}},
-	{ 0x16C, {{1,4}, {1,8}, {1,8}}},
-};
-
-struct memclk_data {
-	unsigned char multiplier;
-	unsigned char divisor;
-};
-
-static struct memclk_data st40_memclk_table[8] = {
-	{1,1},	// 000
-	{1,2},	// 001
-	{1,3},	// 010
-	{2,3},	// 011
-	{1,4},	// 100
-	{1,6},	// 101
-	{1,8},	// 110
-	{1,8}	// 111
-};
-
-static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr)
+static int __init timer_init_sysfs(void)
 {
-	unsigned int cpu_clock, master_clock, bus_clock, memory_clock;
-	struct frqcr_data *d;
-	int a;
-	unsigned long memclkcr;
-	struct memclk_data *e;
-
-	for (a = 0; a < ARRAY_SIZE(st40_frqcr_table); a++) {
-		d = &st40_frqcr_table[a];
-
-		if (d->frqcr == (frqcr & 0x1ff))
-			break;
-	}
-
-	if (a == ARRAY_SIZE(st40_frqcr_table)) {
-		d = st40_frqcr_table;
+	int ret = sysdev_class_register(&timer_sysclass);
+	if (ret != 0)
+		return ret;
 
-		printk("ERROR: Unrecognised FRQCR value (0x%x), "
-		       "using default multipliers\n", frqcr);
-	}
+	sys_timer->dev.cls = &timer_sysclass;
+	return sysdev_register(&sys_timer->dev);
+}
 
-	memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
-	e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
+device_initcall(timer_init_sysfs);
 
-	printk(KERN_INFO "Clock multipliers: CPU: %d/%d Bus: %d/%d "
-	       "Mem: %d/%d Periph: %d/%d\n",
-	       d->factor[0].multiplier, d->factor[0].divisor,
-	       d->factor[1].multiplier, d->factor[1].divisor,
-	       e->multiplier,           e->divisor,
-	       d->factor[2].multiplier, d->factor[2].divisor);
-
-	master_clock = module_clock * d->factor[2].divisor
-				    / d->factor[2].multiplier;
-	bus_clock    = master_clock * d->factor[1].multiplier
-				    / d->factor[1].divisor;
-	memory_clock = master_clock * e->multiplier
-				    / e->divisor;
-	cpu_clock    = master_clock * d->factor[0].multiplier
-				    / d->factor[0].divisor;
-
-	current_cpu_data.cpu_clock    = cpu_clock;
-	current_cpu_data.master_clock = master_clock;
-	current_cpu_data.bus_clock    = bus_clock;
-	current_cpu_data.memory_clock = memory_clock;
-	current_cpu_data.module_clock = module_clock;
-}
-#endif
+void (*board_time_init)(void);
 
 void __init time_init(void)
 {
-	unsigned int timer_freq = 0;
-	unsigned int ifc, pfc, bfc;
-	unsigned long interval;
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	unsigned long pvr;
-	unsigned short frqcr;
-#endif
-
 	if (board_time_init)
 		board_time_init();
 
-	/*
-	 * If we don't have an RTC (such as with the SH7300), don't attempt to
-	 * probe the timer frequency. Rely on an either hardcoded peripheral
-	 * clock value, or on the sh_pclk command line option. Note that we
-	 * still need to have CONFIG_SH_PCLK_FREQ set in order for things like
-	 * CLOCK_TICK_RATE to be sane.
-	 */
-	current_cpu_data.module_clock = sh_pclk_freq;
-
-#ifdef CONFIG_SH_PCLK_CALC
-	/* XXX: Switch this over to a more generic test. */
-	{
-		unsigned int freq;
-
-		/*
-		 * If we've specified a peripheral clock frequency, and we have
-		 * an RTC, compare it against the autodetected value. Complain
-		 * if there's a mismatch.
-		 */
-		timer_freq = get_timer_frequency();
-		freq = timer_freq * 4;
-
-		if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) {
-			printk(KERN_NOTICE "Calculated peripheral clock value "
-			       "%d differs from sh_pclk value %d, fixing..\n",
-			       freq, sh_pclk_freq);
-			current_cpu_data.module_clock = freq;
-		}
-	}
-#endif
-
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	/* XXX: Update ST40 code to use board_time_init() */
-	pvr = ctrl_inl(CCN_PVR);
-	frqcr = ctrl_inw(FRQCR);
-	printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr);
-
-	if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1)
-		st40_specific_time_init(current_cpu_data.module_clock, frqcr);
-	else
-#endif
-		get_current_frequency_divisors(&ifc, &bfc, &pfc);
+	clk_init();
 
 	if (rtc_get_time) {
 		rtc_get_time(&xtime);
@@ -594,51 +179,12 @@
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
 
-	if (board_timer_setup) {
-		board_timer_setup(&irq0);
-	} else {
-		setup_irq(TIMER_IRQ, &irq0);
-	}
-
 	/*
-	 * for ST40 chips the current_cpu_data should already be set
-	 * so not having valid pfc/bfc/ifc shouldn't be a problem
+	 * Find the timer to use as the system timer, it will be
+	 * initialized for us.
 	 */
-	if (!current_cpu_data.master_clock)
-		current_cpu_data.master_clock = current_cpu_data.module_clock * pfc;
-	if (!current_cpu_data.bus_clock)
-		current_cpu_data.bus_clock = current_cpu_data.master_clock / bfc;
-	if (!current_cpu_data.cpu_clock)
-		current_cpu_data.cpu_clock = current_cpu_data.master_clock / ifc;
-
-	printk("CPU clock: %d.%02dMHz\n",
-	       (current_cpu_data.cpu_clock / 1000000),
-	       (current_cpu_data.cpu_clock % 1000000)/10000);
-	printk("Bus clock: %d.%02dMHz\n",
-	       (current_cpu_data.bus_clock / 1000000),
-	       (current_cpu_data.bus_clock % 1000000)/10000);
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	printk("Memory clock: %d.%02dMHz\n",
-	       (current_cpu_data.memory_clock / 1000000),
-	       (current_cpu_data.memory_clock % 1000000)/10000);
-#endif
-	printk("Module clock: %d.%02dMHz\n",
-	       (current_cpu_data.module_clock / 1000000),
-	       (current_cpu_data.module_clock % 1000000)/10000);
-
-	interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ;
-
-	printk("Interval = %ld\n", interval);
-
-	/* Start TMU0 */
-	ctrl_outb(0, TMU_TSTR);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
-	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
-#endif
-	ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
-	ctrl_outl(interval, TMU0_TCOR);
-	ctrl_outl(interval, TMU0_TCNT);
-	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+	sys_timer = get_sys_timer();
+	printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
 
 #if defined(CONFIG_SH_KGDB)
 	/*


diff -urN -X exclude linux-2.6.15/arch/sh/boards/overdrive/Makefile sh-2.6.15/arch/sh/boards/overdrive/Makefile
--- linux-2.6.15/arch/sh/boards/overdrive/Makefile	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/overdrive/Makefile	2006-01-04 00:15:26.000000000 +0200
@@ -2,7 +2,7 @@
 # Makefile for the STMicroelectronics Overdrive specific parts of the kernel
 #
 
-obj-y	 := mach.o setup.o io.o irq.o led.o time.o
+obj-y	 := mach.o setup.o io.o irq.o led.o
 
 obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o
 
diff -urN -X exclude linux-2.6.15/arch/sh/boards/overdrive/setup.c sh-2.6.15/arch/sh/boards/overdrive/setup.c
--- linux-2.6.15/arch/sh/boards/overdrive/setup.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/overdrive/setup.c	2006-01-04 00:15:26.000000000 +0200
@@ -17,8 +17,6 @@
 #include <asm/overdrive/overdrive.h>
 #include <asm/overdrive/fpga.h>
 
-extern void od_time_init(void);
-
 const char *get_system_type(void)
 {
 	return "SH7750 Overdrive";
@@ -31,11 +29,9 @@
 {
 #ifdef CONFIG_PCI
 	init_overdrive_fpga();
-	galileo_init(); 
+	galileo_init();
 #endif
 
-	board_time_init = od_time_init;
-
         /* Enable RS232 receive buffers */
 	writel(0x1e, OVERDRIVE_CTRL);
 }
diff -urN -X exclude linux-2.6.15/arch/sh/boards/overdrive/time.c sh-2.6.15/arch/sh/boards/overdrive/time.c
--- linux-2.6.15/arch/sh/boards/overdrive/time.c	2004-07-15 22:21:13.000000000 +0300
+++ sh-2.6.15/arch/sh/boards/overdrive/time.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,119 +0,0 @@
-/*
- * arch/sh/boards/overdrive/time.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- * Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * STMicroelectronics Overdrive Support.
- */
-
-void od_time_init(void)
-{
-	struct frqcr_data {
-		unsigned short frqcr;
-		struct {
-			unsigned char multiplier;
-			unsigned char divisor;
-		} factor[3];
-	};
-
-	static struct frqcr_data st40_frqcr_table[] = {		
-		{ 0x000, {{1,1}, {1,1}, {1,2}}},
-		{ 0x002, {{1,1}, {1,1}, {1,4}}},
-		{ 0x004, {{1,1}, {1,1}, {1,8}}},
-		{ 0x008, {{1,1}, {1,2}, {1,2}}},
-		{ 0x00A, {{1,1}, {1,2}, {1,4}}},
-		{ 0x00C, {{1,1}, {1,2}, {1,8}}},
-		{ 0x011, {{1,1}, {2,3}, {1,6}}},
-		{ 0x013, {{1,1}, {2,3}, {1,3}}},
-		{ 0x01A, {{1,1}, {1,2}, {1,4}}},
-		{ 0x01C, {{1,1}, {1,2}, {1,8}}},
-		{ 0x023, {{1,1}, {2,3}, {1,3}}},
-		{ 0x02C, {{1,1}, {1,2}, {1,8}}},
-		{ 0x048, {{1,2}, {1,2}, {1,4}}},
-		{ 0x04A, {{1,2}, {1,2}, {1,6}}},
-		{ 0x04C, {{1,2}, {1,2}, {1,8}}},
-		{ 0x05A, {{1,2}, {1,3}, {1,6}}},
-		{ 0x05C, {{1,2}, {1,3}, {1,6}}},
-		{ 0x063, {{1,2}, {1,4}, {1,4}}},
-		{ 0x06C, {{1,2}, {1,4}, {1,8}}},
-		{ 0x091, {{1,3}, {1,3}, {1,6}}},
-		{ 0x093, {{1,3}, {1,3}, {1,6}}},
-		{ 0x0A3, {{1,3}, {1,6}, {1,6}}},
-		{ 0x0DA, {{1,4}, {1,4}, {1,8}}},
-		{ 0x0DC, {{1,4}, {1,4}, {1,8}}},
-		{ 0x0EC, {{1,4}, {1,8}, {1,8}}},
-		{ 0x123, {{1,4}, {1,4}, {1,8}}},
-		{ 0x16C, {{1,4}, {1,8}, {1,8}}},
-	};
-
-	struct memclk_data {
-		unsigned char multiplier;
-		unsigned char divisor;
-	};
-	static struct memclk_data st40_memclk_table[8] = {
-		{1,1},	// 000
-		{1,2},	// 001
-		{1,3},	// 010
-		{2,3},	// 011
-		{1,4},	// 100
-		{1,6},	// 101
-		{1,8},	// 110
-		{1,8}	// 111
-	};
-
-	unsigned long pvr;
-
-	/* 
-	 * This should probably be moved into the SH3 probing code, and then
-	 * use the processor structure to determine which CPU we are running
-	 * on.
-	 */
-	pvr = ctrl_inl(CCN_PVR);
-	printk("PVR %08x\n", pvr);
-
-	if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) {
-		/* 
-		 * Unfortunatly the STB1 FRQCR values are different from the
-		 * 7750 ones.
-		 */
-		struct frqcr_data *d;
-		int a;
-		unsigned long memclkcr;
-		struct memclk_data *e;
-
-		for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
-			d = &st40_frqcr_table[a];
-			if (d->frqcr == (frqcr & 0x1ff))
-				break;
-		}
-		if (a == ARRAY_SIZE(st40_frqcr_table)) {
-			d = st40_frqcr_table;
-			printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
-		}
-
-		memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
-		e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
-
-		printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
-		       d->factor[0].multiplier, d->factor[0].divisor,
-		       d->factor[1].multiplier, d->factor[1].divisor,
-		       e->multiplier,           e->divisor,
-		       d->factor[2].multiplier, d->factor[2].divisor);
-		
-		current_cpu_data.master_clock = current_cpu_data.module_clock *
-						d->factor[2].divisor /
-						d->factor[2].multiplier;
-		current_cpu_data.bus_clock    = current_cpu_data.master_clock *
-						d->factor[1].multiplier /
-						d->factor[1].divisor;
-		current_cpu_data.memory_clock = current_cpu_data.master_clock *
-						e->multiplier / e->divisor;
-		current_cpu_data.cpu_clock    = current_cpu_data.master_clock *
-						d->factor[0].multiplier /
-						d->factor[0].divisor;
-}
-
diff -urN -X exclude linux-2.6.15/include/asm-sh/clock.h sh-2.6.15/include/asm-sh/clock.h
--- linux-2.6.15/include/asm-sh/clock.h	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/include/asm-sh/clock.h	2006-01-04 00:15:30.000000000 +0200
@@ -0,0 +1,61 @@
+#ifndef __ASM_SH_CLOCK_H
+#define __ASM_SH_CLOCK_H
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+
+struct clk;
+
+struct clk_ops {
+	void (*init)(struct clk *clk);
+	void (*enable)(struct clk *clk);
+	void (*disable)(struct clk *clk);
+	void (*recalc)(struct clk *clk);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+};
+
+struct clk {
+	struct list_head	node;
+	const char		*name;
+
+	struct module		*owner;
+
+	struct clk		*parent;
+	struct clk_ops		*ops;
+
+	struct kref		kref;
+
+	unsigned long		rate;
+	unsigned long		flags;
+};
+
+#define CLK_ALWAYS_ENABLED	(1 << 0)
+#define CLK_RATE_PROPAGATES	(1 << 1)
+
+/* Should be defined by processor-specific code */
+void arch_init_clk_ops(struct clk_ops **, int type);
+
+/* arch/sh/kernel/cpu/clock.c */
+int clk_init(void);
+
+int __clk_enable(struct clk *);
+int clk_enable(struct clk *);
+
+void __clk_disable(struct clk *);
+void clk_disable(struct clk *);
+
+int clk_set_rate(struct clk *, unsigned long rate);
+unsigned long clk_get_rate(struct clk *);
+void clk_recalc_rate(struct clk *);
+
+struct clk *clk_get(const char *id);
+void clk_put(struct clk *);
+
+int clk_register(struct clk *);
+void clk_unregister(struct clk *);
+
+int show_clocks(struct seq_file *m);
+
+#endif /* __ASM_SH_CLOCK_H */
+
diff -urN -X exclude linux-2.6.15/include/asm-sh/cpu-sh4/freq.h sh-2.6.15/include/asm-sh/cpu-sh4/freq.h
--- linux-2.6.15/include/asm-sh/cpu-sh4/freq.h	2004-12-26 05:37:56.000000000 +0200
+++ sh-2.6.15/include/asm-sh/cpu-sh4/freq.h	2006-01-04 00:15:29.000000000 +0200
@@ -12,6 +12,8 @@
 
 #if defined(CONFIG_CPU_SUBTYPE_SH73180)
 #define FRQCR		        0xa4150000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define	FRQCR			0xffc80000
 #else
 #define FRQCR			0xffc00000
 #endif


diff -urN -X exclude linux-2.6.15/include/asm-sh/freq.h sh-2.6.15/include/asm-sh/freq.h
--- linux-2.6.15/include/asm-sh/freq.h	2004-12-26 05:37:56.000000000 +0200
+++ sh-2.6.15/include/asm-sh/freq.h	2006-01-04 00:15:29.000000000 +0200
@@ -14,16 +14,5 @@
 
 #include <asm/cpu/freq.h>
 
-/* arch/sh/kernel/time.c */
-extern void get_current_frequency_divisors(unsigned int *ifc, unsigned int *pfc, unsigned int *bfc);
-
-extern unsigned int get_ifc_divisor(unsigned int value);
-extern unsigned int get_ifc_divisor(unsigned int value);
-extern unsigned int get_ifc_divisor(unsigned int value);
-
-extern unsigned int get_ifc_value(unsigned int divisor);
-extern unsigned int get_pfc_value(unsigned int divisor);
-extern unsigned int get_bfc_value(unsigned int divisor);
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_FREQ_H */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/8] sh: Simple timer framework.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
                   ` (5 preceding siblings ...)
  2006-01-14 22:55 ` [PATCH 6/8] sh: Simplistic clock framework Paul Mundt
@ 2006-01-14 22:55 ` Paul Mundt
  2006-01-14 22:56 ` [PATCH 8/8] sh: Move CPU subtype configuration to its own Kconfig Paul Mundt
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:55 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

This builds on some of the clock framework code to support a simple
system timer interface.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 arch/sh/kernel/timers/Makefile    |    8 +
 arch/sh/kernel/timers/timer-tmu.c |  229 ++++++++++++++++++++++++++++++++++++++
 arch/sh/kernel/timers/timer.c     |   50 ++++++++
 include/asm-sh/timer.h            |   42 ++++++
 4 files changed, 329 insertions(+)

diff -urN -X exclude linux-2.6.15/arch/sh/kernel/timers/Makefile sh-2.6.15/arch/sh/kernel/timers/Makefile
--- linux-2.6.15/arch/sh/kernel/timers/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/timers/Makefile	2006-01-04 00:15:28.000000000 +0200
@@ -0,0 +1,8 @@
+#
+# Makefile for the various Linux/SuperH timers
+#
+
+obj-y	:= timer.o
+
+obj-$(CONFIG_SH_TMU)		+= timer-tmu.o
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/timers/timer-tmu.c sh-2.6.15/arch/sh/kernel/timers/timer-tmu.c
--- linux-2.6.15/arch/sh/kernel/timers/timer-tmu.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/timers/timer-tmu.c	2006-01-04 00:15:28.000000000 +0200
@@ -0,0 +1,229 @@
+/*
+ * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support
+ *
+ *  Copyright (C) 2005  Paul Mundt
+ *
+ * TMU handling code hacked out of arch/sh/kernel/time.c
+ *
+ *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2002, 2003, 2004  Paul Mundt
+ *  Copyright (C) 2002  M. R. Brown  <mrbrown@linux-sh.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/seqlock.h>
+#include <asm/timer.h>
+#include <asm/rtc.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/clock.h>
+
+#define TMU_TOCR_INIT	0x00
+#define TMU0_TCR_INIT	0x0020
+#define TMU_TSTR_INIT	1
+
+#define TMU0_TCR_CALIB	0x0000
+
+static DEFINE_SPINLOCK(tmu0_lock);
+
+static unsigned long tmu_timer_get_offset(void)
+{
+	int count;
+	unsigned long flags;
+
+	static int count_p = 0x7fffffff;    /* for the first call after boot */
+	static unsigned long jiffies_p = 0;
+
+	/*
+	 * cache volatile jiffies temporarily; we have IRQs turned off.
+	 */
+	unsigned long jiffies_t;
+
+	spin_lock_irqsave(&tmu0_lock, flags);
+	/* timer count may underflow right here */
+	count = ctrl_inl(TMU0_TCNT);	/* read the latched count */
+
+	jiffies_t = jiffies;
+
+	/*
+	 * avoiding timer inconsistencies (they are rare, but they happen)...
+	 * there is one kind of problem that must be avoided here:
+	 *  1. the timer counter underflows
+	 */
+
+	if (jiffies_t == jiffies_p) {
+		if (count > count_p) {
+			/* the nutcase */
+			if (ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */
+				count -= LATCH;
+			} else {
+				printk("%s (): hardware timer problem?\n",
+				       __FUNCTION__);
+			}
+		}
+	} else
+		jiffies_p = jiffies_t;
+
+	count_p = count;
+	spin_unlock_irqrestore(&tmu0_lock, flags);
+
+	count = ((LATCH-1) - count) * TICK_SIZE;
+	count = (count + LATCH/2) / LATCH;
+
+	return count;
+}
+
+static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id,
+				       struct pt_regs *regs)
+{
+	unsigned long timer_status;
+
+	/* Clear UNF bit */
+	timer_status = ctrl_inw(TMU0_TCR);
+	timer_status &= ~0x100;
+	ctrl_outw(timer_status, TMU0_TCR);
+
+	/*
+	 * 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
+	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+	 * the irq version of write_lock because as just said we have irq
+	 * locally disabled. -arca
+	 */
+	write_seqlock(&xtime_lock);
+	handle_timer_tick(regs);
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction tmu_irq = {
+	.name		= "timer",
+	.handler	= tmu_timer_interrupt,
+	.flags		= SA_INTERRUPT,
+	.mask		= CPU_MASK_NONE,
+};
+
+/*
+ * Hah!  We'll see if this works (switching from usecs to nsecs).
+ */
+static unsigned long tmu_timer_get_frequency(void)
+{
+	u32 freq;
+	struct timespec ts1, ts2;
+	unsigned long diff_nsec;
+	unsigned long factor;
+
+	/* Setup the timer:  We don't want to generate interrupts, just
+	 * have it count down at its natural rate.
+	 */
+	ctrl_outb(0, TMU_TSTR);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
+	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+#endif
+	ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
+	ctrl_outl(0xffffffff, TMU0_TCOR);
+	ctrl_outl(0xffffffff, TMU0_TCNT);
+
+	rtc_get_time(&ts2);
+
+	do {
+		rtc_get_time(&ts1);
+	} while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
+
+	/* actually start the timer */
+	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+
+	do {
+		rtc_get_time(&ts2);
+	} while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
+
+	freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
+	if (ts2.tv_nsec < ts1.tv_nsec) {
+		ts2.tv_nsec += 1000000000;
+		ts2.tv_sec--;
+	}
+
+	diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec);
+
+	/* this should work well if the RTC has a precision of n Hz, where
+	 * n is an integer.  I don't think we have to worry about the other
+	 * cases. */
+	factor = (1000000000 + diff_nsec/2) / diff_nsec;
+
+	if (factor * diff_nsec > 1100000000 ||
+	    factor * diff_nsec <  900000000)
+		panic("weird RTC (diff_nsec %ld)", diff_nsec);
+
+	return freq * factor;
+}
+
+static void tmu_clk_init(struct clk *clk)
+{
+	u8 divisor = TMU0_TCR_INIT & 0x7;
+	ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
+	clk->rate = clk->parent->rate / (4 << (divisor << 1));
+}
+
+static void tmu_clk_recalc(struct clk *clk)
+{
+	u8 divisor = ctrl_inw(TMU0_TCR) & 0x7;
+	clk->rate = clk->parent->rate / (4 << (divisor << 1));
+}
+
+static struct clk_ops tmu_clk_ops = {
+	.init		= tmu_clk_init,
+	.recalc		= tmu_clk_recalc,
+};
+
+static struct clk tmu0_clk = {
+	.name		= "tmu0_clk",
+	.ops		= &tmu_clk_ops,
+};
+
+static int tmu_timer_init(void)
+{
+	unsigned long interval;
+
+	setup_irq(TIMER_IRQ, &tmu_irq);
+
+	tmu0_clk.parent = clk_get("module_clk");
+
+	/* Start TMU0 */
+	ctrl_outb(0, TMU_TSTR);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
+	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+#endif
+
+	clk_register(&tmu0_clk);
+	clk_enable(&tmu0_clk);
+
+	interval = (clk_get_rate(&tmu0_clk) + HZ / 2) / HZ;
+	printk(KERN_INFO "Interval = %ld\n", interval);
+
+	ctrl_outl(interval, TMU0_TCOR);
+	ctrl_outl(interval, TMU0_TCNT);
+
+	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+
+	return 0;
+}
+
+struct sys_timer_ops tmu_timer_ops = {
+	.init		= tmu_timer_init,
+	.get_frequency	= tmu_timer_get_frequency,
+	.get_offset	= tmu_timer_get_offset,
+};
+
+struct sys_timer tmu_timer = {
+	.name	= "tmu",
+	.ops	= &tmu_timer_ops,
+};
+
diff -urN -X exclude linux-2.6.15/arch/sh/kernel/timers/timer.c sh-2.6.15/arch/sh/kernel/timers/timer.c
--- linux-2.6.15/arch/sh/kernel/timers/timer.c	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/kernel/timers/timer.c	2006-01-04 00:15:28.000000000 +0200
@@ -0,0 +1,50 @@
+/*
+ * arch/sh/kernel/timers/timer.c - Common timer code
+ *
+ *  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/kernel.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <asm/timer.h>
+
+static struct sys_timer *sys_timers[] __initdata = {
+#ifdef CONFIG_SH_TMU
+	&tmu_timer,
+#endif
+	NULL,
+};
+
+static char timer_override[10] __initdata;
+static int __init timer_setup(char *str)
+{
+	if (str)
+		strlcpy(timer_override, str, sizeof(timer_override));
+	return 1;
+}
+__setup("timer=", timer_setup);
+
+struct sys_timer *get_sys_timer(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sys_timers); i++) {
+		struct sys_timer *t = sys_timers[i];
+
+		if (unlikely(!t))
+			break;
+		if (unlikely(timer_override[0]))
+			if ((strcmp(timer_override, t->name) != 0))
+				continue;
+		if (likely(t->ops->init() == 0))
+			return t;
+	}
+
+	return NULL;
+}
+

diff -urN -X exclude linux-2.6.15/include/asm-sh/timer.h sh-2.6.15/include/asm-sh/timer.h
--- linux-2.6.15/include/asm-sh/timer.h	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/include/asm-sh/timer.h	2006-01-04 00:15:30.000000000 +0200
@@ -0,0 +1,42 @@
+#ifndef __ASM_SH_TIMER_H
+#define __ASM_SH_TIMER_H
+
+#include <linux/sysdev.h>
+#include <asm/cpu/timer.h>
+
+struct sys_timer_ops {
+	int (*init)(void);
+	unsigned long (*get_offset)(void);
+	unsigned long (*get_frequency)(void);
+};
+
+struct sys_timer {
+	const char		*name;
+
+	struct sys_device	dev;
+	struct sys_timer_ops	*ops;
+};
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+extern struct sys_timer tmu_timer;
+extern struct sys_timer *sys_timer;
+
+static inline unsigned long get_timer_offset(void)
+{
+	return sys_timer->ops->get_offset();
+}
+
+static inline unsigned long get_timer_frequency(void)
+{
+	return sys_timer->ops->get_frequency();
+}
+
+/* arch/sh/kernel/timers/timer.c */
+struct sys_timer *get_sys_timer(void);
+
+/* arch/sh/kernel/time.c */
+void handle_timer_tick(struct pt_regs *);
+
+#endif /* __ASM_SH_TIMER_H */
+

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/8] sh: Move CPU subtype configuration to its own Kconfig.
  2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
                   ` (6 preceding siblings ...)
  2006-01-14 22:55 ` [PATCH 7/8] sh: Simple timer framework Paul Mundt
@ 2006-01-14 22:56 ` Paul Mundt
  7 siblings, 0 replies; 9+ messages in thread
From: Paul Mundt @ 2006-01-14 22:56 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

Currently the CPU subtype options are cluttering up arch/sh/Kconfig
somewhat. Given that, this moves all of that in to its own
arch/sh/mm/Kconfig. Things like cache configuration are also moved to
this new location.

This also adds support for strict CPU tuning on newer cores, which
requires the addition of as-option.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

---

 Makefile              |    7 
 arch/sh/Kconfig       |  541 +++++++++++++++++++-------------------------------
 arch/sh/Kconfig.debug |    2 
 arch/sh/Makefile      |   60 +++--
 arch/sh/mm/Kconfig    |  233 +++++++++++++++++++++
 5 files changed, 491 insertions(+), 352 deletions(-)

diff -urN -X exclude linux-2.6.15/Makefile sh-2.6.15/Makefile
--- linux-2.6.15/Makefile	2006-01-04 14:19:56.000000000 +0200
+++ sh-2.6.15/Makefile	2006-01-04 14:25:43.000000000 +0200
@@ -280,6 +280,13 @@
 # cc support functions to be used (only) in arch/$(ARCH)/Makefile
 # See documentation in Documentation/kbuild/makefiles.txt
 
+# as-option
+# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,)
+
+as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
+	     -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
+	     else echo "$(2)"; fi ;)
+
 # cc-option
 # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
 
diff -urN -X exclude linux-2.6.15/arch/sh/Kconfig sh-2.6.15/arch/sh/Kconfig
--- linux-2.6.15/arch/sh/Kconfig	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/Kconfig	2006-01-07 22:20:41.249427831 +0200
@@ -37,9 +37,11 @@
 	bool
 	default y
 
+config GENERIC_IOMAP
+	bool
+
 config ARCH_MAY_HAVE_PC_FDC
 	bool
-	default y
 
 source "init/Kconfig"
 
@@ -57,24 +59,28 @@
 
 config SH_7751_SOLUTION_ENGINE
 	bool "SolutionEngine7751"
+	select CPU_SUBTYPE_SH7751
 	help
 	  Select 7751 SolutionEngine if configuring for a Hitachi SH7751
 	  evaluation board.
 
 config SH_7300_SOLUTION_ENGINE
 	bool "SolutionEngine7300"
+	select CPU_SUBTYPE_SH7300
 	help
 	  Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V)
 	  evaluation board.
 
 config SH_73180_SOLUTION_ENGINE
        bool "SolutionEngine73180"
+       select CPU_SUBTYPE_SH73180
        help
          Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3)
          evaluation board.
 
 config SH_7751_SYSTEMH
 	bool "SystemH7751R"
+	select CPU_SUBTYPE_SH7751R
 	help
 	  Select SystemH if you are configuring for a Renesas SystemH
 	  7751R evaluation board.
@@ -85,27 +91,13 @@
 config SH_STB1_OVERDRIVE
 	bool "STB1_Overdrive"
 
-config SH_HP620
-	bool "HP620"
+config SH_HP6XX
+	bool "HP6XX"
 	help
-	  Select HP620 if configuring for a HP jornada HP620.
+	  Select HP6XX if configuring for a HP jornada HP6xx.
 	  More information (hardware only) at
 	  <http://www.hp.com/jornada/>.
 
-config SH_HP680
-	bool "HP680"
-	help
-	  Select HP680 if configuring for a HP Jornada HP680.
-	  More information (hardware only) at
-	  <http://www.hp.com/jornada/products/680/>.
-
-config SH_HP690
-	bool "HP690"
-	help
-	  Select HP690 if configuring for a HP Jornada HP690.
-	  More information (hardware only)
-	  at <http://www.hp.com/jornada/products/680/>.
-
 config SH_CQREEK
 	bool "CqREEK"
 	help
@@ -127,11 +119,13 @@
 
 config SH_SATURN
 	bool "Saturn"
+	select CPU_SUBTYPE_SH7604
 	help
 	  Select Saturn if configuring for a SEGA Saturn.
 
 config SH_DREAMCAST
 	bool "Dreamcast"
+	select CPU_SUBTYPE_SH7091
 	help
 	  Select Dreamcast if configuring for a SEGA Dreamcast.
 	  More information at
@@ -146,6 +140,7 @@
 
 config SH_SH2000
 	bool "SH2000"
+	select CPU_SUBTYPE_SH7709
 	help
 	  SH-2000 is a single-board computer based around SH7709A chip
 	  intended for embedded applications.
@@ -157,20 +152,22 @@
 	bool "ADX"
 
 config SH_MPC1211
-	bool "MPC1211"
+	bool "Interface MPC1211"
+	help
+	  CTP/PCI-SH02 is a CPU module computer that is produced
+	  by Interface Corporation.
+	  More information at <http://www.interface.co.jp>
 
 config SH_SH03
-	bool "SH03"
+	bool "Interface CTP/PCI-SH03"
 	help
-	  CTP/PCI-SH03 is a CPU module computer that produced
+	  CTP/PCI-SH03 is a CPU module computer that is produced
 	  by Interface Corporation.
-	  It is compact and excellent in durability.
-	  It will play an active part in your factory or laboratory
-	  as a FA computer.
 	  More information at <http://www.interface.co.jp>
 
 config SH_SECUREEDGE5410
 	bool "SecureEdge5410"
+	select CPU_SUBTYPE_SH7751R
 	help
 	  Select SecureEdge5410 if configuring for a SnapGear SH board.
 	  This includes both the OEM SecureEdge products as well as the
@@ -178,25 +175,49 @@
 
 config SH_HS7751RVOIP
 	bool "HS7751RVOIP"
+	select CPU_SUBTYPE_SH7751R
 	help
 	  Select HS7751RVOIP if configuring for a Renesas Technology
 	  Sales VoIP board.
 
 config SH_RTS7751R2D
 	bool "RTS7751R2D"
+	select CPU_SUBTYPE_SH7751R
 	help
 	  Select RTS7751R2D if configuring for a Renesas Technology
 	  Sales SH-Graphics board.
 
+config SH_R7780RP
+	bool "R7780RP-1"
+	select CPU_SUBTYPE_SH7780
+	help
+	  Select R7780RP-1 if configuring for a Renesas Solutions
+	  HIGHLANDER board.
+
 config SH_EDOSK7705
 	bool "EDOSK7705"
+	select CPU_SUBTYPE_SH7705
 
 config SH_SH4202_MICRODEV
 	bool "SH4-202 MicroDev"
+	select CPU_SUBTYPE_SH4_202
 	help
 	  Select SH4-202 MicroDev if configuring for a SuperH MicroDev board
 	  with an SH4-202 CPU.
 
+config SH_LANDISK
+	bool "LANDISK"
+	select CPU_SUBTYPE_SH7751R
+	help
+	  I-O DATA DEVICE, INC. "LANDISK Series" support.
+
+config SH_TITAN
+	bool "TITAN"
+	select CPU_SUBTYPE_SH7751R
+	help
+	  Select Titan if you are configuring for a Nimble Microsystems
+	  NetEngine NP51R.
+
 config SH_UNKNOWN
 	bool "BareCPU"
 	help
@@ -211,168 +232,27 @@
 
 endchoice
 
-choice
-	prompt "Processor family"
-	default CPU_SH4
-	help
-	  This option determines the CPU family to compile for. Supported
-	  targets are SH-2, SH-3, and SH-4. These options are independent of
-	  CPU functionality. As such, SH-DSP users will still want to select
-	  their respective processor family in addition to the DSP support
-	  option.
-
-config CPU_SH2
-	bool "SH-2"
-	select SH_WRITETHROUGH
-
-config CPU_SH3
-	bool "SH-3"
-
-config CPU_SH4
-	bool "SH-4"
-
-endchoice
-
-choice
-	prompt "Processor subtype"
-
-config CPU_SUBTYPE_SH7604
-	bool "SH7604"
-	depends on CPU_SH2
-	help
-	  Select SH7604 if you have SH7604
-
-config CPU_SUBTYPE_SH7300
-	bool "SH7300"
-	depends on CPU_SH3
-
-config CPU_SUBTYPE_SH7705
-	bool "SH7705"
-	depends on CPU_SH3
-
-config CPU_SUBTYPE_SH7707
-	bool "SH7707"
-	depends on CPU_SH3
-	help
-	  Select SH7707 if you have a  60 Mhz SH-3 HD6417707 CPU.
-
-config CPU_SUBTYPE_SH7708
-	bool "SH7708"
-	depends on CPU_SH3
-	help
-	  Select SH7708 if you have a  60 Mhz SH-3 HD6417708S or
-	  if you have a 100 Mhz SH-3 HD6417708R CPU.
-
-config CPU_SUBTYPE_SH7709
-	bool "SH7709"
-	depends on CPU_SH3
-	help
-	  Select SH7709 if you have a  80 Mhz SH-3 HD6417709 CPU.
-
-config CPU_SUBTYPE_SH7750
-	bool "SH7750"
-	depends on CPU_SH4
-	help
-	  Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
-
-config CPU_SUBTYPE_SH7751
-	bool "SH7751/SH7751R"
-	depends on CPU_SH4
-	help
-	  Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
-	  or if you have a HD6417751R CPU.
-
-config CPU_SUBTYPE_SH7760
-	bool "SH7760"
-	depends on CPU_SH4
-
-config CPU_SUBTYPE_SH73180
-       bool "SH73180"
-       depends on CPU_SH4
-
-config CPU_SUBTYPE_ST40STB1
-       bool "ST40STB1 / ST40RA"
-       depends on CPU_SH4
-       help
-         Select ST40STB1 if you have a ST40RA CPU.
-         This was previously called the ST40STB1, hence the option name.
-
-config CPU_SUBTYPE_ST40GX1
-       bool "ST40GX1"
-       depends on CPU_SH4
-       help
-         Select ST40GX1 if you have a ST40GX1 CPU.
-
-config CPU_SUBTYPE_SH4_202
-	bool "SH4-202"
-	depends on CPU_SH4
-
-endchoice
-
-config SH7705_CACHE_32KB
-    bool "Enable 32KB cache size for SH7705"
-    depends on CPU_SUBTYPE_SH7705
-    default y
-
-config MMU
-        bool "Support for memory management hardware"
-	depends on !CPU_SH2
-	default y
-	help
-	  Early SH processors (such as the SH7604) lack an MMU. In order to
-	  boot on these systems, this option must not be set.
-
-	  On other systems (such as the SH-3 and 4) where an MMU exists,
-	  turning this off will boot the kernel on these machines with the
-	  MMU implicitly switched off.
-
-choice
-	prompt "HugeTLB page size"
-	depends on HUGETLB_PAGE && CPU_SH4 && MMU
-	default HUGETLB_PAGE_SIZE_64K
-
-config HUGETLB_PAGE_SIZE_64K
-	bool "64K"
-
-config HUGETLB_PAGE_SIZE_1MB
-	bool "1MB"
+source "arch/sh/mm/Kconfig"
 
-endchoice
-
-config CMDLINE_BOOL
-	bool "Default bootloader kernel arguments"
-
-config CMDLINE
-	string "Initial kernel command string"
-	depends on CMDLINE_BOOL
-	default "console=ttySC1,115200"
-
-# Platform-specific memory start and size definitions
 config MEMORY_START
-	hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE
-	default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SH03 || SH_SECUREEDGE5410 || SH_SH4202_MICRODEV
-	default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_73180_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_EDOSK7705)
+	hex "Physical memory start address"
+	default "0x08000000"
 	---help---
 	  Computers built with Hitachi SuperH processors always
 	  map the ROM starting at address zero.  But the processor
 	  does not specify the range that RAM takes.
 
 	  The physical memory (RAM) start address will be automatically
-	  set to 08000000, unless you selected one of the following
-	  processor types: SolutionEngine, Overdrive, HP620, HP680, HP690,
-	  in which case the start address will be set to 0c000000.
+	  set to 08000000. Other platforms, such as the Solution Engine
+	  boards typically map RAM at 0C000000.
 
-	  Tweak this only when porting to a new machine which is not already
-	  known by the config system.  Changing it from the known correct
+	  Tweak this only when porting to a new machine which does not
+	  already have a defconfig. Changing it from the known correct
 	  value on any of the known systems will only lead to disaster.
 
 config MEMORY_SIZE
-	hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE
-	default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000)
-	default "0x01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST || SH_SECUREEDGE5410 || SH_EDOSK7705
-        default "0x02000000" if !MEMORY_OVERRIDE && (SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE)
-        default "0x04000000" if !MEMORY_OVERRIDE && (SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV)
-	default "0x08000000" if SH_MPC1211 || SH_SH03
+	hex "Physical memory size"
+	default "0x00400000"
 	help
 	  This sets the default memory size assumed by your SH kernel. It can
 	  be overridden as normal by the 'mem=' argument on the kernel command
@@ -380,21 +260,6 @@
 	  as 0x00400000 which was the default value before this became
 	  configurable.
 
-config MEMORY_SET
-	bool
-	depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_SH03 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410 || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_EDOSK7705)
-	default y
-	help
-	  This is an option about which you will never be asked a question.
-	  Therefore, I conclude that you do not exist - go away.
-
-	  There is a grue here.
-
-# If none of the above have set memory start/size, ask the user.
-config MEMORY_OVERRIDE
-	bool "Override default load address and memory size"
-
-# XXX: break these out into the board-specific configs below
 config CF_ENABLER
 	bool "Compact Flash Enabler support"
 	depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03
@@ -438,10 +303,21 @@
 	default "0xb8000000" if CF_AREA6
 	default "0xb4000000" if CF_AREA5
 
+menu "Processor features"
+
+config CPU_LITTLE_ENDIAN
+	bool "Little Endian"
+	help
+	  Some SuperH machines can be configured for either little or big
+	  endian byte order. These modes require different kernels. Say Y if
+	  your machine is little endian, N if it's a big endian machine.
+
 # The SH7750 RTC module is disabled in the Dreamcast
 config SH_RTC
 	bool
-	depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && !SH_73180_SOLUTION_ENGINE
+	depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \
+		   !SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \
+		   !SH_R7780RP
 	default y
 	help
 	  Selecting this option will allow the Linux kernel to emulate
@@ -455,7 +331,7 @@
 	default y
 	help
 	  Selecting this option will enable support for SH processors that
-	  have FPU units (ie, SH77xx).
+	  have FPU units (ie, SH77xx).
 
 	  This option must be set in order to enable the FPU.
 
@@ -480,104 +356,131 @@
 
 	  If unsure, say N.
 
-config SH_HP600
+config SH_STORE_QUEUES
+	bool "Support for Store Queues"
+	depends on CPU_SH4
+	help
+	  Selecting this option will enable an in-kernel API for manipulating
+	  the store queues integrated in the SH-4 processors.
+
+config CPU_HAS_INTEVT
 	bool
-	depends on SH_HP620 || SH_HP680 || SH_HP690
-	default y
 
-config CPU_SUBTYPE_ST40
-       bool
-       depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
-       default y
+config CPU_HAS_PINT_IRQ
+	bool
 
-source "mm/Kconfig"
+config CPU_HAS_INTC2_IRQ
+	bool
 
-config ZERO_PAGE_OFFSET
-	hex "Zero page offset"
-	default "0x00001000" if !(SH_MPC1211 || SH_SH03)
-	default "0x00004000" if SH_MPC1211 || SH_SH03
+config CPU_HAS_SR_RB
+	bool "CPU has SR.RB"
+	depends on CPU_SH3 || CPU_SH4
+	default y
 	help
-	  This sets the default offset of zero page.
+	  This will enable the use of SR.RB register bank usage. Processors
+	  that are lacking this bit must have another method in place for
+	  accomplishing what is taken care of by the banked registers.
 
-# XXX: needs to lose subtype for system type
-config ST40_LMI_MEMORY
-	bool "Memory on LMI"
-	depends on CPU_SUBTYPE_ST40STB1
+	  See <file:Documentation/sh/register-banks.txt> for further
+	  information on SR.RB and register banking in the kernel in general.
 
-config MEMORY_START
-	hex
-	depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
-	default "0x08000000"
+endmenu
 
-config MEMORY_SIZE
-	hex
-	depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
-	default "0x00400000"
+menu "Timer support"
 
-config MEMORY_SET
-	bool
-	depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
+config SH_TMU
+	bool "TMU timer support"
 	default y
-
-config BOOT_LINK_OFFSET
-	hex "Link address offset for booting"
-	default "0x00800000"
 	help
-	  This option allows you to set the link address offset of the zImage.
-	  This can be useful if you are on a board which has a small amount of
-	  memory.
+	  This enables the use of the TMU as the system timer.
 
-config CPU_LITTLE_ENDIAN
-	bool "Little Endian"
+endmenu
+
+source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
+
+source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
+
+config SH_PCLK_FREQ_BOOL
+	bool "Set default pclk frequency"
+	default y if !SH_RTC
+	default n
+
+config SH_PCLK_FREQ
+	int "Peripheral clock frequency (in Hz)"
+	depends on SH_PCLK_FREQ_BOOL
+	default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
+	default "60000000" if CPU_SUBTYPE_SH7751
+	default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760
+	default "27000000" if CPU_SUBTYPE_SH73180
+	default "66000000" if CPU_SUBTYPE_SH4_202
 	help
-	  Some SuperH machines can be configured for either little or big
-	  endian byte order. These modes require different kernels. Say Y if
-	  your machine is little endian, N if it's a big endian machine.
+	  This option is used to specify the peripheral clock frequency.
+	  This is necessary for determining the reference clock value on
+	  platforms lacking an RTC.
 
-config PREEMPT
-	bool "Preemptible Kernel (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+menu "CPU Frequency scaling"
 
-config UBC_WAKEUP
-	bool "Wakeup UBC on startup"
+source "drivers/cpufreq/Kconfig"
+
+config SH_CPU_FREQ
+	tristate "SuperH CPU Frequency driver"
+	depends on CPU_FREQ
+	select CPU_FREQ_TABLE
 	help
-	  Selecting this option will wakeup the User Break Controller (UBC) on
-	  startup. Although the UBC is left in an awake state when the processor
-	  comes up, some boot loaders misbehave by putting the UBC to sleep in a
-	  power saving state, which causes issues with things like ptrace().
+	  This adds the cpufreq driver for SuperH. At present, only
+	  the SH-4 is supported.
+
+	  For details, take a look at <file:Documentation/cpu-freq>.
 
 	  If unsure, say N.
 
-config SH_WRITETHROUGH
-	bool "Use write-through caching"
-	default y if CPU_SH2
-	help
-	  Selecting this option will configure the caches in write-through
-	  mode, as opposed to the default write-back configuration.
-
-	  Since there's sill some aliasing issues on SH-4, this option will
-	  unfortunately still require the majority of flushing functions to
-	  be implemented to deal with aliasing.
+endmenu
 
-	  If unsure, say N.
+source "arch/sh/drivers/dma/Kconfig"
+
+source "arch/sh/cchips/Kconfig"
 
-config SH_OCRAM
-	bool "Operand Cache RAM (OCRAM) support"
+config HEARTBEAT
+	bool "Heartbeat LED"
+	depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \
+		   SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \
+		   SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \
+		   SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \
+		   SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK
 	help
-	  Selecting this option will automatically tear down the number of
-	  sets in the dcache by half, which in turn exposes a memory range.
+	  Use the power-on LED on your machine as a load meter.  The exact
+	  behavior is platform-dependent, but normally the flash frequency is
+	  a hyperbolic function of the 5-minute load average.
 
-	  The addresses for the OC RAM base will vary according to the
-	  processor version. Consult vendor documentation for specifics.
+endmenu
 
-	  If unsure, say N.
+config ISA_DMA_API
+	bool
+	depends on MPC1211
+	default y
 
-config SH_STORE_QUEUES
-	bool "Support for Store Queues"
-	depends on CPU_SH4
+menu "Kernel features"
+
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
 	help
-	  Selecting this option will enable an in-kernel API for manipulating
-	  the store queues integrated in the SH-4 processors.
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.  And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  The name comes from the similiarity to the exec system call.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.  As of this writing the exact hardware interface is
+	  strongly in flux, so no good recommendation can be made.
+
+config PREEMPT
+	bool "Preemptible Kernel (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
 
 config SMP
 	bool "Symmetric multi-processing support"
@@ -614,87 +517,58 @@
 	  This is purely to save memory - each supported CPU adds
 	  approximately eight kilobytes to the kernel image.
 
-config HS7751RVOIP_CODEC
-	bool "Support VoIP Codec section"
-	depends on SH_HS7751RVOIP
-	help
-	  Selecting this option will support CODEC section.
-
-config RTS7751R2D_REV11
-	bool "RTS7751R2D Rev. 1.1 board support"
-	depends on SH_RTS7751R2D
-	help
-	  Selecting this option will support version rev. 1.1.
-
-config SH_PCLK_CALC
-	bool
-	default n if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH73180
+config CPU_HAS_SR_RB
+	bool "CPU has SR.RB"
+	depends on CPU_SH3 || CPU_SH4
 	default y
 	help
-	  This option will cause the PCLK value to be probed at run-time. It
-	  will display a notification if the probed value has greater than a
-	  1% variance of the hardcoded CONFIG_SH_PCLK_FREQ.
+	  This will enable the use of SR.RB register bank usage. Processors
+	  that are lacking this bit must have another method in place for
+	  accomplishing what is taken care of by the banked registers.
 
-config SH_PCLK_FREQ
-	int "Peripheral clock frequency (in Hz)"
-	default "50000000" if CPU_SUBTYPE_SH7750
-	default "60000000" if CPU_SUBTYPE_SH7751
-	default "33333333" if CPU_SUBTYPE_SH7300
-	default "27000000" if CPU_SUBTYPE_SH73180
-	default "66000000" if CPU_SUBTYPE_SH4_202
-	default "1193182"
-	help
-	  This option is used to specify the peripheral clock frequency. This
-	  option must be set for each processor in order for the kernel to
-	  function reliably. If no sane default exists, we use a default from
-	  the legacy i8254. Any discrepancies will be reported on boot time
-	  with an auto-probed frequency which should be considered the proper
-	  value for your hardware.
+	  See <file:Documentation/sh/register-banks.txt> for further
+	  information on SR.RB and register banking in the kernel in general.
 
-menu "CPU Frequency scaling"
+endmenu
 
-source "drivers/cpufreq/Kconfig"
+menu "Boot options"
 
-config SH_CPU_FREQ
-	tristate "SuperH CPU Frequency driver"
-	depends on CPU_FREQ
-	select CPU_FREQ_TABLE
+config ZERO_PAGE_OFFSET
+	hex "Zero page offset"
+	default "0x00004000" if SH_MPC1211 || SH_SH03
+	default "0x00001000"
 	help
-	  This adds the cpufreq driver for SuperH. At present, only
-	  the SH-4 is supported.
-
-	  For details, take a look at <file:Documentation/cpu-freq>.
-
-	  If unsure, say N.
+	  This sets the default offset of zero page.
 
-endmenu
+config BOOT_LINK_OFFSET
+	hex "Link address offset for booting"
+	default "0x00800000"
+	help
+	  This option allows you to set the link address offset of the zImage.
+	  This can be useful if you are on a board which has a small amount of
+	  memory.
 
-source "arch/sh/drivers/dma/Kconfig"
+config UBC_WAKEUP
+	bool "Wakeup UBC on startup"
+	help
+	  Selecting this option will wakeup the User Break Controller (UBC) on
+	  startup. Although the UBC is left in an awake state when the processor
+	  comes up, some boot loaders misbehave by putting the UBC to sleep in a
+	  power saving state, which causes issues with things like ptrace().
 
-source "arch/sh/cchips/Kconfig"
+	  If unsure, say N.
 
-config HEARTBEAT
-	bool "Heartbeat LED"
-	depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_RTS7751R2D || SH_SH4202_MICRODEV
-	help
-	  Use the power-on LED on your machine as a load meter.  The exact
-	  behavior is platform-dependent, but normally the flash frequency is
-	  a hyperbolic function of the 5-minute load average.
+config CMDLINE_BOOL
+	bool "Default bootloader kernel arguments"
 
-config RTC_9701JE
-	tristate "EPSON RTC-9701JE support"
-	depends on SH_RTS7751R2D
-	help
-	  Selecting this option will support EPSON RTC-9701JE.
+config CMDLINE
+	string "Initial kernel command string"
+	depends on CMDLINE_BOOL
+	default "console=ttySC1,115200"
 
 endmenu
 
-config ISA_DMA_API
-	bool
-	depends on MPC1211
-	default y
-
-menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+menu "Bus options"
 
 # Even on SuperH devices which don't have an ISA bus,
 # this variable helps the PCMCIA modules handle
@@ -705,7 +579,7 @@
 # PCMCIA outright. -- PFM.
 config ISA
 	bool
-	default y if PCMCIA || SMC91X
+	default y if PCMCIA
 	help
 	  Find out whether you have ISA slots on your motherboard.  ISA is the
 	  name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -739,10 +613,9 @@
 config SBUS
 	bool
 
-config MAPLE
-	tristate "Maple Bus support"
-	depends on SH_DREAMCAST
-	default y
+config SUPERHYWAY
+	tristate "SuperHyway Bus support"
+	depends on CPU_SUBTYPE_SH4_202
 
 source "arch/sh/drivers/pci/Kconfig"
 
diff -urN -X exclude linux-2.6.15/arch/sh/Kconfig.debug sh-2.6.15/arch/sh/Kconfig.debug
--- linux-2.6.15/arch/sh/Kconfig.debug	2004-10-25 13:03:28.000000000 +0300
+++ sh-2.6.15/arch/sh/Kconfig.debug	2006-01-04 00:15:28.000000000 +0200
@@ -17,7 +17,7 @@
 
 config EARLY_SCIF_CONSOLE
 	bool "Use early SCIF console"
-	depends on CPU_SH4
+	depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS
 
 config EARLY_PRINTK
 	bool "Early printk support"
diff -urN -X exclude linux-2.6.15/arch/sh/Makefile sh-2.6.15/arch/sh/Makefile
--- linux-2.6.15/arch/sh/Makefile	2006-01-04 14:19:57.000000000 +0200
+++ sh-2.6.15/arch/sh/Makefile	2006-01-07 23:51:00.506910848 +0200
@@ -17,10 +17,30 @@
 cflags-y				:= -mb
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	:= -ml
 
+isa-y					:= any
+isa-$(CONFIG_CPU_SH2)			:= sh2
+isa-$(CONFIG_CPU_SH3)			:= sh3
+isa-$(CONFIG_CPU_SH4)			:= sh4
+isa-$(CONFIG_CPU_SH4A)			:= sh4a
+isa-$(CONFIG_CPU_SH2A)			:= sh2a
+
+isa-$(CONFIG_SH_DSP)			:= $(isa-y)-dsp
+
+ifndef CONFIG_MMU
+isa-y			:= $(isa-y)-nommu
+endif
+
+ifndef CONFIG_SH_FPU
+isa-y			:= $(isa-y)-nofpu
+endif
+
+cflags-y	+= $(call as-option,-Wa$(comma)-isa=$(isa-y),)
+
 cflags-$(CONFIG_CPU_SH2)		+= -m2
 cflags-$(CONFIG_CPU_SH3)		+= -m3
 cflags-$(CONFIG_CPU_SH4)		+= -m4 \
 	$(call cc-option,-mno-implicit-fp,-m4-nofpu)
+cflags-$(CONFIG_CPU_SH4A)		+= $(call cc-option,-m4a-nofpu,)
 
 cflags-$(CONFIG_SH_DSP)			+= -Wa,-dsp
 cflags-$(CONFIG_SH_KGDB)		+= -g
@@ -67,9 +87,7 @@
 machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE)	:= se/73180
 machdir-$(CONFIG_SH_STB1_HARP)			:= harp
 machdir-$(CONFIG_SH_STB1_OVERDRIVE)		:= overdrive
-machdir-$(CONFIG_SH_HP620)			:= hp6xx/hp620
-machdir-$(CONFIG_SH_HP680)			:= hp6xx/hp680
-machdir-$(CONFIG_SH_HP690)			:= hp6xx/hp690
+machdir-$(CONFIG_SH_HP6XX)			:= hp6xx
 machdir-$(CONFIG_SH_CQREEK)			:= cqreek
 machdir-$(CONFIG_SH_DMIDA)			:= dmida
 machdir-$(CONFIG_SH_EC3104)			:= ec3104
@@ -119,31 +135,39 @@
 
 CPPFLAGS_vmlinux.lds := -traditional
 
+ifneq ($(KBUILD_SRC),)
+incdir-prefix	:= $(srctree)/include/asm-sh/
+else
+incdir-prefix	:=
+endif
+
 #	Update machine arch and proc symlinks if something which affects
 #	them changed.  We use .arch and .mach to indicate when they were
 #	updated last, otherwise make uses the target directory mtime.
 
 include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER
 	@echo '  SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)'
-ifneq ($(KBUILD_SRC),)
-	$(Q)mkdir -p include/asm-sh
-	$(Q)ln -fsn $(srctree)/include/asm-sh/$(cpuincdir-y) include/asm-sh/cpu
-else
-	$(Q)ln -fsn $(cpuincdir-y) include/asm-sh/cpu
-endif
+	$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
+	$(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu
 	@touch $@
 
+#	Most boards have their own mach directories.  For the ones that
+#	don't, just reference the parent directory so the semantics are
+#	kept roughly the same.
+
 include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER
-	@echo '  SYMLINK include/asm-sh/mach -> include/asm-sh/$(incdir-y)'
-ifneq ($(KBUILD_SRC),)
-	$(Q)mkdir -p include/asm-sh
-	$(Q)ln -fsn $(srctree)/include/asm-sh/$(incdir-y) include/asm-sh/mach
-else
-	$(Q)ln -fsn $(incdir-y) include/asm-sh/mach
-endif
+	@echo -n '  SYMLINK include/asm-sh/mach -> '
+	$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
+	$(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \
+		echo -e 'include/asm-sh/$(incdir-y)'; \
+		ln -fsn $(incdir-prefix)$(incdir-y) \
+			include/asm-sh/mach; \
+	else \
+		echo -e 'include/asm-sh'; \
+		ln -fsn $(incdir-prefix) include/asm-sh/mach; \
+	fi
 	@touch $@
 
-
 archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
 
 .PHONY: maketools FORCE

diff -urN -X exclude linux-2.6.15/arch/sh/mm/Kconfig sh-2.6.15/arch/sh/mm/Kconfig
--- linux-2.6.15/arch/sh/mm/Kconfig	1970-01-01 02:00:00.000000000 +0200
+++ sh-2.6.15/arch/sh/mm/Kconfig	2006-01-07 22:19:41.052260810 +0200
@@ -0,0 +1,233 @@
+menu "Processor selection"
+
+#
+# Processor families
+#
+config CPU_SH2
+	bool
+	select SH_WRITETHROUGH
+
+config CPU_SH3
+	bool
+	select CPU_HAS_INTEVT
+	select CPU_HAS_SR_RB
+
+config CPU_SH4
+	bool
+	select CPU_HAS_INTEVT
+	select CPU_HAS_SR_RB
+
+config CPU_SH4A
+	bool
+	select CPU_SH4
+	select CPU_HAS_INTC2_IRQ
+
+config CPU_SUBTYPE_ST40
+	bool
+	select CPU_SH4
+	select CPU_HAS_INTC2_IRQ
+
+#
+# Processor subtypes
+#
+
+comment "SH-2 Processor Support"
+
+config CPU_SUBTYPE_SH7604
+	bool "Support SH7604 processor"
+	select CPU_SH2
+
+comment "SH-3 Processor Support"
+
+config CPU_SUBTYPE_SH7300
+	bool "Support SH7300 processor"
+	select CPU_SH3
+
+config CPU_SUBTYPE_SH7705
+	bool "Support SH7705 processor"
+	select CPU_SH3
+	select CPU_HAS_PINT_IRQ
+
+config CPU_SUBTYPE_SH7707
+	bool "Support SH7707 processor"
+	select CPU_SH3
+	select CPU_HAS_PINT_IRQ
+	help
+	  Select SH7707 if you have a  60 Mhz SH-3 HD6417707 CPU.
+
+config CPU_SUBTYPE_SH7708
+	bool "Support SH7708 processor"
+	select CPU_SH3
+	help
+	  Select SH7708 if you have a  60 Mhz SH-3 HD6417708S or
+	  if you have a 100 Mhz SH-3 HD6417708R CPU.
+
+config CPU_SUBTYPE_SH7709
+	bool "Support SH7709 processor"
+	select CPU_SH3
+	select CPU_HAS_PINT_IRQ
+	help
+	  Select SH7709 if you have a  80 Mhz SH-3 HD6417709 CPU.
+
+comment "SH-4 Processor Support"
+
+config CPU_SUBTYPE_SH7750
+	bool "Support SH7750 processor"
+	select CPU_SH4
+	help
+	  Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
+
+config CPU_SUBTYPE_SH7091
+	bool "Support SH7091 processor"
+	select CPU_SH4
+	select CPU_SUBTYPE_SH7750
+	help
+	  Select SH7091 if you have an SH-4 based Sega device (such as
+	  the Dreamcast, Naomi, and Naomi 2).
+
+config CPU_SUBTYPE_SH7750R
+	bool "Support SH7750R processor"
+	select CPU_SH4
+	select CPU_SUBTYPE_SH7750
+
+config CPU_SUBTYPE_SH7750S
+	bool "Support SH7750S processor"
+	select CPU_SH4
+	select CPU_SUBTYPE_SH7750
+
+config CPU_SUBTYPE_SH7751
+	bool "Support SH7751 processor"
+	select CPU_SH4
+	help
+	  Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
+	  or if you have a HD6417751R CPU.
+
+config CPU_SUBTYPE_SH7751R
+	bool "Support SH7751R processor"
+	select CPU_SH4
+	select CPU_SUBTYPE_SH7751
+
+config CPU_SUBTYPE_SH7760
+	bool "Support SH7760 processor"
+	select CPU_SH4
+	select CPU_HAS_INTC2_IRQ
+
+config CPU_SUBTYPE_SH4_202
+	bool "Support SH4-202 processor"
+	select CPU_SH4
+
+comment "ST40 Processor Support"
+
+config CPU_SUBTYPE_ST40STB1
+	bool "Support ST40STB1/ST40RA processors"
+	select CPU_SUBTYPE_ST40
+	help
+	  Select ST40STB1 if you have a ST40RA CPU.
+	  This was previously called the ST40STB1, hence the option name.
+
+config CPU_SUBTYPE_ST40GX1
+	bool "Support ST40GX1 processor"
+	select CPU_SUBTYPE_ST40
+	help
+	  Select ST40GX1 if you have a ST40GX1 CPU.
+
+comment "SH-4A Processor Support"
+
+config CPU_SUBTYPE_SH73180
+	bool "Support SH73180 processor"
+	select CPU_SH4A
+
+config CPU_SUBTYPE_SH7770
+	bool "Support SH7770 processor"
+	select CPU_SH4A
+
+config CPU_SUBTYPE_SH7780
+	bool "Support SH7780 processor"
+	select CPU_SH4A
+
+endmenu
+
+menu "Memory management options"
+
+config MMU
+        bool "Support for memory management hardware"
+	depends on !CPU_SH2
+	default y
+	help
+	  Some SH processors (such as SH-2/SH-2A) lack an MMU. In order to
+	  boot on these systems, this option must not be set.
+
+	  On other systems (such as the SH-3 and 4) where an MMU exists,
+	  turning this off will boot the kernel on these machines with the
+	  MMU implicitly switched off.
+
+config 32BIT
+	bool "Support 32-bit physical addressing through PMB"
+	depends on CPU_SH4A
+	default y
+	help
+	  If you say Y here, physical addressing will be extended to
+	  32-bits through the SH-4A PMB. If this is not set, legacy
+	  29-bit physical addressing will be used.
+
+choice
+	prompt "HugeTLB page size"
+	depends on HUGETLB_PAGE && CPU_SH4 && MMU
+	default HUGETLB_PAGE_SIZE_64K
+
+config HUGETLB_PAGE_SIZE_64K
+	bool "64K"
+
+config HUGETLB_PAGE_SIZE_1MB
+	bool "1MB"
+
+endchoice
+
+source "mm/Kconfig"
+
+endmenu
+
+menu "Cache configuration"
+
+config SH7705_CACHE_32KB
+	bool "Enable 32KB cache size for SH7705"
+	depends on CPU_SUBTYPE_SH7705
+	default y
+
+config SH_DIRECT_MAPPED
+	bool "Use direct-mapped caching"
+	default n
+	help
+	  Selecting this option will configure the caches to be direct-mapped,
+	  even if the cache supports a 2 or 4-way mode. This is useful primarily
+	  for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R,
+	  SH4-202, SH4-501, etc.)
+
+	  Turn this option off for platforms that do not have a direct-mapped
+	  cache, and you have no need to run the caches in such a configuration.
+
+config SH_WRITETHROUGH
+	bool "Use write-through caching"
+	default y if CPU_SH2
+	help
+	  Selecting this option will configure the caches in write-through
+	  mode, as opposed to the default write-back configuration.
+
+	  Since there's sill some aliasing issues on SH-4, this option will
+	  unfortunately still require the majority of flushing functions to
+	  be implemented to deal with aliasing.
+
+	  If unsure, say N.
+
+config SH_OCRAM
+	bool "Operand Cache RAM (OCRAM) support"
+	help
+	  Selecting this option will automatically tear down the number of
+	  sets in the dcache by half, which in turn exposes a memory range.
+
+	  The addresses for the OC RAM base will vary according to the
+	  processor version. Consult vendor documentation for specifics.
+
+	  If unsure, say N.
+
+endmenu

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-01-14 22:56 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-14 22:50 [PATCH 0/8] sh updates Paul Mundt
2006-01-14 22:51 ` [PATCH 1/8] sh: Consolidate hp620/hp680/hp690 targets into hp6xx Paul Mundt
2006-01-14 22:51 ` [PATCH 2/8] sh: DMA updates Paul Mundt
2006-01-14 22:52 ` [PATCH 3/8] sh: kexec() support Paul Mundt
2006-01-14 22:53 ` [PATCH 4/8] sh: IRQ handler updates Paul Mundt
2006-01-14 22:54 ` [PATCH 5/8] sh: I/O routine cleanups and ioremap() overhaul Paul Mundt
2006-01-14 22:55 ` [PATCH 6/8] sh: Simplistic clock framework Paul Mundt
2006-01-14 22:55 ` [PATCH 7/8] sh: Simple timer framework Paul Mundt
2006-01-14 22:56 ` [PATCH 8/8] sh: Move CPU subtype configuration to its own Kconfig Paul Mundt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).