diff -ruN linux-2.6.4.org/arch/m32r/Kconfig linux-2.6.4/arch/m32r/Kconfig
--- linux-2.6.4.org/arch/m32r/Kconfig	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/Kconfig	2004-03-31 19:54:22.000000000 +0900
@@ -0,0 +1,597 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "Linux Kernel Configuration"
+
+config M32R
+	bool
+	default y
+
+config SBUS
+	bool
+
+config UID16
+	bool
+	default y
+
+config GENERIC_ISA_DMA
+	bool
+	default y
+
+source "init/Kconfig"
+
+
+menu "Processor type and features"
+
+choice
+	prompt "Platform Type"
+	default PLAT_MAPPI
+
+config PLAT_MAPPI
+	bool "Mappi-I"
+	help
+	  The Mappi-I is an FPGA board for SOC (System-On-a-Chip) prototyping.
+	  You can operate a Linux system on this board by using an M32R
+	  softmacro core, which is a fully-synthesizable functional model 
+	  described in Verilog-HDL.
+
+	  The Mappi-I board was the first platform, which had been used 
+	  to port and develop a Linux system for the M32R processor.  
+	  Currently, the Mappi-II, an heir to the Mappi-I, is available.
+
+config PLAT_USRV
+	bool "uServer"
+
+config PLAT_M32700UT
+	bool "M32700UT"
+	help
+	  The M3T-M32700UT is an evaluation board based on uT-Engine
+	  specification.  This board has an M32700 (Chaos) evaluation chip.
+	  You can say Y for SMP, because the M32700 is a single chip 
+	  multiprocessor.
+
+config PLAT_OAKS32R
+	bool "OAKS32R"
+	help
+	  The OAKS32R is a tiny, inexpensive evaluation board.
+	  Please note that if you say Y here and choose chip "M32102", 
+	  say N for MMU and select a no-MMU version kernel, otherwise 
+	  a kernel with MMU support will not work, because the M32102 
+	  is a microcontroller for embedded systems and it has no MMU.
+
+endchoice
+
+choice
+	prompt "Processor family"
+	default CHIP_M32700
+
+config CHIP_M32700
+	bool "M32700 (Chaos)"
+
+config CHIP_M32102
+	bool "M32102"
+
+endchoice
+
+config MMU
+	bool "Support for memory management hardware"
+	depends on CHIP_M32700
+	default y
+
+config ISA_M32R
+        bool
+	depends on CHIP_M32102
+	default y
+
+config ISA_M32R2
+	bool
+	depends on CHIP_M32700
+	default y
+
+config ISA_DSP_LEVEL2
+	bool
+	depends on CHIP_M32700
+	default y
+
+config ISA_DUAL_ISSUE
+	bool
+	depends on CHIP_M32700
+	default y
+
+config BUS_CLOCK
+	int "Bus Clock [Hz] (integer)"
+	default "70000000" if PLAT_MAPPI
+	default "25000000" if PLAT_USRV
+	default "50000000" if PLAT_M32700UT
+	default "33333333" if PLAT_OAKS32R
+
+config TIMER_DIVIDE
+	int "Timer divider (integer)"
+	default "128"
+
+config CPU_LITTLE_ENDIAN
+        bool "Generate little endian code"
+	default n
+
+config MEMORY_START
+	hex "Physical memory start address (hex)"
+	default "08000000" if PLAT_MAPPI
+	default "08000000" if PLAT_USRV
+	default "08000000" if PLAT_M32700UT
+	default "01000000" if PLAT_OAKS32R
+
+config MEMORY_SIZE
+	hex "Physical memory size (hex)"
+	default "04000000" if PLAT_MAPPI
+	default "02000000" if PLAT_USRV
+	default "01000000" if PLAT_M32700UT
+	default "00800000" if PLAT_OAKS32R
+
+config NOHIGHMEM
+	bool
+	default y
+
+config DISCONTIGMEM
+	bool "Internal RAM Support"
+	depends on CHIP_M32700 || CHIP_M32102
+	default y
+
+config IRAM_START
+	hex "Internal memory start address (hex)"
+	default "00f00000"
+	depends on (CHIP_M32700 || CHIP_M32102) && DISCONTIGMEM
+
+config IRAM_SIZE
+	hex "Internal memory size (hex)"
+	depends on (CHIP_M32700 || CHIP_M32102) && DISCONTIGMEM
+	default "00080000" if CHIP_M32700
+	default "00010000" if CHIP_M32102
+
+#
+# Define implied options from the CPU selection here
+#
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	depends on M32R
+	default y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+	default n
+
+config PREEMPT
+	bool "Preemptible Kernel"
+	help
+	  This option reduces the latency of the kernel when reacting to
+	  real-time or interactive events by allowing a low priority process to
+	  be preempted even if it is in kernel mode executing a system call.
+	  This allows applications to run more reliably even when the system is
+	  under load.
+
+	  Say Y here if you are building a kernel for a desktop, embedded
+	  or real-time system.  Say N if you are unsure.
+
+config HAVE_DEC_LOCK
+	bool
+	depends on (SMP || PREEMPT)
+	default n
+
+config SMP
+	bool "Symmetric multi-processing support"
+	---help---
+	  This enables support for systems with more than one CPU. If you have
+	  a system with only one CPU, like most personal computers, say N. If
+	  you have a system with more than one CPU, say Y.
+
+	  If you say N here, the kernel will run on single and multiprocessor
+	  machines, but will use only one CPU of a multiprocessor machine. If
+	  you say Y here, the kernel will run on many, but not all,
+	  singleprocessor machines. On a singleprocessor machine, the kernel
+	  will run faster if you say N here.
+
+	  Note that if you say Y here and choose architecture "586" or
+	  "Pentium" under "Processor family", the kernel will not work on 486
+	  architectures. Similarly, multiprocessor kernels for the "PPro"
+	  architecture may not work on all Pentium based boards.
+
+	  People using multiprocessor machines who say Y here should also say
+	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
+	  Management" code will be disabled if you say Y here.
+
+	  See also the <file:Documentation/smp.tex>,
+	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
+	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+	  <http://www.linuxdoc.org/docs.html#howto>.
+
+	  If you don't know what to do here, say N.
+
+config CHIP_M32700_TS1
+	bool "Workaround code for the M32700 TS1 chip's bug"
+	depends on (CHIP_M32700 && SMP)
+	default n
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-32)"
+	range 2 32
+	depends on SMP
+	default "2"
+	help
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 32 and the
+	  minimum value which makes sense is 2.
+
+	  This is purely to save memory - each supported CPU adds
+	  approximately eight kilobytes to the kernel image.
+
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation Support"
+	depends on SMP
+	default n
+
+source "arch/m32r/drivers/Kconfig"
+
+# turning this on wastes a bunch of space.
+# Summit needs it only when NUMA is on
+config BOOT_IOREMAP
+	bool
+	depends on NUMA
+	default n
+
+endmenu
+
+
+menu "Power management options (ACPI, APM)"
+
+source kernel/power/Kconfig
+
+config APM
+	tristate "Advanced Power Management BIOS support"
+	depends on PM
+	---help---
+	  APM is a BIOS specification for saving power using several different
+	  techniques. This is mostly useful for battery powered laptops with
+	  APM compliant BIOSes. If you say Y here, the system time will be
+	  reset after a RESUME operation, the /proc/apm device will provide
+	  battery status information, and user-space programs will receive
+	  notification of APM "events" (e.g. battery status change).
+
+	  If you select "Y" here, you can disable actual use of the APM
+	  BIOS by passing the "apm=off" option to the kernel at boot time.
+
+	  Note that the APM support is almost completely disabled for
+	  machines with more than one CPU.
+
+	  In order to use APM, you will need supporting software. For location
+	  and more information, read <file:Documentation/pm.txt> and the
+	  Battery Powered Linux mini-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>.
+
+	  This driver does not spin down disk drives (see the hdparm(8)
+	  manpage ("man 8 hdparm") for that), and it doesn't turn off
+	  VESA-compliant "green" monitors.
+
+	  This driver does not support the TI 4000M TravelMate and the ACER
+	  486/DX4/75 because they don't have compliant BIOSes. Many "green"
+	  desktop machines also don't have compliant BIOSes, and this driver
+	  may cause those machines to panic during the boot phase.
+
+	  Generally, if you don't have a battery in your machine, there isn't
+	  much point in using this driver and you should say N. If you get
+	  random kernel OOPSes or reboots that don't seem to be related to
+	  anything, try disabling/enabling this option (or disabling/enabling
+	  APM in your BIOS).
+
+	  Some other things you should try when experiencing seemingly random,
+	  "weird" problems:
+
+	  1) make sure that you have enough swap space and that it is
+	  enabled.
+	  2) pass the "no-hlt" option to the kernel
+	  3) switch on floating point emulation in the kernel and pass
+	  the "no387" option to the kernel
+	  4) pass the "floppy=nodma" option to the kernel
+	  5) pass the "mem=4M" option to the kernel (thereby disabling
+	  all but the first 4 MB of RAM)
+	  6) make sure that the CPU is not over clocked.
+	  7) read the sig11 FAQ at <http://www.bitwizard.nl/sig11/>
+	  8) disable the cache from your BIOS settings
+	  9) install a fan for the video card or exchange video RAM
+	  10) install a better fan for the CPU
+	  11) exchange RAM chips
+	  12) exchange the motherboard.
+
+	  To compile this driver as a module ( = code which can be inserted in
+	  and removed from the running kernel whenever you want), say M here
+	  and read <file:Documentation/modules.txt>. The module will be called
+	  apm.
+
+config APM_IGNORE_USER_SUSPEND
+	bool "Ignore USER SUSPEND"
+	depends on APM
+	help
+	  This option will ignore USER SUSPEND requests. On machines with a
+	  compliant APM BIOS, you want to say N. However, on the NEC Versa M
+	  series notebooks, it is necessary to say Y because of a BIOS bug.
+
+config APM_DO_ENABLE
+	bool "Enable PM at boot time"
+	depends on APM
+	---help---
+	  Enable APM features at boot time. From page 36 of the APM BIOS
+	  specification: "When disabled, the APM BIOS does not automatically
+	  power manage devices, enter the Standby State, enter the Suspend
+	  State, or take power saving steps in response to CPU Idle calls."
+	  This driver will make CPU Idle calls when Linux is idle (unless this
+	  feature is turned off -- see "Do CPU IDLE calls", below). This
+	  should always save battery power, but more complicated APM features
+	  will be dependent on your BIOS implementation. You may need to turn
+	  this option off if your computer hangs at boot time when using APM
+	  support, or if it beeps continuously instead of suspending. Turn
+	  this off if you have a NEC UltraLite Versa 33/C or a Toshiba
+	  T400CDT. This is off by default since most machines do fine without
+	  this feature.
+
+config APM_CPU_IDLE
+	bool "Make CPU Idle calls when idle"
+	depends on APM
+	help
+	  Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
+	  On some machines, this can activate improved power savings, such as
+	  a slowed CPU clock rate, when the machine is idle. These idle calls
+	  are made after the idle loop has run for some length of time (e.g.,
+	  333 mS). On some machines, this will cause a hang at boot time or
+	  whenever the CPU becomes idle. (On machines with more than one CPU,
+	  this option does nothing.)
+
+config APM_DISPLAY_BLANK
+	bool "Enable console blanking using APM"
+	depends on APM
+	help
+	  Enable console blanking using the APM. Some laptops can use this to
+	  turn off the LCD backlight when the screen blanker of the Linux
+	  virtual console blanks the screen. Note that this is only used by
+	  the virtual console screen blanker, and won't turn off the backlight
+	  when using the X Window system. This also doesn't have anything to
+	  do with your VESA-compliant power-saving monitor. Further, this
+	  option doesn't work for all laptops -- it might not turn off your
+	  backlight at all, or it might print a lot of errors to the console,
+	  especially if you are using gpm.
+
+config APM_RTC_IS_GMT
+	bool "RTC stores time in GMT"
+	depends on APM
+	help
+	  Say Y here if your RTC (Real Time Clock a.k.a. hardware clock)
+	  stores the time in GMT (Greenwich Mean Time). Say N if your RTC
+	  stores localtime.
+
+	  It is in fact recommended to store GMT in your RTC, because then you
+	  don't have to worry about daylight savings time changes. The only
+	  reason not to use GMT in your RTC is if you also run a broken OS
+	  that doesn't understand GMT.
+
+config APM_ALLOW_INTS
+	bool "Allow interrupts during APM BIOS calls"
+	depends on APM
+	help
+	  Normally we disable external interrupts while we are making calls to
+	  the APM BIOS as a measure to lessen the effects of a badly behaving
+	  BIOS implementation.  The BIOS should reenable interrupts if it
+	  needs to.  Unfortunately, some BIOSes do not -- especially those in
+	  many of the newer IBM Thinkpads.  If you experience hangs when you
+	  suspend, try setting this to Y.  Otherwise, say N.
+
+config APM_REAL_MODE_POWER_OFF
+	bool "Use real mode APM BIOS call to power off"
+	depends on APM
+	help
+	  Use real mode APM BIOS calls to switch off the computer. This is
+	  a work-around for a number of buggy BIOSes. Switch this option on if
+	  your computer crashes instead of powering off properly.
+
+endmenu
+
+
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+config PCI
+	bool "PCI support"
+	default n
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+	  VESA. If you have PCI, say Y, otherwise N.
+
+	  The PCI-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+	  information about which PCI hardware does work under Linux and which
+	  doesn't.
+
+choice
+	prompt "PCI access mode"
+	depends on PCI
+	default PCI_GOANY
+
+config PCI_GOBIOS
+	bool "BIOS"
+	---help---
+	  On PCI systems, the BIOS can be used to detect the PCI devices and
+	  determine their configuration. However, some old PCI motherboards
+	  have BIOS bugs and may crash if this is done. Also, some embedded
+	  PCI-based systems don't have any BIOS at all. Linux can also try to
+	  detect the PCI hardware directly without using the BIOS.
+
+	  With this option, you can specify how Linux should detect the PCI
+	  devices. If you choose "BIOS", the BIOS will be used, if you choose
+	  "Direct", the BIOS won't be used, and if you choose "Any", the
+	  kernel will try the direct access method and falls back to the BIOS
+	  if that doesn't work. If unsure, go with the default, which is
+	  "Any".
+
+config PCI_GODIRECT
+	bool "Direct"
+
+config PCI_GOANY
+	bool "Any"
+
+endchoice
+
+config PCI_BIOS
+	bool
+	depends on PCI && (PCI_GOBIOS || PCI_GOANY)
+	default y
+
+config PCI_DIRECT
+	bool
+ 	depends on PCI && (PCI_GODIRECT || PCI_GOANY)
+	default y
+
+source "drivers/pci/Kconfig"
+
+config ISA
+	bool "ISA support"
+	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
+	  inside your box.  Other bus systems are PCI, EISA, MicroChannel
+	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
+	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
+
+config EISA
+	bool "EISA support"
+	depends on ISA
+	---help---
+	  The Extended Industry Standard Architecture (EISA) bus was
+	  developed as an open alternative to the IBM MicroChannel bus.
+
+	  The EISA bus provided some of the features of the IBM MicroChannel
+	  bus while maintaining backward compatibility with cards made for
+	  the older ISA bus.  The EISA bus saw limited use between 1988 and
+	  1995 when it was made obsolete by the PCI bus.
+
+	  Say Y here if you are building a kernel for an EISA-based machine.
+
+	  Otherwise, say N.
+
+source "drivers/eisa/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+menu "Kernel hacking"
+
+config DEBUG_KERNEL
+	bool "Kernel debugging"
+	help
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
+
+config DEBUG_STACKOVERFLOW
+	bool "Check for stack overflows"
+	depends on DEBUG_KERNEL
+
+config DEBUG_SLAB
+	bool "Debug memory allocations"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
+
+config DEBUG_IOVIRT
+	bool "Memory mapped I/O debugging"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to get warned whenever an attempt is made to do I/O on
+	  obviously invalid addresses such as those generated when ioremap()
+	  calls are forgotten.  Memory mapped I/O will go through an extra
+	  check to catch access to unmapped ISA addresses, an access method
+	  that can still be used by old drivers that are being ported from
+	  2.0/2.2.
+
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, you will have some control over the system even
+	  if the system crashes for example during kernel debugging (e.g., you
+	  will be able to flush the buffer cache to disk, reboot the system
+	  immediately or dump some status information). This is accomplished
+	  by pressing various keys while holding SysRq (Alt+PrintScreen). It
+	  also works on a serial console (on PC hardware at least), if you
+	  send a BREAK and then within 5 seconds a command keypress. The
+	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+	  unless you really know what this hack does.
+
+config DEBUG_SPINLOCK
+	bool "Spinlock debugging"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here and build SMP to catch missing spinlock initialization
+	  and certain other kinds of spinlock errors commonly made.  This is
+	  best used in conjunction with the NMI watchdog so that spinlock
+	  deadlocks are also debuggable.
+
+config DEBUG_PAGEALLOC
+	bool "Page alloc debugging"
+	depends on DEBUG_KERNEL
+	help
+	  Unmap pages from the kernel linear mapping after free_pages().
+	  This results in a large slowdown, but helps to find certain types
+	  of memory corruptions.
+
+config DEBUG_HIGHMEM
+	bool "Highmem debugging"
+	depends on DEBUG_KERNEL && HIGHMEM
+	help
+	  This options enables addition error checking for high memory systems.
+	  Disable for production systems.
+
+config KALLSYMS
+	bool "Load all symbols for debugging/kksymoops"
+	help
+	  Say Y here to let the kernel print out symbolic crash information and
+	  symbolic stack backtraces. This increases the size of the kernel
+	  somewhat, as all symbols have to be loaded into the kernel image.
+
+config DEBUG_SPINLOCK_SLEEP
+	bool "Sleep-inside-spinlock checking"
+	help
+	  If you say Y here, various routines which may sleep will become very
+	  noisy if they are called with a spinlock held.	
+
+config FRAME_POINTER
+	bool "Compile the kernel with frame pointers"
+	help
+	  If you say Y here the resulting kernel image will be slightly larger
+	  and slower, but it will give very useful debugging information.
+	  If you don't debug the kernel, you can say N, but we may not be able
+	  to solve problems without frame pointers.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
diff -ruN linux-2.6.4.org/arch/m32r/Makefile linux-2.6.4/arch/m32r/Makefile
--- linux-2.6.4.org/arch/m32r/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/Makefile	2004-03-31 14:05:48.000000000 +0900
@@ -0,0 +1,32 @@
+#
+# m32r/Makefile
+# 
+
+LDFLAGS		:=
+OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
+LDFLAGS_vmlinux	:= -e startup_32
+LDFLAGS_BLOB	:= --format binary --oformat elf32-m32r
+
+CFLAGS += -g -pipe -fno-schedule-insns
+CFLAGS_KERNEL += -mmodel=medium
+CFLAGS_MODULE += -mmodel=large
+
+cflags-$(CONFIG_CHIP_M32700)	+= -DNO_FPU -m32r2
+aflags-$(CONFIG_CHIP_M32700)	+= -DNO_FPU -m32r2
+
+cflags-$(CONFIG_CHIP_M32102)	+= -DNO_FPU 
+aflags-$(CONFIG_CHIP_M32102)	+= -DNO_FPU -Wa,-no-bitinst
+
+CFLAGS += $(cflags-y)
+AFLAGS += $(aflags-y)
+
+head-y	:= arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o
+
+LIBGCC	:= $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+libs-y	+= arch/m32r/lib/ $(LIBGCC)
+core-y	+= arch/m32r/kernel/	\
+	   arch/m32r/mm/	\
+	   arch/m32r/boot/	\
+	   arch/m32r/drivers/
+
diff -ruN linux-2.6.4.org/arch/m32r/boot/Makefile linux-2.6.4/arch/m32r/boot/Makefile
--- linux-2.6.4.org/arch/m32r/boot/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/Makefile	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,6 @@
+#
+# arch/m32r/boot/Makefile
+#
+
+obj-y	:= setup.o
+
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/Makefile linux-2.6.4/arch/m32r/boot/compressed/Makefile
--- linux-2.6.4.org/arch/m32r/boot/compressed/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/Makefile	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,36 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+OBJECTS = $(HEAD) misc.o m32r_sio.o
+
+ZLDFLAGS = -e startup
+ZLINKFLAGS = $(ZLDFLAGS)
+
+all: vmlinux
+
+vmlinux: piggy.o $(OBJECTS) vmlinux.lds
+	$(LD) $(ZLINKFLAGS) -o vmlinux $(OBJECTS) piggy.o -T vmlinux.lds
+
+piggy.o: $(SYSTEM)
+	$(OBJCOPY) $(SYSTEM) piggy
+	gzip -f -9 < piggy > piggy.gz
+	$(LD) -r -o $@ -b binary piggy.gz
+
+vmlinux.lds: vmlinux.lds.S
+	$(CPP) $(AFLAGS) -traditional -C -P -I$(HPATH) \
+	    vmlinux.lds.S > vmlinux.lds
+
+clean:
+	rm -f vmlinux piggy.o piggy.gz $(OBJECTS)
+
+include $(TOPDIR)/Rules.make
+
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/boot.h linux-2.6.4/arch/m32r/boot/compressed/boot.h
--- linux-2.6.4.org/arch/m32r/boot/compressed/boot.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/boot.h	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,59 @@
+/*
+ * 1. load vmlinuz
+ *
+ * CONFIG_MEMORY_START  	+-----------------------+
+ *				|        vmlinuz	|
+ *				+-----------------------+
+ * 2. decompressed
+ *
+ * CONFIG_MEMORY_START  	+-----------------------+
+ *				|        vmlinuz	|
+ *				+-----------------------+
+ *				|			|
+ * BOOT_RELOC_ADDR		+-----------------------+
+ *				|		 	|
+ * KERNEL_DECOMPRESS_ADDR 	+-----------------------+
+ *				|  	vmlinux		|
+ *				+-----------------------+
+ *
+ * 3. relocate copy & jump code
+ *		
+ * CONFIG_MEMORY_START  	+-----------------------+
+ *				|        vmlinuz	|
+ *				+-----------------------+
+ *				|			|
+ * BOOT_RELOC_ADDR		+-----------------------+
+ *				|    boot(copy&jump)	|
+ * KERNEL_DECOMPRESS_ADDR 	+-----------------------+
+ *				|  	vmlinux		|
+ *				+-----------------------+
+ *
+ * 4. relocate decompressed kernel
+ *
+ * CONFIG_MEMORY_START  	+-----------------------+
+ *				|        vmlinux	|
+ *				+-----------------------+
+ *				|			|
+ * BOOT_RELOC_ADDR		+-----------------------+
+ *				|     boot(copy&jump) 	|
+ * KERNEL_DECOMPRESS_ADDR 	+-----------------------+
+ *				|  			|
+ *				+-----------------------+
+ *
+ */
+#ifdef __ASSEMBLY__
+#define __val(x)	x
+#else
+#define __val(x)	(x)
+#endif
+
+#define DECOMPRESS_OFFSET_BASE	__val(0x00900000)
+#define BOOT_RELOC_SIZE		__val(0x00001000)
+
+#define KERNEL_EXEC_ADDR	__val(CONFIG_MEMORY_START)
+#define KERNEL_DECOMPRESS_ADDR	__val(CONFIG_MEMORY_START + \
+				      DECOMPRESS_OFFSET_BASE + BOOT_RELOC_SIZE)
+#define KERNEL_ENTRY		__val(CONFIG_MEMORY_START + 0x1000)
+
+#define BOOT_EXEC_ADDR		__val(CONFIG_MEMORY_START)
+#define BOOT_RELOC_ADDR		__val(CONFIG_MEMORY_START + DECOMPRESS_OFFSET_BASE)
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/head.S linux-2.6.4/arch/m32r/boot/compressed/head.S
--- linux-2.6.4.org/arch/m32r/boot/compressed/head.S	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/head.S	2004-03-16 19:34:57.000000000 +0900
@@ -0,0 +1,193 @@
+/*
+ *  linux/arch/m32r/boot/compressed/head.S
+ *
+ *  Copyright (c) 2001-2003	Hiroyuki Kondo, Hirokazu Takata,
+ *				Hitoshi Yamamoto, Takeo Takahashi
+ */
+
+	.text
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/assembler.h>
+#include "boot.h"
+
+	.global	startup
+startup:
+	ldi	r0, #0x0000			/* SPI, disable EI */
+	mvtc	r0, psw
+
+/*
+ * Clear BSS first so that there are no surprises...
+ */
+#ifdef CONFIG_ISA_DUAL_ISSUE
+
+	LDIMM	(r2, SYMBOL_NAME(__bss_start))
+	LDIMM	(r3, SYMBOL_NAME(_end))
+	sub	r3, r2		; BSS size in bytes
+	; R4 = BSS size in longwords (rounded down)
+	mv	r4, r3		    ||	ldi	r1, #0
+	srli	r4, #4		    ||	addi	r2, #-4	
+	beqz	r4, .Lendloop1
+.Lloop1:	
+#ifndef CONFIG_CHIP_M32310
+	; Touch memory for the no-write-allocating cache.
+	ld	r0, @(4,r2)
+#endif
+	st	r1, @+r2	    ||	addi	r4, #-1
+	st	r1, @+r2
+	st	r1, @+r2
+	st	r1, @+r2	    ||	cmpeq	r1, r4	; R4 = 0?
+	bnc	.Lloop1
+.Lendloop1:
+	and3	r4, r3, #15
+	addi	r2, #4
+	beqz	r4, .Lendloop2
+.Lloop2:
+	stb	r1, @r2		    ||	addi	r4, #-1
+	addi	r2, #1
+	bnez	r4, .Lloop2
+.Lendloop2:
+
+#else /* not CONFIG_ISA_DUAL_ISSUE */
+
+	LDIMM	(r2, SYMBOL_NAME(__bss_start))
+	LDIMM	(r3, SYMBOL_NAME(_end))
+	sub	r3, r2		; BSS size in bytes
+	mv	r4, r3
+	srli	r4, #2		; R4 = BSS size in longwords (rounded down)
+	ldi	r1, #0		; clear R1 for longwords store
+	addi	r2, #-4		; account for pre-inc store
+	beqz	r4, .Lendloop1	; any more to go?
+.Lloop1:	
+	st	r1, @+r2	; yep, zero out another longword
+	addi	r4, #-1		; decrement count
+	bnez	r4, .Lloop1	; go do some more
+.Lendloop1:
+	and3	r4, r3, #3	; get no. of remaining BSS bytes to clear
+	addi	r2, #4		; account for pre-inc store
+	beqz	r4, .Lendloop2	; any more to go?
+.Lloop2:
+	stb	r1, @r2		; yep, zero out another byte
+	addi	r2, #1		; bump address
+	addi	r4, #-1		; decrement count
+	bnez	r4, .Lloop2	; go do some more
+.Lendloop2:		
+
+#endif /* not CONFIG_ISA_DUAL_ISSUE */
+
+	seth	r0, #shigh(stack_start)
+	ld	sp, @(r0, low(stack_start))	/* set stack point */
+
+/*
+ * decompress the kernel
+ */
+	bl	decompress_kernel
+	mv	r12, r0 		/* size of decompressed kernel */
+
+/*
+ * relocate copy routine & jump routine
+ */
+	LDIMM	(r1, BOOT_RELOC_ADDR)
+	mv	r5, r1		; save reloc addr to jump
+
+	LDIMM	(r2, SYMBOL_NAME(startup_reloc))
+	LDIMM	(r3, SYMBOL_NAME(exit_reloc))
+	sub	r3, r2		; relocated code size in bytes
+	mv	r4, r3
+	srli	r4, #2		; R4 = code size in longwords (rounded down)
+	addi	r1, #-4		; account for pre-inc store
+	beqz	r4, 2f		; any more to go?
+1:	
+	ld	r6, @r2+	; code to be relocated
+	st	r6, @+r1	; relocate code
+	addi	r4, #-1		; decrement count
+	bnez	r4, 1b		; go do some more
+2:
+	and3	r4, r3, #3	; get no. of remaining bytes
+	addi	r1, #4		; account for pre-inc store
+	beqz	r4, 4f		; any more to go?
+3:
+	ldb	r6, @r2		; code to be relocated
+	stb	r6, @r1		; relocate code
+	addi	r1, #1		; bump address
+	addi	r2, #1		; bump address
+	addi	r4, #-1		; decrement count
+	bnez	r4, 3b		; go do some more
+4:		
+	jmp	r5		; jump to relocated code
+
+/*
+ * startup_reloc runs on BOOT_RELOC_ADDR.
+ * copy decompressed kernel to original location
+ */
+	.text
+	__ALIGN
+startup_reloc:
+	LDIMM	(r1, CONFIG_MEMORY_START)
+	LDIMM	(r2, KERNEL_DECOMPRESS_ADDR)
+	mv	r4, r12		; r12 holds size of decompressed kernel
+	srli	r4, #2		; R4 = code size in longwords (rounded down)
+	addi	r1, #-4		; account for pre-inc store
+	beqz	r4, 2f		; any more to go?
+1:	
+	ld	r6, @r2+	; code to be relocated
+	st	r6, @+r1	; relocate code
+	addi	r4, #-1		; decrement count
+	bnez	r4, 1b		; go do some more
+2:
+	and3	r4, r12, #3	; get no. of remaining bytes
+	addi	r1, #4		; account for pre-inc store
+	beqz	r4, 4f		; any more to go?
+3:
+	ldb	r6, @r2		; code to be relocated
+	stb	r6, @r1		; relocate code
+	addi	r1, #1		; bump address
+	addi	r2, #1		; bump address
+	addi	r4, #-1		; decrement count
+	bnez	r4, 3b		; go do some more
+4:		
+	/*
+	 * invalidate i-cache before jump to kernel
+	 */
+#if defined(CONFIG_CHIP_VDEC2)
+	ldi	r0, #-1
+	ldi	r1, #0xc0	; invalidate i-cache
+	stb	r1, @r0
+#elif defined(CONFIG_CHIP_XNUX2)
+	ldi	r0, #-2
+	ldi	r1, #0x0100	; invalidate
+	sth	r1, @r0
+#elif defined(CONFIG_CHIP_M32700)
+	ldi	r0, #-1		; MCCR(cache control register)
+	ldi	r1, #0xc0	; invalidate i-cache
+	stb	r1, @r0
+#else
+#error unknown chip configuration
+#endif
+	LDIMM	(r0, KERNEL_ENTRY)
+	jmp	r0				/* jump to kernel */
+
+	__ALIGN
+exit_reloc:
+
+	.balign 4096
+.fake_empty_zero_page:
+	/* FIXME: correct table value */
+	.word	0
+	.ascii	"HdrS"
+	.word	0x0202
+	.word	0
+	.word	0
+	.word	0x1000
+	.word	0
+	.byte	0
+	.byte	1
+	.word	0x8000
+	.long	0
+	.long	0
+
+	.section	.fake_eit_vector, "aw"
+	.long	0
+
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/install.sh linux-2.6.4/arch/m32r/boot/compressed/install.sh
--- linux-2.6.4.org/arch/m32r/boot/compressed/install.sh	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/install.sh	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# arch/sh/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
+# Adapted from code in arch/sh/boot/install.sh by Takeo Takahashi
+#
+# "make install" script for sh architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+  exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  if [ -f $4/vmlinuz-$1 ]; then
+    mv $4/vmlinuz-$1 $4/vmlinuz.old
+  fi
+
+  if [ -f $4/System.map-$1 ]; then
+    mv $4/System.map-$1 $4/System.old
+  fi
+
+  cat $2 > $4/vmlinuz-$1
+  cp $3 $4/System.map-$1
+else
+# Normal install
+  echo "Installing normal kernel"
+  if [ -f $4/vmlinux-$1 ]; then
+    mv $4/vmlinux-$1 $4/vmlinux.old
+  fi
+
+  if [ -f $4/System.map ]; then
+    mv $4/System.map $4/System.old
+  fi
+
+  cat $2 > $4/vmlinux-$1
+  cp $3 $4/System.map
+fi
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/m32r_sio.c linux-2.6.4/arch/m32r/boot/compressed/m32r_sio.c
--- linux-2.6.4.org/arch/m32r/boot/compressed/m32r_sio.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/m32r_sio.c	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,50 @@
+/*
+ * arch/m32r/boot/compressed/m32r_sio.c
+ * 
+ * 2003-02-12:	Takeo Takahashi
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/m32r.h>
+#include <asm/io.h>
+
+void putc(char c);
+
+void puts(char *s)
+{
+	char c;
+	while ((c = *s++)) putc(c);
+}
+
+#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT)
+#define USE_FPGA_MAP	0
+
+#if USE_FPGA_MAP
+/*
+ * fpga configuration program uses MMU, and define map as same as
+ * M32104 uT-Engine board.
+ */
+#define BOOT_SIO0STS	(volatile unsigned short *)(0x02c00000 + 0x20006)
+#define BOOT_SIO0TXB	(volatile unsigned short *)(0x02c00000 + 0x2000c)
+#else
+#define BOOT_SIO0STS	PLD_ESIO0STS
+#define BOOT_SIO0TXB	PLD_ESIO0TXB
+#endif
+
+void putc(char c)
+{
+
+	while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
+	if (c == '\n') {
+		*BOOT_SIO0TXB = '\r';
+		while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
+	}
+	*BOOT_SIO0TXB = c;
+}
+#else
+void putc(char c)
+{
+	/* do nothing */
+}
+#endif
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/misc.c linux-2.6.4/arch/m32r/boot/compressed/misc.c
--- linux-2.6.4.org/arch/m32r/boot/compressed/misc.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/misc.c	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,224 @@
+/*
+ * arch/m32r/boot/compressed/misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ *
+ * 2003-02-12:	Support M32R by Takeo Takahashi
+ * 		This is based on arch/sh/boot/compressed/misc.c.
+ */
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+#include "boot.h"
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;	     /* input buffer */
+static uch window[WSIZE];    /* Sliding window buffer */
+
+static unsigned insize;  /* valid bytes in inbuf */
+static unsigned inptr;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt;  /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+		
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+  
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out;
+static uch *output_data;
+static unsigned long output_ptr;
+
+ 
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+ 
+extern void puts(const char *);
+  
+extern int _text;		/* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+ 
+#define HEAP_SIZE             0x10000
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+	if (free_mem_ptr == 0) error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_end_ptr)
+		error("\nOut of memory\n");
+
+	return p;
+}
+
+static void free(void *where)
+{	/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+void* memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+	return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data\n");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, *out, ch;
+    
+    in = window;
+    out = &output_data[output_ptr]; 
+    for (n = 0; n < outcnt; n++) {
+	    ch = *out++ = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#define STACK_SIZE (4096)
+long user_stack [STACK_SIZE];
+long* stack_start = &user_stack[STACK_SIZE];
+
+/* return decompressed size */
+long decompress_kernel(void)
+{
+	insize = 0;
+	inptr = 0;
+	bytes_out = 0;
+	outcnt = 0;
+	output_data = 0;
+	output_ptr = (unsigned long)KERNEL_DECOMPRESS_ADDR;
+	free_mem_ptr = (unsigned long)&_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+	makecrc();
+	puts("Uncompressing Linux... ");
+	gunzip();
+	puts("Ok, booting the kernel.\n");
+	return bytes_out;
+}
diff -ruN linux-2.6.4.org/arch/m32r/boot/compressed/vmlinux.lds.S linux-2.6.4/arch/m32r/boot/compressed/vmlinux.lds.S
--- linux-2.6.4.org/arch/m32r/boot/compressed/vmlinux.lds.S	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/compressed/vmlinux.lds.S	2003-12-15 15:48:06.000000000 +0900
@@ -0,0 +1,107 @@
+#include <linux/config.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+OUTPUT_ARCH(m32r)
+ENTRY(startup)
+SECTIONS
+{
+  . = CONFIG_MEMORY_START + 0x00000000;
+  .fake_eit_vector : { *(.fake_eit_vector) }
+  
+  /* boot runs in physical address space */
+  . = ALIGN(4096);
+  _text = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+    *(.stub)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } = 0
+  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
+  .rodata : { *(.rodata) }
+  .kstrtab : { *(.kstrtab) }
+  _etext = .;			/* End of text section */
+
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN(32) + (. & (32 - 1));
+  .data    :
+  {
+    input_len = .;
+    LONG(input_data_end - input_data)
+    input_data = .;
+    piggy.o(.data)
+    input_data_end = .;
+    misc.o(.data)
+    m32r_sio.o(.data)
+  }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) *(.sdata.*) }
+  _edata  =  .;
+
+  . = ALIGN(32 / 8);
+  __bss_start = .;		/* BSS */
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.bss)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(32 / 8);
+  }
+  . = ALIGN(32 / 8);
+  _end = . ;
+
+  /* When something in the kernel is NOT compiled as a module, the
+   * module cleanup code and data are put into these segments.  Both
+   * can then be thrown away, as cleanup code is never called unless
+   * it's a module.
+   */
+  /DISCARD/ : {
+    *(.text.exit)
+    *(.data.exit)
+    *(.exitcall.exit)
+  }
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff -ruN linux-2.6.4.org/arch/m32r/boot/setup.S linux-2.6.4/arch/m32r/boot/setup.S
--- linux-2.6.4.org/arch/m32r/boot/setup.S	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/boot/setup.S	2004-03-31 14:05:56.000000000 +0900
@@ -0,0 +1,217 @@
+/*
+ *  linux/arch/m32r/boot/setup.S -- A setup code.
+ *
+ *  Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
+ *  and Hitoshi Yamamoto
+ *
+ */
+/* $Id$ */
+
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+	
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/mmu_context.h>
+#include <asm/m32r.h>
+
+/*
+ * References to members of the boot_cpu_data structure.
+ */
+
+#define CPU_PARAMS	boot_cpu_data
+#define M32R_MCICAR	 0xfffffff0	
+#define M32R_MCDCAR	 0xfffffff4	
+#define	M32R_MCCR 	 0xfffffffc
+#define M32R_BSCR0	 0xffffffd2
+
+;BSEL
+#define BSEL0CR0	 0x00ef5000
+#define	BSEL0CR1	 0x00ef5004
+#define BSEL1CR0	 0x00ef5100
+#define BSEL1CR1	 0x00ef5104
+#define BSEL0CR0_VAL	 0x00000000
+#define BSEL0CR1_VAL	 0x01200100
+#define BSEL1CR0_VAL	 0x01018000
+#define BSEL1CR1_VAL	 0x00200001
+
+;SDRAMC
+#define SDRAMC_SDRF0	 0x00ef6000
+#define SDRAMC_SDRF1	 0x00ef6004
+#define SDRAMC_SDIR0	 0x00ef6008
+#define SDRAMC_SDIR1	 0x00ef600c
+#define SDRAMC_SD0ADR	 0x00ef6020
+#define SDRAMC_SD0ER	 0x00ef6024
+#define SDRAMC_SD0TR	 0x00ef6028
+#define SDRAMC_SD0MOD	 0x00ef602c
+#define SDRAMC_SD1ADR	 0x00ef6040
+#define SDRAMC_SD1ER	 0x00ef6044
+#define SDRAMC_SD1TR	 0x00ef6048
+#define SDRAMC_SD1MOD	 0x00ef604c
+#define SDRAM0		 0x18000000
+#define SDRAM1		 0x1c000000
+
+/*------------------------------------------------------------------------
+ * start up
+ */
+
+/*------------------------------------------------------------------------
+ * Kernel entry
+ */
+	.section .boot,"ax"
+ENTRY(boot)
+
+/* Set cache mode */
+#if defined(CONFIG_CHIP_XNUX2)
+	ldi	r0, #-2              ;LDIMM	(r0, M32R_MCCR)
+	ldi	r1, #0x0101		; cache on (with invalidation)
+;	ldi	r1, #0x00		; cache off
+	sth	r1, @r0
+#elif defined(CONFIG_CHIP_VDEC2)
+	; cache condition is controlled by loader
+	; r13 = pointer to kernel parameter passed from loader
+	beqz	r13, param_skip
+	ldi	r2, #4096				; size
+	seth	r1, #high(empty_zero_page)
+	or3	r1, r1, #low(empty_zero_page)
+	seth	r3, #high(__PAGE_OFFSET)
+	or3	r3, r3, #low(__PAGE_OFFSET)
+	not	r3, r3
+	and	r1, r3
+	addi	r1, #-4
+param_loop:
+	ld	r3, @r13+
+	st	r3, @+r1
+	addi	r2, #-4
+	bnez	r2, param_loop
+	bra	param_end
+param_skip:
+	ldi	r0, #-1              ;LDIMM	(r0, M32R_MCCR)
+	ldi	r1, #0x63      		; cache on
+;	ldi	r1, #0x00		; cache off
+	stb	r1, @r0
+param_end:
+
+#elif defined(CONFIG_CHIP_M32700) && (defined(CONFIG_PLAT_M32700UT) \
+	|| defined(CONFIG_PLAT_USRV))
+	; cache condition is controlled by loader
+	; r13 = pointer to kernel parameter passed from loader
+	ldi     r0, #-4
+	ldi     r1, #0x63		;  cache Ion/Don
+	st      r1, @r0
+#if defined(CONFIG_SMP) && !defined(CONFIG_PLAT_USRV)
+	seth    r5, #high(M32R_CPUID_PORTL)
+	or3     r5, r5, #low(M32R_CPUID_PORTL)
+	ld      r5, @r5
+	bnez    r5, param_end
+		;;  boot AP
+	ld24    r5, #0xeff2f8		;  IPICR7
+	ldi     r6, #0x2		;  IPI to CPU1
+	st      r6, @r5
+#endif
+	beqz	r13, param_end
+	ldi	r2, #4096				; size
+	seth	r1, #high(empty_zero_page)
+	or3	r1, r1, #low(empty_zero_page)
+	seth	r3, #high(__PAGE_OFFSET)
+	or3	r3, r3, #low(__PAGE_OFFSET)
+	not	r3, r3
+	and	r1, r3
+	addi	r1, #-4
+param_loop:
+	ld	r3, @r13+
+	st	r3, @+r1
+	addi	r2, #-4
+	bnez	r2, param_loop
+param_end:
+#elif defined(CONFIG_CHIP_M32700)
+	ldi	r0, #-4			;LDIMM	(r0, M32R_MCCR)
+	ldi	r1, #0x63		; cache Ion/Don (with invalidation)
+;	ldi	r1, #0x00		; cache off
+	st	r1, @r0
+#elif defined(CONFIG_CHIP_M32102)
+        ldi     r0, #-4                 ;LDIMM  (r0, M32R_MCCR)
+        ldi     r1, #0x101              ; cache Ion (with invalidation)
+;       ldi     r1, #0x00               ; cache off
+        st      r1, @r0
+#else
+#error unknown chip configuration
+#endif
+
+#ifdef CONFIG_SMP
+	;; if not BSP (CPU#0) goto AP_loop
+	seth	r5, #shigh(M32R_CPUID_PORTL)
+	ld      r5, @(low(M32R_CPUID_PORTL), r5)
+	bnez	r5, AP_loop
+#endif
+
+/*
+ *  Now, Jump to stext 
+ *        if with MMU,    TLB on.
+ *        if with no MMU, only jump.
+ */
+mmu_on:
+	LDIMM	(r13, stext)
+#ifdef CONFIG_MMU
+	LDIMM	(r2, init_tlb)
+	jl	r2
+	LDIMM	(r2, _RE)			; set EVB(cr5)
+	mvtc    r2, cr5	
+	seth	r0, #high(MMU_REG_BASE)		; Set MMU_REG_BASE higher
+	or3     r0, r0, #low(MMU_REG_BASE)	; Set MMU_REG_BASE lower
+	ldi     r1, #0x01    
+	st      r1, @(MATM_offset,r0)		; Set MATM (T bit ON)
+	ld      r0, @(MATM_offset,r0)		; Check
+#else
+	seth	r0,#high(M32R_MCDCAR)
+	or3	r0,r0,#low(M32R_MCDCAR)
+	ld24	r1,#0x8080
+	st	r1,@r0
+#endif	/* CONFIG_MMU */
+	jmp	r13
+	nop
+	nop
+
+#ifdef CONFIG_SMP
+/* 
+ * AP wait loop
+ */
+ENTRY(AP_loop)
+	;; disable interrupt
+	clrpsw	#0x40
+	;; reset EVB
+	LDIMM	(r4, _AP_RE)
+	seth	r5, #high(__PAGE_OFFSET)
+	or3	r5, r5, #low(__PAGE_OFFSET)
+	not	r5, r5
+	and	r4, r5
+	mvtc	r4, cr5
+	;; disable maskable interrupt
+	seth	r4, #high(M32R_ICU_IMASK_PORTL)
+	or3	r4, r4, #low(M32R_ICU_IMASK_PORTL)
+	ldi	r5, #0
+	st	r5, @r4
+	ld	r5, @r4
+	;; enable only IPI
+	setpsw	#0x40
+    	;; LOOOOOOOOOOOOOOP!!!
+	.fillinsn
+2:
+	nop
+	nop
+	bra	2b
+	nop
+	nop
+
+#ifdef CONFIG_CHIP_M32700_TS1
+	.global	dcache_dummy
+	.balign	16, 0
+dcache_dummy:
+	.byte	16
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+#endif	/* CONFIG_SMP */
+
+	.end
+
diff -ruN linux-2.6.4.org/arch/m32r/defconfig linux-2.6.4/arch/m32r/defconfig
--- linux-2.6.4.org/arch/m32r/defconfig	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/defconfig	2004-04-07 12:54:35.000000000 +0900
@@ -0,0 +1,623 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_M32R=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_IKCONFIG=y
+# CONFIG_IKCONFIG_PROC is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+# CONFIG_PLAT_MAPPI is not set
+# CONFIG_PLAT_USRV is not set
+CONFIG_PLAT_M32700UT=y
+# CONFIG_PLAT_OAKS32R is not set
+CONFIG_CHIP_M32700=y
+# CONFIG_CHIP_M32102 is not set
+CONFIG_MMU=y
+CONFIG_ISA_M32R2=y
+CONFIG_ISA_DSP_LEVEL2=y
+CONFIG_ISA_DUAL_ISSUE=y
+CONFIG_BUS_CLOCK=50000000
+CONFIG_TIMER_DIVIDE=128
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x01000000
+CONFIG_NOHIGHMEM=y
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_PREEMPT=y
+# CONFIG_HAVE_DEC_LOCK is not set
+# CONFIG_SMP is not set
+
+#
+# M32R drivers
+#
+# CONFIG_M32RPCC is not set
+CONFIG_M32R_CFC=y
+CONFIG_M32700UT_CFC=y
+CONFIG_CFC_NUM=1
+CONFIG_M32R_SMC91111=y
+CONFIG_M32700UT_DS1302=y
+
+#
+# Power management options (ACPI, APM)
+#
+# CONFIG_PM is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+# CONFIG_TCIC is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# 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_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETDEVICES is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# 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 I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 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
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_M32R_SIO is not set
+CONFIG_SERIAL_M32R_PLDSIO=y
+CONFIG_SERIAL_M32R_PLDSIO_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_CPIA is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=m
+CONFIG_JBD_DEBUG=y
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# 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_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
diff -ruN linux-2.6.4.org/arch/m32r/drivers/8390.c linux-2.6.4/arch/m32r/drivers/8390.c
--- linux-2.6.4.org/arch/m32r/drivers/8390.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/8390.c	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1 @@
+#include "../../../drivers/net/8390.c"
diff -ruN linux-2.6.4.org/arch/m32r/drivers/8390.h linux-2.6.4/arch/m32r/drivers/8390.h
--- linux-2.6.4.org/arch/m32r/drivers/8390.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/8390.h	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1 @@
+#include "../../../drivers/net/8390.h"
diff -ruN linux-2.6.4.org/arch/m32r/drivers/Kconfig linux-2.6.4/arch/m32r/drivers/Kconfig
--- linux-2.6.4.org/arch/m32r/drivers/Kconfig	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/Kconfig	2004-03-31 14:06:00.000000000 +0900
@@ -0,0 +1,42 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menu "M32R drivers"
+
+config M32RPCC
+	bool "M32R PCMCIA I/F"
+	depends on CHIP_M32700
+
+config M32R_NE2000
+	bool "On board NE2000 Network Interface Chip"
+	depends on PLAT_MAPPI || PLAT_OAKS32R
+
+config M32R_CFC
+	bool "CF I/F Controller"
+	depends on PLAT_USRV || PLAT_M32700UT
+
+config M32700UT_CFC
+	bool
+	depends on M32R_CFC
+	default y
+
+config CFC_NUM
+	int "CF I/F number"
+	depends on PLAT_USRV || PLAT_M32700UT
+	default "1" if PLAT_USRV || PLAT_M32700UT
+
+config MTD_M32R
+	bool "Flash device mapped on M32R"
+	depends on PLAT_USRV
+
+config M32R_SMC91111
+	bool "On board SMC91111 Network Interface Chip"
+	depends on PLAT_M32700UT
+
+config M32700UT_DS1302
+	bool "DS1302 Real Time Clock support"
+	depends on PLAT_M32700UT
+
+endmenu
diff -ruN linux-2.6.4.org/arch/m32r/drivers/Makefile linux-2.6.4/arch/m32r/drivers/Makefile
--- linux-2.6.4.org/arch/m32r/drivers/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/Makefile	2004-02-17 17:31:39.000000000 +0900
@@ -0,0 +1,9 @@
+#
+# Makefile for the Linux/M32R driver
+#
+
+obj-$(CONFIG_M32R_SMC91111)	+= smc91111.o
+obj-$(CONFIG_M32R_NE2000)	+= mappi_ne.o 8390.o
+obj-$(CONFIG_M32RPCC)		+= m32r_pcc.o
+obj-$(CONFIG_M32R_CFC)		+= m32r_cfc.o
+obj-$(CONFIG_M32700UT_DS1302)	+= ds1302.o
diff -ruN linux-2.6.4.org/arch/m32r/drivers/cs_internal.h linux-2.6.4/arch/m32r/drivers/cs_internal.h
--- linux-2.6.4.org/arch/m32r/drivers/cs_internal.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/cs_internal.h	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,2 @@
+#include "../../../drivers/pcmcia/cs_internal.h"
+
diff -ruN linux-2.6.4.org/arch/m32r/drivers/ds1302.c linux-2.6.4/arch/m32r/drivers/ds1302.c
--- linux-2.6.4.org/arch/m32r/drivers/ds1302.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/ds1302.c	2004-03-26 12:11:24.000000000 +0900
@@ -0,0 +1,432 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : ds1302.c
+*!
+*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
+*!
+*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
+*!
+*! $Log: ds1302.c,v $
+*! Revision 1.2  2003/10/29 08:42:58  fujiwara
+*! Set PLD_RTCBAUR from bus clock
+*!
+*! Revision 1.12  2002/04/10 15:35:25  johana
+*! Moved probe function closer to init function and marked it __init.
+*!
+*! Revision 1.11  2001/06/14 12:35:52  jonashg
+*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
+*!
+*! Revision 1.9  2001/06/14 10:00:14  jonashg
+*! No need for tempudelay to be inline anymore (had to adjust the usec to
+*! loops conversion because of this to make it slow enough to be a udelay).
+*!
+*! Revision 1.8  2001/06/14 08:06:32  jonashg
+*! Made tempudelay delay usecs (well, just a tad more).
+*!
+*! Revision 1.7  2001/06/13 14:18:11  jonashg
+*! Only allow processes with SYS_TIME capability to set time and charge.
+*!
+*! Revision 1.6  2001/06/12 15:22:07  jonashg
+*! * Made init function __init.
+*! * Parameter to out_byte() is unsigned char.
+*! * The magic number 42 has got a name.
+*! * Removed comment about /proc (nothing is exported there).
+*!
+*! Revision 1.5  2001/06/12 14:35:13  jonashg
+*! Gave the module a name and added it to printk's.
+*!
+*! Revision 1.4  2001/05/31 14:53:40  jonashg
+*! Made tempudelay() inline so that the watchdog doesn't reset (see
+*! function comment).
+*!
+*! Revision 1.3  2001/03/26 16:03:06  bjornw
+*! Needs linux/config.h
+*!
+*! Revision 1.2  2001/03/20 19:42:00  bjornw
+*! Use the ETRAX prefix on the DS1302 options
+*!
+*! Revision 1.1  2001/03/20 09:13:50  magnusmn
+*! Linux 2.4 port
+*!
+*! Revision 1.10  2000/07/05 15:38:23  bjornw
+*! Dont update kernel time when a RTC_SET_TIME is done
+*!
+*! Revision 1.9  2000/03/02 15:42:59  macce
+*! * Hack to make RTC work on all 2100/2400
+*!
+*! Revision 1.8  2000/02/23 16:59:18  torbjore
+*! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
+*!
+*! Revision 1.7  2000/01/17 15:51:43  johana
+*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
+*!
+*! Revision 1.6  1999/10/27 13:19:47  bjornw
+*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
+*! /dev/rtc calls it now.
+*!
+*! Revision 1.5  1999/10/27 12:39:37  bjornw
+*! Disabled superuser check. Anyone can now set the time.
+*!
+*! Revision 1.4  1999/09/02 13:27:46  pkj
+*! Added shadow for R_PORT_PB_CONFIG.
+*! Renamed port_g_shadow to port_g_data_shadow.
+*!
+*! Revision 1.3  1999/09/02 08:28:06  pkj
+*! Made it possible to select either port PB or the generic port for the RST
+*! signal line to the DS1302 RTC.
+*! Also make sure the RST bit is configured as output on Port PB (if used).
+*!
+*! Revision 1.2  1999/09/01 14:47:20  bjornw
+*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
+*! and set the date. Register as major 121.
+*!
+*! Revision 1.1  1999/09/01 09:45:29  bjornw
+*! Implemented a DS1302 RTC driver.
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
+*!
+*! $Id: ds1302.c,v 1.2 2003/10/29 08:42:58 fujiwara Exp $
+*!
+*!***************************************************************************/
+
+#include <linux/config.h>
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+#include <linux/bcd.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/rtc.h>
+#include <asm/m32700ut/m32700ut_pld.h>
+
+#define RTC_MAJOR_NR 121 /* local major, change later */
+
+static const char ds1302_name[] = "ds1302";
+
+/* Send 8 bits. */
+static void
+out_byte_rtc(unsigned int reg_addr, unsigned char x) 
+{
+	//RST H
+	outw(0x0001,(unsigned long)PLD_RTCRSTODT);
+	//write data
+	outw(((x<<8)|(reg_addr&0xff)),(unsigned long)PLD_RTCWRDATA);
+	//WE
+	outw(0x0002,(unsigned long)PLD_RTCCR);
+	//wait
+	while(inw((unsigned long)PLD_RTCCR));
+	
+	//RST L
+	outw(0x0000,(unsigned long)PLD_RTCRSTODT);
+
+}
+
+static unsigned char
+in_byte_rtc(unsigned int reg_addr) 
+{
+	unsigned char retval;
+	
+	//RST H
+	outw(0x0001,(unsigned long)PLD_RTCRSTODT);
+	//write data
+	outw((reg_addr&0xff),(unsigned long)PLD_RTCRDDATA);
+	//RE
+	outw(0x0001,(unsigned long)PLD_RTCCR);
+	//wait
+	while(inw((unsigned long)PLD_RTCCR));
+
+	//read data
+	retval=(inw((unsigned long)PLD_RTCRDDATA) & 0xff00)>>8;
+
+	//RST L
+	outw(0x0000,(unsigned long)PLD_RTCRSTODT);
+
+	return retval;
+}
+
+/* Enable writing. */
+
+static void
+ds1302_wenable(void) 
+{
+	out_byte_rtc(0x8e,0x00);
+}
+
+/* Disable writing. */
+
+static void
+ds1302_wdisable(void) 
+{
+	out_byte_rtc(0x8e,0x80);
+}
+
+
+
+/* Read a byte from the selected register in the DS1302. */
+
+unsigned char
+ds1302_readreg(int reg) 
+{
+	unsigned char x;
+
+	x=in_byte_rtc((0x81 | (reg << 1))); /* read register */
+
+	return x;
+}
+
+/* Write a byte to the selected register. */
+
+void
+ds1302_writereg(int reg, unsigned char val) 
+{
+	ds1302_wenable();
+	out_byte_rtc((0x80 | (reg << 1)),val);
+	ds1302_wdisable();
+}
+
+void
+get_rtc_time(struct rtc_time *rtc_tm) 
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	local_irq_disable();
+
+	rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
+	rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
+	rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
+	rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
+	rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
+	rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
+
+	local_irq_restore(flags);
+	
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	/*
+	 * Account for differences between how the RTC uses the values
+	 * and how they are defined in a struct rtc_time;
+	 */
+
+	if (rtc_tm->tm_year <= 69)
+		rtc_tm->tm_year += 100;
+
+	rtc_tm->tm_mon--;
+}
+
+static unsigned char days_in_mo[] = 
+    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
+
+static int
+rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg) 
+{
+        unsigned long flags;
+
+	switch(cmd) {
+		case RTC_RD_TIME:	/* read the time/date from RTC	*/
+		{
+			struct rtc_time rtc_tm;
+						
+			memset(&rtc_tm, 0, sizeof (struct rtc_time));
+			get_rtc_time(&rtc_tm);						
+			if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
+				return -EFAULT;	
+			return 0;
+		}
+
+		case RTC_SET_TIME:	/* set the RTC */
+		{
+			struct rtc_time rtc_tm;
+			unsigned char mon, day, hrs, min, sec, leap_yr;
+			unsigned int yrs;
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+
+			if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+				return -EFAULT;    	
+
+			yrs = rtc_tm.tm_year + 1900;
+			mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
+			day = rtc_tm.tm_mday;
+			hrs = rtc_tm.tm_hour;
+			min = rtc_tm.tm_min;
+			sec = rtc_tm.tm_sec;
+			
+			
+			if ((yrs < 1970) || (yrs > 2069))
+				return -EINVAL;
+
+			leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+			if ((mon > 12) || (day == 0))
+				return -EINVAL;
+
+			if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+				return -EINVAL;
+			
+			if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+				return -EINVAL;
+
+			if (yrs >= 2000)
+				yrs -= 2000;	/* RTC (0, 1, ... 69) */
+			else
+				yrs -= 1900;	/* RTC (70, 71, ... 99) */
+
+			BIN_TO_BCD(sec);
+			BIN_TO_BCD(min);
+			BIN_TO_BCD(hrs);
+			BIN_TO_BCD(day);
+			BIN_TO_BCD(mon);
+			BIN_TO_BCD(yrs);
+
+			local_irq_save(flags);
+			local_irq_disable();
+			CMOS_WRITE(yrs, RTC_YEAR);
+			CMOS_WRITE(mon, RTC_MONTH);
+			CMOS_WRITE(day, RTC_DAY_OF_MONTH);
+			CMOS_WRITE(hrs, RTC_HOURS);
+			CMOS_WRITE(min, RTC_MINUTES);
+			CMOS_WRITE(sec, RTC_SECONDS);
+			local_irq_restore(flags);
+
+			/* Notice that at this point, the RTC is updated but
+			 * the kernel is still running with the old time.
+			 * You need to set that separately with settimeofday
+			 * or adjtimex.
+			 */
+			return 0;
+		}
+
+		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
+		{
+			int tcs_val;                        
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+			
+			if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
+				return -EFAULT;
+
+			tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
+			ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
+			return 0;
+		}
+		default:
+			return -EINVAL;
+	}
+}
+
+int
+get_rtc_status(char *buf) 
+{
+	char *p;
+	struct rtc_time tm;
+
+	p = buf;
+
+	get_rtc_time(&tm);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+
+	p += sprintf(p,
+		"rtc_time\t: %02d:%02d:%02d\n"
+		"rtc_date\t: %04d-%02d-%02d\n",
+		tm.tm_hour, tm.tm_min, tm.tm_sec,
+		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+
+	return  p - buf;
+}
+
+
+/* The various file operations we support. */
+
+static struct file_operations rtc_fops = {
+	.owner          = THIS_MODULE,
+	.ioctl          = rtc_ioctl,    
+}; 
+
+/* Probe for the chip by writing something to its RAM and try reading it back. */
+
+#define MAGIC_PATTERN 0x42
+
+static int __init
+ds1302_probe(void) 
+{
+	int retval, res, baur; 
+
+	baur=(boot_cpu_data.bus_clock/(2*1000*1000));
+
+	printk("%s: Set PLD_RTCBAUR = %d\n", ds1302_name,baur);
+
+	outw(0x0000,(unsigned long)PLD_RTCCR);
+	outw(0x0000,(unsigned long)PLD_RTCRSTODT);
+	outw(baur,(unsigned long)PLD_RTCBAUR);
+
+	/* Try to talk to timekeeper. */
+
+	ds1302_wenable();  
+	/* write RAM byte 0 */	
+	/* write something magic */
+	out_byte_rtc(0xc0,MAGIC_PATTERN);
+	
+	/* read RAM byte 0 */
+	if((res = in_byte_rtc(0xc1)) == MAGIC_PATTERN) {
+		char buf[100];
+		ds1302_wdisable();
+		printk("%s: RTC found.\n", ds1302_name);
+                get_rtc_status(buf);
+                printk(buf);
+		retval = 1;
+	} else {
+		printk("%s: RTC not found.\n", ds1302_name);
+		retval = 0;
+	}
+
+	return retval;
+}
+
+
+/* Just probe for the RTC and register the device to handle the ioctl needed. */
+
+int __init
+ds1302_init(void) 
+{ 
+	if (!ds1302_probe()) {
+    		return -1;
+  	}
+	return 0;
+}
+
+static int __init ds1302_register(void)
+{
+        ds1302_init();
+	if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
+		printk(KERN_INFO "%s: unable to get major %d for rtc\n", 
+		       ds1302_name, RTC_MAJOR_NR);
+		return -1;
+	}
+	return 0;
+}
+
+module_init(ds1302_register);
diff -ruN linux-2.6.4.org/arch/m32r/drivers/m32r-pldsio.c linux-2.6.4/arch/m32r/drivers/m32r-pldsio.c
--- linux-2.6.4.org/arch/m32r/drivers/m32r-pldsio.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.4/arch/m32r/drivers/m32r-pldsio.c	2003-09-09 10:15:02.000000000 +0900
@@ -0,0 +1,3067 @@
+/* $Id$
+ *
+ * M32R onboard PLD serial module support.
+ * 
+ * Much of the design and some of the code came from serial.c:
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
+ *              1998, 1999  Theodore Ts'o
+ *
+ * M32R work:
+ *  Copyright 1996, 2001, Mitsubishi Electric Corporation 
+ *  Copyright (C) 2000,2001  by Hiro Kondo, Hiro Takata, and Hitoshi Yamamoto.
+ *
+ *  2002-12-25: Support M32700UT Platform by Takeo Takahashi
+ *  		Derived from dbg_console.c.
+ */
+
+static char *serial_version = "kondo";
+static char *serial_revdate = "2002-09-11";
+static char *serial_name = "M32R Serial driver";
+
+#define LOCAL_VERSTRING ""
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/tty_driver.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>  /* serial_state */
+#include <linux/slab.h>  /* kmalloc */
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/serial.h>
+#include <asm/m32r.h>
+
+extern struct console  console_for_debug;
+
+static int psio_write(struct tty_struct *tty, int from_user, 
+			const unsigned char *buf, int count);
+static int psio_write_room(struct tty_struct *tty);
+static int psio_chars_in_buffer(struct tty_struct *tty);
+
+static void dbg_console_write(struct console *, const char *, unsigned);
+static kdev_t dbg_console_device(struct console *c);
+//static void psio_interrupt_single(int, void *, struct pt_regs *);
+void psio_interrupt_single(int, void *, struct pt_regs *);
+static void psio_receive_chars(struct async_struct *, int *);
+
+static void psio_wait_until_sent(struct tty_struct *, int);
+static void change_speed(struct async_struct *,struct termios *);
+static void autoconfig(struct serial_state *);
+static unsigned detect_uart_irq (struct serial_state *);
+
+static struct tty_driver psio_driver;
+static int psio_refcount;
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_SERIAL_CONSOLE
+static struct console cons;
+static int lsr_break_flag;
+#endif
+
+#define BAUDRATE 115200        /* Set Baudrate */
+
+/*
+ * Here we define the default xmit fifo size used for each type of
+ * UART
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "cirrus", 1, 0 },     /* usurped by cyclades.c */
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		UART_STARTECH },
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "Startech", 1, 0},    /* usurped by cyclades.c */
+	{ "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO |
+		UART_STARTECH },
+	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
+		UART_STARTECH },
+	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "m32102", 1, 0 },
+	{ 0, 0}
+};
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+/*    UART CLK        PORT        IRQ   FLAGS        */ 
+      { 0,   BAUDRATE, ((int)PLD_ESIO0CR + NONCACHE_OFFSET), PLD_IRQ_SIO0_RCV,   STD_COM_FLAGS }, 
+};
+#define NR_PORTS    (sizeof(rs_table)/sizeof(struct serial_state))
+
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static DECLARE_TASK_QUEUE(tq_psio_serial);
+static struct tty_struct *psio_table[NR_PORTS];
+static struct termios *psio_termios[NR_PORTS];
+static struct termios *psio_termios_locked[NR_PORTS];
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s
+)
+#else
+#define DBG_CNT(s)
+#endif
+
+
+static struct timer_list serial_timer;
+
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+static int dbg_console_setup(struct console *console, char *options);
+
+#undef SIO0CR
+#undef SIO0MOD0
+#undef SIO0MOD1
+#undef SIO0STS
+#undef SIO0IMASK
+#undef SIO0BAUR
+#undef SIO0TXB
+#undef SIO0RXB
+#define SIO0CR     PLD_ESIO0CR
+#define SIO0MOD0   PLD_ESIO0MOD0
+#define SIO0MOD1   PLD_ESIO0MOD1
+#define SIO0STS    PLD_ESIO0STS
+#define SIO0IMASK  PLD_ESIO0INTCR
+#define SIO0BAUR   PLD_ESIO0BAUR
+#define SIO0TXB    PLD_ESIO0TXB
+#define SIO0RXB    PLD_ESIO0RXB
+
+#define SIO_IMASK_TEMPIE       (1UL<<1)  /* b14: enable */
+#define SIO_IMASK_RXCEN        (1UL<<2)  /* b13: enable */
+#define SIO_IMASK_REIE         (0UL)
+#define	SIO_SIO0STS_TEMP       (1UL<<0)  /* Transmitter Register Empty */
+#define	SIO_SIO0STS_TXCP       (1UL<<1)
+#define	SIO_SIO0STS_RXCP       (1UL<<2)
+#define	SIO_SIO0STS_OERR       (0UL)
+#define	SIO_SIO0STS_PERR       (0UL)
+#define	SIO_SIO0STS_FERR       (0UL)
+#define	SIO_SIO0MOD0_CTSS      (1UL<<6)
+#define	SIO_SIO0MOD0_RTSS      (1UL<<7)
+#define	SIO_NONE               (0UL)
+
+#define	UART_TX   	((unsigned char *)SIO0TXB - (unsigned char *)SIO0CR)
+#define	UART_RX         ((unsigned char *)SIO0RXB - (unsigned char *)SIO0CR)
+#define	UART_IER        ((unsigned char *)SIO0IMASK - (unsigned char *)SIO0CR)
+#define UART_IER_THRI   	SIO_IMASK_TEMPIE
+#define UART_IER_MSI    	SIO_NONE
+#define UART_IER_RLSI   	SIO_IMASK_RXCEN
+#define UART_IER_RDI    	SIO_IMASK_REIE
+#define	UART_LSR        ((unsigned char *)SIO0STS - (unsigned char *)SIO0CR)
+#define	UART_LSR_DR     	SIO_SIO0STS_RXCP
+#define	UART_LSR_THRE   	SIO_SIO0STS_TEMP
+#define	UART_LSR_TEMT   	SIO_SIO0STS_TXCP
+#define UART_EMPTY		(UART_LSR_TEMT | UART_LSR_THRE)
+#define	UART_LSR_BI     	SIO_NONE
+#define	UART_LSR_PE     	SIO_SIO0STS_PERR
+#define	UART_LSR_FE     	SIO_SIO0STS_FERR
+#define	UART_LSR_OE     	SIO_SIO0STS_OERR
+#define	UART_IIR	((unsigned char *)SIO0STS - (unsigned char *)SIO0CR)
+#define	UART_LCR        ((unsigned char *)SIO0CR - (unsigned char *)SIO0CR)
+#define	UART_LCR_SBC    	SIO_NONE
+#define	UART_LCR_PARITY 	SIO_NONE
+#define	UART_LCR_EPAR   	SIO_NONE
+#define	UART_LCR_SPAR   	SIO_NONE
+#define	UART_MCR        ((unsigned char *)SIO0MOD0 - (unsigned char *)SIO0CR)
+#define	UART_MCR_RTS    	SIO_SIO0MOD0_RTSS
+#define	UART_MCR_DTR    	SIO_NONE	/* SIO_SIO0MOD0_CTSS */
+#define	UART_MCR_LOOP   	SIO_NONE
+#define	UART_MCR_OUT1   	SIO_NONE
+#define	UART_MCR_OUT2   	SIO_NONE
+#define	UART_MSR        ((unsigned char *)SIO0MOD0 - (unsigned char *)SIO0CR)
+#define	UART_MSR_DCD           	SIO_NONE
+#define	UART_MSR_RI            	SIO_NONE
+#define	UART_MSR_DSR           	SIO_NONE
+#define	UART_MSR_CTS           	SIO_NONE
+
+#define	UART_BAUR       ((unsigned char *)SIO0BAUR - (unsigned char *)SIO0CR)
+#define	UART_MOD0   	((unsigned char *)SIO0MOD0 - (unsigned char *)SIO0CR)
+#define	UART_MOD1       ((unsigned char *)SIO0MOD1 - (unsigned char *)SIO0CR)
+
+static  inline unsigned int psio_in(struct async_struct *info,int offset)
+{
+	return *(volatile unsigned short *)(info->port + offset);
+}
+static inline void psio_out(struct async_struct *info,int offset,int value)
+{
+	*(volatile unsigned short *)(info->port + offset) = value;
+}
+
+#define serial_in(info, offset)            psio_in(info,(int)offset)
+#define serial_out(info, offset, value)    psio_out(info,(int)offset, value)
+#define serial_inp(info, offset)           psio_in(info,(int)offset)
+#define serial_outp(info, offset, value)   psio_out(info,(int)offset, value)
+
+
+static inline int serial_paranoia_check(struct async_struct *info,
+				        kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * psio_stop() and psio_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void psio_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "psio_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->IER & UART_IER_THRI) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+	restore_flags(flags);
+
+}
+
+static void psio_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "psio_start"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+		&& info->xmit.buf
+		&& !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+	}
+	restore_flags(flags);
+}
+
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static inline void psio_sched_event(struct async_struct *info,int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_psio_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static inline void psio_receive_chars(struct async_struct *info,int *status)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	struct  async_icount *icount;
+	int max_count = 256;
+
+	icount = &info->state->icount;
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *) tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return;     // if TTY_DONT_FLIP is set
+		}
+		ch = serial_inp(info, UART_RX);
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+	
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%02x...", ch, *status);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+		if (*status & (UART_LSR_BI | UART_LSR_PE |
+			       UART_LSR_FE | UART_LSR_OE)) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				icount->brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+				if (info->line == cons.index) {
+					if (!break_pressed) {
+						break_pressed = jiffies;
+						goto ignore_char;
+					}
+					break_pressed = 0;
+				}
+#endif
+			        if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (*status & UART_LSR_PE)
+				icount->parity++;
+			else if (*status & UART_LSR_FE)
+				icount->frame++;
+			if (*status & UART_LSR_OE)
+				icount->overrun++;
+
+			/*
+			 * Mask off conditions which should be ignored.
+			 */
+			*status &= info->read_status_mask;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+			if (info->line == cons.index) {
+				/* Recover the break flag from console xmit */
+				*status |= lsr_break_flag;
+				lsr_break_flag = 0;
+			}
+#endif
+			if (*status & (UART_LSR_BI)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == cons.index) {
+			if (ch != 0 &&
+				time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		if ((*status & info->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+	ignore_char:
+#endif
+		*status = serial_inp(info, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+	tty_flip_buffer_push(tty);
+#else
+	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+#endif
+}
+
+static void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+
+	if (info->x_char) {
+		// for M32102 serial
+		// serial_outp(info, UART_TX, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		while((serial_in(info,UART_LSR) & UART_LSR_TEMT) == 0);
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+		|| info->tty->stopped
+		|| info->tty->hw_stopped) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+		return;
+	}
+	count = info->xmit_fifo_size;
+	count = SERIAL_XMIT_SIZE-1;
+	do {
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+
+		if (info->xmit.head == info->xmit.tail)
+			break;
+
+		while((serial_in(info,UART_LSR) & UART_LSR_THRE) == 0);
+	} while (--count > 0);
+	while((serial_in(info,UART_LSR) & UART_LSR_TEMT) == 0);
+
+	if (CIRC_CNT(info->xmit.head,
+			 info->xmit.tail,
+			 SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		psio_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+}
+
+
+/*
+
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+#endif 
+*/
+
+static void sio_reset(struct async_struct *info)
+{
+	unsigned int dummy;
+	/* reset sio */
+	/* read receive buffer */
+	dummy = serial_inp(info, UART_RX);
+	dummy = serial_inp(info, UART_RX);
+	dummy = serial_inp(info, UART_LSR);
+	serial_outp(info, UART_LCR, 0x0300);	/* RSCLR:1, TSCLR:1 */
+	serial_outp(info, UART_LCR, 0x0003);	/* RSEN:1, TXEN:1 */
+}
+
+static void sio_error(struct async_struct *info,int status)
+{
+	unsigned int dummy;
+	/* reset sio */
+	printk("sio[%d] error[%04x]\n", info->line,status);
+	/* read receive buffer */
+	dummy = serial_inp(info, UART_RX);
+	dummy = serial_inp(info, UART_RX);
+	dummy = serial_inp(info, UART_LSR);
+	serial_outp(info, UART_LCR, 0x0300);	/* RSCLR:1, TSCLR:1 */
+	serial_outp(info, UART_LCR, 0x0003);	/* RSEN:1, TXEN:1 */
+}
+
+//static void psio_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+void psio_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	// int pass_counter = 0;
+	struct async_struct * info;
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+	int first_multi = 0;
+	struct rs_multiport_struct *multi;
+#endif
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("psio_interrupt_single(%d)...", irq);
+#endif
+	
+	info = IRQ_ports[irq&(~1)];
+	if (!info || !info->tty)
+		return;
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+	multi = &rs_multiport[irq];
+	if (multi->port_monitor)
+		first_multi = inb(multi->port_monitor);
+#endif
+
+	{
+		status = serial_inp(info, UART_LSR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR){
+			psio_receive_chars(info, &status);
+		}
+		if ((serial_in(info,UART_LSR) & UART_EMPTY) != UART_EMPTY)
+			sio_error(info, status);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+#ifdef SERIAL_DEBUG_INTR
+		printk("IIR = %x...", serial_in(info, UART_IIR));
+#endif
+	}
+
+	info->last_active = jiffies;
+#ifdef CONFIG_SERIAL_MULTIPORT
+	if (multi->port_monitor)
+			printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n",
+			info->state->irq, first_multi,
+			inb(multi->port_monitor));
+#endif
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+#ifdef CONFIG_SERIAL_MULTIPORT
+static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
+{}
+#endif
+
+static void do_psio_serial_bh(void)
+{
+	run_task_queue(&tq_psio_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct async_struct *info = (struct async_struct *) private_;
+	struct tty_struct *tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+			tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+static void psio_timer(void)
+{
+	static unsigned long last_strobe = 0;
+	struct async_struct *info;
+	unsigned int  i;
+	unsigned long flags;
+
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+			psio_interrupt_single(i, NULL, NULL);
+			restore_flags(flags);
+		}
+	}
+	last_strobe = jiffies;
+
+#if 1
+	mod_timer(&serial_timer, jiffies + 10);
+#else 
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+#endif
+
+	if (IRQ_ports[0]) {
+		save_flags(flags); cli();
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+		psio_interrupt(0, NULL, NULL);
+#else
+		psio_interrupt_single(0, NULL, NULL);
+#endif
+		restore_flags(flags);
+
+		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
+	}
+}
+
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct  async_struct    *info;
+	int timeout = 60*HZ;    /* 60 seconds === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = timeout ? timeout : 1;
+}
+
+#ifdef CONFIG_SERIAL_RSA
+/* Attempts to turn on the RSA FIFO.  Returns zero on failure */
+static int enable_rsa(struct async_struct *info) {}
+
+/* Attempts to turn off the RSA FIFO.  Returns zero on failure */
+static int disable_rsa(struct async_struct *info) { }
+#endif /* CONFIG_SERIAL_RSA */
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	unsigned short ICP;
+#endif
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyD%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	sio_reset(info);
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			   !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			free_irq(state->irq+1, &IRQ_ports[state->irq]);
+#ifdef CONFIG_SERIAL_MULTIPORT
+			if (rs_multiport[state->irq].port1)
+				handler = rs_interrupt_multi;
+			else
+#endif
+				handler = psio_interrupt;
+#else
+			retval = -EBUSY;
+			goto errout;
+#endif /* CONFIG_SERIAL_SHARE_IRQ */
+		} else
+			handler = psio_interrupt_single;
+
+		/* 020116 */
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+			"serial_rx", &IRQ_ports[state->irq]);
+		retval = request_irq(state->irq+1, handler, SA_SHIRQ,
+			"serial_tx", &IRQ_ports[state->irq]);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	/*
+	 * Now, initialize the UART
+	 */
+	/* for m32r @020113 */
+	sio_reset(info);
+
+	info->MCR = 0;
+	if (info->tty->termios->c_cflag & CBAUD)
+		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		if (state->irq == 0)
+			info->MCR |= UART_MCR_OUT1;
+	} else
+#endif
+	{
+		if (state->irq != 0)
+			info->MCR |= UART_MCR_OUT2;
+	}
+	info->MCR |= ALPHA_KLUDGE_MCR;      /* Don't ask */
+	serial_outp(info, UART_MCR, info->MCR);
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(info, UART_IER, info->IER); /* enable interrupts */
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		/* Enable interrupts on the AST Fourport board */
+		ICP = (info->port & 0xFE0) | 0x01F;
+		outb_p(0x80, ICP);
+		(void) inb_p(ICP);
+	}
+#endif
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void)serial_inp(info, UART_LSR);
+	(void)serial_inp(info, UART_RX);
+	(void)serial_inp(info, UART_IIR);
+	(void)serial_inp(info, UART_MSR);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/*
+	 * Set up serial timers...
+	 */
+	mod_timer(&serial_timer, jiffies + 2*HZ/100);
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+#endif
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long   flags;
+	struct serial_state *state;
+	int     retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+		   state->irq);
+#endif
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			/* 020116 */
+			free_irq(state->irq+1, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq+1, psio_interrupt_single,
+				         SA_SHIRQ, "serial_xx",
+				         &IRQ_ports[state->irq]);
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, psio_interrupt_single,
+				         SA_SHIRQ, "serial",
+				         &IRQ_ports[state->irq]);
+
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else{
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			/* 020116 */
+			free_irq(state->irq+1, &IRQ_ports[state->irq]);
+		}
+	}
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	info->IER = 0;
+	serial_outp(info, UART_IER, 0x00);  /* disable all intrs */
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		/* reset interrupts on the AST Fourport board */
+		(void) inb((info->port & 0xFE0) | 0x01F);
+		info->MCR |= UART_MCR_OUT1;
+	} else
+#endif
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+	serial_outp(info, UART_MCR, info->MCR);
+
+#ifdef CONFIG_SERIAL_RSA
+	/*
+	 * Reset the RSA board back to 115kbps compat mode.
+	 */
+	if ((state->type == PORT_RSA) &&
+		(state->baud_base == SERIAL_RSA_BAUD_BASE &&
+		 disable_rsa(info)))
+		state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
+#endif
+
+
+	(void)serial_in(info, UART_RX);    /* read data port to reset things */
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	sio_reset(info);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+static void change_speed(struct async_struct *info,struct termios *old_termios)
+{
+	int quot = 0, baud_base, baud;
+	unsigned cflag, cval = 0;
+	int bits;
+	unsigned long   flags;
+	unsigned mod0, mod1;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+		  case CS5: mod1 = 0x05; bits = 7; break;
+		  case CS6: mod1 = 0x06; bits = 8; break;
+		  case CS7: mod1 = 0x07; bits = 9; break;
+		  case CS8: mod1 = 0x08; bits = 10; break;
+		  /* Never happens, but GCC is too dumb to figure it out */
+		  default:  mod1 = 0x05; bits = 7; break;
+	}
+	mod1 <<= 8;
+	mod0 = 0;
+	if (cflag & CSTOPB) {
+		mod0 |= 0x03;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		mod0 |= 0x10;
+		bits++;
+	}
+	if (!(cflag & PARODD)) {
+		mod0 |= 0x4;
+	}
+	mod0 = 0x80;	/* Use RTS# output only */
+
+	serial_outp(info, UART_MOD0, mod0);      /* */
+	//serial_outp(info, UART_MOD1, mod1); 
+	//mod1 = 0;
+	info->LCR = mod1;               /* Save LCR */
+
+	/* Determine divisor based on baud rate */
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;    /* B0 transition handled in rs_set_termios */
+#ifdef CONFIG_SERIAL_RSA
+	if ((info->state->type == PORT_RSA) &&
+		(info->state->baud_base != SERIAL_RSA_BAUD_BASE) &&
+		enable_rsa(info))
+		info->state->baud_base = SERIAL_RSA_BAUD_BASE;
+#endif
+	baud_base = info->state->baud_base;
+
+	if (baud == 38400 &&
+		((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = info->state->custom_divisor;
+	else {
+		if (baud == 134)
+			/* Special case since 134 is really 134.5 */
+			quot = (2*baud_base / 269);
+		else if (baud)
+			quot = baud_base / baud;
+	}
+	/* If the quotient is zero refuse the change */
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+		if (baud == 38400 &&
+			((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->state->custom_divisor;
+		else {
+			if (baud == 134)
+				/* Special case since 134 is really 134.5 */
+				quot = (2*baud_base / 269);
+			else if (baud)
+				quot = baud_base / baud ;
+		}
+	}
+	quot = baud_base / (baud*4) ;
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot)
+		quot = baud_base / 9600;
+	/*
+	 * Work around a bug in the Oxford Semiconductor 952 rev B
+	 * chip which causes it to seriously miscalculate baud rates
+	 * when DLL is 0.
+	 */
+	if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) &&
+		(info->state->revision == 0x5201))
+		quot++;
+
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;     /* Add .02 seconds of slop */
+
+	/* CTS flow control flag and modem status interrupts */
+	info->IER &= ~UART_IER_MSI;
+	if (info->flags & ASYNC_HARDPPS_CD)
+		info->IER |= UART_IER_MSI;
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		info->IER |= UART_IER_MSI;
+	} else
+		info->flags &= ~ASYNC_CTS_FLOW;
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else {
+		info->flags |= ASYNC_CHECK_CD;
+		info->IER |= UART_IER_MSI;
+	}
+	serial_out(info, UART_IER, info->IER);
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characters to ignore
+	 */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignore parity and break indicators, ignore
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= UART_LSR_OE;
+	}
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		info->ignore_status_mask |= UART_LSR_DR;
+	cval = (baud_base / (baud * 4)) - 1;
+
+	save_flags(flags); cli();
+	serial_outp(info, UART_BAUR, cval );  /* set baurate reg */
+	serial_outp(info, UART_LCR, 0x03);
+	restore_flags(flags);
+}
+
+static void psio_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "psio_put_char"))
+		return;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+			   info->xmit.tail,
+			   SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void psio_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "psio_flush_chars"))
+		return;
+
+	if (info->xmit.head == info->xmit.tail
+		|| tty->stopped
+		|| tty->hw_stopped
+		|| !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (!(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+	}
+	restore_flags(flags);
+	while((serial_in(info,UART_LSR) & UART_EMPTY) != UART_EMPTY);
+}
+
+static int psio_write(struct tty_struct *tty, int from_user, 
+		    const unsigned char *buf, int count)
+{
+	int c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+		
+	if (serial_paranoia_check(info, tty->device, "psio_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					info->xmit.tail,
+					SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					info->xmit.tail,
+					SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					(SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					info->xmit.tail,
+					SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+				 (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+		&& !tty->stopped
+		&& !tty->hw_stopped
+		&& !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+	}
+	restore_flags(flags);
+	while((serial_in(info,UART_LSR) & UART_EMPTY) != UART_EMPTY);
+	return ret;
+}
+
+static int psio_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "psio_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int psio_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+		
+	if (serial_paranoia_check(info, tty->device, "psio_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void psio_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "psio_flush_buffer"))
+		return;
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+			 tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void psio_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "psio_send_char"))
+		return;
+
+	info->x_char = ch;
+	if (ch) {
+		unsigned long flags;
+		save_flags(flags); cli();
+		if (!(info->IER & UART_IER_THRI)) {
+	   		info->IER |= UART_IER_THRI;
+			serial_out(info, UART_IER, info->IER);
+			serial_out(info, UART_TX, info->x_char);
+		}
+		restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void psio_throttle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char    buf[64];
+
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+		tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "psio_throttle"))
+		return;
+
+	if (I_IXOFF(tty))
+		psio_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR &= ~UART_MCR_RTS;
+
+	save_flags(flags); cli();
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+static void psio_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char    buf[64];
+
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+		tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "psio_unthrottle"))
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char) info->x_char = 0;
+	}
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR |= UART_MCR_RTS;
+	save_flags(flags); cli();
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(struct async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		    (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+					(new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+				   (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+		(new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+			   (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+#ifdef CONFIG_SERIAL_RSA
+		if (old_state.type == PORT_RSA)
+			release_region(state->port + UART_RSA_BASE, 16);
+		else
+#endif
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+		info->hub6 = state->hub6 = new_serial.hub6;
+		if (info->hub6)
+			info->io_type = state->io_type = SERIAL_IO_HUB6;
+		else if (info->io_type == SERIAL_IO_HUB6)
+			info->io_type = state->io_type = SERIAL_IO_PORT;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+#ifdef CONFIG_SERIAL_RSA
+		if (state->type == PORT_RSA)
+			request_region(state->port + UART_RSA_BASE,
+				       16, "serial_rsa(set)");
+		else
+#endif
+			request_region(state->port,8,"serial(set)");
+	}
+
+
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+			 (state->flags & ASYNC_SPD_MASK)) ||
+			(old_state.custom_divisor != state->custom_divisor)) {
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+#endif
+			change_speed(info, 0);
+		}
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *      is emptied.  On bus types like RS485, the transmitter must
+ *      release the bus after transmitting. This must be done when
+ *      the transmit shift register is empty, not be done when the
+ *      transmit holding register is empty.  This functionality
+ *      allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = serial_in(info, UART_LSR);
+	restore_flags(flags);
+	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+
+	/*
+	 * If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+	if (info->x_char ||
+		((CIRC_CNT(info->xmit.head, info->xmit.tail,
+			   SERIAL_XMIT_SIZE) > 0) &&
+		 !info->tty->stopped && !info->tty->hw_stopped))
+		result &= ~TIOCSER_TEMT;
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+
+static int get_modem_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char control, status;
+	unsigned int result;
+	unsigned long flags;
+
+	control = info->MCR;
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	restore_flags(flags);
+	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+#ifdef TIOCM_OUT1
+		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
+		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
+#endif
+		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
+		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
+		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
+		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+static int set_modem_info(struct async_struct * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	unsigned int arg;
+	unsigned long flags;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIOCMBIS:
+		if (arg & TIOCM_RTS)
+			info->MCR |= UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR |= UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR |= UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR |= UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR |= UART_MCR_LOOP;
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->MCR &= ~UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR &= ~UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR &= ~UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR &= ~UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR &= ~UART_MCR_LOOP;
+		break;
+	case TIOCMSET:
+		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
+#ifdef TIOCM_OUT1
+				        UART_MCR_OUT1 |
+				        UART_MCR_OUT2 |
+#endif
+				        UART_MCR_LOOP |
+				        UART_MCR_DTR))
+				 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+#ifdef TIOCM_OUT1
+				 | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
+				 | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+#endif
+				 | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
+				 | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	save_flags(flags); cli();
+	info->MCR |= ALPHA_KLUDGE_MCR;      /* Don't ask */
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+	return 0;
+}
+
+static int do_autoconfig(struct async_struct * info)
+{
+	int irq, retval;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (info->state->count > 1)
+		return -EBUSY;
+
+	shutdown(info);
+
+	autoconfig(info->state);
+	if ((info->state->flags & ASYNC_AUTO_IRQ) &&
+		(info->state->port != 0  || info->state->iomem_base != 0) &&
+		(info->state->type != PORT_UNKNOWN)) {
+		irq = detect_uart_irq(info->state);
+		if (irq > 0)
+			info->state->irq = irq;
+	}
+
+	retval = startup(info);
+	if (retval)
+		return retval;
+	return 0;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static void send_break( struct async_struct * info, int duration)
+{
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+	cli();
+	info->LCR |= UART_LCR_SBC;
+	serial_out(info, UART_LCR, 0x3);
+	schedule();
+	info->LCR &= ~UART_LCR_SBC;
+	serial_out(info, UART_LCR, 0x3);
+	sti();
+}
+#else
+static void psio_break(struct tty_struct *tty, int break_state)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		info->LCR |= UART_LCR_SBC;
+	else
+		info->LCR &= ~UART_LCR_SBC;
+	restore_flags(flags);
+}
+#endif
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+static int get_multiport_struct(struct async_struct * info,
+				struct serial_multiport_struct *retinfo)
+{
+	struct serial_multiport_struct ret;
+	struct rs_multiport_struct *multi;
+
+	multi = &rs_multiport[info->state->irq];
+
+	ret.port_monitor = multi->port_monitor;
+
+	ret.port1 = multi->port1;
+	ret.mask1 = multi->mask1;
+	ret.match1 = multi->match1;
+
+	ret.port2 = multi->port2;
+	ret.mask2 = multi->mask2;
+	ret.match2 = multi->match2;
+
+	ret.port3 = multi->port3;
+	ret.mask3 = multi->mask3;
+	ret.match3 = multi->match3;
+
+	ret.port4 = multi->port4;
+	ret.mask4 = multi->mask4;
+	ret.match4 = multi->match4;
+
+	ret.irq = info->state->irq;
+
+	if (copy_to_user(retinfo,&ret,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_multiport_struct(struct async_struct * info,
+				struct serial_multiport_struct *in_multi)
+{
+	struct serial_multiport_struct new_multi;
+	struct rs_multiport_struct *multi;
+	struct serial_state *state;
+	int was_multi, now_multi;
+	int retval;
+	void (*handler)(int, void *, struct pt_regs *);
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	state = info->state;
+
+	if (copy_from_user(&new_multi, in_multi,
+			   sizeof(struct serial_multiport_struct)))
+		return -EFAULT;
+
+	if (new_multi.irq != state->irq || state->irq == 0 ||
+		!IRQ_ports[state->irq])
+		return -EINVAL;
+
+	multi = &rs_multiport[state->irq];
+	was_multi = (multi->port1 != 0);
+
+	multi->port_monitor = new_multi.port_monitor;
+
+	if (multi->port1)
+		release_region(multi->port1,1);
+	multi->port1 = new_multi.port1;
+	multi->mask1 = new_multi.mask1;
+	multi->match1 = new_multi.match1;
+	if (multi->port1)
+		request_region(multi->port1,1,"serial(multiport1)");
+
+	if (multi->port2)
+		release_region(multi->port2,1);
+	multi->port2 = new_multi.port2;
+	multi->mask2 = new_multi.mask2;
+	multi->match2 = new_multi.match2;
+	if (multi->port2)
+		request_region(multi->port2,1,"serial(multiport2)");
+
+	if (multi->port3)
+		release_region(multi->port3,1);
+	multi->port3 = new_multi.port3;
+	multi->mask3 = new_multi.mask3;
+	multi->match3 = new_multi.match3;
+	if (multi->port3)
+		request_region(multi->port3,1,"serial(multiport3)");
+
+	if (multi->port4)
+		release_region(multi->port4,1);
+	multi->port4 = new_multi.port4;
+	multi->mask4 = new_multi.mask4;
+	multi->match4 = new_multi.match4;
+	if (multi->port4)
+		request_region(multi->port4,1,"serial(multiport4)");
+
+	now_multi = (multi->port1 != 0);
+
+	if (IRQ_ports[state->irq]->next_port &&
+		(was_multi != now_multi)) {
+		free_irq(state->irq, &IRQ_ports[state->irq]);
+		if (now_multi)
+			handler = rs_interrupt_multi;
+		else
+			handler = rs_interrupt;
+
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq]);
+		if (retval) {
+			printk("Couldn't reallocate serial interrupt "
+				   "driver!!\n");
+		}
+	}
+	return 0;
+}
+#endif
+
+static int psio_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct async_icount cprev, cnow;    /* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+	int retval, tmp;
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+		(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+		case TCSBRK:    /* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4); /* 1/4 second */
+				if (signal_pending(current))
+				    return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:   /* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCGSOFTCAR:
+			tmp = C_CLOCAL(tty) ? 1 : 0;
+			if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+				return -EFAULT;
+			return 0;
+		case TIOCSSOFTCAR:
+			if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+				return -EFAULT;
+
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (tmp ? CLOCAL : 0));
+			return 0;
+#endif
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+				               (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct async_struct *) arg,
+			    info, sizeof(struct async_struct)))
+				return -EFAULT;
+			return 0;
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+		case TIOCSERGETMULTI:
+			return get_multiport_struct(info,
+				       (struct serial_multiport_struct *) arg);
+		case TIOCSERSETMULTI:
+			return set_multiport_struct(info,
+				       (struct serial_multiport_struct *) arg);
+#endif
+
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			save_flags(flags); cli();
+			/* note the counters on entry */
+			cprev = info->state->icount;
+			restore_flags(flags);
+			/* Force modem status interrupts on */
+			info->IER |= UART_IER_MSI;
+			serial_out(info, UART_IER, info->IER);
+			while (1) {
+				interruptible_sleep_on(&info->delta_msr_wait);
+				/* see if a signal did it */
+				if (signal_pending(current))
+				    return -ERESTARTSYS;
+				save_flags(flags); cli();
+				cnow = info->state->icount; /* atomic copy */
+				restore_flags(flags);
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+				    return -EIO; /* no change => error */
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+				    return 0;
+				}
+				cprev = cnow;
+			}
+			/* NOTREACHED */
+
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void psio_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	unsigned int cflag = tty->termios->c_cflag;
+
+	if (   (cflag == old_termios->c_cflag)
+		&& (   RELEVANT_IFLAG(tty->termios->c_iflag)
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+		!(cflag & CBAUD)) {
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+		(cflag & CBAUD)) {
+		info->MCR |= UART_MCR_DTR;
+		if (!(tty->termios->c_cflag & CRTSCTS) ||
+			!test_bit(TTY_THROTTLED, &tty->flags)) {
+			info->MCR |= UART_MCR_RTS;
+		}
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+		!(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		psio_start(tty);
+	}
+}
+
+/*
+ * -----------------------------------------------------------
+ * psio_close()
+ *
+ * This routine is called when the debug console port gets closed.  
+ * First, we wait for the last remaining data to be sent.  Then, we unlink 
+ * its async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * -----------------------------------------------------------
+ */
+static void psio_close(struct tty_struct *tty, struct file *filp)
+{
+	struct async_struct * info = (s